From 1b9ba2b2333746c5e2b05a2bf24fa6ec3828dcdf Mon Sep 17 00:00:00 2001 From: Andrzej Janik Date: Sat, 27 Feb 2021 20:55:19 +0100 Subject: [PATCH] Nobody expects the Red Team Too many changes to list, but broadly: * Remove Intel GPU support from the compiler * Add AMD GPU support to the compiler * Remove Intel GPU host code * Add AMD GPU host code * More device instructions. From 40 to 68 * More host functions. From 48 to 184 * Add proof of concept implementation of OptiX framework * Add minimal support of cuDNN, cuBLAS, cuSPARSE, cuFFT, NCCL, NVML * Improve ZLUDA launcher for Windows --- .cargo/config.toml | 10 +- .devcontainer/Dockerfile | 6 + .devcontainer/Dockerfile-common | 64 + .devcontainer/Dockerfile-el8_8 | 72 + .devcontainer/Dockerfile-xgboost | 16 + .devcontainer/devcontainer.json | 39 + .gitattributes | 3 + .github/workflows/rust.yml | 58 - .gitmodules | 12 +- ARCHITECTURE.md | 197 + CONTRIBUTING.md | 61 - Cargo.toml | 65 +- GeekBench_5_2_3.svg | 1 - Makefile.toml | 57 + README.md | 291 +- atiadlxx-sys/Cargo.toml | 8 + atiadlxx-sys/README | 1 + atiadlxx-sys/build.rs | 19 + atiadlxx-sys/include/adapter.h | 389 + atiadlxx-sys/include/adl.h | 64 + atiadlxx-sys/include/adl_defines.h | 2596 +++ atiadlxx-sys/include/adl_sdk.h | 46 + atiadlxx-sys/include/adl_structures.h | 4289 ++++ atiadlxx-sys/include/display.h | 573 + atiadlxx-sys/include/overdrive5.h | 85 + atiadlxx-sys/include/overdrive6.h | 164 + atiadlxx-sys/include/overdrive8.h | 68 + atiadlxx-sys/include/overdriveN.h | 90 + atiadlxx-sys/include/wrapper.hpp | 6 + atiadlxx-sys/lib/atiadlxx.def | 1216 + atiadlxx-sys/lib/atiadlxx.lib | Bin 0 -> 345274 bytes atiadlxx-sys/src/adl.rs | 8540 +++++++ atiadlxx-sys/src/lib.rs | 5 + comgr/Cargo.toml | 12 + comgr/README | 1 + comgr/include/amd_comgr.h | 2344 ++ comgr/src/amd_comgr.rs | 1004 + comgr/src/double_wave32_on_wave64.ll | 4 + comgr/src/lib.rs | 626 + comgr/src/linux.ll | 4 + comgr/src/wave32.ll | 4 + comgr/src/wave32_on_wave64.ll | 4 + comgr/src/windows.ll | 4 + cuda_base/Cargo.toml | 14 + cuda_base/README | 1 + cuda_base/build/wrapper.h | 7 + {zluda_dump => cuda_base}/src/cuda.rs | 11148 ++++++---- cuda_base/src/lib.rs | 556 + cuda_types/Cargo.toml | 8 + cuda_types/src/lib.rs | 12 + detours-sys/src/bundled_bindings.rs | 720 +- ext/llvm-project | 1 + ext/llvm-sys.rs/.gitignore | 3 + ext/llvm-sys.rs/.gitlab-ci.yml | 19 + ext/llvm-sys.rs/Cargo.toml | 21 + ext/llvm-sys.rs/LICENSE | 19 + ext/llvm-sys.rs/README.md | 188 + ext/llvm-sys.rs/appveyor.yml | 20 + ext/llvm-sys.rs/build.cmake | 2 + ext/llvm-sys.rs/build.rs | 140 + ext/llvm-sys.rs/scripts/RELEASE_CHECKLIST.md | 24 + ext/llvm-sys.rs/scripts/build-binaries.sh | 32 + ext/llvm-sys.rs/src/analysis.rs | 35 + ext/llvm-sys.rs/src/bit_reader.rs | 70 + ext/llvm-sys.rs/src/bit_writer.rs | 23 + ext/llvm-sys.rs/src/blake3.rs | 66 + ext/llvm-sys.rs/src/comdat.rs | 34 + ext/llvm-sys.rs/src/core.rs | 2095 ++ ext/llvm-sys.rs/src/debuginfo.rs | 880 + ext/llvm-sys.rs/src/disassembler.rs | 147 + ext/llvm-sys.rs/src/error.rs | 18 + ext/llvm-sys.rs/src/error_handling.rs | 17 + ext/llvm-sys.rs/src/execution_engine.rs | 212 + ext/llvm-sys.rs/src/initialization.rs | 19 + ext/llvm-sys.rs/src/ir_reader.rs | 16 + ext/llvm-sys.rs/src/lib.rs | 500 + ext/llvm-sys.rs/src/linker.rs | 19 + ext/llvm-sys.rs/src/lto.rs | 442 + ext/llvm-sys.rs/src/object.rs | 164 + ext/llvm-sys.rs/src/orc2/ee.rs | 11 + ext/llvm-sys.rs/src/orc2/lljit.rs | 74 + ext/llvm-sys.rs/src/orc2/mod.rs | 539 + ext/llvm-sys.rs/src/remarks.rs | 134 + ext/llvm-sys.rs/src/support.rs | 22 + ext/llvm-sys.rs/src/target.rs | 195 + ext/llvm-sys.rs/src/target_machine.rs | 111 + ext/llvm-sys.rs/src/transforms.rs | 8 + .../src/transforms/aggressive_instcombine.rs | 5 + ext/llvm-sys.rs/src/transforms/instcombine.rs | 5 + ext/llvm-sys.rs/src/transforms/ipo.rs | 25 + .../src/transforms/pass_builder.rs | 64 + .../src/transforms/pass_manager_builder.rs | 43 + ext/llvm-sys.rs/src/transforms/scalar.rs | 51 + ext/llvm-sys.rs/src/transforms/util.rs | 9 + ext/llvm-sys.rs/src/transforms/vectorize.rs | 8 + ext/llvm-sys.rs/wrappers/target.c | 48 + ext/optix_ext/README.md | 10 + ext/optix_ext/optix_ext_compile_no_inline.h | 56 + ...pile_no_inline_function_table_definition.h | 39 + .../optix_ext_compile_no_inline_stubs.h | 98 + ext/optix_ext/optix_ext_knobs.h | 67 + ...ptix_ext_knobs_function_table_definition.h | 39 + ext/optix_ext/optix_ext_knobs_stubs.h | 98 + ext/optix_ext/optix_ext_ptx_encryption.h | 82 + ...ptx_encryption_function_table_definition.h | 39 + .../optix_ext_ptx_encryption_stubs.h | 109 + ext/optix_ext/optix_ptx_encryption.h | 416 + ext/spirv-headers | 1 - ext/spirv-tools | 1 - geekbench.svg | 1 + hip_common/Cargo.toml | 23 + hip_common/src/cache.rs | 257 + hip_common/src/kernel_metadata.rs | 214 + hip_common/src/lib.rs | 117 + hip_common/src/raytracing.rs | 24 + hip_common/src/zluda.capnp | 18 + hip_common/src/zluda_capnp.rs | 713 + hip_common/src/zluda_ext.rs | 77 + hip_common/src/zluda_rt6.capnp | 30 + hip_common/src/zluda_rt6_capnp.rs | 1177 + hip_runtime-sys/Cargo.toml | 11 + hip_runtime-sys/Makefile.toml | 17 + hip_runtime-sys/README | 1 + {level_zero-sys => hip_runtime-sys}/build.rs | 8 +- hip_runtime-sys/include/hip_runtime_api.h | 2 + hip_runtime-sys/lib/amdhip64.def | 561 + hip_runtime-sys/lib/amdhip64.lib | Bin 0 -> 124886 bytes hip_runtime-sys/src/hip_runtime_api.rs | 7135 ++++++ hip_runtime-sys/src/lib.rs | 11 + {level_zero-sys => hipblaslt-sys}/Cargo.toml | 6 +- hipblaslt-sys/README | 1 + hipblaslt-sys/build.rs | 7 + hipblaslt-sys/src/hipblaslt.rs | 513 + hipblaslt-sys/src/lib.rs | 3 + hipfft-sys/Cargo.toml | 8 + hipfft-sys/README | 1 + hipfft-sys/build.rs | 4 + hipfft-sys/src/hipfft.rs | 458 + hipfft-sys/src/lib.rs | 3 + hiprt-sys/Cargo.toml | 14 + hiprt-sys/Makefile.toml | 16 + hiprt-sys/include/hiprt.h | 714 + hiprt-sys/include/hiprt/hiprt_vec.h | 79 + hiprt-sys/lib/hiprt64.dll | Bin 0 -> 580608 bytes hiprt-sys/lib/hiprt64.lib | Bin 0 -> 7470 bytes hiprt-sys/lib/libhiprt64.so | Bin 0 -> 586056 bytes hiprt-sys/src/hiprt.rs | 979 + hiprt-sys/src/lib.rs | 84 + level_zero-sys/README | 4 - level_zero-sys/lib/ze_loader.def | Bin 15760 -> 0 bytes level_zero-sys/lib/ze_loader.lib | Bin 77220 -> 0 bytes level_zero-sys/src/lib.rs | 3 - level_zero-sys/src/ze_api.rs | 9948 --------- level_zero/Cargo.toml | 14 - level_zero/README | 1 - level_zero/src/lib.rs | 4 - level_zero/src/ze.rs | 947 - {spirv_tools-sys => miopen-sys}/Cargo.toml | 18 +- miopen-sys/README | 1 + miopen-sys/build.rs | 4 + miopen-sys/src/lib.rs | 3 + miopen-sys/src/miopen.rs | 2991 +++ offline_compiler/Cargo.toml | 21 + offline_compiler/src/main.rs | 305 + optix_base/Cargo.toml | 14 + optix_base/README | 2 + optix_base/include/wrapper.hpp | 2 + optix_base/include/wrapper6.hpp | 6 + optix_base/src/lib.rs | 316 + optix_base/src/optix.rs | 3381 +++ optix_base/src/optix6.rs | 16049 ++++++++++++++ optix_dump/Cargo.toml | 25 + optix_dump/README | 1 + optix_dump/include/wrapper.hpp | 2 + optix_dump/src/eptx.rs | 170 + optix_dump/src/lib.rs | 425 + optix_types/Cargo.toml | 11 + optix_types/src/lib.rs | 2 + process_address_table/Cargo.toml | 20 + process_address_table/src/main.rs | 230 + process_address_table/table.rs | 7963 +++++++ ptx/Cargo.toml | 39 +- ptx/build.rs | 2 +- ptx/lib/.gitattributes | 2 + ptx/lib/cvt.h | 413 + ptx/lib/cvt.py | 279 + ptx/lib/raytracing.cpp | Bin 0 -> 3263 bytes ptx/lib/raytracing.hpp | 1007 + ptx/lib/raytracing_bounding_box.cpp | Bin 0 -> 938 bytes ptx/lib/raytracing_callable.cpp | 10 + ptx/lib/raytracing_intersect.cpp | Bin 0 -> 4526 bytes ptx/lib/zluda_ptx_impl.bc | Bin 0 -> 144764 bytes ptx/lib/zluda_ptx_impl.cl | 146 - ptx/lib/zluda_ptx_impl.cpp | 1490 ++ ptx/lib/zluda_ptx_impl.spv | Bin 49500 -> 0 bytes ptx/lib/zluda_rt_ptx_impl.bc | Bin 0 -> 18996 bytes ptx/lib/zluda_rt_ptx_impl.cpp | 572 + ptx/src/ast.rs | 2844 +-- ptx/src/emit.rs | 3868 ++++ ptx/src/lib.rs | 511 +- ptx/src/llvm.rs | 181 + ptx/src/ptx.lalrpop | 4776 ++-- ptx/src/raytracing.rs | 3906 ++++ ptx/src/test/mod.rs | 13 +- ptx/src/test/ptx_raytracing/closest_hit.cu | 12 + ptx/src/test/ptx_raytracing/closest_hit.ptx | 83 + ...ograms_generated_optixCallablePrograms.ptx | 226 + ...ms_generated_optixCallablePrograms_miss.ll | 342 + .../optixHello_generated_draw_color.ptx | 78 + ...o_generated_draw_color_draw_solid_color.ll | 230 + ...ello_generated_draw_color_var_ptr_cast.ptx | 79 + ...raw_color_var_ptr_cast_draw_solid_color.ll | 232 + .../optixPathTracer_generated_disney.ptx | 622 + .../optixPathTracer_generated_disney_Eval.ll | 1247 ++ .../optixPathTracer_generated_hit_program.ptx | 946 + ...racer_generated_hit_program_closest_hit.ll | 2396 ++ .../optixSphere_generated_normal_shader.ptx | 103 + ...ated_normal_shader_closest_hit_radiance.ll | 252 + .../optixSphere_generated_sphere.ptx | 348 + .../optixSphere_generated_sphere_bounds.ll | 273 + ...phere_generated_sphere_robust_intersect.ll | 639 + ptx/src/test/raytracing.rs | 144 + ptx/src/test/spirv_run/abs.ll | 49 + ptx/src/test/spirv_run/abs.ptx | 25 + ptx/src/test/spirv_run/activemask.ll | 26 + ptx/src/test/spirv_run/activemask.ptx | 18 + ptx/src/test/spirv_run/add.ll | 32 + ptx/src/test/spirv_run/add.ptx | 2 +- ptx/src/test/spirv_run/add.spvtxt | 47 - ptx/src/test/spirv_run/add_global.ll | 37 + ptx/src/test/spirv_run/add_global.ptx | 26 + ptx/src/test/spirv_run/add_non_coherent.ll | 32 + ptx/src/test/spirv_run/add_non_coherent.ptx | 22 + ptx/src/test/spirv_run/add_param_ptr.ll | 48 + ptx/src/test/spirv_run/add_param_ptr.ptx | 25 + ptx/src/test/spirv_run/add_tuning.ll | 32 + ptx/src/test/spirv_run/add_tuning.ptx | 24 + ptx/src/test/spirv_run/addc_cc.ll | 90 + ptx/src/test/spirv_run/addc_cc.ptx | 34 + ptx/src/test/spirv_run/addc_cc2.ll | 68 + ptx/src/test/spirv_run/addc_cc2.ptx | 33 + ptx/src/test/spirv_run/alloca_call.ll | 61 + ptx/src/test/spirv_run/alloca_call.ptx | 43 + ptx/src/test/spirv_run/amdgpu_unnamed.ll | 84 + ptx/src/test/spirv_run/amdgpu_unnamed.ptx | 57 + ptx/src/test/spirv_run/and.ll | 38 + ptx/src/test/spirv_run/and.spvtxt | 58 - ptx/src/test/spirv_run/assertfail.ll | 66 + ptx/src/test/spirv_run/assertfail.spvtxt | 105 - ptx/src/test/spirv_run/atom_add.ll | 48 + ptx/src/test/spirv_run/atom_add.spvtxt | 76 - ptx/src/test/spirv_run/atom_add_f16.ll | 49 + ptx/src/test/spirv_run/atom_add_f16.ptx | 25 + ptx/src/test/spirv_run/atom_add_float.ll | 48 + ptx/src/test/spirv_run/atom_add_float.ptx | 28 + ptx/src/test/spirv_run/atom_cas.ll | 46 + ptx/src/test/spirv_run/atom_cas.spvtxt | 69 - ptx/src/test/spirv_run/atom_inc.ll | 53 + ptx/src/test/spirv_run/atom_inc.spvtxt | 81 - ptx/src/test/spirv_run/atom_ld_st.ll | 28 + ptx/src/test/spirv_run/atom_ld_st.ptx | 19 + ptx/src/test/spirv_run/atom_ld_st_vec.ll | 37 + ptx/src/test/spirv_run/atom_ld_st_vec.ptx | 20 + ptx/src/test/spirv_run/atom_max_u32.ll | 39 + ptx/src/test/spirv_run/atom_max_u32.ptx | 23 + ptx/src/test/spirv_run/b64tof64.ll | 35 + ptx/src/test/spirv_run/b64tof64.spvtxt | 50 - ptx/src/test/spirv_run/barrier.ll | 17 + ptx/src/test/spirv_run/barrier.ptx | 9 + ptx/src/test/spirv_run/bfe.ll | 48 + ptx/src/test/spirv_run/bfe.spvtxt | 70 - ptx/src/test/spirv_run/bfi.ll | 55 + ptx/src/test/spirv_run/bfi.ptx | 24 + ptx/src/test/spirv_run/bfind.ll | 75 + ptx/src/test/spirv_run/bfind.ptx | 27 + ptx/src/test/spirv_run/bfind_shiftamt.ll | 72 + ptx/src/test/spirv_run/bfind_shiftamt.ptx | 27 + ptx/src/test/spirv_run/block.ll | 36 + ptx/src/test/spirv_run/block.spvtxt | 52 - ptx/src/test/spirv_run/bra.ll | 44 + ptx/src/test/spirv_run/bra.spvtxt | 57 - ptx/src/test/spirv_run/brev.ll | 35 + ptx/src/test/spirv_run/brev.spvtxt | 47 - ptx/src/test/spirv_run/call.ll | 64 + ptx/src/test/spirv_run/call.ptx | 4 +- ptx/src/test/spirv_run/call.spvtxt | 67 - ptx/src/test/spirv_run/call_bug.ll | 69 + ptx/src/test/spirv_run/call_bug.ptx | 40 + ptx/src/test/spirv_run/call_multi_return.ll | 85 + ptx/src/test/spirv_run/call_multi_return.ptx | 46 + ptx/src/test/spirv_run/callprototype.ll | 68 + ptx/src/test/spirv_run/callprototype.ptx | 41 + ptx/src/test/spirv_run/carry_mixed.ll | 51 + ptx/src/test/spirv_run/carry_mixed.ptx | 32 + ptx/src/test/spirv_run/clz.ll | 35 + ptx/src/test/spirv_run/clz.spvtxt | 47 - ptx/src/test/spirv_run/const.ll | 52 + ptx/src/test/spirv_run/const.ptx | 31 + ptx/src/test/spirv_run/constant_f32.ll | 31 + ptx/src/test/spirv_run/constant_f32.spvtxt | 48 - ptx/src/test/spirv_run/constant_negative.ll | 31 + .../test/spirv_run/constant_negative.spvtxt | 48 - ptx/src/test/spirv_run/cos.ll | 35 + ptx/src/test/spirv_run/cos.spvtxt | 47 - ptx/src/test/spirv_run/cvt_clamp.ll | 73 + ptx/src/test/spirv_run/cvt_clamp.ptx | 30 + ptx/src/test/spirv_run/cvt_f32_f16.ll | 33 + ptx/src/test/spirv_run/cvt_f32_f16.ptx | 22 + ptx/src/test/spirv_run/cvt_f32_s32.ll | 90 + ptx/src/test/spirv_run/cvt_f32_s32.ptx | 33 + ptx/src/test/spirv_run/cvt_f64_f32.ll | 32 + ptx/src/test/spirv_run/cvt_f64_f32.ptx | 22 + ptx/src/test/spirv_run/cvt_rni.ll | 49 + ptx/src/test/spirv_run/cvt_rni.spvtxt | 63 - ptx/src/test/spirv_run/cvt_rzi.ll | 49 + ptx/src/test/spirv_run/cvt_rzi.spvtxt | 63 - ptx/src/test/spirv_run/cvt_s16_s8.ll | 34 + ptx/src/test/spirv_run/cvt_s16_s8.ptx | 26 + ptx/src/test/spirv_run/cvt_s32_f32.ll | 52 + ptx/src/test/spirv_run/cvt_s32_f32.spvtxt | 75 - ptx/src/test/spirv_run/cvt_s64_s32.ll | 32 + ptx/src/test/spirv_run/cvt_s64_s32.spvtxt | 53 - ptx/src/test/spirv_run/cvt_sat_s_u.ll | 55 + ptx/src/test/spirv_run/cvt_sat_s_u.ptx | 16 +- ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt | 52 - ptx/src/test/spirv_run/cvt_u32_s16.ll | 32 + ptx/src/test/spirv_run/cvt_u32_s16.ptx | 22 + ptx/src/test/spirv_run/cvta.ll | 38 + ptx/src/test/spirv_run/cvta.spvtxt | 65 - ptx/src/test/spirv_run/div_approx.ll | 38 + ptx/src/test/spirv_run/div_approx.spvtxt | 56 - ptx/src/test/spirv_run/dp4a.ll | 48 + ptx/src/test/spirv_run/dp4a.ptx | 25 + ptx/src/test/spirv_run/ex2.ll | 74 + ptx/src/test/spirv_run/ex2.ptx | 10 + ptx/src/test/spirv_run/ex2.spvtxt | 47 - ptx/src/test/spirv_run/extern_shared.ll | 34 + ptx/src/test/spirv_run/extern_shared.spvtxt | 66 - ptx/src/test/spirv_run/extern_shared_call.ll | 52 + .../test/spirv_run/extern_shared_call.spvtxt | 93 - ptx/src/test/spirv_run/fma.ll | 49 + ptx/src/test/spirv_run/fma.spvtxt | 63 - ptx/src/test/spirv_run/func_ptr.ll | 57 + ptx/src/test/spirv_run/func_ptr.ptx | 31 + ptx/src/test/spirv_run/generic.ll | 70 + ptx/src/test/spirv_run/generic.ptx | 40 + ptx/src/test/spirv_run/global_array.ll | 33 + ptx/src/test/spirv_run/global_array.ptx | 3 +- ptx/src/test/spirv_run/global_array.spvtxt | 53 - ptx/src/test/spirv_run/implicit_param.ll | 55 + ptx/src/test/spirv_run/implicit_param.spvtxt | 53 - ptx/src/test/spirv_run/laneid.ptx | 24 + ptx/src/test/spirv_run/lanemask_lt.ll | 45 + ptx/src/test/spirv_run/lanemask_lt.ptx | 25 + ptx/src/test/spirv_run/ld_st.ll | 28 + ptx/src/test/spirv_run/ld_st.spvtxt | 42 - ptx/src/test/spirv_run/ld_st_implicit.ll | 36 + ptx/src/test/spirv_run/ld_st_implicit.ptx | 5 +- ptx/src/test/spirv_run/ld_st_implicit.spvtxt | 49 - ptx/src/test/spirv_run/ld_st_offset.ll | 39 + ptx/src/test/spirv_run/ld_st_offset.spvtxt | 57 - ptx/src/test/spirv_run/lg2.ll | 35 + ptx/src/test/spirv_run/lg2.spvtxt | 47 - ptx/src/test/spirv_run/local_align.ll | 29 + ptx/src/test/spirv_run/local_align.spvtxt | 49 - ptx/src/test/spirv_run/mad_s32.ll | 83 + ptx/src/test/spirv_run/mad_s32.ptx | 24 +- ptx/src/test/spirv_run/mad_s32.spvtxt | 77 - ptx/src/test/spirv_run/madc_cc.ll | 72 + ptx/src/test/spirv_run/madc_cc.ptx | 29 + ptx/src/test/spirv_run/madc_cc2.ll | 73 + ptx/src/test/spirv_run/madc_cc2.ptx | 38 + ptx/src/test/spirv_run/match_any_32.ptx | 32 + ptx/src/test/spirv_run/max.ll | 42 + ptx/src/test/spirv_run/max.spvtxt | 55 - ptx/src/test/spirv_run/membar.ll | 29 + .../test/spirv_run/{shr.ptx => membar.ptx} | 6 +- ptx/src/test/spirv_run/min.ll | 42 + ptx/src/test/spirv_run/min.spvtxt | 55 - ptx/src/test/spirv_run/mod.rs | 952 +- ptx/src/test/spirv_run/mov.ll | 34 + ptx/src/test/spirv_run/mov.spvtxt | 46 - ptx/src/test/spirv_run/mov_address.ll | 20 + ptx/src/test/spirv_run/mov_address.spvtxt | 33 - ptx/src/test/spirv_run/mov_vector_cast.ll | 67 + ptx/src/test/spirv_run/mov_vector_cast.ptx | 30 + ptx/src/test/spirv_run/mul_ftz.ll | 38 + ptx/src/test/spirv_run/mul_ftz.spvtxt | 55 - ptx/src/test/spirv_run/mul_hi.ll | 35 + ptx/src/test/spirv_run/mul_hi.spvtxt | 47 - ptx/src/test/spirv_run/mul_lo.ll | 32 + ptx/src/test/spirv_run/mul_lo.spvtxt | 47 - ptx/src/test/spirv_run/mul_non_ftz.ll | 38 + ptx/src/test/spirv_run/mul_non_ftz.spvtxt | 55 - ptx/src/test/spirv_run/mul_wide.ll | 41 + ptx/src/test/spirv_run/mul_wide.spvtxt | 64 - ptx/src/test/spirv_run/multireg.ll | 32 + ptx/src/test/spirv_run/multireg.ptx | 19 + ptx/src/test/spirv_run/neg.ll | 31 + ptx/src/test/spirv_run/neg.spvtxt | 47 - .../test/spirv_run/non_scalar_ptr_offset.ll | 37 + .../test/spirv_run/non_scalar_ptr_offset.ptx | 22 + ptx/src/test/spirv_run/not.ll | 32 + ptx/src/test/spirv_run/not.spvtxt | 48 - ptx/src/test/spirv_run/ntid.ll | 41 + ptx/src/test/spirv_run/ntid.spvtxt | 59 - ptx/src/test/spirv_run/or.ll | 38 + ptx/src/test/spirv_run/or.spvtxt | 56 - ptx/src/test/spirv_run/param_ptr.ll | 40 + ptx/src/test/spirv_run/param_ptr.ptx | 25 + ptx/src/test/spirv_run/popc.ll | 35 + ptx/src/test/spirv_run/popc.spvtxt | 47 - ptx/src/test/spirv_run/pred_not.ll | 65 + ptx/src/test/spirv_run/pred_not.spvtxt | 78 - ptx/src/test/spirv_run/prmt.ll | 41 + ptx/src/test/spirv_run/prmt.ptx | 23 + ptx/src/test/spirv_run/prmt_non_immediate.ll | 46 + ptx/src/test/spirv_run/prmt_non_immediate.ptx | 25 + ptx/src/test/spirv_run/rcp.ll | 31 + ptx/src/test/spirv_run/rcp.spvtxt | 49 - ptx/src/test/spirv_run/red_shared.ptx | 39 + ptx/src/test/spirv_run/reg_local.ll | 38 + ptx/src/test/spirv_run/reg_local.spvtxt | 69 - ptx/src/test/spirv_run/rem.ll | 38 + ptx/src/test/spirv_run/rem.spvtxt | 55 - ptx/src/test/spirv_run/rsqrt.ll | 36 + ptx/src/test/spirv_run/rsqrt.spvtxt | 47 - ptx/src/test/spirv_run/s64_min.ll | 25 + ptx/src/test/spirv_run/s64_min.ptx | 17 + ptx/src/test/spirv_run/selp.ll | 38 + ptx/src/test/spirv_run/selp.spvtxt | 57 - ptx/src/test/spirv_run/selp_true.ll | 38 + ptx/src/test/spirv_run/selp_true.spvtxt | 57 - ptx/src/test/spirv_run/setp.ll | 62 + ptx/src/test/spirv_run/setp.spvtxt | 73 - ptx/src/test/spirv_run/setp_bool.ll | 80 + ptx/src/test/spirv_run/setp_bool.ptx | 31 + ptx/src/test/spirv_run/setp_gt.ll | 64 + ptx/src/test/spirv_run/setp_gt.spvtxt | 75 - ptx/src/test/spirv_run/setp_leu.ll | 64 + ptx/src/test/spirv_run/setp_leu.spvtxt | 75 - ptx/src/test/spirv_run/setp_nan.ll | 191 + ptx/src/test/spirv_run/setp_nan.ptx | 51 + ptx/src/test/spirv_run/setp_num.ll | 191 + ptx/src/test/spirv_run/setp_num.ptx | 51 + ptx/src/test/spirv_run/setp_pred2.ll | 67 + ptx/src/test/spirv_run/setp_pred2.ptx | 28 + ptx/src/test/spirv_run/shared_ptr_32.ll | 45 + ptx/src/test/spirv_run/shared_ptr_32.spvtxt | 66 - .../test/spirv_run/shared_ptr_take_address.ll | 44 + .../spirv_run/shared_ptr_take_address.spvtxt | 68 - ptx/src/test/spirv_run/shared_unify_decl.ll | 80 + ptx/src/test/spirv_run/shared_unify_decl.ptx | 47 + ptx/src/test/spirv_run/shared_unify_extern.ll | 80 + .../test/spirv_run/shared_unify_extern.ptx | 47 + ptx/src/test/spirv_run/shared_unify_local.ll | 85 + ptx/src/test/spirv_run/shared_unify_local.ptx | 43 + ptx/src/test/spirv_run/shared_variable.ll | 35 + ptx/src/test/spirv_run/shared_variable.spvtxt | 57 - ptx/src/test/spirv_run/shf.ll | 43 + ptx/src/test/spirv_run/shf.ptx | 24 + ptx/src/test/spirv_run/shfl.ptx | 22 + ptx/src/test/spirv_run/shl.ll | 33 + ptx/src/test/spirv_run/shl.spvtxt | 51 - ptx/src/test/spirv_run/shl_link_hack.ll | 41 + ptx/src/test/spirv_run/shl_link_hack.spvtxt | 65 - ptx/src/test/spirv_run/shl_overflow.ll | 75 + ptx/src/test/spirv_run/shl_overflow.ptx | 32 + ptx/src/test/spirv_run/shr.spvtxt | 48 - ptx/src/test/spirv_run/shr_s32.ll | 40 + ptx/src/test/spirv_run/shr_s32.ptx | 23 + ptx/src/test/spirv_run/shr_u32.ll | 59 + ptx/src/test/spirv_run/shr_u32.ptx | 31 + ptx/src/test/spirv_run/sign_extend.ll | 29 + ptx/src/test/spirv_run/sign_extend.ptx | 20 + ptx/src/test/spirv_run/sin.ll | 35 + ptx/src/test/spirv_run/sin.spvtxt | 47 - ptx/src/test/spirv_run/sqrt.ll | 35 + ptx/src/test/spirv_run/sqrt.spvtxt | 47 - ptx/src/test/spirv_run/st_f16x2.ll | 43 + ptx/src/test/spirv_run/st_f16x2.ptx | 24 + .../test/spirv_run/stateful_ld_st_ntid.ptx | 31 - .../test/spirv_run/stateful_ld_st_ntid.spvtxt | 91 - .../spirv_run/stateful_ld_st_ntid_chain.ptx | 35 - .../stateful_ld_st_ntid_chain.spvtxt | 95 - .../spirv_run/stateful_ld_st_ntid_sub.ptx | 35 - .../spirv_run/stateful_ld_st_ntid_sub.spvtxt | 107 - .../test/spirv_run/stateful_ld_st_simple.ptx | 25 - .../spirv_run/stateful_ld_st_simple.spvtxt | 65 - ptx/src/test/spirv_run/sub.ll | 32 + ptx/src/test/spirv_run/sub.spvtxt | 47 - ptx/src/test/spirv_run/subc_cc.ll | 90 + ptx/src/test/spirv_run/subc_cc.ptx | 34 + ptx/src/test/spirv_run/subc_cc2.ll | 127 + ptx/src/test/spirv_run/subc_cc2.ptx | 55 + ptx/src/test/spirv_run/vector.ll | 96 + ptx/src/test/spirv_run/vector.spvtxt | 99 - ptx/src/test/spirv_run/vector4.ll | 35 + ptx/src/test/spirv_run/vector4.ptx | 22 + ptx/src/test/spirv_run/vector_extract.ll | 97 + ptx/src/test/spirv_run/vector_extract.spvtxt | 125 - ptx/src/test/spirv_run/verify.py | 21 + ptx/src/test/spirv_run/vote_ballot.ll | 52 + ptx/src/test/spirv_run/vote_ballot.ptx | 29 + ptx/src/test/spirv_run/vshr.ll | 49 + ptx/src/test/spirv_run/vshr.ptx | 27 + ptx/src/test/spirv_run/xor.ll | 38 + ptx/src/test/spirv_run/xor.spvtxt | 55 - ptx/src/translate.rs | 13008 ++++++----- rocblas-sys/Cargo.toml | 8 + rocblas-sys/README | 1 + rocblas-sys/build.rs | 4 + rocblas-sys/src/lib.rs | 3 + rocblas-sys/src/rocblas.rs | 10099 +++++++++ rocm_smi-sys/Cargo.toml | 8 + rocm_smi-sys/README | 1 + rocm_smi-sys/build.rs | 4 + rocm_smi-sys/src/lib.rs | 5 + rocm_smi-sys/src/rocm_smi.rs | 1720 ++ rocsolver-sys/Cargo.toml | 8 + rocsolver-sys/README | 1 + rocsolver-sys/build.rs | 4 + rocsolver-sys/src/lib.rs | 3 + rocsolver-sys/src/rocsolver.rs | 11506 ++++++++++ rocsparse-sys/Cargo.toml | 8 + rocsparse-sys/README | 1 + rocsparse-sys/build.rs | 4 + rocsparse-sys/src/lib.rs | 3 + rocsparse-sys/src/rocsparse.rs | 10631 +++++++++ spirv_tools-sys/README | 1 - spirv_tools-sys/build.rs | 28 - spirv_tools-sys/src/lib.rs | 3 - spirv_tools-sys/src/spirv_tools.rs | 972 - xtask/Cargo.toml | 14 + xtask/src/main.rs | 281 + zluda/Cargo.toml | 40 +- zluda/README | 2 +- zluda/build.rs | 23 +- zluda/lib/OpenCL.lib | Bin 28824 -> 0 bytes zluda/src/cuda.rs | 6263 ++---- zluda/src/cuda_impl/mod.rs | 1 - zluda/src/cuda_impl/rt.rs | 2 - zluda/src/impl/array.rs | 83 + zluda/src/impl/cache.rs | 82 + zluda/src/impl/context.rs | 485 +- zluda/src/impl/dark_api.rs | 399 + zluda/src/impl/device.rs | 977 +- zluda/src/impl/empty_module.ptx | 3 + zluda/src/impl/export_table.rs | 398 - zluda/src/impl/function.rs | 343 +- zluda/src/impl/gl.rs | 43 + zluda/src/impl/graph.rs | 57 + zluda/src/impl/hipfix.rs | 377 + zluda/src/impl/library.rs | 90 + zluda/src/impl/link.rs | 112 + zluda/src/impl/memory.rs | 318 +- zluda/src/impl/mod.rs | 765 +- zluda/src/impl/module.rs | 617 +- zluda/src/impl/os_unix.rs | 26 + zluda/src/impl/os_win.rs | 7 + zluda/src/impl/pointer.rs | 142 + zluda/src/impl/stream.rs | 437 +- zluda/src/impl/surface.rs | 117 + zluda/src/impl/surfref.rs | 23 + zluda/src/impl/test.rs | 157 - zluda/src/impl/texobj.rs | 19 + zluda/src/impl/texref.rs | 263 + zluda/src/lib.rs | 39 +- zluda/tests/bfi.ptx | 34 + zluda/tests/bfi.rs | 173 + zluda/tests/common.rs | 128 + .../context_dark_api_primary_is_unretained.rs | 84 + .../context_destroy_also_destroys_stream.rs | 26 + zluda/tests/context_destroy_leaves_zombie.rs | 54 + .../context_destroy_pops_top_of_stack.rs | 33 + zluda/tests/context_double_destroy_fails.rs | 23 + zluda/tests/context_empty_pop_fails.rs | 16 + zluda/tests/context_no_current_on_init.rs | 14 + .../context_push_invalid_should_crash.rs | 15 + zluda/tests/function_version.ptx | 5 + zluda/tests/function_version.rs | 67 + zluda/tests/kernel_args_align.ptx | 25 + zluda/tests/kernel_args_align.rs | 81 + zluda/tests/kernel_extra.ptx | 22 + zluda/tests/kernel_extra.rs | 70 + zluda/tests/kernel_suld.ptx | 36 + zluda/tests/kernel_suld.rs | 479 + zluda/tests/kernel_sust.ptx | 31 + zluda/tests/kernel_sust.rs | 464 + zluda/tests/kernel_tex.ptx | 34 + zluda/tests/kernel_tex.rs | 666 + zluda/tests/kernel_texobj_2d.ptx | 34 + zluda/tests/kernel_texobj_2d.rs | 166 + zluda/tests/kernel_texref_1d.ptx | 30 + zluda/tests/kernel_texref_1d.rs | 108 + zluda/tests/kernel_texref_2d.ptx | 33 + zluda/tests/kernel_texref_2d.rs | 138 + zluda/tests/kernel_unused_global.ptx | 12 + zluda/tests/kernel_unused_global.rs | 49 + zluda/tests/linking.rs | 1109 + zluda/tests/llama.bin | Bin 0 -> 388 bytes zluda/tests/llama.ptx | 102 + zluda/tests/llama.rs | 84 + zluda/tests/maxntid.ptx | 23 + zluda/tests/maxntid.rs | 36 + zluda/tests/memcpy_pitch.rs | 147 + .../module_texrefs_have_correct_format.rs | 35 + zluda/tests/shuffle.ptx | 34 + zluda/tests/shuffle.rs | 191 + zluda/tests/stream_can_destroy.rs | 21 + zluda/tests/stream_cant_destroy_default.rs | 22 + zluda/tests/stream_context_destroyed.rs | 45 + .../stream_default_uses_current_ctx_impl.rs | 46 + .../stream_moves_context_to_another_thread.rs | 42 + zluda_api/Cargo.toml | 28 + zluda_api/README | 1 + zluda_api/src/lib.rs | 301 + zluda_api/src/nvapi.rs | 18348 ++++++++++++++++ zluda_api/src/nvapi_wrapper.h | 14 + zluda_blas/Cargo.toml | 21 + zluda_blas/README | 2 + zluda_blas/build/wrapper.h | 2 + zluda_blas/src/cublas.rs | 6870 ++++++ zluda_blas/src/lib.rs | 918 + zluda_blaslt/Cargo.toml | 20 + zluda_blaslt/README | 2 + zluda_blaslt/src/cublaslt.rs | 5372 +++++ zluda_blaslt/src/lib.rs | 313 + zluda_ccl/Cargo.toml | 16 + zluda_ccl/README | 2 + zluda_ccl/src/lib.rs | 13 + zluda_ccl/src/nccl.rs | 666 + zluda_dark_api/Cargo.toml | 19 + zluda_dark_api/src/lib.rs | 1165 + zluda_dnn/Cargo.toml | 18 + zluda_dnn/README | 6 + zluda_dnn/build/cudnn_adv_infer.h | 1 + zluda_dnn/build/cudnn_adv_train.h | 1 + zluda_dnn/build/cudnn_backend.h | 1 + zluda_dnn/build/cudnn_cnn_infer.h | 1 + zluda_dnn/build/cudnn_cnn_train.h | 1 + zluda_dnn/build/cudnn_ops_infer.h | 1 + zluda_dnn/build/cudnn_ops_train.h | 1 + zluda_dnn/build/cudnn_version.h | 1 + zluda_dnn/src/cudnn_types_v7.rs | 47 + zluda_dnn/src/cudnn_types_v8.rs | 2813 +++ zluda_dnn/src/cudnn_v7.rs | 91 + zluda_dnn/src/cudnn_v8.rs | 3468 +++ zluda_dnn/src/lib.rs | 1101 + zluda_dump/Cargo.toml | 26 +- zluda_dump/README.md | 3 + zluda_dump/src/dark_api.rs | 934 + zluda_dump/src/debug.ptx | 55 + zluda_dump/src/events_to_csv.py | 24 + zluda_dump/src/format.rs | 961 + zluda_dump/src/lib.rs | 1700 +- zluda_dump/src/log.rs | 793 + zluda_dump/src/os_unix.rs | 76 +- zluda_dump/src/os_win.rs | 221 +- zluda_dump/src/profiler.rs | 447 + zluda_dump/src/replay.py | 202 +- zluda_dump/src/side_by_side.rs | 1297 ++ zluda_dump/src/trace.rs | 740 + zluda_fft/Cargo.toml | 22 + zluda_fft/README | 4 + zluda_fft/src/cufft.rs | 474 + zluda_fft/src/cufftxt.rs | 446 + zluda_fft/src/lib.rs | 253 + zluda_inject/Cargo.toml | 18 +- zluda_inject/build.rs | 96 + zluda_inject/src/bin.rs | 326 +- zluda_inject/tests/helpers/direct_cuinit.rs | 9 + zluda_inject/tests/helpers/do_cuinit.rs | 10 + zluda_inject/tests/helpers/do_cuinit_early.rs | 10 + zluda_inject/tests/helpers/do_cuinit_late.rs | 23 + .../tests/helpers/do_cuinit_late_clr.cs | 34 + .../tests/helpers/do_cuinit_late_clr.exe | Bin 0 -> 4608 bytes zluda_inject/tests/helpers/indirect_cuinit.rs | 16 + zluda_inject/tests/helpers/nvcuda.lib | Bin 0 -> 71050 bytes zluda_inject/tests/helpers/query_exe.rs | 11 + zluda_inject/tests/helpers/subprocess.rs | 10 + zluda_inject/tests/inject.rs | 67 + zluda_lib/Cargo.toml | 4 + zluda_lib/src/lib.rs | 2 +- zluda_llvm/Cargo.toml | 11 + zluda_llvm/README.md | 8 + zluda_llvm/build.rs | 15 + zluda_llvm/src/lib.cpp | 161 + zluda_llvm/src/lib.rs | 67 + zluda_ml/Cargo.toml | 19 + zluda_ml/README | 3 + zluda_ml/src/common.rs | 160 + zluda_ml/src/lib.rs | 6 + zluda_ml/src/nvml.rs | 4966 +++++ zluda_ml/src/unix.rs | 246 + zluda_ml/src/windows.rs | 446 + zluda_redirect/Cargo.toml | 6 +- zluda_redirect/src/lib.rs | 1022 +- zluda_redirect/src/payload_guid.rs | 29 +- zluda_rt/Cargo.toml | 47 + zluda_rt/bin/liboptix.so.6.5.0 | Bin 0 -> 1004520 bytes zluda_rt/bin/optix.6.5.0.dll | Bin 0 -> 203248 bytes zluda_rt/build.rs | 5 + zluda_rt/optix.xmi | 325 + zluda_rt/src/acceleration.rs | 139 + zluda_rt/src/buffer.rs | 972 + zluda_rt/src/cache.rs | 281 + zluda_rt/src/context.rs | 698 + zluda_rt/src/eptx.rs | 109 + zluda_rt/src/geometry.rs | 147 + zluda_rt/src/geometry_group.rs | 316 + zluda_rt/src/geometry_instance.rs | 411 + zluda_rt/src/geometry_triangles.rs | 269 + zluda_rt/src/group.rs | 411 + zluda_rt/src/hip.rs | 103 + zluda_rt/src/lib.rs | 1884 ++ zluda_rt/src/material.rs | 142 + zluda_rt/src/program.rs | 720 + zluda_rt/src/repr_gpu.rs | 1320 ++ zluda_rt/src/test_common.rs | 125 + zluda_rt/src/tests/alloca_bug.cu | 22 + zluda_rt/src/tests/alloca_bug.ptx | 126 + zluda_rt/src/tests/any_hit_intersect.cu | 78 + zluda_rt/src/tests/any_hit_intersect.ptx | 271 + zluda_rt/src/tests/barycentrics.cu | 84 + zluda_rt/src/tests/barycentrics.ptx | 297 + zluda_rt/src/tests/buffer_id.cu | 13 + zluda_rt/src/tests/buffer_id.ptx | 80 + zluda_rt/src/tests/buffer_id_call.cu | 23 + zluda_rt/src/tests/buffer_id_call.ptx | 112 + zluda_rt/src/tests/buffer_id_callable.cu | 18 + zluda_rt/src/tests/buffer_id_callable.ptx | 110 + zluda_rt/src/tests/buffer_mipmap.cu | 17 + zluda_rt/src/tests/buffer_mipmap.ptx | 89 + zluda_rt/src/tests/callable_programs.cu | 28 + zluda_rt/src/tests/callable_programs.ptx | 152 + zluda_rt/src/tests/default_variable.cu | 13 + zluda_rt/src/tests/default_variable.ptx | 65 + zluda_rt/src/tests/exception.cu | 50 + zluda_rt/src/tests/exception.ptx | 294 + zluda_rt/src/tests/exception_subfunc.cu | 28 + zluda_rt/src/tests/exception_subfunc.ptx | 148 + zluda_rt/src/tests/get_transform.cu | 80 + zluda_rt/src/tests/get_transform.ptx | 368 + zluda_rt/src/tests/mod.rs | 1648 ++ zluda_rt/src/tests/oob.cu | 16 + zluda_rt/src/tests/oob.ptx | 98 + zluda_rt/src/tests/texture_sampler.cu | 21 + zluda_rt/src/tests/texture_sampler.ptx | 119 + zluda_rt/src/tests/trace_control.cu | 121 + zluda_rt/src/tests/trace_control.ptx | 442 + zluda_rt/src/tests/transform.cu | 92 + zluda_rt/src/tests/transform.ptx | 462 + zluda_rt/src/tests/triangle_front.cu | 76 + zluda_rt/src/tests/triangle_front.ptx | 280 + zluda_rt/src/texture_sampler.rs | 411 + zluda_rt/src/transform.rs | 196 + zluda_rt/src/variable.rs | 237 + zluda_sparse/Cargo.toml | 21 + zluda_sparse/README | 2 + zluda_sparse/src/cusparse.rs | 8870 ++++++++ zluda_sparse/src/lib.rs | 1289 ++ 762 files changed, 252358 insertions(+), 39368 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/Dockerfile-common create mode 100644 .devcontainer/Dockerfile-el8_8 create mode 100644 .devcontainer/Dockerfile-xgboost create mode 100644 .devcontainer/devcontainer.json create mode 100644 .gitattributes delete mode 100644 .github/workflows/rust.yml create mode 100644 ARCHITECTURE.md delete mode 100644 CONTRIBUTING.md delete mode 100644 GeekBench_5_2_3.svg create mode 100644 Makefile.toml create mode 100644 atiadlxx-sys/Cargo.toml create mode 100644 atiadlxx-sys/README create mode 100644 atiadlxx-sys/build.rs create mode 100644 atiadlxx-sys/include/adapter.h create mode 100644 atiadlxx-sys/include/adl.h create mode 100644 atiadlxx-sys/include/adl_defines.h create mode 100644 atiadlxx-sys/include/adl_sdk.h create mode 100644 atiadlxx-sys/include/adl_structures.h create mode 100644 atiadlxx-sys/include/display.h create mode 100644 atiadlxx-sys/include/overdrive5.h create mode 100644 atiadlxx-sys/include/overdrive6.h create mode 100644 atiadlxx-sys/include/overdrive8.h create mode 100644 atiadlxx-sys/include/overdriveN.h create mode 100644 atiadlxx-sys/include/wrapper.hpp create mode 100644 atiadlxx-sys/lib/atiadlxx.def create mode 100644 atiadlxx-sys/lib/atiadlxx.lib create mode 100644 atiadlxx-sys/src/adl.rs create mode 100644 atiadlxx-sys/src/lib.rs create mode 100644 comgr/Cargo.toml create mode 100644 comgr/README create mode 100644 comgr/include/amd_comgr.h create mode 100644 comgr/src/amd_comgr.rs create mode 100644 comgr/src/double_wave32_on_wave64.ll create mode 100644 comgr/src/lib.rs create mode 100644 comgr/src/linux.ll create mode 100644 comgr/src/wave32.ll create mode 100644 comgr/src/wave32_on_wave64.ll create mode 100644 comgr/src/windows.ll create mode 100644 cuda_base/Cargo.toml create mode 100644 cuda_base/README create mode 100644 cuda_base/build/wrapper.h rename {zluda_dump => cuda_base}/src/cuda.rs (51%) create mode 100644 cuda_base/src/lib.rs create mode 100644 cuda_types/Cargo.toml create mode 100644 cuda_types/src/lib.rs create mode 160000 ext/llvm-project create mode 100644 ext/llvm-sys.rs/.gitignore create mode 100644 ext/llvm-sys.rs/.gitlab-ci.yml create mode 100644 ext/llvm-sys.rs/Cargo.toml create mode 100644 ext/llvm-sys.rs/LICENSE create mode 100644 ext/llvm-sys.rs/README.md create mode 100644 ext/llvm-sys.rs/appveyor.yml create mode 100644 ext/llvm-sys.rs/build.cmake create mode 100644 ext/llvm-sys.rs/build.rs create mode 100644 ext/llvm-sys.rs/scripts/RELEASE_CHECKLIST.md create mode 100644 ext/llvm-sys.rs/scripts/build-binaries.sh create mode 100644 ext/llvm-sys.rs/src/analysis.rs create mode 100644 ext/llvm-sys.rs/src/bit_reader.rs create mode 100644 ext/llvm-sys.rs/src/bit_writer.rs create mode 100644 ext/llvm-sys.rs/src/blake3.rs create mode 100644 ext/llvm-sys.rs/src/comdat.rs create mode 100644 ext/llvm-sys.rs/src/core.rs create mode 100644 ext/llvm-sys.rs/src/debuginfo.rs create mode 100644 ext/llvm-sys.rs/src/disassembler.rs create mode 100644 ext/llvm-sys.rs/src/error.rs create mode 100644 ext/llvm-sys.rs/src/error_handling.rs create mode 100644 ext/llvm-sys.rs/src/execution_engine.rs create mode 100644 ext/llvm-sys.rs/src/initialization.rs create mode 100644 ext/llvm-sys.rs/src/ir_reader.rs create mode 100644 ext/llvm-sys.rs/src/lib.rs create mode 100644 ext/llvm-sys.rs/src/linker.rs create mode 100644 ext/llvm-sys.rs/src/lto.rs create mode 100644 ext/llvm-sys.rs/src/object.rs create mode 100644 ext/llvm-sys.rs/src/orc2/ee.rs create mode 100644 ext/llvm-sys.rs/src/orc2/lljit.rs create mode 100644 ext/llvm-sys.rs/src/orc2/mod.rs create mode 100644 ext/llvm-sys.rs/src/remarks.rs create mode 100644 ext/llvm-sys.rs/src/support.rs create mode 100644 ext/llvm-sys.rs/src/target.rs create mode 100644 ext/llvm-sys.rs/src/target_machine.rs create mode 100644 ext/llvm-sys.rs/src/transforms.rs create mode 100644 ext/llvm-sys.rs/src/transforms/aggressive_instcombine.rs create mode 100644 ext/llvm-sys.rs/src/transforms/instcombine.rs create mode 100644 ext/llvm-sys.rs/src/transforms/ipo.rs create mode 100644 ext/llvm-sys.rs/src/transforms/pass_builder.rs create mode 100644 ext/llvm-sys.rs/src/transforms/pass_manager_builder.rs create mode 100644 ext/llvm-sys.rs/src/transforms/scalar.rs create mode 100644 ext/llvm-sys.rs/src/transforms/util.rs create mode 100644 ext/llvm-sys.rs/src/transforms/vectorize.rs create mode 100644 ext/llvm-sys.rs/wrappers/target.c create mode 100644 ext/optix_ext/README.md create mode 100644 ext/optix_ext/optix_ext_compile_no_inline.h create mode 100644 ext/optix_ext/optix_ext_compile_no_inline_function_table_definition.h create mode 100644 ext/optix_ext/optix_ext_compile_no_inline_stubs.h create mode 100644 ext/optix_ext/optix_ext_knobs.h create mode 100644 ext/optix_ext/optix_ext_knobs_function_table_definition.h create mode 100644 ext/optix_ext/optix_ext_knobs_stubs.h create mode 100644 ext/optix_ext/optix_ext_ptx_encryption.h create mode 100644 ext/optix_ext/optix_ext_ptx_encryption_function_table_definition.h create mode 100644 ext/optix_ext/optix_ext_ptx_encryption_stubs.h create mode 100644 ext/optix_ext/optix_ptx_encryption.h delete mode 160000 ext/spirv-headers delete mode 160000 ext/spirv-tools create mode 100644 geekbench.svg create mode 100644 hip_common/Cargo.toml create mode 100644 hip_common/src/cache.rs create mode 100644 hip_common/src/kernel_metadata.rs create mode 100644 hip_common/src/lib.rs create mode 100644 hip_common/src/raytracing.rs create mode 100644 hip_common/src/zluda.capnp create mode 100644 hip_common/src/zluda_capnp.rs create mode 100644 hip_common/src/zluda_ext.rs create mode 100644 hip_common/src/zluda_rt6.capnp create mode 100644 hip_common/src/zluda_rt6_capnp.rs create mode 100644 hip_runtime-sys/Cargo.toml create mode 100644 hip_runtime-sys/Makefile.toml create mode 100644 hip_runtime-sys/README rename {level_zero-sys => hip_runtime-sys}/build.rs (69%) create mode 100644 hip_runtime-sys/include/hip_runtime_api.h create mode 100644 hip_runtime-sys/lib/amdhip64.def create mode 100644 hip_runtime-sys/lib/amdhip64.lib create mode 100644 hip_runtime-sys/src/hip_runtime_api.rs create mode 100644 hip_runtime-sys/src/lib.rs rename {level_zero-sys => hipblaslt-sys}/Cargo.toml (55%) create mode 100644 hipblaslt-sys/README create mode 100644 hipblaslt-sys/build.rs create mode 100644 hipblaslt-sys/src/hipblaslt.rs create mode 100644 hipblaslt-sys/src/lib.rs create mode 100644 hipfft-sys/Cargo.toml create mode 100644 hipfft-sys/README create mode 100644 hipfft-sys/build.rs create mode 100644 hipfft-sys/src/hipfft.rs create mode 100644 hipfft-sys/src/lib.rs create mode 100644 hiprt-sys/Cargo.toml create mode 100644 hiprt-sys/Makefile.toml create mode 100644 hiprt-sys/include/hiprt.h create mode 100644 hiprt-sys/include/hiprt/hiprt_vec.h create mode 100644 hiprt-sys/lib/hiprt64.dll create mode 100644 hiprt-sys/lib/hiprt64.lib create mode 100644 hiprt-sys/lib/libhiprt64.so create mode 100644 hiprt-sys/src/hiprt.rs create mode 100644 hiprt-sys/src/lib.rs delete mode 100644 level_zero-sys/README delete mode 100644 level_zero-sys/lib/ze_loader.def delete mode 100644 level_zero-sys/lib/ze_loader.lib delete mode 100644 level_zero-sys/src/lib.rs delete mode 100644 level_zero-sys/src/ze_api.rs delete mode 100644 level_zero/Cargo.toml delete mode 100644 level_zero/README delete mode 100644 level_zero/src/lib.rs delete mode 100644 level_zero/src/ze.rs rename {spirv_tools-sys => miopen-sys}/Cargo.toml (58%) create mode 100644 miopen-sys/README create mode 100644 miopen-sys/build.rs create mode 100644 miopen-sys/src/lib.rs create mode 100644 miopen-sys/src/miopen.rs create mode 100644 offline_compiler/Cargo.toml create mode 100644 offline_compiler/src/main.rs create mode 100644 optix_base/Cargo.toml create mode 100644 optix_base/README create mode 100644 optix_base/include/wrapper.hpp create mode 100644 optix_base/include/wrapper6.hpp create mode 100644 optix_base/src/lib.rs create mode 100644 optix_base/src/optix.rs create mode 100644 optix_base/src/optix6.rs create mode 100644 optix_dump/Cargo.toml create mode 100644 optix_dump/README create mode 100644 optix_dump/include/wrapper.hpp create mode 100644 optix_dump/src/eptx.rs create mode 100644 optix_dump/src/lib.rs create mode 100644 optix_types/Cargo.toml create mode 100644 optix_types/src/lib.rs create mode 100644 process_address_table/Cargo.toml create mode 100644 process_address_table/src/main.rs create mode 100644 process_address_table/table.rs create mode 100644 ptx/lib/.gitattributes create mode 100644 ptx/lib/cvt.h create mode 100644 ptx/lib/cvt.py create mode 100644 ptx/lib/raytracing.cpp create mode 100644 ptx/lib/raytracing.hpp create mode 100644 ptx/lib/raytracing_bounding_box.cpp create mode 100644 ptx/lib/raytracing_callable.cpp create mode 100644 ptx/lib/raytracing_intersect.cpp create mode 100644 ptx/lib/zluda_ptx_impl.bc delete mode 100644 ptx/lib/zluda_ptx_impl.cl create mode 100644 ptx/lib/zluda_ptx_impl.cpp delete mode 100644 ptx/lib/zluda_ptx_impl.spv create mode 100644 ptx/lib/zluda_rt_ptx_impl.bc create mode 100644 ptx/lib/zluda_rt_ptx_impl.cpp create mode 100644 ptx/src/emit.rs create mode 100644 ptx/src/llvm.rs create mode 100644 ptx/src/raytracing.rs create mode 100644 ptx/src/test/ptx_raytracing/closest_hit.cu create mode 100644 ptx/src/test/ptx_raytracing/closest_hit.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms_miss.ll create mode 100644 ptx/src/test/ptx_raytracing/optixHello_generated_draw_color.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_draw_solid_color.ll create mode 100644 ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast_draw_solid_color.ll create mode 100644 ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney_Eval.ll create mode 100644 ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program_closest_hit.ll create mode 100644 ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader_closest_hit_radiance.ll create mode 100644 ptx/src/test/ptx_raytracing/optixSphere_generated_sphere.ptx create mode 100644 ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_bounds.ll create mode 100644 ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_robust_intersect.ll create mode 100644 ptx/src/test/raytracing.rs create mode 100644 ptx/src/test/spirv_run/abs.ll create mode 100644 ptx/src/test/spirv_run/abs.ptx create mode 100644 ptx/src/test/spirv_run/activemask.ll create mode 100644 ptx/src/test/spirv_run/activemask.ptx create mode 100644 ptx/src/test/spirv_run/add.ll delete mode 100644 ptx/src/test/spirv_run/add.spvtxt create mode 100644 ptx/src/test/spirv_run/add_global.ll create mode 100644 ptx/src/test/spirv_run/add_global.ptx create mode 100644 ptx/src/test/spirv_run/add_non_coherent.ll create mode 100644 ptx/src/test/spirv_run/add_non_coherent.ptx create mode 100644 ptx/src/test/spirv_run/add_param_ptr.ll create mode 100644 ptx/src/test/spirv_run/add_param_ptr.ptx create mode 100644 ptx/src/test/spirv_run/add_tuning.ll create mode 100644 ptx/src/test/spirv_run/add_tuning.ptx create mode 100644 ptx/src/test/spirv_run/addc_cc.ll create mode 100644 ptx/src/test/spirv_run/addc_cc.ptx create mode 100644 ptx/src/test/spirv_run/addc_cc2.ll create mode 100644 ptx/src/test/spirv_run/addc_cc2.ptx create mode 100644 ptx/src/test/spirv_run/alloca_call.ll create mode 100644 ptx/src/test/spirv_run/alloca_call.ptx create mode 100644 ptx/src/test/spirv_run/amdgpu_unnamed.ll create mode 100644 ptx/src/test/spirv_run/amdgpu_unnamed.ptx create mode 100644 ptx/src/test/spirv_run/and.ll delete mode 100644 ptx/src/test/spirv_run/and.spvtxt create mode 100644 ptx/src/test/spirv_run/assertfail.ll delete mode 100644 ptx/src/test/spirv_run/assertfail.spvtxt create mode 100644 ptx/src/test/spirv_run/atom_add.ll delete mode 100644 ptx/src/test/spirv_run/atom_add.spvtxt create mode 100644 ptx/src/test/spirv_run/atom_add_f16.ll create mode 100644 ptx/src/test/spirv_run/atom_add_f16.ptx create mode 100644 ptx/src/test/spirv_run/atom_add_float.ll create mode 100644 ptx/src/test/spirv_run/atom_add_float.ptx create mode 100644 ptx/src/test/spirv_run/atom_cas.ll delete mode 100644 ptx/src/test/spirv_run/atom_cas.spvtxt create mode 100644 ptx/src/test/spirv_run/atom_inc.ll delete mode 100644 ptx/src/test/spirv_run/atom_inc.spvtxt create mode 100644 ptx/src/test/spirv_run/atom_ld_st.ll create mode 100644 ptx/src/test/spirv_run/atom_ld_st.ptx create mode 100644 ptx/src/test/spirv_run/atom_ld_st_vec.ll create mode 100644 ptx/src/test/spirv_run/atom_ld_st_vec.ptx create mode 100644 ptx/src/test/spirv_run/atom_max_u32.ll create mode 100644 ptx/src/test/spirv_run/atom_max_u32.ptx create mode 100644 ptx/src/test/spirv_run/b64tof64.ll delete mode 100644 ptx/src/test/spirv_run/b64tof64.spvtxt create mode 100644 ptx/src/test/spirv_run/barrier.ll create mode 100644 ptx/src/test/spirv_run/barrier.ptx create mode 100644 ptx/src/test/spirv_run/bfe.ll delete mode 100644 ptx/src/test/spirv_run/bfe.spvtxt create mode 100644 ptx/src/test/spirv_run/bfi.ll create mode 100644 ptx/src/test/spirv_run/bfi.ptx create mode 100644 ptx/src/test/spirv_run/bfind.ll create mode 100644 ptx/src/test/spirv_run/bfind.ptx create mode 100644 ptx/src/test/spirv_run/bfind_shiftamt.ll create mode 100644 ptx/src/test/spirv_run/bfind_shiftamt.ptx create mode 100644 ptx/src/test/spirv_run/block.ll delete mode 100644 ptx/src/test/spirv_run/block.spvtxt create mode 100644 ptx/src/test/spirv_run/bra.ll delete mode 100644 ptx/src/test/spirv_run/bra.spvtxt create mode 100644 ptx/src/test/spirv_run/brev.ll delete mode 100644 ptx/src/test/spirv_run/brev.spvtxt create mode 100644 ptx/src/test/spirv_run/call.ll delete mode 100644 ptx/src/test/spirv_run/call.spvtxt create mode 100644 ptx/src/test/spirv_run/call_bug.ll create mode 100644 ptx/src/test/spirv_run/call_bug.ptx create mode 100644 ptx/src/test/spirv_run/call_multi_return.ll create mode 100644 ptx/src/test/spirv_run/call_multi_return.ptx create mode 100644 ptx/src/test/spirv_run/callprototype.ll create mode 100644 ptx/src/test/spirv_run/callprototype.ptx create mode 100644 ptx/src/test/spirv_run/carry_mixed.ll create mode 100644 ptx/src/test/spirv_run/carry_mixed.ptx create mode 100644 ptx/src/test/spirv_run/clz.ll delete mode 100644 ptx/src/test/spirv_run/clz.spvtxt create mode 100644 ptx/src/test/spirv_run/const.ll create mode 100644 ptx/src/test/spirv_run/const.ptx create mode 100644 ptx/src/test/spirv_run/constant_f32.ll delete mode 100644 ptx/src/test/spirv_run/constant_f32.spvtxt create mode 100644 ptx/src/test/spirv_run/constant_negative.ll delete mode 100644 ptx/src/test/spirv_run/constant_negative.spvtxt create mode 100644 ptx/src/test/spirv_run/cos.ll delete mode 100644 ptx/src/test/spirv_run/cos.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_clamp.ll create mode 100644 ptx/src/test/spirv_run/cvt_clamp.ptx create mode 100644 ptx/src/test/spirv_run/cvt_f32_f16.ll create mode 100644 ptx/src/test/spirv_run/cvt_f32_f16.ptx create mode 100644 ptx/src/test/spirv_run/cvt_f32_s32.ll create mode 100644 ptx/src/test/spirv_run/cvt_f32_s32.ptx create mode 100644 ptx/src/test/spirv_run/cvt_f64_f32.ll create mode 100644 ptx/src/test/spirv_run/cvt_f64_f32.ptx create mode 100644 ptx/src/test/spirv_run/cvt_rni.ll delete mode 100644 ptx/src/test/spirv_run/cvt_rni.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_rzi.ll delete mode 100644 ptx/src/test/spirv_run/cvt_rzi.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_s16_s8.ll create mode 100644 ptx/src/test/spirv_run/cvt_s16_s8.ptx create mode 100644 ptx/src/test/spirv_run/cvt_s32_f32.ll delete mode 100644 ptx/src/test/spirv_run/cvt_s32_f32.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_s64_s32.ll delete mode 100644 ptx/src/test/spirv_run/cvt_s64_s32.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_sat_s_u.ll delete mode 100644 ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt create mode 100644 ptx/src/test/spirv_run/cvt_u32_s16.ll create mode 100644 ptx/src/test/spirv_run/cvt_u32_s16.ptx create mode 100644 ptx/src/test/spirv_run/cvta.ll delete mode 100644 ptx/src/test/spirv_run/cvta.spvtxt create mode 100644 ptx/src/test/spirv_run/div_approx.ll delete mode 100644 ptx/src/test/spirv_run/div_approx.spvtxt create mode 100644 ptx/src/test/spirv_run/dp4a.ll create mode 100644 ptx/src/test/spirv_run/dp4a.ptx create mode 100644 ptx/src/test/spirv_run/ex2.ll delete mode 100644 ptx/src/test/spirv_run/ex2.spvtxt create mode 100644 ptx/src/test/spirv_run/extern_shared.ll delete mode 100644 ptx/src/test/spirv_run/extern_shared.spvtxt create mode 100644 ptx/src/test/spirv_run/extern_shared_call.ll delete mode 100644 ptx/src/test/spirv_run/extern_shared_call.spvtxt create mode 100644 ptx/src/test/spirv_run/fma.ll delete mode 100644 ptx/src/test/spirv_run/fma.spvtxt create mode 100644 ptx/src/test/spirv_run/func_ptr.ll create mode 100644 ptx/src/test/spirv_run/func_ptr.ptx create mode 100644 ptx/src/test/spirv_run/generic.ll create mode 100644 ptx/src/test/spirv_run/generic.ptx create mode 100644 ptx/src/test/spirv_run/global_array.ll delete mode 100644 ptx/src/test/spirv_run/global_array.spvtxt create mode 100644 ptx/src/test/spirv_run/implicit_param.ll delete mode 100644 ptx/src/test/spirv_run/implicit_param.spvtxt create mode 100644 ptx/src/test/spirv_run/laneid.ptx create mode 100644 ptx/src/test/spirv_run/lanemask_lt.ll create mode 100644 ptx/src/test/spirv_run/lanemask_lt.ptx create mode 100644 ptx/src/test/spirv_run/ld_st.ll delete mode 100644 ptx/src/test/spirv_run/ld_st.spvtxt create mode 100644 ptx/src/test/spirv_run/ld_st_implicit.ll delete mode 100644 ptx/src/test/spirv_run/ld_st_implicit.spvtxt create mode 100644 ptx/src/test/spirv_run/ld_st_offset.ll delete mode 100644 ptx/src/test/spirv_run/ld_st_offset.spvtxt create mode 100644 ptx/src/test/spirv_run/lg2.ll delete mode 100644 ptx/src/test/spirv_run/lg2.spvtxt create mode 100644 ptx/src/test/spirv_run/local_align.ll delete mode 100644 ptx/src/test/spirv_run/local_align.spvtxt create mode 100644 ptx/src/test/spirv_run/mad_s32.ll delete mode 100644 ptx/src/test/spirv_run/mad_s32.spvtxt create mode 100644 ptx/src/test/spirv_run/madc_cc.ll create mode 100644 ptx/src/test/spirv_run/madc_cc.ptx create mode 100644 ptx/src/test/spirv_run/madc_cc2.ll create mode 100644 ptx/src/test/spirv_run/madc_cc2.ptx create mode 100644 ptx/src/test/spirv_run/match_any_32.ptx create mode 100644 ptx/src/test/spirv_run/max.ll delete mode 100644 ptx/src/test/spirv_run/max.spvtxt create mode 100644 ptx/src/test/spirv_run/membar.ll rename ptx/src/test/spirv_run/{shr.ptx => membar.ptx} (72%) create mode 100644 ptx/src/test/spirv_run/min.ll delete mode 100644 ptx/src/test/spirv_run/min.spvtxt create mode 100644 ptx/src/test/spirv_run/mov.ll delete mode 100644 ptx/src/test/spirv_run/mov.spvtxt create mode 100644 ptx/src/test/spirv_run/mov_address.ll delete mode 100644 ptx/src/test/spirv_run/mov_address.spvtxt create mode 100644 ptx/src/test/spirv_run/mov_vector_cast.ll create mode 100644 ptx/src/test/spirv_run/mov_vector_cast.ptx create mode 100644 ptx/src/test/spirv_run/mul_ftz.ll delete mode 100644 ptx/src/test/spirv_run/mul_ftz.spvtxt create mode 100644 ptx/src/test/spirv_run/mul_hi.ll delete mode 100644 ptx/src/test/spirv_run/mul_hi.spvtxt create mode 100644 ptx/src/test/spirv_run/mul_lo.ll delete mode 100644 ptx/src/test/spirv_run/mul_lo.spvtxt create mode 100644 ptx/src/test/spirv_run/mul_non_ftz.ll delete mode 100644 ptx/src/test/spirv_run/mul_non_ftz.spvtxt create mode 100644 ptx/src/test/spirv_run/mul_wide.ll delete mode 100644 ptx/src/test/spirv_run/mul_wide.spvtxt create mode 100644 ptx/src/test/spirv_run/multireg.ll create mode 100644 ptx/src/test/spirv_run/multireg.ptx create mode 100644 ptx/src/test/spirv_run/neg.ll delete mode 100644 ptx/src/test/spirv_run/neg.spvtxt create mode 100644 ptx/src/test/spirv_run/non_scalar_ptr_offset.ll create mode 100644 ptx/src/test/spirv_run/non_scalar_ptr_offset.ptx create mode 100644 ptx/src/test/spirv_run/not.ll delete mode 100644 ptx/src/test/spirv_run/not.spvtxt create mode 100644 ptx/src/test/spirv_run/ntid.ll delete mode 100644 ptx/src/test/spirv_run/ntid.spvtxt create mode 100644 ptx/src/test/spirv_run/or.ll delete mode 100644 ptx/src/test/spirv_run/or.spvtxt create mode 100644 ptx/src/test/spirv_run/param_ptr.ll create mode 100644 ptx/src/test/spirv_run/param_ptr.ptx create mode 100644 ptx/src/test/spirv_run/popc.ll delete mode 100644 ptx/src/test/spirv_run/popc.spvtxt create mode 100644 ptx/src/test/spirv_run/pred_not.ll delete mode 100644 ptx/src/test/spirv_run/pred_not.spvtxt create mode 100644 ptx/src/test/spirv_run/prmt.ll create mode 100644 ptx/src/test/spirv_run/prmt.ptx create mode 100644 ptx/src/test/spirv_run/prmt_non_immediate.ll create mode 100644 ptx/src/test/spirv_run/prmt_non_immediate.ptx create mode 100644 ptx/src/test/spirv_run/rcp.ll delete mode 100644 ptx/src/test/spirv_run/rcp.spvtxt create mode 100644 ptx/src/test/spirv_run/red_shared.ptx create mode 100644 ptx/src/test/spirv_run/reg_local.ll delete mode 100644 ptx/src/test/spirv_run/reg_local.spvtxt create mode 100644 ptx/src/test/spirv_run/rem.ll delete mode 100644 ptx/src/test/spirv_run/rem.spvtxt create mode 100644 ptx/src/test/spirv_run/rsqrt.ll delete mode 100644 ptx/src/test/spirv_run/rsqrt.spvtxt create mode 100644 ptx/src/test/spirv_run/s64_min.ll create mode 100644 ptx/src/test/spirv_run/s64_min.ptx create mode 100644 ptx/src/test/spirv_run/selp.ll delete mode 100644 ptx/src/test/spirv_run/selp.spvtxt create mode 100644 ptx/src/test/spirv_run/selp_true.ll delete mode 100644 ptx/src/test/spirv_run/selp_true.spvtxt create mode 100644 ptx/src/test/spirv_run/setp.ll delete mode 100644 ptx/src/test/spirv_run/setp.spvtxt create mode 100644 ptx/src/test/spirv_run/setp_bool.ll create mode 100644 ptx/src/test/spirv_run/setp_bool.ptx create mode 100644 ptx/src/test/spirv_run/setp_gt.ll delete mode 100644 ptx/src/test/spirv_run/setp_gt.spvtxt create mode 100644 ptx/src/test/spirv_run/setp_leu.ll delete mode 100644 ptx/src/test/spirv_run/setp_leu.spvtxt create mode 100644 ptx/src/test/spirv_run/setp_nan.ll create mode 100644 ptx/src/test/spirv_run/setp_nan.ptx create mode 100644 ptx/src/test/spirv_run/setp_num.ll create mode 100644 ptx/src/test/spirv_run/setp_num.ptx create mode 100644 ptx/src/test/spirv_run/setp_pred2.ll create mode 100644 ptx/src/test/spirv_run/setp_pred2.ptx create mode 100644 ptx/src/test/spirv_run/shared_ptr_32.ll delete mode 100644 ptx/src/test/spirv_run/shared_ptr_32.spvtxt create mode 100644 ptx/src/test/spirv_run/shared_ptr_take_address.ll delete mode 100644 ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt create mode 100644 ptx/src/test/spirv_run/shared_unify_decl.ll create mode 100644 ptx/src/test/spirv_run/shared_unify_decl.ptx create mode 100644 ptx/src/test/spirv_run/shared_unify_extern.ll create mode 100644 ptx/src/test/spirv_run/shared_unify_extern.ptx create mode 100644 ptx/src/test/spirv_run/shared_unify_local.ll create mode 100644 ptx/src/test/spirv_run/shared_unify_local.ptx create mode 100644 ptx/src/test/spirv_run/shared_variable.ll delete mode 100644 ptx/src/test/spirv_run/shared_variable.spvtxt create mode 100644 ptx/src/test/spirv_run/shf.ll create mode 100644 ptx/src/test/spirv_run/shf.ptx create mode 100644 ptx/src/test/spirv_run/shfl.ptx create mode 100644 ptx/src/test/spirv_run/shl.ll delete mode 100644 ptx/src/test/spirv_run/shl.spvtxt create mode 100644 ptx/src/test/spirv_run/shl_link_hack.ll delete mode 100644 ptx/src/test/spirv_run/shl_link_hack.spvtxt create mode 100644 ptx/src/test/spirv_run/shl_overflow.ll create mode 100644 ptx/src/test/spirv_run/shl_overflow.ptx delete mode 100644 ptx/src/test/spirv_run/shr.spvtxt create mode 100644 ptx/src/test/spirv_run/shr_s32.ll create mode 100644 ptx/src/test/spirv_run/shr_s32.ptx create mode 100644 ptx/src/test/spirv_run/shr_u32.ll create mode 100644 ptx/src/test/spirv_run/shr_u32.ptx create mode 100644 ptx/src/test/spirv_run/sign_extend.ll create mode 100644 ptx/src/test/spirv_run/sign_extend.ptx create mode 100644 ptx/src/test/spirv_run/sin.ll delete mode 100644 ptx/src/test/spirv_run/sin.spvtxt create mode 100644 ptx/src/test/spirv_run/sqrt.ll delete mode 100644 ptx/src/test/spirv_run/sqrt.spvtxt create mode 100644 ptx/src/test/spirv_run/st_f16x2.ll create mode 100644 ptx/src/test/spirv_run/st_f16x2.ptx delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_simple.ptx delete mode 100644 ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt create mode 100644 ptx/src/test/spirv_run/sub.ll delete mode 100644 ptx/src/test/spirv_run/sub.spvtxt create mode 100644 ptx/src/test/spirv_run/subc_cc.ll create mode 100644 ptx/src/test/spirv_run/subc_cc.ptx create mode 100644 ptx/src/test/spirv_run/subc_cc2.ll create mode 100644 ptx/src/test/spirv_run/subc_cc2.ptx create mode 100644 ptx/src/test/spirv_run/vector.ll delete mode 100644 ptx/src/test/spirv_run/vector.spvtxt create mode 100644 ptx/src/test/spirv_run/vector4.ll create mode 100644 ptx/src/test/spirv_run/vector4.ptx create mode 100644 ptx/src/test/spirv_run/vector_extract.ll delete mode 100644 ptx/src/test/spirv_run/vector_extract.spvtxt create mode 100644 ptx/src/test/spirv_run/verify.py create mode 100644 ptx/src/test/spirv_run/vote_ballot.ll create mode 100644 ptx/src/test/spirv_run/vote_ballot.ptx create mode 100644 ptx/src/test/spirv_run/vshr.ll create mode 100644 ptx/src/test/spirv_run/vshr.ptx create mode 100644 ptx/src/test/spirv_run/xor.ll delete mode 100644 ptx/src/test/spirv_run/xor.spvtxt create mode 100644 rocblas-sys/Cargo.toml create mode 100644 rocblas-sys/README create mode 100644 rocblas-sys/build.rs create mode 100644 rocblas-sys/src/lib.rs create mode 100644 rocblas-sys/src/rocblas.rs create mode 100644 rocm_smi-sys/Cargo.toml create mode 100644 rocm_smi-sys/README create mode 100644 rocm_smi-sys/build.rs create mode 100644 rocm_smi-sys/src/lib.rs create mode 100644 rocm_smi-sys/src/rocm_smi.rs create mode 100644 rocsolver-sys/Cargo.toml create mode 100644 rocsolver-sys/README create mode 100644 rocsolver-sys/build.rs create mode 100644 rocsolver-sys/src/lib.rs create mode 100644 rocsolver-sys/src/rocsolver.rs create mode 100644 rocsparse-sys/Cargo.toml create mode 100644 rocsparse-sys/README create mode 100644 rocsparse-sys/build.rs create mode 100644 rocsparse-sys/src/lib.rs create mode 100644 rocsparse-sys/src/rocsparse.rs delete mode 100644 spirv_tools-sys/README delete mode 100644 spirv_tools-sys/build.rs delete mode 100644 spirv_tools-sys/src/lib.rs delete mode 100644 spirv_tools-sys/src/spirv_tools.rs create mode 100644 xtask/Cargo.toml create mode 100644 xtask/src/main.rs delete mode 100644 zluda/lib/OpenCL.lib delete mode 100644 zluda/src/cuda_impl/mod.rs delete mode 100644 zluda/src/cuda_impl/rt.rs create mode 100644 zluda/src/impl/array.rs create mode 100644 zluda/src/impl/cache.rs create mode 100644 zluda/src/impl/dark_api.rs create mode 100644 zluda/src/impl/empty_module.ptx delete mode 100644 zluda/src/impl/export_table.rs create mode 100644 zluda/src/impl/gl.rs create mode 100644 zluda/src/impl/graph.rs create mode 100644 zluda/src/impl/hipfix.rs create mode 100644 zluda/src/impl/library.rs create mode 100644 zluda/src/impl/link.rs create mode 100644 zluda/src/impl/os_unix.rs create mode 100644 zluda/src/impl/os_win.rs create mode 100644 zluda/src/impl/pointer.rs create mode 100644 zluda/src/impl/surface.rs create mode 100644 zluda/src/impl/surfref.rs delete mode 100644 zluda/src/impl/test.rs create mode 100644 zluda/src/impl/texobj.rs create mode 100644 zluda/src/impl/texref.rs create mode 100644 zluda/tests/bfi.ptx create mode 100644 zluda/tests/bfi.rs create mode 100644 zluda/tests/common.rs create mode 100644 zluda/tests/context_dark_api_primary_is_unretained.rs create mode 100644 zluda/tests/context_destroy_also_destroys_stream.rs create mode 100644 zluda/tests/context_destroy_leaves_zombie.rs create mode 100644 zluda/tests/context_destroy_pops_top_of_stack.rs create mode 100644 zluda/tests/context_double_destroy_fails.rs create mode 100644 zluda/tests/context_empty_pop_fails.rs create mode 100644 zluda/tests/context_no_current_on_init.rs create mode 100644 zluda/tests/context_push_invalid_should_crash.rs create mode 100644 zluda/tests/function_version.ptx create mode 100644 zluda/tests/function_version.rs create mode 100644 zluda/tests/kernel_args_align.ptx create mode 100644 zluda/tests/kernel_args_align.rs create mode 100644 zluda/tests/kernel_extra.ptx create mode 100644 zluda/tests/kernel_extra.rs create mode 100644 zluda/tests/kernel_suld.ptx create mode 100644 zluda/tests/kernel_suld.rs create mode 100644 zluda/tests/kernel_sust.ptx create mode 100644 zluda/tests/kernel_sust.rs create mode 100644 zluda/tests/kernel_tex.ptx create mode 100644 zluda/tests/kernel_tex.rs create mode 100644 zluda/tests/kernel_texobj_2d.ptx create mode 100644 zluda/tests/kernel_texobj_2d.rs create mode 100644 zluda/tests/kernel_texref_1d.ptx create mode 100644 zluda/tests/kernel_texref_1d.rs create mode 100644 zluda/tests/kernel_texref_2d.ptx create mode 100644 zluda/tests/kernel_texref_2d.rs create mode 100644 zluda/tests/kernel_unused_global.ptx create mode 100644 zluda/tests/kernel_unused_global.rs create mode 100644 zluda/tests/linking.rs create mode 100644 zluda/tests/llama.bin create mode 100644 zluda/tests/llama.ptx create mode 100644 zluda/tests/llama.rs create mode 100644 zluda/tests/maxntid.ptx create mode 100644 zluda/tests/maxntid.rs create mode 100644 zluda/tests/memcpy_pitch.rs create mode 100644 zluda/tests/module_texrefs_have_correct_format.rs create mode 100644 zluda/tests/shuffle.ptx create mode 100644 zluda/tests/shuffle.rs create mode 100644 zluda/tests/stream_can_destroy.rs create mode 100644 zluda/tests/stream_cant_destroy_default.rs create mode 100644 zluda/tests/stream_context_destroyed.rs create mode 100644 zluda/tests/stream_default_uses_current_ctx_impl.rs create mode 100644 zluda/tests/stream_moves_context_to_another_thread.rs create mode 100644 zluda_api/Cargo.toml create mode 100644 zluda_api/README create mode 100644 zluda_api/src/lib.rs create mode 100644 zluda_api/src/nvapi.rs create mode 100644 zluda_api/src/nvapi_wrapper.h create mode 100644 zluda_blas/Cargo.toml create mode 100644 zluda_blas/README create mode 100644 zluda_blas/build/wrapper.h create mode 100644 zluda_blas/src/cublas.rs create mode 100644 zluda_blas/src/lib.rs create mode 100644 zluda_blaslt/Cargo.toml create mode 100644 zluda_blaslt/README create mode 100644 zluda_blaslt/src/cublaslt.rs create mode 100644 zluda_blaslt/src/lib.rs create mode 100644 zluda_ccl/Cargo.toml create mode 100644 zluda_ccl/README create mode 100644 zluda_ccl/src/lib.rs create mode 100644 zluda_ccl/src/nccl.rs create mode 100644 zluda_dark_api/Cargo.toml create mode 100644 zluda_dark_api/src/lib.rs create mode 100644 zluda_dnn/Cargo.toml create mode 100644 zluda_dnn/README create mode 100644 zluda_dnn/build/cudnn_adv_infer.h create mode 100644 zluda_dnn/build/cudnn_adv_train.h create mode 100644 zluda_dnn/build/cudnn_backend.h create mode 100644 zluda_dnn/build/cudnn_cnn_infer.h create mode 100644 zluda_dnn/build/cudnn_cnn_train.h create mode 100644 zluda_dnn/build/cudnn_ops_infer.h create mode 100644 zluda_dnn/build/cudnn_ops_train.h create mode 100644 zluda_dnn/build/cudnn_version.h create mode 100644 zluda_dnn/src/cudnn_types_v7.rs create mode 100644 zluda_dnn/src/cudnn_types_v8.rs create mode 100644 zluda_dnn/src/cudnn_v7.rs create mode 100644 zluda_dnn/src/cudnn_v8.rs create mode 100644 zluda_dnn/src/lib.rs create mode 100644 zluda_dump/README.md create mode 100644 zluda_dump/src/dark_api.rs create mode 100644 zluda_dump/src/debug.ptx create mode 100644 zluda_dump/src/events_to_csv.py create mode 100644 zluda_dump/src/format.rs create mode 100644 zluda_dump/src/log.rs create mode 100644 zluda_dump/src/profiler.rs create mode 100644 zluda_dump/src/side_by_side.rs create mode 100644 zluda_dump/src/trace.rs create mode 100644 zluda_fft/Cargo.toml create mode 100644 zluda_fft/README create mode 100644 zluda_fft/src/cufft.rs create mode 100644 zluda_fft/src/cufftxt.rs create mode 100644 zluda_fft/src/lib.rs create mode 100644 zluda_inject/build.rs create mode 100644 zluda_inject/tests/helpers/direct_cuinit.rs create mode 100644 zluda_inject/tests/helpers/do_cuinit.rs create mode 100644 zluda_inject/tests/helpers/do_cuinit_early.rs create mode 100644 zluda_inject/tests/helpers/do_cuinit_late.rs create mode 100644 zluda_inject/tests/helpers/do_cuinit_late_clr.cs create mode 100644 zluda_inject/tests/helpers/do_cuinit_late_clr.exe create mode 100644 zluda_inject/tests/helpers/indirect_cuinit.rs create mode 100644 zluda_inject/tests/helpers/nvcuda.lib create mode 100644 zluda_inject/tests/helpers/query_exe.rs create mode 100644 zluda_inject/tests/helpers/subprocess.rs create mode 100644 zluda_inject/tests/inject.rs create mode 100644 zluda_llvm/Cargo.toml create mode 100644 zluda_llvm/README.md create mode 100644 zluda_llvm/build.rs create mode 100644 zluda_llvm/src/lib.cpp create mode 100644 zluda_llvm/src/lib.rs create mode 100644 zluda_ml/Cargo.toml create mode 100644 zluda_ml/README create mode 100644 zluda_ml/src/common.rs create mode 100644 zluda_ml/src/lib.rs create mode 100644 zluda_ml/src/nvml.rs create mode 100644 zluda_ml/src/unix.rs create mode 100644 zluda_ml/src/windows.rs create mode 100644 zluda_rt/Cargo.toml create mode 100644 zluda_rt/bin/liboptix.so.6.5.0 create mode 100644 zluda_rt/bin/optix.6.5.0.dll create mode 100644 zluda_rt/build.rs create mode 100644 zluda_rt/optix.xmi create mode 100644 zluda_rt/src/acceleration.rs create mode 100644 zluda_rt/src/buffer.rs create mode 100644 zluda_rt/src/cache.rs create mode 100644 zluda_rt/src/context.rs create mode 100644 zluda_rt/src/eptx.rs create mode 100644 zluda_rt/src/geometry.rs create mode 100644 zluda_rt/src/geometry_group.rs create mode 100644 zluda_rt/src/geometry_instance.rs create mode 100644 zluda_rt/src/geometry_triangles.rs create mode 100644 zluda_rt/src/group.rs create mode 100644 zluda_rt/src/hip.rs create mode 100644 zluda_rt/src/lib.rs create mode 100644 zluda_rt/src/material.rs create mode 100644 zluda_rt/src/program.rs create mode 100644 zluda_rt/src/repr_gpu.rs create mode 100644 zluda_rt/src/test_common.rs create mode 100644 zluda_rt/src/tests/alloca_bug.cu create mode 100644 zluda_rt/src/tests/alloca_bug.ptx create mode 100644 zluda_rt/src/tests/any_hit_intersect.cu create mode 100644 zluda_rt/src/tests/any_hit_intersect.ptx create mode 100644 zluda_rt/src/tests/barycentrics.cu create mode 100644 zluda_rt/src/tests/barycentrics.ptx create mode 100644 zluda_rt/src/tests/buffer_id.cu create mode 100644 zluda_rt/src/tests/buffer_id.ptx create mode 100644 zluda_rt/src/tests/buffer_id_call.cu create mode 100644 zluda_rt/src/tests/buffer_id_call.ptx create mode 100644 zluda_rt/src/tests/buffer_id_callable.cu create mode 100644 zluda_rt/src/tests/buffer_id_callable.ptx create mode 100644 zluda_rt/src/tests/buffer_mipmap.cu create mode 100644 zluda_rt/src/tests/buffer_mipmap.ptx create mode 100644 zluda_rt/src/tests/callable_programs.cu create mode 100644 zluda_rt/src/tests/callable_programs.ptx create mode 100644 zluda_rt/src/tests/default_variable.cu create mode 100644 zluda_rt/src/tests/default_variable.ptx create mode 100644 zluda_rt/src/tests/exception.cu create mode 100644 zluda_rt/src/tests/exception.ptx create mode 100644 zluda_rt/src/tests/exception_subfunc.cu create mode 100644 zluda_rt/src/tests/exception_subfunc.ptx create mode 100644 zluda_rt/src/tests/get_transform.cu create mode 100644 zluda_rt/src/tests/get_transform.ptx create mode 100644 zluda_rt/src/tests/mod.rs create mode 100644 zluda_rt/src/tests/oob.cu create mode 100644 zluda_rt/src/tests/oob.ptx create mode 100644 zluda_rt/src/tests/texture_sampler.cu create mode 100644 zluda_rt/src/tests/texture_sampler.ptx create mode 100644 zluda_rt/src/tests/trace_control.cu create mode 100644 zluda_rt/src/tests/trace_control.ptx create mode 100644 zluda_rt/src/tests/transform.cu create mode 100644 zluda_rt/src/tests/transform.ptx create mode 100644 zluda_rt/src/tests/triangle_front.cu create mode 100644 zluda_rt/src/tests/triangle_front.ptx create mode 100644 zluda_rt/src/texture_sampler.rs create mode 100644 zluda_rt/src/transform.rs create mode 100644 zluda_rt/src/variable.rs create mode 100644 zluda_sparse/Cargo.toml create mode 100644 zluda_sparse/README create mode 100644 zluda_sparse/src/cusparse.rs create mode 100644 zluda_sparse/src/lib.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index cd7ce74..0088cc2 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,8 @@ -[target."x86_64-pc-windows-gnu"] -rustflags = ["-C", "link-self-contained=y"] +[target."x86_64-unknown-linux-gnu"] +rustflags = ["-C", "target-cpu=x86-64-v2"] + +[target."x86_64-pc-windows-msvc"] +rustflags = ["-C", "target-cpu=x86-64-v2"] + +[alias] +xtask = "run --package xtask --" diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..76b7630 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,6 @@ +# syntax = devthefuture/dockerfile-x + +# This duplicate FROM is here purely to make dev containers happy, +# Otherwise it tries to parse the file (whyyy???) and chokes on custom syntax +FROM ubuntu:22.04 +INCLUDE ./Dockerfile-common \ No newline at end of file diff --git a/.devcontainer/Dockerfile-common b/.devcontainer/Dockerfile-common new file mode 100644 index 0000000..e7a5356 --- /dev/null +++ b/.devcontainer/Dockerfile-common @@ -0,0 +1,64 @@ +WORKDIR /root + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + nano \ + wget \ + curl \ + gnupg \ + ripgrep \ + ltrace \ + file\ + python3-minimal \ + build-essential \ + git \ + cmake \ + ninja-build +ENV PATH="${PATH}:/opt/rocm/bin:/opt/rocm/llvm/bin:/usr/local/cuda/bin/" + + +ARG CUDA_VERSION=11-8 +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES compute,utility +RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb && \ + dpkg -i cuda-keyring_1.0-1_all.deb && \ + apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + nvidia-headless-no-dkms-515 \ + nvidia-utils-515 \ + cuda-cudart-${CUDA_VERSION} \ + cuda-compiler-${CUDA_VERSION} \ + libcufft-dev-${CUDA_VERSION} \ + libcusparse-dev-${CUDA_VERSION} \ + libcublas-dev-${CUDA_VERSION} \ + cuda-nvml-dev-${CUDA_VERSION} \ + libcudnn8-dev + +ARG RUST_VERSION=1.66.1 +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=${RUST_VERSION} +RUN . $HOME/.cargo/env && cargo install bindgen-cli --locked + +ARG ROCM_VERSION=5.7.3 +RUN echo "Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600" > /etc/apt/preferences.d/rocm-pin-600 +RUN mkdir --parents --mode=0755 /etc/apt/keyrings && \ + sh -c 'wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null' && \ + sh -c 'echo deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/${ROCM_VERSION} jammy main > /etc/apt/sources.list.d/rocm.list' && \ + apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + rocminfo \ + rocm-gdb \ + rocprofiler \ + rocm-smi-lib \ + hip-runtime-amd \ + comgr \ + hipblaslt-dev \ + hipfft-dev \ + rocblas-dev \ + rocsolver-dev \ + rocsparse-dev \ + miopen-hip-dev \ + rocm-device-libs && \ + echo 'export PATH="$PATH:/opt/rocm/bin"' > /etc/profile.d/rocm.sh && \ + echo '/opt/rocm/lib' > /etc/ld.so.conf.d/rocm.conf && \ + ldconfig + +# Default to a login shell +CMD ["bash", "-l"] diff --git a/.devcontainer/Dockerfile-el8_8 b/.devcontainer/Dockerfile-el8_8 new file mode 100644 index 0000000..105ed05 --- /dev/null +++ b/.devcontainer/Dockerfile-el8_8 @@ -0,0 +1,72 @@ +FROM rockylinux:8.8 + +WORKDIR /root + +RUN dnf -y --setopt=install_weak_deps=False install \ + nano \ + wget \ + curl \ + ltrace \ + file \ + python3 \ + git \ + gcc \ + gcc-c++ \ + cmake + +RUN wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm && \ + rpm -ivh epel-release-latest-8.noarch.rpm && \ + dnf -y --setopt=install_weak_deps=False install 'dnf-command(config-manager)' && \ + crb enable && \ + dnf -y --setopt=install_weak_deps=False install \ + ripgrep \ + ninja-build + +ARG CUDA_VERSION=11-8 +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES compute,utility +RUN dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo && \ + dnf -y --setopt=install_weak_deps=False module install \ + nvidia-driver:515 && \ + dnf -y --setopt=install_weak_deps=False install \ + cuda-cudart-${CUDA_VERSION} \ + cuda-compiler-${CUDA_VERSION} \ + libcufft-devel-${CUDA_VERSION} \ + libcusparse-devel-${CUDA_VERSION} \ + libcublas-devel-${CUDA_VERSION} \ + cuda-nvml-devel-${CUDA_VERSION} \ + libcudnn8-devel + +ARG RUST_VERSION=1.66.1 +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=${RUST_VERSION} +RUN . $HOME/.cargo/env && cargo install bindgen-cli --locked + +ARG ROCM_VERSION=5.7.1 +RUN sh -c 'echo -e "[ROCm-${ROCM_VERSION}]\n\ +name=ROCm${ROCM_VERSION}\n\ +baseurl=https://repo.radeon.com/rocm/rhel8/${ROCM_VERSION}/main\n\ +enabled=1\n\ +priority=50\n\ +gpgcheck=1\n\ +gpgkey=https://repo.radeon.com/rocm/rocm.gpg.key"' \ + > /etc/yum.repos.d/rocm.repo && \ + dnf -y --setopt=install_weak_deps=False install \ + rocminfo \ + rocm-gdb \ + rocprofiler \ + rocm-smi-lib \ + hip-runtime-amd \ + comgr \ + hipblaslt-devel \ + hipfft-devel \ + rocblas-devel \ + rocsolver-devel \ + rocsparse-devel \ + miopen-hip-devel \ + rocm-device-libs && \ + echo 'export PATH="$PATH:/opt/rocm/bin"' > /etc/profile.d/rocm.sh && \ + echo '/opt/rocm/lib' > /etc/ld.so.conf.d/rocm.conf && \ + ldconfig + +# Default to a login shell +CMD ["bash", "-l"] \ No newline at end of file diff --git a/.devcontainer/Dockerfile-xgboost b/.devcontainer/Dockerfile-xgboost new file mode 100644 index 0000000..1f1045d --- /dev/null +++ b/.devcontainer/Dockerfile-xgboost @@ -0,0 +1,16 @@ +# syntax = devthefuture/dockerfile-x +FROM ubuntu:22.04 +INCLUDE ./Dockerfile-common + +ARG XGBOOST_VERSION=2.0.3 +RUN git clone --branch "v${XGBOOST_VERSION}" --recurse-submodules https://github.com/dmlc/xgboost.git && \ + cd xgboost && \ + # Broken test, segfaults on normal CUDA + sed -i 's/TEST(Allocator, OOM) {/TEST(Allocator, OOM) { GTEST_SKIP();/g' tests/cpp/common/test_device_helpers.cu && \ + mkdir build && \ + cd build && \ + cmake .. -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON -DUSE_CUDA=ON -GNinja && \ + ninja + +# + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..e71762d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json +{ + "name": "ZLUDA", + "build": { + "dockerfile": "Dockerfile" + }, + "securityOpt": [ + "seccomp=unconfined" + ], + // Make NVIDIA and AMD GPUs available + "runArgs": [ + // Uncomment on newer docker/podman + //"--runtime=nvidia", + "--device=/dev/kfd", + "--device=/dev/dri", + "--group-add=video" + ], + // Cache cargo packages and compiled ZLUDA kernels + "initializeCommand": "mkdir -p ${localEnv:HOME}/.cargo/git ${localEnv:HOME}/.cargo/registry ${localEnv:HOME}/.cache/ZLUDA", + "mounts": [ + { + "source": "${localEnv:HOME}/.cargo/git", + "target": "/root/.cargo/git", + "type": "bind" + }, + { + "source": "${localEnv:HOME}/.cargo/registry", + "target": "/root/.cargo/registry", + "type": "bind" + }, + { + "source": "${localEnv:HOME}/.cache/ZLUDA", + "target": "/root/.cache/ZLUDA", + "type": "bind" + } + ], + // Rootless docker requires logging as root: https://aka.ms/dev-containers-non-root. + "remoteUser": "root" +} \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..249127a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +ext/** linguist-vendored +atiadlxx-sys/include/* linguist-vendored +*.ptx linguist-language=Assembly \ No newline at end of file diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index c4e348b..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Rust - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build_lin: - name: Build and publish (Linux) - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - with: - submodules: true - - name: Install GPU drivers - run: | - sudo apt-get install -y gpg-agent wget - wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | sudo apt-key add - - sudo apt-add-repository 'deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu focal main' - sudo apt-get update - sudo apt-get install intel-opencl-icd intel-level-zero-gpu level-zero intel-media-va-driver-non-free libmfx1 libigc-dev intel-igc-cm libigdfcl-dev libigfxcmrt-dev level-zero-dev ocl-icd-opencl-dev - - name: Build - run: cargo build --workspace --verbose --release - - name: Rename to libcuda.so - run: | - mv target/release/libnvcuda.so target/release/libcuda.so - ln -s libcuda.so target/release/libcuda.so.1 - - uses: actions/upload-artifact@v2 - with: - name: Linux - path: | - target/release/libcuda.so - target/release/libcuda.so.1 - build_win: - name: Build and publish (Windows) - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: true - - name: Build - run: cargo build --workspace --verbose --release - - uses: actions/upload-artifact@v2 - with: - name: Windows - path: | - target/release/nvcuda.dll - target/release/zluda_redirect.dll - target/release/zluda_with.exe - target/release/zluda_dump.dll - # TODO(take-cheeze): Support testing - # - name: Run tests - # run: cargo test --verbose diff --git a/.gitmodules b/.gitmodules index 9796b04..8f582bf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,5 @@ -[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 +[submodule "ext/llvm-project"] + path = ext/llvm-project + url = https://github.com/llvm/llvm-project.git + branch = release/15.x + shallow = true diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..466a481 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,197 @@ +# Architecture of ZLUDA + +## Introduction + +ZLUDA is a binary-compatible implementation of CUDA for AMD GPUs. An application built with CUDA compiler for NVIDIA GPU can be executed with near-native performance with ZLUDA on AMD GPUs without recompilation or any modifications to the application. +The principle behind ZLUDA is similar to that of WINE or WSL: to provide a highly-compatible execution environment with a near-native performance. +The design of the code follows directly from execution requirements of CUDA applications. Accordingly, this document is is split into five parts: +* Introduction +* CUDA runtime, which describes how CPU code, which controls NVIDIA GPUs is translated to control AMD GPUs +* CUDA GPU code compiler, which describes how NVIDIA GPU code is compiled for AMD GPUs +* Other projects, which describes miscellaneous ZLUDA tools for configuration and debugging +* Diagrams, which show general dependencies between code projects and typical flow of ZLUDA-enabled application + +This document will avoid referring to specific files, structures or functions. The project is still in flux and those details are bound to change soon. High-level design, on the other hand will stay the same. + +### Top-level design assumptions +If you are reading the code or even the rest of this document, you should be aware of assumptions made when developing the project: +* ZLUDA itself is written in Rust + C or C++ source dependencies are fine if they are are impossible to avoid (LLVM). GPU code in HIP/OpenCL C is fine - Rust support for writing GPU code is pitiful +* ZLUDA is focused on end users + By user we mean someone who uses a CUDA program, e.g. a 3D artist using Blender. Developer developing a CUDA application is not an. While we would like to support developers in the future, right now the time constraints do not allow it +* Building the project should require just `cargo build` (if possible) + That means that we avoid relying on `cargo` subcommands, `bindgen` or user setting up environment variables certain way to build the project. We can't avoid depending on some tools (cmake, Python), but that's because of C++ dependencies (LLVM) + +## CUDA runtime + +### Structure of a CUDA application +This is a CUDA "Hello World" application: +``` +__global__ void cuda_hello(){ + printf("Hello World from GPU!\n"); +} + +int main() { + cuda_hello<<<1,1>>>(); + return 0; +} +``` +Anyone familiar with C++ will instantly understand that compiling it is a complicated affair. CUDA does add special syntax for GPUs support: address spaces (`__global__` in the example above), kernel calling (`<<...>>` int the example above). Additionally CUDA allows, to a large degree, mixing CPU code and GPU code. What does all this complexity mean for ZLUDA? + +Absolutely nothing + +Turns out, CUDA compiler transforms CUDA source code into a normal application with calls to CUDA Driver API. The "Hello World" application gets transformed into something not too far from this: +``` +char* cuda_hello_ptx = "..."; + +int main() { + cuInit(); + CUmodule module = NULL; + cuModuleLoad(&module, cuda_hello_ptx); + CUfunction func = NULL; + cuModuleGetFunction(&func, module, "cuda_hello"); + cuLaunchKernel(func, 1,1,1 1,1,1, NULL, NULL, NULL, NULL); + return 0; +} +``` +All functions starting with `cu` are CUDA Driver API calls to functions in a shared library `nvcuda.dll` or `libcuda.so`. ZLUDA simply provides an alternative `nvcuda.dll` or `libcuda.so` with the same functions, which accept the same arguments. The difference is that an NVIDIA-provided library works with NVIDIA GPUs, a ZLUDA-provided library works with AMD GPUs. + +This is a fairly simplified view. In reality, there is more than one CUDA API. Next section explains how to all of them relate to each other and how they are implemented by ZLUDA. + +### Three CUDA APIs + +More experienced CUDA programmers understand that there are two CUDA APIs. Driver API and Runtime API: + +| | Driver API | Runtime API | +|---|---|---| +| __Function prefix__ | `cu` | `cuda` | +| __Dependencies__ | Kernel-mode driver | Driver API | +| __Dynamic (runtime) linking__ | ✅ | ✅ | +| __Static linking__ | ❌| ✅ | + +Driver API is the lowest-level user-mode API. Runtime API builds on top of Driver API and provides miscellaneous high-level features. Since an application can dynamically link to either Driver API or Runtime API, it would seem that ZLUDA needs to provide both. In reality very few applications dynamically link to Runtime API. For the vast majority of applications it's sufficient to provide Driver API for dynamic (runtime) linking. + +Driver API implementation is relatively straightforward: for each function ZLUDA calls a similarly called HIP runtime function. HIP is highly compatible with CUDA. For example, `cuDeviceGetAttribute(...)` is implemented by remapping some of the arguments to HIP versions and calling `hipDeviceGetAttribute(...)`. There's one exception: functions for compiling GPU code: `cuModuleLoadData(...)`, `cuModuleLoadDataEx(...)`. It's covered in the section [CUDA GPU code compiler](#cuda-gpu-code-compiler). + +In addition to Driver API, Runtime API relies on CUDA Dark API. CUDA Driver API exposes function `cuGetExportTable(...)`. This function accepts a GUID and returns a table of function pointers. Those pointer point to undocumented functions forming CUDA Dark API. It's impossible to tell how many of them exist, but debugging experience suggests there are tens of function pointers across tens of tables. A typical application will use one or two most common. Due to they undocumented nature they are exclusively used by Runtime API and NVIDIA libraries (and in by CUDA applications in turn). We don't have names of those functions nor names or types of the arguments. This makes implementing them time-consuming. Dark API functions are are reverse-engineered and implemented by ZLUDA on case-by-case basis once we observe an application making use of it. + +In addition, CUDA applications rely on various NVIDIA-provided libraries: NVML, cuBLAS, cuSPARSE. They are implemented by ZLUDA similarly - by providing a library with the same name and with the same functions, which call to native AMD libraries. + +## CUDA GPU code compiler + +A CUDA application ships with GPU code. This code can be either compiled into PTX or into SASS. The difference is that PTX is a textual assembly not specific to a particular NVIDIA GPU architecture (it is still specific to NVIDIA GPU hardware capabilities) while SASS is a binary asssembly specific to a given a particular NVIDIA GPU architecture. PTX is documented here: [https://docs.nvidia.com/cuda/parallel-thread-execution/index.html](https://docs.nvidia.com/cuda/parallel-thread-execution/index.html). SASS is undocumented. +Majority of applications ship their GPU code in PTX. PTX is forward compatible with future GPU architectures. For all those reasons, currently, our compiler only supports PTX. +The compiler accepts PTX and outputs AMD GPU binary code. It is structured into a sequence of passes. Output of each pass is the input to the next one. Following sections contain description of the current compilation passes. + +Compiler code is end-to-end tested. For every new feature or a bug fix we add a tiny PTX program that makes use of this feature. Firstly it's compiled and the output is compared to the reference LLVM IR. Next it's run and the result is compared to a saved reference result and a result of the same program running on NVIDIA CUDA. + + +## Other projects + +Additionally, ZLUDA ships with more projects which serve some platform-specific purpose or are used for debugging. + +### ZLUDA injector (Windows-only) +This is a Windows executable which starts injects process with ZLUDA redirector and a chosen CUDA Runtime API, typically either ZLUDA or ZLUDA dumper. This is a ZLUDA-specific replacement for `LD_PRELOAD`. + +### ZLUDA redirector (Windows-only) +This is an injector helper library. It intercepts calls to WinAPI `LoadLibrary...(...)` function calls, detecting attempts to load NVIDIA CUDA library and instead forcing load of the CUDA Runtime API chosen by the injector. Furthermore it intercepts calls to WinAPI `CreateProcess..(...)` function calls to inject itself and the chosen CUDA Runtime API into child processes. + +### ZLUDA dumper +This is a CUDA Runtime API implementation for diagnostics and debugging. The library does not have CUDA implementation per-se, but rather for each CUDA Runtime API function call, it intercepts the call, does some kind of pre-processing, routes the call to a real implementation (either ZLUDA or CUDA) and does post-processing. Currently, its main features are: +* Tracing CUDA application execution. A trace is a log of all CUDA function calls (with parameters and files with all the kernels used by the application +* Single kernel dump (in progress). This allows us to dump to disk a single `cuLaunchKernel(...)` with all the parameters (both memory and scalar). Then this kernel can be debugged without running whole application again +* Side-by-side execution (in progress). This allows to run application normally and for every call to `cuLaunchKernel(...)` also do the same call with another CUDA implementation. The differences in their outputs are then logged + + + +## Diagrams + +### Block diagram of the project +External dependencies are in rounded boxes + +```mermaid +graph TD; + subgraph c["ZLUDA debug startup on Windows"]; + ZLUDA_INJECT2[ZLUDA injector]-->ZLUDA_REDIRECT2[ZLUDA redirector]; + ZLUDA_INJECT2-->ZLUDA_R3[ZLUDA dumper]; + ZLUDA_REDIRECT2-->ZLUDA_R3; + ZLUDA_R3-->NV[NVIDIA CUDA Runtime] + end; + subgraph b[ZLUDA startup on Windows]; + ZLUDA_INJECT[ZLUDA injector]-->ZLUDA_REDIRECT[ZLUDA redirector]; + ZLUDA_INJECT-->ZLUDA_RT2[ZLUDA Runtime]; + ZLUDA_REDIRECT-->ZLUDA_RT2; + end; + subgraph a[" "]; + ZLUDA_RT[ZLUDA Runtime]-->HIP([HIP Runtime]); + ZLUDA_RT-->ZLUDA_CMP[ZLUDA PTX Compiler]; + ZLUDA_CMP--generate LLVM bitcode-->LLVM([LLVM]); + ZLUDA_CMP--compile LLVM bitcode to AMD GPU binary-->Lightning([Lightning Compiler]); + end; +``` + +### Flow of a typical ZLUDA-enabled application +Some details omitted and certain interactions simplified +```mermaid +sequenceDiagram + Application->>CUDA Runtime: cudaMemcpy(...) + Note over Application, CUDA Runtime: First call, can be some other function + activate CUDA Runtime + CUDA Runtime->>ZLUDA: cuInit(...) + activate ZLUDA + ZLUDA->>HIP: hipInit(...) + activate HIP + HIP-->>ZLUDA: hipSuccess + deactivate HIP + ZLUDA-->>CUDA Runtime: CUDA_SUCCESS + deactivate ZLUDA + CUDA Runtime->>ZLUDA: cuDeviceGetCount(...) + activate ZLUDA + ZLUDA->>HIP: hipDeviceGetCount(...) + activate HIP + HIP-->>ZLUDA: hipSuccess + deactivate HIP + ZLUDA-->>CUDA Runtime: CUDA_SUCCESS + deactivate ZLUDA + Note over CUDA Runtime, HIP: More calls to CUDA Device API omitted + rect rgb(200, 150, 255) + Note over CUDA Runtime, ZLUDA: Dark API region + CUDA Runtime->>ZLUDA: cuGetExportTable({6BD5FB6C-5BF4-E74A-8987-D93912FD9DF9}) + activate ZLUDA + ZLUDA-->>CUDA Runtime: 0x1776e710 + deactivate ZLUDA + Note right of CUDA Runtime: 0x1776e710 is the address of CUDA Dark API function table {6BD5FB6C-5BF4-E74A-8987-D93912FD9DF9} + CUDA Runtime->>ZLUDA: (0x1776e710+0x30)(0x1499e2000) + activate ZLUDA + Note right of CUDA Runtime: Calling function at index 6 from table at 0x1776e710 + Note left of ZLUDA: ZLUDA recognizes this function as a private variant of cuModuleLoadData + ZLUDA->>ZLUDA: Parse and compile PTX to AMD GPU binary + ZLUDA-->>CUDA Runtime: 0x2982da70 + Note right of CUDA Runtime: We return newly created module handle 0x2982da70 + deactivate ZLUDA + end + Note over CUDA Runtime, HIP: More calls to CUDA Device API omitted + CUDA Runtime->>ZLUDA: cuModuleGetFunction(module: 0x2982da70, ...) + activate ZLUDA + ZLUDA->>HIP: hipModuleGetFunction(...) + activate HIP + HIP-->>ZLUDA: hipSuccess + deactivate HIP + ZLUDA-->>CUDA Runtime: CUDA_SUCCESS + deactivate ZLUDA + Note over CUDA Runtime, HIP: More calls to CUDA Device API omitted + CUDA Runtime-->>Application: cudaSuccess + deactivate CUDA Runtime + Application->>CUDA Runtime: cuLaunchKernel(...) + activate CUDA Runtime + CUDA Runtime->>ZLUDA: cuLaunchKernel(...) + activate ZLUDA + ZLUDA->>HIP: hipLaunchKernel(...) + activate HIP + HIP-->>ZLUDA: hipSuccess + deactivate HIP + ZLUDA-->>CUDA Runtime: CUDA_SUCCESS + deactivate ZLUDA + CUDA Runtime->>Application: cudaSuccess + deactivate CUDA Runtime +``` \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 59899a8..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,61 +0,0 @@ -# Dependencies - -Development builds of ZLUDA requires following dependencies: - -* CMake -* Python 3 - -Additionally the repository has to be cloned with Git submodules initalized. If you cloned the repo without initalizing submodules, do this: -``` -git submodule update --init --recursive -``` - -# Tests - -Tests should be executed with `--workspace` option to test non-default targets: -``` -cargo test --workspace -``` - -# Debugging - -## Debuggging CUDA applications - -When running an application with ZLUDA quite often you will run into subtle bugs or incompatibilities in the generated GPU code. The best way to debug an application's GPU CUDA code is to use ZLUDA dumper. - -Library `zluda_dump` can be injected into a CUDA application and produce a trace which, for every launched GPU function contains: -* PTX source -* Launch arguments (block size, grid size, shared memory size) -* Dump of function arguments. Both after and before - -Example use with GeekBench: -``` -set ZLUDA_DUMP_KERNEL=knn_match -set ZLUDA_DUMP_DIR=C:\temp\zluda_dump -"\zluda_with.exe" "\zluda_dump.dll" -- "geekbench_x86_64.exe" --compute CUDA -``` - -The example above, for every execution of GPU function `knn_match`, will save its details into the directory `C:\temp\zluda_dump` - -This dump can be replayed with `replay.py` script from `zluda_dump` source directory. Use it like this: -``` -python replay.py "C:\temp\zluda_dump\geekbench_x86_64.exe" -``` -You must copy (or symlink) ZLUDA `nvcuda.dll` into PyCUDA directory, so it will run using ZLUDA. Example output: -``` -Intel(R) Graphics [0x3e92] [github.com/vosen/ZLUDA] -C:\temp\zluda_dump\geekbench_x86_64.exe\4140_scale_pyramid -C:\temp\zluda_dump\geekbench_x86_64.exe\4345_convolve_1d_vertical_grayscale - Skipping, launch block size (512) bigger than maximum block size (256) -C:\temp\zluda_dump\geekbench_x86_64.exe\4480_scale_pyramid -6: -Arrays are not equal - -Mismatched elements: 1200 / 19989588 (0.006%) -Max absolute difference: 255 -Max relative difference: 255. - x: array([ 7, 6, 8, ..., 193, 195, 193], dtype=uint8) - y: array([ 7, 6, 8, ..., 193, 195, 193], dtype=uint8) -``` -From this output one can observe that in kernel launch 4480, 6th argument to function `scale_pyramid` differs between what was executed on an NVIDIA GPU using CUDA and Intel GPU using ZLUDA. -__Important__: It's impossible to infer what was the type (and semantics) of argument passed to a GPU function. At our level it's a buffer of bytes and by default `replay.py` simply checks if two buffers are byte-equal. That means you will have a ton of false negatives when running `replay.py`. You should override them for your particular case in `replay.py` - it already contains some overrides for GeekBench kernels \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 038af15..2e9a6ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,61 @@ [workspace] +# Remember to also update the project's Cargo.toml +# if it's a top-level project members = [ + "atiadlxx-sys", + "comgr", + "cuda_base", + "cuda_types", "detours-sys", - "level_zero-sys", - "level_zero", - "spirv_tools-sys", - "zluda", - "zluda_dump", - "zluda_lib", - "zluda_inject", - "zluda_redirect", + "ext/llvm-sys.rs", + "hip_common", + "hip_runtime-sys", + "hipblaslt-sys", + "hipfft-sys", + "hiprt-sys", + "miopen-sys", + "offline_compiler", + "optix_base", + "optix_dump", + "process_address_table", "ptx", + "rocblas-sys", + "rocm_smi-sys", + "rocsparse-sys", + "xtask", + "zluda", + "zluda_api", + "zluda_blas", + "zluda_blaslt", + "zluda_ccl", + "zluda_dark_api", + "zluda_dnn", + "zluda_dump", + "zluda_fft", + "zluda_inject", + "zluda_lib", + "zluda_llvm", + "zluda_ml", + "zluda_redirect", + "zluda_rt", + "zluda_sparse", ] -default-members = ["zluda_lib", "zluda_inject", "zluda_redirect"] +# Cargo does not support OS-specific or profile-specific +# targets. We keep list here to bare minimum and rely on xtask +default-members = [ + "zluda_lib", + "zluda_ml", + "zluda_inject", + "zluda_redirect" +] -[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 +[profile.dev.package.blake3] +opt-level = 3 + +[profile.dev.package.lz4-sys] +opt-level = 3 + +[profile.dev.package.xtask] +opt-level = 3 diff --git a/GeekBench_5_2_3.svg b/GeekBench_5_2_3.svg deleted file mode 100644 index 900e2b1..0000000 --- a/GeekBench_5_2_3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000..adab2b9 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,57 @@ +[config] +default_to_workspace = false +skip_core_tasks = true + +[tasks.build] +run_task = [ + { name = "build-windows", condition = { platforms = ["windows"] } }, + { name = "build-linux", condition = { platforms = ["linux"] } }, +] + +[tasks.build-windows] +command = "cargo" +args = [ + "build", + "-p", "offline_compiler", + "-p", "zluda_dump", + "-p", "zluda_inject", + "-p", "zluda_lib", + "-p", "zluda_ml", + "-p", "zluda_redirect", +] + +[tasks.build-linux] +command = "cargo" +args = [ + "build", + "-p", "offline_compiler", + "-p", "zluda_blas", + "-p", "zluda_blaslt", + "-p", "zluda_ccl", + "-p", "zluda_dnn", + "-p", "zluda_dump", + "-p", "zluda_fft", + "-p", "zluda_lib", + "-p", "zluda_ml", + "-p", "zluda_sparse", +] + +[tasks.build-release] +command = "cargo" +args = [ + "build", + "--release", + "-p", "offline_compiler", + "-p", "zluda_blas", + "-p", "zluda_blaslt", + "-p", "zluda_ccl", + "-p", "zluda_dnn", + "-p", "zluda_dump", + "-p", "zluda_fft", + "-p", "zluda_lib", + "-p", "zluda_ml", + "-p", "zluda_sparse", +] + +[tasks.default] +alias = "build" diff --git a/README.md b/README.md index bb47ed0..8d76a9e 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,250 @@ -__Notice__: Due to private reasons I am currently unable to continue developing this project. If you -want to take it over, fork it and contact me at vosen@vosen.pl - # ZLUDA -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 +ZLUDA lets you run unmodified CUDA applications with near-native performance on ~~Intel~~ AMD GPUs. -## Performance +ZLUDA is currently alpha quality, but it has been confirmed to work with a variety of native CUDA applications: Geekbench, 3DF Zephyr, Blender, Reality Capture, LAMMPS, NAMD, waifu2x, OpenFOAM, Arnold (proof of concept) and more. -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. - -Performance below is normalized to OpenCL performance. 110% means that ZLUDA-implemented CUDA is 10% faster on Intel UHD 630. - -![Performance graph](GeekBench_5_2_3.svg) - -[ZLUDA - detailed results on Geekbench.com](https://browser.geekbench.com/v5/compute/2305009) - -[OpenCL - detailed results on Geekbench.com](https://browser.geekbench.com/v5/compute/2304997) - -Overall, ZLUDA is slower in GeekBench by roughly 2%. - -### Explanation of the results - * Why is ZLUDA faster in some benchmarks?\ - This has not been precisely pinpointed to one thing or another but it's likely a combination of things: - * ZLUDA uses [Level 0](https://spec.oneapi.com/level-zero/latest/index.html), which in general is a more low level, high performance API than OpenCL - * 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 is ZLUDA slower in the remaining benchmarks?\ - The reason is unknown. Most likely, in some tests we compile from suboptimal NVIDIA GPU code and in other tests ZLUDA itself is emitting suboptimal Intel GPU code. For example, SFFT used to be even slower before PR [#22](https://github.com/vosen/ZLUDA/pull/22) - - -## Details - - * 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. 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 close 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 +If you want to give it a try, download it from Release page to the right and read [Usage](#usage) and [Known Issues](#known-issues) sections below. If you are interested in its history and future read [FAQ](#faq) section further below. +![geekbench.svg](geekbench.svg) ## 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 or statically-linked CUDA Runtime API - dynamically-linked CUDA Runtime API is not supported at all ### Windows -You should have the most recent Intel GPU drivers installed.\ -Run your application like this: +Using command line: ``` -\zluda_with.exe -- +\zluda.exe -- ``` +If you downloaded a ZIP file with the release and unpacked it, then `` is the `zluda` directory you have just unpacked.\ +If you are building from source, then `` is subdirectory `target\release`. ### Linux -You should install most recent run-time driver packages as outlined here: https://dgpu-docs.intel.com/installation-guides/index.html. -Run your application like this: +Using command line: ``` -LD_LIBRARY_PATH= +LD_LIBRARY_PATH=":$LD_LIBRARY_PATH" +``` +If you downloaded a ZIP file with the release and unpacked it, then `` is the `zluda` directory you have just unpacked.\ +If you are building from source, then `` is subdirectory `target\release`. + +## Build + +### Prerequisites + +Make sure you have the following installed: +* Git +* CMake +* Python 3 +* Rust (1.66.1 or newer) +* C++ compiler +* (Linux only) ROCm 5.7+ (_not ROCm 6_) (https://rocm.docs.amd.com/en/latest/deploy/linux/install_overview.html) +* (Windows only) Recent AMD Radeon Software Adrenalin (https://rocm.docs.amd.com/en/latest/deploy/linux/install_overview.html) +* (Recommended, optional) Ninja (https://ninja-build.org/) + +Alternatively, if you are building for Linux, [.devcontainer](.devcontainer) directory contains various developer Dockerfiles with all the required dependencies + +### Checkout + +Checkout ZLUDA code with: +``` +git clone --recurse-submodules https://github.com/vosen/zluda.git ``` -## Building -You should have a relatively recent version of Rust installed, then you just do: +### Build +Build by running: ``` -cargo build --release -``` -in the main directory of the project. -### Linux -You should install most recent run-time an developer driver packages as outlined here: https://dgpu-docs.intel.com/installation-guides/index.html. Additionally, you should have `ocl-icd-opencl-dev` (or equivalent) installed. -If you are building on Linux you must also symlink (or rename) the ZLUDA output binaries after ZLUDA build finishes: -``` -ln -s libnvcuda.so target/release/libcuda.so -ln -s libcuda.so target/release/libcuda.so.1 +cargo xtask --release ``` -## Contributing +## Known Issues -If you want to develop ZLUDA itself, read [CONTRIBUTING.md](CONTRIBUTING.md), it contains instructions how to set up dependencies and run tests +### Hardware +- If both integrated AMD GPU and dedicated AMD GPU are present in the system, ZLUDA uses the integrated GPU. + + This is a bug in underying ROCm/HIP runtime. You can work around it by disabling the integrated GPU. + + On Windows we recommend you use environment variable `HIP_VISIBLE_DEVICES=1` environment variable (more [here](https://rocmdocs.amd.com/en/latest/conceptual/gpu-isolation.html#hip-visible-devices)) or disable it system-wide in Device Manager. + + On Linux we recommend you use environment variable `ROCR_VISIBLE_DEVICES=` where `` is the UUID of the dedicated GPU as reported by `rocminfo` command line tool (you can also use `HIP_VISIBLE_DEVICES=1`, but this does not seem to be stable). Alternatively you can disable integrated GPU syste-wide by passing `pci-stub.ids=:` to the kernel options. On Ubuntu you can pass additional kernel options by adding them to `/etc/default/grub` to the option `GRUB_CMDLINE_LINUX_DEFAULT`. You can find `:` with the help of `lspci -nn`. This will emit a series of lines with one of them matching you integrated GPU, for example:\ + `1b:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Device [1002:164e] (rev c1)`\ + `:` ar at the end, in this case `1002:164e`. + +- Integrated GPUs (as tested with Radeon 680M) work in a limited way. Some rarely used GPU operations (abort, printf, etc.) will hang or crash the application. Additionally, performance library support (cuBLAS, cuDNN, etc.) might be limited, rendering more complex applications inoperable. + +- ZLUDA can use AMD server GPUs (as tested with Instinct MI200) with a caveat. + + On Server GPUs, ZLUDA can compile CUDA GPU code to run in one of two modes: + - Fast mode, which is faster, but can make exotic (but correct) GPU code hang. + - Slow mode, which should make GPU code more stable, but can prevent some applications from running on ZLUDA. + + By default, ZLUDA uses fast mode. That's because: + - There's a huge performance difference, fast mode can be twice as fast. + - The code patterns that can trip fast mode were not encountered across multiple projects (SPECFEM3D, QUDA, CHroma, MILC, Kokkos, LAMMPS, OpenFOAM, XGBoost, NAMD, LAMMPS). + + You can use environment variable `ZLUDA_WAVE64_SLOW_MODE=1` to force compilation in slow mode. + + Nothing of that applies to desktop and integrated GPUs (RDNA family). + + +### Software + +- Applications using ZLUDA are slow to start. + + On the first start ZLUDA needs to compile GPU code for the application. This is a one-time cost, compiled GPU code is cached in `%LOCALAPPDATA%` on Windows and in `$XDG_CACHE_HOME` or `$HOME/.cache` on Linux.\ + Some applications will gradually load the GPU code as it is used. If that is undesirable you can try setting environment variable `CUDA_MODULE_LOADING=EAGER`. It depends on how the application was programmed, but it might force to load (and compile) all the kernels on startup, no matter if they are used or not. + +- Applications running ZLUDA might produce slightly different values + + Firstly, ZLUDA ignores some of the floating point denormal and rounding mode information present in the kernels. Secondly, for certain approximate (not IEEE 754) NVIDIA floating point operations in CUDA, ZLUDA blindly uses approximate AMD floating point operations. The two might have a different precision. + +#### CUDA 12+ +- Application built with CUDA 12 and using Thrust crashes with `LLVM ERROR: unsupported libcall legalization`. + + This is a ROCm/HIP bug. Currently, CUDA applications built with CUDA versions pre-12 work the best. Building with CUDA 12 and a pre-CUDA 12 Thrust might also work. + +#### OptiX +- ZLUDA has a bare-minimum OptiX implementation for Arnold. See details in [Arnold](#arnold) section. + +#### Windows +- Antivirus flags ZLUDA as malware. + + ZLUDA launcher (`zluda.exe`) uses some of the techniques used by malware, but for good. `zluda.exe` hijacks the process and redirects all uses of the original NVIDIA's CUDA libraries to use ZLUDA's CUDA instead. + + Don't use `zluda.exe` with games that use anti-cheat. ZLUDA does not support CUDA gaming workloads (PhysX or DLSS) and anti-cheat might mistake `zluda.exe` for a malware or a cheat. + +- Following error when launching an application with `zluda.exe`: `Error: OsError { function: "DetourCreateProcessWithDllsW", error_code: 740, message: "The requested operation requires elevation." }` + + You are launching an application that requires Administrator rights through `zluda.exe`. Try launching `zluda.exe` from an Administrator command line. + +- ZLUDA offers limited support for performance libraries (cuDNN, cuBLAS, cuSPARSE, cuFFT, OptiX, NCCL). Currently, this support is Linux-only and not available on Windows. + +- ZLUDA launcher (`zluda.exe`) does not support 32 bit processes. If an application launches 32 bit subprocess `a.exe` neither the 32 bit process `a.exe`, nor its 64 bit subprocess `a64.exe` will be able to use ZLUDA. This affects e.g. SiSoft Sandra. + +### Applications + +#### Arnold + +* ZLUDA implements minimum of OptiX framework to support Arnold. ZLUDA's OptiX is buggy, unoptimized and incomplete. It's been tested with Arnold 7.1.4.1 command line rendering on Linux. + + ZLUDA-OptiX is not built by default or redistributed in the release. To use it follow those steps: + + * Firstly build a newer version of ROCm LLVM. Version shipped with 5.7.1 is known to miscompile Arnold code. Get it here: https://github.com/ROCm/llvm-project. Switch to a known good commit: `0c7fd5b6d1bbf471d2c068c2b6172d9cfd76b08d` and build it. + + * Then build amd_comgr: https://github.com/ROCm/ROCm-CompilerSupport with the LLVM built in the previous step. I'm using the last commit from https://github.com/ROCm/ROCm-CompilerSupport (`8276083301409001ec7643e68f5ad58b057c21fd`). + + * Now build ZLUDA-OptiX: + ``` + cargo ctask --release + cargo build -p zluda_rt --release + cd target/release + ln -s libnvoptix.so liboptix.so.6.6.0 + cp ../../hiprt-sys/lib/libhiprt64.so . + ``` + + * After those quick and easy steps you can use it with the command line Arnold renderer: + ``` + LD_LIBRARY_PATH=/target/release/ LD_PRELOAD="/build/libamd_comgr.so.2 /liboptix.so.6.6.0" /usr/autodesk/arnold/maya2023/bin/kick attic.ass -device gpu -o /tmp/attic.jpg -v 6 -sl + ``` + + * Keep in mind that ZLUDA-OptiX can only successfully render the simplest Arnold scene (and possibly one more): + + * Cornell box (from [here](https://help.autodesk.com/view/ARNOL/ENU/?guid=arnold_user_guide_ac_scene_source_ac_ass_examples_html)):\ + [![cornell](https://imgur.com/4Vv3GO8s.jpg)](https://imgur.com/4Vv3GO8) + * (used to work, broken now) Attic scene (from [here](https://github.com/wahn/export_multi/tree/master/17_attic)):\ + [![cornell](https://imgur.com/Sut2YMys.jpg)](https://imgur.com/a/2jF9Kb5) + +#### PyTorch + +* PyTorch received very little testing. ZLUDA's coverage of cuDNN APIs is very minimal (just enough to run ResNet-50) and realistically you won't get much running.\ + However if you are interested in trying it out you need to build it from sources with the settings below. Default PyTorch does not ship PTX and uses bundled NCCL which also builds without PTX: + + ``` + export TORCH_CUDA_ARCH_LIST="6.1+PTX" + export CUDAARCHS=61 + export CMAKE_CUDA_ARCHITECTURES=61 + export USE_SYSTEM_NCCL=1 + export NCCL_ROOT_DIR=/usr + export NCCL_INCLUDE_DIR=/usr/include + export NCCL_LIB_DIR=/usr/lib/x86_64-linux-gnu + export USE_EXPERIMENTAL_CUDNN_V8_API=OFF + ``` + or (untested): + ``` + export TORCH_CUDA_ARCH_LIST="6.1+PTX" + export CUDAARCHS=61 + export CMAKE_CUDA_ARCHITECTURES=61 + export USE_SYSTEM_NCCL=1 + export USE_NCCL=0 + export USE_EXPERIMENTAL_CUDNN_V8_API=OFF + ``` + + When running use the following environment variable: + ``` + DISABLE_ADDMM_CUDA_LT=1 + ``` + + +#### 3DF Zephyr +- ZLUDA is much slower than CUDA. + + 3DF Zephyr is triggering an uderlying ROCm/HIP performance issue. + +#### Reality Capture +- ZLUDA is much slower than CUDA. + + Reality Capture is triggering an uderlying ROCm/HIP performance issue. + +#### CompuBench + +- When running multiple tests, first test passes and the subsequent tests fail with `CUDA_ERROR_UNKNOWN`. + + This is a ROCm/HIP bug. Currently, CompuBench tests have to be run one at a time. + +- Some tests output black screen. + + This is due to a bug (or an unintended hardware feature) in CompuBench that just happens to work on NVIDIA GPUs. + +#### V-Ray Benchmark + +- Currently, ZLUDA crashes when running V-Ray benchmark. Nonetheless, certain "lucky" older combinations of ZLUDA and ROCm/HIP are known to run V-Ray Benchmark successfully. + +#### Cinebench CUDA + +- ZLUDA can't run it. Cinebench CUDA benchmark has not been fully compiled with PTX. It may be possible to run it (sans OptiX) if the OctaneBench developers re-compile it. + +#### OctaneBench + +- ZLUDA can't run it. OctaneBench has not been fully compiled with PTX. It may be possible to run it (sans OptiX) if the OctaneBench developers re-compile it. + +## FAQ + +- Why is this project suddenly back after 3 years? What happened to Intel GPU support? + + In 2021 I was contacted by Intel about the development od ZLUDA. I was an Intel employee at the time. While we were building a case for ZLUDA internally, I was asked for a far-reaching discretion: not to advertise the fact that Intel was evaluating ZLUDA and definitely not to make any commits to the public ZLUDA repo. After some deliberation, Intel decided that there is no business case for running CUDA applications on Intel GPUs. + + Shortly thereafter I got in contact with AMD and in early 2022 I have left Intel and signed a ZLUDA development contract with AMD. Once again I was asked for a far-reaching discretion: not to advertise the fact that AMD is evaluating ZLUDA and definitely not to make any commits to the public ZLUDA repo. After two years of development and some deliberation, AMD decided that there is no business case for running CUDA applications on AMD GPUs. + + One of the terms of my contract with AMD was that if AMD did not find it fit for further development, I could release it. Which brings us to today. + + +* What's the future of the project? + + With neither Intel nor AMD interested, we've run out of GPU companies. I'm open though to any offers of that could move the project forward. + + Realistically, it's now abandoned and will only possibly receive updates to run workloads I am personally interested in (DLSS). + +* What underlying GPU API does ZLUDA use? Is it OpenCL? ROCm? Vulkan? + + ZLUDA is built purely on ROCm/HIP. On both Windows and Linux. + +* I am a developer writing CUDA code, does this project help me port my code to ROCm/HIP? + + Currently no, this project is strictly for end users. However this project could be used for a much more gradual porting from CUDA to HIP than anything else. You could start with an unmodified application running on ZLUDA, then have ZLUDA expose the underlying HIP objects (streams, modules, etc.), allowing to rewrite GPU kernels one at a time. Or you could have a mixed CUDA-HIP application where only the most performance sensitive GPU kernels are written in the native AMD language. + +## For developers + +If you are curious about ZLUDA's architecture, you can read a broad overview in [ARCHITECTURE.md](ARCHITECTURE.md). ## License diff --git a/atiadlxx-sys/Cargo.toml b/atiadlxx-sys/Cargo.toml new file mode 100644 index 0000000..3a425cc --- /dev/null +++ b/atiadlxx-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "atiadlxx-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "atiadlxx" + +[lib] \ No newline at end of file diff --git a/atiadlxx-sys/README b/atiadlxx-sys/README new file mode 100644 index 0000000..83cc325 --- /dev/null +++ b/atiadlxx-sys/README @@ -0,0 +1 @@ +bindgen include/wrapper.hpp -o src/adl.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --allowlist-function "ADL2_.*" --allowlist-var "ADL.*" --allowlist-type "ADL.*" \ No newline at end of file diff --git a/atiadlxx-sys/build.rs b/atiadlxx-sys/build.rs new file mode 100644 index 0000000..464b374 --- /dev/null +++ b/atiadlxx-sys/build.rs @@ -0,0 +1,19 @@ +use std::env::VarError; +use std::{env, path::PathBuf}; + +fn main() -> Result<(), VarError> { + println!("cargo:rustc-link-lib=dylib=atiadlxx"); + if cfg!(windows) { + let env = env::var("CARGO_CFG_TARGET_ENV")?; + if env == "msvc" { + let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); + path.push("lib"); + println!("cargo:rustc-link-search=native={}", path.display()); + } else { + println!("cargo:rustc-link-search=native=C:\\Windows\\System32"); + }; + } else { + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); + } + Ok(()) +} diff --git a/atiadlxx-sys/include/adapter.h b/atiadlxx-sys/include/adapter.h new file mode 100644 index 0000000..67dd42f --- /dev/null +++ b/atiadlxx-sys/include/adapter.h @@ -0,0 +1,389 @@ +#ifndef ADAPTER_H_ +#define ADAPTER_H_ + +#include "adl_structures.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ObservedClockInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpCoreClock, int* lpMemoryClock); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ObservedClockInfo_Get(int iAdapterIndex, int* lpCoreClock, int* lpMemoryClock); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ObservedGameClockInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpBaseClock, int* lpGameClock, int* lpBoostClock, int* lpMemoryClock); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Active_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, + int iStatus, + int* lpNewlyActivate); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Active_Set(int iAdapterIndex, + int iStatus, + int* lpNewlyActivate); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Active_SetPrefer(ADL_CONTEXT_HANDLE context, int iAdapterIndex, + int iStatus, + int iNumPreferTarget, + ADLDisplayTarget* lpPreferTarget, + int* lpNewlyActivate); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Active_SetPrefer(int iAdapterIndex, + int iStatus, + int iNumPreferTarget, + ADLDisplayTarget* lpPreferTarget, + int* lpNewlyActivate); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Primary_Get(ADL_CONTEXT_HANDLE context, int* lpPrimaryAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Primary_Get(int* lpPrimaryAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Primary_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Primary_Set(int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ModeSwitch(ADL_CONTEXT_HANDLE context, int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ModeSwitch(int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Active_Get (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpStatus); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Active_Get ( int iAdapterIndex, int* lpStatus); + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Aspects_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, char* lpAspects, int iSize ); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Aspects_Get( int iAdapterIndex, char* lpAspects, int iSize ); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_NumberOfAdapters_Get (ADL_CONTEXT_HANDLE context, int* lpNumAdapters ); + +ADL_EXTERNC int EXPOSED ADL_Adapter_NumberOfAdapters_Get ( int* lpNumAdapters ); + +ADL_EXTERNC int EXPOSED ADL2_Flush_Driver_Data(ADL_CONTEXT_HANDLE context,int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL_Flush_Driver_Data(int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AdapterInfo_Get (ADL_CONTEXT_HANDLE context,LPAdapterInfo lpInfo, int iInputSize); + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VerndorID_Int_get(ADL_CONTEXT_HANDLE context, int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL_Adapter_AdapterInfo_Get (LPAdapterInfo lpInfo, int iInputSize); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AdapterInfoX2_Get (ADL_CONTEXT_HANDLE context,AdapterInfo **lppAdapterInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_AdapterInfoX2_Get (AdapterInfo **lppAdapterInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_RegValueString_Get(int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int iSize, char *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL_Adapter_RegValueString_Set(int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int iSize, char *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_RegValueString_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int iSize, char *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_RegValueString_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int iSize, char *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_RegValueInt_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL_Adapter_RegValueInt_Get(int iAdapterIndex, int iDriverPathOption, char* szSubKey, char *szKeyName, int *lpKeyValue); + +ADL_EXTERNC int EXPOSED ADL_Adapter_RegValueInt_Set(int iAdapterIndex, int iDriverPathOption, char *szSubKey, char *szKeyName, int iKeyValue); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_RegValueInt_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDriverPathOption, char *szSubKey, char *szKeyName, int iKeyValue); + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ASICFamilyType_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpAsicTypes, int* lpValids); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ASICFamilyType_Get (int iAdapterIndex, int* lpAsicTypes, int* lpValids); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Speed_Caps (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpCaps, int* lpValid); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Speed_Caps (int iAdapterIndex, int* lpCaps, int* lpValid); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Speed_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Speed_Get (int iAdapterIndex, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Speed_Set (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iSpeed); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Speed_Set (int iAdapterIndex, int iSpeed); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Accessibility_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpAccessibility); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Accessibility_Get (int iAdapterIndex, int *lpAccessibility); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VideoBiosInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLBiosInfo* lpBiosInfo ); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VideoBiosInfo_Get( int iAdapterIndex, ADLBiosInfo* lpBiosInfo ); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ID_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpAdapterID); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ID_Get(int iAdapterIndex, int* lpAdapterID); + +ADL_EXTERNC int EXPOSED ADL2_AdapterX2_Caps(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLAdapterCapsX2 *adapterCaps); + +ADL_EXTERNC int EXPOSED ADL_AdapterX2_Caps(int iAdapterIndex, ADLAdapterCapsX2 *adapterCaps); + +ADL_EXTERNC int EXPOSED ADL2_Stress_Test_Cap(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion); + +ADL_EXTERNC int EXPOSED ADL2_Throttle_Notification_Cap(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AceDefaults_Restore(ADL_CONTEXT_HANDLE context, int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AdapterInfoX4_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* numAdapters, AdapterInfoX2** lppAdapterInfoX2); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AdapterInfoX3_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* numAdapters, AdapterInfo** lppAdapterInfo); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_AdapterList_Disable(ADL_CONTEXT_HANDLE context, int iNumAdapters, int *lpAdapterIndexList, bool isSkipSaveDB = false); + +ADL_EXTERNC int EXPOSED ADL_Adapter_AdapterList_Disable(int iNumAdapters, int *lpAdapterIndexList); + +ADL_EXTERNC int EXPOSED ADL_Adapter_BigSw_Info_Get(int iAdapterIndex, int* lpBigSwSupportMajor, int* lpBigSwSupportMinor, int* lpRedStoneSupport); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_BigSw_Info_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpBigSwSupportMajor, int* lpBigSwSupportMinor, int* lpRedStoneSupport); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLAdapterCaps *adapterCaps); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Caps(int iAdapterIndex, ADLAdapterCaps *adapterCaps); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ChipSetInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLChipSetInfo * lpChipSetInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ChipSetInfo_Get(int iAdapterIndex, ADLChipSetInfo * lpChipSetInfo); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Feature_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_UIFEATURES_GROUP iFeatureID, int *iIsFeatureSupported); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_HBC_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpHbcCapable); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Headless_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpHeadless); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_IsGamingDriver_Info_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpCwgSupport, int* lpIsGamingMode); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_MemoryInfo2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLMemoryInfo2 *lpMemoryInfo2); + +ADL_EXTERNC int EXPOSED ADL_Adapter_MemoryInfo2_Get(int iAdapterIndex, ADLMemoryInfo2 *lpMemoryInfo2); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_TRNG_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iTRNGSize, int iTRNGBufferSize, char *lpTRNGBuffer); + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Modes_ReEnumerate(ADL_CONTEXT_HANDLE context); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Modes_ReEnumerate(); + +ADL_EXTERNC int EXPOSED ADL2_Feature_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_UIFEATURES_GROUP iFeatureID, int *iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Feature_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_UIFEATURES_GROUP iFeatureID, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_GcnAsicInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLGcnInfo* gcnInfo); + +ADL_EXTERNC int EXPOSED ADL2_GPUVMPageSize_Info_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iVMPageSizeSupport, int* iVMPageSizeType); + +ADL_EXTERNC int EXPOSED ADL2_GPUVMPageSize_Info_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iVMPageSizeType); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VRAMUsage_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iVRAMUsageInMB); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_DedicatedVRAMUsage_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iVRAMUsageInMB); + + + + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VideoTheaterModeInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpOverlayDisplayMode, int* lpSavedSettings); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VideoTheaterModeInfo_Get(int iAdapterIndex, int* lpOverlayDisplayMode, int* lpSavedSettings); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VideoTheaterModeInfo_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iOverlayDisplayMode, int iSavedSettings); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VideoTheaterModeInfo_Set(int iAdapterIndex, int iOverlayDisplayMode, int iSavedSettings); + +ADL_EXTERNC int EXPOSED ADL2_MMD_Features_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLFeatureCaps ** lppFeatureCaps, int * lpFeatureCount); + +ADL_EXTERNC int EXPOSED ADL_MMD_Features_Caps(int iAdapterIndex, ADLFeatureCaps ** lppFeatureCaps, int * lpFeatureCount); + +ADL_EXTERNC int EXPOSED ADL2_MMD_FeatureValues_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLFeatureValues ** lppFeatureValues, int * lpFeatureCount); + +ADL_EXTERNC int EXPOSED ADL_MMD_FeatureValues_Get(int iAdapterIndex, ADLFeatureValues ** lppFeatureValues, int * lpFeatureCount); + +ADL_EXTERNC int EXPOSED ADL2_MMD_FeatureValues_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLFeatureValues * lpFeatureValues, int iFeatureCount, int ClientID); + +ADL_EXTERNC int EXPOSED ADL_MMD_FeatureValues_Set(int iAdapterIndex, ADLFeatureValues * lpFeatureValues, int iFeatureCount, int ClientID); + + + +#if defined (_WIN32) || defined(_WIN64) + +ADL_EXTERNC int EXPOSED ADL2_PageMigration_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLVirtualSegmentSettingsOutput *lpVirtualSegSettings); + +ADL_EXTERNC int EXPOSED ADL2_PageMigration_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iEnabled, int iNewSize); + +#endif /*(_WIN32) || (_WIN64)*/ + + + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Crossfire_Caps (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpPreferred, int* lpNumComb, ADLCrossfireComb **ppCrossfireComb); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Crossfire_Caps (int iAdapterIndex, int* lpPreferred, int* lpNumComb, ADLCrossfireComb **ppCrossfireComb); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Crossfire_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb, ADLCrossfireInfo *lpCrossfireInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Crossfire_Get (int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb, ADLCrossfireInfo *lpCrossfireInfo); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_Crossfire_Set (ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb); + +ADL_EXTERNC int EXPOSED ADL_Adapter_Crossfire_Set (int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_MVPU_Set (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iState); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_CrossfireX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb, ADLCrossfireInfo *lpCrossfireInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_CrossfireX2_Get(int iAdapterIndex, ADLCrossfireComb *lpCrossfireComb, ADLCrossfireInfo *lpCrossfireInfo); + + + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_BoardLayout_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpValidFlags, int *lpNumberSlots, ADLBracketSlotInfo** lppBracketSlot, int* lpNumberConnector, ADLConnectorInfo** lppConnector); + +ADL_EXTERNC int EXPOSED ADL_Adapter_BoardLayout_Get(int iAdapterIndex, int* lpValidFlags, int *lpNumberSlots, ADLBracketSlotInfo** lppBracketSlot, int* lpNumberConnector, ADLConnectorInfo** lppConnector); + + +ADL_EXTERNC int EXPOSED ADL2_Adapter_SupportedConnections_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort, ADLSupportedConnections* lpADLSupportedConnections); + +ADL_EXTERNC int EXPOSED ADL_Adapter_SupportedConnections_Get(int iAdapterIndex, ADLDevicePort devicePort, ADLSupportedConnections* lpADLSupportedConnections); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ConnectionState_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort, ADLConnectionState* lpADLConnectionState); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ConnectionState_Get(int iAdapterIndex, ADLDevicePort devicePort, ADLConnectionState* lpADLConnectionState); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_EmulationMode_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort, int iEmulationMode); + +ADL_EXTERNC int EXPOSED ADL_Adapter_EmulationMode_Set(int iAdapterIndex, ADLDevicePort devicePort, int iEmulationMode); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ConnectionData_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort, ADLConnectionData ConnectionData); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ConnectionData_Set(int iAdapterIndex, ADLDevicePort devicePort, ADLConnectionData ConnectionData); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ConnectionData_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort, int iQueryType, ADLConnectionData* lpConnectionData); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ConnectionData_Get(int iAdapterIndex, ADLDevicePort devicePort, int iQueryType, ADLConnectionData* lpConnectionData); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ConnectionData_Remove(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLDevicePort devicePort); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ConnectionData_Remove(int iAdapterIndex, ADLDevicePort devicePort); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_EDIDManagement_Caps(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL_Adapter_EDIDManagement_Caps(int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_Workstation_GlobalEDIDPersistence_Get(ADL_CONTEXT_HANDLE context,int *lpCurResultValue, int *lpDefResultValue); + +ADL_EXTERNC int EXPOSED ADL_Workstation_GlobalEDIDPersistence_Get(int *lpCurResultValue, int *lpDefResultValue); + +ADL_EXTERNC int EXPOSED ADL2_Workstation_GlobalEDIDPersistence_Set(ADL_CONTEXT_HANDLE context,int iCurState); + +ADL_EXTERNC int EXPOSED ADL_Workstation_GlobalEDIDPersistence_Set(int iCurState); + + + +ADL_EXTERNC int EXPOSED ADL2_ElmCompatibilityMode_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_ElmCompatibilityMode_Status_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpValue); + +ADL_EXTERNC int EXPOSED ADL2_ElmCompatibilityMode_Status_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iValue); + + +#if defined (_WIN32) || defined(_WIN64) +ADL_EXTERNC int EXPOSED ADL2_FPS_Caps (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpSupported, int *lpVersion); + +ADL_EXTERNC int EXPOSED ADL2_FPS_Settings_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLFPSSettingsOutput *lpFPSSettings); + +ADL_EXTERNC int EXPOSED ADL2_FPS_Settings_Set (ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLFPSSettingsInput lpFPSSettings); + +ADL_EXTERNC int EXPOSED ADL2_FPS_Settings_Reset (ADL_CONTEXT_HANDLE context,int iAdapterIndex); + + +ADL_EXTERNC int EXPOSED ADL2_RIS_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_RIS_SETTINGS settings, ADL_RIS_NOTFICATION_REASON changeReason); + +ADL_EXTERNC int EXPOSED ADL2_RIS_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_RIS_SETTINGS* settings); + +ADL_EXTERNC int EXPOSED ADL2_CHILL_SettingsX2_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_CHILL_SETTINGS settings, ADL_CHILL_NOTFICATION_REASON changeReason, ADL_ERROR_REASON* errorReason); + +ADL_EXTERNC int EXPOSED ADL2_CHILL_SettingsX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_CHILL_SETTINGS* settings); + + +ADL_EXTERNC int EXPOSED ADL2_DELAG_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_DELAG_SETTINGS settings, ADL_DELAG_NOTFICATION_REASON changeReason, ADL_ERROR_REASON* errorReason); + +ADL_EXTERNC int EXPOSED ADL2_DELAG_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_DELAG_SETTINGS* settings); + +ADL_EXTERNC int EXPOSED ADL2_BOOST_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_BOOST_SETTINGS settings, ADL_BOOST_NOTFICATION_REASON changeReason, ADL_ERROR_REASON* errorReason); + +ADL_EXTERNC int EXPOSED ADL2_BOOST_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_BOOST_SETTINGS* settings); + +ADL_EXTERNC int EXPOSED ADL2_PROVSR_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_PROVSR_SETTINGS settings, ADL_PROVSR_NOTFICATION_REASON changeReason, ADL_ERROR_REASON* errorReason); + + +ADL_EXTERNC int EXPOSED ADL2_PROVSR_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_PROVSR_SETTINGS* settings); + + +ADL_EXTERNC int EXPOSED ADL2_Chill_Settings_Notify(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iChanged); + +ADL_EXTERNC int EXPOSED ADL2_Chill_Settings_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iEnabled); + +ADL_EXTERNC int EXPOSED ADL2_Chill_Settings_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpEnabled); + +ADL_EXTERNC int EXPOSED ADL2_Chill_Caps_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iSupported, int* iCheckCaps); + +ADL_EXTERNC int EXPOSED ADL2_PerformanceTuning_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_PerfTuning_Status_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpPTuningValue); + +ADL_EXTERNC int EXPOSED ADL2_PerfTuning_Status_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int lpPTuningValue); + +ADL_EXTERNC int EXPOSED ADL2_PPW_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_PPW_Status_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpFPWValue); + +ADL_EXTERNC int EXPOSED ADL2_PPW_Status_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iFPWValue); + +#endif /*(_WIN32) || (_WIN64)*/ + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *iIsFrameMonitorSupported); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_Start(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int VidPnSourceId); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_Stop(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int VidPnSourceId); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int VidPnSourceId, float *iFramesPerSecond); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_FrameDuration_Enable(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_FRAME_DURATION_HANDLE* frameDurationHandle); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_FrameDuration_Disable(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_FRAME_DURATION_HANDLE* frameDurationHandle); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_FrameDuration_Start(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int VidPnSourceId); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_FrameDuration_Stop(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int VidPnSourceId); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_FrameMetrics_FrameDuration_Get(ADL_CONTEXT_HANDLE context, ADL_FRAME_DURATION_HANDLE frameDurationHandle, unsigned long long * pFrameDurationsArr, unsigned int frameDurationsArrSize, unsigned int *elementsCopied); + +// Deprecated APIs + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ClockInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLClockInfo* lpClockInfo); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ClockInfo_Get(int iAdapterIndex, ADLClockInfo* lpClockInfo); + +ADL_EXTERNC int EXPOSED ADL2_Display_AdapterID_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpAdapterID); + +ADL_EXTERNC int EXPOSED ADL_Display_AdapterID_Get(int iAdapterIndex, int* lpAdapterID); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_EDC_ErrorRecords_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* pErrorrecordCount, ADLErrorRecord* errorRecords); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_EDC_ErrorInjection_Set (ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLErrorInjection* errorInjection); + + +#endif /* ADAPTER_H_ */ diff --git a/atiadlxx-sys/include/adl.h b/atiadlxx-sys/include/adl.h new file mode 100644 index 0000000..2056121 --- /dev/null +++ b/atiadlxx-sys/include/adl.h @@ -0,0 +1,64 @@ +#ifndef ADL_H_ +#define ADL_H_ + +#include "adl_sdk.h" +//#include "amd_only/amd_structures.h" + +#include "adapter.h" +#include "display.h" +//#include "workstation.h" +//#include "displaysmanager.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + + +ADL_EXTERNC int EXPOSED ADL_Main_ControlX2_Create ( ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters, ADLThreadingModel threadingModel ); + +ADL_EXTERNC int EXPOSED ADL2_Main_ControlX2_Create ( ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters, ADL_CONTEXT_HANDLE* context, ADLThreadingModel threadingModel); + +ADL_EXTERNC int EXPOSED ADL2_Main_ControlX3_Create(ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters, ADL_CONTEXT_HANDLE* context, ADLThreadingModel threadingModel, int adlCreateOptions); + +ADL_EXTERNC int EXPOSED ADL_Main_Control_Create ( ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters ); + +ADL_EXTERNC int EXPOSED ADL2_Main_Control_Create ( ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters, ADL_CONTEXT_HANDLE* context); + +ADL_EXTERNC int EXPOSED ADL2_Main_Control_Refresh (ADL_CONTEXT_HANDLE context); + +ADL_EXTERNC int EXPOSED ADL_Main_Control_Refresh (); + +ADL_EXTERNC int EXPOSED ADL_Main_Control_Destroy (); + +ADL_EXTERNC int EXPOSED ADL2_Main_Control_Destroy (ADL_CONTEXT_HANDLE context); + +ADL_EXTERNC EXPOSED void* ADL2_Main_Control_GetProcAddress (ADL_CONTEXT_HANDLE context, void* lpModule, char* lpProcName ); + +ADL_EXTERNC EXPOSED void* ADL_Main_Control_GetProcAddress ( void* lpModule, char* lpProcName ); + + +ADL_EXTERNC int EXPOSED ADL2_RegisterEvent(ADL_CONTEXT_HANDLE context, int eventID, void* evntHandle); + +ADL_EXTERNC int EXPOSED ADL2_UnRegisterEvent(ADL_CONTEXT_HANDLE context, int eventID, void* evntHandle); + + + +ADL_EXTERNC int EXPOSED ADL2_RegisterEventX2(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int clientID, int eventID, void* evntHandle); + +ADL_EXTERNC int EXPOSED ADL2_UnRegisterEventX2(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int clientID, int eventID, void* evntHandle); + +ADL_EXTERNC int EXPOSED ADL2_PerGPU_GDEvent_Register(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int clientID, int eventID, void* evntHandle); + +ADL_EXTERNC int EXPOSED ADL2_PerGPU_GDEvent_UnRegister(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int clientID, int eventID, void* evntHandle); + + +#endif /* ADL_H_ */ \ No newline at end of file diff --git a/atiadlxx-sys/include/adl_defines.h b/atiadlxx-sys/include/adl_defines.h new file mode 100644 index 0000000..b3aa731 --- /dev/null +++ b/atiadlxx-sys/include/adl_defines.h @@ -0,0 +1,2596 @@ +// +// Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// MIT LICENSE: +// 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. + +/// \file adl_defines.h +/// \brief Contains all definitions exposed by ADL for \ALL platforms.\n Included in ADL SDK +/// +/// This file contains all definitions used by ADL. +/// The ADL definitions include the following: +/// \li ADL error codes +/// \li Enumerations for the ADLDisplayInfo structure +/// \li Maximum limits +/// + +#ifndef ADL_DEFINES_H_ +#define ADL_DEFINES_H_ + +/// \defgroup DEFINES Constants and Definitions +/// @{ + +/// \defgroup define_misc Miscellaneous Constant Definitions +/// @{ + +/// \name General Definitions +/// @{ + +/// Defines ADL_TRUE +#define ADL_TRUE 1 +/// Defines ADL_FALSE +#define ADL_FALSE 0 + +/// Defines the maximum string length +#define ADL_MAX_CHAR 4096 +/// Defines the maximum string length +#define ADL_MAX_PATH 256 +/// Defines the maximum number of supported adapters +#define ADL_MAX_ADAPTERS 250 +/// Defines the maxumum number of supported displays +#define ADL_MAX_DISPLAYS 150 +/// Defines the maxumum string length for device name +#define ADL_MAX_DEVICENAME 32 +/// Defines for all adapters +#define ADL_ADAPTER_INDEX_ALL -1 +/// Defines APIs with iOption none +#define ADL_MAIN_API_OPTION_NONE 0 +/// @} + +/// \name Definitions for iOption parameter used by +/// ADL_Display_DDCBlockAccess_Get() +/// @{ + +/// Switch to DDC line 2 before sending the command to the display. +#define ADL_DDC_OPTION_SWITCHDDC2 0x00000001 +/// Save command in the registry under a unique key, corresponding to parameter \b iCommandIndex +#define ADL_DDC_OPTION_RESTORECOMMAND 0x00000002 +/// Combine write-read DDC block access command. +#define ADL_DDC_OPTION_COMBOWRITEREAD 0x00000010 +/// Direct DDC access to the immediate device connected to graphics card. +/// MST with this option set: DDC command is sent to first branch. +/// MST with this option not set: DDC command is sent to the end node sink device. +#define ADL_DDC_OPTION_SENDTOIMMEDIATEDEVICE 0x00000020 +/// @} + +/// \name Values for +/// ADLI2C.iAction used with ADL_Display_WriteAndReadI2C() +/// @{ + +#define ADL_DL_I2C_ACTIONREAD 0x00000001 +#define ADL_DL_I2C_ACTIONWRITE 0x00000002 +#define ADL_DL_I2C_ACTIONREAD_REPEATEDSTART 0x00000003 +#define ADL_DL_I2C_ACTIONIS_PRESENT 0x00000004 +/// @} + + +/// @} //Misc + +/// \defgroup define_adl_results Result Codes +/// This group of definitions are the various results returned by all ADL functions \n +/// @{ +/// All OK, but need to wait +#define ADL_OK_WAIT 4 +/// All OK, but need restart +#define ADL_OK_RESTART 3 +/// All OK but need mode change +#define ADL_OK_MODE_CHANGE 2 +/// All OK, but with warning +#define ADL_OK_WARNING 1 +/// ADL function completed successfully +#define ADL_OK 0 +/// Generic Error. Most likely one or more of the Escape calls to the driver failed! +#define ADL_ERR -1 +/// ADL not initialized +#define ADL_ERR_NOT_INIT -2 +/// One of the parameter passed is invalid +#define ADL_ERR_INVALID_PARAM -3 +/// One of the parameter size is invalid +#define ADL_ERR_INVALID_PARAM_SIZE -4 +/// Invalid ADL index passed +#define ADL_ERR_INVALID_ADL_IDX -5 +/// Invalid controller index passed +#define ADL_ERR_INVALID_CONTROLLER_IDX -6 +/// Invalid display index passed +#define ADL_ERR_INVALID_DIPLAY_IDX -7 +/// Function not supported by the driver +#define ADL_ERR_NOT_SUPPORTED -8 +/// Null Pointer error +#define ADL_ERR_NULL_POINTER -9 +/// Call can't be made due to disabled adapter +#define ADL_ERR_DISABLED_ADAPTER -10 +/// Invalid Callback +#define ADL_ERR_INVALID_CALLBACK -11 +/// Display Resource conflict +#define ADL_ERR_RESOURCE_CONFLICT -12 +//Failed to update some of the values. Can be returned by set request that include multiple values if not all values were successfully committed. +#define ADL_ERR_SET_INCOMPLETE -20 +/// There's no Linux XDisplay in Linux Console environment +#define ADL_ERR_NO_XDISPLAY -21 +/// escape call failed becuse of incompatiable driver found in driver store +#define ADL_ERR_CALL_TO_INCOMPATIABLE_DRIVER -22 +/// not running as administrator +#define ADL_ERR_NO_ADMINISTRATOR_PRIVILEGES -23 +/// Feature Sync Start api is not called yet +#define ADL_ERR_FEATURESYNC_NOT_STARTED -24 +/// Adapter is in an invalid power state +#define ADL_ERR_INVALID_POWER_STATE -25 + +/// @} +/// + +/// \defgroup define_display_type Display Type +/// Define Monitor/CRT display type +/// @{ +/// Define Monitor display type +#define ADL_DT_MONITOR 0 +/// Define TV display type +#define ADL_DT_TELEVISION 1 +/// Define LCD display type +#define ADL_DT_LCD_PANEL 2 +/// Define DFP display type +#define ADL_DT_DIGITAL_FLAT_PANEL 3 +/// Define Componment Video display type +#define ADL_DT_COMPONENT_VIDEO 4 +/// Define Projector display type +#define ADL_DT_PROJECTOR 5 +/// @} + +/// \defgroup define_display_connection_type Display Connection Type +/// @{ +/// Define unknown display output type +#define ADL_DOT_UNKNOWN 0 +/// Define composite display output type +#define ADL_DOT_COMPOSITE 1 +/// Define SVideo display output type +#define ADL_DOT_SVIDEO 2 +/// Define analog display output type +#define ADL_DOT_ANALOG 3 +/// Define digital display output type +#define ADL_DOT_DIGITAL 4 +/// @} + +/// \defgroup define_color_type Display Color Type and Source +/// Define Display Color Type and Source +/// @{ +#define ADL_DISPLAY_COLOR_BRIGHTNESS (1 << 0) +#define ADL_DISPLAY_COLOR_CONTRAST (1 << 1) +#define ADL_DISPLAY_COLOR_SATURATION (1 << 2) +#define ADL_DISPLAY_COLOR_HUE (1 << 3) +#define ADL_DISPLAY_COLOR_TEMPERATURE (1 << 4) + +/// Color Temperature Source is EDID +#define ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_EDID (1 << 5) +/// Color Temperature Source is User +#define ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_USER (1 << 6) +/// @} + +/// \defgroup define_adjustment_capabilities Display Adjustment Capabilities +/// Display adjustment capabilities values. Returned by ADL_Display_AdjustCaps_Get +/// @{ +#define ADL_DISPLAY_ADJUST_OVERSCAN (1 << 0) +#define ADL_DISPLAY_ADJUST_VERT_POS (1 << 1) +#define ADL_DISPLAY_ADJUST_HOR_POS (1 << 2) +#define ADL_DISPLAY_ADJUST_VERT_SIZE (1 << 3) +#define ADL_DISPLAY_ADJUST_HOR_SIZE (1 << 4) +#define ADL_DISPLAY_ADJUST_SIZEPOS (ADL_DISPLAY_ADJUST_VERT_POS | ADL_DISPLAY_ADJUST_HOR_POS | ADL_DISPLAY_ADJUST_VERT_SIZE | ADL_DISPLAY_ADJUST_HOR_SIZE) +#define ADL_DISPLAY_CUSTOMMODES (1<<5) +#define ADL_DISPLAY_ADJUST_UNDERSCAN (1<<6) +/// @} + +///Down-scale support +#define ADL_DISPLAY_CAPS_DOWNSCALE (1 << 0) + +/// Sharpness support +#define ADL_DISPLAY_CAPS_SHARPNESS (1 << 0) + +/// \defgroup define_desktop_config Desktop Configuration Flags +/// These flags are used by ADL_DesktopConfig_xxx +/// \deprecated This API has been deprecated because it was only used for RandR 1.1 (Red Hat 5.x) distributions which is now not supported. +/// @{ +#define ADL_DESKTOPCONFIG_UNKNOWN 0 /* UNKNOWN desktop config */ +#define ADL_DESKTOPCONFIG_SINGLE (1 << 0) /* Single */ +#define ADL_DESKTOPCONFIG_CLONE (1 << 2) /* Clone */ +#define ADL_DESKTOPCONFIG_BIGDESK_H (1 << 4) /* Big Desktop Horizontal */ +#define ADL_DESKTOPCONFIG_BIGDESK_V (1 << 5) /* Big Desktop Vertical */ +#define ADL_DESKTOPCONFIG_BIGDESK_HR (1 << 6) /* Big Desktop Reverse Horz */ +#define ADL_DESKTOPCONFIG_BIGDESK_VR (1 << 7) /* Big Desktop Reverse Vert */ +#define ADL_DESKTOPCONFIG_RANDR12 (1 << 8) /* RandR 1.2 Multi-display */ +/// @} + +/// needed for ADLDDCInfo structure +#define ADL_MAX_DISPLAY_NAME 256 + +/// \defgroup define_edid_flags Values for ulDDCInfoFlag +/// defines for ulDDCInfoFlag EDID flag +/// @{ +#define ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE (1 << 0) +#define ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION (1 << 1) +#define ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE (1 << 2) +#define ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE (1 << 3) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI (1 << 4) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601 (1 << 5) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709 (1 << 6) +/// @} + +/// \defgroup define_displayinfo_connector Display Connector Type +/// defines for ADLDisplayInfo.iDisplayConnector +/// @{ +#define ADL_DISPLAY_CONTYPE_UNKNOWN 0 +#define ADL_DISPLAY_CONTYPE_VGA 1 +#define ADL_DISPLAY_CONTYPE_DVI_D 2 +#define ADL_DISPLAY_CONTYPE_DVI_I 3 +#define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NTSC 4 +#define ADL_DISPLAY_CONTYPE_ATICVDONGLE_JPN 5 +#define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_JPN 6 +#define ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_NTSC 7 +#define ADL_DISPLAY_CONTYPE_PROPRIETARY 8 +#define ADL_DISPLAY_CONTYPE_HDMI_TYPE_A 10 +#define ADL_DISPLAY_CONTYPE_HDMI_TYPE_B 11 +#define ADL_DISPLAY_CONTYPE_SVIDEO 12 +#define ADL_DISPLAY_CONTYPE_COMPOSITE 13 +#define ADL_DISPLAY_CONTYPE_RCA_3COMPONENT 14 +#define ADL_DISPLAY_CONTYPE_DISPLAYPORT 15 +#define ADL_DISPLAY_CONTYPE_EDP 16 +#define ADL_DISPLAY_CONTYPE_WIRELESSDISPLAY 17 +#define ADL_DISPLAY_CONTYPE_USB_TYPE_C 18 +/// @} + +/// TV Capabilities and Standards +/// \defgroup define_tv_caps TV Capabilities and Standards +/// \deprecated Dropping support for TV displays +/// @{ +#define ADL_TV_STANDARDS (1 << 0) +#define ADL_TV_SCART (1 << 1) + +/// TV Standards Definitions +#define ADL_STANDARD_NTSC_M (1 << 0) +#define ADL_STANDARD_NTSC_JPN (1 << 1) +#define ADL_STANDARD_NTSC_N (1 << 2) +#define ADL_STANDARD_PAL_B (1 << 3) +#define ADL_STANDARD_PAL_COMB_N (1 << 4) +#define ADL_STANDARD_PAL_D (1 << 5) +#define ADL_STANDARD_PAL_G (1 << 6) +#define ADL_STANDARD_PAL_H (1 << 7) +#define ADL_STANDARD_PAL_I (1 << 8) +#define ADL_STANDARD_PAL_K (1 << 9) +#define ADL_STANDARD_PAL_K1 (1 << 10) +#define ADL_STANDARD_PAL_L (1 << 11) +#define ADL_STANDARD_PAL_M (1 << 12) +#define ADL_STANDARD_PAL_N (1 << 13) +#define ADL_STANDARD_PAL_SECAM_D (1 << 14) +#define ADL_STANDARD_PAL_SECAM_K (1 << 15) +#define ADL_STANDARD_PAL_SECAM_K1 (1 << 16) +#define ADL_STANDARD_PAL_SECAM_L (1 << 17) +/// @} + + +/// \defgroup define_video_custom_mode Video Custom Mode flags +/// Component Video Custom Mode flags. This is used by the iFlags parameter in ADLCustomMode +/// @{ +#define ADL_CUSTOMIZEDMODEFLAG_MODESUPPORTED (1 << 0) +#define ADL_CUSTOMIZEDMODEFLAG_NOTDELETETABLE (1 << 1) +#define ADL_CUSTOMIZEDMODEFLAG_INSERTBYDRIVER (1 << 2) +#define ADL_CUSTOMIZEDMODEFLAG_INTERLACED (1 << 3) +#define ADL_CUSTOMIZEDMODEFLAG_BASEMODE (1 << 4) +/// @} + +/// \defgroup define_ddcinfoflag Values used for DDCInfoFlag +/// ulDDCInfoFlag field values used by the ADLDDCInfo structure +/// @{ +#define ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE (1 << 0) +#define ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION (1 << 1) +#define ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE (1 << 2) +#define ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE (1 << 3) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI (1 << 4) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601 (1 << 5) +#define ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709 (1 << 6) +/// @} + +/// \defgroup define_cv_dongle Values used by ADL_CV_DongleSettings_xxx +/// The following is applicable to ADL_DISPLAY_CONTYPE_ATICVDONGLE_JP and ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_D only +/// \deprecated Dropping support for Component Video displays +/// @{ +#define ADL_DISPLAY_CV_DONGLE_D1 (1 << 0) +#define ADL_DISPLAY_CV_DONGLE_D2 (1 << 1) +#define ADL_DISPLAY_CV_DONGLE_D3 (1 << 2) +#define ADL_DISPLAY_CV_DONGLE_D4 (1 << 3) +#define ADL_DISPLAY_CV_DONGLE_D5 (1 << 4) + +/// The following is applicable to ADL_DISPLAY_CONTYPE_ATICVDONGLE_NA and ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C only + +#define ADL_DISPLAY_CV_DONGLE_480I (1 << 0) +#define ADL_DISPLAY_CV_DONGLE_480P (1 << 1) +#define ADL_DISPLAY_CV_DONGLE_540P (1 << 2) +#define ADL_DISPLAY_CV_DONGLE_720P (1 << 3) +#define ADL_DISPLAY_CV_DONGLE_1080I (1 << 4) +#define ADL_DISPLAY_CV_DONGLE_1080P (1 << 5) +#define ADL_DISPLAY_CV_DONGLE_16_9 (1 << 6) +#define ADL_DISPLAY_CV_DONGLE_720P50 (1 << 7) +#define ADL_DISPLAY_CV_DONGLE_1080I25 (1 << 8) +#define ADL_DISPLAY_CV_DONGLE_576I25 (1 << 9) +#define ADL_DISPLAY_CV_DONGLE_576P50 (1 << 10) +#define ADL_DISPLAY_CV_DONGLE_1080P24 (1 << 11) +#define ADL_DISPLAY_CV_DONGLE_1080P25 (1 << 12) +#define ADL_DISPLAY_CV_DONGLE_1080P30 (1 << 13) +#define ADL_DISPLAY_CV_DONGLE_1080P50 (1 << 14) +/// @} + +/// \defgroup define_formats_ovr Formats Override Settings +/// Display force modes flags +/// @{ +/// +#define ADL_DISPLAY_FORMAT_FORCE_720P 0x00000001 +#define ADL_DISPLAY_FORMAT_FORCE_1080I 0x00000002 +#define ADL_DISPLAY_FORMAT_FORCE_1080P 0x00000004 +#define ADL_DISPLAY_FORMAT_FORCE_720P50 0x00000008 +#define ADL_DISPLAY_FORMAT_FORCE_1080I25 0x00000010 +#define ADL_DISPLAY_FORMAT_FORCE_576I25 0x00000020 +#define ADL_DISPLAY_FORMAT_FORCE_576P50 0x00000040 +#define ADL_DISPLAY_FORMAT_FORCE_1080P24 0x00000080 +#define ADL_DISPLAY_FORMAT_FORCE_1080P25 0x00000100 +#define ADL_DISPLAY_FORMAT_FORCE_1080P30 0x00000200 +#define ADL_DISPLAY_FORMAT_FORCE_1080P50 0x00000400 + +///< Below are \b EXTENDED display mode flags + +#define ADL_DISPLAY_FORMAT_CVDONGLEOVERIDE 0x00000001 +#define ADL_DISPLAY_FORMAT_CVMODEUNDERSCAN 0x00000002 +#define ADL_DISPLAY_FORMAT_FORCECONNECT_SUPPORTED 0x00000004 +#define ADL_DISPLAY_FORMAT_RESTRICT_FORMAT_SELECTION 0x00000008 +#define ADL_DISPLAY_FORMAT_SETASPECRATIO 0x00000010 +#define ADL_DISPLAY_FORMAT_FORCEMODES 0x00000020 +#define ADL_DISPLAY_FORMAT_LCDRTCCOEFF 0x00000040 +/// @} + +/// Defines used by OD5 +#define ADL_PM_PARAM_DONT_CHANGE 0 + +/// The following defines Bus types +/// @{ +#define ADL_BUSTYPE_PCI 0 /* PCI bus */ +#define ADL_BUSTYPE_AGP 1 /* AGP bus */ +#define ADL_BUSTYPE_PCIE 2 /* PCI Express bus */ +#define ADL_BUSTYPE_PCIE_GEN2 3 /* PCI Express 2nd generation bus */ +#define ADL_BUSTYPE_PCIE_GEN3 4 /* PCI Express 3rd generation bus */ +#define ADL_BUSTYPE_PCIE_GEN4 5 /* PCI Express 4th generation bus */ +/// @} + +/// \defgroup define_ws_caps Workstation Capabilities +/// Workstation values +/// @{ + +/// This value indicates that the workstation card supports active stereo though stereo output connector +#define ADL_STEREO_SUPPORTED (1 << 2) +/// This value indicates that the workstation card supports active stereo via "blue-line" +#define ADL_STEREO_BLUE_LINE (1 << 3) +/// This value is used to turn off stereo mode. +#define ADL_STEREO_OFF 0 +/// This value indicates that the workstation card supports active stereo. This is also used to set the stereo mode to active though the stereo output connector +#define ADL_STEREO_ACTIVE (1 << 1) +/// This value indicates that the workstation card supports auto-stereo monitors with horizontal interleave. This is also used to set the stereo mode to use the auto-stereo monitor with horizontal interleave +#define ADL_STEREO_AUTO_HORIZONTAL (1 << 30) +/// This value indicates that the workstation card supports auto-stereo monitors with vertical interleave. This is also used to set the stereo mode to use the auto-stereo monitor with vertical interleave +#define ADL_STEREO_AUTO_VERTICAL (1 << 31) +/// This value indicates that the workstation card supports passive stereo, ie. non stereo sync +#define ADL_STEREO_PASSIVE (1 << 6) +/// This value indicates that the workstation card supports auto-stereo monitors with vertical interleave. This is also used to set the stereo mode to use the auto-stereo monitor with vertical interleave +#define ADL_STEREO_PASSIVE_HORIZ (1 << 7) +/// This value indicates that the workstation card supports auto-stereo monitors with vertical interleave. This is also used to set the stereo mode to use the auto-stereo monitor with vertical interleave +#define ADL_STEREO_PASSIVE_VERT (1 << 8) +/// This value indicates that the workstation card supports auto-stereo monitors with Samsung. +#define ADL_STEREO_AUTO_SAMSUNG (1 << 11) +/// This value indicates that the workstation card supports auto-stereo monitors with Tridility. +#define ADL_STEREO_AUTO_TSL (1 << 12) +/// This value indicates that the workstation card supports DeepBitDepth (10 bpp) +#define ADL_DEEPBITDEPTH_10BPP_SUPPORTED (1 << 5) + +/// This value indicates that the workstation supports 8-Bit Grayscale +#define ADL_8BIT_GREYSCALE_SUPPORTED (1 << 9) +/// This value indicates that the workstation supports CUSTOM TIMING +#define ADL_CUSTOM_TIMING_SUPPORTED (1 << 10) + +/// Load balancing is supported. +#define ADL_WORKSTATION_LOADBALANCING_SUPPORTED 0x00000001 +/// Load balancing is available. +#define ADL_WORKSTATION_LOADBALANCING_AVAILABLE 0x00000002 + +/// Load balancing is disabled. +#define ADL_WORKSTATION_LOADBALANCING_DISABLED 0x00000000 +/// Load balancing is Enabled. +#define ADL_WORKSTATION_LOADBALANCING_ENABLED 0x00000001 + + + +/// @} + +/// \defgroup define_adapterspeed speed setting from the adapter +/// @{ +#define ADL_CONTEXT_SPEED_UNFORCED 0 /* default asic running speed */ +#define ADL_CONTEXT_SPEED_FORCEHIGH 1 /* asic running speed is forced to high */ +#define ADL_CONTEXT_SPEED_FORCELOW 2 /* asic running speed is forced to low */ + +#define ADL_ADAPTER_SPEEDCAPS_SUPPORTED (1 << 0) /* change asic running speed setting is supported */ +/// @} + +/// \defgroup define_glsync Genlock related values +/// GL-Sync port types (unique values) +/// @{ +/// Unknown port of GL-Sync module +#define ADL_GLSYNC_PORT_UNKNOWN 0 +/// BNC port of of GL-Sync module +#define ADL_GLSYNC_PORT_BNC 1 +/// RJ45(1) port of of GL-Sync module +#define ADL_GLSYNC_PORT_RJ45PORT1 2 +/// RJ45(2) port of of GL-Sync module +#define ADL_GLSYNC_PORT_RJ45PORT2 3 + +// GL-Sync Genlock settings mask (bit-vector) + +/// None of the ADLGLSyncGenlockConfig members are valid +#define ADL_GLSYNC_CONFIGMASK_NONE 0 +/// The ADLGLSyncGenlockConfig.lSignalSource member is valid +#define ADL_GLSYNC_CONFIGMASK_SIGNALSOURCE (1 << 0) +/// The ADLGLSyncGenlockConfig.iSyncField member is valid +#define ADL_GLSYNC_CONFIGMASK_SYNCFIELD (1 << 1) +/// The ADLGLSyncGenlockConfig.iSampleRate member is valid +#define ADL_GLSYNC_CONFIGMASK_SAMPLERATE (1 << 2) +/// The ADLGLSyncGenlockConfig.lSyncDelay member is valid +#define ADL_GLSYNC_CONFIGMASK_SYNCDELAY (1 << 3) +/// The ADLGLSyncGenlockConfig.iTriggerEdge member is valid +#define ADL_GLSYNC_CONFIGMASK_TRIGGEREDGE (1 << 4) +/// The ADLGLSyncGenlockConfig.iScanRateCoeff member is valid +#define ADL_GLSYNC_CONFIGMASK_SCANRATECOEFF (1 << 5) +/// The ADLGLSyncGenlockConfig.lFramelockCntlVector member is valid +#define ADL_GLSYNC_CONFIGMASK_FRAMELOCKCNTL (1 << 6) + + +// GL-Sync Framelock control mask (bit-vector) + +/// Framelock is disabled +#define ADL_GLSYNC_FRAMELOCKCNTL_NONE 0 +/// Framelock is enabled +#define ADL_GLSYNC_FRAMELOCKCNTL_ENABLE ( 1 << 0) + +#define ADL_GLSYNC_FRAMELOCKCNTL_DISABLE ( 1 << 1) +#define ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_RESET ( 1 << 2) +#define ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_ACK ( 1 << 3) +#define ADL_GLSYNC_FRAMELOCKCNTL_VERSION_KMD (1 << 4) + +#define ADL_GLSYNC_FRAMELOCKCNTL_STATE_ENABLE ( 1 << 0) +#define ADL_GLSYNC_FRAMELOCKCNTL_STATE_KMD (1 << 4) + +// GL-Sync Framelock counters mask (bit-vector) +#define ADL_GLSYNC_COUNTER_SWAP ( 1 << 0 ) + +// GL-Sync Signal Sources (unique values) + +/// GL-Sync signal source is undefined +#define ADL_GLSYNC_SIGNALSOURCE_UNDEFINED 0x00000100 +/// GL-Sync signal source is Free Run +#define ADL_GLSYNC_SIGNALSOURCE_FREERUN 0x00000101 +/// GL-Sync signal source is the BNC GL-Sync port +#define ADL_GLSYNC_SIGNALSOURCE_BNCPORT 0x00000102 +/// GL-Sync signal source is the RJ45(1) GL-Sync port +#define ADL_GLSYNC_SIGNALSOURCE_RJ45PORT1 0x00000103 +/// GL-Sync signal source is the RJ45(2) GL-Sync port +#define ADL_GLSYNC_SIGNALSOURCE_RJ45PORT2 0x00000104 + + +// GL-Sync Signal Types (unique values) + +/// GL-Sync signal type is unknown +#define ADL_GLSYNC_SIGNALTYPE_UNDEFINED 0 +/// GL-Sync signal type is 480I +#define ADL_GLSYNC_SIGNALTYPE_480I 1 +/// GL-Sync signal type is 576I +#define ADL_GLSYNC_SIGNALTYPE_576I 2 +/// GL-Sync signal type is 480P +#define ADL_GLSYNC_SIGNALTYPE_480P 3 +/// GL-Sync signal type is 576P +#define ADL_GLSYNC_SIGNALTYPE_576P 4 +/// GL-Sync signal type is 720P +#define ADL_GLSYNC_SIGNALTYPE_720P 5 +/// GL-Sync signal type is 1080P +#define ADL_GLSYNC_SIGNALTYPE_1080P 6 +/// GL-Sync signal type is 1080I +#define ADL_GLSYNC_SIGNALTYPE_1080I 7 +/// GL-Sync signal type is SDI +#define ADL_GLSYNC_SIGNALTYPE_SDI 8 +/// GL-Sync signal type is TTL +#define ADL_GLSYNC_SIGNALTYPE_TTL 9 +/// GL_Sync signal type is Analog +#define ADL_GLSYNC_SIGNALTYPE_ANALOG 10 + +// GL-Sync Sync Field options (unique values) + +///GL-Sync sync field option is undefined +#define ADL_GLSYNC_SYNCFIELD_UNDEFINED 0 +///GL-Sync sync field option is Sync to Field 1 (used for Interlaced signal types) +#define ADL_GLSYNC_SYNCFIELD_BOTH 1 +///GL-Sync sync field option is Sync to Both fields (used for Interlaced signal types) +#define ADL_GLSYNC_SYNCFIELD_1 2 + + +// GL-Sync trigger edge options (unique values) + +/// GL-Sync trigger edge is undefined +#define ADL_GLSYNC_TRIGGEREDGE_UNDEFINED 0 +/// GL-Sync trigger edge is the rising edge +#define ADL_GLSYNC_TRIGGEREDGE_RISING 1 +/// GL-Sync trigger edge is the falling edge +#define ADL_GLSYNC_TRIGGEREDGE_FALLING 2 +/// GL-Sync trigger edge is both the rising and the falling edge +#define ADL_GLSYNC_TRIGGEREDGE_BOTH 3 + + +// GL-Sync scan rate coefficient/multiplier options (unique values) + +/// GL-Sync scan rate coefficient/multiplier is undefined +#define ADL_GLSYNC_SCANRATECOEFF_UNDEFINED 0 +/// GL-Sync scan rate coefficient/multiplier is 5 +#define ADL_GLSYNC_SCANRATECOEFF_x5 1 +/// GL-Sync scan rate coefficient/multiplier is 4 +#define ADL_GLSYNC_SCANRATECOEFF_x4 2 +/// GL-Sync scan rate coefficient/multiplier is 3 +#define ADL_GLSYNC_SCANRATECOEFF_x3 3 +/// GL-Sync scan rate coefficient/multiplier is 5:2 (SMPTE) +#define ADL_GLSYNC_SCANRATECOEFF_x5_DIV_2 4 +/// GL-Sync scan rate coefficient/multiplier is 2 +#define ADL_GLSYNC_SCANRATECOEFF_x2 5 +/// GL-Sync scan rate coefficient/multiplier is 3 : 2 +#define ADL_GLSYNC_SCANRATECOEFF_x3_DIV_2 6 +/// GL-Sync scan rate coefficient/multiplier is 5 : 4 +#define ADL_GLSYNC_SCANRATECOEFF_x5_DIV_4 7 +/// GL-Sync scan rate coefficient/multiplier is 1 (default) +#define ADL_GLSYNC_SCANRATECOEFF_x1 8 +/// GL-Sync scan rate coefficient/multiplier is 4 : 5 +#define ADL_GLSYNC_SCANRATECOEFF_x4_DIV_5 9 +/// GL-Sync scan rate coefficient/multiplier is 2 : 3 +#define ADL_GLSYNC_SCANRATECOEFF_x2_DIV_3 10 +/// GL-Sync scan rate coefficient/multiplier is 1 : 2 +#define ADL_GLSYNC_SCANRATECOEFF_x1_DIV_2 11 +/// GL-Sync scan rate coefficient/multiplier is 2 : 5 (SMPTE) +#define ADL_GLSYNC_SCANRATECOEFF_x2_DIV_5 12 +/// GL-Sync scan rate coefficient/multiplier is 1 : 3 +#define ADL_GLSYNC_SCANRATECOEFF_x1_DIV_3 13 +/// GL-Sync scan rate coefficient/multiplier is 1 : 4 +#define ADL_GLSYNC_SCANRATECOEFF_x1_DIV_4 14 +/// GL-Sync scan rate coefficient/multiplier is 1 : 5 +#define ADL_GLSYNC_SCANRATECOEFF_x1_DIV_5 15 + + +// GL-Sync port (signal presence) states (unique values) + +/// GL-Sync port state is undefined +#define ADL_GLSYNC_PORTSTATE_UNDEFINED 0 +/// GL-Sync port is not connected +#define ADL_GLSYNC_PORTSTATE_NOCABLE 1 +/// GL-Sync port is Idle +#define ADL_GLSYNC_PORTSTATE_IDLE 2 +/// GL-Sync port has an Input signal +#define ADL_GLSYNC_PORTSTATE_INPUT 3 +/// GL-Sync port is Output +#define ADL_GLSYNC_PORTSTATE_OUTPUT 4 + + +// GL-Sync LED types (used index within ADL_Workstation_GLSyncPortState_Get returned ppGlSyncLEDs array) (unique values) + +/// Index into the ADL_Workstation_GLSyncPortState_Get returned ppGlSyncLEDs array for the one LED of the BNC port +#define ADL_GLSYNC_LEDTYPE_BNC 0 +/// Index into the ADL_Workstation_GLSyncPortState_Get returned ppGlSyncLEDs array for the Left LED of the RJ45(1) or RJ45(2) port +#define ADL_GLSYNC_LEDTYPE_RJ45_LEFT 0 +/// Index into the ADL_Workstation_GLSyncPortState_Get returned ppGlSyncLEDs array for the Right LED of the RJ45(1) or RJ45(2) port +#define ADL_GLSYNC_LEDTYPE_RJ45_RIGHT 1 + + +// GL-Sync LED colors (unique values) + +/// GL-Sync LED undefined color +#define ADL_GLSYNC_LEDCOLOR_UNDEFINED 0 +/// GL-Sync LED is unlit +#define ADL_GLSYNC_LEDCOLOR_NOLIGHT 1 +/// GL-Sync LED is yellow +#define ADL_GLSYNC_LEDCOLOR_YELLOW 2 +/// GL-Sync LED is red +#define ADL_GLSYNC_LEDCOLOR_RED 3 +/// GL-Sync LED is green +#define ADL_GLSYNC_LEDCOLOR_GREEN 4 +/// GL-Sync LED is flashing green +#define ADL_GLSYNC_LEDCOLOR_FLASH_GREEN 5 + + +// GL-Sync Port Control (refers one GL-Sync Port) (unique values) + +/// Used to configure the RJ54(1) or RJ42(2) port of GL-Sync is as Idle +#define ADL_GLSYNC_PORTCNTL_NONE 0x00000000 +/// Used to configure the RJ54(1) or RJ42(2) port of GL-Sync is as Output +#define ADL_GLSYNC_PORTCNTL_OUTPUT 0x00000001 + + +// GL-Sync Mode Control (refers one Display/Controller) (bitfields) + +/// Used to configure the display to use internal timing (not genlocked) +#define ADL_GLSYNC_MODECNTL_NONE 0x00000000 +/// Bitfield used to configure the display as genlocked (either as Timing Client or as Timing Server) +#define ADL_GLSYNC_MODECNTL_GENLOCK 0x00000001 +/// Bitfield used to configure the display as Timing Server +#define ADL_GLSYNC_MODECNTL_TIMINGSERVER 0x00000002 + +// GL-Sync Mode Status +/// Display is currently not genlocked +#define ADL_GLSYNC_MODECNTL_STATUS_NONE 0x00000000 +/// Display is currently genlocked +#define ADL_GLSYNC_MODECNTL_STATUS_GENLOCK 0x00000001 +/// Display requires a mode switch +#define ADL_GLSYNC_MODECNTL_STATUS_SETMODE_REQUIRED 0x00000002 +/// Display is capable of being genlocked +#define ADL_GLSYNC_MODECNTL_STATUS_GENLOCK_ALLOWED 0x00000004 + +#define ADL_MAX_GLSYNC_PORTS 8 +#define ADL_MAX_GLSYNC_PORT_LEDS 8 + +/// @} + +/// \defgroup define_crossfirestate CrossfireX state of a particular adapter CrossfireX combination +/// @{ +#define ADL_XFIREX_STATE_NOINTERCONNECT ( 1 << 0 ) /* Dongle / cable is missing */ +#define ADL_XFIREX_STATE_DOWNGRADEPIPES ( 1 << 1 ) /* CrossfireX can be enabled if pipes are downgraded */ +#define ADL_XFIREX_STATE_DOWNGRADEMEM ( 1 << 2 ) /* CrossfireX cannot be enabled unless mem downgraded */ +#define ADL_XFIREX_STATE_REVERSERECOMMENDED ( 1 << 3 ) /* Card reversal recommended, CrossfireX cannot be enabled. */ +#define ADL_XFIREX_STATE_3DACTIVE ( 1 << 4 ) /* 3D client is active - CrossfireX cannot be safely enabled */ +#define ADL_XFIREX_STATE_MASTERONSLAVE ( 1 << 5 ) /* Dongle is OK but master is on slave */ +#define ADL_XFIREX_STATE_NODISPLAYCONNECT ( 1 << 6 ) /* No (valid) display connected to master card. */ +#define ADL_XFIREX_STATE_NOPRIMARYVIEW ( 1 << 7 ) /* CrossfireX is enabled but master is not current primary device */ +#define ADL_XFIREX_STATE_DOWNGRADEVISMEM ( 1 << 8 ) /* CrossfireX cannot be enabled unless visible mem downgraded */ +#define ADL_XFIREX_STATE_LESSTHAN8LANE_MASTER ( 1 << 9 ) /* CrossfireX can be enabled however performance not optimal due to <8 lanes */ +#define ADL_XFIREX_STATE_LESSTHAN8LANE_SLAVE ( 1 << 10 ) /* CrossfireX can be enabled however performance not optimal due to <8 lanes */ +#define ADL_XFIREX_STATE_PEERTOPEERFAILED ( 1 << 11 ) /* CrossfireX cannot be enabled due to failed peer to peer test */ +#define ADL_XFIREX_STATE_MEMISDOWNGRADED ( 1 << 16 ) /* Notification that memory is currently downgraded */ +#define ADL_XFIREX_STATE_PIPESDOWNGRADED ( 1 << 17 ) /* Notification that pipes are currently downgraded */ +#define ADL_XFIREX_STATE_XFIREXACTIVE ( 1 << 18 ) /* CrossfireX is enabled on current device */ +#define ADL_XFIREX_STATE_VISMEMISDOWNGRADED ( 1 << 19 ) /* Notification that visible FB memory is currently downgraded */ +#define ADL_XFIREX_STATE_INVALIDINTERCONNECTION ( 1 << 20 ) /* Cannot support current inter-connection configuration */ +#define ADL_XFIREX_STATE_NONP2PMODE ( 1 << 21 ) /* CrossfireX will only work with clients supporting non P2P mode */ +#define ADL_XFIREX_STATE_DOWNGRADEMEMBANKS ( 1 << 22 ) /* CrossfireX cannot be enabled unless memory banks downgraded */ +#define ADL_XFIREX_STATE_MEMBANKSDOWNGRADED ( 1 << 23 ) /* Notification that memory banks are currently downgraded */ +#define ADL_XFIREX_STATE_DUALDISPLAYSALLOWED ( 1 << 24 ) /* Extended desktop or clone mode is allowed. */ +#define ADL_XFIREX_STATE_P2P_APERTURE_MAPPING ( 1 << 25 ) /* P2P mapping was through peer aperture */ +#define ADL_XFIREX_STATE_P2PFLUSH_REQUIRED ADL_XFIREX_STATE_P2P_APERTURE_MAPPING /* For back compatible */ +#define ADL_XFIREX_STATE_XSP_CONNECTED ( 1 << 26 ) /* There is CrossfireX side port connection between GPUs */ +#define ADL_XFIREX_STATE_ENABLE_CF_REBOOT_REQUIRED ( 1 << 27 ) /* System needs a reboot bofore enable CrossfireX */ +#define ADL_XFIREX_STATE_DISABLE_CF_REBOOT_REQUIRED ( 1 << 28 ) /* System needs a reboot after disable CrossfireX */ +#define ADL_XFIREX_STATE_DRV_HANDLE_DOWNGRADE_KEY ( 1 << 29 ) /* Indicate base driver handles the downgrade key updating */ +#define ADL_XFIREX_STATE_CF_RECONFIG_REQUIRED ( 1 << 30 ) /* CrossfireX need to be reconfigured by CCC because of a LDA chain broken */ +#define ADL_XFIREX_STATE_ERRORGETTINGSTATUS ( 1 << 31 ) /* Could not obtain current status */ +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_ADJUSTMENT_PIXELFORMAT adjustment values +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +/// \defgroup define_pixel_formats Pixel Formats values +/// This group defines the various Pixel Formats that a particular digital display can support. \n +/// Since a display can support multiple formats, these values can be bit-or'ed to indicate the various formats \n +/// @{ +#define ADL_DISPLAY_PIXELFORMAT_UNKNOWN 0 +#define ADL_DISPLAY_PIXELFORMAT_RGB (1 << 0) +#define ADL_DISPLAY_PIXELFORMAT_YCRCB444 (1 << 1) //Limited range +#define ADL_DISPLAY_PIXELFORMAT_YCRCB422 (1 << 2) //Limited range +#define ADL_DISPLAY_PIXELFORMAT_RGB_LIMITED_RANGE (1 << 3) +#define ADL_DISPLAY_PIXELFORMAT_RGB_FULL_RANGE ADL_DISPLAY_PIXELFORMAT_RGB //Full range +#define ADL_DISPLAY_PIXELFORMAT_YCRCB420 (1 << 4) +/// @} + +/// \defgroup define_contype Connector Type Values +/// ADLDisplayConfig.ulConnectorType defines +/// @{ +#define ADL_DL_DISPLAYCONFIG_CONTYPE_UNKNOWN 0 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_JP 1 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_CV_JPN 2 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NA 3 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_NA 4 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_VGA 5 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_D 6 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_I 7 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_A 8 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_B 9 +#define ADL_DL_DISPLAYCONFIG_CONTYPE_DISPLAYPORT 10 +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_DISPLAYINFO_ Definitions +// for ADLDisplayInfo.iDisplayInfoMask and ADLDisplayInfo.iDisplayInfoValue +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +/// \defgroup define_displayinfomask Display Info Mask Values +/// @{ +#define ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED 0x00000001 +#define ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED 0x00000002 +#define ADL_DISPLAY_DISPLAYINFO_NONLOCAL 0x00000004 +#define ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED 0x00000008 +#define ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED 0x00000010 +#define ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED 0x00000020 +#define ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY 0x00000040 +#define ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED 0x00000080 + +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE 0x00000100 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE 0x00000200 + +/// Legacy support for XP +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH 0x00000400 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH 0x00000800 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED 0x00001000 + +/// More support manners +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU 0x00010000 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU 0x00020000 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2 0x00040000 +#define ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3 0x00080000 + +/// Projector display type +#define ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR 0x00100000 + +/// @} + + +/////////////////////////////////////////////////////////////////////////// +// ADL_ADAPTER_DISPLAY_MANNER_SUPPORTED_ Definitions +// for ADLAdapterDisplayCap of ADL_Adapter_Display_Cap() +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +/// \defgroup define_adaptermanner Adapter Manner Support Values +/// @{ +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NOTACTIVE 0x00000001 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_SINGLE 0x00000002 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_CLONE 0x00000004 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCH1GPU 0x00000008 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCHNGPU 0x00000010 + +/// Legacy support for XP +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2VSTRETCH 0x00000020 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2HSTRETCH 0x00000040 +#define ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_EXTENDED 0x00000080 + +#define ADL_ADAPTER_DISPLAYCAP_PREFERDISPLAY_SUPPORTED 0x00000100 +#define ADL_ADAPTER_DISPLAYCAP_BEZEL_SUPPORTED 0x00000200 + + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_DISPLAYMAP_MANNER_ Definitions +// for ADLDisplayMap.iDisplayMapMask and ADLDisplayMap.iDisplayMapValue +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +#define ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED 0x00000001 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_NOTACTIVE 0x00000002 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_SINGLE 0x00000004 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_CLONE 0x00000008 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED1 0x00000010 // Removed NSTRETCH +#define ADL_DISPLAY_DISPLAYMAP_MANNER_HSTRETCH 0x00000020 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_VSTRETCH 0x00000040 +#define ADL_DISPLAY_DISPLAYMAP_MANNER_VLD 0x00000080 + +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_DISPLAYMAP_OPTION_ Definitions +// for iOption in function ADL_Display_DisplayMapConfig_Get +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +#define ADL_DISPLAY_DISPLAYMAP_OPTION_GPUINFO 0x00000001 + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_DISPLAYTARGET_ Definitions +// for ADLDisplayTarget.iDisplayTargetMask and ADLDisplayTarget.iDisplayTargetValue +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +#define ADL_DISPLAY_DISPLAYTARGET_PREFERRED 0x00000001 + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_POSSIBLEMAPRESULT_VALID Definitions +// for ADLPossibleMapResult.iPossibleMapResultMask and ADLPossibleMapResult.iPossibleMapResultValue +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +#define ADL_DISPLAY_POSSIBLEMAPRESULT_VALID 0x00000001 +#define ADL_DISPLAY_POSSIBLEMAPRESULT_BEZELSUPPORTED 0x00000002 +#define ADL_DISPLAY_POSSIBLEMAPRESULT_OVERLAPSUPPORTED 0x00000004 + +/////////////////////////////////////////////////////////////////////////// +// ADL_DISPLAY_MODE_ Definitions +// for ADLMode.iModeMask, ADLMode.iModeValue, and ADLMode.iModeFlag +// (bit-vector) +/////////////////////////////////////////////////////////////////////////// +/// \defgroup define_displaymode Display Mode Values +/// @{ +#define ADL_DISPLAY_MODE_COLOURFORMAT_565 0x00000001 +#define ADL_DISPLAY_MODE_COLOURFORMAT_8888 0x00000002 +#define ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000 0x00000004 +#define ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_090 0x00000008 +#define ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_180 0x00000010 +#define ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_270 0x00000020 +#define ADL_DISPLAY_MODE_REFRESHRATE_ROUNDED 0x00000040 +#define ADL_DISPLAY_MODE_REFRESHRATE_ONLY 0x00000080 + +#define ADL_DISPLAY_MODE_PROGRESSIVE_FLAG 0 +#define ADL_DISPLAY_MODE_INTERLACED_FLAG 2 +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADL_OSMODEINFO Definitions +/////////////////////////////////////////////////////////////////////////// +/// \defgroup define_osmode OS Mode Values +/// @{ +#define ADL_OSMODEINFOXPOS_DEFAULT -640 +#define ADL_OSMODEINFOYPOS_DEFAULT 0 +#define ADL_OSMODEINFOXRES_DEFAULT 640 +#define ADL_OSMODEINFOYRES_DEFAULT 480 +#define ADL_OSMODEINFOXRES_DEFAULT800 800 +#define ADL_OSMODEINFOYRES_DEFAULT600 600 +#define ADL_OSMODEINFOREFRESHRATE_DEFAULT 60 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT 8 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT16 16 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT24 24 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT32 32 +#define ADL_OSMODEINFOORIENTATION_DEFAULT 0 +#define ADL_OSMODEINFOORIENTATION_DEFAULT_WIN7 DISPLAYCONFIG_ROTATION_FORCE_UINT32 +#define ADL_OSMODEFLAG_DEFAULT 0 +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADLThreadingModel Enumeration +/////////////////////////////////////////////////////////////////////////// +/// \defgroup thread_model +/// Used with \ref ADL_Main_ControlX2_Create and \ref ADL2_Main_ControlX2_Create to specify how ADL handles API calls when executed by multiple threads concurrently. +/// \brief Declares ADL threading behavior. +/// @{ +typedef enum ADLThreadingModel +{ + ADL_THREADING_UNLOCKED = 0, /*!< Default behavior. ADL will not enforce serialization of ADL API executions by multiple threads. Multiple threads will be allowed to enter to ADL at the same time. Note that ADL library is not guaranteed to be thread-safe. Client that calls ADL_Main_Control_Create have to provide its own mechanism for ADL calls serialization. */ + ADL_THREADING_LOCKED /*!< ADL will enforce serialization of ADL API when called by multiple threads. Only single thread will be allowed to enter ADL API at the time. This option makes ADL calls thread-safe. You shouldn't use this option if ADL calls will be executed on Linux on x-server rendering thread. It can cause the application to hung. */ +}ADLThreadingModel; + +/// @} +/////////////////////////////////////////////////////////////////////////// +// ADLPurposeCode Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLPurposeCode +{ + ADL_PURPOSECODE_NORMAL = 0, + ADL_PURPOSECODE_HIDE_MODE_SWITCH, + ADL_PURPOSECODE_MODE_SWITCH, + ADL_PURPOSECODE_ATTATCH_DEVICE, + ADL_PURPOSECODE_DETACH_DEVICE, + ADL_PURPOSECODE_SETPRIMARY_DEVICE, + ADL_PURPOSECODE_GDI_ROTATION, + ADL_PURPOSECODE_ATI_ROTATION +}; +/////////////////////////////////////////////////////////////////////////// +// ADLAngle Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLAngle +{ + ADL_ANGLE_LANDSCAPE = 0, + ADL_ANGLE_ROTATERIGHT = 90, + ADL_ANGLE_ROTATE180 = 180, + ADL_ANGLE_ROTATELEFT = 270, +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLOrientationDataType Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLOrientationDataType +{ + ADL_ORIENTATIONTYPE_OSDATATYPE, + ADL_ORIENTATIONTYPE_NONOSDATATYPE +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLPanningMode Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLPanningMode +{ + ADL_PANNINGMODE_NO_PANNING = 0, + ADL_PANNINGMODE_AT_LEAST_ONE_NO_PANNING = 1, + ADL_PANNINGMODE_ALLOW_PANNING = 2, +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLLARGEDESKTOPTYPE Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLLARGEDESKTOPTYPE +{ + ADL_LARGEDESKTOPTYPE_NORMALDESKTOP = 0, + ADL_LARGEDESKTOPTYPE_PSEUDOLARGEDESKTOP = 1, + ADL_LARGEDESKTOPTYPE_VERYLARGEDESKTOP = 2 +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLPlatform Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLPlatForm +{ + GRAPHICS_PLATFORM_DESKTOP = 0, + GRAPHICS_PLATFORM_MOBILE = 1 +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLGraphicCoreGeneration Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLGraphicCoreGeneration +{ + ADL_GRAPHIC_CORE_GENERATION_UNDEFINED = 0, + ADL_GRAPHIC_CORE_GENERATION_PRE_GCN = 1, + ADL_GRAPHIC_CORE_GENERATION_GCN = 2, + ADL_GRAPHIC_CORE_GENERATION_RDNA = 3 +}; + +// Other Definitions for internal use + +// Values for ADL_Display_WriteAndReadI2CRev_Get() + +#define ADL_I2C_MAJOR_API_REV 0x00000001 +#define ADL_I2C_MINOR_DEFAULT_API_REV 0x00000000 +#define ADL_I2C_MINOR_OEM_API_REV 0x00000001 + +// Values for ADL_Display_WriteAndReadI2C() +#define ADL_DL_I2C_LINE_OEM 0x00000001 +#define ADL_DL_I2C_LINE_OD_CONTROL 0x00000002 +#define ADL_DL_I2C_LINE_OEM2 0x00000003 +#define ADL_DL_I2C_LINE_OEM3 0x00000004 +#define ADL_DL_I2C_LINE_OEM4 0x00000005 +#define ADL_DL_I2C_LINE_OEM5 0x00000006 +#define ADL_DL_I2C_LINE_OEM6 0x00000007 +#define ADL_DL_I2C_LINE_GPIO 0x00000008 + +// Max size of I2C data buffer +#define ADL_DL_I2C_MAXDATASIZE 0x00000018 +#define ADL_DL_I2C_MAXWRITEDATASIZE 0x0000000C +#define ADL_DL_I2C_MAXADDRESSLENGTH 0x00000006 +#define ADL_DL_I2C_MAXOFFSETLENGTH 0x00000004 + +// I2C clock speed in KHz +#define ADL_DL_I2C_SPEED_50K 50 +#define ADL_DL_I2C_SPEED_100K 100 +#define ALD_DL_I2C_SPEED_400K 400 +#define ADL_DL_I2C_SPEED_1M 1000 +#define ADL_DL_I2C_SPEED_2M 2300 + +/// Values for ADLDisplayProperty.iPropertyType +#define ADL_DL_DISPLAYPROPERTY_TYPE_UNKNOWN 0 +#define ADL_DL_DISPLAYPROPERTY_TYPE_EXPANSIONMODE 1 +#define ADL_DL_DISPLAYPROPERTY_TYPE_USEUNDERSCANSCALING 2 +/// Enables ITC processing for HDMI panels that are capable of the feature +#define ADL_DL_DISPLAYPROPERTY_TYPE_ITCFLAGENABLE 9 +#define ADL_DL_DISPLAYPROPERTY_TYPE_DOWNSCALE 11 +#define ADL_DL_DISPLAYPROPERTY_TYPE_INTEGER_SCALING 12 + + +/// Values for ADLDisplayContent.iContentType +/// Certain HDMI panels that support ITC have support for a feature such that, the display on the panel +/// can be adjusted to optimize the view of the content being displayed, depending on the type of content. +#define ADL_DL_DISPLAYCONTENT_TYPE_GRAPHICS 1 +#define ADL_DL_DISPLAYCONTENT_TYPE_PHOTO 2 +#define ADL_DL_DISPLAYCONTENT_TYPE_CINEMA 4 +#define ADL_DL_DISPLAYCONTENT_TYPE_GAME 8 + + + +//values for ADLDisplayProperty.iExpansionMode +#define ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_CENTER 0 +#define ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_FULLSCREEN 1 +#define ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_ASPECTRATIO 2 + + +///\defgroup define_dither_states Dithering options +/// @{ +/// Dithering disabled. +#define ADL_DL_DISPLAY_DITHER_DISABLED 0 +/// Use default driver settings for dithering. Note that the default setting could be dithering disabled. +#define ADL_DL_DISPLAY_DITHER_DRIVER_DEFAULT 1 +/// Temporal dithering to 6 bpc. Note that if the input is 12 bits, the two least significant bits will be truncated. +#define ADL_DL_DISPLAY_DITHER_FM6 2 +/// Temporal dithering to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_FM8 3 +/// Temporal dithering to 10 bpc. +#define ADL_DL_DISPLAY_DITHER_FM10 4 +/// Spatial dithering to 6 bpc. Note that if the input is 12 bits, the two least significant bits will be truncated. +#define ADL_DL_DISPLAY_DITHER_DITH6 5 +/// Spatial dithering to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_DITH8 6 +/// Spatial dithering to 10 bpc. +#define ADL_DL_DISPLAY_DITHER_DITH10 7 +/// Spatial dithering to 6 bpc. Random number generators are reset every frame, so the same input value of a certain pixel will always be dithered to the same output value. Note that if the input is 12 bits, the two least significant bits will be truncated. +#define ADL_DL_DISPLAY_DITHER_DITH6_NO_FRAME_RAND 8 +/// Spatial dithering to 8 bpc. Random number generators are reset every frame, so the same input value of a certain pixel will always be dithered to the same output value. +#define ADL_DL_DISPLAY_DITHER_DITH8_NO_FRAME_RAND 9 +/// Spatial dithering to 10 bpc. Random number generators are reset every frame, so the same input value of a certain pixel will always be dithered to the same output value. +#define ADL_DL_DISPLAY_DITHER_DITH10_NO_FRAME_RAND 10 +/// Truncation to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN6 11 +/// Truncation to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN8 12 +/// Truncation to 10 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10 13 +/// Truncation to 10 bpc followed by spatial dithering to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10_DITH8 14 +/// Truncation to 10 bpc followed by spatial dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10_DITH6 15 +/// Truncation to 10 bpc followed by temporal dithering to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10_FM8 16 +/// Truncation to 10 bpc followed by temporal dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10_FM6 17 +/// Truncation to 10 bpc followed by spatial dithering to 8 bpc and temporal dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN10_DITH8_FM6 18 +/// Spatial dithering to 10 bpc followed by temporal dithering to 8 bpc. +#define ADL_DL_DISPLAY_DITHER_DITH10_FM8 19 +/// Spatial dithering to 10 bpc followed by temporal dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_DITH10_FM6 20 +/// Truncation to 8 bpc followed by spatial dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN8_DITH6 21 +/// Truncation to 8 bpc followed by temporal dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_TRUN8_FM6 22 +/// Spatial dithering to 8 bpc followed by temporal dithering to 6 bpc. +#define ADL_DL_DISPLAY_DITHER_DITH8_FM6 23 +#define ADL_DL_DISPLAY_DITHER_LAST ADL_DL_DISPLAY_DITHER_DITH8_FM6 +/// @} + + +/// Display Get Cached EDID flag +#define ADL_MAX_EDIDDATA_SIZE 256 // number of UCHAR +#define ADL_MAX_OVERRIDEEDID_SIZE 512 // number of UCHAR +#define ADL_MAX_EDID_EXTENSION_BLOCKS 3 + +#define ADL_DL_CONTROLLER_OVERLAY_ALPHA 0 +#define ADL_DL_CONTROLLER_OVERLAY_ALPHAPERPIX 1 + +#define ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_RESET 0x00000000 +#define ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_SET 0x00000001 +#define ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_SCAN 0x00000002 + +///\defgroup define_display_packet Display Data Packet Types +/// @{ +#define ADL_DL_DISPLAY_DATA_PACKET__TYPE__AVI 0x00000001 +#define ADL_DL_DISPLAY_DATA_PACKET__TYPE__GAMMUT 0x00000002 +#define ADL_DL_DISPLAY_DATA_PACKET__TYPE__VENDORINFO 0x00000004 +#define ADL_DL_DISPLAY_DATA_PACKET__TYPE__HDR 0x00000008 +#define ADL_DL_DISPLAY_DATA_PACKET__TYPE__SPD 0x00000010 +/// @} + +// matrix types +#define ADL_GAMUT_MATRIX_SD 1 // SD matrix i.e. BT601 +#define ADL_GAMUT_MATRIX_HD 2 // HD matrix i.e. BT709 + +///\defgroup define_clockinfo_flags Clock flags +/// Used by ADLAdapterODClockInfo.iFlag +/// @{ +#define ADL_DL_CLOCKINFO_FLAG_FULLSCREEN3DONLY 0x00000001 +#define ADL_DL_CLOCKINFO_FLAG_ALWAYSFULLSCREEN3D 0x00000002 +#define ADL_DL_CLOCKINFO_FLAG_VPURECOVERYREDUCED 0x00000004 +#define ADL_DL_CLOCKINFO_FLAG_THERMALPROTECTION 0x00000008 +/// @} + +// Supported GPUs +// ADL_Display_PowerXpressActiveGPU_Get() +#define ADL_DL_POWERXPRESS_GPU_INTEGRATED 1 +#define ADL_DL_POWERXPRESS_GPU_DISCRETE 2 + +// Possible values for lpOperationResult +// ADL_Display_PowerXpressActiveGPU_Get() +#define ADL_DL_POWERXPRESS_SWITCH_RESULT_STARTED 1 // Switch procedure has been started - Windows platform only +#define ADL_DL_POWERXPRESS_SWITCH_RESULT_DECLINED 2 // Switch procedure cannot be started - All platforms +#define ADL_DL_POWERXPRESS_SWITCH_RESULT_ALREADY 3 // System already has required status - All platforms +#define ADL_DL_POWERXPRESS_SWITCH_RESULT_DEFERRED 5 // Switch was deferred and requires an X restart - Linux platform only + +// PowerXpress support version +// ADL_Display_PowerXpressVersion_Get() +#define ADL_DL_POWERXPRESS_VERSION_MAJOR 2 // Current PowerXpress support version 2.0 +#define ADL_DL_POWERXPRESS_VERSION_MINOR 0 + +#define ADL_DL_POWERXPRESS_VERSION (((ADL_DL_POWERXPRESS_VERSION_MAJOR) << 16) | ADL_DL_POWERXPRESS_VERSION_MINOR) + +//values for ADLThermalControllerInfo.iThermalControllerDomain +#define ADL_DL_THERMAL_DOMAIN_OTHER 0 +#define ADL_DL_THERMAL_DOMAIN_GPU 1 + +//values for ADLThermalControllerInfo.iFlags +#define ADL_DL_THERMAL_FLAG_INTERRUPT 1 +#define ADL_DL_THERMAL_FLAG_FANCONTROL 2 + +///\defgroup define_fanctrl Fan speed cotrol +/// Values for ADLFanSpeedInfo.iFlags +/// @{ +#define ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ 1 +#define ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE 2 +#define ADL_DL_FANCTRL_SUPPORTS_RPM_READ 4 +#define ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE 8 +/// @} + +//values for ADLFanSpeedValue.iSpeedType +#define ADL_DL_FANCTRL_SPEED_TYPE_PERCENT 1 +#define ADL_DL_FANCTRL_SPEED_TYPE_RPM 2 + +//values for ADLFanSpeedValue.iFlags +#define ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED 1 + +// MVPU interfaces +#define ADL_DL_MAX_MVPU_ADAPTERS 4 +#define MVPU_ADAPTER_0 0x00000001 +#define MVPU_ADAPTER_1 0x00000002 +#define MVPU_ADAPTER_2 0x00000004 +#define MVPU_ADAPTER_3 0x00000008 +#define ADL_DL_MAX_REGISTRY_PATH 256 + +//values for ADLMVPUStatus.iStatus +#define ADL_DL_MVPU_STATUS_OFF 0 +#define ADL_DL_MVPU_STATUS_ON 1 + +// values for ASIC family +///\defgroup define_Asic_type Detailed asic types +/// Defines for Adapter ASIC family type +/// @{ +#define ADL_ASIC_UNDEFINED 0 +#define ADL_ASIC_DISCRETE (1 << 0) +#define ADL_ASIC_INTEGRATED (1 << 1) +#define ADL_ASIC_WORKSTATION (1 << 2) +#define ADL_ASIC_FIREMV (1 << 3) +#define ADL_ASIC_XGP (1 << 4) +#define ADL_ASIC_FUSION (1 << 5) +#define ADL_ASIC_FIRESTREAM (1 << 6) +#define ADL_ASIC_EMBEDDED (1 << 7) +// Backward compatibility +#define ADL_ASIC_FIREGL ADL_ASIC_WORKSTATION +/// @} + +///\defgroup define_detailed_timing_flags Detailed Timimg Flags +/// Defines for ADLDetailedTiming.sTimingFlags field +/// @{ +#define ADL_DL_TIMINGFLAG_DOUBLE_SCAN 0x0001 +//sTimingFlags is set when the mode is INTERLACED, if not PROGRESSIVE +#define ADL_DL_TIMINGFLAG_INTERLACED 0x0002 +//sTimingFlags is set when the Horizontal Sync is POSITIVE, if not NEGATIVE +#define ADL_DL_TIMINGFLAG_H_SYNC_POLARITY 0x0004 +//sTimingFlags is set when the Vertical Sync is POSITIVE, if not NEGATIVE +#define ADL_DL_TIMINGFLAG_V_SYNC_POLARITY 0x0008 +/// @} + +///\defgroup define_modetiming_standard Timing Standards +/// Defines for ADLDisplayModeInfo.iTimingStandard field +/// @{ +#define ADL_DL_MODETIMING_STANDARD_CVT 0x00000001 // CVT Standard +#define ADL_DL_MODETIMING_STANDARD_GTF 0x00000002 // GFT Standard +#define ADL_DL_MODETIMING_STANDARD_DMT 0x00000004 // DMT Standard +#define ADL_DL_MODETIMING_STANDARD_CUSTOM 0x00000008 // User-defined standard +#define ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT 0x00000010 // Remove Mode from overriden list +#define ADL_DL_MODETIMING_STANDARD_CVT_RB 0x00000020 // CVT-RB Standard +/// @} + +// \defgroup define_xserverinfo driver x-server info +/// These flags are used by ADL_XServerInfo_Get() +// @ + +/// Xinerama is active in the x-server, Xinerama extension may report it to be active but it +/// may not be active in x-server +#define ADL_XSERVERINFO_XINERAMAACTIVE (1<<0) + +/// RandR 1.2 is supported by driver, RandR extension may report version 1.2 +/// but driver may not support it +#define ADL_XSERVERINFO_RANDR12SUPPORTED (1<<1) +// @ + + +///\defgroup define_eyefinity_constants Eyefinity Definitions +/// @{ + +#define ADL_CONTROLLERVECTOR_0 1 // ADL_CONTROLLERINDEX_0 = 0, (1 << ADL_CONTROLLERINDEX_0) +#define ADL_CONTROLLERVECTOR_1 2 // ADL_CONTROLLERINDEX_1 = 1, (1 << ADL_CONTROLLERINDEX_1) + +#define ADL_DISPLAY_SLSGRID_ORIENTATION_000 0x00000001 +#define ADL_DISPLAY_SLSGRID_ORIENTATION_090 0x00000002 +#define ADL_DISPLAY_SLSGRID_ORIENTATION_180 0x00000004 +#define ADL_DISPLAY_SLSGRID_ORIENTATION_270 0x00000008 +#define ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE 0x00000001 +#define ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE 0x00000002 +#define ADL_DISPLAY_SLSGRID_PORTAIT_MODE 0x00000004 +#define ADL_DISPLAY_SLSGRID_KEEPTARGETROTATION 0x00000080 + +#define ADL_DISPLAY_SLSGRID_SAMEMODESLS_SUPPORT 0x00000010 +#define ADL_DISPLAY_SLSGRID_MIXMODESLS_SUPPORT 0x00000020 +#define ADL_DISPLAY_SLSGRID_DISPLAYROTATION_SUPPORT 0x00000040 +#define ADL_DISPLAY_SLSGRID_DESKTOPROTATION_SUPPORT 0x00000080 + + +#define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FIT 0x0100 +#define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FILL 0x0200 +#define ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_EXPAND 0x0400 + +#define ADL_DISPLAY_SLSMAP_IS_SLS 0x1000 +#define ADL_DISPLAY_SLSMAP_IS_SLSBUILDER 0x2000 +#define ADL_DISPLAY_SLSMAP_IS_CLONEVT 0x4000 + +#define ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_LANDSCAPE 0x00000001 +#define ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_CURRENTANGLE 0x00000002 + +#define ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_LANDSCAPE 0x00000001 +#define ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_CURRENTANGLE 0x00000002 + +#define ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_LANDSCAPE 0x00000001 +#define ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_CURRENTANGLE 0x00000002 + +#define ADL_SLS_SAMEMODESLS_SUPPORT 0x0001 +#define ADL_SLS_MIXMODESLS_SUPPORT 0x0002 +#define ADL_SLS_DISPLAYROTATIONSLS_SUPPORT 0x0004 +#define ADL_SLS_DESKTOPROTATIONSLS_SUPPORT 0x0008 + +#define ADL_SLS_TARGETS_INVALID 0x0001 +#define ADL_SLS_MODES_INVALID 0x0002 +#define ADL_SLS_ROTATIONS_INVALID 0x0004 +#define ADL_SLS_POSITIONS_INVALID 0x0008 +#define ADL_SLS_LAYOUTMODE_INVALID 0x0010 + +#define ADL_DISPLAY_SLSDISPLAYOFFSET_VALID 0x0002 + +#define ADL_DISPLAY_SLSGRID_RELATIVETO_LANDSCAPE 0x00000010 +#define ADL_DISPLAY_SLSGRID_RELATIVETO_CURRENTANGLE 0x00000020 + + +/// The bit mask identifies displays is currently in bezel mode. +#define ADL_DISPLAY_SLSMAP_BEZELMODE 0x00000010 +/// The bit mask identifies displays from this map is arranged. +#define ADL_DISPLAY_SLSMAP_DISPLAYARRANGED 0x00000002 +/// The bit mask identifies this map is currently in used for the current adapter. +#define ADL_DISPLAY_SLSMAP_CURRENTCONFIG 0x00000004 + +///For onlay active SLS map info +#define ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE 0x00000001 + +///For Bezel +#define ADL_DISPLAY_BEZELOFFSET_STEPBYSTEPSET 0x00000004 +#define ADL_DISPLAY_BEZELOFFSET_COMMIT 0x00000008 + +typedef enum SLS_ImageCropType { + Fit = 1, + Fill = 2, + Expand = 3 +}SLS_ImageCropType; + + +typedef enum DceSettingsType { + DceSetting_HdmiLq, + DceSetting_DpSettings, + DceSetting_Protection + +} DceSettingsType; + +typedef enum DpLinkRate { + DPLinkRate_Unknown, + DPLinkRate_RBR, + DPLinkRate_2_16Gbps, + DPLinkRate_2_43Gbps, + DPLinkRate_HBR, + DPLinkRate_4_32Gbps, + DPLinkRate_HBR2, + DPLinkRate_HBR3, + DPLinkRate_UHBR10, + DPLinkRate_UHBR13D5, + DPLinkRate_UHBR20 + +} DpLinkRate; + +/// @} + +///\defgroup define_powerxpress_constants PowerXpress Definitions +/// @{ + +/// The bit mask identifies PX caps for ADLPXConfigCaps.iPXConfigCapMask and ADLPXConfigCaps.iPXConfigCapValue +#define ADL_PX_CONFIGCAPS_SPLASHSCREEN_SUPPORT 0x0001 +#define ADL_PX_CONFIGCAPS_CF_SUPPORT 0x0002 +#define ADL_PX_CONFIGCAPS_MUXLESS 0x0004 +#define ADL_PX_CONFIGCAPS_PROFILE_COMPLIANT 0x0008 +#define ADL_PX_CONFIGCAPS_NON_AMD_DRIVEN_DISPLAYS 0x0010 +#define ADL_PX_CONFIGCAPS_FIXED_SUPPORT 0x0020 +#define ADL_PX_CONFIGCAPS_DYNAMIC_SUPPORT 0x0040 +#define ADL_PX_CONFIGCAPS_HIDE_AUTO_SWITCH 0x0080 + +/// The bit mask identifies PX schemes for ADLPXSchemeRange +#define ADL_PX_SCHEMEMASK_FIXED 0x0001 +#define ADL_PX_SCHEMEMASK_DYNAMIC 0x0002 + +/// PX Schemes +typedef enum ADLPXScheme +{ + ADL_PX_SCHEME_INVALID = 0, + ADL_PX_SCHEME_FIXED = ADL_PX_SCHEMEMASK_FIXED, + ADL_PX_SCHEME_DYNAMIC = ADL_PX_SCHEMEMASK_DYNAMIC +}ADLPXScheme; + +/// Just keep the old definitions for compatibility, need to be removed later +typedef enum PXScheme +{ + PX_SCHEME_INVALID = 0, + PX_SCHEME_FIXED = 1, + PX_SCHEME_DYNAMIC = 2 +} PXScheme; + + +/// @} + +///\defgroup define_appprofiles For Application Profiles +/// @{ + +#define ADL_APP_PROFILE_FILENAME_LENGTH 256 +#define ADL_APP_PROFILE_TIMESTAMP_LENGTH 32 +#define ADL_APP_PROFILE_VERSION_LENGTH 32 +#define ADL_APP_PROFILE_PROPERTY_LENGTH 64 + +enum ApplicationListType +{ + ADL_PX40_MRU, + ADL_PX40_MISSED, + ADL_PX40_DISCRETE, + ADL_PX40_INTEGRATED, + ADL_MMD_PROFILED, + ADL_PX40_TOTAL +}; + +typedef enum ADLProfilePropertyType +{ + ADL_PROFILEPROPERTY_TYPE_BINARY = 0, + ADL_PROFILEPROPERTY_TYPE_BOOLEAN, + ADL_PROFILEPROPERTY_TYPE_DWORD, + ADL_PROFILEPROPERTY_TYPE_QWORD, + ADL_PROFILEPROPERTY_TYPE_ENUMERATED, + ADL_PROFILEPROPERTY_TYPE_STRING +}ADLProfilePropertyType; + + +//Virtual display type returning virtual display type and for request for creating a dummy target ID (xInput or remote play) +typedef enum ADL_VIRTUALDISPLAY_TYPE +{ + ADL_VIRTUALDISPLAY_NONE = 0, + ADL_VIRTUALDISPLAY_XINPUT = 1, //Requested for xInput + ADL_VIRTUALDISPLAY_REMOTEPLAY = 2, //Requested for emulated display during remote play + ADL_VIRTUALDISPLAY_GENERIC = 10 //Generic virtual display, af a type different than any of the above special ones +}ADL_VIRTUALDISPLAY_TYPE; + +/// @} + +///\defgroup define_dp12 For Display Port 1.2 +/// @{ + +/// Maximum Relative Address Link +#define ADL_MAX_RAD_LINK_COUNT 15 + +/// @} + +///\defgroup defines_gamutspace Driver Supported Gamut Space +/// @{ + +/// The flags desribes that gamut is related to source or to destination and to overlay or to graphics +#define ADL_GAMUT_REFERENCE_SOURCE (1 << 0) +#define ADL_GAMUT_GAMUT_VIDEO_CONTENT (1 << 1) + +/// The flags are used to describe the source of gamut and how read information from struct ADLGamutData +#define ADL_CUSTOM_WHITE_POINT (1 << 0) +#define ADL_CUSTOM_GAMUT (1 << 1) +#define ADL_GAMUT_REMAP_ONLY (1 << 2) + +/// The define means the predefined gamut values . +///Driver uses to find entry in the table and apply appropriate gamut space. +#define ADL_GAMUT_SPACE_CCIR_709 (1 << 0) +#define ADL_GAMUT_SPACE_CCIR_601 (1 << 1) +#define ADL_GAMUT_SPACE_ADOBE_RGB (1 << 2) +#define ADL_GAMUT_SPACE_CIE_RGB (1 << 3) +#define ADL_GAMUT_SPACE_CUSTOM (1 << 4) +#define ADL_GAMUT_SPACE_CCIR_2020 (1 << 5) +#define ADL_GAMUT_SPACE_APPCTRL (1 << 6) + +/// Predefine white point values are structed similar to gamut . +#define ADL_WHITE_POINT_5000K (1 << 0) +#define ADL_WHITE_POINT_6500K (1 << 1) +#define ADL_WHITE_POINT_7500K (1 << 2) +#define ADL_WHITE_POINT_9300K (1 << 3) +#define ADL_WHITE_POINT_CUSTOM (1 << 4) + +///gamut and white point coordinates are from 0.0 -1.0 and divider is used to find the real value . +/// X float = X int /divider +#define ADL_GAMUT_WHITEPOINT_DIVIDER 10000 + +///gamma a0 coefficient uses the following divider: +#define ADL_REGAMMA_COEFFICIENT_A0_DIVIDER 10000000 +///gamma a1 ,a2,a3 coefficients use the following divider: +#define ADL_REGAMMA_COEFFICIENT_A1A2A3_DIVIDER 1000 + +///describes whether the coefficients are from EDID or custom user values. +#define ADL_EDID_REGAMMA_COEFFICIENTS (1 << 0) +///Used for struct ADLRegamma. Feature if set use gamma ramp, if missing use regamma coefficents +#define ADL_USE_GAMMA_RAMP (1 << 4) +///Used for struct ADLRegamma. If the gamma ramp flag is used then the driver could apply de gamma corretion to the supplied curve and this depends on this flag +#define ADL_APPLY_DEGAMMA (1 << 5) +///specifies that standard SRGB gamma should be applied +#define ADL_EDID_REGAMMA_PREDEFINED_SRGB (1 << 1) +///specifies that PQ gamma curve should be applied +#define ADL_EDID_REGAMMA_PREDEFINED_PQ (1 << 2) +///specifies that PQ gamma curve should be applied, lower max nits +#define ADL_EDID_REGAMMA_PREDEFINED_PQ_2084_INTERIM (1 << 3) +///specifies that 3.6 gamma should be applied +#define ADL_EDID_REGAMMA_PREDEFINED_36 (1 << 6) +///specifies that BT709 gama should be applied +#define ADL_EDID_REGAMMA_PREDEFINED_BT709 (1 << 7) +///specifies that regamma should be disabled, and application controls regamma content (of the whole screen) +#define ADL_EDID_REGAMMA_PREDEFINED_APPCTRL (1 << 8) + +/// @} + +/// \defgroup define_ddcinfo_pixelformats DDCInfo Pixel Formats +/// @{ +/// defines for iPanelPixelFormat in struct ADLDDCInfo2 +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB656 0x00000001L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB666 0x00000002L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB888 0x00000004L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB101010 0x00000008L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB161616 0x00000010L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED1 0x00000020L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED2 0x00000040L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED3 0x00000080L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_XRGB_BIAS101010 0x00000100L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_8BPCC 0x00000200L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_10BPCC 0x00000400L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_12BPCC 0x00000800L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_8BPCC 0x00001000L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_10BPCC 0x00002000L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_12BPCC 0x00004000L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_8BPCC 0x00008000L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_10BPCC 0x00010000L +#define ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_12BPCC 0x00020000L +/// @} + +/// \defgroup define_source_content_TF ADLSourceContentAttributes transfer functions (gamma) +/// @{ +/// defines for iTransferFunction in ADLSourceContentAttributes +#define ADL_TF_sRGB 0x0001 ///< sRGB +#define ADL_TF_BT709 0x0002 ///< BT.709 +#define ADL_TF_PQ2084 0x0004 ///< PQ2084 +#define ADL_TF_PQ2084_INTERIM 0x0008 ///< PQ2084-Interim +#define ADL_TF_LINEAR_0_1 0x0010 ///< Linear 0 - 1 +#define ADL_TF_LINEAR_0_125 0x0020 ///< Linear 0 - 125 +#define ADL_TF_DOLBYVISION 0x0040 ///< DolbyVision +#define ADL_TF_GAMMA_22 0x0080 ///< Plain 2.2 gamma curve +/// @} + +/// \defgroup define_source_content_CS ADLSourceContentAttributes color spaces +/// @{ +/// defines for iColorSpace in ADLSourceContentAttributes +#define ADL_CS_sRGB 0x0001 ///< sRGB +#define ADL_CS_BT601 0x0002 ///< BT.601 +#define ADL_CS_BT709 0x0004 ///< BT.709 +#define ADL_CS_BT2020 0x0008 ///< BT.2020 +#define ADL_CS_ADOBE 0x0010 ///< Adobe RGB +#define ADL_CS_P3 0x0020 ///< DCI-P3 +#define ADL_CS_scRGB_MS_REF 0x0040 ///< scRGB (MS Reference) +#define ADL_CS_DISPLAY_NATIVE 0x0080 ///< Display Native +#define ADL_CS_APP_CONTROL 0x0100 ///< Application Controlled +#define ADL_CS_DOLBYVISION 0x0200 ///< DolbyVision +/// @} + +/// \defgroup define_HDR_support ADLDDCInfo2 HDR support options +/// @{ +/// defines for iSupportedHDR in ADLDDCInfo2 +#define ADL_HDR_CEA861_3 0x0001 ///< HDR10/CEA861.3 HDR supported +#define ADL_HDR_DOLBYVISION 0x0002 ///< \deprecated DolbyVision HDR supported +#define ADL_HDR_FREESYNC_HDR 0x0004 ///< FreeSync HDR supported +/// @} + +/// \defgroup define_FreesyncFlags ADLDDCInfo2 Freesync HDR flags +/// @{ +/// defines for iFreesyncFlags in ADLDDCInfo2 +#define ADL_HDR_FREESYNC_BACKLIGHT_SUPPORT 0x0001 ///< Global backlight control supported +#define ADL_HDR_FREESYNC_LOCAL_DIMMING 0x0002 ///< Local dimming supported +/// @} + +/// \defgroup define_source_content_flags ADLSourceContentAttributes flags +/// @{ +/// defines for iFlags in ADLSourceContentAttributes +#define ADL_SCA_LOCAL_DIMMING_DISABLE 0x0001 ///< Disable local dimming +/// @} + +/// \defgroup define_dbd_state Deep Bit Depth +/// @{ + +/// defines for ADL_Workstation_DeepBitDepth_Get and ADL_Workstation_DeepBitDepth_Set functions +// This value indicates that the deep bit depth state is forced off +#define ADL_DEEPBITDEPTH_FORCEOFF 0 +/// This value indicates that the deep bit depth state is set to auto, the driver will automatically enable the +/// appropriate deep bit depth state depending on what connected display supports. +#define ADL_DEEPBITDEPTH_10BPP_AUTO 1 +/// This value indicates that the deep bit depth state is forced on to 10 bits per pixel, this is regardless if the display +/// supports 10 bpp. +#define ADL_DEEPBITDEPTH_10BPP_FORCEON 2 + +/// defines for ADLAdapterConfigMemory of ADL_Adapter_ConfigMemory_Get +/// If this bit is set, it indicates that the Deep Bit Depth pixel is set on the display +#define ADL_ADAPTER_CONFIGMEMORY_DBD (1 << 0) +/// If this bit is set, it indicates that the display is rotated (90, 180 or 270) +#define ADL_ADAPTER_CONFIGMEMORY_ROTATE (1 << 1) +/// If this bit is set, it indicates that passive stereo is set on the display +#define ADL_ADAPTER_CONFIGMEMORY_STEREO_PASSIVE (1 << 2) +/// If this bit is set, it indicates that the active stereo is set on the display +#define ADL_ADAPTER_CONFIGMEMORY_STEREO_ACTIVE (1 << 3) +/// If this bit is set, it indicates that the tear free vsync is set on the display +#define ADL_ADAPTER_CONFIGMEMORY_ENHANCEDVSYNC (1 << 4) +#define ADL_ADAPTER_CONFIGMEMORY_TEARFREEVSYNC (1 << 4) +/// @} + +/// \defgroup define_adl_validmemoryrequiredfields Memory Type +/// @{ + +/// This group defines memory types in ADLMemoryRequired struct \n +/// Indicates that this is the visible memory +#define ADL_MEMORYREQTYPE_VISIBLE (1 << 0) +/// Indicates that this is the invisible memory. +#define ADL_MEMORYREQTYPE_INVISIBLE (1 << 1) +/// Indicates that this is amount of visible memory per GPU that should be reserved for all other allocations. +#define ADL_MEMORYREQTYPE_GPURESERVEDVISIBLE (1 << 2) +/// @} + +/// \defgroup define_adapter_tear_free_status +/// Used in ADL_Adapter_TEAR_FREE_Set and ADL_Adapter_TFD_Get functions to indicate the tear free +/// desktop status. +/// @{ +/// Tear free desktop is enabled. +#define ADL_ADAPTER_TEAR_FREE_ON 1 +/// Tear free desktop can't be enabled due to a lack of graphic adapter memory. +#define ADL_ADAPTER_TEAR_FREE_NOTENOUGHMEM -1 +/// Tear free desktop can't be enabled due to quad buffer stereo being enabled. +#define ADL_ADAPTER_TEAR_FREE_OFF_ERR_QUADBUFFERSTEREO -2 +/// Tear free desktop can't be enabled due to MGPU-SLS being enabled. +#define ADL_ADAPTER_TEAR_FREE_OFF_ERR_MGPUSLD -3 +/// Tear free desktop is disabled. +#define ADL_ADAPTER_TEAR_FREE_OFF 0 +/// @} + +/// \defgroup define_adapter_crossdisplay_platforminfo +/// Used in ADL_Adapter_CrossDisplayPlatformInfo_Get function to indicate the Crossdisplay platform info. +/// @{ +/// CROSSDISPLAY platform. +#define ADL_CROSSDISPLAY_PLATFORM (1 << 0) +/// CROSSDISPLAY platform for Lasso station. +#define ADL_CROSSDISPLAY_PLATFORM_LASSO (1 << 1) +/// CROSSDISPLAY platform for docking station. +#define ADL_CROSSDISPLAY_PLATFORM_DOCKSTATION (1 << 2) +/// @} + +/// \defgroup define_adapter_crossdisplay_option +/// Used in ADL_Adapter_CrossdisplayInfoX2_Set function to indicate cross display options. +/// @{ +/// Checking if 3D application is runnning. If yes, not to do switch, return ADL_OK_WAIT; otherwise do switch. +#define ADL_CROSSDISPLAY_OPTION_NONE 0 +/// Force switching without checking for running 3D applications +#define ADL_CROSSDISPLAY_OPTION_FORCESWITCH (1 << 0) +/// @} + +/// \defgroup define_adapter_states Adapter Capabilities +/// These defines the capabilities supported by an adapter. It is used by \ref ADL_Adapter_ConfigureState_Get +/// @{ +/// Indicates that the adapter is headless (i.e. no displays can be connected to it) +#define ADL_ADAPTERCONFIGSTATE_HEADLESS ( 1 << 2 ) +/// Indicates that the adapter is configured to define the main rendering capabilities. For example, adapters +/// in Crossfire(TM) configuration, this bit would only be set on the adapter driving the display(s). +#define ADL_ADAPTERCONFIGSTATE_REQUISITE_RENDER ( 1 << 0 ) +/// Indicates that the adapter is configured to be used to unload some of the rendering work for a particular +/// requisite rendering adapter. For eample, for adapters in a Crossfire configuration, this bit would be set +/// on all adapters that are currently not driving the display(s) +#define ADL_ADAPTERCONFIGSTATE_ANCILLARY_RENDER ( 1 << 1 ) +/// Indicates that scatter gather feature enabled on the adapter +#define ADL_ADAPTERCONFIGSTATE_SCATTERGATHER ( 1 << 4 ) +/// @} + +/// \defgroup define_controllermode_ulModifiers +/// These defines the detailed actions supported by set viewport. It is used by \ref ADL_Display_ViewPort_Set +/// @{ +/// Indicate that the viewport set will change the view position +#define ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_POSITION 0x00000001 +/// Indicate that the viewport set will change the view PanLock +#define ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_PANLOCK 0x00000002 +/// Indicate that the viewport set will change the view size +#define ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_SIZE 0x00000008 +/// @} + +/// \defgroup defines for Mirabilis +/// These defines are used for the Mirabilis feature +/// @{ +/// +/// Indicates the maximum number of audio sample rates +#define ADL_MAX_AUDIO_SAMPLE_RATE_COUNT 16 +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADLMultiChannelSplitStateFlag Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLMultiChannelSplitStateFlag +{ + ADLMultiChannelSplit_Unitialized = 0, + ADLMultiChannelSplit_Disabled = 1, + ADLMultiChannelSplit_Enabled = 2, + ADLMultiChannelSplit_SaveProfile = 3 +}; + +/////////////////////////////////////////////////////////////////////////// +// ADLSampleRate Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLSampleRate +{ + ADLSampleRate_32KHz =0, + ADLSampleRate_44P1KHz, + ADLSampleRate_48KHz, + ADLSampleRate_88P2KHz, + ADLSampleRate_96KHz, + ADLSampleRate_176P4KHz, + ADLSampleRate_192KHz, + ADLSampleRate_384KHz, //DP1.2 + ADLSampleRate_768KHz, //DP1.2 + ADLSampleRate_Undefined +}; + +/// \defgroup define_overdrive6_capabilities +/// These defines the capabilities supported by Overdrive 6. It is used by \ref ADL_Overdrive6_Capabilities_Get +/// @{ +/// Indicate that core (engine) clock can be changed. +#define ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION 0x00000001 +/// Indicate that memory clock can be changed. +#define ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION 0x00000002 +/// Indicate that graphics activity reporting is supported. +#define ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR 0x00000004 +/// Indicate that power limit can be customized. +#define ADL_OD6_CAPABILITY_POWER_CONTROL 0x00000008 +/// Indicate that SVI2 Voltage Control is supported. +#define ADL_OD6_CAPABILITY_VOLTAGE_CONTROL 0x00000010 +/// Indicate that OD6+ percentage adjustment is supported. +#define ADL_OD6_CAPABILITY_PERCENT_ADJUSTMENT 0x00000020 +/// Indicate that Thermal Limit Unlock is supported. +#define ADL_OD6_CAPABILITY_THERMAL_LIMIT_UNLOCK 0x00000040 +///Indicate that Fan speed needs to be displayed in RPM +#define ADL_OD6_CAPABILITY_FANSPEED_IN_RPM 0x00000080 +/// @} + +/// \defgroup define_overdrive6_supported_states +/// These defines the power states supported by Overdrive 6. It is used by \ref ADL_Overdrive6_Capabilities_Get +/// @{ +/// Indicate that overdrive is supported in the performance state. This is currently the only state supported. +#define ADL_OD6_SUPPORTEDSTATE_PERFORMANCE 0x00000001 +/// Do not use. Reserved for future use. +#define ADL_OD6_SUPPORTEDSTATE_POWER_SAVING 0x00000002 +/// @} + +/// \defgroup define_overdrive6_getstateinfo +/// These defines the power states to get information about. It is used by \ref ADL_Overdrive6_StateInfo_Get +/// @{ +/// Get default clocks for the performance state. +#define ADL_OD6_GETSTATEINFO_DEFAULT_PERFORMANCE 0x00000001 +/// Do not use. Reserved for future use. +#define ADL_OD6_GETSTATEINFO_DEFAULT_POWER_SAVING 0x00000002 +/// Get clocks for current state. Currently this is the same as \ref ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE +/// since only performance state is supported. +#define ADL_OD6_GETSTATEINFO_CURRENT 0x00000003 +/// Get the modified clocks (if any) for the performance state. If clocks were not modified +/// through Overdrive 6, then this will return the same clocks as \ref ADL_OD6_GETSTATEINFO_DEFAULT_PERFORMANCE. +#define ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE 0x00000004 +/// Do not use. Reserved for future use. +#define ADL_OD6_GETSTATEINFO_CUSTOM_POWER_SAVING 0x00000005 +/// @} + +/// \defgroup define_overdrive6_getstate and define_overdrive6_getmaxclockadjust +/// These defines the power states to get information about. It is used by \ref ADL_Overdrive6_StateEx_Get and \ref ADL_Overdrive6_MaxClockAdjust_Get +/// @{ +/// Get default clocks for the performance state. Only performance state is currently supported. +#define ADL_OD6_STATE_PERFORMANCE 0x00000001 +/// @} + +/// \defgroup define_overdrive6_setstate +/// These define which power state to set customized clocks on. It is used by \ref ADL_Overdrive6_State_Set +/// @{ +/// Set customized clocks for the performance state. +#define ADL_OD6_SETSTATE_PERFORMANCE 0x00000001 +/// Do not use. Reserved for future use. +#define ADL_OD6_SETSTATE_POWER_SAVING 0x00000002 +/// @} + +/// \defgroup define_overdrive6_thermalcontroller_caps +/// These defines the capabilities of the GPU thermal controller. It is used by \ref ADL_Overdrive6_ThermalController_Caps +/// @{ +/// GPU thermal controller is supported. +#define ADL_OD6_TCCAPS_THERMAL_CONTROLLER 0x00000001 +/// GPU fan speed control is supported. +#define ADL_OD6_TCCAPS_FANSPEED_CONTROL 0x00000002 +/// Fan speed percentage can be read. +#define ADL_OD6_TCCAPS_FANSPEED_PERCENT_READ 0x00000100 +/// Fan speed can be set by specifying a percentage value. +#define ADL_OD6_TCCAPS_FANSPEED_PERCENT_WRITE 0x00000200 +/// Fan speed RPM (revolutions-per-minute) can be read. +#define ADL_OD6_TCCAPS_FANSPEED_RPM_READ 0x00000400 +/// Fan speed can be set by specifying an RPM value. +#define ADL_OD6_TCCAPS_FANSPEED_RPM_WRITE 0x00000800 +/// @} + +/// \defgroup define_overdrive6_fanspeed_type +/// These defines the fan speed type being reported. It is used by \ref ADL_Overdrive6_FanSpeed_Get +/// @{ +/// Fan speed reported in percentage. +#define ADL_OD6_FANSPEED_TYPE_PERCENT 0x00000001 +/// Fan speed reported in RPM. +#define ADL_OD6_FANSPEED_TYPE_RPM 0x00000002 +/// Fan speed has been customized by the user, and fan is not running in automatic mode. +#define ADL_OD6_FANSPEED_USER_DEFINED 0x00000100 +/// @} + +/// \defgroup define_overdrive_EventCounter_type +/// These defines the EventCounter type being reported. It is used by \ref ADL2_OverdriveN_CountOfEvents_Get ,can be used on older OD version supported ASICs also. +/// @{ +#define ADL_ODN_EVENTCOUNTER_THERMAL 0 +#define ADL_ODN_EVENTCOUNTER_VPURECOVERY 1 +/// @} + +/////////////////////////////////////////////////////////////////////////// +// ADLODNControlType Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLODNControlType +{ + ODNControlType_Current = 0, + ODNControlType_Default, + ODNControlType_Auto, + ODNControlType_Manual +}; + +enum ADLODNDPMMaskType +{ + ADL_ODN_DPM_CLOCK = 1 << 0, + ADL_ODN_DPM_VDDC = 1 << 1, + ADL_ODN_DPM_MASK = 1 << 2, +}; + +//ODN features Bits for ADLODNCapabilitiesX2 +enum ADLODNFeatureControl +{ + ADL_ODN_SCLK_DPM = 1 << 0, + ADL_ODN_MCLK_DPM = 1 << 1, + ADL_ODN_SCLK_VDD = 1 << 2, + ADL_ODN_MCLK_VDD = 1 << 3, + ADL_ODN_FAN_SPEED_MIN = 1 << 4, + ADL_ODN_FAN_SPEED_TARGET = 1 << 5, + ADL_ODN_ACOUSTIC_LIMIT_SCLK = 1 << 6, + ADL_ODN_TEMPERATURE_FAN_MAX = 1 << 7, + ADL_ODN_TEMPERATURE_SYSTEM = 1 << 8, + ADL_ODN_POWER_LIMIT = 1 << 9, + ADL_ODN_SCLK_AUTO_LIMIT = 1 << 10, + ADL_ODN_MCLK_AUTO_LIMIT = 1 << 11, + ADL_ODN_SCLK_DPM_MASK_ENABLE = 1 << 12, + ADL_ODN_MCLK_DPM_MASK_ENABLE = 1 << 13, + ADL_ODN_MCLK_UNDERCLOCK_ENABLE = 1 << 14, + ADL_ODN_SCLK_DPM_THROTTLE_NOTIFY = 1 << 15, + ADL_ODN_POWER_UTILIZATION = 1 << 16, + ADL_ODN_PERF_TUNING_SLIDER = 1 << 17, + ADL_ODN_REMOVE_WATTMAN_PAGE = 1 << 31 // Internal Only +}; + +//If any new feature is added, PPLIB only needs to add ext feature ID and Item ID(Seeting ID). These IDs should match the drive defined in CWDDEPM.h +enum ADLODNExtFeatureControl +{ + ADL_ODN_EXT_FEATURE_MEMORY_TIMING_TUNE = 1 << 0, + ADL_ODN_EXT_FEATURE_FAN_ZERO_RPM_CONTROL = 1 << 1, + ADL_ODN_EXT_FEATURE_AUTO_UV_ENGINE = 1 << 2, //Auto under voltage + ADL_ODN_EXT_FEATURE_AUTO_OC_ENGINE = 1 << 3, //Auto OC Enine + ADL_ODN_EXT_FEATURE_AUTO_OC_MEMORY = 1 << 4, //Auto OC memory + ADL_ODN_EXT_FEATURE_FAN_CURVE = 1 << 5 //Fan curve + +}; + +//If any new feature is added, PPLIB only needs to add ext feature ID and Item ID(Seeting ID).These IDs should match the drive defined in CWDDEPM.h +enum ADLODNExtSettingId +{ + ADL_ODN_PARAMETER_AC_TIMING = 0, + ADL_ODN_PARAMETER_FAN_ZERO_RPM_CONTROL, + ADL_ODN_PARAMETER_AUTO_UV_ENGINE, + ADL_ODN_PARAMETER_AUTO_OC_ENGINE, + ADL_ODN_PARAMETER_AUTO_OC_MEMORY, + ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_1, + ADL_ODN_PARAMETER_FAN_CURVE_SPEED_1, + ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_2, + ADL_ODN_PARAMETER_FAN_CURVE_SPEED_2, + ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_3, + ADL_ODN_PARAMETER_FAN_CURVE_SPEED_3, + ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_4, + ADL_ODN_PARAMETER_FAN_CURVE_SPEED_4, + ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_5, + ADL_ODN_PARAMETER_FAN_CURVE_SPEED_5, + ADL_ODN_POWERGAUGE, + ODN_COUNT + +} ; + +//OD8 Capability features bits +enum ADLOD8FeatureControl +{ + ADL_OD8_GFXCLK_LIMITS = 1 << 0, + ADL_OD8_GFXCLK_CURVE = 1 << 1, + ADL_OD8_UCLK_MAX = 1 << 2, + ADL_OD8_POWER_LIMIT = 1 << 3, + ADL_OD8_ACOUSTIC_LIMIT_SCLK = 1 << 4, //FanMaximumRpm + ADL_OD8_FAN_SPEED_MIN = 1 << 5, //FanMinimumPwm + ADL_OD8_TEMPERATURE_FAN = 1 << 6, //FanTargetTemperature + ADL_OD8_TEMPERATURE_SYSTEM = 1 << 7, //MaxOpTemp + ADL_OD8_MEMORY_TIMING_TUNE = 1 << 8, + ADL_OD8_FAN_ZERO_RPM_CONTROL = 1 << 9 , + ADL_OD8_AUTO_UV_ENGINE = 1 << 10, //Auto under voltage + ADL_OD8_AUTO_OC_ENGINE = 1 << 11, //Auto overclock engine + ADL_OD8_AUTO_OC_MEMORY = 1 << 12, //Auto overclock memory + ADL_OD8_FAN_CURVE = 1 << 13, //Fan curve + ADL_OD8_WS_AUTO_FAN_ACOUSTIC_LIMIT = 1 << 14, //Workstation Manual Fan controller + ADL_OD8_GFXCLK_QUADRATIC_CURVE = 1 << 15, + ADL_OD8_OPTIMIZED_GPU_POWER_MODE = 1 << 16, + ADL_OD8_ODVOLTAGE_LIMIT = 1 << 17, + ADL_OD8_ADV_OC_LIMITS = 1 << 18, //Advanced OC limits. + ADL_OD8_PER_ZONE_GFX_VOLTAGE_OFFSET = 1 << 19, //Per Zone gfx voltage offset feature + ADL_OD8_AUTO_CURVE_OPTIMIZER = 1 << 20, //Auto per zone tuning. + ADL_OD8_GFX_VOLTAGE_LIMIT = 1 << 21, //Voltage limit slider + ADL_OD8_TDC_LIMIT = 1 << 22, //TDC slider + ADL_OD8_FULL_CONTROL_MODE = 1 << 23, //Full control + ADL_OD8_POWER_SAVING_FEATURE_CONTROL = 1 << 24, //Power saving feature control + ADL_OD8_POWER_GAUGE = 1 << 25 //Power Gauge +}; + + +typedef enum ADLOD8SettingId +{ + OD8_GFXCLK_FMAX = 0, + OD8_GFXCLK_FMIN, + OD8_GFXCLK_FREQ1, + OD8_GFXCLK_VOLTAGE1, + OD8_GFXCLK_FREQ2, + OD8_GFXCLK_VOLTAGE2, + OD8_GFXCLK_FREQ3, + OD8_GFXCLK_VOLTAGE3, + OD8_UCLK_FMAX, + OD8_POWER_PERCENTAGE, + OD8_FAN_MIN_SPEED, + OD8_FAN_ACOUSTIC_LIMIT, + OD8_FAN_TARGET_TEMP, + OD8_OPERATING_TEMP_MAX, + OD8_AC_TIMING, + OD8_FAN_ZERORPM_CONTROL, + OD8_AUTO_UV_ENGINE_CONTROL, + OD8_AUTO_OC_ENGINE_CONTROL, + OD8_AUTO_OC_MEMORY_CONTROL, + OD8_FAN_CURVE_TEMPERATURE_1, + OD8_FAN_CURVE_SPEED_1, + OD8_FAN_CURVE_TEMPERATURE_2, + OD8_FAN_CURVE_SPEED_2, + OD8_FAN_CURVE_TEMPERATURE_3, + OD8_FAN_CURVE_SPEED_3, + OD8_FAN_CURVE_TEMPERATURE_4, + OD8_FAN_CURVE_SPEED_4, + OD8_FAN_CURVE_TEMPERATURE_5, + OD8_FAN_CURVE_SPEED_5, + OD8_WS_FAN_AUTO_FAN_ACOUSTIC_LIMIT, + OD8_GFXCLK_CURVE_COEFFICIENT_A, // As part of the agreement with UI team, the min/max voltage limits for the + OD8_GFXCLK_CURVE_COEFFICIENT_B, // quadratic curve graph will be stored in the min and max limits of + OD8_GFXCLK_CURVE_COEFFICIENT_C, // coefficient a, b and c. A, b and c themselves do not have limits. + OD8_GFXCLK_CURVE_VFT_FMIN, + OD8_UCLK_FMIN, + OD8_FAN_ZERO_RPM_STOP_TEMPERATURE, + OD8_OPTIMZED_POWER_MODE, + OD8_OD_VOLTAGE,// RSX - voltage offset feature + OD8_ADV_OC_LIMITS_SETTING, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_1, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_2, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_3, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_4, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_5, + OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_6, + OD8_AUTO_CURVE_OPTIMIZER_SETTING, + OD8_GFX_VOLTAGE_LIMIT_SETTING, + OD8_TDC_PERCENTAGE, + OD8_FULL_CONTROL_MODE_SETTING, + OD8_IDLE_POWER_SAVING_FEATURE_CONTROL, + OD8_RUNTIME_POWER_SAVING_FEATURE_CONTROL, + OD8_POWER_GAUGE, + OD8_COUNT +} ADLOD8SettingId; + + +//Define Performance Metrics Log max sensors number +#define ADL_PMLOG_MAX_SENSORS 256 + +/// \deprecated Replaced with ADL_PMLOG_SENSORS +typedef enum ADLSensorType +{ + SENSOR_MAXTYPES = 0, + PMLOG_CLK_GFXCLK = 1, // Current graphic clock value in MHz + PMLOG_CLK_MEMCLK = 2, // Current memory clock value in MHz + PMLOG_CLK_SOCCLK = 3, + PMLOG_CLK_UVDCLK1 = 4, + PMLOG_CLK_UVDCLK2 = 5, + PMLOG_CLK_VCECLK = 6, + PMLOG_CLK_VCNCLK = 7, + PMLOG_TEMPERATURE_EDGE = 8, // Current edge of the die temperature value in C + PMLOG_TEMPERATURE_MEM = 9, + PMLOG_TEMPERATURE_VRVDDC = 10, + PMLOG_TEMPERATURE_VRMVDD = 11, + PMLOG_TEMPERATURE_LIQUID = 12, + PMLOG_TEMPERATURE_PLX = 13, + PMLOG_FAN_RPM = 14, // Current fan RPM value + PMLOG_FAN_PERCENTAGE = 15, // Current ratio of fan RPM and max RPM + PMLOG_SOC_VOLTAGE = 16, + PMLOG_SOC_POWER = 17, + PMLOG_SOC_CURRENT = 18, + PMLOG_INFO_ACTIVITY_GFX = 19, // Current graphic activity level in percentage + PMLOG_INFO_ACTIVITY_MEM = 20, // Current memory activity level in percentage + PMLOG_GFX_VOLTAGE = 21, // Current graphic voltage in mV + PMLOG_MEM_VOLTAGE = 22, + PMLOG_ASIC_POWER = 23, // Current ASIC power draw in Watt + PMLOG_TEMPERATURE_VRSOC = 24, + PMLOG_TEMPERATURE_VRMVDD0 = 25, + PMLOG_TEMPERATURE_VRMVDD1 = 26, + PMLOG_TEMPERATURE_HOTSPOT = 27, // Current center of the die temperature value in C + PMLOG_TEMPERATURE_GFX = 28, + PMLOG_TEMPERATURE_SOC = 29, + PMLOG_GFX_POWER = 30, + PMLOG_GFX_CURRENT = 31, + PMLOG_TEMPERATURE_CPU = 32, + PMLOG_CPU_POWER = 33, + PMLOG_CLK_CPUCLK = 34, + PMLOG_THROTTLER_STATUS = 35, // A bit map of GPU throttle information. If a bit is set, the bit represented type of thorttling occurred in the last metrics sampling period + PMLOG_CLK_VCN1CLK1 = 36, + PMLOG_CLK_VCN1CLK2 = 37, + PMLOG_SMART_POWERSHIFT_CPU = 38, + PMLOG_SMART_POWERSHIFT_DGPU = 39, + PMLOG_BUS_SPEED = 40, // Current PCIE bus speed running + PMLOG_BUS_LANES = 41, // Current PCIE bus lanes using + PMLOG_TEMPERATURE_LIQUID0 = 42, + PMLOG_TEMPERATURE_LIQUID1 = 43, + PMLOG_CLK_FCLK = 44, + PMLOG_THROTTLER_STATUS_CPU = 45, + PMLOG_SSPAIRED_ASICPOWER = 46, // apuPower + PMLOG_SSTOTAL_POWERLIMIT = 47, // Total Power limit + PMLOG_SSAPU_POWERLIMIT = 48, // APU Power limit + PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit + PMLOG_TEMPERATURE_HOTSPOT_GCD = 50, + PMLOG_TEMPERATURE_HOTSPOT_MCD = 51, + PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52, + PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53, + PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54, + PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55, + PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56, + PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57, + PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58, + PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59, + PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60, + PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61, + PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62, + PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63, + PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64, + PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65, + PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66, + PMLOG_THROTTLER_PPT0_PERCENTAGE = 67, + PMLOG_THROTTLER_PPT1_PERCENTAGE = 68, + PMLOG_THROTTLER_PPT2_PERCENTAGE = 69, + PMLOG_THROTTLER_PPT3_PERCENTAGE = 70, + PMLOG_THROTTLER_FIT_PERCENTAGE = 71, + PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72, + PMLOG_BOARD_POWER = 73, + PMLOG_MAX_SENSORS_REAL +} ADLSensorType; + + +//Throttle Status +typedef enum ADL_THROTTLE_NOTIFICATION +{ + ADL_PMLOG_THROTTLE_POWER = 1 << 0, + ADL_PMLOG_THROTTLE_THERMAL = 1 << 1, + ADL_PMLOG_THROTTLE_CURRENT = 1 << 2, +} ADL_THROTTLE_NOTIFICATION; + +typedef enum ADL_PMLOG_SENSORS +{ + ADL_SENSOR_MAXTYPES = 0, + ADL_PMLOG_CLK_GFXCLK = 1, + ADL_PMLOG_CLK_MEMCLK = 2, + ADL_PMLOG_CLK_SOCCLK = 3, + ADL_PMLOG_CLK_UVDCLK1 = 4, + ADL_PMLOG_CLK_UVDCLK2 = 5, + ADL_PMLOG_CLK_VCECLK = 6, + ADL_PMLOG_CLK_VCNCLK = 7, + ADL_PMLOG_TEMPERATURE_EDGE = 8, + ADL_PMLOG_TEMPERATURE_MEM = 9, + ADL_PMLOG_TEMPERATURE_VRVDDC = 10, + ADL_PMLOG_TEMPERATURE_VRMVDD = 11, + ADL_PMLOG_TEMPERATURE_LIQUID = 12, + ADL_PMLOG_TEMPERATURE_PLX = 13, + ADL_PMLOG_FAN_RPM = 14, + ADL_PMLOG_FAN_PERCENTAGE = 15, + ADL_PMLOG_SOC_VOLTAGE = 16, + ADL_PMLOG_SOC_POWER = 17, + ADL_PMLOG_SOC_CURRENT = 18, + ADL_PMLOG_INFO_ACTIVITY_GFX = 19, + ADL_PMLOG_INFO_ACTIVITY_MEM = 20, + ADL_PMLOG_GFX_VOLTAGE = 21, + ADL_PMLOG_MEM_VOLTAGE = 22, + ADL_PMLOG_ASIC_POWER = 23, + ADL_PMLOG_TEMPERATURE_VRSOC = 24, + ADL_PMLOG_TEMPERATURE_VRMVDD0 = 25, + ADL_PMLOG_TEMPERATURE_VRMVDD1 = 26, + ADL_PMLOG_TEMPERATURE_HOTSPOT = 27, + ADL_PMLOG_TEMPERATURE_GFX = 28, + ADL_PMLOG_TEMPERATURE_SOC = 29, + ADL_PMLOG_GFX_POWER = 30, + ADL_PMLOG_GFX_CURRENT = 31, + ADL_PMLOG_TEMPERATURE_CPU = 32, + ADL_PMLOG_CPU_POWER = 33, + ADL_PMLOG_CLK_CPUCLK = 34, + ADL_PMLOG_THROTTLER_STATUS = 35, // GFX + ADL_PMLOG_CLK_VCN1CLK1 = 36, + ADL_PMLOG_CLK_VCN1CLK2 = 37, + ADL_PMLOG_SMART_POWERSHIFT_CPU = 38, + ADL_PMLOG_SMART_POWERSHIFT_DGPU = 39, + ADL_PMLOG_BUS_SPEED = 40, + ADL_PMLOG_BUS_LANES = 41, + ADL_PMLOG_TEMPERATURE_LIQUID0 = 42, + ADL_PMLOG_TEMPERATURE_LIQUID1 = 43, + ADL_PMLOG_CLK_FCLK = 44, + ADL_PMLOG_THROTTLER_STATUS_CPU = 45, + ADL_PMLOG_SSPAIRED_ASICPOWER = 46, // apuPower + ADL_PMLOG_SSTOTAL_POWERLIMIT = 47, // Total Power limit + ADL_PMLOG_SSAPU_POWERLIMIT = 48, // APU Power limit + ADL_PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit + ADL_PMLOG_TEMPERATURE_HOTSPOT_GCD = 50, + ADL_PMLOG_TEMPERATURE_HOTSPOT_MCD = 51, + ADL_PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54, + ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55, + ADL_PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56, + ADL_PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57, + ADL_PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58, + ADL_PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59, + ADL_PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60, + ADL_PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61, + ADL_PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62, + ADL_PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63, + ADL_PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64, + ADL_PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65, + ADL_PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66, + ADL_PMLOG_THROTTLER_PPT0_PERCENTAGE = 67, + ADL_PMLOG_THROTTLER_PPT1_PERCENTAGE = 68, + ADL_PMLOG_THROTTLER_PPT2_PERCENTAGE = 69, + ADL_PMLOG_THROTTLER_PPT3_PERCENTAGE = 70, + ADL_PMLOG_THROTTLER_FIT_PERCENTAGE = 71, + ADL_PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72, + ADL_PMLOG_BOARD_POWER = 73, + ADL_PMLOG_MAX_SENSORS_REAL +} ADL_PMLOG_SENSORS; + +/// \defgroup define_ecc_mode_states +/// These defines the ECC(Error Correction Code) state. It is used by \ref ADL_Workstation_ECC_Get,ADL_Workstation_ECC_Set +/// @{ +/// Error Correction is OFF. +#define ECC_MODE_OFF 0 +/// Error Correction is ECCV2. +#define ECC_MODE_ON 2 +/// Error Correction is HBM. +#define ECC_MODE_HBM 3 +/// @} + +/// \defgroup define_board_layout_flags +/// These defines are the board layout flags state which indicates what are the valid properties of \ref ADLBoardLayoutInfo . It is used by \ref ADL_Adapter_BoardLayout_Get +/// @{ +/// Indicates the number of slots is valid. +#define ADL_BLAYOUT_VALID_NUMBER_OF_SLOTS 0x1 +/// Indicates the slot sizes are valid. Size of the slot consists of the length and width. +#define ADL_BLAYOUT_VALID_SLOT_SIZES 0x2 +/// Indicates the connector offsets are valid. +#define ADL_BLAYOUT_VALID_CONNECTOR_OFFSETS 0x4 +/// Indicates the connector lengths is valid. +#define ADL_BLAYOUT_VALID_CONNECTOR_LENGTHS 0x8 +/// @} + +/// \defgroup define_max_constants +/// These defines are the maximum value constants. +/// @{ +/// Indicates the Maximum supported slots on board. +#define ADL_ADAPTER_MAX_SLOTS 4 +/// Indicates the Maximum supported connectors on slot. +#define ADL_ADAPTER_MAX_CONNECTORS 10 +/// Indicates the Maximum supported properties of connection +#define ADL_MAX_CONNECTION_TYPES 32 +/// Indicates the Maximum relative address link count. +#define ADL_MAX_RELATIVE_ADDRESS_LINK_COUNT 15 +/// Indicates the Maximum size of EDID data block size +#define ADL_MAX_DISPLAY_EDID_DATA_SIZE 1024 +/// Indicates the Maximum count of Error Records. +#define ADL_MAX_ERROR_RECORDS_COUNT 256 +/// Indicates the maximum number of power states supported +#define ADL_MAX_POWER_POLICY 6 +/// @} + +/// \defgroup define_connection_types +/// These defines are the connection types constants which indicates what are the valid connection type of given connector. It is used by \ref ADL_Adapter_SupportedConnections_Get +/// @{ +/// Indicates the VGA connection type is valid. +#define ADL_CONNECTION_TYPE_VGA 0 +/// Indicates the DVI_I connection type is valid. +#define ADL_CONNECTION_TYPE_DVI 1 +/// Indicates the DVI_SL connection type is valid. +#define ADL_CONNECTION_TYPE_DVI_SL 2 +/// Indicates the HDMI connection type is valid. +#define ADL_CONNECTION_TYPE_HDMI 3 +/// Indicates the DISPLAY PORT connection type is valid. +#define ADL_CONNECTION_TYPE_DISPLAY_PORT 4 +/// Indicates the Active dongle DP->DVI(single link) connection type is valid. +#define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_SL 5 +/// Indicates the Active dongle DP->DVI(double link) connection type is valid. +#define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_DL 6 +/// Indicates the Active dongle DP->HDMI connection type is valid. +#define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_HDMI 7 +/// Indicates the Active dongle DP->VGA connection type is valid. +#define ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_VGA 8 +/// Indicates the Passive dongle DP->HDMI connection type is valid. +#define ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_HDMI 9 +/// Indicates the Active dongle DP->VGA connection type is valid. +#define ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_DVI 10 +/// Indicates the MST type is valid. +#define ADL_CONNECTION_TYPE_MST 11 +/// Indicates the active dongle, all types. +#define ADL_CONNECTION_TYPE_ACTIVE_DONGLE 12 +/// Indicates the Virtual Connection Type. +#define ADL_CONNECTION_TYPE_VIRTUAL 13 +/// Macros for generating bitmask from index. +#define ADL_CONNECTION_BITMAST_FROM_INDEX(index) (1 << index) +/// @} + +/// \defgroup define_connection_properties +/// These defines are the connection properties which indicates what are the valid properties of given connection type. It is used by \ref ADL_Adapter_SupportedConnections_Get +/// @{ +/// Indicates the property Bitrate is valid. +#define ADL_CONNECTION_PROPERTY_BITRATE 0x1 +/// Indicates the property number of lanes is valid. +#define ADL_CONNECTION_PROPERTY_NUMBER_OF_LANES 0x2 +/// Indicates the property 3D caps is valid. +#define ADL_CONNECTION_PROPERTY_3DCAPS 0x4 +/// Indicates the property output bandwidth is valid. +#define ADL_CONNECTION_PROPERTY_OUTPUT_BANDWIDTH 0x8 +/// Indicates the property colordepth is valid. +#define ADL_CONNECTION_PROPERTY_COLORDEPTH 0x10 +/// @} + +/// \defgroup define_lanecount_constants +/// These defines are the Lane count constants which will be used in DP & etc. +/// @{ +/// Indicates if lane count is unknown +#define ADL_LANECOUNT_UNKNOWN 0 +/// Indicates if lane count is 1 +#define ADL_LANECOUNT_ONE 1 +/// Indicates if lane count is 2 +#define ADL_LANECOUNT_TWO 2 +/// Indicates if lane count is 4 +#define ADL_LANECOUNT_FOUR 4 +/// Indicates if lane count is 8 +#define ADL_LANECOUNT_EIGHT 8 +/// Indicates default value of lane count +#define ADL_LANECOUNT_DEF ADL_LANECOUNT_FOUR +/// @} + +/// \defgroup define_linkrate_constants +/// These defines are the link rate constants which will be used in DP & etc. +/// @{ +/// Indicates if link rate is unknown +#define ADL_LINK_BITRATE_UNKNOWN 0 +/// Indicates if link rate is 1.62Ghz +#define ADL_LINK_BITRATE_1_62_GHZ 0x06 +/// Indicates if link rate is 2.7Ghz +#define ADL_LINK_BITRATE_2_7_GHZ 0x0A +/// Indicates if link rate is 5.4Ghz +#define ADL_LINK_BITRATE_5_4_GHZ 0x14 + +/// Indicates if link rate is 8.1Ghz +#define ADL_LINK_BITRATE_8_1_GHZ 0x1E +/// Indicates default value of link rate +#define ADL_LINK_BITRATE_DEF ADL_LINK_BITRATE_2_7_GHZ +/// @} + +/// \defgroup define_colordepth_constants +/// These defines are the color depth constants which will be used in DP & etc. +/// @{ +#define ADL_CONNPROP_S3D_ALTERNATE_TO_FRAME_PACK 0x00000001 +/// @} + + +/// \defgroup define_colordepth_constants +/// These defines are the color depth constants which will be used in DP & etc. +/// @{ +/// Indicates if color depth is unknown +#define ADL_COLORDEPTH_UNKNOWN 0 +/// Indicates if color depth is 666 +#define ADL_COLORDEPTH_666 1 +/// Indicates if color depth is 888 +#define ADL_COLORDEPTH_888 2 +/// Indicates if color depth is 101010 +#define ADL_COLORDEPTH_101010 3 +/// Indicates if color depth is 121212 +#define ADL_COLORDEPTH_121212 4 +/// Indicates if color depth is 141414 +#define ADL_COLORDEPTH_141414 5 +/// Indicates if color depth is 161616 +#define ADL_COLORDEPTH_161616 6 +/// Indicates default value of color depth +#define ADL_COLOR_DEPTH_DEF ADL_COLORDEPTH_888 +/// @} + + +/// \defgroup define_emulation_status +/// These defines are the status of emulation +/// @{ +/// Indicates if real device is connected. +#define ADL_EMUL_STATUS_REAL_DEVICE_CONNECTED 0x1 +/// Indicates if emulated device is presented. +#define ADL_EMUL_STATUS_EMULATED_DEVICE_PRESENT 0x2 +/// Indicates if emulated device is used. +#define ADL_EMUL_STATUS_EMULATED_DEVICE_USED 0x4 +/// In case when last active real/emulated device used (when persistence is enabled but no emulation enforced then persistence will use last connected/emulated device). +#define ADL_EMUL_STATUS_LAST_ACTIVE_DEVICE_USED 0x8 +/// @} + +/// \defgroup define_emulation_mode +/// These defines are the modes of emulation +/// @{ +/// Indicates if no emulation is used +#define ADL_EMUL_MODE_OFF 0 +/// Indicates if emulation is used when display connected +#define ADL_EMUL_MODE_ON_CONNECTED 1 +/// Indicates if emulation is used when display dis connected +#define ADL_EMUL_MODE_ON_DISCONNECTED 2 +/// Indicates if emulation is used always +#define ADL_EMUL_MODE_ALWAYS 3 +/// @} + +/// \defgroup define_emulation_query +/// These defines are the modes of emulation +/// @{ +/// Indicates Data from real device +#define ADL_QUERY_REAL_DATA 0 +/// Indicates Emulated data +#define ADL_QUERY_EMULATED_DATA 1 +/// Indicates Data currently in use +#define ADL_QUERY_CURRENT_DATA 2 +/// @} + +/// \defgroup define_persistence_state +/// These defines are the states of persistence +/// @{ +/// Indicates persistence is disabled +#define ADL_EDID_PERSISTANCE_DISABLED 0 +/// Indicates persistence is enabled +#define ADL_EDID_PERSISTANCE_ENABLED 1 +/// @} + +/// \defgroup define_connector_types Connector Type +/// defines for ADLConnectorInfo.iType +/// @{ +/// Indicates unknown Connector type +#define ADL_CONNECTOR_TYPE_UNKNOWN 0 +/// Indicates VGA Connector type +#define ADL_CONNECTOR_TYPE_VGA 1 +/// Indicates DVI-D Connector type +#define ADL_CONNECTOR_TYPE_DVI_D 2 +/// Indicates DVI-I Connector type +#define ADL_CONNECTOR_TYPE_DVI_I 3 +/// Indicates Active Dongle-NA Connector type +#define ADL_CONNECTOR_TYPE_ATICVDONGLE_NA 4 +/// Indicates Active Dongle-JP Connector type +#define ADL_CONNECTOR_TYPE_ATICVDONGLE_JP 5 +/// Indicates Active Dongle-NONI2C Connector type +#define ADL_CONNECTOR_TYPE_ATICVDONGLE_NONI2C 6 +/// Indicates Active Dongle-NONI2C-D Connector type +#define ADL_CONNECTOR_TYPE_ATICVDONGLE_NONI2C_D 7 +/// Indicates HDMI-Type A Connector type +#define ADL_CONNECTOR_TYPE_HDMI_TYPE_A 8 +/// Indicates HDMI-Type B Connector type +#define ADL_CONNECTOR_TYPE_HDMI_TYPE_B 9 +/// Indicates Display port Connector type +#define ADL_CONNECTOR_TYPE_DISPLAYPORT 10 +/// Indicates EDP Connector type +#define ADL_CONNECTOR_TYPE_EDP 11 +/// Indicates MiniDP Connector type +#define ADL_CONNECTOR_TYPE_MINI_DISPLAYPORT 12 +/// Indicates Virtual Connector type +#define ADL_CONNECTOR_TYPE_VIRTUAL 13 +/// Indicates USB type C Connector type +#define ADL_CONNECTOR_TYPE_USB_TYPE_C 14 +/// @} + +/// \defgroup define_freesync_usecase +/// These defines are to specify use cases in which FreeSync should be enabled +/// They are a bit mask. To specify FreeSync for more than one use case, the input value +/// should be set to include multiple bits set +/// @{ +/// Indicates FreeSync is enabled for Static Screen case +#define ADL_FREESYNC_USECASE_STATIC 0x1 +/// Indicates FreeSync is enabled for Video use case +#define ADL_FREESYNC_USECASE_VIDEO 0x2 +/// Indicates FreeSync is enabled for Gaming use case +#define ADL_FREESYNC_USECASE_GAMING 0x4 +/// @} + +/// \defgroup define_freesync_caps +/// These defines are used to retrieve FreeSync display capabilities. +/// GPU support flag also indicates whether the display is +/// connected to a GPU that actually supports FreeSync +/// @{ +#define ADL_FREESYNC_CAP_SUPPORTED (1 << 0) +#define ADL_FREESYNC_CAP_GPUSUPPORTED (1 << 1) +#define ADL_FREESYNC_CAP_DISPLAYSUPPORTED (1 << 2) +#define ADL_FREESYNC_CAP_CURRENTMODESUPPORTED (1 << 3) +#define ADL_FREESYNC_CAP_NOCFXORCFXSUPPORTED (1 << 4) +#define ADL_FREESYNC_CAP_NOGENLOCKORGENLOCKSUPPORTED (1 << 5) +#define ADL_FREESYNC_CAP_BORDERLESSWINDOWSUPPORTED (1 << 6) +/// @} + +/// \defgroup define_freesync_labelIndex +/// These defines are used to retrieve which FreeSync label to use +/// @{ +#define ADL_FREESYNC_LABEL_UNSUPPORTED 0 +#define ADL_FREESYNC_LABEL_FREESYNC 1 +#define ADL_FREESYNC_LABEL_ADAPTIVE_SYNC 2 +#define ADL_FREESYNC_LABEL_VRR 3 +#define ADL_FREESYNC_LABEL_FREESYNC_PREMIUM 4 +#define ADL_FREESYNC_LABEL_FREESYNC_PREMIUM_PRO 5 +/// @} + +/// Freesync Power optimization masks +/// @{ +#define ADL_FREESYNC_POWEROPTIMIZATION_SUPPORTED_MASK (1 << 0) +#define ADL_FREESYNC_POWEROPTIMIZATION_ENABLED_MASK (1 << 1) +#define ADL_FREESYNC_POWEROPTIMIZATION_DEFAULT_VALUE_MASK (1 << 2) +/// @} + +/// \defgroup define_MST_CommandLine_execute +/// @{ +/// Indicates the MST command line for branch message if the bit is set. Otherwise, it is display message +#define ADL_MST_COMMANDLINE_PATH_MSG 0x1 +/// Indicates the MST command line to send message in broadcast way it the bit is set +#define ADL_MST_COMMANDLINE_BROADCAST 0x2 + +/// @} + + +/// \defgroup define_Adapter_CloneTypes_Get +/// @{ +/// Indicates there is crossGPU clone with non-AMD dispalys +#define ADL_CROSSGPUDISPLAYCLONE_AMD_WITH_NONAMD 0x1 +/// Indicates there is crossGPU clone +#define ADL_CROSSGPUDISPLAYCLONE 0x2 + +/// @} + +/// \defgroup define_D3DKMT_HANDLE +/// @{ +/// Handle can be used to create Device Handle when using CreateDevice() +typedef unsigned int ADL_D3DKMT_HANDLE; +/// @} + + +// End Bracket for Constants and Definitions. Add new groups ABOVE this line! + +/// @} + + +typedef enum ADL_RAS_ERROR_INJECTION_MODE +{ + ADL_RAS_ERROR_INJECTION_MODE_SINGLE = 1, + ADL_RAS_ERROR_INJECTION_MODE_MULTIPLE = 2 +}ADL_RAS_ERROR_INJECTION_MODE; + + +typedef enum ADL_RAS_BLOCK_ID +{ + ADL_RAS_BLOCK_ID_UMC = 0, + ADL_RAS_BLOCK_ID_SDMA, + ADL_RAS_BLOCK_ID_GFX_HUB, + ADL_RAS_BLOCK_ID_MMHUB, + ADL_RAS_BLOCK_ID_ATHUB, + ADL_RAS_BLOCK_ID_PCIE_BIF, + ADL_RAS_BLOCK_ID_HDP, + ADL_RAS_BLOCK_ID_XGMI_WAFL, + ADL_RAS_BLOCK_ID_DF, + ADL_RAS_BLOCK_ID_SMN, + ADL_RAS_BLOCK_ID_SEM, + ADL_RAS_BLOCK_ID_MP0, + ADL_RAS_BLOCK_ID_MP1, + ADL_RAS_BLOCK_ID_FUSE +}ADL_RAS_BLOCK_ID; + +typedef enum ADL_MEM_SUB_BLOCK_ID +{ + ADL_RAS__UMC_HBM = 0, + ADL_RAS__UMC_SRAM = 1 +}ADL_MEM_SUB_BLOCK_ID; + +typedef enum _ADL_RAS_ERROR_TYPE +{ + ADL_RAS_ERROR__NONE = 0, + ADL_RAS_ERROR__PARITY = 1, + ADL_RAS_ERROR__SINGLE_CORRECTABLE = 2, + ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE = 3, + ADL_RAS_ERROR__MULTI_UNCORRECTABLE = 4, + ADL_RAS_ERROR__PARITY_MULTI_UNCORRECTABLE = 5, + ADL_RAS_ERROR__SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE = 6, + ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE = 7, + ADL_RAS_ERROR__POISON = 8, + ADL_RAS_ERROR__PARITY_POISON = 9, + ADL_RAS_ERROR__SINGLE_CORRECTABLE_POISON = 10, + ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_POISON = 11, + ADL_RAS_ERROR__MULTI_UNCORRECTABLE_POISON = 12, + ADL_RAS_ERROR__PARITY_MULTI_UNCORRECTABLE_POISON = 13, + ADL_RAS_ERROR__SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE_POISON = 14, + ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE_POISON = 15 +}ADL_RAS_ERROR_TYPE; + +typedef enum ADL_RAS_INJECTION_METHOD +{ + ADL_RAS_ERROR__UMC_METH_COHERENT = 0, + ADL_RAS_ERROR__UMC_METH_SINGLE_SHOT = 1, + ADL_RAS_ERROR__UMC_METH_PERSISTENT = 2, + ADL_RAS_ERROR__UMC_METH_PERSISTENT_DISABLE = 3 +}ADL_RAS_INJECTION_METHOD; + +// Driver event types +typedef enum ADL_DRIVER_EVENT_TYPE +{ + ADL_EVENT_ID_AUTO_FEATURE_COMPLETED = 30, + ADL_EVENT_ID_FEATURE_AVAILABILITY = 31, + +} ADL_DRIVER_EVENT_TYPE; + + +//UIFeature Ids +typedef enum ADL_UIFEATURES_GROUP +{ + ADL_UIFEATURES_GROUP_DVR = 0, + ADL_UIFEATURES_GROUP_TURBOSYNC = 1, + ADL_UIFEATURES_GROUP_FRAMEMETRICSMONITOR = 2, + ADL_UIFEATURES_GROUP_FRTC = 3, + ADL_UIFEATURES_GROUP_XVISION = 4, + ADL_UIFEATURES_GROUP_BLOCKCHAIN = 5, + ADL_UIFEATURES_GROUP_GAMEINTELLIGENCE = 6, + ADL_UIFEATURES_GROUP_CHILL = 7, + ADL_UIFEATURES_GROUP_DELAG = 8, + ADL_UIFEATURES_GROUP_BOOST = 9, + ADL_UIFEATURES_GROUP_USU = 10, + ADL_UIFEATURES_GROUP_XGMI = 11, + ADL_UIFEATURES_GROUP_PROVSR = 12, + ADL_UIFEATURES_GROUP_SMA = 13, + ADL_UIFEATURES_GROUP_CAMERA = 14, + ADL_UIFEATURES_GROUP_FRTCPRO = 15 +} ADL_UIFEATURES_GROUP; + + + +/// Maximum brightness supported by Radeon LED interface +#define ADL_RADEON_LED_MAX_BRIGHTNESS 2 + +/// Maximum speed supported by Radeon LED interface +#define ADL_RADEON_LED_MAX_SPEED 4 + +/// Maximum RGB supported by Radeon LED interface +#define ADL_RADEON_LED_MAX_RGB 255 + +/// Maximum MORSE code supported string +#define ADL_RADEON_LED_MAX_MORSE_CODE 260 + +/// Maximum LED ROW ON GRID +#define ADL_RADEON_LED_MAX_LED_ROW_ON_GRID 7 + +/// Maximum LED COLUMN ON GRID +#define ADL_RADEON_LED_MAX_LED_COLUMN_ON_GRID 24 + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief +/// +/// +/// +/// +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef enum ADL_RADEON_USB_LED_BAR_CONTROLS +{ + RadeonLEDBarControl_OFF = 0, + RadeonLEDBarControl_Static, + RadeonLEDBarControl_Rainbow, + RadeonLEDBarControl_Swirl, + RadeonLEDBarControl_Chase, + RadeonLEDBarControl_Bounce, + RadeonLEDBarControl_MorseCode, + RadeonLEDBarControl_ColorCycle, + RadeonLEDBarControl_Breathing, + RadeonLEDBarControl_CustomPattern, + RadeonLEDBarControl_MAX +}ADL_RADEON_USB_LED_BAR_CONTROLS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief +/// +/// +/// +/// +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef unsigned int RadeonLEDBARSupportedControl; + + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief +/// +/// +/// +/// +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef enum ADL_RADEON_USB_LED_CONTROL_CONFIGS +{ + RadeonLEDPattern_Speed = 0, + RadeonLEDPattern_Brightness, + RadeonLEDPattern_Direction, + RadeonLEDPattern_Color, + RadeonLEDPattern_MAX +}ADL_RADEON_USB_LED_CONTROL_CONFIGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief +/// +/// +/// +/// +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef unsigned int RadeonLEDBARSupportedConfig; + +//User blob feature settings +typedef enum ADL_USER_SETTINGS +{ + ADL_USER_SETTINGS_ENHANCEDSYNC = 1 << 0, //notify Enhanced Sync settings change + ADL_USER_SETTINGS_CHILL_PROFILE = 1 << 1, //notify Chill settings change + ADL_USER_SETTINGS_DELAG_PROFILE = 1 << 2, //notify Delag settings change + ADL_USER_SETTINGS_BOOST_PROFILE = 1 << 3, //notify Boost settings change + ADL_USER_SETTINGS_USU_PROFILE = 1 << 4, //notify USU settings change + ADL_USER_SETTINGS_CVDC_PROFILE = 1 << 5, //notify Color Vision Deficiency Corretion settings change + ADL_USER_SETTINGS_SCE_PROFILE = 1 << 6, + ADL_USER_SETTINGS_PROVSR = 1 << 7 + } ADL_USER_SETTINGS; + +#define ADL_REG_DEVICE_FUNCTION_1 0x00000001 +#endif /* ADL_DEFINES_H_ */ + + diff --git a/atiadlxx-sys/include/adl_sdk.h b/atiadlxx-sys/include/adl_sdk.h new file mode 100644 index 0000000..0923a6a --- /dev/null +++ b/atiadlxx-sys/include/adl_sdk.h @@ -0,0 +1,46 @@ +// +// Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// MIT LICENSE: +// 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. + +/// \file adl_sdk.h +/// \brief Contains the definition of the Memory Allocation Callback.\n Included in ADL SDK +/// +/// \n\n +/// This file contains the definition of the Memory Allocation Callback.\n +/// It also includes definitions of the respective structures and constants.\n +/// This is the only header file to be included in a C/C++ project using ADL + +#ifndef ADL_SDK_H_ +#define ADL_SDK_H_ + +#include "adl_structures.h" + +#if defined (LINUX) +#define __stdcall +#endif /* (LINUX) */ + +/// Memory Allocation Call back +typedef void* ( __stdcall *ADL_MAIN_MALLOC_CALLBACK )( int ); + +#define ADL_SDK_MAJOR_VERSION 17 +#define ADL_SDK_MINOR_VERSION 1 + +#endif /* ADL_SDK_H_ */ diff --git a/atiadlxx-sys/include/adl_structures.h b/atiadlxx-sys/include/adl_structures.h new file mode 100644 index 0000000..601ad74 --- /dev/null +++ b/atiadlxx-sys/include/adl_structures.h @@ -0,0 +1,4289 @@ +// +// Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// MIT LICENSE: +// 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. + +/// \file adl_structures.h +///\brief This file contains the structure declarations that are used by the public ADL interfaces for \ALL platforms.\n Included in ADL SDK +/// +/// All data structures used in AMD Display Library (ADL) public interfaces should be defined in this header file. +/// + +#ifndef ADL_STRUCTURES_H_ +#define ADL_STRUCTURES_H_ + +#include "adl_defines.h" +#include +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the graphics adapter. +/// +/// This structure is used to store various information about the graphics adapter. This +/// information can be returned to the user. Alternatively, it can be used to access various driver calls to set +/// or fetch various settings upon the user's request. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct AdapterInfo +{ +/// \ALL_STRUCT_MEM + +/// Size of the structure. + int iSize; +/// The ADL index handle. One GPU may be associated with one or two index handles + int iAdapterIndex; +/// The unique device ID associated with this adapter. + char strUDID[ADL_MAX_PATH]; +/// The BUS number associated with this adapter. + int iBusNumber; +/// The driver number associated with this adapter. + int iDeviceNumber; +/// The function number. + int iFunctionNumber; +/// The vendor ID associated with this adapter. + int iVendorID; +/// Adapter name. + char strAdapterName[ADL_MAX_PATH]; +/// Display name. For example, "\\\\Display0" for Windows or ":0:0" for Linux. + char strDisplayName[ADL_MAX_PATH]; +/// Present or not; 1 if present and 0 if not present.It the logical adapter is present, the display name such as \\\\.\\Display1 can be found from OS + int iPresent; + +#if defined (_WIN32) || defined (_WIN64) +/// \WIN_STRUCT_MEM + +/// Exist or not; 1 is exist and 0 is not present. + int iExist; +/// Driver registry path. + char strDriverPath[ADL_MAX_PATH]; +/// Driver registry path Ext for. + char strDriverPathExt[ADL_MAX_PATH]; +/// PNP string from Windows. + char strPNPString[ADL_MAX_PATH]; +/// It is generated from EnumDisplayDevices. + int iOSDisplayIndex; + +#endif /* (_WIN32) || (_WIN64) */ + +#if defined (LINUX) +/// \LNX_STRUCT_MEM + +/// Internal X screen number from GPUMapInfo (DEPRICATED use XScreenInfo) + int iXScreenNum; +/// Internal driver index from GPUMapInfo + int iDrvIndex; +/// \deprecated Internal x config file screen identifier name. Use XScreenInfo instead. + char strXScreenConfigName[ADL_MAX_PATH]; + +#endif /* (LINUX) */ +} AdapterInfo, *LPAdapterInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the Linux X screen information. +/// +/// This structure is used to store the current screen number and xorg.conf ID name assoicated with an adapter index. +/// This structure is updated during ADL_Main_Control_Refresh or ADL_ScreenInfo_Update. +/// Note: This structure should be used in place of iXScreenNum and strXScreenConfigName in AdapterInfo as they will be +/// deprecated. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +#if defined (LINUX) +typedef struct XScreenInfo +{ +/// Internal X screen number from GPUMapInfo. + int iXScreenNum; +/// Internal x config file screen identifier name. + char strXScreenConfigName[ADL_MAX_PATH]; +} XScreenInfo, *LPXScreenInfo; +#endif /* (LINUX) */ + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an controller mode +/// +/// This structure is used to store information of an controller mode +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterCaps +{ + /// AdapterID for this adapter + int iAdapterID; + /// Number of controllers for this adapter + int iNumControllers; + /// Number of displays for this adapter + int iNumDisplays; + /// Number of overlays for this adapter + int iNumOverlays; + /// Number of GLSyncConnectors + int iNumOfGLSyncConnectors; + /// The bit mask identifies the adapter caps + int iCapsMask; + /// The bit identifies the adapter caps \ref define_adapter_caps + int iCapsValue; +}ADLAdapterCaps; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing additional information about the ASIC memory +/// +/// This structure is used to store additional information about the ASIC memory. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryInfo2 +{ + /// Memory size in bytes. + long long iMemorySize; + /// Memory type in string. + char strMemoryType[ADL_MAX_PATH]; + /// Highest default performance level Memory bandwidth in Mbytes/s + long long iMemoryBandwidth; + /// HyperMemory size in bytes. + long long iHyperMemorySize; + + /// Invisible Memory size in bytes. + long long iInvisibleMemorySize; + /// Visible Memory size in bytes. + long long iVisibleMemorySize; +} ADLMemoryInfo2, *LPADLMemoryInfo2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing additional information about the ASIC memory +/// +/// This structure is used to store additional information about the ASIC memory. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryInfo3 +{ + /// Memory size in bytes. + long long iMemorySize; + /// Memory type in string. + char strMemoryType[ADL_MAX_PATH]; + /// Highest default performance level Memory bandwidth in Mbytes/s + long long iMemoryBandwidth; + /// HyperMemory size in bytes. + long long iHyperMemorySize; + + /// Invisible Memory size in bytes. + long long iInvisibleMemorySize; + /// Visible Memory size in bytes. + long long iVisibleMemorySize; + /// Vram vendor ID + long long iVramVendorRevId; +} ADLMemoryInfo3, *LPADLMemoryInfo3; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing additional information about the ASIC memory +/// +/// This structure is used to store additional information about the ASIC memory. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryInfoX4 +{ + /// Memory size in bytes. + long long iMemorySize; + /// Memory type in string. + char strMemoryType[ADL_MAX_PATH]; + /// Highest default performance level Memory bandwidth in Mbytes/s + long long iMemoryBandwidth; + /// HyperMemory size in bytes. + long long iHyperMemorySize; + + /// Invisible Memory size in bytes. + long long iInvisibleMemorySize; + /// Visible Memory size in bytes. + long long iVisibleMemorySize; + /// Vram vendor ID + long long iVramVendorRevId; + /// Memory Bandiwidth that is calculated and finalized on the driver side, grab and go. + long long iMemoryBandwidthX2; + /// Memory Bit Rate that is calculated and finalized on the driver side, grab and go. + long long iMemoryBitRateX2; + +} ADLMemoryInfoX4, *LPADLMemoryInfoX4; + +/////////////////////////////////////////////////////////////////////////// +// ADLvRamVendor Enumeration +/////////////////////////////////////////////////////////////////////////// +enum ADLvRamVendors +{ + ADLvRamVendor_Unsupported = 0x0, + ADLvRamVendor_SAMSUNG, + ADLvRamVendor_INFINEON, + ADLvRamVendor_ELPIDA, + ADLvRamVendor_ETRON, + ADLvRamVendor_NANYA, + ADLvRamVendor_HYNIX, + ADLvRamVendor_MOSEL, + ADLvRamVendor_WINBOND, + ADLvRamVendor_ESMT, + ADLvRamVendor_MICRON = 0xF, + ADLvRamVendor_Undefined +}; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about components of ASIC GCN architecture +/// +/// Elements of GCN info are compute units, number of Tex (Texture filtering units) , number of ROPs (render back-ends). +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLGcnInfo +{ + int CuCount; //Number of compute units on the ASIC. + int TexCount; //Number of texture mapping units. + int RopCount; //Number of Render backend Units. + int ASICFamilyId; //Such SI, VI. See /inc/asic_reg/atiid.h for family ids + int ASICRevisionId; //Such as Ellesmere, Fiji. For example - VI family revision ids are stored in /inc/asic_reg/vi_id.h +}ADLGcnInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related virtual segment config information. +/// +/// This structure is used to store information related virtual segment config +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLVirtualSegmentSettingsOutput +{ + int virtualSegmentSupported; // 1 - subsequent values are valid + int virtualSegmentDefault; //virtual segment default, 1: enable, 0: disable + int virtualSegmentCurrent; //virtual segment current, 1: enable, 0: disable + int iMinSizeInMB; //minimum value + int iMaxSizeInMB; //maximum value + int icurrentSizeInMB; //last configured otherwise same as factory default + int idefaultSizeInMB; //factory default + int iMask; //fileds for extension in the future + int iValue; //fileds for extension in the future +} ADLVirtualSegmentSettingsOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the Chipset. +/// +/// This structure is used to store various information about the Chipset. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLChipSetInfo +{ + int iBusType; ///< Bus type. + int iBusSpeedType; ///Maximum Bus Speed of the current platform + int iMaxPCIELaneWidth; ///< Number of PCIE lanes. + int iCurrentPCIELaneWidth; ///< Current PCIE Lane Width + int iSupportedAGPSpeeds; ///< Bit mask or AGP transfer speed. + int iCurrentAGPSpeed; ///< Current AGP speed +} ADLChipSetInfo, *LPADLChipSetInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the ASIC memory. +/// +/// This structure is used to store various information about the ASIC memory. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryInfo +{ +/// Memory size in bytes. + long long iMemorySize; +/// Memory type in string. + char strMemoryType[ADL_MAX_PATH]; +/// Memory bandwidth in Mbytes/s. + long long iMemoryBandwidth; +} ADLMemoryInfo, *LPADLMemoryInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about memory required by type +/// +/// This structure is returned by ADL_Adapter_ConfigMemory_Get, which given a desktop and display configuration +/// will return the Memory used. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryRequired +{ + long long iMemoryReq; /// Memory in bytes required + int iType; /// Type of Memory \ref define_adl_validmemoryrequiredfields + int iDisplayFeatureValue; /// Display features \ref define_adl_visiblememoryfeatures that are using this type of memory +} ADLMemoryRequired, *LPADLMemoryRequired; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the features associated with a display +/// +/// This structure is a parameter to ADL_Adapter_ConfigMemory_Get, which given a desktop and display configuration +/// will return the Memory used. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMemoryDisplayFeatures +{ + int iDisplayIndex; /// ADL Display index + int iDisplayFeatureValue; /// features that the display is using \ref define_adl_visiblememoryfeatures +} ADLMemoryDisplayFeatures, *LPADLMemoryDisplayFeatures; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing DDC information. +/// +/// This structure is used to store various DDC information that can be returned to the user. +/// Note that all fields of type int are actually defined as unsigned int types within the driver. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDDCInfo +{ +/// Size of the structure + int ulSize; +/// Indicates whether the attached display supports DDC. If this field is zero on return, no other DDC information fields will be used. + int ulSupportsDDC; +/// Returns the manufacturer ID of the display device. Should be zeroed if this information is not available. + int ulManufacturerID; +/// Returns the product ID of the display device. Should be zeroed if this information is not available. + int ulProductID; +/// Returns the name of the display device. Should be zeroed if this information is not available. + char cDisplayName[ADL_MAX_DISPLAY_NAME]; +/// Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available. + int ulMaxHResolution; +/// Returns the maximum Vertical supported resolution. Should be zeroed if this information is not available. + int ulMaxVResolution; +/// Returns the maximum supported refresh rate. Should be zeroed if this information is not available. + int ulMaxRefresh; +/// Returns the display device preferred timing mode's horizontal resolution. + int ulPTMCx; +/// Returns the display device preferred timing mode's vertical resolution. + int ulPTMCy; +/// Returns the display device preferred timing mode's refresh rate. + int ulPTMRefreshRate; +/// Return EDID flags. + int ulDDCInfoFlag; +} ADLDDCInfo, *LPADLDDCInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing DDC information. +/// +/// This structure is used to store various DDC information that can be returned to the user. +/// Note that all fields of type int are actually defined as unsigned int types within the driver. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDDCInfo2 +{ +/// Size of the structure + int ulSize; +/// Indicates whether the attached display supports DDC. If this field is zero on return, no other DDC +/// information fields will be used. + int ulSupportsDDC; +/// Returns the manufacturer ID of the display device. Should be zeroed if this information is not available. + int ulManufacturerID; +/// Returns the product ID of the display device. Should be zeroed if this information is not available. + int ulProductID; +/// Returns the name of the display device. Should be zeroed if this information is not available. + char cDisplayName[ADL_MAX_DISPLAY_NAME]; +/// Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available. + int ulMaxHResolution; +/// Returns the maximum Vertical supported resolution. Should be zeroed if this information is not available. + int ulMaxVResolution; +/// Returns the maximum supported refresh rate. Should be zeroed if this information is not available. + int ulMaxRefresh; +/// Returns the display device preferred timing mode's horizontal resolution. + int ulPTMCx; +/// Returns the display device preferred timing mode's vertical resolution. + int ulPTMCy; +/// Returns the display device preferred timing mode's refresh rate. + int ulPTMRefreshRate; +/// Return EDID flags. + int ulDDCInfoFlag; +/// Returns 1 if the display supported packed pixel, 0 otherwise + int bPackedPixelSupported; +/// Returns the Pixel formats the display supports \ref define_ddcinfo_pixelformats + int iPanelPixelFormat; +/// Return EDID serial ID. + int ulSerialID; +/// Return minimum monitor luminance data + int ulMinLuminanceData; +/// Return average monitor luminance data + int ulAvgLuminanceData; +/// Return maximum monitor luminance data + int ulMaxLuminanceData; + +/// Bit vector of supported transfer functions \ref define_source_content_TF + int iSupportedTransferFunction; + +/// Bit vector of supported color spaces \ref define_source_content_CS + int iSupportedColorSpace; + +/// Display Red Chromaticity X coordinate multiplied by 10000 + int iNativeDisplayChromaticityRedX; +/// Display Red Chromaticity Y coordinate multiplied by 10000 + int iNativeDisplayChromaticityRedY; +/// Display Green Chromaticity X coordinate multiplied by 10000 + int iNativeDisplayChromaticityGreenX; +/// Display Green Chromaticity Y coordinate multiplied by 10000 + int iNativeDisplayChromaticityGreenY; +/// Display Blue Chromaticity X coordinate multiplied by 10000 + int iNativeDisplayChromaticityBlueX; +/// Display Blue Chromaticity Y coordinate multiplied by 10000 + int iNativeDisplayChromaticityBlueY; +/// Display White Point X coordinate multiplied by 10000 + int iNativeDisplayChromaticityWhitePointX; +/// Display White Point Y coordinate multiplied by 10000 + int iNativeDisplayChromaticityWhitePointY; +/// Display diffuse screen reflectance 0-1 (100%) in units of 0.01 + int iDiffuseScreenReflectance; +/// Display specular screen reflectance 0-1 (100%) in units of 0.01 + int iSpecularScreenReflectance; +/// Bit vector of supported color spaces \ref define_HDR_support + int iSupportedHDR; +/// Bit vector for freesync flags + int iFreesyncFlags; + +/// Return minimum monitor luminance without dimming data + int ulMinLuminanceNoDimmingData; + + int ulMaxBacklightMaxLuminanceData; + int ulMinBacklightMaxLuminanceData; + int ulMaxBacklightMinLuminanceData; + int ulMinBacklightMinLuminanceData; + + // Reserved for future use + int iReserved[4]; +} ADLDDCInfo2, *LPADLDDCInfo2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information controller Gamma settings. +/// +/// This structure is used to store the red, green and blue color channel information for the. +/// controller gamma setting. This information is returned by ADL, and it can also be used to +/// set the controller gamma setting. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGamma +{ +/// Red color channel gamma value. + float fRed; +/// Green color channel gamma value. + float fGreen; +/// Blue color channel gamma value. + float fBlue; +} ADLGamma, *LPADLGamma; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about component video custom modes. +/// +/// This structure is used to store the component video custom mode. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLCustomMode +{ +/// Custom mode flags. They are returned by the ADL driver. + int iFlags; +/// Custom mode width. + int iModeWidth; +/// Custom mode height. + int iModeHeight; +/// Custom mode base width. + int iBaseModeWidth; +/// Custom mode base height. + int iBaseModeHeight; +/// Custom mode refresh rate. + int iRefreshRate; +} ADLCustomMode, *LPADLCustomMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing Clock information for OD5 calls. +/// +/// This structure is used to retrieve clock information for OD5 calls. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGetClocksOUT +{ + long ulHighCoreClock; + long ulHighMemoryClock; + long ulHighVddc; + long ulCoreMin; + long ulCoreMax; + long ulMemoryMin; + long ulMemoryMax; + long ulActivityPercent; + long ulCurrentCoreClock; + long ulCurrentMemoryClock; + long ulReserved; +} ADLGetClocksOUT; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing HDTV information for display calls. +/// +/// This structure is used to retrieve HDTV information information for display calls. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayConfig +{ +/// Size of the structure + long ulSize; +/// HDTV connector type. + long ulConnectorType; +/// HDTV capabilities. + long ulDeviceData; +/// Overridden HDTV capabilities. + long ulOverridedDeviceData; +/// Reserved field + long ulReserved; +} ADLDisplayConfig; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display device. +/// +/// This structure is used to store display device information +/// such as display index, type, name, connection status, mapped adapter and controller indexes, +/// whether or not multiple VPUs are supported, local display connections or not (through Lasso), etc. +/// This information can be returned to the user. Alternatively, it can be used to access various driver calls to set +/// or fetch various display device related settings upon the user's request. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayID +{ +/// The logical display index belonging to this adapter. + int iDisplayLogicalIndex; + +///\brief The physical display index. +/// For example, display index 2 from adapter 2 can be used by current adapter 1.\n +/// So current adapter may enumerate this adapter as logical display 7 but the physical display +/// index is still 2. + int iDisplayPhysicalIndex; + +/// The persistent logical adapter index for the display. + int iDisplayLogicalAdapterIndex; + +///\brief The persistent physical adapter index for the display. +/// It can be the current adapter or a non-local adapter. \n +/// If this adapter index is different than the current adapter, +/// the Display Non Local flag is set inside DisplayInfoValue. + int iDisplayPhysicalAdapterIndex; +} ADLDisplayID, *LPADLDisplayID; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display device. +/// +/// This structure is used to store various information about the display device. This +/// information can be returned to the user, or used to access various driver calls to set +/// or fetch various display-device-related settings upon the user's request +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayInfo +{ +/// The DisplayID structure + ADLDisplayID displayID; + +///\deprecated The controller index to which the display is mapped.\n Will not be used in the future\n + int iDisplayControllerIndex; + +/// The display's EDID name. + char strDisplayName[ADL_MAX_PATH]; + +/// The display's manufacturer name. + char strDisplayManufacturerName[ADL_MAX_PATH]; + +/// The Display type. For example: CRT, TV, CV, DFP. + int iDisplayType; + +/// The display output type. For example: HDMI, SVIDEO, COMPONMNET VIDEO. + int iDisplayOutputType; + +/// The connector type for the device. + int iDisplayConnector; + +///\brief The bit mask identifies the number of bits ADLDisplayInfo is currently using. \n +/// It will be the sum all the bit definitions in ADL_DISPLAY_DISPLAYINFO_xxx. + int iDisplayInfoMask; + +/// The bit mask identifies the display status. \ref define_displayinfomask + int iDisplayInfoValue; +} ADLDisplayInfo, *LPADLDisplayInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display port MST device. +/// +/// This structure is used to store various MST information about the display port device. This +/// information can be returned to the user, or used to access various driver calls to +/// fetch various display-device-related settings upon the user's request +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayDPMSTInfo +{ + /// The ADLDisplayID structure + ADLDisplayID displayID; + + /// total bandwidth available on the DP connector + int iTotalAvailableBandwidthInMpbs; + /// bandwidth allocated to this display + int iAllocatedBandwidthInMbps; + + // info from DAL DpMstSinkInfo + /// string identifier for the display + char strGlobalUniqueIdentifier[ADL_MAX_PATH]; + + /// The link count of relative address, rad[0] upto rad[linkCount] are valid + int radLinkCount; + /// The physical connector ID, used to identify the physical DP port + int iPhysicalConnectorID; + + /// Relative address, address scheme starts from source side + char rad[ADL_MAX_RAD_LINK_COUNT]; +} ADLDisplayDPMSTInfo, *LPADLDisplayDPMSTInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the display mode definition used per controller. +/// +/// This structure is used to store the display mode definition used per controller. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayMode +{ +/// Vertical resolution (in pixels). + int iPelsHeight; +/// Horizontal resolution (in pixels). + int iPelsWidth; +/// Color depth. + int iBitsPerPel; +/// Refresh rate. + int iDisplayFrequency; +} ADLDisplayMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing detailed timing parameters. +/// +/// This structure is used to store the detailed timing parameters. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDetailedTiming +{ +/// Size of the structure. + int iSize; +/// Timing flags. \ref define_detailed_timing_flags + short sTimingFlags; +/// Total width (columns). + short sHTotal; +/// Displayed width. + short sHDisplay; +/// Horizontal sync signal offset. + short sHSyncStart; +/// Horizontal sync signal width. + short sHSyncWidth; +/// Total height (rows). + short sVTotal; +/// Displayed height. + short sVDisplay; +/// Vertical sync signal offset. + short sVSyncStart; +/// Vertical sync signal width. + short sVSyncWidth; +/// Pixel clock value. + short sPixelClock; +/// Overscan right. + short sHOverscanRight; +/// Overscan left. + short sHOverscanLeft; +/// Overscan bottom. + short sVOverscanBottom; +/// Overscan top. + short sVOverscanTop; + short sOverscan8B; + short sOverscanGR; +} ADLDetailedTiming; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing display mode information. +/// +/// This structure is used to store the display mode information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayModeInfo +{ +/// Timing standard of the current mode. \ref define_modetiming_standard + int iTimingStandard; +/// Applicable timing standards for the current mode. + int iPossibleStandard; +/// Refresh rate factor. + int iRefreshRate; +/// Num of pixels in a row. + int iPelsWidth; +/// Num of pixels in a column. + int iPelsHeight; +/// Detailed timing parameters. + ADLDetailedTiming sDetailedTiming; +} ADLDisplayModeInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about display property. +/// +/// This structure is used to store the display property for the current adapter. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayProperty +{ +/// Must be set to sizeof the structure + int iSize; +/// Must be set to \ref ADL_DL_DISPLAYPROPERTY_TYPE_EXPANSIONMODE or \ref ADL_DL_DISPLAYPROPERTY_TYPE_USEUNDERSCANSCALING + int iPropertyType; +/// Get or Set \ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_CENTER or \ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_FULLSCREEN or \ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_ASPECTRATIO or \ref ADL_DL_DISPLAYPROPERTY_TYPE_ITCFLAGENABLE + int iExpansionMode; +/// Display Property supported? 1: Supported, 0: Not supported + int iSupport; +/// Display Property current value + int iCurrent; +/// Display Property Default value + int iDefault; +} ADLDisplayProperty; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Clock. +/// +/// This structure is used to store the clock information for the current adapter +/// such as core clock and memory clock info. +///\nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLClockInfo +{ +/// Core clock in 10 KHz. + int iCoreClock; +/// Memory clock in 10 KHz. + int iMemoryClock; +} ADLClockInfo, *LPADLClockInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about I2C. +/// +/// This structure is used to store the I2C information for the current adapter. +/// This structure is used by the ADL_Display_WriteAndReadI2C() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLI2C +{ +/// Size of the structure + int iSize; +/// Numerical value representing hardware I2C. + int iLine; +/// The 7-bit I2C slave device address, shifted one bit to the left. + int iAddress; +/// The offset of the data from the address. + int iOffset; +/// Read from or write to slave device. \ref ADL_DL_I2C_ACTIONREAD or \ref ADL_DL_I2C_ACTIONWRITE or \ref ADL_DL_I2C_ACTIONREAD_REPEATEDSTART + int iAction; +/// I2C clock speed in KHz. + int iSpeed; +/// A numerical value representing the number of bytes to be sent or received on the I2C bus. + int iDataSize; +/// Address of the characters which are to be sent or received on the I2C bus. + char *pcData; +} ADLI2C; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about EDID data. +/// +/// This structure is used to store the information about EDID data for the adapter. +/// This structure is used by the ADL_Display_EdidData_Get() and ADL_Display_EdidData_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayEDIDData +{ +/// Size of the structure + int iSize; +/// Set to 0 + int iFlag; + /// Size of cEDIDData. Set by ADL_Display_EdidData_Get() upon return + int iEDIDSize; +/// 0, 1 or 2. If set to 3 or above an error ADL_ERR_INVALID_PARAM is generated + int iBlockIndex; +/// EDID data + char cEDIDData[ADL_MAX_EDIDDATA_SIZE]; +/// Reserved + int iReserved[4]; +}ADLDisplayEDIDData; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about input of controller overlay adjustment. +/// +/// This structure is used to store the information about input of controller overlay adjustment for the adapter. +/// This structure is used by the ADL_Display_ControllerOverlayAdjustmentCaps_Get, ADL_Display_ControllerOverlayAdjustmentData_Get, and +/// ADL_Display_ControllerOverlayAdjustmentData_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLControllerOverlayInput +{ +/// Should be set to the sizeof the structure + int iSize; +///\ref ADL_DL_CONTROLLER_OVERLAY_ALPHA or \ref ADL_DL_CONTROLLER_OVERLAY_ALPHAPERPIX + int iOverlayAdjust; +/// Data. + int iValue; +/// Should be 0. + int iReserved; +} ADLControllerOverlayInput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about overlay adjustment. +/// +/// This structure is used to store the information about overlay adjustment for the adapter. +/// This structure is used by the ADLControllerOverlayInfo() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdjustmentinfo +{ +/// Default value + int iDefault; +/// Minimum value + int iMin; +/// Maximum Value + int iMax; +/// Step value + int iStep; +} ADLAdjustmentinfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about controller overlay information. +/// +/// This structure is used to store information about controller overlay info for the adapter. +/// This structure is used by the ADL_Display_ControllerOverlayAdjustmentCaps_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLControllerOverlayInfo +{ +/// Should be set to the sizeof the structure + int iSize; +/// Data. + ADLAdjustmentinfo sOverlayInfo; +/// Should be 0. + int iReserved[3]; +} ADLControllerOverlayInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync module information. +/// +/// This structure is used to retrieve GL-Sync module information for +/// Workstation Framelock/Genlock. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGLSyncModuleID +{ +/// Unique GL-Sync module ID. + int iModuleID; +/// GL-Sync GPU port index (to be passed into ADLGLSyncGenlockConfig.lSignalSource and ADLGlSyncPortControl.lSignalSource). + int iGlSyncGPUPort; +/// GL-Sync module firmware version of Boot Sector. + int iFWBootSectorVersion; +/// GL-Sync module firmware version of User Sector. + int iFWUserSectorVersion; +} ADLGLSyncModuleID , *LPADLGLSyncModuleID; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync ports capabilities. +/// +/// This structure is used to retrieve hardware capabilities for the ports of the GL-Sync module +/// for Workstation Framelock/Genlock (such as port type and number of associated LEDs). +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGLSyncPortCaps +{ +/// Port type. Bitfield of ADL_GLSYNC_PORTTYPE_* \ref define_glsync + int iPortType; +/// Number of LEDs associated for this port. + int iNumOfLEDs; +}ADLGLSyncPortCaps, *LPADLGLSyncPortCaps; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync Genlock settings. +/// +/// This structure is used to get and set genlock settings for the GPU ports of the GL-Sync module +/// for Workstation Framelock/Genlock.\n +/// \see define_glsync +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGLSyncGenlockConfig +{ +/// Specifies what fields in this structure are valid \ref define_glsync + int iValidMask; +/// Delay (ms) generating a sync signal. + int iSyncDelay; +/// Vector of framelock control bits. Bitfield of ADL_GLSYNC_FRAMELOCKCNTL_* \ref define_glsync + int iFramelockCntlVector; +/// Source of the sync signal. Either GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_* \ref define_glsync + int iSignalSource; +/// Use sampled sync signal. A value of 0 specifies no sampling. + int iSampleRate; +/// For interlaced sync signals, the value can be ADL_GLSYNC_SYNCFIELD_1 or *_BOTH \ref define_glsync + int iSyncField; +/// The signal edge that should trigger synchronization. ADL_GLSYNC_TRIGGEREDGE_* \ref define_glsync + int iTriggerEdge; +/// Scan rate multiplier applied to the sync signal. ADL_GLSYNC_SCANRATECOEFF_* \ref define_glsync + int iScanRateCoeff; +}ADLGLSyncGenlockConfig, *LPADLGLSyncGenlockConfig; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync port information. +/// +/// This structure is used to get status of the GL-Sync ports (BNC or RJ45s) +/// for Workstation Framelock/Genlock. +/// \see define_glsync +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGlSyncPortInfo +{ +/// Type of GL-Sync port (ADL_GLSYNC_PORT_*). + int iPortType; +/// The number of LEDs for this port. It's also filled within ADLGLSyncPortCaps. + int iNumOfLEDs; +/// Port state ADL_GLSYNC_PORTSTATE_* \ref define_glsync + int iPortState; +/// Scanned frequency for this port (vertical refresh rate in milliHz; 60000 means 60 Hz). + int iFrequency; +/// Used for ADL_GLSYNC_PORT_BNC. It is ADL_GLSYNC_SIGNALTYPE_* \ref define_glsync + int iSignalType; +/// Used for ADL_GLSYNC_PORT_RJ45PORT*. It is GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_*. \ref define_glsync + int iSignalSource; +} ADLGlSyncPortInfo, *LPADLGlSyncPortInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync port control settings. +/// +/// This structure is used to configure the GL-Sync ports (RJ45s only) +/// for Workstation Framelock/Genlock. +/// \see define_glsync +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGlSyncPortControl +{ +/// Port to control ADL_GLSYNC_PORT_RJ45PORT1 or ADL_GLSYNC_PORT_RJ45PORT2 \ref define_glsync + int iPortType; +/// Port control data ADL_GLSYNC_PORTCNTL_* \ref define_glsync + int iControlVector; +/// Source of the sync signal. Either GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_* \ref define_glsync + int iSignalSource; +} ADLGlSyncPortControl; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync mode of a display. +/// +/// This structure is used to get and set GL-Sync mode settings for a display connected to +/// an adapter attached to a GL-Sync module for Workstation Framelock/Genlock. +/// \see define_glsync +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGlSyncMode +{ +/// Mode control vector. Bitfield of ADL_GLSYNC_MODECNTL_* \ref define_glsync + int iControlVector; +/// Mode status vector. Bitfield of ADL_GLSYNC_MODECNTL_STATUS_* \ref define_glsync + int iStatusVector; +/// Index of GL-Sync connector used to genlock the display/controller. + int iGLSyncConnectorIndex; +} ADLGlSyncMode, *LPADLGlSyncMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing GL-Sync mode of a display. +/// +/// This structure is used to get and set GL-Sync mode settings for a display connected to +/// an adapter attached to a GL-Sync module for Workstation Framelock/Genlock. +/// \see define_glsync +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGlSyncMode2 +{ +/// Mode control vector. Bitfield of ADL_GLSYNC_MODECNTL_* \ref define_glsync + int iControlVector; +/// Mode status vector. Bitfield of ADL_GLSYNC_MODECNTL_STATUS_* \ref define_glsync + int iStatusVector; +/// Index of GL-Sync connector used to genlock the display/controller. + int iGLSyncConnectorIndex; +/// Index of the display to which this GLSync applies to. + int iDisplayIndex; +} ADLGlSyncMode2, *LPADLGlSyncMode2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the packet info of a display. +/// +/// This structure is used to get and set the packet information of a display. +/// This structure is used by ADLDisplayDataPacket. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLInfoPacket +{ + char hb0; + char hb1; + char hb2; +/// sb0~sb27 + char sb[28]; +}ADLInfoPacket; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the AVI packet info of a display. +/// +/// This structure is used to get and set AVI the packet info of a display. +/// This structure is used by ADLDisplayDataPacket. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAVIInfoPacket //Valid user defined data/ +{ +/// byte 3, bit 7 + char bPB3_ITC; +/// byte 5, bit [7:4]. + char bPB5; +}ADLAVIInfoPacket; + +// Overdrive clock setting structure definition. + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the Overdrive clock setting. +/// +/// This structure is used to get the Overdrive clock setting. +/// This structure is used by ADLAdapterODClockInfo. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODClockSetting +{ +/// Deafult clock + int iDefaultClock; +/// Current clock + int iCurrentClock; +/// Maximum clcok + int iMaxClock; +/// Minimum clock + int iMinClock; +/// Requested clcock + int iRequestedClock; +/// Step + int iStepClock; +} ADLODClockSetting; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the Overdrive clock information. +/// +/// This structure is used to get the Overdrive clock information. +/// This structure is used by the ADL_Display_ODClockInfo_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterODClockInfo +{ +/// Size of the structure + int iSize; +/// Flag \ref define_clockinfo_flags + int iFlags; +/// Memory Clock + ADLODClockSetting sMemoryClock; +/// Engine Clock + ADLODClockSetting sEngineClock; +} ADLAdapterODClockInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the Overdrive clock configuration. +/// +/// This structure is used to set the Overdrive clock configuration. +/// This structure is used by the ADL_Display_ODClockConfig_Set() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterODClockConfig +{ +/// Size of the structure + int iSize; +/// Flag \ref define_clockinfo_flags + int iFlags; +/// Memory Clock + int iMemoryClock; +/// Engine Clock + int iEngineClock; +} ADLAdapterODClockConfig; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about current power management related activity. +/// +/// This structure is used to store information about current power management related activity. +/// This structure (Overdrive 5 interfaces) is used by the ADL_PM_CurrentActivity_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPMActivity +{ +/// Must be set to the size of the structure + int iSize; +/// Current engine clock. + int iEngineClock; +/// Current memory clock. + int iMemoryClock; +/// Current core voltage. + int iVddc; +/// GPU utilization. + int iActivityPercent; +/// Performance level index. + int iCurrentPerformanceLevel; +/// Current PCIE bus speed. + int iCurrentBusSpeed; +/// Number of PCIE bus lanes. + int iCurrentBusLanes; +/// Maximum number of PCIE bus lanes. + int iMaximumBusLanes; +/// Reserved for future purposes. + int iReserved; +} ADLPMActivity; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about thermal controller. +/// +/// This structure is used to store information about thermal controller. +/// This structure is used by ADL_PM_ThermalDevices_Enum. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLThermalControllerInfo +{ +/// Must be set to the size of the structure + int iSize; +/// Possible valies: \ref ADL_DL_THERMAL_DOMAIN_OTHER or \ref ADL_DL_THERMAL_DOMAIN_GPU. + int iThermalDomain; +/// GPU 0, 1, etc. + int iDomainIndex; +/// Possible valies: \ref ADL_DL_THERMAL_FLAG_INTERRUPT or \ref ADL_DL_THERMAL_FLAG_FANCONTROL + int iFlags; +} ADLThermalControllerInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about thermal controller temperature. +/// +/// This structure is used to store information about thermal controller temperature. +/// This structure is used by the ADL_PM_Temperature_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLTemperature +{ +/// Must be set to the size of the structure + int iSize; +/// Temperature in millidegrees Celsius. + int iTemperature; +} ADLTemperature; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about thermal controller fan speed. +/// +/// This structure is used to store information about thermal controller fan speed. +/// This structure is used by the ADL_PM_FanSpeedInfo_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFanSpeedInfo +{ +/// Must be set to the size of the structure + int iSize; +/// \ref define_fanctrl + int iFlags; +/// Minimum possible fan speed value in percents. + int iMinPercent; +/// Maximum possible fan speed value in percents. + int iMaxPercent; +/// Minimum possible fan speed value in RPM. + int iMinRPM; +/// Maximum possible fan speed value in RPM. + int iMaxRPM; +} ADLFanSpeedInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about fan speed reported by thermal controller. +/// +/// This structure is used to store information about fan speed reported by thermal controller. +/// This structure is used by the ADL_Overdrive5_FanSpeed_Get() and ADL_Overdrive5_FanSpeed_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFanSpeedValue +{ +/// Must be set to the size of the structure + int iSize; +/// Possible valies: \ref ADL_DL_FANCTRL_SPEED_TYPE_PERCENT or \ref ADL_DL_FANCTRL_SPEED_TYPE_RPM + int iSpeedType; +/// Fan speed value + int iFanSpeed; +/// The only flag for now is: \ref ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED + int iFlags; +} ADLFanSpeedValue; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the range of Overdrive parameter. +/// +/// This structure is used to store information about the range of Overdrive parameter. +/// This structure is used by ADLODParameters. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODParameterRange +{ +/// Minimum parameter value. + int iMin; +/// Maximum parameter value. + int iMax; +/// Parameter step value. + int iStep; +} ADLODParameterRange; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive parameters. +/// +/// This structure is used to store information about Overdrive parameters. +/// This structure is used by the ADL_Overdrive5_ODParameters_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODParameters +{ +/// Must be set to the size of the structure + int iSize; +/// Number of standard performance states. + int iNumberOfPerformanceLevels; +/// Indicates whether the GPU is capable to measure its activity. + int iActivityReportingSupported; +/// Indicates whether the GPU supports discrete performance levels or performance range. + int iDiscretePerformanceLevels; +/// Reserved for future use. + int iReserved; +/// Engine clock range. + ADLODParameterRange sEngineClock; +/// Memory clock range. + ADLODParameterRange sMemoryClock; +/// Core voltage range. + ADLODParameterRange sVddc; +} ADLODParameters; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive level. +/// +/// This structure is used to store information about Overdrive level. +/// This structure is used by ADLODPerformanceLevels. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODPerformanceLevel +{ +/// Engine clock. + int iEngineClock; +/// Memory clock. + int iMemoryClock; +/// Core voltage. + int iVddc; +} ADLODPerformanceLevel; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive performance levels. +/// +/// This structure is used to store information about Overdrive performance levels. +/// This structure is used by the ADL_Overdrive5_ODPerformanceLevels_Get() and ADL_Overdrive5_ODPerformanceLevels_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODPerformanceLevels +{ +/// Must be set to sizeof( \ref ADLODPerformanceLevels ) + sizeof( \ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1) + int iSize; + int iReserved; +/// Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements. + ADLODPerformanceLevel aLevels [1]; +} ADLODPerformanceLevels; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the proper CrossfireX chains combinations. +/// +/// This structure is used to store information about the CrossfireX chains combination for a particular adapter. +/// This structure is used by the ADL_Adapter_Crossfire_Caps(), ADL_Adapter_Crossfire_Get(), and ADL_Adapter_Crossfire_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLCrossfireComb +{ +/// Number of adapters in this combination. + int iNumLinkAdapter; +/// A list of ADL indexes of the linked adapters in this combination. + int iAdaptLink[3]; +} ADLCrossfireComb; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing CrossfireX state and error information. +/// +/// This structure is used to store state and error information about a particular adapter CrossfireX combination. +/// This structure is used by the ADL_Adapter_Crossfire_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLCrossfireInfo +{ +/// Current error code of this CrossfireX combination. + int iErrorCode; +/// Current \ref define_crossfirestate + int iState; +/// If CrossfireX is supported by this combination. The value is either \ref ADL_TRUE or \ref ADL_FALSE. + int iSupported; +} ADLCrossfireInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the BIOS. +/// +/// This structure is used to store various information about the Chipset. This +/// information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLBiosInfo +{ + char strPartNumber[ADL_MAX_PATH]; ///< Part number. + char strVersion[ADL_MAX_PATH]; ///< Version number. + char strDate[ADL_MAX_PATH]; ///< BIOS date in yyyy/mm/dd hh:mm format. +} ADLBiosInfo, *LPADLBiosInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about adapter location. +/// +/// This structure is used to store information about adapter location. +/// This structure is used by ADLMVPUStatus. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterLocation +{ +/// PCI Bus number : 8 bits + int iBus; +/// Device number : 5 bits + int iDevice; +/// Function number : 3 bits + int iFunction; +} ADLAdapterLocation,ADLBdf; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing version information +/// +/// This structure is used to store software version information, description of the display device and a web link to the latest installed Catalyst drivers. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLVersionsInfo +{ + /// Driver Release (Packaging) Version (e.g. 8.71-100128n-094835E-ATI) + char strDriverVer[ADL_MAX_PATH]; + /// Catalyst Version(e.g. "10.1"). + char strCatalystVersion[ADL_MAX_PATH]; + /// Web link to an XML file with information about the latest AMD drivers and locations (e.g. "http://www.amd.com/us/driverxml" ) + char strCatalystWebLink[ADL_MAX_PATH]; +} ADLVersionsInfo, *LPADLVersionsInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing version information +/// +/// This structure is used to store software version information, description of the display device and a web link to the latest installed Catalyst drivers. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLVersionsInfoX2 +{ + /// Driver Release (Packaging) Version (e.g. "16.20.1035-160621a-303814C") + char strDriverVer[ADL_MAX_PATH]; + /// Catalyst Version(e.g. "15.8"). + char strCatalystVersion[ADL_MAX_PATH]; + /// Crimson Version(e.g. "16.6.2"). + char strCrimsonVersion[ADL_MAX_PATH]; + /// Web link to an XML file with information about the latest AMD drivers and locations (e.g. "http://support.amd.com/drivers/xml/driver_09_us.xml" ) + char strCatalystWebLink[ADL_MAX_PATH]; +} ADLVersionsInfoX2, *LPADLVersionsInfoX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about MultiVPU capabilities. +/// +/// This structure is used to store information about MultiVPU capabilities. +/// This structure is used by the ADL_Display_MVPUCaps_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMVPUCaps +{ +/// Must be set to sizeof( ADLMVPUCaps ). + int iSize; +/// Number of adapters. + int iAdapterCount; +/// Bits set for all possible MVPU masters. \ref MVPU_ADAPTER_0 .. \ref MVPU_ADAPTER_3 + int iPossibleMVPUMasters; +/// Bits set for all possible MVPU slaves. \ref MVPU_ADAPTER_0 .. \ref MVPU_ADAPTER_3 + int iPossibleMVPUSlaves; +/// Registry path for each adapter. + char cAdapterPath[ADL_DL_MAX_MVPU_ADAPTERS][ADL_DL_MAX_REGISTRY_PATH]; +} ADLMVPUCaps; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about MultiVPU status. +/// +/// This structure is used to store information about MultiVPU status. +/// Ths structure is used by the ADL_Display_MVPUStatus_Get() function. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMVPUStatus +{ +/// Must be set to sizeof( ADLMVPUStatus ). + int iSize; +/// Number of active adapters. + int iActiveAdapterCount; +/// MVPU status. + int iStatus; +/// PCI Bus/Device/Function for each active adapter participating in MVPU. + ADLAdapterLocation aAdapterLocation[ADL_DL_MAX_MVPU_ADAPTERS]; +} ADLMVPUStatus; + +// Displays Manager structures + +/////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the activatable source. +/// +/// This structure is used to store activatable source information +/// This information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLActivatableSource +{ + /// The Persistent logical Adapter Index. + int iAdapterIndex; + /// The number of Activatable Sources. + int iNumActivatableSources; + /// The bit mask identifies the number of bits ActivatableSourceValue is using. (Not currnetly used) + int iActivatableSourceMask; + /// The bit mask identifies the status. (Not currnetly used) + int iActivatableSourceValue; +} ADLActivatableSource, *LPADLActivatableSource; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about display mode. +/// +/// This structure is used to store the display mode for the current adapter +/// such as X, Y positions, screen resolutions, orientation, +/// color depth, refresh rate, progressive or interlace mode, etc. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLMode +{ +/// Adapter index. + int iAdapterIndex; +/// Display IDs. + ADLDisplayID displayID; +/// Screen position X coordinate. + int iXPos; +/// Screen position Y coordinate. + int iYPos; +/// Screen resolution Width. + int iXRes; +/// Screen resolution Height. + int iYRes; +/// Screen Color Depth. E.g., 16, 32. + int iColourDepth; +/// Screen refresh rate. Could be fractional E.g. 59.97 + float fRefreshRate; +/// Screen orientation. E.g., 0, 90, 180, 270. + int iOrientation; +/// Vista mode flag indicating Progressive or Interlaced mode. + int iModeFlag; +/// The bit mask identifying the number of bits this Mode is currently using. It is the sum of all the bit definitions defined in \ref define_displaymode + int iModeMask; +/// The bit mask identifying the display status. The detailed definition is in \ref define_displaymode + int iModeValue; +} ADLMode, *LPADLMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about display target information. +/// +/// This structure is used to store the display target information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayTarget +{ + /// The Display ID. + ADLDisplayID displayID; + + /// The display map index identify this manner and the desktop surface. + int iDisplayMapIndex; + + /// The bit mask identifies the number of bits DisplayTarget is currently using. It is the sum of all the bit definitions defined in \ref ADL_DISPLAY_DISPLAYTARGET_PREFERRED. + int iDisplayTargetMask; + + /// The bit mask identifies the display status. The detailed definition is in \ref ADL_DISPLAY_DISPLAYTARGET_PREFERRED. + int iDisplayTargetValue; +} ADLDisplayTarget, *LPADLDisplayTarget; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display SLS bezel Mode information. +/// +/// This structure is used to store the display SLS bezel Mode information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct tagADLBezelTransientMode +{ + /// Adapter Index + int iAdapterIndex; + + /// SLS Map Index + int iSLSMapIndex; + + /// The mode index + int iSLSModeIndex; + + /// The mode + ADLMode displayMode; + + /// The number of bezel offsets belongs to this map + int iNumBezelOffset; + + /// The first bezel offset array index in the native mode array + int iFirstBezelOffsetArrayIndex; + + /// The bit mask identifies the bits this structure is currently using. It will be the total OR of all the bit definitions. + int iSLSBezelTransientModeMask; + + /// The bit mask identifies the display status. The detail definition is defined below. + int iSLSBezelTransientModeValue; +} ADLBezelTransientMode, *LPADLBezelTransientMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the adapter display manner. +/// +/// This structure is used to store adapter display manner information +/// This information can be returned to the user. Alternatively, it can be used to access various driver calls to +/// fetch various display device related display manner settings upon the user's request. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterDisplayCap +{ + /// The Persistent logical Adapter Index. + int iAdapterIndex; + /// The bit mask identifies the number of bits AdapterDisplayCap is currently using. Sum all the bits defined in ADL_ADAPTER_DISPLAYCAP_XXX + int iAdapterDisplayCapMask; + /// The bit mask identifies the status. Refer to ADL_ADAPTER_DISPLAYCAP_XXX + int iAdapterDisplayCapValue; +} ADLAdapterDisplayCap, *LPADLAdapterDisplayCap; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about display mapping. +/// +/// This structure is used to store the display mapping data such as display manner. +/// For displays with horizontal or vertical stretch manner, +/// this structure also stores the display order, display row, and column data. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayMap +{ +/// The current display map index. It is the OS desktop index. For example, if the OS index 1 is showing clone mode, the display map will be 1. + int iDisplayMapIndex; + +/// The Display Mode for the current map + ADLMode displayMode; + +/// The number of display targets belongs to this map\n + int iNumDisplayTarget; + +/// The first target array index in the Target array\n + int iFirstDisplayTargetArrayIndex; + +/// The bit mask identifies the number of bits DisplayMap is currently using. It is the sum of all the bit definitions defined in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx. + int iDisplayMapMask; + +///The bit mask identifies the display status. The detailed definition is in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx. + int iDisplayMapValue; +} ADLDisplayMap, *LPADLDisplayMap; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the display device possible map for one GPU +/// +/// This structure is used to store the display device possible map +/// This information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPossibleMap +{ + /// The current PossibleMap index. Each PossibleMap is assigned an index + int iIndex; + /// The adapter index identifying the GPU for which to validate these Maps & Targets + int iAdapterIndex; + /// Number of display Maps for this GPU to be validated + int iNumDisplayMap; + /// The display Maps list to validate + ADLDisplayMap* displayMap; + /// the number of display Targets for these display Maps + int iNumDisplayTarget; + /// The display Targets list for these display Maps to be validated. + ADLDisplayTarget* displayTarget; +} ADLPossibleMap, *LPADLPossibleMap; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about display possible mapping. +/// +/// This structure is used to store the display possible mapping's controller index for the current display. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPossibleMapping +{ + int iDisplayIndex; ///< The display index. Each display is assigned an index. + int iDisplayControllerIndex; ///< The controller index to which display is mapped. + int iDisplayMannerSupported; ///< The supported display manner. +} ADLPossibleMapping, *LPADLPossibleMapping; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing information about the validated display device possible map result. +/// +/// This structure is used to store the validated display device possible map result +/// This information can be returned to the user. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPossibleMapResult +{ + /// The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1. + int iIndex; + // The bit mask identifies the number of bits PossibleMapResult is currently using. It will be the sum all the bit definitions defined in ADL_DISPLAY_POSSIBLEMAPRESULT_VALID. + int iPossibleMapResultMask; + /// The bit mask identifies the possible map result. The detail definition is defined in ADL_DISPLAY_POSSIBLEMAPRESULT_XXX. + int iPossibleMapResultValue; +} ADLPossibleMapResult, *LPADLPossibleMapResult; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display SLS Grid information. +/// +/// This structure is used to store the display SLS Grid information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSGrid +{ +/// The Adapter index. + int iAdapterIndex; + +/// The grid index. + int iSLSGridIndex; + +/// The grid row. + int iSLSGridRow; + +/// The grid column. + int iSLSGridColumn; + +/// The grid bit mask identifies the number of bits DisplayMap is currently using. Sum of all bits defined in ADL_DISPLAY_SLSGRID_ORIENTATION_XXX + int iSLSGridMask; + +/// The grid bit value identifies the display status. Refer to ADL_DISPLAY_SLSGRID_ORIENTATION_XXX + int iSLSGridValue; +} ADLSLSGrid, *LPADLSLSGrid; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display SLS Map information. +/// +/// This structure is used to store the display SLS Map information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSMap +{ + /// The Adapter Index + int iAdapterIndex; + + /// The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1. + int iSLSMapIndex; + + /// Indicate the current grid + ADLSLSGrid grid; + + /// OS surface index + int iSurfaceMapIndex; + + /// Screen orientation. E.g., 0, 90, 180, 270 + int iOrientation; + + /// The number of display targets belongs to this map + int iNumSLSTarget; + + /// The first target array index in the Target array + int iFirstSLSTargetArrayIndex; + + /// The number of native modes belongs to this map + int iNumNativeMode; + + /// The first native mode array index in the native mode array + int iFirstNativeModeArrayIndex; + + /// The number of bezel modes belongs to this map + int iNumBezelMode; + + /// The first bezel mode array index in the native mode array + int iFirstBezelModeArrayIndex; + + /// The number of bezel offsets belongs to this map + int iNumBezelOffset; + + /// The first bezel offset array index in the + int iFirstBezelOffsetArrayIndex; + + /// The bit mask identifies the number of bits DisplayMap is currently using. Sum all the bit definitions defined in ADL_DISPLAY_SLSMAP_XXX. + int iSLSMapMask; + + /// The bit mask identifies the display map status. Refer to ADL_DISPLAY_SLSMAP_XXX + int iSLSMapValue; +} ADLSLSMap, *LPADLSLSMap; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display SLS Offset information. +/// +/// This structure is used to store the display SLS Offset information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSOffset +{ + /// The Adapter Index + int iAdapterIndex; + + /// The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1. + int iSLSMapIndex; + + /// The Display ID. + ADLDisplayID displayID; + + /// SLS Bezel Mode Index + int iBezelModeIndex; + + /// SLS Bezel Offset X + int iBezelOffsetX; + + /// SLS Bezel Offset Y + int iBezelOffsetY; + + /// SLS Display Width + int iDisplayWidth; + + /// SLS Display Height + int iDisplayHeight; + + /// The bit mask identifies the number of bits Offset is currently using. + int iBezelOffsetMask; + + /// The bit mask identifies the display status. + int iBezelffsetValue; +} ADLSLSOffset, *LPADLSLSOffset; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display SLS Mode information. +/// +/// This structure is used to store the display SLS Mode information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSMode +{ + /// The Adapter Index + int iAdapterIndex; + + /// The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1. + int iSLSMapIndex; + + /// The mode index + int iSLSModeIndex; + + /// The mode for this map. + ADLMode displayMode; + + /// The bit mask identifies the number of bits Mode is currently using. + int iSLSNativeModeMask; + + /// The bit mask identifies the display status. + int iSLSNativeModeValue; +} ADLSLSMode, *LPADLSLSMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the display Possible SLS Map information. +/// +/// This structure is used to store the display Possible SLS Map information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPossibleSLSMap +{ + /// The current display map index. It is the OS Desktop index. + /// For example, OS Index 1 showing clone mode. The Display Map will be 1. + int iSLSMapIndex; + + /// Number of display map to be validated. + int iNumSLSMap; + + /// The display map list for validation + ADLSLSMap* lpSLSMap; + + /// the number of display map config to be validated. + int iNumSLSTarget; + + /// The display target list for validation. + ADLDisplayTarget* lpDisplayTarget; +} ADLPossibleSLSMap, *LPADLPossibleSLSMap; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the SLS targets. +/// +/// This structure is used to store the SLS targets information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSTarget +{ + /// the logic adapter index + int iAdapterIndex; + + /// The SLS map index + int iSLSMapIndex; + + /// The target ID + ADLDisplayTarget displayTarget; + + /// Target postion X in SLS grid + int iSLSGridPositionX; + + /// Target postion Y in SLS grid + int iSLSGridPositionY; + + /// The view size width, height and rotation angle per SLS Target + ADLMode viewSize; + + /// The bit mask identifies the bits in iSLSTargetValue are currently used + int iSLSTargetMask; + + /// The bit mask identifies status info. It is for function extension purpose + int iSLSTargetValue; +} ADLSLSTarget, *LPADLSLSTarget; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the Adapter offset stepping size. +/// +/// This structure is used to store the Adapter offset stepping size information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLBezelOffsetSteppingSize +{ + /// the logic adapter index + int iAdapterIndex; + + /// The SLS map index + int iSLSMapIndex; + + /// Bezel X stepping size offset + int iBezelOffsetSteppingSizeX; + + /// Bezel Y stepping size offset + int iBezelOffsetSteppingSizeY; + + /// Identifies the bits this structure is currently using. It will be the total OR of all the bit definitions. + int iBezelOffsetSteppingSizeMask; + + /// Bit mask identifies the display status. + int iBezelOffsetSteppingSizeValue; +} ADLBezelOffsetSteppingSize, *LPADLBezelOffsetSteppingSize; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the overlap offset info for all the displays for each SLS mode. +/// +/// This structure is used to store the no. of overlapped modes for each SLS Mode once user finishes the configuration from Overlap Widget +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSLSOverlappedMode +{ + /// the SLS mode for which the overlap is configured + ADLMode SLSMode; + /// the number of target displays in SLS. + int iNumSLSTarget; + /// the first target array index in the target array + int iFirstTargetArrayIndex; +}ADLSLSTargetOverlap, *LPADLSLSTargetOverlap; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver supported PowerExpress Config Caps +/// +/// This structure is used to store the driver supported PowerExpress Config Caps +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPXConfigCaps +{ + /// The Persistent logical Adapter Index. + int iAdapterIndex; + + /// The bit mask identifies the number of bits PowerExpress Config Caps is currently using. It is the sum of all the bit definitions defined in ADL_PX_CONFIGCAPS_XXXX /ref define_powerxpress_constants. + int iPXConfigCapMask; + + /// The bit mask identifies the PowerExpress Config Caps value. The detailed definition is in ADL_PX_CONFIGCAPS_XXXX /ref define_powerxpress_constants. + int iPXConfigCapValue; +} ADLPXConfigCaps, *LPADLPXConfigCaps; + +///////////////////////////////////////////////////////////////////////////////////////// +///\brief Enum containing PX or HG type +/// +/// This enum is used to get PX or hG type +/// +/// \nosubgrouping +////////////////////////////////////////////////////////////////////////////////////////// +typedef enum ADLPxType +{ + //Not AMD related PX/HG or not PX or HG at all + ADL_PX_NONE = 0, + //A+A PX + ADL_SWITCHABLE_AMDAMD = 1, + // A+A HG + ADL_HG_AMDAMD = 2, + //A+I PX + ADL_SWITCHABLE_AMDOTHER = 3, + //A+I HG + ADL_HG_AMDOTHER = 4, +}ADLPxType; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an application +/// +/// This structure is used to store basic information of an application +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLApplicationData +{ + /// Path Name + char strPathName[ADL_MAX_PATH]; + /// File Name + char strFileName[ADL_APP_PROFILE_FILENAME_LENGTH]; + /// Creation timestamp + char strTimeStamp[ADL_APP_PROFILE_TIMESTAMP_LENGTH]; + /// Version + char strVersion[ADL_APP_PROFILE_VERSION_LENGTH]; +}ADLApplicationData; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an application +/// +/// This structure is used to store basic information of an application +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLApplicationDataX2 +{ + /// Path Name + wchar_t strPathName[ADL_MAX_PATH]; + /// File Name + wchar_t strFileName[ADL_APP_PROFILE_FILENAME_LENGTH]; + /// Creation timestamp + wchar_t strTimeStamp[ADL_APP_PROFILE_TIMESTAMP_LENGTH]; + /// Version + wchar_t strVersion[ADL_APP_PROFILE_VERSION_LENGTH]; +}ADLApplicationDataX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an application +/// +/// This structure is used to store basic information of an application including process id +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLApplicationDataX3 +{ + /// Path Name + wchar_t strPathName[ADL_MAX_PATH]; + /// File Name + wchar_t strFileName[ADL_APP_PROFILE_FILENAME_LENGTH]; + /// Creation timestamp + wchar_t strTimeStamp[ADL_APP_PROFILE_TIMESTAMP_LENGTH]; + /// Version + wchar_t strVersion[ADL_APP_PROFILE_VERSION_LENGTH]; + //Application Process id + unsigned int iProcessId; +}ADLApplicationDataX3; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information of a property of an application profile +/// +/// This structure is used to store property information of an application profile +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct PropertyRecord +{ + /// Property Name + char strName [ADL_APP_PROFILE_PROPERTY_LENGTH]; + /// Property Type + ADLProfilePropertyType eType; + /// Data Size in bytes + int iDataSize; + /// Property Value, can be any data type + unsigned char uData[1]; +}PropertyRecord; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an application profile +/// +/// This structure is used to store information of an application profile +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLApplicationProfile +{ + /// Number of properties + int iCount; + /// Buffer to store all property records + PropertyRecord record[1]; +}ADLApplicationProfile; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an OD5 Power Control feature +/// +/// This structure is used to store information of an Power Control feature +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPowerControlInfo +{ +/// Minimum value. +int iMinValue; +/// Maximum value. +int iMaxValue; +/// The minimum change in between minValue and maxValue. +int iStepValue; + } ADLPowerControlInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an controller mode +/// +/// This structure is used to store information of an controller mode +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLControllerMode +{ + /// This falg indicates actions that will be applied by set viewport + /// The value can be a combination of ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_POSITION, + /// ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_PANLOCK and ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_SIZE + int iModifiers; + + /// Horizontal view starting position + int iViewPositionCx; + + /// Vertical view starting position + int iViewPositionCy; + + /// Horizontal left panlock position + int iViewPanLockLeft; + + /// Horizontal right panlock position + int iViewPanLockRight; + + /// Vertical top panlock position + int iViewPanLockTop; + + /// Vertical bottom panlock position + int iViewPanLockBottom; + + /// View resolution in pixels (width) + int iViewResolutionCx; + + /// View resolution in pixels (hight) + int iViewResolutionCy; +}ADLControllerMode; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about a display +/// +/// This structure is used to store information about a display +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayIdentifier +{ + /// ADL display index + long ulDisplayIndex; + + /// manufacturer ID of the display + long ulManufacturerId; + + /// product ID of the display + long ulProductId; + + /// serial number of the display + long ulSerialNo; +} ADLDisplayIdentifier; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 clock range +/// +/// This structure is used to store information about Overdrive 6 clock range +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6ParameterRange +{ + /// The starting value of the clock range + int iMin; + /// The ending value of the clock range + int iMax; + /// The minimum increment between clock values + int iStep; +} ADLOD6ParameterRange; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 capabilities +/// +/// This structure is used to store information about Overdrive 6 capabilities +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6Capabilities +{ + /// Contains a bitmap of the OD6 capability flags. Possible values: \ref ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION, + /// \ref ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION, \ref ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR + int iCapabilities; + /// Contains a bitmap indicating the power states + /// supported by OD6. Currently only the performance state + /// is supported. Possible Values: \ref ADL_OD6_SUPPORTEDSTATE_PERFORMANCE + int iSupportedStates; + /// Number of levels. OD6 will always use 2 levels, which describe + /// the minimum to maximum clock ranges. + /// The 1st level indicates the minimum clocks, and the 2nd level + /// indicates the maximum clocks. + int iNumberOfPerformanceLevels; + /// Contains the hard limits of the sclk range. Overdrive + /// clocks cannot be set outside this range. + ADLOD6ParameterRange sEngineClockRange; + /// Contains the hard limits of the mclk range. Overdrive + /// clocks cannot be set outside this range. + ADLOD6ParameterRange sMemoryClockRange; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6Capabilities; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 clock values. +/// +/// This structure is used to store information about Overdrive 6 clock values. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6PerformanceLevel +{ + /// Engine (core) clock. + int iEngineClock; + /// Memory clock. + int iMemoryClock; +} ADLOD6PerformanceLevel; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 clocks. +/// +/// This structure is used to store information about Overdrive 6 clocks. This is a +/// variable-sized structure. iNumberOfPerformanceLevels indicate how many elements +/// are contained in the aLevels array. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6StateInfo +{ + /// Number of levels. OD6 uses clock ranges instead of discrete performance levels. + /// iNumberOfPerformanceLevels is always 2. The 1st level indicates the minimum clocks + /// in the range. The 2nd level indicates the maximum clocks in the range. + int iNumberOfPerformanceLevels; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; + + /// Variable-sized array of levels. + /// The number of elements in the array is specified by iNumberofPerformanceLevels. + ADLOD6PerformanceLevel aLevels [1]; +} ADLOD6StateInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about current Overdrive 6 performance status. +/// +/// This structure is used to store information about current Overdrive 6 performance status. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6CurrentStatus +{ + /// Current engine clock in 10 KHz. + int iEngineClock; + /// Current memory clock in 10 KHz. + int iMemoryClock; + /// Current GPU activity in percent. This + /// indicates how "busy" the GPU is. + int iActivityPercent; + /// Not used. Reserved for future use. + int iCurrentPerformanceLevel; + /// Current PCI-E bus speed + int iCurrentBusSpeed; + /// Current PCI-E bus # of lanes + int iCurrentBusLanes; + /// Maximum possible PCI-E bus # of lanes + int iMaximumBusLanes; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6CurrentStatus; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 thermal contoller capabilities +/// +/// This structure is used to store information about Overdrive 6 thermal controller capabilities +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6ThermalControllerCaps +{ + /// Contains a bitmap of thermal controller capability flags. Possible values: \ref ADL_OD6_TCCAPS_THERMAL_CONTROLLER, \ref ADL_OD6_TCCAPS_FANSPEED_CONTROL, + /// \ref ADL_OD6_TCCAPS_FANSPEED_PERCENT_READ, \ref ADL_OD6_TCCAPS_FANSPEED_PERCENT_WRITE, \ref ADL_OD6_TCCAPS_FANSPEED_RPM_READ, \ref ADL_OD6_TCCAPS_FANSPEED_RPM_WRITE + int iCapabilities; + /// Minimum fan speed expressed as a percentage + int iFanMinPercent; + /// Maximum fan speed expressed as a percentage + int iFanMaxPercent; + /// Minimum fan speed expressed in revolutions-per-minute + int iFanMinRPM; + /// Maximum fan speed expressed in revolutions-per-minute + int iFanMaxRPM; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6ThermalControllerCaps; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 fan speed information +/// +/// This structure is used to store information about Overdrive 6 fan speed information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6FanSpeedInfo +{ + /// Contains a bitmap of the valid fan speed type flags. Possible values: \ref ADL_OD6_FANSPEED_TYPE_PERCENT, \ref ADL_OD6_FANSPEED_TYPE_RPM, \ref ADL_OD6_FANSPEED_USER_DEFINED + int iSpeedType; + /// Contains current fan speed in percent (if valid flag exists in iSpeedType) + int iFanSpeedPercent; + /// Contains current fan speed in RPM (if valid flag exists in iSpeedType) + int iFanSpeedRPM; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6FanSpeedInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 fan speed value +/// +/// This structure is used to store information about Overdrive 6 fan speed value +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6FanSpeedValue +{ + /// Indicates the units of the fan speed. Possible values: \ref ADL_OD6_FANSPEED_TYPE_PERCENT, \ref ADL_OD6_FANSPEED_TYPE_RPM + int iSpeedType; + /// Fan speed value (units as indicated above) + int iFanSpeed; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6FanSpeedValue; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 PowerControl settings. +/// +/// This structure is used to store information about Overdrive 6 PowerControl settings. +/// PowerControl is the feature which allows the performance characteristics of the GPU +/// to be adjusted by changing the PowerTune power limits. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6PowerControlInfo +{ + /// The minimum PowerControl adjustment value + int iMinValue; + /// The maximum PowerControl adjustment value + int iMaxValue; + /// The minimum difference between PowerControl adjustment values + int iStepValue; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6PowerControlInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 PowerControl settings. +/// +/// This structure is used to store information about Overdrive 6 PowerControl settings. +/// PowerControl is the feature which allows the performance characteristics of the GPU +/// to be adjusted by changing the PowerTune power limits. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6VoltageControlInfo +{ + /// The minimum VoltageControl adjustment value + int iMinValue; + /// The maximum VoltageControl adjustment value + int iMaxValue; + /// The minimum difference between VoltageControl adjustment values + int iStepValue; + + /// Value for future extension + int iExtValue; + /// Mask for future extension + int iExtMask; +} ADLOD6VoltageControlInfo; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing ECC statistics namely SEC counts and DED counts +/// Single error count - count of errors that can be corrected +/// Doubt Error Detect - count of errors that cannot be corrected +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLECCData +{ + // Single error count - count of errors that can be corrected + int iSec; + // Double error detect - count of errors that cannot be corrected + int iDed; +} ADLECCData; + +/// \brief Handle to ADL client context. +/// +/// ADL clients obtain context handle from initial call to \ref ADL2_Main_Control_Create. +/// Clients have to pass the handle to each subsequent ADL call and finally destroy +/// the context with call to \ref ADL2_Main_Control_Destroy +/// \nosubgrouping +typedef void *ADL_CONTEXT_HANDLE; + +/// \brief Handle to ADL Frame Monitor Token. +/// +/// Frame Monitor clients obtain handle from initial call to \ref ADL2_Adapter_FrameMetrics_FrameDuration_Enable +/// Clients have to pass the handle to each subsequent ADL call to \ref ADL2_Adapter_FrameMetrics_FrameDuration_Get +/// and finally destroy the token with call to \ref ADL2_Adapter_FrameMetrics_FrameDuration_Disable +/// \nosubgrouping +typedef void *ADL_FRAME_DURATION_HANDLE; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the display mode definition used per controller. +/// +/// This structure is used to store the display mode definition used per controller. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayModeX2 +{ +/// Horizontal resolution (in pixels). + int iWidth; +/// Vertical resolution (in lines). + int iHeight; +/// Interlaced/Progressive. The value will be set for Interlaced as ADL_DL_TIMINGFLAG_INTERLACED. If not set it is progressive. Refer define_detailed_timing_flags. + int iScanType; +/// Refresh rate. + int iRefreshRate; +/// Timing Standard. Refer define_modetiming_standard. + int iTimingStandard; +} ADLDisplayModeX2; + +typedef enum ADLAppProcessState +{ + APP_PROC_INVALID = 0, // Invalid Application + APP_PROC_PREMPTION = 1, // The Application is being set up for Process Creation + APP_PROC_CREATION = 2, // The Application's Main Process is created by the OS + APP_PROC_READ = 3, // The Application's Data is ready to be read + APP_PROC_WAIT = 4, // The Application is waiting for Timeout or Notification to Resume + APP_PROC_RUNNING = 5, // The Application is running + APP_PROC_TERMINATE = 6 // The Application is about to terminate +}ADLAppProcessState; + +typedef enum ADLAppInterceptionListType +{ + ADL_INVALID_FORMAT = 0, + ADL_IMAGEFILEFORMAT = 1, + ADL_ENVVAR = 2 +}ADLAppInterceptionListType; + +typedef struct ADLAppInterceptionInfo +{ + wchar_t AppName[ADL_MAX_PATH]; // the file name of the application or env var + unsigned int ProcessId; + ADLAppInterceptionListType AppFormat; + ADLAppProcessState AppState; +} ADLAppInterceptionInfo; + +typedef enum ADL_AP_DATABASE // same as _SHARED_AP_DATABASE in "inc/shared/shared_escape.h" +{ + ADL_AP_DATABASE__SYSTEM, + ADL_AP_DATABASE__USER, + ADL_AP_DATABASE__OEM +} ADL_AP_DATABASE; + +typedef struct ADLAppInterceptionInfoX2 +{ + wchar_t AppName[ADL_MAX_PATH]; // the file name of the application or env var + unsigned int ProcessId; + unsigned int WaitForResumeNeeded; + wchar_t CommandLine[ADL_MAX_PATH]; // The command line on app start/stop event + ADLAppInterceptionListType AppFormat; + ADLAppProcessState AppState; +} ADLAppInterceptionInfoX2; + +typedef struct ADLAppInterceptionInfoX3 +{ + wchar_t AppName[ADL_MAX_PATH]; // the file name of the application or env var + unsigned int ProcessId; + unsigned int WaitForResumeNeeded; + unsigned int RayTracingStatus; // returns the Ray Tracing status if it is enabled atleast once in session. + wchar_t CommandLine[ADL_MAX_PATH]; // The command line on app start/stop event + ADLAppInterceptionListType AppFormat; + ADLAppProcessState AppState; +} ADLAppInterceptionInfoX3; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information info for a property record in a profile +/// +/// This structure is used to store info for a property record in a profile +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPropertyRecordCreate +{ + /// Name of the property + wchar_t * strPropertyName; + /// Data type of the property + ADLProfilePropertyType eType; + // Value of the property + wchar_t * strPropertyValue; +} ADLPropertyRecordCreate; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information info for an application record +/// +/// This structure is used to store info for an application record +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLApplicationRecord +{ + /// Title of the application + wchar_t * strTitle; + /// File path of the application + wchar_t * strPathName; + /// File name of the application + wchar_t * strFileName; + /// File versin the application + wchar_t * strVersion; + /// Nostes on the application + wchar_t * strNotes; + /// Driver area which the application uses + wchar_t * strArea; + /// Name of profile assigned to the application + wchar_t * strProfileName; + // Source where this application record come from + ADL_AP_DATABASE recordSource; +} ADLApplicationRecord; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 extension capabilities +/// +/// This structure is used to store information about Overdrive 6 extension capabilities +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6CapabilitiesEx +{ + /// Contains a bitmap of the OD6 extension capability flags. Possible values: \ref ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION, + /// \ref ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION, \ref ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR, + /// \ref ADL_OD6_CAPABILITY_POWER_CONTROL, \ref ADL_OD6_CAPABILITY_VOLTAGE_CONTROL, \ref ADL_OD6_CAPABILITY_PERCENT_ADJUSTMENT, + //// \ref ADL_OD6_CAPABILITY_THERMAL_LIMIT_UNLOCK + int iCapabilities; + /// The Power states that support clock and power customization. Only performance state is currently supported. + /// Possible Values: \ref ADL_OD6_SUPPORTEDSTATE_PERFORMANCE + int iSupportedStates; + /// Returns the hard limits of the SCLK overdrive adjustment range. Overdrive clocks should not be adjusted outside of this range. The values are specified as +/- percentages. + ADLOD6ParameterRange sEngineClockPercent; + /// Returns the hard limits of the MCLK overdrive adjustment range. Overdrive clocks should not be adjusted outside of this range. The values are specified as +/- percentages. + ADLOD6ParameterRange sMemoryClockPercent; + /// Returns the hard limits of the Power Limit adjustment range. Power limit should not be adjusted outside this range. The values are specified as +/- percentages. + ADLOD6ParameterRange sPowerControlPercent; + /// Reserved for future expansion of the structure. + int iExtValue; + /// Reserved for future expansion of the structure. + int iExtMask; +} ADLOD6CapabilitiesEx; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 extension state information +/// +/// This structure is used to store information about Overdrive 6 extension state information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6StateEx +{ + /// The current engine clock adjustment value, specified as a +/- percent. + int iEngineClockPercent; + /// The current memory clock adjustment value, specified as a +/- percent. + int iMemoryClockPercent; + /// The current power control adjustment value, specified as a +/- percent. + int iPowerControlPercent; + /// Reserved for future expansion of the structure. + int iExtValue; + /// Reserved for future expansion of the structure. + int iExtMask; +} ADLOD6StateEx; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive 6 extension recommended maximum clock adjustment values +/// +/// This structure is used to store information about Overdrive 6 extension recommended maximum clock adjustment values +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD6MaxClockAdjust +{ + /// The recommended maximum engine clock adjustment in percent, for the specified power limit value. + int iEngineClockMax; + /// The recommended maximum memory clock adjustment in percent, for the specified power limit value. + /// Currently the memory is independent of the Power Limit setting, so iMemoryClockMax will always return the maximum + /// possible adjustment value. This field is here for future enhancement in case we add a dependency between Memory Clock + /// adjustment and Power Limit setting. + int iMemoryClockMax; + /// Reserved for future expansion of the structure. + int iExtValue; + /// Reserved for future expansion of the structure. + int iExtMask; +} ADLOD6MaxClockAdjust; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the Connector information +/// +/// this structure is used to get the connector information like length, positions & etc. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLConnectorInfo +{ + ///index of the connector(0-based) + int iConnectorIndex; + ///used for disply identification/ordering + int iConnectorId; + ///index of the slot, 0-based index. + int iSlotIndex; + ///Type of the connector. \ref define_connector_types + int iType; + ///Position of the connector(in millimeters), from the right side of the slot. + int iOffset; + ///Length of the connector(in millimeters). + int iLength; +} ADLConnectorInfo; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the slot information +/// +/// this structure is used to get the slot information like length of the slot, no of connectors on the slot & etc. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLBracketSlotInfo +{ + ///index of the slot, 0-based index. + int iSlotIndex; + ///length of the slot(in millimeters). + int iLength; + ///width of the slot(in millimeters). + int iWidth; +} ADLBracketSlotInfo; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing MST branch information +/// +/// this structure is used to store the MST branch information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLMSTRad +{ + ///depth of the link. + int iLinkNumber; + /// Relative address, address scheme starts from source side + char rad[ADL_MAX_RAD_LINK_COUNT]; +} ADLMSTRad; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing port information +/// +/// this structure is used to get the display or MST branch information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDevicePort +{ + ///index of the connector. + int iConnectorIndex; + ///Relative MST address. If MST RAD contains 0 it means DP or Root of the MST topology. For non DP connectors MST RAD is ignored. + ADLMSTRad aMSTRad; +} ADLDevicePort; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing supported connection types and properties +/// +/// this structure is used to get the supported connection types and supported properties of given connector +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSupportedConnections +{ + ///Bit vector of supported connections. Bitmask is defined in constants section. \ref define_connection_types + int iSupportedConnections; + ///Array of bitvectors. Each bit vector represents supported properties for one connection type. Index of this array is connection type (bit number in mask). + int iSupportedProperties[ADL_MAX_CONNECTION_TYPES]; +} ADLSupportedConnections; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing connection state of the connector +/// +/// this structure is used to get the current Emulation status and mode of the given connector +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLConnectionState +{ + ///The value is bit vector. Each bit represents status. See masks constants for details. \ref define_emulation_status + int iEmulationStatus; + ///It contains information about current emulation mode. See constants for details. \ref define_emulation_mode + int iEmulationMode; + ///If connection is active it will contain display id, otherwise CWDDEDI_INVALID_DISPLAY_INDEX + int iDisplayIndex; +} ADLConnectionState; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing connection properties information +/// +/// this structure is used to retrieve the properties of connection type +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLConnectionProperties +{ + //Bit vector. Represents actual properties. Supported properties for specific connection type. \ref define_connection_properties + int iValidProperties; + //Bitrate(in MHz). Could be used for MST branch, DP or DP active dongle. \ref define_linkrate_constants + int iBitrate; + //Number of lanes in DP connection. \ref define_lanecount_constants + int iNumberOfLanes; + //Color depth(in bits). \ref define_colordepth_constants + int iColorDepth; + //3D capabilities. It could be used for some dongles. For instance: alternate framepack. Value of this property is bit vector. + int iStereo3DCaps; + ///Output Bandwidth. Could be used for MST branch, DP or DP Active dongle. \ref define_linkrate_constants + int iOutputBandwidth; +} ADLConnectionProperties; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing connection information +/// +/// this structure is used to retrieve the data from driver which includes +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLConnectionData +{ + ///Connection type. based on the connection type either iNumberofPorts or IDataSize,EDIDdata is valid, \ref define_connection_types + int iConnectionType; + ///Specifies the connection properties. + ADLConnectionProperties aConnectionProperties; + ///Number of ports + int iNumberofPorts; + ///Number of Active Connections + int iActiveConnections; + ///actual size of EDID data block size. + int iDataSize; + ///EDID Data + char EdidData[ADL_MAX_DISPLAY_EDID_DATA_SIZE]; +} ADLConnectionData; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an controller mode including Number of Connectors +/// +/// This structure is used to store information of an controller mode +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLAdapterCapsX2 +{ + /// AdapterID for this adapter + int iAdapterID; + /// Number of controllers for this adapter + int iNumControllers; + /// Number of displays for this adapter + int iNumDisplays; + /// Number of overlays for this adapter + int iNumOverlays; + /// Number of GLSyncConnectors + int iNumOfGLSyncConnectors; + /// The bit mask identifies the adapter caps + int iCapsMask; + /// The bit identifies the adapter caps \ref define_adapter_caps + int iCapsValue; + /// Number of Connectors for this adapter + int iNumConnectors; +}ADLAdapterCapsX2; + +typedef enum ADL_ERROR_RECORD_SEVERITY +{ + ADL_GLOBALLY_UNCORRECTED = 1, + ADL_LOCALLY_UNCORRECTED = 2, + ADL_DEFFERRED = 3, + ADL_CORRECTED = 4 +}ADL_ERROR_RECORD_SEVERITY; + +typedef union _ADL_ECC_EDC_FLAG +{ + struct + { + unsigned int isEccAccessing : 1; + unsigned int reserved : 31; + }bits; + unsigned int u32All; +}ADL_ECC_EDC_FLAG; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about EDC Error Record +/// +/// This structure is used to store EDC Error Record +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLErrorRecord +{ + // Severity of error + ADL_ERROR_RECORD_SEVERITY Severity; + + // Is the counter valid? + int countValid; + + // Counter value, if valid + unsigned int count; + + // Is the location information valid? + int locationValid; + + // Physical location of error + unsigned int CU; // CU number on which error occurred, if known + char StructureName[32]; // e.g. LDS, TCC, etc. + + // Time of error record creation (e.g. time of query, or time of poison interrupt) + char tiestamp[32]; + + unsigned int padding[3]; +}ADLErrorRecord; + +typedef enum ADL_EDC_BLOCK_ID +{ + ADL_EDC_BLOCK_ID_SQCIS = 1, + ADL_EDC_BLOCK_ID_SQCDS = 2, + ADL_EDC_BLOCK_ID_SGPR = 3, + ADL_EDC_BLOCK_ID_VGPR = 4, + ADL_EDC_BLOCK_ID_LDS = 5, + ADL_EDC_BLOCK_ID_GDS = 6, + ADL_EDC_BLOCK_ID_TCL1 = 7, + ADL_EDC_BLOCK_ID_TCL2 = 8 +}ADL_EDC_BLOCK_ID; + +typedef enum ADL_ERROR_INJECTION_MODE +{ + ADL_ERROR_INJECTION_MODE_SINGLE = 1, + ADL_ERROR_INJECTION_MODE_MULTIPLE = 2, + ADL_ERROR_INJECTION_MODE_ADDRESS = 3 +}ADL_ERROR_INJECTION_MODE; + +typedef union _ADL_ERROR_PATTERN +{ + struct + { + unsigned long EccInjVector : 16; + unsigned long EccInjEn : 9; + unsigned long EccBeatEn : 4; + unsigned long EccChEn : 4; + unsigned long reserved : 31; + } bits; + unsigned long long u64Value; +} ADL_ERROR_PATTERN; + +typedef struct ADL_ERROR_INJECTION_DATA +{ + unsigned long long errorAddress; + ADL_ERROR_PATTERN errorPattern; +}ADL_ERROR_INJECTION_DATA; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about EDC Error Injection +/// +/// This structure is used to store EDC Error Injection +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLErrorInjection +{ + ADL_EDC_BLOCK_ID blockId; + ADL_ERROR_INJECTION_MODE errorInjectionMode; +}ADLErrorInjection; + +typedef struct ADLErrorInjectionX2 +{ + ADL_EDC_BLOCK_ID blockId; + ADL_ERROR_INJECTION_MODE errorInjectionMode; + ADL_ERROR_INJECTION_DATA errorInjectionData; +}ADLErrorInjectionX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing per display FreeSync capability information. +/// +/// This structure is used to store the FreeSync capability of both the display and +/// the GPU the display is connected to. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFreeSyncCap +{ + /// FreeSync capability flags. \ref define_freesync_caps + int iCaps; + /// Reports minimum FreeSync refresh rate supported by the display in micro hertz + int iMinRefreshRateInMicroHz; + /// Reports maximum FreeSync refresh rate supported by the display in micro hertz + int iMaxRefreshRateInMicroHz; + /// Index of FreeSync Label to use: ADL_FREESYNC_LABEL_* + unsigned char ucLabelIndex; + /// Reserved + char cReserved[3]; + int iReserved[4]; +} ADLFreeSyncCap; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing per display Display Connectivty Experience Settings +/// +/// This structure is used to store the Display Connectivity Experience settings of a +/// display +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDceSettings +{ + DceSettingsType type; // Defines which structure is in the union below + union + { + struct + { + bool qualityDetectionEnabled; + } HdmiLq; + struct + { + DpLinkRate linkRate; // Read-only + unsigned int numberOfActiveLanes; // Read-only + unsigned int numberofTotalLanes; // Read-only + int relativePreEmphasis; // Allowable values are -2 to +2 + int relativeVoltageSwing; // Allowable values are -2 to +2 + int persistFlag; + } DpLink; + struct + { + bool linkProtectionEnabled; // Read-only + } Protection; + } Settings; + int iReserved[15]; +} ADLDceSettings; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Graphic Core +/// +/// This structure is used to get Graphic Core Info +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLGraphicCoreInfo +{ + /// indicate the graphic core generation + int iGCGen; + + union + { + /// Total number of CUs. Valid for GCN (iGCGen == GCN) + int iNumCUs; + /// Total number of WGPs. Valid for RDNA (iGCGen == RDNA) + int iNumWGPs; + }; + + union + { + /// Number of processing elements per CU. Valid for GCN (iGCGen == GCN) + int iNumPEsPerCU; + /// Number of processing elements per WGP. Valid for RDNA (iGCGen == RDNA) + int iNumPEsPerWGP; + }; + + /// Total number of SIMDs. Valid for Pre GCN (iGCGen == Pre-GCN) + int iNumSIMDs; + + /// Total number of ROPs. Valid for both GCN and Pre GCN + int iNumROPs; + + /// reserved for future use + int iReserved[11]; +}ADLGraphicCoreInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N clock range +/// +/// This structure is used to store information about Overdrive N clock range +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNParameterRange +{ + /// The starting value of the clock range + int iMode; + /// The starting value of the clock range + int iMin; + /// The ending value of the clock range + int iMax; + /// The minimum increment between clock values + int iStep; + /// The default clock values + int iDefault; +} ADLODNParameterRange; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N capabilities +/// +/// This structure is used to store information about Overdrive N capabilities +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNCapabilities +{ + /// Number of levels which describe the minimum to maximum clock ranges. + /// The 1st level indicates the minimum clocks, and the 2nd level + /// indicates the maximum clocks. + int iMaximumNumberOfPerformanceLevels; + /// Contains the hard limits of the sclk range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange sEngineClockRange; + /// Contains the hard limits of the mclk range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange sMemoryClockRange; + /// Contains the hard limits of the vddc range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange svddcRange; + /// Contains the hard limits of the power range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange power; + /// Contains the hard limits of the power range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange powerTuneTemperature; + /// Contains the hard limits of the Temperature range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange fanTemperature; + /// Contains the hard limits of the Fan range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange fanSpeed; + /// Contains the hard limits of the Fan range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange minimumPerformanceClock; +} ADLODNCapabilities; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N capabilities +/// +/// This structure is used to store information about Overdrive N capabilities +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNCapabilitiesX2 +{ + /// Number of levels which describe the minimum to maximum clock ranges. + /// The 1st level indicates the minimum clocks, and the 2nd level + /// indicates the maximum clocks. + int iMaximumNumberOfPerformanceLevels; + /// bit vector, which tells what are the features are supported. + /// \ref: ADLODNFEATURECONTROL + int iFlags; + /// Contains the hard limits of the sclk range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange sEngineClockRange; + /// Contains the hard limits of the mclk range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange sMemoryClockRange; + /// Contains the hard limits of the vddc range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange svddcRange; + /// Contains the hard limits of the power range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange power; + /// Contains the hard limits of the power range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange powerTuneTemperature; + /// Contains the hard limits of the Temperature range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange fanTemperature; + /// Contains the hard limits of the Fan range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange fanSpeed; + /// Contains the hard limits of the Fan range. Overdrive + /// clocks cannot be set outside this range. + ADLODNParameterRange minimumPerformanceClock; + /// Contains the hard limits of the throttleNotification + ADLODNParameterRange throttleNotificaion; + /// Contains the hard limits of the Auto Systemclock + ADLODNParameterRange autoSystemClock; +} ADLODNCapabilitiesX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive level. +/// +/// This structure is used to store information about Overdrive level. +/// This structure is used by ADLODPerformanceLevels. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNPerformanceLevel +{ + /// clock. + int iClock; + /// VDCC. + int iVddc; + /// enabled + int iEnabled; +} ADLODNPerformanceLevel; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N performance levels. +/// +/// This structure is used to store information about Overdrive performance levels. +/// This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNPerformanceLevels +{ + int iSize; + //Automatic/manual + int iMode; + /// Must be set to sizeof( \ref ADLODPerformanceLevels ) + sizeof( \ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1) + int iNumberOfPerformanceLevels; + /// Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements. + ADLODNPerformanceLevel aLevels[1]; +} ADLODNPerformanceLevels; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N Fan Speed. +/// +/// This structure is used to store information about Overdrive Fan control . +/// This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNFanControl +{ + int iMode; + int iFanControlMode; + int iCurrentFanSpeedMode; + int iCurrentFanSpeed; + int iTargetFanSpeed; + int iTargetTemperature; + int iMinPerformanceClock; + int iMinFanLimit; +} ADLODNFanControl; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N power limit. +/// +/// This structure is used to store information about Overdrive power limit. +/// This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNPowerLimitSetting +{ + int iMode; + int iTDPLimit; + int iMaxOperatingTemperature; +} ADLODNPowerLimitSetting; + +typedef struct ADLODNPerformanceStatus +{ + int iCoreClock; + int iMemoryClock; + int iDCEFClock; + int iGFXClock; + int iUVDClock; + int iVCEClock; + int iGPUActivityPercent; + int iCurrentCorePerformanceLevel; + int iCurrentMemoryPerformanceLevel; + int iCurrentDCEFPerformanceLevel; + int iCurrentGFXPerformanceLevel; + int iUVDPerformanceLevel; + int iVCEPerformanceLevel; + int iCurrentBusSpeed; + int iCurrentBusLanes; + int iMaximumBusLanes; + int iVDDC; + int iVDDCI; +} ADLODNPerformanceStatus; + +///\brief Structure containing information about Overdrive level. +/// +/// This structure is used to store information about Overdrive level. +/// This structure is used by ADLODPerformanceLevels. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNPerformanceLevelX2 +{ + /// clock. + int iClock; + /// VDCC. + int iVddc; + /// enabled + int iEnabled; + /// MASK + int iControl; +} ADLODNPerformanceLevelX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive N performance levels. +/// +/// This structure is used to store information about Overdrive performance levels. +/// This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLODNPerformanceLevelsX2 +{ + int iSize; + //Automatic/manual + int iMode; + /// Must be set to sizeof( \ref ADLODPerformanceLevels ) + sizeof( \ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1) + int iNumberOfPerformanceLevels; + /// Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements. + ADLODNPerformanceLevelX2 aLevels[1]; +} ADLODNPerformanceLevelsX2; + +typedef enum ADLODNCurrentPowerType +{ + ODN_GPU_TOTAL_POWER = 0, + ODN_GPU_PPT_POWER, + ODN_GPU_SOCKET_POWER, + ODN_GPU_CHIP_POWER +} ADLODNCurrentPowerType; + +// in/out: CWDDEPM_CURRENTPOWERPARAMETERS +typedef struct ADLODNCurrentPowerParameters +{ + int size; + ADLODNCurrentPowerType powerType; + int currentPower; +} ADLODNCurrentPowerParameters; + +//ODN Ext range data structure +typedef struct ADLODNExtSingleInitSetting +{ + int mode; + int minValue; + int maxValue; + int step; + int defaultValue; +} ADLODNExtSingleInitSetting; + +//OD8 Ext range data structure +typedef struct ADLOD8SingleInitSetting +{ + int featureID; + int minValue; + int maxValue; + int defaultValue; +} ADLOD8SingleInitSetting; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive8 initial setting +/// +/// This structure is used to store information about Overdrive8 initial setting +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD8InitSetting +{ + int count; + int overdrive8Capabilities; + ADLOD8SingleInitSetting od8SettingTable[OD8_COUNT]; +} ADLOD8InitSetting; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive8 current setting +/// +/// This structure is used to store information about Overdrive8 current setting +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLOD8CurrentSetting +{ + int count; + int Od8SettingTable[OD8_COUNT]; +} ADLOD8CurrentSetting; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Overdrive8 set setting +/// +/// This structure is used to store information about Overdrive8 set setting +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLOD8SingleSetSetting +{ + int value; + int requested; // 0 - default , 1 - requested + int reset; // 0 - do not reset , 1 - reset setting back to default +} ADLOD8SingleSetSetting; + +typedef struct ADLOD8SetSetting +{ + int count; + ADLOD8SingleSetSetting od8SettingTable[OD8_COUNT]; +} ADLOD8SetSetting; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Performance Metrics data +/// +/// This structure is used to store information about Performance Metrics data output +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSingleSensorData +{ + int supported; + int value; +} ADLSingleSensorData; + +typedef struct ADLPMLogDataOutput +{ + int size; + ADLSingleSensorData sensors[ADL_PMLOG_MAX_SENSORS]; +}ADLPMLogDataOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about PPLog settings. +/// +/// This structure is used to store information about PPLog settings. +/// This structure is used by the ADL2_PPLogSettings_Set() and ADL2_PPLogSettings_Get() functions. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPPLogSettings +{ + int BreakOnAssert; + int BreakOnWarn; + int LogEnabled; + int LogFieldMask; + int LogDestinations; + int LogSeverityEnabled; + int LogSourceMask; + int PowerProfilingEnabled; + int PowerProfilingTimeInterval; +}ADLPPLogSettings; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related Frames Per Second for AC and DC. +/// +/// This structure is used to store information related AC and DC Frames Per Second settings +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFPSSettingsOutput +{ + /// size + int ulSize; + /// FPS Monitor is enabled in the AC state if 1 + int bACFPSEnabled; + /// FPS Monitor is enabled in the DC state if 1 + int bDCFPSEnabled; + /// Current Value of FPS Monitor in AC state + int ulACFPSCurrent; + /// Current Value of FPS Monitor in DC state + int ulDCFPSCurrent; + /// Maximum FPS Threshold allowed in PPLib for AC + int ulACFPSMaximum; + /// Minimum FPS Threshold allowed in PPLib for AC + int ulACFPSMinimum; + /// Maximum FPS Threshold allowed in PPLib for DC + int ulDCFPSMaximum; + /// Minimum FPS Threshold allowed in PPLib for DC + int ulDCFPSMinimum; +} ADLFPSSettingsOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related Frames Per Second for AC and DC. +/// +/// This structure is used to store information related AC and DC Frames Per Second settings +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFPSSettingsInput +{ + /// size + int ulSize; + /// Settings are for Global FPS (used by CCC) + int bGlobalSettings; + /// Current Value of FPS Monitor in AC state + int ulACFPSCurrent; + /// Current Value of FPS Monitor in DC state + int ulDCFPSCurrent; + /// Reserved + int ulReserved[6]; +} ADLFPSSettingsInput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related power management logging. +/// +/// This structure is used to store support information for power management logging. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +enum { ADL_PMLOG_MAX_SUPPORTED_SENSORS = 256 }; + +typedef struct ADLPMLogSupportInfo +{ + /// list of sensors defined by ADL_PMLOG_SENSORS + unsigned short usSensors[ADL_PMLOG_MAX_SUPPORTED_SENSORS]; + /// Reserved + int ulReserved[16]; +} ADLPMLogSupportInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information to start power management logging. +/// +/// This structure is used as input to ADL2_Adapter_PMLog_Start +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPMLogStartInput +{ + /// list of sensors defined by ADL_PMLOG_SENSORS + unsigned short usSensors[ADL_PMLOG_MAX_SUPPORTED_SENSORS]; + /// Sample rate in milliseconds + unsigned long ulSampleRate; + /// Reserved + int ulReserved[15]; +} ADLPMLogStartInput; + +typedef struct ADLPMLogData +{ + /// Structure version + unsigned int ulVersion; + /// Current driver sample rate + unsigned int ulActiveSampleRate; + /// Timestamp of last update + unsigned long long ulLastUpdated; + /// 2D array of senesor and values + unsigned int ulValues[ADL_PMLOG_MAX_SUPPORTED_SENSORS][2]; + /// Reserved + unsigned int ulReserved[256]; +} ADLPMLogData; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information to start power management logging. +/// +/// This structure is returned as output from ADL2_Adapter_PMLog_Start +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPMLogStartOutput +{ + /// Pointer to memory address containing logging data + union + { + void* pLoggingAddress; + unsigned long long ptr_LoggingAddress; + }; + /// Reserved + int ulReserved[14]; +} ADLPMLogStartOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information to query limts of power management logging. +/// +/// This structure is returned as output from ADL2_Adapter_PMLog_SensorLimits_Get +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLPMLogSensorLimits +{ + int SensorLimits[ADL_PMLOG_MAX_SENSORS][2]; //index 0: min, 1: max +} ADLPMLogSensorLimits; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Get Error Counts Information +/// +/// This structure is used to store RAS Error Counts Get Input Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASGetErrorCountsInput +{ + unsigned int Reserved[16]; +} ADLRASGetErrorCountsInput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Get Error Counts Information +/// +/// This structure is used to store RAS Error Counts Get Output Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASGetErrorCountsOutput +{ + unsigned int CorrectedErrors; // includes both DRAM and SRAM ECC + unsigned int UnCorrectedErrors; // includes both DRAM and SRAM ECC + unsigned int Reserved[14]; +} ADLRASGetErrorCountsOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Get Error Counts Information +/// +/// This structure is used to store RAS Error Counts Get Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASGetErrorCounts +{ + unsigned int InputSize; + ADLRASGetErrorCountsInput Input; + unsigned int OutputSize; + ADLRASGetErrorCountsOutput Output; +} ADLRASGetErrorCounts; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Counts Reset Information +/// +/// This structure is used to store RAS Error Counts Reset Input Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASResetErrorCountsInput +{ + unsigned int Reserved[8]; +} ADLRASResetErrorCountsInput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Counts Reset Information +/// +/// This structure is used to store RAS Error Counts Reset Output Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASResetErrorCountsOutput +{ + unsigned int Reserved[8]; +} ADLRASResetErrorCountsOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Counts Reset Information +/// +/// This structure is used to store RAS Error Counts Reset Information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASResetErrorCounts +{ + unsigned int InputSize; + ADLRASResetErrorCountsInput Input; + unsigned int OutputSize; + ADLRASResetErrorCountsOutput Output; +} ADLRASResetErrorCounts; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Injection information +/// +/// This structure is used to store RAS Error Injection input information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASErrorInjectonInput +{ + unsigned long long Address; + ADL_RAS_INJECTION_METHOD Value; + ADL_RAS_BLOCK_ID BlockId; + ADL_RAS_ERROR_TYPE InjectErrorType; + ADL_MEM_SUB_BLOCK_ID SubBlockIndex; + unsigned int padding[9]; +} ADLRASErrorInjectonInput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Injection information +/// +/// This structure is used to store RAS Error Injection output information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASErrorInjectionOutput +{ + unsigned int ErrorInjectionStatus; + unsigned int padding[15]; +} ADLRASErrorInjectionOutput; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related RAS Error Injection information +/// +/// This structure is used to store RAS Error Injection information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLRASErrorInjection +{ + unsigned int InputSize; + ADLRASErrorInjectonInput Input; + unsigned int OutputSize; + ADLRASErrorInjectionOutput Output; +} ADLRASErrorInjection; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about an application +/// +/// This structure is used to store basic information of a recently ran or currently running application +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSGApplicationInfo +{ + /// Application file name + wchar_t strFileName[ADL_MAX_PATH]; + /// Application file path + wchar_t strFilePath[ADL_MAX_PATH]; + /// Application version + wchar_t strVersion[ADL_MAX_PATH]; + /// Timestamp at which application has run + long long int timeStamp; + /// Holds whether the applicaition profile exists or not + unsigned int iProfileExists; + /// The GPU on which application runs + unsigned int iGPUAffinity; + /// The BDF of the GPU on which application runs + ADLBdf GPUBdf; +} ADLSGApplicationInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related Frames Per Second for AC and DC. +/// +/// This structure is used to store information related AC and DC Frames Per Second settings +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +enum { ADLPreFlipPostProcessingInfoInvalidLUTIndex = 0xFFFFFFFF }; + +enum ADLPreFlipPostProcessingLUTAlgorithm +{ + ADLPreFlipPostProcessingLUTAlgorithm_Default = 0, + ADLPreFlipPostProcessingLUTAlgorithm_Full, + ADLPreFlipPostProcessingLUTAlgorithm_Approximation +}; + +typedef struct ADLPreFlipPostProcessingInfo +{ + /// size + int ulSize; + /// Current active state + int bEnabled; + /// Current selected LUT index. 0xFFFFFFF returned if nothing selected. + int ulSelectedLUTIndex; + /// Current selected LUT Algorithm + int ulSelectedLUTAlgorithm; + /// Reserved + int ulReserved[12]; +} ADLPreFlipPostProcessingInfo; + +typedef struct ADL_ERROR_REASON +{ + int boost; //ON, when boost is Enabled + int delag; //ON, when delag is Enabled + int chill; //ON, when chill is Enabled + int proVsr; //ON, when proVsr is Enabled +}ADL_ERROR_REASON; + +typedef struct ADL_ERROR_REASON2 +{ + int boost; //ON, when boost is Enabled + int delag; //ON, when delag is Enabled + int chill; //ON, when chill is Enabled + int proVsr; //ON, when proVsr is Enabled + int upscale; //ON, when RSR is Enabled +}ADL_ERROR_REASON2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about DELAG Settings change reason +/// +/// Elements of DELAG settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_DELAG_NOTFICATION_REASON +{ + int HotkeyChanged; //Set when Hotkey value is changed + int GlobalEnableChanged; //Set when Global enable value is changed + int GlobalLimitFPSChanged; //Set when Global enable value is changed +}ADL_DELAG_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about DELAG Settings +/// +/// Elements of DELAG settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_DELAG_SETTINGS +{ + int Hotkey; // Hotkey value + int GlobalEnable; //Global enable value + int GlobalLimitFPS; //Global Limit FPS + int GlobalLimitFPS_MinLimit; //Gloabl Limit FPS slider min limit value + int GlobalLimitFPS_MaxLimit; //Gloabl Limit FPS slider max limit value + int GlobalLimitFPS_Step; //Gloabl Limit FPS step value +}ADL_DELAG_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about BOOST Settings change reason +/// +/// Elements of BOOST settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_BOOST_NOTFICATION_REASON +{ + int HotkeyChanged; //Set when Hotkey value is changed + int GlobalEnableChanged; //Set when Global enable value is changed + int GlobalMinResChanged; //Set when Global min resolution value is changed +}ADL_BOOST_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about BOOST Settings +/// +/// Elements of BOOST settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_BOOST_SETTINGS +{ + int Hotkey; // Hotkey value + int GlobalEnable; //Global enable value + int GlobalMinRes; //Gloabl Min Resolution value + int GlobalMinRes_MinLimit; //Gloabl Min Resolution slider min limit value + int GlobalMinRes_MaxLimit; //Gloabl Min Resolution slider max limit value + int GlobalMinRes_Step; //Gloabl Min Resolution step value +}ADL_BOOST_SETTINGS; + + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about ProVSR Settings change reason +/// +/// Elements of ProVSR settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_PROVSR_NOTFICATION_REASON +{ + int HotkeyChanged; //Set when Hotkey value is changed + int GlobalEnableChanged; //Set when Global enable value is changed +}ADL_PROVSR_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Pro VSR Settings +/// +/// Elements of ProVSR settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_PROVSR_SETTINGS +{ + int Hotkey; // Hotkey value + int GlobalEnable; //Global enable value +}ADL_PROVSR_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about Image Boost(OGL) Settings change reason +/// +/// Elements of Image Boost settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_IMAGE_BOOST_NOTFICATION_REASON +{ + int HotkeyChanged; //Set when Hotkey value is changed + int GlobalEnableChanged; //Set when Global enable value is changed +}ADL_IMAGE_BOOST_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about OGL IMAGE BOOST Settings +/// +/// Elements of OGL IMAGE BOOST settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_IMAGE_BOOST_SETTINGS +{ + int Hotkey; // Hotkey value + int GlobalEnable; //Global enable value +}ADL_IMAGE_BOOST_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about RIS Settings change reason +/// +/// Elements of RIS settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RIS_NOTFICATION_REASON +{ + unsigned int GlobalEnableChanged; //Set when Global enable value is changed + unsigned int GlobalSharpeningDegreeChanged; //Set when Global sharpening Degree value is changed +}ADL_RIS_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about RIS Settings +/// +/// Elements of RIS settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RIS_SETTINGS +{ + int GlobalEnable; //Global enable value + int GlobalSharpeningDegree; //Global sharpening value + int GlobalSharpeningDegree_MinLimit; //Gloabl sharpening slider min limit value + int GlobalSharpeningDegree_MaxLimit; //Gloabl sharpening slider max limit value + int GlobalSharpeningDegree_Step; //Gloabl sharpening step value +}ADL_RIS_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about CHILL Settings change reason +/// +/// Elements of Chiil settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_CHILL_NOTFICATION_REASON +{ + int HotkeyChanged; //Set when Hotkey value is changed + int GlobalEnableChanged; //Set when Global enable value is changed + int GlobalMinFPSChanged; //Set when Global min FPS value is changed + int GlobalMaxFPSChanged; //Set when Global max FPS value is changed +}ADL_CHILL_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about CHILL Settings +/// +/// Elements of Chill settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_CHILL_SETTINGS +{ + int Hotkey; // Hotkey value + int GlobalEnable; //Global enable value + int GlobalMinFPS; //Global Min FPS value + int GlobalMaxFPS; //Global Max FPS value + int GlobalFPS_MinLimit; //Gloabl FPS slider min limit value + int GlobalFPS_MaxLimit; //Gloabl FPS slider max limit value + int GlobalFPS_Step; //Gloabl FPS Slider step value +}ADL_CHILL_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about DRIVERUPSCALE Settings change reason +/// +/// Elements of DRIVERUPSCALE settings changed reason. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_DRIVERUPSCALE_NOTFICATION_REASON +{ + int ModeOverrideEnabledChanged; //Set when Global min resolution value is changed + int GlobalEnabledChanged; //Set when Global enable value is changed +}ADL_DRIVERUPSCALE_NOTFICATION_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about DRIVERUPSCALE Settings +/// +/// Elements of DRIVERUPSCALE settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_DRIVERUPSCALE_SETTINGS +{ + int ModeOverrideEnabled; + int GlobalEnabled; +}ADL_DRIVERUPSCALE_SETTINGS; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure Containing R G B values for Radeon USB LED Bar +/// +/// Elements of RGB Values. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RADEON_LED_COLOR_CONFIG +{ + unsigned short R : 8; // Red Value + unsigned short G : 8; // Green Value + unsigned short B : 8; // Blue Value +}ADL_RADEON_LED_COLOR_CONFIG; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure Containing All Generic LED configuration for user requested LED pattern. The driver will apply the confgiuration as requested +/// +/// Elements of Radeon USB LED configuration. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RADEON_LED_PATTERN_CONFIG_GENERIC +{ + short brightness : 8; // Brightness of LED + short speed : 8; // Speed of LED pattern + bool directionCounterClockWise; //Direction of LED Pattern + ADL_RADEON_LED_COLOR_CONFIG colorConfig; // RGB value of LED pattern + char morseCodeText[ADL_RADEON_LED_MAX_MORSE_CODE]; // Morse Code user input for Morse Code LED pattern + char morseCodeTextOutPut[ADL_RADEON_LED_MAX_MORSE_CODE]; // Driver set output representation of Morse Code + int morseCodeTextOutPutLen; // Length of Morse Code output +}ADL_RADEON_LED_PATTERN_CONFIG_GENERIC; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure Containing All custom grid pattern LED configuration for user requested LED grid pattern. The driver will apply the confgiuration as requested +/// +/// Elements of Radeon USB LED custom grid configuration. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RADEON_LED_CUSTOM_LED_CONFIG +{ + short brightness : 8; // Brightness of LED + ADL_RADEON_LED_COLOR_CONFIG colorConfig[ADL_RADEON_LED_MAX_LED_ROW_ON_GRID][ADL_RADEON_LED_MAX_LED_COLUMN_ON_GRID]; // Full grid array representation of Radeon LED to be populated by user +}ADL_RADEON_LED_CUSTOM_GRID_LED_CONFIG; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure Containing All Radeon USB LED requests and controls. +/// +/// Elements of Radeon USB LED Controls. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_RADEON_LED_PATTERN_CONFIG +{ + ADL_RADEON_USB_LED_BAR_CONTROLS control; //Requested LED pattern + + union + { + ADL_RADEON_LED_PATTERN_CONFIG_GENERIC genericPararmeters; //Requested pattern configuration settings + ADL_RADEON_LED_CUSTOM_GRID_LED_CONFIG customGridConfig; //Requested custom grid configuration settings + }; +}ADL_RADEON_LED_PATTERN_CONFIG; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about the graphics adapter with extended caps +/// +/// This structure is used to store various information about the graphics adapter. This +/// information can be returned to the user. Alternatively, it can be used to access various driver calls to set +/// or fetch various settings upon the user's request. +/// This AdapterInfoX2 struct extends the AdapterInfo struct in adl_structures.h +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct AdapterInfoX2 +{ + /// \ALL_STRUCT_MEM + + /// Size of the structure. + int iSize; + /// The ADL index handle. One GPU may be associated with one or two index handles + int iAdapterIndex; + /// The unique device ID associated with this adapter. + char strUDID[ADL_MAX_PATH]; + /// The BUS number associated with this adapter. + int iBusNumber; + /// The driver number associated with this adapter. + int iDeviceNumber; + /// The function number. + int iFunctionNumber; + /// The vendor ID associated with this adapter. + int iVendorID; + /// Adapter name. + char strAdapterName[ADL_MAX_PATH]; + /// Display name. For example, "\\\\Display0" + char strDisplayName[ADL_MAX_PATH]; + /// Present or not; 1 if present and 0 if not present.It the logical adapter is present, the display name such as \\\\.\\Display1 can be found from OS + int iPresent; + /// Exist or not; 1 is exist and 0 is not present. + int iExist; + /// Driver registry path. + char strDriverPath[ADL_MAX_PATH]; + /// Driver registry path Ext for. + char strDriverPathExt[ADL_MAX_PATH]; + /// PNP string from Windows. + char strPNPString[ADL_MAX_PATH]; + /// It is generated from EnumDisplayDevices. + int iOSDisplayIndex; + /// The bit mask identifies the adapter info + int iInfoMask; + /// The bit identifies the adapter info \ref define_adapter_info + int iInfoValue; +} AdapterInfoX2, *LPAdapterInfoX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver gamut space , whether it is related to source or to destination, overlay or graphics +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLGamutReference +{ + /// mask whether it is related to source or to destination, overlay or graphics + int iGamutRef; +}ADLGamutReference; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver supported gamut spaces , capability method +/// +/// This structure is used to get driver all supported gamut spaces +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLGamutInfo +{ + ///Any combination of following ADL_GAMUT_SPACE_CCIR_709 - ADL_GAMUT_SPACE_CUSTOM + int SupportedGamutSpace; + + ///Any combination of following ADL_WHITE_POINT_5000K - ADL_WHITE_POINT_CUSTOM + int SupportedWhitePoint; +} ADLGamutInfo; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver point coordinates +/// +/// This structure is used to store the driver point coodinates for gamut and white point +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLPoint +{ + /// x coordinate + int iX; + /// y coordinate + int iY; +} ADLPoint; +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver supported gamut coordinates +/// +/// This structure is used to store the driver supported supported gamut coordinates +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLGamutCoordinates +{ + /// red channel chromasity coordinate + ADLPoint Red; + /// green channel chromasity coordinate + ADLPoint Green; + /// blue channel chromasity coordinate + ADLPoint Blue; +} ADLGamutCoordinates; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about driver current gamut space , parent struct for ADLGamutCoordinates and ADLWhitePoint +/// This structure is used to get/set driver supported gamut space +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLGamutData +{ + ///used as mask and could be 4 options + ///BIT_0 If flag ADL_GAMUT_REFERENCE_SOURCE is asserted set operation is related to gamut source , + ///if not gamut destination + ///BIT_1 If flag ADL_GAMUT_GAMUT_VIDEO_CONTENT is asserted + ///BIT_2,BIT_3 used as mask and could be 4 options custom (2) + predefined (2) + ///0. Gamut predefined, white point predefined -> 0 | 0 + ///1. Gamut predefined, white point custom -> 0 | ADL_CUSTOM_WHITE_POINT + ///2. White point predefined, gamut custom -> 0 | ADL_CUSTOM_GAMUT + ///3. White point custom, gamut custom -> ADL_CUSTOM_GAMUT | ADL_CUSTOM_WHITE_POINT + int iFeature; + + ///one of ADL_GAMUT_SPACE_CCIR_709 - ADL_GAMUT_SPACE_CIE_RGB + int iPredefinedGamut; + + ///one of ADL_WHITE_POINT_5000K - ADL_WHITE_POINT_9300K + int iPredefinedWhitePoint; + + ///valid when in mask avails ADL_CUSTOM_WHITE_POINT + ADLPoint CustomWhitePoint; + + ///valid when in mask avails ADL_CUSTOM_GAMUT + ADLGamutCoordinates CustomGamut; +} ADLGamutData; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing detailed timing parameters. +/// +/// This structure is used to store the detailed timing parameters. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDetailedTimingX2 +{ + /// Size of the structure. + int iSize; + /// Timing flags. \ref define_detailed_timing_flags + int sTimingFlags; + /// Total width (columns). + int sHTotal; + /// Displayed width. + int sHDisplay; + /// Horizontal sync signal offset. + int sHSyncStart; + /// Horizontal sync signal width. + int sHSyncWidth; + /// Total height (rows). + int sVTotal; + /// Displayed height. + int sVDisplay; + /// Vertical sync signal offset. + int sVSyncStart; + /// Vertical sync signal width. + int sVSyncWidth; + /// Pixel clock value. + int sPixelClock; + /// Overscan right. + short sHOverscanRight; + /// Overscan left. + short sHOverscanLeft; + /// Overscan bottom. + short sVOverscanBottom; + /// Overscan top. + short sVOverscanTop; + short sOverscan8B; + short sOverscanGR; +} ADLDetailedTimingX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing display mode information. +/// +/// This structure is used to store the display mode information. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLDisplayModeInfoX2 +{ + /// Timing standard of the current mode. \ref define_modetiming_standard + int iTimingStandard; + /// Applicable timing standards for the current mode. + int iPossibleStandard; + /// Refresh rate factor. + int iRefreshRate; + /// Num of pixels in a row. + int iPelsWidth; + /// Num of pixels in a column. + int iPelsHeight; + /// Detailed timing parameters. + ADLDetailedTimingX2 sDetailedTiming; +} ADLDisplayModeInfoX2; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about I2C. +/// +/// This structure is used to store the I2C information for the current adapter. +/// This structure is used by \ref ADL_Display_WriteAndReadI2CLargePayload +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLI2CLargePayload +{ + /// Size of the structure + int iSize; + /// Numerical value representing hardware I2C. + int iLine; + /// The 7-bit I2C slave device address. + int iAddress; + /// The offset of the data from the address. + int iOffset; + /// Read from or write to slave device. \ref ADL_DL_I2C_ACTIONREAD or \ref ADL_DL_I2C_ACTIONWRITE + int iAction; + /// I2C clock speed in KHz. + int iSpeed; + /// I2C option flags. \ref define_ADLI2CLargePayload + int iFlags; + /// A numerical value representing the number of bytes to be sent or received on the I2C bus. + int iDataSize; + /// Address of the characters which are to be sent or received on the I2C bus. + char *pcData; +} ADLI2CLargePayload; + +/// Size in bytes of the Feature Name +#define ADL_FEATURE_NAME_LENGTH 16 + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing the Multimedia Feature Name +/// +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFeatureName +{ + /// The Feature Name + char FeatureName[ADL_FEATURE_NAME_LENGTH]; +} ADLFeatureName, *LPADLFeatureName; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about MM Feature Capabilities. +/// +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFeatureCaps +{ + /// The Feature Name + ADLFeatureName Name; + // char strFeatureName[ADL_FEATURE_NAME_LENGTH]; + + /// Group ID. All Features in the same group are shown sequentially in the same UI Page. + int iGroupID; + + /// Visual ID. Places one or more features in a Group Box. If zero, no Group Box is added. + int iVisualID; + + /// Page ID. All Features with the same Page ID value are shown together on the same UI page. + int iPageID; + + /// Feature Property Mask. Indicates which are the valid bits for iFeatureProperties. + int iFeatureMask; + + /// Feature Property Values. See definitions for ADL_FEATURE_PROPERTIES_XXX + int iFeatureProperties; + + /// Apperance of the User-Controlled Boolean. + int iControlType; + + /// Style of the User-Controlled Boolean. + int iControlStyle; + + /// Apperance of the Adjustment Controls. + int iAdjustmentType; + + /// Style of the Adjustment Controls. + int iAdjustmentStyle; + + /// Default user-controlled boolean value. Valid only if ADLFeatureCaps supports user-controlled boolean. + int bDefault; + + /// Minimum integer value. Valid only if ADLFeatureCaps indicates support for integers. + int iMin; + + /// Maximum integer value. Valid only if ADLFeatureCaps indicates support for integers. + int iMax; + + /// Step integer value. Valid only if ADLFeatureCaps indicates support for integers. + int iStep; + + /// Default integer value. Valid only if ADLFeatureCaps indicates support for integers. + int iDefault; + + /// Minimum float value. Valid only if ADLFeatureCaps indicates support for floats. + float fMin; + + /// Maximum float value. Valid only if ADLFeatureCaps indicates support for floats. + float fMax; + + /// Step float value. Valid only if ADLFeatureCaps indicates support for floats. + float fStep; + + /// Default float value. Valid only if ADLFeatureCaps indicates support for floats. + float fDefault; + + /// The Mask for available bits for enumerated values.(If ADLFeatureCaps supports ENUM values) + int EnumMask; +} ADLFeatureCaps, *LPADLFeatureCaps; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about MM Feature Values. +/// +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLFeatureValues +{ + /// The Feature Name + ADLFeatureName Name; + // char strFeatureName[ADL_FEATURE_NAME_LENGTH]; + + /// User controlled Boolean current value. Valid only if ADLFeatureCaps supports Boolean. + int bCurrent; + + /// Current integer value. Valid only if ADLFeatureCaps indicates support for integers. + int iCurrent; + + /// Current float value. Valid only if ADLFeatureCaps indicates support for floats. + float fCurrent; + + /// The States for the available bits for enumerated values. + int EnumStates; +} ADLFeatureValues, *LPADLFeatureValues; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing HDCP Settings info +/// +/// This structure is used to store the HDCP settings of a +/// display +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLHDCPSettings +{ + int iHDCPProtectionVersion; // Version, starting from 1 + int iHDCPCaps; //Caps used to ensure at least one protection scheme is supported, 1 is HDCP1X and 2 is HDCP22 + int iAllowAll; //Allow all is true, disable all is false + int iHDCPVale; + int iHDCPMask; +} ADLHDCPSettings; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing Mantle App info +/// +/// This structure is used to store the Mantle Driver information +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// + +typedef struct ADLMantleAppInfo +{ + /// mantle api version + int apiVersion; + /// mantle driver version + long driverVersion; + /// mantle vendroe id + long vendorId; + /// mantle device id + long deviceId; + /// mantle gpu type; + int gpuType; + /// gpu name + char gpuName[256]; + /// mem size + int maxMemRefsPerSubmission; + /// virtual mem size + long long virtualMemPageSize; + /// mem update + long long maxInlineMemoryUpdateSize; + /// bound descriptot + long maxBoundDescriptorSets; + /// thread group size + long maxThreadGroupSize; + /// time stamp frequency + long long timestampFrequency; + /// color target + long multiColorTargetClears; +}ADLMantleAppInfo, *LPADLMantleAppInfo; + +//////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about SDIData +///This structure is used to store information about the state of the SDI whether it is on +///or off and the current size of the segment or aperture size. +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSDIData +{ + /// The SDI state, ADL_SDI_ON or ADL_SDI_OFF, for the current SDI mode + int iSDIState; + /// Size of the memory segment for SDI (in MB). + int iSizeofSDISegment; +} ADLSDIData, *LPADLSDIData; + + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about FRTCPRO Settings +/// +/// Elements of FRTCPRO settings. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_FRTCPRO_Settings +{ + int DefaultState; //The default status for FRTC pro + int CurrentState; //The current enable/disable status for FRTC pro + unsigned int DefaultValue; //The default FPS value for FRTC pro. + unsigned int CurrentValue; //The current FPS value for FRTC pro. + unsigned int maxSupportedFps; //The max value for FRTC pro. + unsigned int minSupportedFps; //The min value for FRTC pro. +}ADL_FRTCPRO_Settings, *LPADLFRTCProSettings; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information about FRTCPRO Settings changed reason +/// +/// Reason of FRTCPRO changed. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_FRTCPRO_CHANGED_REASON +{ + int StateChanged; // FRTCPro state changed + int ValueChanged; // FRTCPro value changed +}ADL_FRTCPRO_CHANGED_REASON; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure containing the display mode definition used per controller. +/// +/// This structure is used to store the display mode definition used per controller. +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADL_DL_DISPLAY_MODE +{ + int iPelsHeight; // Vertical resolution (in pixels). + int iPelsWidth; // Horizontal resolution (in pixels). + int iBitsPerPel; // Color depth. + int iDisplayFrequency; // Refresh rate. +} ADL_DL_DISPLAY_MODE; + +///////////////////////////////////////////////////////////////////////////////////////////// +///\brief Structure containing information related DCE support +/// +/// This structure is used to store a bit vector of possible DCE support +/// +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef union _ADLDCESupport +{ + struct + { + unsigned int PrePhasis : 1; + unsigned int voltageSwing : 1; + unsigned int reserved : 30; + }bits; + unsigned int u32All; +}ADLDCESupport; + +///////////////////////////////////////////////////////////////////////////////////////////// +/// \brief Structure for Smart shift 2.0 settings +/// +/// This structure is used to return the smart shift settings +/// \nosubgrouping +//////////////////////////////////////////////////////////////////////////////////////////// +typedef struct ADLSmartShiftSettings +{ + int iMinRange; + int iMaxRange; + int iDefaultMode; //Refer to CWDDEPM_ODN_CONTROL_TYPE + int iDefaultValue; + int iCurrentMode; + int iCurrentValue; + int iFlags; //refer to define_smartshift_bits +}ADLSmartShiftSettings, *LPADLSmartShiftSettings; +#endif /* ADL_STRUCTURES_H_ */ diff --git a/atiadlxx-sys/include/display.h b/atiadlxx-sys/include/display.h new file mode 100644 index 0000000..acdc393 --- /dev/null +++ b/atiadlxx-sys/include/display.h @@ -0,0 +1,573 @@ +#ifndef DISPLAY_H_ +#define DISPLAY_H_ + + +#include "adl_structures.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + + + +ADL_EXTERNC int EXPOSED ADL2_Display_VirtualType_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADL_VIRTUALDISPLAY_TYPE *iVirtualType); + +ADL_EXTERNC int EXPOSED ADL2_Display_WriteAndReadI2CLargePayload(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLI2CLargePayload *plI2C); + +ADL_EXTERNC int EXPOSED ADL_Display_WriteAndReadI2CLargePayload(int iAdapterIndex, ADLI2CLargePayload *plI2C); + +ADL_EXTERNC int EXPOSED ADL2_Display_HDCP_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLHDCPSettings *lpHDCPSettings); + +ADL_EXTERNC int EXPOSED ADL2_Display_HDCP_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int iSetToDefault, int iEnable); + +ADL_EXTERNC int EXPOSED ADL2_Display_HDRState_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int *iSupport, int *iEnable); + +ADL_EXTERNC int EXPOSED ADL2_Display_HDRState_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int iEnable); + +ADL_EXTERNC int EXPOSED ADL2_Display_Limits_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int* lpMaxHRes, int* lpMaxVRes, int* lpMaxRefresh); + +ADL_EXTERNC int EXPOSED ADL2_Display_PreferredMode_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int* lpNumModes, ADLMode** lppModes); + +ADL_EXTERNC int EXPOSED ADL_Display_Limits_Get(int iAdapterIndex, int iDisplayIndex, int* lpMaxHRes, int* lpMaxVRes, int* lpMaxRefresh); + +ADL_EXTERNC int EXPOSED ADL2_Display_DisplayInfo_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, + int* lpNumDisplays, + ADLDisplayInfo ** lppInfo, + int iForceDetect); + +ADL_EXTERNC int EXPOSED ADL_Display_DisplayInfo_Get (int iAdapterIndex, + int* lpNumDisplays, + ADLDisplayInfo ** lppInfo, + int iForceDetect); + +ADL_EXTERNC int EXPOSED ADL2_Display_DpMstInfo_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, + int* lpNumDisplays, + ADLDisplayDPMSTInfo ** lppDisplayDPMstInfo, + int iForceDetect); + +ADL_EXTERNC int EXPOSED ADL_Display_DpMstInfo_Get (int iAdapterIndex, + int* lpNumDisplays, + ADLDisplayDPMSTInfo ** lppDisplayDPMstInfo, + int iForceDetect); + + +ADL_EXTERNC int EXPOSED ADL2_Display_NumberOfDisplays_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpNumDisplays); + +ADL_EXTERNC int EXPOSED ADL_Display_NumberOfDisplays_Get(int iAdapterIndex, int *lpNumDisplays); + +ADL_EXTERNC int EXPOSED ADL2_Display_PreservedAspectRatio_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpSupport, int * lpCurrent, int * lpDefault); + +ADL_EXTERNC int EXPOSED ADL_Display_PreservedAspectRatio_Get(int iAdapterIndex, int iDisplayIndex, int* lpSupport, int * lpCurrent, int * lpDefault); + + +ADL_EXTERNC int EXPOSED ADL2_Display_PreservedAspectRatio_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_PreservedAspectRatio_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_ImageExpansion_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpSupport, int * lpCurrent, int * lpDefault); + +ADL_EXTERNC int EXPOSED ADL_Display_ImageExpansion_Get(int iAdapterIndex, int iDisplayIndex, int* lpSupport, int * lpCurrent, int * lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_Display_ImageExpansion_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_ImageExpansion_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_Position_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpX, int* lpY, int* lpXDefault, int* lpYDefault, + int* lpMinX, int* lpMinY, int* lpMaxX, int*lpMaxY, int* lpStepX, int* lpStepY); + +ADL_EXTERNC int EXPOSED ADL_Display_Position_Get(int iAdapterIndex, int iDisplayIndex, int* lpX, int* lpY, int* lpXDefault, int* lpYDefault, + int* lpMinX, int* lpMinY, int* lpMaxX, int*lpMaxY, int* lpStepX, int* lpStepY); + + +ADL_EXTERNC int EXPOSED ADL2_Display_Position_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iX, int iY); + +ADL_EXTERNC int EXPOSED ADL_Display_Position_Set(int iAdapterIndex, int iDisplayIndex, int iX, int iY); + +ADL_EXTERNC int EXPOSED ADL2_Display_Size_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpWidth, int* lpHeight, int* lpDefaultWidth, int* lpDefaultHeight, + int* lpMinWidth, int* lpMinHeight, int* lpMaxWidth, int*lpMaxHeight, int* lpStepWidth, int* lpStepHeight); + +ADL_EXTERNC int EXPOSED ADL_Display_Size_Get(int iAdapterIndex, int iDisplayIndex, int* lpWidth, int* lpHeight, int* lpDefaultWidth, int* lpDefaultHeight, + int* lpMinWidth, int* lpMinHeight, int* lpMaxWidth, int*lpMaxHeight, int* lpStepWidth, int* lpStepHeight); + +ADL_EXTERNC int EXPOSED ADL2_Display_Size_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iWidth, int iHeight); + +ADL_EXTERNC int EXPOSED ADL_Display_Size_Set(int iAdapterIndex, int iDisplayIndex, int iWidth, int iHeight); + +ADL_EXTERNC int EXPOSED ADL2_Display_AdjustCaps_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpInfo); + +ADL_EXTERNC int EXPOSED ADL_Display_AdjustCaps_Get(int iAdapterIndex, int iDisplayIndex, int* lpInfo); + +ADL_EXTERNC int EXPOSED ADL2_Display_Capabilities_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpNumberOfControlers, int* lpNumberOfDisplays); + +ADL_EXTERNC int EXPOSED ADL_Display_Capabilities_Get(int iAdapterIndex, int* lpNumberOfControlers, int* lpNumberOfDisplays); + +ADL_EXTERNC int EXPOSED ADL2_Display_ConnectedDisplays_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int * lpConnections); + +ADL_EXTERNC int EXPOSED ADL_Display_ConnectedDisplays_Get(int iAdapterIndex, int * lpConnections); + +ADL_EXTERNC int EXPOSED ADL2_Display_DeviceConfig_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayConfig * lpDisplayConfig); + +ADL_EXTERNC int EXPOSED ADL_Display_DeviceConfig_Get(int iAdapterIndex, int iDisplayIndex, ADLDisplayConfig * lpDisplayConfig); + +ADL_EXTERNC int EXPOSED ADL2_Display_Property_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayProperty * lpDisplayProperty); + +ADL_EXTERNC int EXPOSED ADL_Display_Property_Get(int iAdapterIndex, int iDisplayIndex, ADLDisplayProperty * lpDisplayProperty); + +ADL_EXTERNC int EXPOSED ADL2_Display_Property_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayProperty * lpDisplayProperty); + +ADL_EXTERNC int EXPOSED ADL_Display_Property_Set(int iAdapterIndex, int iDisplayIndex, ADLDisplayProperty * lpDisplayProperty); + + +ADL_EXTERNC int EXPOSED ADL2_Display_SwitchingCapability_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpResult); + +ADL_EXTERNC int EXPOSED ADL_Display_SwitchingCapability_Get(int iAdapterIndex, int *lpResult); + +ADL_EXTERNC int EXPOSED ADL2_Display_DitherState_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpDitherState); + +ADL_EXTERNC int EXPOSED ADL_Display_DitherState_Get(int iAdapterIndex, int iDisplayIndex, int *lpDitherState); + +ADL_EXTERNC int EXPOSED ADL2_Display_DitherState_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iDitherState); + +ADL_EXTERNC int EXPOSED ADL_Display_DitherState_Set(int iAdapterIndex, int iDisplayIndex, int iDitherState); + +ADL_EXTERNC int EXPOSED ADL2_Display_SupportedPixelFormat_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpPixelFormat); + +ADL_EXTERNC int EXPOSED ADL_Display_SupportedPixelFormat_Get(int iAdapterIndex, int iDisplayIndex, int *lpPixelFormat); + +ADL_EXTERNC int EXPOSED ADL2_Display_PixelFormat_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpPixelFormat); + +ADL_EXTERNC int EXPOSED ADL_Display_PixelFormat_Get(int iAdapterIndex, int iDisplayIndex, int *lpPixelFormat); + +ADL_EXTERNC int EXPOSED ADL2_Display_PixelFormatDefault_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int *lpDefPixelFormat); + +ADL_EXTERNC int EXPOSED ADL2_Display_PixelFormat_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iPixelFormat); + +ADL_EXTERNC int EXPOSED ADL_Display_PixelFormat_Set(int iAdapterIndex, int iDisplayIndex, int iPixelFormat); + +ADL_EXTERNC int EXPOSED ADL2_Display_SupportedColorDepth_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int *lpColorDepth); + +ADL_EXTERNC int EXPOSED ADL_Display_SupportedColorDepth_Get(int iAdapterIndex, int iDisplayIndex, int *lpColorDepth); + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorDepth_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int *lpColorDepth); + +ADL_EXTERNC int EXPOSED ADL_Display_ColorDepth_Get(int iAdapterIndex, int iDisplayIndex, int *lpColorDepth); + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorDepth_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int iColorDepth); + +ADL_EXTERNC int EXPOSED ADL_Display_ColorDepth_Set(int iAdapterIndex, int iDisplayIndex, int iColorDepth); + +ADL_EXTERNC int EXPOSED ADL2_Display_ODClockInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLAdapterODClockInfo *lpOdClockInfo); + +ADL_EXTERNC int EXPOSED ADL_Display_ODClockInfo_Get(int iAdapterIndex, ADLAdapterODClockInfo *lpOdClockInfo); + +ADL_EXTERNC int EXPOSED ADL2_Display_ODClockConfig_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLAdapterODClockConfig *lpOdClockConfig); + +ADL_EXTERNC int EXPOSED ADL_Display_ODClockConfig_Set(int iAdapterIndex, ADLAdapterODClockConfig *lpOdClockConfig); + +ADL_EXTERNC int EXPOSED ADL2_Display_AdjustmentCoherent_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpAdjustmentCoherentCurrent, int *lpAdjustmentCoherentDefault); + +ADL_EXTERNC int EXPOSED ADL_Display_AdjustmentCoherent_Get(int iAdapterIndex, int iDisplayIndex, int *lpAdjustmentCoherentCurrent, int *lpAdjustmentCoherentDefault); + +ADL_EXTERNC int EXPOSED ADL2_Display_AdjustmentCoherent_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iAdjustmentCoherent); + +ADL_EXTERNC int EXPOSED ADL_Display_AdjustmentCoherent_Set(int iAdapterIndex, int iDisplayIndex, int iAdjustmentCoherent); + +ADL_EXTERNC int EXPOSED ADL2_Display_ReducedBlanking_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpReducedBlankingCurrent, int *lpReducedBlankingDefault); + +ADL_EXTERNC int EXPOSED ADL_Display_ReducedBlanking_Get(int iAdapterIndex, int iDisplayIndex, int *lpReducedBlankingCurrent, int *lpReducedBlankingDefault); + +ADL_EXTERNC int EXPOSED ADL2_Display_ReducedBlanking_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iReducedBlanking); + +ADL_EXTERNC int EXPOSED ADL_Display_ReducedBlanking_Set(int iAdapterIndex, int iDisplayIndex, int iReducedBlanking); + +ADL_EXTERNC int EXPOSED ADL2_Display_FormatsOverride_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpSettingsSupported, int* lpSettingsSupportedEx, int* lpCurSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_FormatsOverride_Get(int iAdapterIndex, int iDisplayIndex, int* lpSettingsSupported, int* lpSettingsSupportedEx, int* lpCurSettings); + +ADL_EXTERNC int EXPOSED ADL2_Display_FormatsOverride_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_FormatsOverride_Set(int iAdapterIndex, int iDisplayIndex, int iOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL2_Display_MVPUCaps_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLMVPUCaps *lpMvpuCaps); + +ADL_EXTERNC int EXPOSED ADL_Display_MVPUCaps_Get(int iAdapterIndex, ADLMVPUCaps *lpMvpuCaps); + +ADL_EXTERNC int EXPOSED ADL2_Display_MVPUStatus_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLMVPUStatus *lpMvpuStatus); + +ADL_EXTERNC int EXPOSED ADL_Display_MVPUStatus_Get(int iAdapterIndex, ADLMVPUStatus *lpMvpuStatus); + +ADL_EXTERNC int EXPOSED ADL2_Display_DummyVirtual_Get(ADL_CONTEXT_HANDLE context, int iVirtualDisplayType, int* iTargetID); + +ADL_EXTERNC int EXPOSED ADL2_Display_DummyVirtual_Destroy(ADL_CONTEXT_HANDLE context, int iTargetID); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VariBright_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VariBright_Caps(int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VariBrightEnable_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iEnabled); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VariBrightEnable_Set(int iAdapterIndex, int iEnabled); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VariBrightLevel_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * iDefaultLevel, int * iNumberOfLevels, int * iStep, int * iCurrentLevel); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VariBrightLevel_Get(int iAdapterIndex, int * iDefaultLevel, int * iNumberOfLevels, int * iStep, int * iCurrentLevel); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_VariBrightLevel_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iCurrentLevel, int iApplyImmediately); + +ADL_EXTERNC int EXPOSED ADL_Adapter_VariBrightLevel_Set(int iAdapterIndex, int iCurrentLevel, int iApplyImmediately); + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_ControllerOverlayAdjustmentCaps_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLControllerOverlayInput *lpOverlayInput, ADLControllerOverlayInfo *lpCapsInfo); + +ADL_EXTERNC int EXPOSED ADL_Display_ControllerOverlayAdjustmentCaps_Get(int iAdapterIndex, ADLControllerOverlayInput *lpOverlayInput, ADLControllerOverlayInfo *lpCapsInfo); + +ADL_EXTERNC int EXPOSED ADL2_Display_ControllerOverlayAdjustmentData_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLControllerOverlayInput * lpOverlay); + +ADL_EXTERNC int EXPOSED ADL_Display_ControllerOverlayAdjustmentData_Get(int iAdapterIndex, ADLControllerOverlayInput * lpOverlay); + +ADL_EXTERNC int EXPOSED ADL2_Display_ControllerOverlayAdjustmentData_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLControllerOverlayInput * lpOverlay); + +ADL_EXTERNC int EXPOSED ADL_Display_ControllerOverlayAdjustmentData_Set(int iAdapterIndex, ADLControllerOverlayInput * lpOverlay); + + + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_ViewPort_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLControllerMode * lpControllerMode); + +ADL_EXTERNC int EXPOSED ADL_Display_ViewPort_Set(int iAdapterIndex, int iDisplayIndex, ADLControllerMode * lpControllerMode); + +ADL_EXTERNC int EXPOSED ADL2_Display_ViewPort_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLControllerMode * lpControllerMode); + +ADL_EXTERNC int EXPOSED ADL_Display_ViewPort_Get(int iAdapterIndex, int iDisplayIndex, ADLControllerMode * lpControllerMode); + +ADL_EXTERNC int EXPOSED ADL2_Display_ViewPort_Cap(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int* lpSupported); + +ADL_EXTERNC int EXPOSED ADL_Display_ViewPort_Cap(int iAdapterIndex, int* lpSupported); + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_WriteAndReadI2CRev_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpMajor, int *lpMinor); + +ADL_EXTERNC int EXPOSED ADL_Display_WriteAndReadI2CRev_Get(int iAdapterIndex, int *lpMajor, int *lpMinor); + +ADL_EXTERNC int EXPOSED ADL2_Display_WriteAndReadI2C(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLI2C *plI2C); + +ADL_EXTERNC int EXPOSED ADL_Display_WriteAndReadI2C(int iAdapterIndex, ADLI2C *plI2C); + +ADL_EXTERNC int EXPOSED ADL2_Display_DDCBlockAccess_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iOption, int iCommandIndex,int iSendMsgLen, char *lpucSendMsgBuf, int *lpulRecvMsgLen, char *lpucRecvMsgBuf); + +ADL_EXTERNC int EXPOSED ADL_Display_DDCBlockAccess_Get(int iAdapterIndex, int iDisplayIndex, int iOption, int iCommandIndex,int iSendMsgLen, char *lpucSendMsgBuf, int *lpulRecvMsgLen, char *lpucRecvMsgBuf); + +ADL_EXTERNC int EXPOSED ADL2_Display_DDCInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDDCInfo* lpInfo); + +ADL_EXTERNC int EXPOSED ADL_Display_DDCInfo_Get(int iAdapterIndex, int iDisplayIndex, ADLDDCInfo* lpInfo); + +ADL_EXTERNC int EXPOSED ADL2_Display_DDCInfo2_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDDCInfo2* lpInfo); + +ADL_EXTERNC int EXPOSED ADL_Display_DDCInfo2_Get(int iAdapterIndex, int iDisplayIndex, ADLDDCInfo2* lpInfo); + + +ADL_EXTERNC int EXPOSED ADL2_Display_EdidData_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayEDIDData *lpEDIDData); + +ADL_EXTERNC int EXPOSED ADL_Display_EdidData_Get(int iAdapterIndex, int iDisplayIndex, ADLDisplayEDIDData *lpEDIDData); + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorCaps_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpCaps, int* lpValids); + +ADL_EXTERNC int EXPOSED ADL_Display_ColorCaps_Get(int iAdapterIndex, int iDisplayIndex, int* lpCaps, int* lpValids); + +ADL_EXTERNC int EXPOSED ADL2_Display_Color_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iColorType, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_Color_Set(int iAdapterIndex, int iDisplayIndex, int iColorType, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_Color_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iColorType, int* lpCurrent, int* lpDefault, int* lpMin, int* lpMax, int* lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_Color_Get(int iAdapterIndex, int iDisplayIndex, int iColorType, int* lpCurrent, int* lpDefault, int* lpMin, int* lpMax, int* lpStep); + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorTemperatureSource_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpTempSource); + +ADL_EXTERNC int EXPOSED ADL_Display_ColorTemperatureSource_Get(int iAdapterIndex, int iDisplayIndex, int *lpTempSource); + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorTemperatureSourceDefault_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpTempSourceDefault); + +ADL_EXTERNC int EXPOSED ADL2_Display_ColorTemperatureSource_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iTempSource); + +ADL_EXTERNC int EXPOSED ADL_Display_ColorTemperatureSource_Set(int iAdapterIndex, int iDisplayIndex, int iTempSource); + +ADL_EXTERNC int EXPOSED ADL2_Display_Gamut_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, ADLGamutInfo *lpCap); + +ADL_EXTERNC int EXPOSED ADL_Display_Gamut_Caps(int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, ADLGamutInfo *lpCap); + +ADL_EXTERNC int EXPOSED ADL2_Display_Gamut_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, ADLGamutData *lpSource); + +ADL_EXTERNC int EXPOSED ADL_Display_Gamut_Get(int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, ADLGamutData *lpSource); + +ADL_EXTERNC int EXPOSED ADL2_Display_Gamut_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, const ADLGamutData *lpSource); + +ADL_EXTERNC int EXPOSED ADL_Display_Gamut_Set(int iAdapterIndex, int iDisplayIndex, ADLGamutReference gamut, const ADLGamutData *lpSource); + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverride_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayMode *lpModeIn, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverride_Get(int iAdapterIndex, int iDisplayIndex, ADLDisplayMode *lpModeIn, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverride_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLDisplayModeInfo *lpMode, int iForceUpdate); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverride_Set(int iAdapterIndex, int iDisplayIndex, ADLDisplayModeInfo *lpMode, int iForceUpdate); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideList_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iMaxNumOfOverrides, ADLDisplayModeInfo *lpModeInfoList, int *lpNumOfOverrides); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverrideList_Get(int iAdapterIndex, int iDisplayIndex, int iMaxNumOfOverrides, ADLDisplayModeInfo *lpModeInfoList, int *lpNumOfOverrides); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideX2_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLDisplayModeInfoX2 *lpMode, int iForceUpdate); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideX3_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeX2 *lpModeIn, ADLDisplayModeInfoX2 *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideListX3_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int *lpNumOfModes, ADLDisplayModeInfoX2 **lpModeInfoList); + +ADL_EXTERNC int EXPOSED ADL2_Adapter_ModeTimingOverride_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL_Adapter_ModeTimingOverride_Caps(int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeX2 *lpModeIn, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverrideX2_Get(int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeX2 *lpModeIn, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverrideListX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, int *lpNumOfModes, ADLDisplayModeInfo **lpModeInfoList); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverrideListX2_Get(int iAdapterIndex, ADLDisplayID displayID, int *lpNumOfModes, ADLDisplayModeInfo **lpModeInfoList); + +ADL_EXTERNC int EXPOSED ADL2_Display_ModeTimingOverride_Delete(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeX2 *lpMode, int iForceUpdate); + +ADL_EXTERNC int EXPOSED ADL_Display_ModeTimingOverride_Delete(int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeX2 *lpMode, int iForceUpdate); + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_CustomizedModeListNum_Get (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpListNum); + +ADL_EXTERNC int EXPOSED ADL_Display_CustomizedModeListNum_Get (int iAdapterIndex, int iDisplayIndex, int* lpListNum); + +ADL_EXTERNC int EXPOSED ADL2_Display_CustomizedModeList_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLCustomMode* lpCustomModeList, int iBuffSize); + +ADL_EXTERNC int EXPOSED ADL_Display_CustomizedModeList_Get(int iAdapterIndex, int iDisplayIndex, ADLCustomMode* lpCustomModeList, int iBuffSize); + +ADL_EXTERNC int EXPOSED ADL2_Display_CustomizedMode_Add (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLCustomMode customMode); + +ADL_EXTERNC int EXPOSED ADL_Display_CustomizedMode_Add (int iAdapterIndex, int iDisplayIndex, ADLCustomMode customMode); + +ADL_EXTERNC int EXPOSED ADL2_Display_CustomizedMode_Delete (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iIndex); + +ADL_EXTERNC int EXPOSED ADL_Display_CustomizedMode_Delete (int iAdapterIndex, int iDisplayIndex, int iIndex); + +ADL_EXTERNC int EXPOSED ADL2_Display_CustomizedMode_Validate(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, ADLCustomMode customMode, int *lpValid); + +ADL_EXTERNC int EXPOSED ADL_Display_CustomizedMode_Validate(int iAdapterIndex, int iDisplayIndex, ADLCustomMode customMode, int *lpValid); + + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_UnderscanSupport_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpSupport); + +ADL_EXTERNC int EXPOSED ADL2_Display_UnderscanState_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_Display_UnderscanState_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iUnderscanEnabled); + +ADL_EXTERNC int EXPOSED ADL2_Display_Underscan_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_Underscan_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_Underscan_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpCurrent, int* lpDefault, int* lpMin, int* lpMax, int* lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_Underscan_Get(int iAdapterIndex, int iDisplayIndex, int* lpCurrent, int* lpDefault, int* lpMin, int* lpMax, int* lpStep); + +ADL_EXTERNC int EXPOSED ADL2_Display_Overscan_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_Overscan_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_Overscan_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefualt, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_Overscan_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefualt, int *lpMin, int *lpMax, int *lpStep); + + + + +ADL_EXTERNC int EXPOSED ADL2_DFP_BaseAudioSupport_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL_DFP_BaseAudioSupport_Get(int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL2_DFP_HDMISupport_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL_DFP_HDMISupport_Get(int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL2_DFP_MVPUAnalogSupport_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL_DFP_MVPUAnalogSupport_Get(int iAdapterIndex, int iDisplayIndex,int* lpSupport); + +ADL_EXTERNC int EXPOSED ADL2_DFP_PixelFormat_Caps(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpValidBits, int *lpValidCaps); + +ADL_EXTERNC int EXPOSED ADL_DFP_PixelFormat_Caps(int iAdapterIndex, int iDisplayIndex, int *lpValidBits, int *lpValidCaps); + +ADL_EXTERNC int EXPOSED ADL2_DFP_PixelFormat_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurState, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL_DFP_PixelFormat_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurState, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_DFP_PixelFormat_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iState); + +ADL_EXTERNC int EXPOSED ADL_DFP_PixelFormat_Set(int iAdapterIndex, int iDisplayIndex, int iState); + +ADL_EXTERNC int EXPOSED ADL2_DFP_GPUScalingEnable_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpSupport, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL_DFP_GPUScalingEnable_Get(int iAdapterIndex, int iDisplayIndex, int *lpSupport, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_DFP_GPUScalingEnable_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_DFP_GPUScalingEnable_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_DFP_AllowOnlyCETimings_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpSupport, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL_DFP_AllowOnlyCETimings_Get(int iAdapterIndex, int iDisplayIndex, int *lpSupport, int *lpCurrent, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_DFP_AllowOnlyCETimings_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_DFP_AllowOnlyCETimings_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + + + + + +ADL_EXTERNC int EXPOSED ADL2_Display_TVCaps_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpcaps); + +ADL_EXTERNC int EXPOSED ADL_Display_TVCaps_Get(int iAdapterIndex, int iDisplayIndex, int* lpcaps); + +ADL_EXTERNC int EXPOSED ADL2_TV_Standard_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_TV_Standard_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_TV_Standard_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int* lpSupportedStandards); + +ADL_EXTERNC int EXPOSED ADL_TV_Standard_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int* lpSupportedStandards); + + + +ADL_EXTERNC int EXPOSED ADL2_CV_DongleSettings_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* lpDongleSetting, int* lpOverrideSettingsSupported, int* lpCurOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL_CV_DongleSettings_Get(int iAdapterIndex, int iDisplayIndex, int* lpDongleSetting, int* lpOverrideSettingsSupported, int* lpCurOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL2_CV_DongleSettings_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL_CV_DongleSettings_Set(int iAdapterIndex, int iDisplayIndex, int iOverrideSettings); + +ADL_EXTERNC int EXPOSED ADL2_CV_DongleSettings_Reset(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex); + +ADL_EXTERNC int EXPOSED ADL_CV_DongleSettings_Reset(int iAdapterIndex, int iDisplayIndex); + + +ADL_EXTERNC int EXPOSED ADL2_Display_UnderScan_Auto_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_UnderScan_Auto_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL2_Display_UnderScan_Auto_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_UnderScan_Auto_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_Deflicker_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_Deflicker_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL2_Display_Deflicker_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayindex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_Deflicker_Set(int iAdapterIndex, int iDisplayindex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_FilterSVideo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL_Display_FilterSVideo_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMin, int *lpMax, int *lpStep); + +ADL_EXTERNC int EXPOSED ADL2_Display_FilterSVideo_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL_Display_FilterSVideo_Set(int iAdapterIndex, int iDisplayIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_Display_DisplayContent_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iContent); + +ADL_EXTERNC int EXPOSED ADL_Display_DisplayContent_Set(int iAdapterIndex, int iDisplayIndex, int iContent); + +ADL_EXTERNC int EXPOSED ADL2_Display_DisplayContent_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex,int iDisplayIndex,int* piContent); + +ADL_EXTERNC int EXPOSED ADL_Display_DisplayContent_Get(int iAdapterIndex,int iDisplayIndex,int* piContent); + +ADL_EXTERNC int EXPOSED ADL2_Display_DisplayContent_Cap(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int* pCapContent); + +ADL_EXTERNC int EXPOSED ADL_Display_DisplayContent_Cap(int iAdapterIndex, int iDisplayIndex, int* pCapContent); + +ADL_EXTERNC int EXPOSED ADL2_Display_TargetTiming_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL2_Display_TargetTimingX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeInfoX2 *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL_Display_TargetTiming_Get(int iAdapterIndex, ADLDisplayID displayID, ADLDisplayModeInfo *lpModeInfoOut); + +ADL_EXTERNC int EXPOSED ADL_Display_Downscaling_Caps(int iAdapterIndex, int iDisplayID, int* lpCaps); + + +ADL_EXTERNC int EXPOSED ADL2_Display_Downscaling_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayID, int* lpCaps); + + +ADL_EXTERNC int EXPOSED ADL_Display_FreeSyncState_Get(int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMinRefreshRateInMicroHz, int *lpMaxRefreshRateInMicroHz); + +ADL_EXTERNC int EXPOSED ADL2_Display_FreeSyncState_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, int *lpCurrent, int *lpDefault, int *lpMinRefreshRateInMicroHz, int *lpMaxRefreshRateInMicroHz); + +ADL_EXTERNC int EXPOSED ADL_Display_FreeSyncState_Set(int iAdapterIndex, int iDisplayIndex, int iSetting, int iRefreshRateInMicroHz); + +ADL_EXTERNC int EXPOSED ADL2_Display_FreeSyncState_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDisplayIndex, int iSetting, int iRefreshRateInMicroHz); + +ADL_EXTERNC int EXPOSED ADL2_Display_DCE_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_DCE_Set(int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL2_Display_DCE_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_DCE_Get(int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + + +ADL_EXTERNC int EXPOSED ADL2_Display_FreeSync_Cap(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLFreeSyncCap *lpFreeSyncCaps); + +ADL_EXTERNC int EXPOSED ADL_Display_FreeSync_Cap(int iAdapterIndex, int iDisplayIndex, ADLFreeSyncCap *lpFreeSyncCaps); + +ADL_EXTERNC int EXPOSED ADL2_Display_DCE_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_DCE_Set(int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL2_Display_DCE_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL_Display_DCE_Get(int iAdapterIndex, int iDisplayIndex, ADLDceSettings *lpADLDceSettings); + +ADL_EXTERNC int EXPOSED ADL_CDS_UnsafeMode_Set(int iAdapterIndex, int unsafeMode); + +ADL_EXTERNC int EXPOSED ADL2_CDS_UnsafeMode_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int unsafeMode); + +ADL_EXTERNC int EXPOSED ADL2_TurboSyncSupport_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iTurboSyncSupported); + +ADL_EXTERNC int EXPOSED ADL2_User_Settings_Notify(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_USER_SETTINGS iSetting, int iChanged); + +#endif /* DISPLAY_H_ */ \ No newline at end of file diff --git a/atiadlxx-sys/include/overdrive5.h b/atiadlxx-sys/include/overdrive5.h new file mode 100644 index 0000000..2dae409 --- /dev/null +++ b/atiadlxx-sys/include/overdrive5.h @@ -0,0 +1,85 @@ +#ifndef OVERDRIVE5_H_ +#define OVERDRIVE5_H_ + +#include "adl_structures.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_CurrentActivity_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLPMActivity *lpActivity); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_CurrentActivity_Get(int iAdapterIndex, ADLPMActivity *lpActivity); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_ThermalDevices_Enum(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex, ADLThermalControllerInfo *lpThermalControllerInfo); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_ThermalDevices_Enum(int iAdapterIndex, int iThermalControllerIndex, ADLThermalControllerInfo *lpThermalControllerInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_Temperature_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex, ADLTemperature *lpTemperature); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_Temperature_Get(int iAdapterIndex, int iThermalControllerIndex, ADLTemperature *lpTemperature); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_FanSpeedInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedInfo *lpFanSpeedInfo); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_FanSpeedInfo_Get(int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedInfo *lpFanSpeedInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_FanSpeed_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedValue *lpFanSpeedValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_FanSpeed_Get(int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedValue *lpFanSpeedValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_FanSpeed_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedValue *lpFanSpeedValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_FanSpeed_Set(int iAdapterIndex, int iThermalControllerIndex, ADLFanSpeedValue *lpFanSpeedValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_FanSpeedToDefault_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iThermalControllerIndex); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_FanSpeedToDefault_Set(int iAdapterIndex, int iThermalControllerIndex); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_ODParameters_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLODParameters *lpOdParameters); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_ODParameters_Get(int iAdapterIndex, ADLODParameters *lpOdParameters); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_ODPerformanceLevels_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iDefault, ADLODPerformanceLevels *lpOdPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_ODPerformanceLevels_Get(int iAdapterIndex, int iDefault, ADLODPerformanceLevels *lpOdPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_ODPerformanceLevels_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLODPerformanceLevels *lpOdPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_ODPerformanceLevels_Set(int iAdapterIndex, ADLODPerformanceLevels *lpOdPerformanceLevels); + + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_PowerControl_Caps(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpSupported); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_PowerControl_Caps(int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_PowerControlInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLPowerControlInfo *lpPowerControlInfo); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_PowerControlInfo_Get(int iAdapterIndex, ADLPowerControlInfo *lpPowerControlInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_PowerControl_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_PowerControl_Get(int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive5_PowerControl_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iValue); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive5_PowerControl_Set(int iAdapterIndex, int iValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive_Caps (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion ); + +ADL_EXTERNC int EXPOSED ADL_Overdrive_Caps (int iAdapterIndex, int * iSupported, int * iEnabled, int * iVersion ); + + +#endif /* OVERDRIVE5_H_ */ diff --git a/atiadlxx-sys/include/overdrive6.h b/atiadlxx-sys/include/overdrive6.h new file mode 100644 index 0000000..702f490 --- /dev/null +++ b/atiadlxx-sys/include/overdrive6.h @@ -0,0 +1,164 @@ +#ifndef OVERDRIVE6_H_ +#define OVERDRIVE6_H_ + +#include "adl_structures.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_Capabilities_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6Capabilities *lpODCapabilities); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_Capabilities_Get(int iAdapterIndex, ADLOD6Capabilities *lpODCapabilities); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_StateInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iStateType, ADLOD6StateInfo *lpStateInfo); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_StateInfo_Get(int iAdapterIndex, int iStateType, ADLOD6StateInfo *lpStateInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_State_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iStateType, ADLOD6StateInfo *lpStateInfo); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_State_Set(int iAdapterIndex, int iStateType, ADLOD6StateInfo *lpStateInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_State_Reset(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iStateType); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_State_Reset(int iAdapterIndex, int iStateType); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_CurrentStatus_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6CurrentStatus *lpCurrentStatus); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_CurrentStatus_Get(int iAdapterIndex, ADLOD6CurrentStatus *lpCurrentStatus); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_ThermalController_Caps(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6ThermalControllerCaps *lpThermalControllerCaps); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_ThermalController_Caps(int iAdapterIndex, ADLOD6ThermalControllerCaps *lpThermalControllerCaps); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_Temperature_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpTemperature); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_Temperature_Get(int iAdapterIndex, int *lpTemperature); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanSpeed_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6FanSpeedInfo *lpFanSpeedInfo); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanSpeed_Get(int iAdapterIndex, ADLOD6FanSpeedInfo *lpFanSpeedInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanSpeed_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6FanSpeedValue *lpFanSpeedValue); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanSpeed_Set(int iAdapterIndex, ADLOD6FanSpeedValue *lpFanSpeedValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanSpeed_Reset(ADL_CONTEXT_HANDLE context,int iAdapterIndex); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanSpeed_Reset(int iAdapterIndex); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_PowerControl_Caps (ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpSupported); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_PowerControl_Caps (int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_PowerControlInfo_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, ADLOD6PowerControlInfo *lpPowerControlInfo); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_PowerControlInfo_Get(int iAdapterIndex, ADLOD6PowerControlInfo *lpPowerControlInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_PowerControl_Get(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_PowerControl_Get(int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_PowerControl_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_PowerControl_Set(int iAdapterIndex, int iValue); + + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_VoltageControlInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD6VoltageControlInfo *lpVoltageControlInfo); + + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_VoltageControlInfo_Get(int iAdapterIndex, ADLOD6VoltageControlInfo *lpVoltageControlInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_VoltageControl_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_VoltageControl_Get(int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_VoltageControl_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iValue); + + + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_VoltageControl_Set(int iAdapterIndex, int iValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_CapabilitiesEx_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD6CapabilitiesEx *lpODCapabilities); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_CapabilitiesEx_Get(int iAdapterIndex, ADLOD6CapabilitiesEx *lpODCapabilities); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_StateEx_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iStateType, ADLOD6StateEx *lpODState); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_StateEx_Get(int iAdapterIndex, int iStateType, ADLOD6StateEx *lpODState); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_StateEx_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iStateType, ADLOD6StateEx *lpODState); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_StateEx_Set(int iAdapterIndex, int iStateType, ADLOD6StateEx *lpODState); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_ThermalLimitUnlock_Set(int iAdapterIndex, int iStateType, int iEnable); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_ThermalLimitUnlock_Set(ADL_CONTEXT_HANDLE context,int iAdapterIndex, int iStateType, int iEnable); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_ThermalLimitUnlock_Get(int iAdapterIndex, int iStateType, int* pEnabled); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_ThermalLimitUnlock_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iStateType, int* pEnabled); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_AdvancedFan_Caps (int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_AdvancedFan_Caps (ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_TargetTemperatureRangeInfo_Get(int iAdapterIndex, ADLOD6ParameterRange *lpTargetTemperatureInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_TargetTemperatureRangeInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD6ParameterRange *lpTargetTemperatureInfo); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_TargetTemperatureData_Get(int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_TargetTemperatureData_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_TargetTemperatureData_Set(int iAdapterIndex, int iCurrentValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_TargetTemperatureData_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iCurrentValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanPWMLimitRangeInfo_Get(int iAdapterIndex, ADLOD6ParameterRange *lpFanPWMLimitInfo); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanPWMLimitRangeInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD6ParameterRange *lpFanPWMLimitInfo); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanPWMLimitData_Get(int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanPWMLimitData_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FanPWMLimitData_Set(int iAdapterIndex, int iCurrentValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FanPWMLimitData_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iCurrentValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_CurrentPower_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iPowerType, int *lpCurrentValue); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_ControlI2C(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iControl); + +ADL_EXTERNC int EXPOSED ADL2_Overdrive6_FuzzyController_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL_Overdrive6_FuzzyController_Caps(int iAdapterIndex, int *lpSupported); + + +#endif /* OVERDRIVE6_H_ */ + diff --git a/atiadlxx-sys/include/overdrive8.h b/atiadlxx-sys/include/overdrive8.h new file mode 100644 index 0000000..d2b5ac2 --- /dev/null +++ b/atiadlxx-sys/include/overdrive8.h @@ -0,0 +1,68 @@ +#pragma once + + + + #ifndef OVERDRIVE8_H_ + #define OVERDRIVE8_H_ + + #include "adl_structures.h" + + #ifndef ADL_EXTERNC + #ifdef __cplusplus + #define ADL_EXTERNC extern "C" + #else + #define ADL_EXTERNC + #endif + #endif + + #ifndef EXPOSED + #define EXPOSED + #endif /* EXPOSED */ + + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Init_Setting_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD8InitSetting *lpInitSetting); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Current_Setting_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD8CurrentSetting *lpCurrentSetting); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Setting_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD8SetSetting *lpSetSetting, ADLOD8CurrentSetting *lpCurrentSetting); + + + ADL_EXTERNC int EXPOSED ADL2_New_QueryPMLogData_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogDataOutput* lpDataOutput); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Init_SettingX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpOverdrive8Capabilities, int *lpNumberOfFeatures, ADLOD8SingleInitSetting** lppInitSettingList); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Current_SettingX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpNumberOfFeatures, int** lppCurrentSettingList); + + ADL_EXTERNC int EXPOSED ADL2_AutoTuningResult_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, bool* lpDataOutput); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLogSenorRange_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpNumberOfSupportedSensorRange, ADLOD8SingleInitSetting** lppSenorRangeCapsList); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLogSenorType_Support_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpNumOfSupportedSensorType, int** lppSenroTypesList); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLog_ShareMemory_Support(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int * lpSupported, int option); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLog_ShareMemory_Start(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iSampleRate, int iNumofPMLogSendorList, int* lpPMLogSendorList, ADL_D3DKMT_HANDLE* lpHDevice, void** lppSharedMemory, int iOption); + + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLog_ShareMemory_Read(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iNumSensor, int *lpSensorList, void** lppSharedMemory, ADLPMLogDataOutput* lpDataOutput); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_PMLog_ShareMemory_Stop(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_D3DKMT_HANDLE *lpHDevice); + + + ADL_EXTERNC int EXPOSED ADL2_Device_PMLog_Device_Create(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_D3DKMT_HANDLE *pDevice); + + ADL_EXTERNC int EXPOSED ADL2_Device_PMLog_Device_Destroy(ADL_CONTEXT_HANDLE context, ADL_D3DKMT_HANDLE hDevice); + + ADL_EXTERNC int EXPOSED ADL2_Overdrive8_Current_SettingX3_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpFeatureNotAdjustableBits, int *lpNumberOfSettings, int** lppCurrentSettingList, int iOption); + + ADL_EXTERNC int EXPOSED ADL2_Adapter_PMLog_Support_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogSupportInfo* pPMLogSupportInfo); + + ADL_EXTERNC int EXPOSED ADL2_Adapter_PMLog_Start(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogStartInput* pPMLogStartInput, ADLPMLogStartOutput* pPMLogStartOutput, ADL_D3DKMT_HANDLE hDevice); + + ADL_EXTERNC int EXPOSED ADL2_Adapter_PMLog_Stop(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADL_D3DKMT_HANDLE hDevice); + + + ADL_EXTERNC int EXPOSED ADL2_Adapter_PMLog_SensorLimits_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogSensorLimits* lpDataOutput); + + + #endif /* OVERDRIVE8_H_ */ \ No newline at end of file diff --git a/atiadlxx-sys/include/overdriveN.h b/atiadlxx-sys/include/overdriveN.h new file mode 100644 index 0000000..0c2fa9b --- /dev/null +++ b/atiadlxx-sys/include/overdriveN.h @@ -0,0 +1,90 @@ +#ifndef OVERDRIVEN_H_ +#define OVERDRIVEN_H_ + +#include "adl_structures.h" + +#ifndef ADL_EXTERNC +#ifdef __cplusplus +#define ADL_EXTERNC extern "C" +#else +#define ADL_EXTERNC +#endif +#endif + +#ifndef EXPOSED +#define EXPOSED +#endif /* EXPOSED */ + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_Capabilities_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNCapabilities *lpODCapabilities); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_CapabilitiesX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNCapabilitiesX2 *lpODCapabilities); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SystemClocks_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevels *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SystemClocks_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevels *lpODPerformanceLevels); + + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SystemClocksX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevelsX2 *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SystemClocksX2_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevelsX2 *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryClocksX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevelsX2 *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryClocksX2_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevelsX2 *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryClocks_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevels *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryClocks_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevels *lpODPerformanceLevels); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_FanControl_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNFanControl *lpODFanSpeed); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_FanControl_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNFanControl *lpODFanControl); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_PowerLimit_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPowerLimitSetting *lpODPowerLimit); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_PowerLimit_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPowerLimitSetting *lpODPowerLimit); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_Temperature_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iTemperatureType, int *iTemperature); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_PerformanceStatus_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceStatus *lpODPerformanceStatus); + +// Custom fan for WS ODN vega 10 +ADL_EXTERNC int EXPOSED ADL2_CustomFan_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported); + +ADL_EXTERNC int EXPOSED ADL2_CustomFan_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNFanControl *lpODFanControl); + +ADL_EXTERNC int EXPOSED ADL2_CustomFan_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNFanControl *lpODFanControl); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryTimingLevel_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupport, int *lpCurrentValue, int *lpDefaultValue, int *lpNumberLevels, int **lppLevelList); + + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_MemoryTimingLevel_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int currentValue); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_ZeroRPMFan_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupport, int *lpCurrentValue, int *lpDefaultValue); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_ZeroRPMFan_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int currentValue); + + + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SettingsExt_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpOverdriveNExtCapabilities, int *lpNumberOfODNExtFeatures, ADLODNExtSingleInitSetting** lppInitSettingList, int** lppCurrentSettingList); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SettingsExt_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iNumberOfODNExtFeatures,int* itemValueValidList, int* lpItemValueList); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_AutoWattman_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpSupported, int *lpDefault); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_AutoWattman_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpCurrent); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_AutoWattman_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iCurrent); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_CountOfEvents_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int eventcounterType, int *eventCount); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SCLKAutoOverClock_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpStatus); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_SCLKAutoOverClock_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iStatus, int *iFlags); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_Test_Set(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iEnabled); + +ADL_EXTERNC int EXPOSED ADL2_OverdriveN_ThrottleNotification_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int *lpStatus, int *lpThrottleFlags); + + +#endif /* OVERDRIVEN_H_ */ diff --git a/atiadlxx-sys/include/wrapper.hpp b/atiadlxx-sys/include/wrapper.hpp new file mode 100644 index 0000000..65865fc --- /dev/null +++ b/atiadlxx-sys/include/wrapper.hpp @@ -0,0 +1,6 @@ +#include +#include "adl.h" +#include "overdrive5.h" +#include "overdrive6.h" +#include "overdriveN.h" +#include "overdrive8.h" diff --git a/atiadlxx-sys/lib/atiadlxx.def b/atiadlxx-sys/lib/atiadlxx.def new file mode 100644 index 0000000..185f478 --- /dev/null +++ b/atiadlxx-sys/lib/atiadlxx.def @@ -0,0 +1,1216 @@ +EXPORTS +ADL2_ADC_CurrentProfileFromDrv_Get +ADL2_ADC_Display_AdapterDeviceProfileEx_Get +ADL2_ADC_DrvDataToProfile_Copy +ADL2_ADC_FindClosestMode_Get +ADL2_ADC_IsDevModeEqual_Get +ADL2_ADC_Profile_Apply +ADL2_APO_AudioDelayAdjustmentInfo_Get +ADL2_APO_AudioDelay_Restore +ADL2_APO_AudioDelay_Set +ADL2_AdapterLimitation_Caps +ADL2_AdapterX2_Caps +ADL2_Adapter_AMDAndNonAMDDIsplayClone_Get +ADL2_Adapter_ASICFamilyType_Get +ADL2_Adapter_ASICInfo_Get +ADL2_Adapter_Accessibility_Get +ADL2_Adapter_AceDefaults_Restore +ADL2_Adapter_Active_Get +ADL2_Adapter_Active_Set +ADL2_Adapter_Active_SetPrefer +ADL2_Adapter_AdapterInfoX2_Get +ADL2_Adapter_AdapterInfoX3_Get +ADL2_Adapter_AdapterInfoX4_Get +ADL2_Adapter_AdapterInfo_Get +ADL2_Adapter_AdapterList_Disable +ADL2_Adapter_AdapterLocationPath_Get +ADL2_Adapter_Aspects_Get +ADL2_Adapter_AudioChannelSplitConfiguration_Get +ADL2_Adapter_AudioChannelSplit_Disable +ADL2_Adapter_AudioChannelSplit_Enable +ADL2_Adapter_BigSw_Info_Get +ADL2_Adapter_BlackAndWhiteLevelSupport_Get +ADL2_Adapter_BlackAndWhiteLevel_Get +ADL2_Adapter_BlackAndWhiteLevel_Set +ADL2_Adapter_BoardLayout_Get +ADL2_Adapter_Caps +ADL2_Adapter_ChipSetInfo_Get +ADL2_Adapter_CloneTypes_Get +ADL2_Adapter_ConfigMemory_Cap +ADL2_Adapter_ConfigMemory_Get +ADL2_Adapter_ConfigureState_Get +ADL2_Adapter_ConnectionData_Get +ADL2_Adapter_ConnectionData_Remove +ADL2_Adapter_ConnectionData_Set +ADL2_Adapter_ConnectionState_Get +ADL2_Adapter_CrossDisplayPlatformInfo_Get +ADL2_Adapter_CrossGPUClone_Disable +ADL2_Adapter_CrossdisplayAdapterRole_Caps +ADL2_Adapter_CrossdisplayInfoX2_Set +ADL2_Adapter_CrossdisplayInfo_Get +ADL2_Adapter_CrossdisplayInfo_Set +ADL2_Adapter_CrossfireX2_Get +ADL2_Adapter_Crossfire_Caps +ADL2_Adapter_Crossfire_Get +ADL2_Adapter_Crossfire_Set +ADL2_Adapter_DedicatedVRAMUsage_Get +ADL2_Adapter_DefaultAudioChannelTable_Load +ADL2_Adapter_Desktop_Caps +ADL2_Adapter_Desktop_SupportedSLSGridTypes_Get +ADL2_Adapter_DeviceID_Get +ADL2_Adapter_DisplayAudioEndpoint_Enable +ADL2_Adapter_DisplayAudioEndpoint_Mute +ADL2_Adapter_DisplayAudioInfo_Get +ADL2_Adapter_DisplayGTCCaps_Get +ADL2_Adapter_Display_Caps +ADL2_Adapter_DriverSettings_Get +ADL2_Adapter_DriverSettings_Set +ADL2_Adapter_ECC_ErrorInjection_Set +ADL2_Adapter_ECC_ErrorRecords_Get +ADL2_Adapter_EDC_ErrorInjection_Set +ADL2_Adapter_EDC_ErrorRecords_Get +ADL2_Adapter_EDIDManagement_Caps +ADL2_Adapter_EmulationMode_Set +ADL2_Adapter_ExtInfo_Get +ADL2_Adapter_Feature_Caps +ADL2_Adapter_FrameMetrics_Caps +ADL2_Adapter_FrameMetrics_FrameDuration_Disable +ADL2_Adapter_FrameMetrics_FrameDuration_Enable +ADL2_Adapter_FrameMetrics_FrameDuration_Get +ADL2_Adapter_FrameMetrics_FrameDuration_Start +ADL2_Adapter_FrameMetrics_FrameDuration_Stop +ADL2_Adapter_FrameMetrics_Get +ADL2_Adapter_FrameMetrics_Start +ADL2_Adapter_FrameMetrics_Stop +ADL2_Adapter_GPUUMACarveout_Info_Get +ADL2_Adapter_GPUUMACarveout_Size_Set +ADL2_Adapter_Gamma_Get +ADL2_Adapter_Gamma_Set +ADL2_Adapter_Graphic_Core_Info_Get +ADL2_Adapter_HBC_Caps +ADL2_Adapter_HBM_ECC_UC_Check +ADL2_Adapter_Headless_Get +ADL2_Adapter_ID_Get +ADL2_Adapter_IsGamingDriver_Info_Get +ADL2_Adapter_LocalDisplayConfig_Get +ADL2_Adapter_LocalDisplayConfig_Set +ADL2_Adapter_LocalDisplayState_Get +ADL2_Adapter_MVPU_Set +ADL2_Adapter_MaxCursorSize_Get +ADL2_Adapter_MemoryInfo2_Get +ADL2_Adapter_MemoryInfo3_Get +ADL2_Adapter_MemoryInfoX4_Get +ADL2_Adapter_MemoryInfo_Get +ADL2_Adapter_MirabilisSupport_Get +ADL2_Adapter_ModeSwitch +ADL2_Adapter_ModeTimingOverride_Caps +ADL2_Adapter_Modes_ReEnumerate +ADL2_Adapter_NumberOfActivatableSources_Get +ADL2_Adapter_NumberOfAdapters_Get +ADL2_Adapter_ObservedClockInfo_Get +ADL2_Adapter_PMLog_SensorLimits_Get +ADL2_Adapter_PMLog_Start +ADL2_Adapter_PMLog_Stop +ADL2_Adapter_PMLog_Support_Get +ADL2_Adapter_PreFlipPostProcessing_Disable +ADL2_Adapter_PreFlipPostProcessing_Enable +ADL2_Adapter_PreFlipPostProcessing_Get_Status +ADL2_Adapter_PreFlipPostProcessing_Select_LUT_Algorithm +ADL2_Adapter_PreFlipPostProcessing_Select_LUT_Buffer +ADL2_Adapter_PreFlipPostProcessing_Unselect_LUT_Buffer +ADL2_Adapter_Primary_Get +ADL2_Adapter_Primary_Set +ADL2_Adapter_RAS_ErrorInjection_Set +ADL2_Adapter_RAS_ErrorInjection_SetX2 +ADL2_Adapter_Radeon_LED_Pattern_Control_Set +ADL2_Adapter_Radeon_USB_LED_Pattern_Supported_Controls_Get +ADL2_Adapter_Radeon_USB_LED_Support_Get +ADL2_Adapter_Radeon_USB_LED_Supported_Controls_Get +ADL2_Adapter_Radeon_Usb_Led_Flash_Save +ADL2_Adapter_RegValueInt_Get +ADL2_Adapter_RegValueInt_Set +ADL2_Adapter_RegValueString_Get +ADL2_Adapter_RegValueString_Set +ADL2_Adapter_SWInfo_Get +ADL2_Adapter_SmartMux_Control_Get +ADL2_Adapter_SmartMux_Control_Set +ADL2_Adapter_SmartMux_State_Get +ADL2_Adapter_SmartMux_Support_Get +ADL2_Adapter_SmartMux_Switch_Failure_Get +ADL2_Adapter_Speed_Caps +ADL2_Adapter_Speed_Get +ADL2_Adapter_Speed_Set +ADL2_Adapter_SupportedConnections_Get +ADL2_Adapter_TRNG_Get +ADL2_Adapter_Tear_Free_Cap +ADL2_Adapter_VRAMUsage_Get +ADL2_Adapter_VariBrightEnable_Set +ADL2_Adapter_VariBrightLevel_Get +ADL2_Adapter_VariBrightLevel_Set +ADL2_Adapter_VariBright_Caps +ADL2_Adapter_VariBright_CapsX2 +ADL2_Adapter_VerndorID_Int_get +ADL2_Adapter_VideoBiosInfo_Get +ADL2_Adapter_VideoTheaterModeInfo_Get +ADL2_Adapter_VideoTheaterModeInfo_Set +ADL2_Adapter_XConnectSupport_Get +ADL2_Adapter_XGMIHiveID_Get +ADL2_ApplicationProfilesX2_AppInterceptionList_Set +ADL2_ApplicationProfilesX2_AppStartStopInfo_Get +ADL2_ApplicationProfilesX3_AppStartStopInfo_Get +ADL2_ApplicationProfiles_AppInterceptionList_Set +ADL2_ApplicationProfiles_AppInterception_Set +ADL2_ApplicationProfiles_AppStartStopInfo_Get +ADL2_ApplicationProfiles_AppStartStop_Resume +ADL2_ApplicationProfiles_Applications_Get +ADL2_ApplicationProfiles_ConvertToCompact +ADL2_ApplicationProfiles_DriverAreaPrivacy_Get +ADL2_ApplicationProfiles_GetCustomization +ADL2_ApplicationProfiles_HitListsX2_Get +ADL2_ApplicationProfiles_HitListsX3_Get +ADL2_ApplicationProfiles_HitLists_Get +ADL2_ApplicationProfiles_ProfileApplicationX2_Assign +ADL2_ApplicationProfiles_ProfileApplication_Assign +ADL2_ApplicationProfiles_ProfileOfAnApplicationX2_Search +ADL2_ApplicationProfiles_ProfileOfAnApplication_InMemorySearch +ADL2_ApplicationProfiles_ProfileOfAnApplication_Search +ADL2_ApplicationProfiles_Profile_Create +ADL2_ApplicationProfiles_Profile_Exist +ADL2_ApplicationProfiles_Profile_Remove +ADL2_ApplicationProfiles_PropertyType_Get +ADL2_ApplicationProfiles_Release_Get +ADL2_ApplicationProfiles_RemoveApplication +ADL2_ApplicationProfiles_StatusInfo_Get +ADL2_ApplicationProfiles_System_Reload +ADL2_ApplicationProfiles_User_Load +ADL2_ApplicationProfiles_User_Unload +ADL2_Audio_CurrentSampleRate_Get +ADL2_AutoTuningResult_Get +ADL2_BOOST_Settings_Get +ADL2_BOOST_Settings_Set +ADL2_Blockchain_BlockchainMode_Caps +ADL2_Blockchain_BlockchainMode_Get +ADL2_Blockchain_BlockchainMode_Set +ADL2_Blockchain_Hashrate_Set +ADL2_CDS_UnsafeMode_Set +ADL2_CHILL_SettingsX2_Get +ADL2_CHILL_SettingsX2_Set +ADL2_CVML_Camera_DMFT_Set +ADL2_CV_DongleSettings_Get +ADL2_CV_DongleSettings_Reset +ADL2_CV_DongleSettings_Set +ADL2_Chill_Caps_Get +ADL2_Chill_Settings_Get +ADL2_Chill_Settings_Notify +ADL2_Chill_Settings_Set +ADL2_CustomFan_Caps +ADL2_CustomFan_Get +ADL2_CustomFan_Set +ADL2_DELAG_Settings_Get +ADL2_DELAG_Settings_Set +ADL2_DFP_AllowOnlyCETimings_Get +ADL2_DFP_AllowOnlyCETimings_Set +ADL2_DFP_BaseAudioSupport_Get +ADL2_DFP_GPUScalingEnable_Get +ADL2_DFP_GPUScalingEnable_Set +ADL2_DFP_HDMISupport_Get +ADL2_DFP_MVPUAnalogSupport_Get +ADL2_DFP_PixelFormat_Caps +ADL2_DFP_PixelFormat_Get +ADL2_DFP_PixelFormat_Set +ADL2_DVRSupport_Get +ADL2_Desktop_DOPP_Enable +ADL2_Desktop_DOPP_EnableX2 +ADL2_Desktop_Detach +ADL2_Desktop_Device_Create +ADL2_Desktop_Device_Destroy +ADL2_Desktop_ExclusiveModeX2_Get +ADL2_Desktop_HardwareCursor_SetBitmap +ADL2_Desktop_HardwareCursor_SetPosition +ADL2_Desktop_HardwareCursor_Toggle +ADL2_Desktop_PFPAComplete_Set +ADL2_Desktop_PFPAState_Get +ADL2_Desktop_PrimaryInfo_Get +ADL2_Desktop_SrcRect_Get +ADL2_Desktop_TextureState_Get +ADL2_Desktop_Texture_Enable +ADL2_Device_PMLog_Device_Create +ADL2_Device_PMLog_Device_Destroy +ADL2_DisplayScaling_Set +ADL2_Display_AdapterID_Get +ADL2_Display_AdjustCaps_Get +ADL2_Display_AdjustmentCoherent_Get +ADL2_Display_AdjustmentCoherent_Set +ADL2_Display_AudioMappingInfo_Get +ADL2_Display_AvivoColor_Get +ADL2_Display_AvivoCurrentColor_Set +ADL2_Display_AvivoDefaultColor_Set +ADL2_Display_BackLight_Get +ADL2_Display_BackLight_Set +ADL2_Display_BezelOffsetSteppingSize_Get +ADL2_Display_BezelOffset_Set +ADL2_Display_BezelSupported_Validate +ADL2_Display_CVDC_Caps +ADL2_Display_CVDC_Get +ADL2_Display_CVDC_Set +ADL2_Display_CVDC_Supported +ADL2_Display_Capabilities_Get +ADL2_Display_ColorCaps_Get +ADL2_Display_ColorDepth_Get +ADL2_Display_ColorDepth_Set +ADL2_Display_ColorTemperatureSourceDefault_Get +ADL2_Display_ColorTemperatureSource_Get +ADL2_Display_ColorTemperatureSource_Set +ADL2_Display_Color_Get +ADL2_Display_Color_Set +ADL2_Display_ConnectedDisplays_Get +ADL2_Display_ContainerID_Get +ADL2_Display_ControllerOverlayAdjustmentCaps_Get +ADL2_Display_ControllerOverlayAdjustmentData_Get +ADL2_Display_ControllerOverlayAdjustmentData_Set +ADL2_Display_CustomizedModeListNum_Get +ADL2_Display_CustomizedModeList_Get +ADL2_Display_CustomizedMode_Add +ADL2_Display_CustomizedMode_Delete +ADL2_Display_CustomizedMode_Validate +ADL2_Display_DCE_Get +ADL2_Display_DCE_Set +ADL2_Display_DDCBlockAccess_Get +ADL2_Display_DDCInfo2_Get +ADL2_Display_DDCInfo_Get +ADL2_Display_DPDceSupport_Get +ADL2_Display_Deflicker_Get +ADL2_Display_Deflicker_Set +ADL2_Display_DeviceConfig_Get +ADL2_Display_DisplayContent_Cap +ADL2_Display_DisplayContent_Get +ADL2_Display_DisplayContent_Set +ADL2_Display_DisplayInfo_Get +ADL2_Display_DisplayMapConfigX2_Set +ADL2_Display_DisplayMapConfig_Get +ADL2_Display_DisplayMapConfig_PossibleAddAndRemove +ADL2_Display_DisplayMapConfig_Set +ADL2_Display_DisplayMapConfig_Validate +ADL2_Display_DitherState_Get +ADL2_Display_DitherState_Set +ADL2_Display_Downscaling_Caps +ADL2_Display_DpMstAuxMsg_Get +ADL2_Display_DpMstInfo_Get +ADL2_Display_DummyVirtual_Destroy +ADL2_Display_DummyVirtual_Get +ADL2_Display_EdidData_Get +ADL2_Display_EdidData_Set +ADL2_Display_EnumDisplays_Get +ADL2_Display_FilterSVideo_Get +ADL2_Display_FilterSVideo_Set +ADL2_Display_ForcibleDisplay_Get +ADL2_Display_ForcibleDisplay_Set +ADL2_Display_FormatsOverride_Get +ADL2_Display_FormatsOverride_Set +ADL2_Display_FreeSyncState_Get +ADL2_Display_FreeSyncState_Set +ADL2_Display_FreeSync_Cap +ADL2_Display_GamutMapping_Get +ADL2_Display_GamutMapping_Reset +ADL2_Display_GamutMapping_Set +ADL2_Display_Gamut_Caps +ADL2_Display_Gamut_Get +ADL2_Display_Gamut_Set +ADL2_Display_GetDSCInfo +ADL2_Display_HDCP_Get +ADL2_Display_HDCP_Set +ADL2_Display_HDRState_Get +ADL2_Display_HDRState_Set +ADL2_Display_ImageExpansion_Get +ADL2_Display_ImageExpansion_Set +ADL2_Display_InfoPacket_Get +ADL2_Display_InfoPacket_Set +ADL2_Display_IsVirtual_Get +ADL2_Display_LCDRefreshRateCapability_Get +ADL2_Display_LCDRefreshRateOptions_Get +ADL2_Display_LCDRefreshRateOptions_Set +ADL2_Display_LCDRefreshRate_Get +ADL2_Display_LCDRefreshRate_Set +ADL2_Display_Limits_Get +ADL2_Display_MVPUCaps_Get +ADL2_Display_MVPUStatus_Get +ADL2_Display_ModeTimingOverrideInfo_Get +ADL2_Display_ModeTimingOverrideListX2_Get +ADL2_Display_ModeTimingOverrideListX3_Get +ADL2_Display_ModeTimingOverrideList_Get +ADL2_Display_ModeTimingOverrideX2_Get +ADL2_Display_ModeTimingOverrideX2_Set +ADL2_Display_ModeTimingOverrideX3_Get +ADL2_Display_ModeTimingOverride_Delete +ADL2_Display_ModeTimingOverride_Get +ADL2_Display_ModeTimingOverride_Set +ADL2_Display_Modes_Get +ADL2_Display_Modes_Set +ADL2_Display_Modes_X2_Get +ADL2_Display_MonitorPowerState_Set +ADL2_Display_NativeAUXChannel_Access +ADL2_Display_NeedWorkaroundFor5Clone_Get +ADL2_Display_NumberOfDisplays_Get +ADL2_Display_ODClockConfig_Set +ADL2_Display_ODClockInfo_Get +ADL2_Display_Overlap_NotifyAdjustment +ADL2_Display_Overlap_Set +ADL2_Display_Overscan_Get +ADL2_Display_Overscan_Set +ADL2_Display_PixelFormatDefault_Get +ADL2_Display_PixelFormat_Get +ADL2_Display_PixelFormat_Set +ADL2_Display_Position_Get +ADL2_Display_Position_Set +ADL2_Display_PossibleMapping_Get +ADL2_Display_PossibleMode_Get +ADL2_Display_PowerXpressActiveGPU_Get +ADL2_Display_PowerXpressActiveGPU_Set +ADL2_Display_PowerXpressActvieGPUR2_Get +ADL2_Display_PowerXpressVersion_Get +ADL2_Display_PowerXpress_AutoSwitchConfig_Get +ADL2_Display_PowerXpress_AutoSwitchConfig_Set +ADL2_Display_PreferredMode_Get +ADL2_Display_PreservedAspectRatio_Get +ADL2_Display_PreservedAspectRatio_Set +ADL2_Display_Property_Get +ADL2_Display_Property_Set +ADL2_Display_PsrControl +ADL2_Display_RcDisplayAdjustment +ADL2_Display_ReGammaCoefficients_Get +ADL2_Display_ReGammaCoefficients_Set +ADL2_Display_ReducedBlanking_Get +ADL2_Display_ReducedBlanking_Set +ADL2_Display_RegammaR1_Get +ADL2_Display_RegammaR1_Set +ADL2_Display_Regamma_Get +ADL2_Display_Regamma_Set +ADL2_Display_SCE_State_Get +ADL2_Display_SCE_State_Set +ADL2_Display_SCE_Supported +ADL2_Display_SLSBuilder_CommonMode_Get +ADL2_Display_SLSBuilder_Create +ADL2_Display_SLSBuilder_DisplaysCanBeNextCandidateInSLS_Get +ADL2_Display_SLSBuilder_DisplaysCanBeNextCandidateToEnabled_Get +ADL2_Display_SLSBuilder_Get +ADL2_Display_SLSBuilder_IsActive_Notify +ADL2_Display_SLSBuilder_MaxSLSLayoutSize_Get +ADL2_Display_SLSBuilder_TimeOut_Get +ADL2_Display_SLSBuilder_Update +ADL2_Display_SLSGrid_Caps +ADL2_Display_SLSMapConfigX2_Delete +ADL2_Display_SLSMapConfigX2_Get +ADL2_Display_SLSMapConfig_Create +ADL2_Display_SLSMapConfig_Delete +ADL2_Display_SLSMapConfig_Get +ADL2_Display_SLSMapConfig_ImageCropType_Set +ADL2_Display_SLSMapConfig_Rearrange +ADL2_Display_SLSMapConfig_SetState +ADL2_Display_SLSMapConfig_SupportedImageCropType_Get +ADL2_Display_SLSMapConfig_Valid +ADL2_Display_SLSMapIndexList_Get +ADL2_Display_SLSMapIndex_Get +ADL2_Display_SLSMiddleMode_Get +ADL2_Display_SLSMiddleMode_Set +ADL2_Display_SLSRecords_Get +ADL2_Display_SetDSCAdjustment +ADL2_Display_Sharpness_Caps +ADL2_Display_Sharpness_Get +ADL2_Display_Sharpness_Info_Get +ADL2_Display_Sharpness_Set +ADL2_Display_Size_Get +ADL2_Display_Size_Set +ADL2_Display_SourceContentAttribute_Get +ADL2_Display_SourceContentAttribute_Set +ADL2_Display_SplitDisplay_Caps +ADL2_Display_SplitDisplay_Get +ADL2_Display_SplitDisplay_RestoreDesktopConfiguration +ADL2_Display_SplitDisplay_Set +ADL2_Display_SupportedColorDepth_Get +ADL2_Display_SupportedPixelFormat_Get +ADL2_Display_SwitchingCapability_Get +ADL2_Display_TVCaps_Get +ADL2_Display_TargetTimingX2_Get +ADL2_Display_TargetTiming_Get +ADL2_Display_UnderScan_Auto_Get +ADL2_Display_UnderScan_Auto_Set +ADL2_Display_UnderscanState_Get +ADL2_Display_UnderscanState_Set +ADL2_Display_UnderscanSupport_Get +ADL2_Display_Underscan_Get +ADL2_Display_Underscan_Set +ADL2_Display_Vector_Get +ADL2_Display_ViewPort_Cap +ADL2_Display_ViewPort_Get +ADL2_Display_ViewPort_Set +ADL2_Display_VirtualType_Get +ADL2_Display_WriteAndReadI2C +ADL2_Display_WriteAndReadI2CLargePayload +ADL2_Display_WriteAndReadI2CRev_Get +ADL2_DriverUpscaleSupport_Get +ADL2_DriverUpscale_Settings_Get +ADL2_DriverUpscale_Settings_Set +ADL2_Driver_Path_Get +ADL2_ElmCompatibilityMode_Caps +ADL2_ElmCompatibilityMode_Status_Get +ADL2_ElmCompatibilityMode_Status_Set +ADL2_ExclusiveModeGet +ADL2_FPS_Caps +ADL2_FPS_Settings_Get +ADL2_FPS_Settings_Reset +ADL2_FPS_Settings_Set +ADL2_FRTCPro_Caps +ADL2_FRTCPro_Settings_Get +ADL2_FRTCPro_Settings_Set +ADL2_Feature_Settings_Get +ADL2_Feature_Settings_Set +ADL2_Flush_Driver_Data +ADL2_FreeSync_PowerOptimization_Get +ADL2_FreeSync_PowerOptimization_Set +ADL2_GPUVMPageSize_Info_Get +ADL2_GPUVMPageSize_Info_Set +ADL2_GPUVerInfo_Get +ADL2_GcnAsicInfo_Get +ADL2_Graphics_IsDetachableGraphicsPlatform_Get +ADL2_Graphics_IsGfx9AndAbove +ADL2_Graphics_MantleVersion_Get +ADL2_Graphics_Platform_Get +ADL2_Graphics_VersionsX2_Get +ADL2_Graphics_VersionsX3_Get +ADL2_Graphics_Versions_Get +ADL2_Graphics_VulkanVersionX2_Get +ADL2_Graphics_VulkanVersionX3_Get +ADL2_Graphics_VulkanVersion_Get +ADL2_HybridGraphicsGPU_Set +ADL2_MGPUSLS_Status_Set +ADL2_MMD_FeatureList_Get +ADL2_MMD_FeatureValuesX2_Get +ADL2_MMD_FeatureValuesX2_Set +ADL2_MMD_FeatureValues_Get +ADL2_MMD_FeatureValues_Set +ADL2_MMD_FeaturesX2_Caps +ADL2_MMD_Features_Caps +ADL2_MMD_VideoAdjustInfo_Get +ADL2_MMD_VideoAdjustInfo_Set +ADL2_MMD_VideoColor_Caps +ADL2_MMD_VideoColor_Get +ADL2_MMD_VideoColor_Set +ADL2_MMD_Video_Caps +ADL2_Main_ControlX2_Create +ADL2_Main_ControlX3_Create +ADL2_Main_Control_Create +ADL2_Main_Control_Destroy +ADL2_Main_Control_GetProcAddress +ADL2_Main_Control_IsFunctionValid +ADL2_Main_Control_Refresh +ADL2_Main_FunctionNameCallback_Set +ADL2_Main_LogDebug_Set +ADL2_Main_LogError_Set +ADL2_New_QueryPMLogData_Get +ADL2_Overdrive5_CurrentActivity_Get +ADL2_Overdrive5_FanSpeedInfo_Get +ADL2_Overdrive5_FanSpeedToDefault_Set +ADL2_Overdrive5_FanSpeed_Get +ADL2_Overdrive5_FanSpeed_Set +ADL2_Overdrive5_ODParameters_Get +ADL2_Overdrive5_ODPerformanceLevels_Get +ADL2_Overdrive5_ODPerformanceLevels_Set +ADL2_Overdrive5_PowerControlAbsValue_Caps +ADL2_Overdrive5_PowerControlAbsValue_Get +ADL2_Overdrive5_PowerControlAbsValue_Set +ADL2_Overdrive5_PowerControlInfo_Get +ADL2_Overdrive5_PowerControl_Caps +ADL2_Overdrive5_PowerControl_Get +ADL2_Overdrive5_PowerControl_Set +ADL2_Overdrive5_Temperature_Get +ADL2_Overdrive5_ThermalDevices_Enum +ADL2_Overdrive6_AdvancedFan_Caps +ADL2_Overdrive6_CapabilitiesEx_Get +ADL2_Overdrive6_Capabilities_Get +ADL2_Overdrive6_ControlI2C +ADL2_Overdrive6_CurrentPower_Get +ADL2_Overdrive6_CurrentStatus_Get +ADL2_Overdrive6_FanPWMLimitData_Get +ADL2_Overdrive6_FanPWMLimitData_Set +ADL2_Overdrive6_FanPWMLimitRangeInfo_Get +ADL2_Overdrive6_FanSpeed_Get +ADL2_Overdrive6_FanSpeed_Reset +ADL2_Overdrive6_FanSpeed_Set +ADL2_Overdrive6_FuzzyController_Caps +ADL2_Overdrive6_MaxClockAdjust_Get +ADL2_Overdrive6_PowerControlInfo_Get +ADL2_Overdrive6_PowerControlInfo_Get_X2 +ADL2_Overdrive6_PowerControl_Caps +ADL2_Overdrive6_PowerControl_Get +ADL2_Overdrive6_PowerControl_Set +ADL2_Overdrive6_StateEx_Get +ADL2_Overdrive6_StateEx_Set +ADL2_Overdrive6_StateInfo_Get +ADL2_Overdrive6_State_Reset +ADL2_Overdrive6_State_Set +ADL2_Overdrive6_TargetTemperatureData_Get +ADL2_Overdrive6_TargetTemperatureData_Set +ADL2_Overdrive6_TargetTemperatureRangeInfo_Get +ADL2_Overdrive6_TemperatureEx_Get +ADL2_Overdrive6_Temperature_Get +ADL2_Overdrive6_ThermalController_Caps +ADL2_Overdrive6_ThermalLimitUnlock_Get +ADL2_Overdrive6_ThermalLimitUnlock_Set +ADL2_Overdrive6_VoltageControlInfo_Get +ADL2_Overdrive6_VoltageControl_Get +ADL2_Overdrive6_VoltageControl_Set +ADL2_Overdrive8_Current_SettingX2_Get +ADL2_Overdrive8_Current_SettingX3_Get +ADL2_Overdrive8_Current_Setting_Get +ADL2_Overdrive8_Init_SettingX2_Get +ADL2_Overdrive8_Init_Setting_Get +ADL2_Overdrive8_PMLogSenorRange_Caps +ADL2_Overdrive8_PMLogSenorType_Support_Get +ADL2_Overdrive8_PMLog_ShareMemory_Read +ADL2_Overdrive8_PMLog_ShareMemory_Start +ADL2_Overdrive8_PMLog_ShareMemory_Stop +ADL2_Overdrive8_PMLog_ShareMemory_Support +ADL2_Overdrive8_Setting_Set +ADL2_Overdrive8_SmartShift_Support +ADL2_OverdriveN_AutoWattman_Caps +ADL2_OverdriveN_AutoWattman_Get +ADL2_OverdriveN_AutoWattman_Set +ADL2_OverdriveN_CapabilitiesX2_Get +ADL2_OverdriveN_Capabilities_Get +ADL2_OverdriveN_CountOfEvents_Get +ADL2_OverdriveN_FanControl_Get +ADL2_OverdriveN_FanControl_Set +ADL2_OverdriveN_MemoryClocksX2_Get +ADL2_OverdriveN_MemoryClocksX2_Set +ADL2_OverdriveN_MemoryClocks_Get +ADL2_OverdriveN_MemoryClocks_Set +ADL2_OverdriveN_MemoryTimingLevel_Get +ADL2_OverdriveN_MemoryTimingLevel_Set +ADL2_OverdriveN_PerformanceStatus_Get +ADL2_OverdriveN_PowerLimit_Get +ADL2_OverdriveN_PowerLimit_Set +ADL2_OverdriveN_SCLKAutoOverClock_Get +ADL2_OverdriveN_SCLKAutoOverClock_Set +ADL2_OverdriveN_SettingsExt_Get +ADL2_OverdriveN_SettingsExt_Set +ADL2_OverdriveN_SystemClocksX2_Get +ADL2_OverdriveN_SystemClocksX2_Set +ADL2_OverdriveN_SystemClocks_Get +ADL2_OverdriveN_SystemClocks_Set +ADL2_OverdriveN_Temperature_Get +ADL2_OverdriveN_Test_Set +ADL2_OverdriveN_ThrottleNotification_Get +ADL2_OverdriveN_ZeroRPMFan_Get +ADL2_OverdriveN_ZeroRPMFan_Set +ADL2_Overdrive_Caps +ADL2_PPLogSettings_Get +ADL2_PPLogSettings_Set +ADL2_PPW_Caps +ADL2_PPW_Status_Get +ADL2_PPW_Status_Set +ADL2_PROVSR_Settings_Get +ADL2_PROVSR_Settings_Set +ADL2_PageMigration_Settings_Get +ADL2_PageMigration_Settings_Set +ADL2_PerGPU_GDEvent_Register +ADL2_PerGPU_GDEvent_UnRegister +ADL2_PerfTuning_Status_Get +ADL2_PerfTuning_Status_Set +ADL2_PerformanceTuning_Caps +ADL2_PowerStates_Get +ADL2_PowerXpress_AncillaryDevices_Get +ADL2_PowerXpress_Config_Caps +ADL2_PowerXpress_Configuration_Get +ADL2_PowerXpress_ExtendedBatteryMode_Caps +ADL2_PowerXpress_ExtendedBatteryMode_Get +ADL2_PowerXpress_ExtendedBatteryMode_Set +ADL2_PowerXpress_LongIdleDetect_Get +ADL2_PowerXpress_LongIdleDetect_Set +ADL2_PowerXpress_PowerControlMode_Get +ADL2_PowerXpress_PowerControlMode_Set +ADL2_PowerXpress_Scheme_Get +ADL2_PowerXpress_Scheme_Set +ADL2_ProtectedContent_Info_Get +ADL2_RIS_Settings_Get +ADL2_RIS_Settings_Set +ADL2_RegisterEvent +ADL2_RegisterEventX2 +ADL2_Remap +ADL2_RemoteDisplay_Destroy +ADL2_RemoteDisplay_Display_Acquire +ADL2_RemoteDisplay_Display_Release +ADL2_RemoteDisplay_Display_Release_All +ADL2_RemoteDisplay_Hdcp20_Create +ADL2_RemoteDisplay_Hdcp20_Destroy +ADL2_RemoteDisplay_Hdcp20_Notify +ADL2_RemoteDisplay_Hdcp20_Process +ADL2_RemoteDisplay_IEPort_Set +ADL2_RemoteDisplay_Initialize +ADL2_RemoteDisplay_Nofitiation_Register +ADL2_RemoteDisplay_Notification_UnRegister +ADL2_RemoteDisplay_Support_Caps +ADL2_RemoteDisplay_VirtualWirelessAdapter_InUse_Get +ADL2_RemoteDisplay_VirtualWirelessAdapter_Info_Get +ADL2_RemoteDisplay_VirtualWirelessAdapter_RadioState_Get +ADL2_RemoteDisplay_VirtualWirelessAdapter_WPSSetting_Change +ADL2_RemoteDisplay_VirtualWirelessAdapter_WPSSetting_Get +ADL2_RemoteDisplay_WFDDeviceInfo_Get +ADL2_RemoteDisplay_WFDDeviceName_Change +ADL2_RemoteDisplay_WFDDevice_StatusInfo_Get +ADL2_RemoteDisplay_WFDDiscover_Start +ADL2_RemoteDisplay_WFDDiscover_Stop +ADL2_RemoteDisplay_WFDLink_Connect +ADL2_RemoteDisplay_WFDLink_Creation_Accept +ADL2_RemoteDisplay_WFDLink_Disconnect +ADL2_RemoteDisplay_WFDLink_WPS_Process +ADL2_RemoteDisplay_WFDWDSPSettings_Set +ADL2_RemoteDisplay_WirelessDisplayEnableDisable_Commit +ADL2_RemotePlay_ControlFlags_Set +ADL2_ScreenPoint_AudioMappingInfo_Get +ADL2_Send +ADL2_SendX2 +ADL2_SmartAccessMemory_Mode_Get +ADL2_SmartAccessMemory_Mode_Set +ADL2_SmartDC_Active_State_Get +ADL2_SmartDC_Caps +ADL2_SmartDC_Status_Get +ADL2_SmartDC_Status_Set +ADL2_SmartShift_DeltaGain_Set +ADL2_SmartShift_Settings_Get +ADL2_SmartShift_Support +ADL2_Stereo3D_2DPackedFormat_Set +ADL2_Stereo3D_3DCursorOffset_Get +ADL2_Stereo3D_3DCursorOffset_Set +ADL2_Stereo3D_CurrentFormat_Get +ADL2_Stereo3D_Info_Get +ADL2_Stereo3D_Modes_Get +ADL2_Stress_Test_Cap +ADL2_SwitchableGraphics_Applications_Get +ADL2_TV_Standard_Get +ADL2_TV_Standard_Set +ADL2_Throttle_Notification_Cap +ADL2_TurboSyncSupport_Get +ADL2_UnRegisterEvent +ADL2_UnRegisterEventX2 +ADL2_User_Settings_Notify +ADL2_WS_Overdrive_Caps +ADL2_Win_IsHybridAI +ADL2_Workstation_8BitGrayscale_Get +ADL2_Workstation_8BitGrayscale_Set +ADL2_Workstation_AdapterNumOfGLSyncConnectors_Get +ADL2_Workstation_Caps +ADL2_Workstation_DeepBitDepthX2_Get +ADL2_Workstation_DeepBitDepthX2_Set +ADL2_Workstation_DeepBitDepth_Get +ADL2_Workstation_DeepBitDepth_Set +ADL2_Workstation_DisplayGLSyncMode_Get +ADL2_Workstation_DisplayGLSyncMode_Set +ADL2_Workstation_DisplayGenlockCapable_Get +ADL2_Workstation_ECCData_Get +ADL2_Workstation_ECCX2_Get +ADL2_Workstation_ECC_Caps +ADL2_Workstation_ECC_Get +ADL2_Workstation_ECC_Set +ADL2_Workstation_GLSyncCounters_Get +ADL2_Workstation_GLSyncGenlockConfiguration_Get +ADL2_Workstation_GLSyncGenlockConfiguration_Set +ADL2_Workstation_GLSyncModuleDetect_Get +ADL2_Workstation_GLSyncModuleInfo_Get +ADL2_Workstation_GLSyncPortState_Get +ADL2_Workstation_GLSyncPortState_Set +ADL2_Workstation_GLSyncSupportedTopology_Get +ADL2_Workstation_GlobalEDIDPersistence_Get +ADL2_Workstation_GlobalEDIDPersistence_Set +ADL2_Workstation_LoadBalancing_Caps +ADL2_Workstation_LoadBalancing_Get +ADL2_Workstation_LoadBalancing_Set +ADL2_Workstation_RAS_ErrorCounts_Get +ADL2_Workstation_RAS_ErrorCounts_Reset +ADL2_Workstation_SDISegmentList_Get +ADL2_Workstation_SDI_Caps +ADL2_Workstation_SDI_Get +ADL2_Workstation_SDI_Set +ADL2_Workstation_Stereo_Get +ADL2_Workstation_Stereo_Set +ADL2_Workstation_UnsupportedDisplayModes_Enable +ADL2_Xe_Bus_Access_Acquire +ADL2_Xe_Bus_Access_Release +ADL2_Xe_ControllerX2_Plugin +ADL2_Xe_ControllerX2_Unplug +ADL2_Xe_ControllerX2_Update +ADL2_Xe_Controller_Allocate +ADL2_Xe_Controller_Free +ADL2_Xe_Controller_Plugin +ADL2_Xe_Controller_Unplug +ADL2_Xe_Controller_Update +ADL2_Xe_Controller_Vibration_Get +ADL_ADC_CurrentProfileFromDrv_Get +ADL_ADC_Display_AdapterDeviceProfileEx_Get +ADL_ADC_DrvDataToProfile_Copy +ADL_ADC_FindClosestMode_Get +ADL_ADC_IsDevModeEqual_Get +ADL_ADC_Profile_Apply +ADL_APO_AudioDelayAdjustmentInfo_Get +ADL_APO_AudioDelay_Restore +ADL_APO_AudioDelay_Set +ADL_AdapterLimitation_Caps +ADL_AdapterX2_Caps +ADL_Adapter_ASICFamilyType_Get +ADL_Adapter_ASICInfo_Get +ADL_Adapter_Accessibility_Get +ADL_Adapter_Active_Get +ADL_Adapter_Active_Set +ADL_Adapter_Active_SetPrefer +ADL_Adapter_AdapterInfoX2_Get +ADL_Adapter_AdapterInfo_Get +ADL_Adapter_AdapterList_Disable +ADL_Adapter_Aspects_Get +ADL_Adapter_AudioChannelSplitConfiguration_Get +ADL_Adapter_AudioChannelSplit_Disable +ADL_Adapter_AudioChannelSplit_Enable +ADL_Adapter_BigSw_Info_Get +ADL_Adapter_BlackAndWhiteLevelSupport_Get +ADL_Adapter_BlackAndWhiteLevel_Get +ADL_Adapter_BlackAndWhiteLevel_Set +ADL_Adapter_BoardLayout_Get +ADL_Adapter_Caps +ADL_Adapter_ChipSetInfo_Get +ADL_Adapter_ConfigMemory_Cap +ADL_Adapter_ConfigMemory_Get +ADL_Adapter_ConfigureState_Get +ADL_Adapter_ConnectionData_Get +ADL_Adapter_ConnectionData_Remove +ADL_Adapter_ConnectionData_Set +ADL_Adapter_ConnectionState_Get +ADL_Adapter_CrossDisplayPlatformInfo_Get +ADL_Adapter_CrossdisplayAdapterRole_Caps +ADL_Adapter_CrossdisplayInfoX2_Set +ADL_Adapter_CrossdisplayInfo_Get +ADL_Adapter_CrossdisplayInfo_Set +ADL_Adapter_CrossfireX2_Get +ADL_Adapter_Crossfire_Caps +ADL_Adapter_Crossfire_Get +ADL_Adapter_Crossfire_Set +ADL_Adapter_DefaultAudioChannelTable_Load +ADL_Adapter_DisplayAudioEndpoint_Enable +ADL_Adapter_DisplayAudioEndpoint_Mute +ADL_Adapter_DisplayAudioInfo_Get +ADL_Adapter_DisplayGTCCaps_Get +ADL_Adapter_Display_Caps +ADL_Adapter_DriverSettings_Get +ADL_Adapter_DriverSettings_Set +ADL_Adapter_EDIDManagement_Caps +ADL_Adapter_EmulationMode_Set +ADL_Adapter_ExtInfo_Get +ADL_Adapter_Gamma_Get +ADL_Adapter_Gamma_Set +ADL_Adapter_ID_Get +ADL_Adapter_LocalDisplayConfig_Get +ADL_Adapter_LocalDisplayConfig_Set +ADL_Adapter_LocalDisplayState_Get +ADL_Adapter_MaxCursorSize_Get +ADL_Adapter_MemoryInfo2_Get +ADL_Adapter_MemoryInfo3_Get +ADL_Adapter_MemoryInfo_Get +ADL_Adapter_MirabilisSupport_Get +ADL_Adapter_ModeSwitch +ADL_Adapter_ModeTimingOverride_Caps +ADL_Adapter_Modes_ReEnumerate +ADL_Adapter_NumberOfActivatableSources_Get +ADL_Adapter_NumberOfAdapters_Get +ADL_Adapter_ObservedClockInfo_Get +ADL_Adapter_ObservedGameClockInfo_Get +ADL_Adapter_Primary_Get +ADL_Adapter_Primary_Set +ADL_Adapter_RegValueInt_Get +ADL_Adapter_RegValueInt_Set +ADL_Adapter_RegValueString_Get +ADL_Adapter_RegValueString_Set +ADL_Adapter_SWInfo_Get +ADL_Adapter_Speed_Caps +ADL_Adapter_Speed_Get +ADL_Adapter_Speed_Set +ADL_Adapter_SupportedConnections_Get +ADL_Adapter_Tear_Free_Cap +ADL_Adapter_VariBrightEnable_Set +ADL_Adapter_VariBrightLevel_Get +ADL_Adapter_VariBrightLevel_Set +ADL_Adapter_VariBright_Caps +ADL_Adapter_VariBright_CapsX2 +ADL_Adapter_VideoBiosInfo_Get +ADL_Adapter_VideoTheaterModeInfo_Get +ADL_Adapter_VideoTheaterModeInfo_Set +ADL_ApplicationProfiles_Applications_Get +ADL_ApplicationProfiles_ConvertToCompact +ADL_ApplicationProfiles_DriverAreaPrivacy_Get +ADL_ApplicationProfiles_GetCustomization +ADL_ApplicationProfiles_HitListsX2_Get +ADL_ApplicationProfiles_HitLists_Get +ADL_ApplicationProfiles_ProfileApplicationX2_Assign +ADL_ApplicationProfiles_ProfileApplication_Assign +ADL_ApplicationProfiles_ProfileOfAnApplicationX2_Search +ADL_ApplicationProfiles_ProfileOfAnApplication_InMemorySearch +ADL_ApplicationProfiles_ProfileOfAnApplication_Search +ADL_ApplicationProfiles_Profile_Create +ADL_ApplicationProfiles_Profile_Exist +ADL_ApplicationProfiles_Profile_Remove +ADL_ApplicationProfiles_PropertyType_Get +ADL_ApplicationProfiles_Release_Get +ADL_ApplicationProfiles_RemoveApplication +ADL_ApplicationProfiles_StatusInfo_Get +ADL_ApplicationProfiles_System_Reload +ADL_ApplicationProfiles_User_Load +ADL_ApplicationProfiles_User_Unload +ADL_Audio_CurrentSampleRate_Get +ADL_CDS_UnsafeMode_Set +ADL_CV_DongleSettings_Get +ADL_CV_DongleSettings_Reset +ADL_CV_DongleSettings_Set +ADL_DFP_AllowOnlyCETimings_Get +ADL_DFP_AllowOnlyCETimings_Set +ADL_DFP_BaseAudioSupport_Get +ADL_DFP_GPUScalingEnable_Get +ADL_DFP_GPUScalingEnable_Set +ADL_DFP_HDMISupport_Get +ADL_DFP_MVPUAnalogSupport_Get +ADL_DFP_PixelFormat_Caps +ADL_DFP_PixelFormat_Get +ADL_DFP_PixelFormat_Set +ADL_DisplayScaling_Set +ADL_Display_AdapterID_Get +ADL_Display_AdjustCaps_Get +ADL_Display_AdjustmentCoherent_Get +ADL_Display_AdjustmentCoherent_Set +ADL_Display_AudioMappingInfo_Get +ADL_Display_AvivoColor_Get +ADL_Display_AvivoCurrentColor_Set +ADL_Display_AvivoDefaultColor_Set +ADL_Display_BackLight_Get +ADL_Display_BackLight_Set +ADL_Display_BezelOffsetSteppingSize_Get +ADL_Display_BezelOffset_Set +ADL_Display_BezelSupported_Validate +ADL_Display_Capabilities_Get +ADL_Display_ColorCaps_Get +ADL_Display_ColorDepth_Get +ADL_Display_ColorDepth_Set +ADL_Display_ColorTemperatureSource_Get +ADL_Display_ColorTemperatureSource_Set +ADL_Display_Color_Get +ADL_Display_Color_Set +ADL_Display_ConnectedDisplays_Get +ADL_Display_ContainerID_Get +ADL_Display_ControllerOverlayAdjustmentCaps_Get +ADL_Display_ControllerOverlayAdjustmentData_Get +ADL_Display_ControllerOverlayAdjustmentData_Set +ADL_Display_CurrentPixelClock_Get +ADL_Display_CustomizedModeListNum_Get +ADL_Display_CustomizedModeList_Get +ADL_Display_CustomizedMode_Add +ADL_Display_CustomizedMode_Delete +ADL_Display_CustomizedMode_Validate +ADL_Display_DCE_Get +ADL_Display_DCE_Set +ADL_Display_DDCBlockAccess_Get +ADL_Display_DDCInfo2_Get +ADL_Display_DDCInfo_Get +ADL_Display_Deflicker_Get +ADL_Display_Deflicker_Set +ADL_Display_DeviceConfig_Get +ADL_Display_DisplayContent_Cap +ADL_Display_DisplayContent_Get +ADL_Display_DisplayContent_Set +ADL_Display_DisplayInfo_Get +ADL_Display_DisplayMapConfig_Get +ADL_Display_DisplayMapConfig_PossibleAddAndRemove +ADL_Display_DisplayMapConfig_Set +ADL_Display_DisplayMapConfig_Validate +ADL_Display_DitherState_Get +ADL_Display_DitherState_Set +ADL_Display_Downscaling_Caps +ADL_Display_DpMstInfo_Get +ADL_Display_EdidData_Get +ADL_Display_EdidData_Set +ADL_Display_EnumDisplays_Get +ADL_Display_FilterSVideo_Get +ADL_Display_FilterSVideo_Set +ADL_Display_ForcibleDisplay_Get +ADL_Display_ForcibleDisplay_Set +ADL_Display_FormatsOverride_Get +ADL_Display_FormatsOverride_Set +ADL_Display_FreeSyncState_Get +ADL_Display_FreeSyncState_Set +ADL_Display_FreeSync_Cap +ADL_Display_GamutMapping_Get +ADL_Display_GamutMapping_Reset +ADL_Display_GamutMapping_Set +ADL_Display_Gamut_Caps +ADL_Display_Gamut_Get +ADL_Display_Gamut_Set +ADL_Display_ImageExpansion_Get +ADL_Display_ImageExpansion_Set +ADL_Display_InfoPacket_Get +ADL_Display_InfoPacket_Set +ADL_Display_LCDRefreshRateCapability_Get +ADL_Display_LCDRefreshRateOptions_Get +ADL_Display_LCDRefreshRateOptions_Set +ADL_Display_LCDRefreshRate_Get +ADL_Display_LCDRefreshRate_Set +ADL_Display_Limits_Get +ADL_Display_MVPUCaps_Get +ADL_Display_MVPUStatus_Get +ADL_Display_ModeTimingOverrideInfo_Get +ADL_Display_ModeTimingOverrideListX2_Get +ADL_Display_ModeTimingOverrideList_Get +ADL_Display_ModeTimingOverrideX2_Get +ADL_Display_ModeTimingOverride_Delete +ADL_Display_ModeTimingOverride_Get +ADL_Display_ModeTimingOverride_Set +ADL_Display_Modes_Get +ADL_Display_Modes_Set +ADL_Display_MonitorPowerState_Set +ADL_Display_NativeAUXChannel_Access +ADL_Display_NeedWorkaroundFor5Clone_Get +ADL_Display_NumberOfDisplays_Get +ADL_Display_ODClockConfig_Set +ADL_Display_ODClockInfo_Get +ADL_Display_Overlap_Set +ADL_Display_Overscan_Get +ADL_Display_Overscan_Set +ADL_Display_PixelClockAllowableRange_Set +ADL_Display_PixelClockCaps_Get +ADL_Display_PixelFormat_Get +ADL_Display_PixelFormat_Set +ADL_Display_Position_Get +ADL_Display_Position_Set +ADL_Display_PossibleMapping_Get +ADL_Display_PossibleMode_Get +ADL_Display_PowerXpressActiveGPU_Get +ADL_Display_PowerXpressActiveGPU_Set +ADL_Display_PowerXpressActvieGPUR2_Get +ADL_Display_PowerXpressVersion_Get +ADL_Display_PowerXpress_AutoSwitchConfig_Get +ADL_Display_PowerXpress_AutoSwitchConfig_Set +ADL_Display_PreservedAspectRatio_Get +ADL_Display_PreservedAspectRatio_Set +ADL_Display_Property_Get +ADL_Display_Property_Set +ADL_Display_RcDisplayAdjustment +ADL_Display_ReGammaCoefficients_Get +ADL_Display_ReGammaCoefficients_Set +ADL_Display_ReducedBlanking_Get +ADL_Display_ReducedBlanking_Set +ADL_Display_RegammaR1_Get +ADL_Display_RegammaR1_Set +ADL_Display_Regamma_Get +ADL_Display_Regamma_Set +ADL_Display_SLSGrid_Caps +ADL_Display_SLSMapConfigX2_Get +ADL_Display_SLSMapConfig_Create +ADL_Display_SLSMapConfig_Delete +ADL_Display_SLSMapConfig_Get +ADL_Display_SLSMapConfig_Rearrange +ADL_Display_SLSMapConfig_SetState +ADL_Display_SLSMapIndexList_Get +ADL_Display_SLSMapIndex_Get +ADL_Display_SLSMiddleMode_Get +ADL_Display_SLSMiddleMode_Set +ADL_Display_SLSRecords_Get +ADL_Display_Sharpness_Caps +ADL_Display_Sharpness_Get +ADL_Display_Sharpness_Info_Get +ADL_Display_Sharpness_Set +ADL_Display_Size_Get +ADL_Display_Size_Set +ADL_Display_SourceContentAttribute_Get +ADL_Display_SourceContentAttribute_Set +ADL_Display_SplitDisplay_Caps +ADL_Display_SplitDisplay_Get +ADL_Display_SplitDisplay_RestoreDesktopConfiguration +ADL_Display_SplitDisplay_Set +ADL_Display_SupportedColorDepth_Get +ADL_Display_SupportedPixelFormat_Get +ADL_Display_SwitchingCapability_Get +ADL_Display_TVCaps_Get +ADL_Display_TargetTiming_Get +ADL_Display_UnderScan_Auto_Get +ADL_Display_UnderScan_Auto_Set +ADL_Display_Underscan_Get +ADL_Display_Underscan_Set +ADL_Display_Vector_Get +ADL_Display_ViewPort_Cap +ADL_Display_ViewPort_Get +ADL_Display_ViewPort_Set +ADL_Display_WriteAndReadI2C +ADL_Display_WriteAndReadI2CLargePayload +ADL_Display_WriteAndReadI2CRev_Get +ADL_Flush_Driver_Data +ADL_FreeSync_PowerOptimization_Get +ADL_FreeSync_PowerOptimization_Set +ADL_Graphics_Platform_Get +ADL_Graphics_Versions_Get +ADL_MMD_FeatureList_Get +ADL_MMD_FeatureValuesX2_Get +ADL_MMD_FeatureValuesX2_Set +ADL_MMD_FeatureValues_Get +ADL_MMD_FeatureValues_Set +ADL_MMD_FeaturesX2_Caps +ADL_MMD_Features_Caps +ADL_MMD_VideoAdjustInfo_Get +ADL_MMD_VideoAdjustInfo_Set +ADL_MMD_VideoColor_Caps +ADL_MMD_VideoColor_Get +ADL_MMD_VideoColor_Set +ADL_MMD_Video_Caps +ADL_Main_ControlX2_Create +ADL_Main_Control_Create +ADL_Main_Control_Destroy +ADL_Main_Control_GetProcAddress +ADL_Main_Control_IsFunctionValid +ADL_Main_Control_Refresh +ADL_Main_LogDebug_Set +ADL_Main_LogError_Set +ADL_Overdrive5_CurrentActivity_Get +ADL_Overdrive5_FanSpeedInfo_Get +ADL_Overdrive5_FanSpeedToDefault_Set +ADL_Overdrive5_FanSpeed_Get +ADL_Overdrive5_FanSpeed_Set +ADL_Overdrive5_ODParameters_Get +ADL_Overdrive5_ODPerformanceLevels_Get +ADL_Overdrive5_ODPerformanceLevels_Set +ADL_Overdrive5_PowerControlAbsValue_Caps +ADL_Overdrive5_PowerControlAbsValue_Get +ADL_Overdrive5_PowerControlAbsValue_Set +ADL_Overdrive5_PowerControlInfo_Get +ADL_Overdrive5_PowerControl_Caps +ADL_Overdrive5_PowerControl_Get +ADL_Overdrive5_PowerControl_Set +ADL_Overdrive5_Temperature_Get +ADL_Overdrive5_ThermalDevices_Enum +ADL_Overdrive6_AdvancedFan_Caps +ADL_Overdrive6_CapabilitiesEx_Get +ADL_Overdrive6_Capabilities_Get +ADL_Overdrive6_CurrentStatus_Get +ADL_Overdrive6_FanPWMLimitData_Get +ADL_Overdrive6_FanPWMLimitData_Set +ADL_Overdrive6_FanPWMLimitRangeInfo_Get +ADL_Overdrive6_FanSpeed_Get +ADL_Overdrive6_FanSpeed_Reset +ADL_Overdrive6_FanSpeed_Set +ADL_Overdrive6_FuzzyController_Caps +ADL_Overdrive6_MaxClockAdjust_Get +ADL_Overdrive6_PowerControlInfo_Get +ADL_Overdrive6_PowerControl_Caps +ADL_Overdrive6_PowerControl_Get +ADL_Overdrive6_PowerControl_Set +ADL_Overdrive6_StateEx_Get +ADL_Overdrive6_StateEx_Set +ADL_Overdrive6_StateInfo_Get +ADL_Overdrive6_State_Reset +ADL_Overdrive6_State_Set +ADL_Overdrive6_TargetTemperatureData_Get +ADL_Overdrive6_TargetTemperatureData_Set +ADL_Overdrive6_TargetTemperatureRangeInfo_Get +ADL_Overdrive6_Temperature_Get +ADL_Overdrive6_ThermalController_Caps +ADL_Overdrive6_ThermalLimitUnlock_Get +ADL_Overdrive6_ThermalLimitUnlock_Set +ADL_Overdrive6_VoltageControlInfo_Get +ADL_Overdrive6_VoltageControl_Get +ADL_Overdrive6_VoltageControl_Set +ADL_Overdrive_Caps +ADL_PowerXpress_AncillaryDevices_Get +ADL_PowerXpress_Config_Caps +ADL_PowerXpress_ExtendedBatteryMode_Caps +ADL_PowerXpress_ExtendedBatteryMode_Get +ADL_PowerXpress_ExtendedBatteryMode_Set +ADL_PowerXpress_LongIdleDetect_Get +ADL_PowerXpress_LongIdleDetect_Set +ADL_PowerXpress_PowerControlMode_Get +ADL_PowerXpress_PowerControlMode_Set +ADL_PowerXpress_Scheme_Get +ADL_PowerXpress_Scheme_Set +ADL_Remap +ADL_RemoteDisplay_Destroy +ADL_RemoteDisplay_Display_Acquire +ADL_RemoteDisplay_Display_Release +ADL_RemoteDisplay_Display_Release_All +ADL_RemoteDisplay_Hdcp20_Create +ADL_RemoteDisplay_Hdcp20_Destroy +ADL_RemoteDisplay_Hdcp20_Notify +ADL_RemoteDisplay_Hdcp20_Process +ADL_RemoteDisplay_IEPort_Set +ADL_RemoteDisplay_Initialize +ADL_RemoteDisplay_Nofitiation_Register +ADL_RemoteDisplay_Notification_UnRegister +ADL_RemoteDisplay_Support_Caps +ADL_RemoteDisplay_VirtualWirelessAdapter_InUse_Get +ADL_RemoteDisplay_VirtualWirelessAdapter_Info_Get +ADL_RemoteDisplay_VirtualWirelessAdapter_RadioState_Get +ADL_RemoteDisplay_VirtualWirelessAdapter_WPSSetting_Change +ADL_RemoteDisplay_VirtualWirelessAdapter_WPSSetting_Get +ADL_RemoteDisplay_WFDDeviceInfo_Get +ADL_RemoteDisplay_WFDDeviceName_Change +ADL_RemoteDisplay_WFDDevice_StatusInfo_Get +ADL_RemoteDisplay_WFDDiscover_Start +ADL_RemoteDisplay_WFDDiscover_Stop +ADL_RemoteDisplay_WFDLink_Connect +ADL_RemoteDisplay_WFDLink_Creation_Accept +ADL_RemoteDisplay_WFDLink_Disconnect +ADL_RemoteDisplay_WFDLink_WPS_Process +ADL_RemoteDisplay_WFDWDSPSettings_Set +ADL_RemoteDisplay_WirelessDisplayEnableDisable_Commit +ADL_ScreenPoint_AudioMappingInfo_Get +ADL_Stereo3D_2DPackedFormat_Set +ADL_Stereo3D_3DCursorOffset_Get +ADL_Stereo3D_3DCursorOffset_Set +ADL_Stereo3D_CurrentFormat_Get +ADL_Stereo3D_Info_Get +ADL_Stereo3D_Modes_Get +ADL_TV_Standard_Get +ADL_TV_Standard_Set +ADL_Win_IsHybridAI +ADL_Workstation_8BitGrayscale_Get +ADL_Workstation_8BitGrayscale_Set +ADL_Workstation_AdapterNumOfGLSyncConnectors_Get +ADL_Workstation_Caps +ADL_Workstation_DeepBitDepthX2_Get +ADL_Workstation_DeepBitDepthX2_Set +ADL_Workstation_DeepBitDepth_Get +ADL_Workstation_DeepBitDepth_Set +ADL_Workstation_DisplayGLSyncMode_Get +ADL_Workstation_DisplayGLSyncMode_Set +ADL_Workstation_DisplayGenlockCapable_Get +ADL_Workstation_ECCData_Get +ADL_Workstation_ECCX2_Get +ADL_Workstation_ECC_Caps +ADL_Workstation_ECC_Get +ADL_Workstation_ECC_Set +ADL_Workstation_GLSyncCounters_Get +ADL_Workstation_GLSyncGenlockConfiguration_Get +ADL_Workstation_GLSyncGenlockConfiguration_Set +ADL_Workstation_GLSyncModuleDetect_Get +ADL_Workstation_GLSyncModuleInfo_Get +ADL_Workstation_GLSyncPortState_Get +ADL_Workstation_GLSyncPortState_Set +ADL_Workstation_GLSyncSupportedTopology_Get +ADL_Workstation_GlobalEDIDPersistence_Get +ADL_Workstation_GlobalEDIDPersistence_Set +ADL_Workstation_LoadBalancing_Caps +ADL_Workstation_LoadBalancing_Get +ADL_Workstation_LoadBalancing_Set +ADL_Workstation_RAS_Get_Error_Counts +ADL_Workstation_RAS_Get_Features +ADL_Workstation_RAS_Reset_Error_Counts +ADL_Workstation_RAS_Set_Features +ADL_Workstation_SDISegmentList_Get +ADL_Workstation_SDI_Caps +ADL_Workstation_SDI_Get +ADL_Workstation_SDI_Set +ADL_Workstation_Stereo_Get +ADL_Workstation_Stereo_Set +ADL_Workstation_UnsupportedDisplayModes_Enable +AmdPowerXpressRequestHighPerformance +Desktop_Detach +Send +SendX2 diff --git a/atiadlxx-sys/lib/atiadlxx.lib b/atiadlxx-sys/lib/atiadlxx.lib new file mode 100644 index 0000000000000000000000000000000000000000..88bada1f606e5641056a25cc93a63584172edc5d GIT binary patch literal 345274 zcmbrH4V+X}`Nz+_ca{{Dkcfy75s?rTkv9>E*xlJ>7k8I!cUg#tadu~RcVKpAota%0 zGE*WmGcz+YGcz+XGcz+XGcz+YGcz+IGb1xIGBYD0BKrT%x#!+FuXl$2em-BH9nSMS z=Q%I;+j zONhI7KXLyulen*JAnsr9@p*L#aTyOng1;^2ApLLPwfUT#kl^ogIJZE8eN#BsK!Sga z;amv`_8-gH0SW#|I2S=u_W2yxL|n#;klz8fv+*(b&Z^dA;D4j&3FJ391Z`ByCA{XIh@-e!7=d9pnrp7kw4>3NO0U@&b^Re z9Q-j5>p1ZGd7L{S!T8fT^lxzdTn>C44<glIY=;bfb$Y0I0e5MussFL zI-m12BzS8F=NU*a8~zxtK!Q^d8)eQU&TWw3wCS8{A;IaWf5r`v;EY+E`ys*HIOi!y zaOOJBlaOFu3+GWta8?rswr7F)%Q^IKumJ7BxDOI6tmE7R2^OJ0F>Znci)V7Kg9K-z z{u!4+f+a_BE`=HW00V>i}Nfbs2kwC3JL0wFXIp-h+pi}FoAfCn;}8t5)SIT5v+tC2HJKd zXew|HK!RrYp{#N_mqUW{5I^G@NYFBob1fuj#c#$Hkf06r4Ae&(1$9GNy^TZv2JI!z zUP$nc9?mn6preEHC?x1aKVsYm3A*NTZh-`ArgE-^1l?#y2J-2qyx_BTJ@FV%K!SB` z9Mt_f@XjXALy%zo3J%(8J$ToA&TWuj!*mYnVgqsGg3V}m2K^gk$8&Z-QV#eGW{Jmm5fbE3F2*yEAm7D#91;wz z=j?$57xZzUdjTl4aiCiOMYI>=X-H5?abAN2!y_ETGYm%Xo3S4fY#HV3g#@E$2L|#Q z1zS5fk3fQLan5~^;5`dDcS3>-=W=d`1n-^0xdjqjgmz%;gaq$f%-IDAE?&yH8xmXs ze+=}sOThM-oEsp)`=@fQg9JO!4vfnn!3ScTiygaOt;dahLkl>0XoI4=FN6_CG*Fu6T$8j!&1Rq75jO~yV#7Vgd zaWP(j1Ruk1#z9DM^+g=$UJX9Jjq@rbxMqO!JS6x8elw8v32^Nw=P)GrB=V+QH->XL zB={8KWn2XbuAjg`?AKEe3+2-V4*K4w!3`x2(ry5s*~Zxq32q$Xpw4dupWVbkte*up zt>-)o2|m}&c>)sL+{AeR5`2C+=Uzx~3w|>mgaluJKI2hHuoM0m$ZIF~;zkbr8{FE* zc@7eM3Hpr3Ai-^`IP`DuDnV!Pnb4PeOvb+c-$O8+@aYgFgBVu&a)Py4wZ5xr_tdZ-RSJUyMf} z!MD&JjNOpnUepHzZE-L7b_)l(-v;-=KjVH#@Esf%43zyl;QqOsosi(WQ#dH=cfkV_ zIoCsi@1cGeS3`maXK`+Z1mB;@xfK#TG>3B&B>2HJ4t)IpJUp3mEhP9M@?*gF55Xf7 zIG00$AGw@SNXn}|j}8!zu?G_Tcs=JSNbnebGth@013y{Ec^VQt-o-(kKMsD1dSjrC zehQvw0u7?Cqj_2%vr0nzgd6syL7a+k?8#svRDe#LX&ZCgvX|x{$F+2@^ zxq@>SB-lNZgSOiZel>@Ky8ab-W;zEkJp+C{k#hwkc=lKh{TuvdEN43;<$%v~IpQ&1 zf&{Z@48;60_{%cRLy+K= zRh%av!CyN#PeOuM+c}Rzg1;di2K^hnhTn|GAi>|^kMSTR*tdd%*!O{d)NzpaKfr$I zGw9#opU`LA3keP&UIxl~0Q_q?2fF_P2jd*%brAd;_6*qm8ys55xf2rnXAb9PNN^ax z8K|qn;J@(CKwbX#ei9?gI1fMqC(d~U61Xj##~^`+-;5_9L9C1OG$g3$<~#)n#^5*O zIY{uj9?naU;HWHTA0#+B$9V-3j72(QFC;i-fCJlOz_ERt7a_rM@XtVA$ANJhIrMMv z`VE|CAi;Q~GoFV8$HO0k{tYG|ok9NwZ$LWZ1xPTlhl8|<;Enjr*aHbB!JhFfBzRK? zXE!96+{Hm%P6ltTRoin9%p@~Y2N#Kk~NQ^5&{gMmCx0MpiSkjFG| zViV^|=gEIy=sFO3m+)bR< zAiV_Xdh&YI0ZtY?Aws6WOtkYK_2oV}1>A@XG)hJ|2JjXUmf|dBq zxDygI&E)Ka1kJNKh`AZ8!f(dykl?&|9Q4`qK+Am2ZIGZ9>ws25aYr(o@ zoL!LMoyd=IA0$}6kb}Bh58j3PVB8D|HcaJQ4GG>oma`p_a?oevD2Xu+K!U`@oI{Y{ z{1MJ8kN|TDJ}*Fmo(-HQAVF^v=N?FqLYxe=K?r)lugiQTnGs^<2PdmB*@}71HQ79mwg8NNQ|)u66Dr%&=xt6@8CQM35MD@ zXzL+x0n!<}Awgjs2et)JM1NpB4hc$)ockfc@L~@A8;ry`k3fPg&}Tdd2}YN2?uG z1qm)`=j?_A+q*fagYDq`s82Em&MruB>3q&kNbtcaoGT&0WiAJ8 zdl?0NgYuzm9F*xp;PMg9tB~NsSq{qdVQ|GJ4*J6t;3EYNY(E07gm216$8wPON5NI& zIX6Rsk0D;hBaqRRmNA@*Ai)=69QrrdiF#t73_B^W`Fs)W#dsbP zU_QZTFC_TVMh?pGC2(5@=P^j|<@KDGAi?eE9}Lvf?cgiOi*XPV+<|lk((V9X9pxae zuYx-_aCSq2ueEU=f&_OhXgK z!98dP26XQM-9F`!Glvc*Fu8tkKI(G z%#j!aW%?m_1m$ELf&@Rh$mda)#2DKl!H@BqF#<_J9Z(+I#CaJK{G`Bn6%st2<)Drp z2R}u2q)&Sj94!#>Y# zBQeGSNbp>vTd-${L;nW9%W+n61+H_ za|R%`a zeO?(NF$Vg=E8wr_4~(ZF!K?Vqcoq`;t)24(BzO(K8IM4Mzpvozf&}~KanSbrz(3GG z7}rCB{o^@1ASq}c%0EXruRwwWJsiYz0Q{?wb3Y_FxR8T94uXH9J{db9!J(;~t02LD zVjSf8A8^>^(7!2&f%0F(!PpPEpVW|ToWqd7+2P}kB{htzAb~f5L;nV`ahxk4LCsN| z%OJs+F`P>w!Run2?U3LomqY&sN5h^$|E3@o%GgoPK}c{6;$<9y1jphx;{YT$ZiMp+ zBpBDn*#ik)zmD@bBpBbtc?J?-Zo%hyNH77v8G9kY8*-f2Ai=}}hyD#Px8U;vB*5H) z5B(dwX%pvFNHBSbL;nVEhCjwWNH8VKf$bFVmKM%KkYH+@L;nURG;tn=1k;etcn}ht zxPo&pB*46a&pnXfB&0L$g9I~>ALCg_a5Cbf%tZfS+yn_unZel!31-dZ+zAQZI*&vD z2D6uN5W{S6>T(WZJQd98=In+9r{Oo_DM)a72M29`k2g zkYLGnpL5`!0o!xH(y<&ITT8*YlQ=g*f@QNfsOx3mZTQWge}m<-IrMMv_BoteA;Aiy zGvI3lsGZ2U91_&IoNbVxehlX_NXkB+csHqucPA3ft?jEjx)Sk*&ian#_O8_(iDW60 zOl3z$Ng~m z{9wE=l31B8!E0u42s#xNLzQ@@IFwCpP1L56L#1>fo*v2crn%>aQIpduEXv*sBk^P@ z*_G!W6ZQF_t!k7A-k=ovXw2kN_1SzeT`aZcQ)yF3CY8{>xrjnh%Z3YvlUb9wK_j#d z0O}2uDwB_=QLVM9O~b{~AR4PV*O%AwuB2=5nCL(~CcqSp6@e{V0O z`_ctN|Iu~ieEl3~wW80cBV3TZreyW8pc)^(lGVq;YJB)gHXl`ZU@9j2mQ1mfz!;qD z$;yL(TpN;_(NDgY9og;4(m;iHT2xipUvVhii(YAK9U)n^qoZW~Kr)w0XFG>*Xw>I( zeVP8@f6Y{e>T`H#C|@Yq+N3Vhpn~t}oifcz-YjE^9%4cpU+VJ7LaHUXH9u@GsiGo9 zV>ze!XDwNCATxyQqZ+7QQIYNGiHx3ntcM9Z)s;15Yj$9?rU&zdtu#2(IO-off{xvT z<;apeP#uGZ;X=9-7X;SxM{o!WTB?^E1`AwJ&?`P$Pl6X!E6Pg;DrUqu7AlUoVw5jS zZ&VygwFc{hCqV#poE8ExjmsAnwk9z7-Q`CK> z{2K>;-_ViIrfpYy3FgwKZ}rSi`nDFKVRD~>W~4W3e^Y$vv##8!36v+wt?$XrSr4wsDM zvC%72w)%`3{X}=6p2^e7u6lZ|x7M0pSW(O5#oi};dp}*aEZ}CVfWx7b$@Saw*R`U& zSPs9q>_s~U8|v#54TVC!(45=kpM%-xWayL@O(~{Orz72)FQlwxGwR8nFr!svTxLzP zw@PsZzC=C6Q**pEnZsB`=Wncy-w@Z;WIuz$IFsX&hs|DD8m~c9l6{OuUVAnO$&y`T zI$6Rsn>BbTUA8PF2h*+TQX$h@w3};6b{~yYHy+&G;n20+F)_s;XR}qcx!A|Ih)hiP zXA$a_6KMsDYD<9Y#DYAn%Wv}|{QEZ5=a4tvP()?`6TAOvYDBxbkg}_;)RoHFiSxMW zYCy?KEeo!F*R{_F=dYdB(fHaic>-UOEtq$;o%NffrFRPXw41rN~;l+t=6*gfLCENRHysS215;$B<>1Y1NcuA8Zzdc4zB+ zvOkGZRh9#gK1118}B=)Cs|4I(KbBT zlP;|8W6vuvFNIsl&irrz4{dBUT*1QZ-9K|z_9^N~o>uo1(>N>9r=h)@qef)2qU5W+ zwI$z=!!L)!i9P1C#%0kod9z)ta2G7uXlFiA2WILSn*V$B9Jj6{=UhlPW-~+W`67Le z&YsWZ`ormd!?_-hup$hq@NK^sHM=%lhnh7p5+>+qJZySGo2Y10MeLpFEN&SSEo-_G zwb}lBAyXO{G#&Nkyo}aImTTQ`pXC8!#VomL75S~n70cy3(i~03N}id)Bqs1J=dJca zIoW7uIc*1a+PS);wzJCnYKx{6g;{6ad{Zy5>dGFIsWcWAv^2yMcm|2JCs<^V&y@=K ztnI3xBih2`eNAVbltVbr7UX3e_IPGhI*7`yRv14@t;3^1i`&Z3Y0``KWGRQ{NvqXRBl32@pk$qKSPKtUvVyhasVbH@n7#RAt$2Wv>;vcJ z6rLHxF|kof^ef8;`DA3brX>5oU0%K}lP^XMdfl3m?xSk}^V#VFy`8J*%A{M_qphiE zaH>bGz1Hy~s=^>Yn>8aJ~; zG=(h-Qww=ShS7PkIaxaKYHS}{M!JFyvyfvgPtW)|%C<+I+O3OD~F= z2Q!KCf24I~uHUM1pbJwm3nPvF<`RTK1twAcgI=wl(ag?eeXD02teAl+b>-{xgG0$) z`6-LRv!-wL?9T+(7Sc)FoQ))V^?N>pd$W->4_r3XV`+JQFtd#v@|7xG)3IA%8Jpx*5s;*j(Ov%zCXH1EqKeVGdVbvO?Q}{HAbj$Kc#%va1OIQ^ui>o zPdg18(wSx5>eZcH^wP?>Zp)BrvQjRy6|3;>p^iSy=^aRBa*6Vv^cF|E=_@B2HT@W@ z-jtKM-5FJ^;7cu1IncN7XVcX?=HV3!08TjZDN_8(B9JhZAGEpJ#U>p3n8;>7%9N)f*Ko zw&?Tn<(qEpt61#S0&97fOFWRtW?64lufy1-ojB1!5CSZUd{bfcxA(nQ0sU#lJsRVCV$YpJ`#Rzx|)kB+avkFRcTH>_X} zR@95hHamGn)L_@PqcUWy>6ko39Fp8V(BRhW5b#&)_^+=7 z$Ac7sRmX}URxcBR1IQ7P|8A!%0frVizHZ{<-v(4n_!t;wMwoQ1SYh_r_7{$%_IJ+r4g8gR{#FL1`qC~la=H%)Q}@g4zYE- zrHsBxH7uN}BYU6+Qq+LMI(Dd_+s5%oQQJBq%$s^IYuK!9HCDFP>y4&$r3W!p$X;&p zm+JCk%yta1vP2r`5o+p3=A3C)<29-d^cc+b5gD2#65G*P9?+EN*<1PP6mMev#xUr% z{u&fTQT0{AgjbrbE3h4ASPLksX!ckrn8m7XJj0VVS_(U?;S_^McyxVXq*=B3m^Lsd zcYbR=q1h4TW9=f*`RILxO)%gMq!hg|ppW^mlHJ+@R%JPMO|5!|hMp;T!xfYCLU&lf zx>iI?3GBs%i+SS^D?8$fQNE(iN5K5e&5!OSQwJtwn7)c-U%+if$ivUsDgK)}exIJ3KhJwL4QN z(LE`HIS7*rlb+p^?U)z6Xh(cQDw7JYOAIkc=~CWdilqUiblDQ`>+wpqUP#h+`Xn96 zLt`e3b&Z{D-Kgz&)^zM1EG3XUXnhb<>%H{g54ww``b}zbB#IwfFa|Z%52pHy;j5MQ zcr>+0KlXSeKYIOOIe6#RTyNwkLD!7SN^&exvMmx#$>@U)6s9w45CTh=Eb(sla0x>p zoxQU4GEK+sL3=10_8c)E;km3a-BJls99mnjRO?77r0UT}7F<6^`o5xq)Xz}psqs#B zNoi^yAyta5DPE5Uc=BWJpvJ;9-NF(Yv(W0TDc%v;eWi3IFK%hgPe_+6n+LJ&OvC6< zGFQZt5nBljT2WpsQ7B%t^3(HIJLV|ylBuPp6%9Ftvb8OLSwpri2B%0{){=r`+fpCz zNcR=e#R0l_2nW7DU#2a_4f;!@euU@MY+=3iBqqBRm8t7jTk9FLA|kV0 zg)3h4Sm;*L_DU+JN_o@A+ffrbQo3eI58GjDp43**kgYL0B5yqqUd0)%kLX;AMZ1Dm zIs;>PJj*Yib-#jsHJ%sP+T7yV*RR6!k@;oX6}%ovEpXk+9xaEDUV46aS;^xO)aSaY z>M~+xN)Iwnt`KGQZBtFV*p7EYc-k>fb&65p_=#G1icy*Ri3XeK9#l-2drdBb-Spe@ zTY@`TYnL%8N>Q}oJq)ZNUbBvGNr|n^>9!K4%Nd)h><=%TuFV%VCky%ETne`ki;Uah z2dA&L2zA*n-|d7OS{o?X<3!SvJgttiok;k^m!;-(C6kY+;gx#`Rb+cM|38%Q*ZY;9 zZkwvze^y}7HF~s_hi9nucIqAT5!S0UDP7BvSw>_Trc0K>a;gdsz$}_JZ?>aWaHEeN zVxpxes*0RHUkPN*Tue7x+OiESwN?ve;VRtXnbgz>*fby=^CIGxbrcU6gw_q=g0<*> zI04HF?Vc>Ul|5Q($l%dXTcXxTCXE<7tj`G8uo{*~(zeCfjbkX{jz{n)YTCTvODv_l zzY7%~q%5})f?u;u^*L0oUp)uCp4s;@3j8^eEoe??CraWy|usm9pEZKF^N4dr|qx@!2Rk|r?+>CQQ=bUaO-rt5N)g{<8I6l2G#J&+{8%V{%=@$0*I`D>lA(`v9b)s_3mNo6(5FI;LSbAjH zS*RG{D;WIc;#52)nj1h)DQ9Z&_?mTuy13p_~EEo>PDTf)m0Yzty~tAd+^ z+7fmx?7?SMthw5?tMO`!%w^bRgNf75@*_MwQ19pJ+hq@)pcx|Y?8?MM=R=%fD{oPP?PbefmWE!lh+ zw4^wcbW6`MXz5<)#Bk(|Bl99_MR|#erR+uP$K_o7P8C@*%#WaFj;EpvOY2bYw)^ie zO#KeL8?Q~;-z*bSrD(e|=`HQ_Q=912rg23|H(Oec&d`#kn=LJE6U1EYWiQ-FAkMi4*);@=BaT#d( z-q;tk)(oKoVGj#O-J`YyO?qR7=Nobo{y{*CvYqfs{6p33@>V^U+m-A-ghduYMH)Q`suley)e+?{tP|;lcjW-k(pUtI?VZ~7 zZTN4Y1~M?VG}V;SbPHT-$m`c68$VUIq9qb4Q?j9HzC}k@JvMFA;}`#3(v)Hq{c{T` z-E65wrdpPxYLo?kCSu|KIhBPGxi$-XT7x=JxPpt=P zC8YS;y}8DRON2Q91=3<;}xUMiMKQjl$V-iA#(!|W9mi~Ry?ordx}AHh~qvDzzTHQ9&bmzJnjwOPTO zw^mu@Qu~oJ1=W@oS-r{;at)I;yGScPF|=VXsrVCVrV)_lXHv1+8|qlKm+F`$`tNm{ z%Bm*I`TBOs)lwL8In`uk3)HvLV>DJO3s0<3x>q89hEH2hdrsJDRPf^ylNMC64HY!o z3YI~#ZfAJcOAHr}I{a;GbW5}VuI762qG3TWH#G_7YnrGmNt=9vFr;UFpH;qhUr(#q|udyASFsR z>|4V&n{pzvX-jWOykj_B*vj@NGQA^b(O}ke#b1ivYAp&jGi3|AG9~RDgbJFfH*7t~ zzBpnUO9WS%n$1sFK3F}dRHeb0tZVbAj^hSLQ(u*SA;R(N;Og8*bse&s!?%PTcg5x%2G8E{Zfp|czj3-)zz5sI1%=hi3ms4 zQtJm_M8Oe~^|x&+Vqdpm>8pT3`AwR#x5e1&V}u@Usc>Ue;lvcWGN`G3aD@|Yjnpt| zE#6|L*a1kEd=E4dtWpzW8{#U+i;~&eq ztYWp-Cj8{;@;wOiex~HeD)K!T>t=Y{wynIUVG|_#kcP6DRMj%kZ!OcUzx_L#h`wo1 zRDFpfTZJ|=s#fCCt3I4FS zyc=DG@zAcX#$?vC$7t8D=vf~4%;TiyUN+M5DA!12pAxPxxL$;(h`uTKVOp9O|4OC0 zv5#M@sLB?f>@-L}Ux7PW`?-PpRF$jn8PVi^p+uilS@qeS&zA6rfEOn`gv{-1QI7T* zQEu6vv27F;dwC6ta$HM-`)qow(g$+-Y;rgv*mNs-)Mk|S^O_tZ8d$@L{iJ!3R}RefR?cyTvg)854?RP^{p~9+Tp$Qd|)&CVDcqn50l$ zM24faE#dp|7iX5giEKLRZMx>#5M8o@5UBHDo6 zca@bQeAo*p_%QW`&ia<~=weh_0M=I{!ZGWrQR!Ot;LN(3N4`L+VN`o@L#TJ;!j@45 zT2WpiA`-k9>x+F2uZpAE|7@P5s6{0EiU>+qjPe!Lgn}pIQ7wjTJ^i*NG&MCI^`6Rn zJgZu|7rd)uua_=7?lg`mT?2)D39D+@#vc4rtP!x8o@$Y>i6`^+bb>5}j-lM%CWFR*NV6H|}+9up&jd@}YXdc&ch^ z0fgG++&flxcXrS|U@oU2+0R8uP_r^5`*ye&Zq4-L;{kM|32U}?ttc;Q5N0n_%lDEl z(B(lZbS(p!^82th>DsooIKNbNhMW>TOO=jFfQX3U0U_4 z@*GihCdc6&QKbmfek9bS$#1z=35qTFm}WCx)WiZ(!zZ!C2n?E9=@p%b01cX&HIq78WrfGKxIK- zq@E$7<_7i-o7(%Ot{~``JYX6+gHLsBi|9;r-k9qcJhbKeXfnGh3l0r?;~TY&Uh$#e z;Pyed^s)8>>3%~nF!&B$5mQh5a_vi61~2@bytOzEvuMWJRB{OCZH#^RF1mUtAbYN8 zc_g{%BW;zLal`8K>PX^)fb9D0e=440UVXl6+dI+0=}kt0ZqX_4#ZgsZbr1hj?#eaO zk!BrUL&=6~8{_`vl^Td~HB+EHHl&BhS~t6EsRXNtXf%!E;G`H_oW z2eN8KfAYhYD0jh=7EPxmliN%egXM6YV;|g5nUbP8GGB!*ey2CGbhp`|YJ4gN5x#My z(OYe(f^LLI96*VRr>mg!qO#fN+IVL>KcxL_fvuxDd}_)jpL`JJ*I51@UHCy?K0~t& zVh{6(R;$8T$P;gKZ4K51HfEFkmJ*oNn4ivGyds!u&u4I{%)XP3jc;sUS*@t+d&Hfi zSU^0(P5Cnw^e_4HmH&%xH;7}+-|yIe7LYLA)39fCX00eM%2kQQ3)L!n!6!fcO;p*S zp`AyW50j4MK|QYrR_xy;O<@L1=z@X1kZQ6rl@GCTE4f_$BT?)IR!XjNA7>S zR=tM6w`~3F3~G^nZ1E_5%Iy(k#MjI6Vksy0FdSV=j>dE%42{D?*@hlu+VodwR8Hkq z^tGV`n{Y=DmJaihoaF1XeP6`aZWFab*vqDuop1DPt59ctySi!D&ZY2adA04-Bu!sw zBT+wWm*7c&zhPl;>93U7uH@%AT4udr8$D*P4;8{Dt%TiHUJnO~9R^_PZ@$WDt|J%fne z%4ZSrU*qZY5UP!B1f?(RsGzCkuXu~7HiKrQx2Wb6eKEagPgO?6P8hl;e}c+yM$<)y zRAolxDttzTsQEPZIetaCGR+o>qV3rwrE;<`#i|=<@ix@go0c7m-b59XeRNlYwYYXj zajXv{!l4aQKi!mTR41Z_;hnCUV?=vUJ7Wt3M>-ZM8D0()b1-OX(fc|xI`Zk@ceJT0GL3N_uUqUDWGA%BmIp zRjksozleI|^L^=5SAGbes_)lc_SNGwo9OXo^F7IIL%f;3oLZz$it)N!)G@TuYEY%` zs2VZ)Hr7i^K8dH1*ipWh&Alm4dBy55XljwlIuRqNu2{iWL}_JT#!`0Fb|%>C<7^$I zc6}@s)1<1!rYdPKw?ujLl{KH8@#fBS{~(^NnYIZL9U3%E-Xh0-_^^!qG$o?tf@EWk z5v@e+jBVrJ6Gdjp?&i#A9Bv(zv2Sh6drhwB-$bNS{2~D39B$kE$tCG}S~zc3uwpf{ zE}f{uI!1p+1wwn4XI3!S29M-~;aRo~6ariNgce`Wz)OU4}v^L(e-wcl)wN?WY>7D%4d_mj=rU^^~yI zQbOOpUM{7*hPpF7e4UhXw8{=-HN>8%#RL|g@xXjqz6≫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 KCmi0fo$)^=|CQ_j literal 0 HcmV?d00001 diff --git a/atiadlxx-sys/src/adl.rs b/atiadlxx-sys/src/adl.rs new file mode 100644 index 0000000..3966e6c --- /dev/null +++ b/atiadlxx-sys/src/adl.rs @@ -0,0 +1,8540 @@ +/* automatically generated by rust-bindgen 0.69.1 */ + +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +pub const ADL_TRUE: u32 = 1; +pub const ADL_FALSE: u32 = 0; +pub const ADL_MAX_CHAR: u32 = 4096; +pub const ADL_MAX_PATH: u32 = 256; +pub const ADL_MAX_ADAPTERS: u32 = 250; +pub const ADL_MAX_DISPLAYS: u32 = 150; +pub const ADL_MAX_DEVICENAME: u32 = 32; +pub const ADL_ADAPTER_INDEX_ALL: i32 = -1; +pub const ADL_MAIN_API_OPTION_NONE: u32 = 0; +pub const ADL_DDC_OPTION_SWITCHDDC2: u32 = 1; +pub const ADL_DDC_OPTION_RESTORECOMMAND: u32 = 2; +pub const ADL_DDC_OPTION_COMBOWRITEREAD: u32 = 16; +pub const ADL_DDC_OPTION_SENDTOIMMEDIATEDEVICE: u32 = 32; +pub const ADL_DL_I2C_ACTIONREAD: u32 = 1; +pub const ADL_DL_I2C_ACTIONWRITE: u32 = 2; +pub const ADL_DL_I2C_ACTIONREAD_REPEATEDSTART: u32 = 3; +pub const ADL_DL_I2C_ACTIONIS_PRESENT: u32 = 4; +pub const ADL_OK_WAIT: u32 = 4; +pub const ADL_OK_RESTART: u32 = 3; +pub const ADL_OK_MODE_CHANGE: u32 = 2; +pub const ADL_OK_WARNING: u32 = 1; +pub const ADL_OK: u32 = 0; +pub const ADL_ERR: i32 = -1; +pub const ADL_ERR_NOT_INIT: i32 = -2; +pub const ADL_ERR_INVALID_PARAM: i32 = -3; +pub const ADL_ERR_INVALID_PARAM_SIZE: i32 = -4; +pub const ADL_ERR_INVALID_ADL_IDX: i32 = -5; +pub const ADL_ERR_INVALID_CONTROLLER_IDX: i32 = -6; +pub const ADL_ERR_INVALID_DIPLAY_IDX: i32 = -7; +pub const ADL_ERR_NOT_SUPPORTED: i32 = -8; +pub const ADL_ERR_NULL_POINTER: i32 = -9; +pub const ADL_ERR_DISABLED_ADAPTER: i32 = -10; +pub const ADL_ERR_INVALID_CALLBACK: i32 = -11; +pub const ADL_ERR_RESOURCE_CONFLICT: i32 = -12; +pub const ADL_ERR_SET_INCOMPLETE: i32 = -20; +pub const ADL_ERR_NO_XDISPLAY: i32 = -21; +pub const ADL_ERR_CALL_TO_INCOMPATIABLE_DRIVER: i32 = -22; +pub const ADL_ERR_NO_ADMINISTRATOR_PRIVILEGES: i32 = -23; +pub const ADL_ERR_FEATURESYNC_NOT_STARTED: i32 = -24; +pub const ADL_ERR_INVALID_POWER_STATE: i32 = -25; +pub const ADL_DT_MONITOR: u32 = 0; +pub const ADL_DT_TELEVISION: u32 = 1; +pub const ADL_DT_LCD_PANEL: u32 = 2; +pub const ADL_DT_DIGITAL_FLAT_PANEL: u32 = 3; +pub const ADL_DT_COMPONENT_VIDEO: u32 = 4; +pub const ADL_DT_PROJECTOR: u32 = 5; +pub const ADL_DOT_UNKNOWN: u32 = 0; +pub const ADL_DOT_COMPOSITE: u32 = 1; +pub const ADL_DOT_SVIDEO: u32 = 2; +pub const ADL_DOT_ANALOG: u32 = 3; +pub const ADL_DOT_DIGITAL: u32 = 4; +pub const ADL_DISPLAY_COLOR_BRIGHTNESS: u32 = 1; +pub const ADL_DISPLAY_COLOR_CONTRAST: u32 = 2; +pub const ADL_DISPLAY_COLOR_SATURATION: u32 = 4; +pub const ADL_DISPLAY_COLOR_HUE: u32 = 8; +pub const ADL_DISPLAY_COLOR_TEMPERATURE: u32 = 16; +pub const ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_EDID: u32 = 32; +pub const ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_USER: u32 = 64; +pub const ADL_DISPLAY_ADJUST_OVERSCAN: u32 = 1; +pub const ADL_DISPLAY_ADJUST_VERT_POS: u32 = 2; +pub const ADL_DISPLAY_ADJUST_HOR_POS: u32 = 4; +pub const ADL_DISPLAY_ADJUST_VERT_SIZE: u32 = 8; +pub const ADL_DISPLAY_ADJUST_HOR_SIZE: u32 = 16; +pub const ADL_DISPLAY_ADJUST_SIZEPOS: u32 = 30; +pub const ADL_DISPLAY_CUSTOMMODES: u32 = 32; +pub const ADL_DISPLAY_ADJUST_UNDERSCAN: u32 = 64; +pub const ADL_DISPLAY_CAPS_DOWNSCALE: u32 = 1; +pub const ADL_DISPLAY_CAPS_SHARPNESS: u32 = 1; +pub const ADL_DESKTOPCONFIG_UNKNOWN: u32 = 0; +pub const ADL_DESKTOPCONFIG_SINGLE: u32 = 1; +pub const ADL_DESKTOPCONFIG_CLONE: u32 = 4; +pub const ADL_DESKTOPCONFIG_BIGDESK_H: u32 = 16; +pub const ADL_DESKTOPCONFIG_BIGDESK_V: u32 = 32; +pub const ADL_DESKTOPCONFIG_BIGDESK_HR: u32 = 64; +pub const ADL_DESKTOPCONFIG_BIGDESK_VR: u32 = 128; +pub const ADL_DESKTOPCONFIG_RANDR12: u32 = 256; +pub const ADL_MAX_DISPLAY_NAME: u32 = 256; +pub const ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE: u32 = 1; +pub const ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION: u32 = 2; +pub const ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE: u32 = 4; +pub const ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE: u32 = 8; +pub const ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI: u32 = 16; +pub const ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601: u32 = 32; +pub const ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709: u32 = 64; +pub const ADL_DISPLAY_CONTYPE_UNKNOWN: u32 = 0; +pub const ADL_DISPLAY_CONTYPE_VGA: u32 = 1; +pub const ADL_DISPLAY_CONTYPE_DVI_D: u32 = 2; +pub const ADL_DISPLAY_CONTYPE_DVI_I: u32 = 3; +pub const ADL_DISPLAY_CONTYPE_ATICVDONGLE_NTSC: u32 = 4; +pub const ADL_DISPLAY_CONTYPE_ATICVDONGLE_JPN: u32 = 5; +pub const ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_JPN: u32 = 6; +pub const ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_NTSC: u32 = 7; +pub const ADL_DISPLAY_CONTYPE_PROPRIETARY: u32 = 8; +pub const ADL_DISPLAY_CONTYPE_HDMI_TYPE_A: u32 = 10; +pub const ADL_DISPLAY_CONTYPE_HDMI_TYPE_B: u32 = 11; +pub const ADL_DISPLAY_CONTYPE_SVIDEO: u32 = 12; +pub const ADL_DISPLAY_CONTYPE_COMPOSITE: u32 = 13; +pub const ADL_DISPLAY_CONTYPE_RCA_3COMPONENT: u32 = 14; +pub const ADL_DISPLAY_CONTYPE_DISPLAYPORT: u32 = 15; +pub const ADL_DISPLAY_CONTYPE_EDP: u32 = 16; +pub const ADL_DISPLAY_CONTYPE_WIRELESSDISPLAY: u32 = 17; +pub const ADL_DISPLAY_CONTYPE_USB_TYPE_C: u32 = 18; +pub const ADL_TV_STANDARDS: u32 = 1; +pub const ADL_TV_SCART: u32 = 2; +pub const ADL_STANDARD_NTSC_M: u32 = 1; +pub const ADL_STANDARD_NTSC_JPN: u32 = 2; +pub const ADL_STANDARD_NTSC_N: u32 = 4; +pub const ADL_STANDARD_PAL_B: u32 = 8; +pub const ADL_STANDARD_PAL_COMB_N: u32 = 16; +pub const ADL_STANDARD_PAL_D: u32 = 32; +pub const ADL_STANDARD_PAL_G: u32 = 64; +pub const ADL_STANDARD_PAL_H: u32 = 128; +pub const ADL_STANDARD_PAL_I: u32 = 256; +pub const ADL_STANDARD_PAL_K: u32 = 512; +pub const ADL_STANDARD_PAL_K1: u32 = 1024; +pub const ADL_STANDARD_PAL_L: u32 = 2048; +pub const ADL_STANDARD_PAL_M: u32 = 4096; +pub const ADL_STANDARD_PAL_N: u32 = 8192; +pub const ADL_STANDARD_PAL_SECAM_D: u32 = 16384; +pub const ADL_STANDARD_PAL_SECAM_K: u32 = 32768; +pub const ADL_STANDARD_PAL_SECAM_K1: u32 = 65536; +pub const ADL_STANDARD_PAL_SECAM_L: u32 = 131072; +pub const ADL_CUSTOMIZEDMODEFLAG_MODESUPPORTED: u32 = 1; +pub const ADL_CUSTOMIZEDMODEFLAG_NOTDELETETABLE: u32 = 2; +pub const ADL_CUSTOMIZEDMODEFLAG_INSERTBYDRIVER: u32 = 4; +pub const ADL_CUSTOMIZEDMODEFLAG_INTERLACED: u32 = 8; +pub const ADL_CUSTOMIZEDMODEFLAG_BASEMODE: u32 = 16; +pub const ADL_DISPLAY_CV_DONGLE_D1: u32 = 1; +pub const ADL_DISPLAY_CV_DONGLE_D2: u32 = 2; +pub const ADL_DISPLAY_CV_DONGLE_D3: u32 = 4; +pub const ADL_DISPLAY_CV_DONGLE_D4: u32 = 8; +pub const ADL_DISPLAY_CV_DONGLE_D5: u32 = 16; +pub const ADL_DISPLAY_CV_DONGLE_480I: u32 = 1; +pub const ADL_DISPLAY_CV_DONGLE_480P: u32 = 2; +pub const ADL_DISPLAY_CV_DONGLE_540P: u32 = 4; +pub const ADL_DISPLAY_CV_DONGLE_720P: u32 = 8; +pub const ADL_DISPLAY_CV_DONGLE_1080I: u32 = 16; +pub const ADL_DISPLAY_CV_DONGLE_1080P: u32 = 32; +pub const ADL_DISPLAY_CV_DONGLE_16_9: u32 = 64; +pub const ADL_DISPLAY_CV_DONGLE_720P50: u32 = 128; +pub const ADL_DISPLAY_CV_DONGLE_1080I25: u32 = 256; +pub const ADL_DISPLAY_CV_DONGLE_576I25: u32 = 512; +pub const ADL_DISPLAY_CV_DONGLE_576P50: u32 = 1024; +pub const ADL_DISPLAY_CV_DONGLE_1080P24: u32 = 2048; +pub const ADL_DISPLAY_CV_DONGLE_1080P25: u32 = 4096; +pub const ADL_DISPLAY_CV_DONGLE_1080P30: u32 = 8192; +pub const ADL_DISPLAY_CV_DONGLE_1080P50: u32 = 16384; +pub const ADL_DISPLAY_FORMAT_FORCE_720P: u32 = 1; +pub const ADL_DISPLAY_FORMAT_FORCE_1080I: u32 = 2; +pub const ADL_DISPLAY_FORMAT_FORCE_1080P: u32 = 4; +pub const ADL_DISPLAY_FORMAT_FORCE_720P50: u32 = 8; +pub const ADL_DISPLAY_FORMAT_FORCE_1080I25: u32 = 16; +pub const ADL_DISPLAY_FORMAT_FORCE_576I25: u32 = 32; +pub const ADL_DISPLAY_FORMAT_FORCE_576P50: u32 = 64; +pub const ADL_DISPLAY_FORMAT_FORCE_1080P24: u32 = 128; +pub const ADL_DISPLAY_FORMAT_FORCE_1080P25: u32 = 256; +pub const ADL_DISPLAY_FORMAT_FORCE_1080P30: u32 = 512; +pub const ADL_DISPLAY_FORMAT_FORCE_1080P50: u32 = 1024; +pub const ADL_DISPLAY_FORMAT_CVDONGLEOVERIDE: u32 = 1; +pub const ADL_DISPLAY_FORMAT_CVMODEUNDERSCAN: u32 = 2; +pub const ADL_DISPLAY_FORMAT_FORCECONNECT_SUPPORTED: u32 = 4; +pub const ADL_DISPLAY_FORMAT_RESTRICT_FORMAT_SELECTION: u32 = 8; +pub const ADL_DISPLAY_FORMAT_SETASPECRATIO: u32 = 16; +pub const ADL_DISPLAY_FORMAT_FORCEMODES: u32 = 32; +pub const ADL_DISPLAY_FORMAT_LCDRTCCOEFF: u32 = 64; +pub const ADL_PM_PARAM_DONT_CHANGE: u32 = 0; +pub const ADL_BUSTYPE_PCI: u32 = 0; +pub const ADL_BUSTYPE_AGP: u32 = 1; +pub const ADL_BUSTYPE_PCIE: u32 = 2; +pub const ADL_BUSTYPE_PCIE_GEN2: u32 = 3; +pub const ADL_BUSTYPE_PCIE_GEN3: u32 = 4; +pub const ADL_BUSTYPE_PCIE_GEN4: u32 = 5; +pub const ADL_STEREO_SUPPORTED: u32 = 4; +pub const ADL_STEREO_BLUE_LINE: u32 = 8; +pub const ADL_STEREO_OFF: u32 = 0; +pub const ADL_STEREO_ACTIVE: u32 = 2; +pub const ADL_STEREO_AUTO_HORIZONTAL: u32 = 1073741824; +pub const ADL_STEREO_AUTO_VERTICAL: u32 = 2147483648; +pub const ADL_STEREO_PASSIVE: u32 = 64; +pub const ADL_STEREO_PASSIVE_HORIZ: u32 = 128; +pub const ADL_STEREO_PASSIVE_VERT: u32 = 256; +pub const ADL_STEREO_AUTO_SAMSUNG: u32 = 2048; +pub const ADL_STEREO_AUTO_TSL: u32 = 4096; +pub const ADL_DEEPBITDEPTH_10BPP_SUPPORTED: u32 = 32; +pub const ADL_8BIT_GREYSCALE_SUPPORTED: u32 = 512; +pub const ADL_CUSTOM_TIMING_SUPPORTED: u32 = 1024; +pub const ADL_WORKSTATION_LOADBALANCING_SUPPORTED: u32 = 1; +pub const ADL_WORKSTATION_LOADBALANCING_AVAILABLE: u32 = 2; +pub const ADL_WORKSTATION_LOADBALANCING_DISABLED: u32 = 0; +pub const ADL_WORKSTATION_LOADBALANCING_ENABLED: u32 = 1; +pub const ADL_CONTEXT_SPEED_UNFORCED: u32 = 0; +pub const ADL_CONTEXT_SPEED_FORCEHIGH: u32 = 1; +pub const ADL_CONTEXT_SPEED_FORCELOW: u32 = 2; +pub const ADL_ADAPTER_SPEEDCAPS_SUPPORTED: u32 = 1; +pub const ADL_GLSYNC_PORT_UNKNOWN: u32 = 0; +pub const ADL_GLSYNC_PORT_BNC: u32 = 1; +pub const ADL_GLSYNC_PORT_RJ45PORT1: u32 = 2; +pub const ADL_GLSYNC_PORT_RJ45PORT2: u32 = 3; +pub const ADL_GLSYNC_CONFIGMASK_NONE: u32 = 0; +pub const ADL_GLSYNC_CONFIGMASK_SIGNALSOURCE: u32 = 1; +pub const ADL_GLSYNC_CONFIGMASK_SYNCFIELD: u32 = 2; +pub const ADL_GLSYNC_CONFIGMASK_SAMPLERATE: u32 = 4; +pub const ADL_GLSYNC_CONFIGMASK_SYNCDELAY: u32 = 8; +pub const ADL_GLSYNC_CONFIGMASK_TRIGGEREDGE: u32 = 16; +pub const ADL_GLSYNC_CONFIGMASK_SCANRATECOEFF: u32 = 32; +pub const ADL_GLSYNC_CONFIGMASK_FRAMELOCKCNTL: u32 = 64; +pub const ADL_GLSYNC_FRAMELOCKCNTL_NONE: u32 = 0; +pub const ADL_GLSYNC_FRAMELOCKCNTL_ENABLE: u32 = 1; +pub const ADL_GLSYNC_FRAMELOCKCNTL_DISABLE: u32 = 2; +pub const ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_RESET: u32 = 4; +pub const ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_ACK: u32 = 8; +pub const ADL_GLSYNC_FRAMELOCKCNTL_VERSION_KMD: u32 = 16; +pub const ADL_GLSYNC_FRAMELOCKCNTL_STATE_ENABLE: u32 = 1; +pub const ADL_GLSYNC_FRAMELOCKCNTL_STATE_KMD: u32 = 16; +pub const ADL_GLSYNC_COUNTER_SWAP: u32 = 1; +pub const ADL_GLSYNC_SIGNALSOURCE_UNDEFINED: u32 = 256; +pub const ADL_GLSYNC_SIGNALSOURCE_FREERUN: u32 = 257; +pub const ADL_GLSYNC_SIGNALSOURCE_BNCPORT: u32 = 258; +pub const ADL_GLSYNC_SIGNALSOURCE_RJ45PORT1: u32 = 259; +pub const ADL_GLSYNC_SIGNALSOURCE_RJ45PORT2: u32 = 260; +pub const ADL_GLSYNC_SIGNALTYPE_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_SIGNALTYPE_480I: u32 = 1; +pub const ADL_GLSYNC_SIGNALTYPE_576I: u32 = 2; +pub const ADL_GLSYNC_SIGNALTYPE_480P: u32 = 3; +pub const ADL_GLSYNC_SIGNALTYPE_576P: u32 = 4; +pub const ADL_GLSYNC_SIGNALTYPE_720P: u32 = 5; +pub const ADL_GLSYNC_SIGNALTYPE_1080P: u32 = 6; +pub const ADL_GLSYNC_SIGNALTYPE_1080I: u32 = 7; +pub const ADL_GLSYNC_SIGNALTYPE_SDI: u32 = 8; +pub const ADL_GLSYNC_SIGNALTYPE_TTL: u32 = 9; +pub const ADL_GLSYNC_SIGNALTYPE_ANALOG: u32 = 10; +pub const ADL_GLSYNC_SYNCFIELD_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_SYNCFIELD_BOTH: u32 = 1; +pub const ADL_GLSYNC_SYNCFIELD_1: u32 = 2; +pub const ADL_GLSYNC_TRIGGEREDGE_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_TRIGGEREDGE_RISING: u32 = 1; +pub const ADL_GLSYNC_TRIGGEREDGE_FALLING: u32 = 2; +pub const ADL_GLSYNC_TRIGGEREDGE_BOTH: u32 = 3; +pub const ADL_GLSYNC_SCANRATECOEFF_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_SCANRATECOEFF_x5: u32 = 1; +pub const ADL_GLSYNC_SCANRATECOEFF_x4: u32 = 2; +pub const ADL_GLSYNC_SCANRATECOEFF_x3: u32 = 3; +pub const ADL_GLSYNC_SCANRATECOEFF_x5_DIV_2: u32 = 4; +pub const ADL_GLSYNC_SCANRATECOEFF_x2: u32 = 5; +pub const ADL_GLSYNC_SCANRATECOEFF_x3_DIV_2: u32 = 6; +pub const ADL_GLSYNC_SCANRATECOEFF_x5_DIV_4: u32 = 7; +pub const ADL_GLSYNC_SCANRATECOEFF_x1: u32 = 8; +pub const ADL_GLSYNC_SCANRATECOEFF_x4_DIV_5: u32 = 9; +pub const ADL_GLSYNC_SCANRATECOEFF_x2_DIV_3: u32 = 10; +pub const ADL_GLSYNC_SCANRATECOEFF_x1_DIV_2: u32 = 11; +pub const ADL_GLSYNC_SCANRATECOEFF_x2_DIV_5: u32 = 12; +pub const ADL_GLSYNC_SCANRATECOEFF_x1_DIV_3: u32 = 13; +pub const ADL_GLSYNC_SCANRATECOEFF_x1_DIV_4: u32 = 14; +pub const ADL_GLSYNC_SCANRATECOEFF_x1_DIV_5: u32 = 15; +pub const ADL_GLSYNC_PORTSTATE_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_PORTSTATE_NOCABLE: u32 = 1; +pub const ADL_GLSYNC_PORTSTATE_IDLE: u32 = 2; +pub const ADL_GLSYNC_PORTSTATE_INPUT: u32 = 3; +pub const ADL_GLSYNC_PORTSTATE_OUTPUT: u32 = 4; +pub const ADL_GLSYNC_LEDTYPE_BNC: u32 = 0; +pub const ADL_GLSYNC_LEDTYPE_RJ45_LEFT: u32 = 0; +pub const ADL_GLSYNC_LEDTYPE_RJ45_RIGHT: u32 = 1; +pub const ADL_GLSYNC_LEDCOLOR_UNDEFINED: u32 = 0; +pub const ADL_GLSYNC_LEDCOLOR_NOLIGHT: u32 = 1; +pub const ADL_GLSYNC_LEDCOLOR_YELLOW: u32 = 2; +pub const ADL_GLSYNC_LEDCOLOR_RED: u32 = 3; +pub const ADL_GLSYNC_LEDCOLOR_GREEN: u32 = 4; +pub const ADL_GLSYNC_LEDCOLOR_FLASH_GREEN: u32 = 5; +pub const ADL_GLSYNC_PORTCNTL_NONE: u32 = 0; +pub const ADL_GLSYNC_PORTCNTL_OUTPUT: u32 = 1; +pub const ADL_GLSYNC_MODECNTL_NONE: u32 = 0; +pub const ADL_GLSYNC_MODECNTL_GENLOCK: u32 = 1; +pub const ADL_GLSYNC_MODECNTL_TIMINGSERVER: u32 = 2; +pub const ADL_GLSYNC_MODECNTL_STATUS_NONE: u32 = 0; +pub const ADL_GLSYNC_MODECNTL_STATUS_GENLOCK: u32 = 1; +pub const ADL_GLSYNC_MODECNTL_STATUS_SETMODE_REQUIRED: u32 = 2; +pub const ADL_GLSYNC_MODECNTL_STATUS_GENLOCK_ALLOWED: u32 = 4; +pub const ADL_MAX_GLSYNC_PORTS: u32 = 8; +pub const ADL_MAX_GLSYNC_PORT_LEDS: u32 = 8; +pub const ADL_XFIREX_STATE_NOINTERCONNECT: u32 = 1; +pub const ADL_XFIREX_STATE_DOWNGRADEPIPES: u32 = 2; +pub const ADL_XFIREX_STATE_DOWNGRADEMEM: u32 = 4; +pub const ADL_XFIREX_STATE_REVERSERECOMMENDED: u32 = 8; +pub const ADL_XFIREX_STATE_3DACTIVE: u32 = 16; +pub const ADL_XFIREX_STATE_MASTERONSLAVE: u32 = 32; +pub const ADL_XFIREX_STATE_NODISPLAYCONNECT: u32 = 64; +pub const ADL_XFIREX_STATE_NOPRIMARYVIEW: u32 = 128; +pub const ADL_XFIREX_STATE_DOWNGRADEVISMEM: u32 = 256; +pub const ADL_XFIREX_STATE_LESSTHAN8LANE_MASTER: u32 = 512; +pub const ADL_XFIREX_STATE_LESSTHAN8LANE_SLAVE: u32 = 1024; +pub const ADL_XFIREX_STATE_PEERTOPEERFAILED: u32 = 2048; +pub const ADL_XFIREX_STATE_MEMISDOWNGRADED: u32 = 65536; +pub const ADL_XFIREX_STATE_PIPESDOWNGRADED: u32 = 131072; +pub const ADL_XFIREX_STATE_XFIREXACTIVE: u32 = 262144; +pub const ADL_XFIREX_STATE_VISMEMISDOWNGRADED: u32 = 524288; +pub const ADL_XFIREX_STATE_INVALIDINTERCONNECTION: u32 = 1048576; +pub const ADL_XFIREX_STATE_NONP2PMODE: u32 = 2097152; +pub const ADL_XFIREX_STATE_DOWNGRADEMEMBANKS: u32 = 4194304; +pub const ADL_XFIREX_STATE_MEMBANKSDOWNGRADED: u32 = 8388608; +pub const ADL_XFIREX_STATE_DUALDISPLAYSALLOWED: u32 = 16777216; +pub const ADL_XFIREX_STATE_P2P_APERTURE_MAPPING: u32 = 33554432; +pub const ADL_XFIREX_STATE_P2PFLUSH_REQUIRED: u32 = 33554432; +pub const ADL_XFIREX_STATE_XSP_CONNECTED: u32 = 67108864; +pub const ADL_XFIREX_STATE_ENABLE_CF_REBOOT_REQUIRED: u32 = 134217728; +pub const ADL_XFIREX_STATE_DISABLE_CF_REBOOT_REQUIRED: u32 = 268435456; +pub const ADL_XFIREX_STATE_DRV_HANDLE_DOWNGRADE_KEY: u32 = 536870912; +pub const ADL_XFIREX_STATE_CF_RECONFIG_REQUIRED: u32 = 1073741824; +pub const ADL_XFIREX_STATE_ERRORGETTINGSTATUS: u32 = 2147483648; +pub const ADL_DISPLAY_PIXELFORMAT_UNKNOWN: u32 = 0; +pub const ADL_DISPLAY_PIXELFORMAT_RGB: u32 = 1; +pub const ADL_DISPLAY_PIXELFORMAT_YCRCB444: u32 = 2; +pub const ADL_DISPLAY_PIXELFORMAT_YCRCB422: u32 = 4; +pub const ADL_DISPLAY_PIXELFORMAT_RGB_LIMITED_RANGE: u32 = 8; +pub const ADL_DISPLAY_PIXELFORMAT_RGB_FULL_RANGE: u32 = 1; +pub const ADL_DISPLAY_PIXELFORMAT_YCRCB420: u32 = 16; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_UNKNOWN: u32 = 0; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_JP: u32 = 1; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_CV_JPN: u32 = 2; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NA: u32 = 3; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_NA: u32 = 4; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_VGA: u32 = 5; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_D: u32 = 6; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_I: u32 = 7; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_A: u32 = 8; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_B: u32 = 9; +pub const ADL_DL_DISPLAYCONFIG_CONTYPE_DISPLAYPORT: u32 = 10; +pub const ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED: u32 = 1; +pub const ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED: u32 = 2; +pub const ADL_DISPLAY_DISPLAYINFO_NONLOCAL: u32 = 4; +pub const ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED: u32 = 8; +pub const ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED: u32 = 16; +pub const ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED: u32 = 32; +pub const ADL_DISPLAY_DISPLAYINFO_LDA_DISPLAY: u32 = 64; +pub const ADL_DISPLAY_DISPLAYINFO_MODETIMING_OVERRIDESSUPPORTED: u32 = 128; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE: u32 = 256; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE: u32 = 512; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH: u32 = 1024; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH: u32 = 2048; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED: u32 = 4096; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU: u32 = 65536; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU: u32 = 131072; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2: u32 = 262144; +pub const ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3: u32 = 524288; +pub const ADL_DISPLAY_DISPLAYINFO_SHOWTYPE_PROJECTOR: u32 = 1048576; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NOTACTIVE: u32 = 1; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_SINGLE: u32 = 2; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_CLONE: u32 = 4; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCH1GPU: u32 = 8; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCHNGPU: u32 = 16; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2VSTRETCH: u32 = 32; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2HSTRETCH: u32 = 64; +pub const ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_EXTENDED: u32 = 128; +pub const ADL_ADAPTER_DISPLAYCAP_PREFERDISPLAY_SUPPORTED: u32 = 256; +pub const ADL_ADAPTER_DISPLAYCAP_BEZEL_SUPPORTED: u32 = 512; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED: u32 = 1; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_NOTACTIVE: u32 = 2; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_SINGLE: u32 = 4; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_CLONE: u32 = 8; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED1: u32 = 16; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_HSTRETCH: u32 = 32; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_VSTRETCH: u32 = 64; +pub const ADL_DISPLAY_DISPLAYMAP_MANNER_VLD: u32 = 128; +pub const ADL_DISPLAY_DISPLAYMAP_OPTION_GPUINFO: u32 = 1; +pub const ADL_DISPLAY_DISPLAYTARGET_PREFERRED: u32 = 1; +pub const ADL_DISPLAY_POSSIBLEMAPRESULT_VALID: u32 = 1; +pub const ADL_DISPLAY_POSSIBLEMAPRESULT_BEZELSUPPORTED: u32 = 2; +pub const ADL_DISPLAY_POSSIBLEMAPRESULT_OVERLAPSUPPORTED: u32 = 4; +pub const ADL_DISPLAY_MODE_COLOURFORMAT_565: u32 = 1; +pub const ADL_DISPLAY_MODE_COLOURFORMAT_8888: u32 = 2; +pub const ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000: u32 = 4; +pub const ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_090: u32 = 8; +pub const ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_180: u32 = 16; +pub const ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_270: u32 = 32; +pub const ADL_DISPLAY_MODE_REFRESHRATE_ROUNDED: u32 = 64; +pub const ADL_DISPLAY_MODE_REFRESHRATE_ONLY: u32 = 128; +pub const ADL_DISPLAY_MODE_PROGRESSIVE_FLAG: u32 = 0; +pub const ADL_DISPLAY_MODE_INTERLACED_FLAG: u32 = 2; +pub const ADL_OSMODEINFOXPOS_DEFAULT: i32 = -640; +pub const ADL_OSMODEINFOYPOS_DEFAULT: u32 = 0; +pub const ADL_OSMODEINFOXRES_DEFAULT: u32 = 640; +pub const ADL_OSMODEINFOYRES_DEFAULT: u32 = 480; +pub const ADL_OSMODEINFOXRES_DEFAULT800: u32 = 800; +pub const ADL_OSMODEINFOYRES_DEFAULT600: u32 = 600; +pub const ADL_OSMODEINFOREFRESHRATE_DEFAULT: u32 = 60; +pub const ADL_OSMODEINFOCOLOURDEPTH_DEFAULT: u32 = 8; +pub const ADL_OSMODEINFOCOLOURDEPTH_DEFAULT16: u32 = 16; +pub const ADL_OSMODEINFOCOLOURDEPTH_DEFAULT24: u32 = 24; +pub const ADL_OSMODEINFOCOLOURDEPTH_DEFAULT32: u32 = 32; +pub const ADL_OSMODEINFOORIENTATION_DEFAULT: u32 = 0; +pub const ADL_OSMODEFLAG_DEFAULT: u32 = 0; +pub const ADL_I2C_MAJOR_API_REV: u32 = 1; +pub const ADL_I2C_MINOR_DEFAULT_API_REV: u32 = 0; +pub const ADL_I2C_MINOR_OEM_API_REV: u32 = 1; +pub const ADL_DL_I2C_LINE_OEM: u32 = 1; +pub const ADL_DL_I2C_LINE_OD_CONTROL: u32 = 2; +pub const ADL_DL_I2C_LINE_OEM2: u32 = 3; +pub const ADL_DL_I2C_LINE_OEM3: u32 = 4; +pub const ADL_DL_I2C_LINE_OEM4: u32 = 5; +pub const ADL_DL_I2C_LINE_OEM5: u32 = 6; +pub const ADL_DL_I2C_LINE_OEM6: u32 = 7; +pub const ADL_DL_I2C_LINE_GPIO: u32 = 8; +pub const ADL_DL_I2C_MAXDATASIZE: u32 = 24; +pub const ADL_DL_I2C_MAXWRITEDATASIZE: u32 = 12; +pub const ADL_DL_I2C_MAXADDRESSLENGTH: u32 = 6; +pub const ADL_DL_I2C_MAXOFFSETLENGTH: u32 = 4; +pub const ADL_DL_I2C_SPEED_50K: u32 = 50; +pub const ADL_DL_I2C_SPEED_100K: u32 = 100; +pub const ADL_DL_I2C_SPEED_1M: u32 = 1000; +pub const ADL_DL_I2C_SPEED_2M: u32 = 2300; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_UNKNOWN: u32 = 0; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_EXPANSIONMODE: u32 = 1; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_USEUNDERSCANSCALING: u32 = 2; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_ITCFLAGENABLE: u32 = 9; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_DOWNSCALE: u32 = 11; +pub const ADL_DL_DISPLAYPROPERTY_TYPE_INTEGER_SCALING: u32 = 12; +pub const ADL_DL_DISPLAYCONTENT_TYPE_GRAPHICS: u32 = 1; +pub const ADL_DL_DISPLAYCONTENT_TYPE_PHOTO: u32 = 2; +pub const ADL_DL_DISPLAYCONTENT_TYPE_CINEMA: u32 = 4; +pub const ADL_DL_DISPLAYCONTENT_TYPE_GAME: u32 = 8; +pub const ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_CENTER: u32 = 0; +pub const ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_FULLSCREEN: u32 = 1; +pub const ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_ASPECTRATIO: u32 = 2; +pub const ADL_DL_DISPLAY_DITHER_DISABLED: u32 = 0; +pub const ADL_DL_DISPLAY_DITHER_DRIVER_DEFAULT: u32 = 1; +pub const ADL_DL_DISPLAY_DITHER_FM6: u32 = 2; +pub const ADL_DL_DISPLAY_DITHER_FM8: u32 = 3; +pub const ADL_DL_DISPLAY_DITHER_FM10: u32 = 4; +pub const ADL_DL_DISPLAY_DITHER_DITH6: u32 = 5; +pub const ADL_DL_DISPLAY_DITHER_DITH8: u32 = 6; +pub const ADL_DL_DISPLAY_DITHER_DITH10: u32 = 7; +pub const ADL_DL_DISPLAY_DITHER_DITH6_NO_FRAME_RAND: u32 = 8; +pub const ADL_DL_DISPLAY_DITHER_DITH8_NO_FRAME_RAND: u32 = 9; +pub const ADL_DL_DISPLAY_DITHER_DITH10_NO_FRAME_RAND: u32 = 10; +pub const ADL_DL_DISPLAY_DITHER_TRUN6: u32 = 11; +pub const ADL_DL_DISPLAY_DITHER_TRUN8: u32 = 12; +pub const ADL_DL_DISPLAY_DITHER_TRUN10: u32 = 13; +pub const ADL_DL_DISPLAY_DITHER_TRUN10_DITH8: u32 = 14; +pub const ADL_DL_DISPLAY_DITHER_TRUN10_DITH6: u32 = 15; +pub const ADL_DL_DISPLAY_DITHER_TRUN10_FM8: u32 = 16; +pub const ADL_DL_DISPLAY_DITHER_TRUN10_FM6: u32 = 17; +pub const ADL_DL_DISPLAY_DITHER_TRUN10_DITH8_FM6: u32 = 18; +pub const ADL_DL_DISPLAY_DITHER_DITH10_FM8: u32 = 19; +pub const ADL_DL_DISPLAY_DITHER_DITH10_FM6: u32 = 20; +pub const ADL_DL_DISPLAY_DITHER_TRUN8_DITH6: u32 = 21; +pub const ADL_DL_DISPLAY_DITHER_TRUN8_FM6: u32 = 22; +pub const ADL_DL_DISPLAY_DITHER_DITH8_FM6: u32 = 23; +pub const ADL_DL_DISPLAY_DITHER_LAST: u32 = 23; +pub const ADL_MAX_EDIDDATA_SIZE: u32 = 256; +pub const ADL_MAX_OVERRIDEEDID_SIZE: u32 = 512; +pub const ADL_MAX_EDID_EXTENSION_BLOCKS: u32 = 3; +pub const ADL_DL_CONTROLLER_OVERLAY_ALPHA: u32 = 0; +pub const ADL_DL_CONTROLLER_OVERLAY_ALPHAPERPIX: u32 = 1; +pub const ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_RESET: u32 = 0; +pub const ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_SET: u32 = 1; +pub const ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_SCAN: u32 = 2; +pub const ADL_DL_DISPLAY_DATA_PACKET__TYPE__AVI: u32 = 1; +pub const ADL_DL_DISPLAY_DATA_PACKET__TYPE__GAMMUT: u32 = 2; +pub const ADL_DL_DISPLAY_DATA_PACKET__TYPE__VENDORINFO: u32 = 4; +pub const ADL_DL_DISPLAY_DATA_PACKET__TYPE__HDR: u32 = 8; +pub const ADL_DL_DISPLAY_DATA_PACKET__TYPE__SPD: u32 = 16; +pub const ADL_GAMUT_MATRIX_SD: u32 = 1; +pub const ADL_GAMUT_MATRIX_HD: u32 = 2; +pub const ADL_DL_CLOCKINFO_FLAG_FULLSCREEN3DONLY: u32 = 1; +pub const ADL_DL_CLOCKINFO_FLAG_ALWAYSFULLSCREEN3D: u32 = 2; +pub const ADL_DL_CLOCKINFO_FLAG_VPURECOVERYREDUCED: u32 = 4; +pub const ADL_DL_CLOCKINFO_FLAG_THERMALPROTECTION: u32 = 8; +pub const ADL_DL_POWERXPRESS_GPU_INTEGRATED: u32 = 1; +pub const ADL_DL_POWERXPRESS_GPU_DISCRETE: u32 = 2; +pub const ADL_DL_POWERXPRESS_SWITCH_RESULT_STARTED: u32 = 1; +pub const ADL_DL_POWERXPRESS_SWITCH_RESULT_DECLINED: u32 = 2; +pub const ADL_DL_POWERXPRESS_SWITCH_RESULT_ALREADY: u32 = 3; +pub const ADL_DL_POWERXPRESS_SWITCH_RESULT_DEFERRED: u32 = 5; +pub const ADL_DL_POWERXPRESS_VERSION_MAJOR: u32 = 2; +pub const ADL_DL_POWERXPRESS_VERSION_MINOR: u32 = 0; +pub const ADL_DL_POWERXPRESS_VERSION: u32 = 131072; +pub const ADL_DL_THERMAL_DOMAIN_OTHER: u32 = 0; +pub const ADL_DL_THERMAL_DOMAIN_GPU: u32 = 1; +pub const ADL_DL_THERMAL_FLAG_INTERRUPT: u32 = 1; +pub const ADL_DL_THERMAL_FLAG_FANCONTROL: u32 = 2; +pub const ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ: u32 = 1; +pub const ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE: u32 = 2; +pub const ADL_DL_FANCTRL_SUPPORTS_RPM_READ: u32 = 4; +pub const ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE: u32 = 8; +pub const ADL_DL_FANCTRL_SPEED_TYPE_PERCENT: u32 = 1; +pub const ADL_DL_FANCTRL_SPEED_TYPE_RPM: u32 = 2; +pub const ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED: u32 = 1; +pub const ADL_DL_MAX_MVPU_ADAPTERS: u32 = 4; +pub const ADL_DL_MAX_REGISTRY_PATH: u32 = 256; +pub const ADL_DL_MVPU_STATUS_OFF: u32 = 0; +pub const ADL_DL_MVPU_STATUS_ON: u32 = 1; +pub const ADL_ASIC_UNDEFINED: u32 = 0; +pub const ADL_ASIC_DISCRETE: u32 = 1; +pub const ADL_ASIC_INTEGRATED: u32 = 2; +pub const ADL_ASIC_WORKSTATION: u32 = 4; +pub const ADL_ASIC_FIREMV: u32 = 8; +pub const ADL_ASIC_XGP: u32 = 16; +pub const ADL_ASIC_FUSION: u32 = 32; +pub const ADL_ASIC_FIRESTREAM: u32 = 64; +pub const ADL_ASIC_EMBEDDED: u32 = 128; +pub const ADL_ASIC_FIREGL: u32 = 4; +pub const ADL_DL_TIMINGFLAG_DOUBLE_SCAN: u32 = 1; +pub const ADL_DL_TIMINGFLAG_INTERLACED: u32 = 2; +pub const ADL_DL_TIMINGFLAG_H_SYNC_POLARITY: u32 = 4; +pub const ADL_DL_TIMINGFLAG_V_SYNC_POLARITY: u32 = 8; +pub const ADL_DL_MODETIMING_STANDARD_CVT: u32 = 1; +pub const ADL_DL_MODETIMING_STANDARD_GTF: u32 = 2; +pub const ADL_DL_MODETIMING_STANDARD_DMT: u32 = 4; +pub const ADL_DL_MODETIMING_STANDARD_CUSTOM: u32 = 8; +pub const ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT: u32 = 16; +pub const ADL_DL_MODETIMING_STANDARD_CVT_RB: u32 = 32; +pub const ADL_XSERVERINFO_XINERAMAACTIVE: u32 = 1; +pub const ADL_XSERVERINFO_RANDR12SUPPORTED: u32 = 2; +pub const ADL_CONTROLLERVECTOR_0: u32 = 1; +pub const ADL_CONTROLLERVECTOR_1: u32 = 2; +pub const ADL_DISPLAY_SLSGRID_ORIENTATION_000: u32 = 1; +pub const ADL_DISPLAY_SLSGRID_ORIENTATION_090: u32 = 2; +pub const ADL_DISPLAY_SLSGRID_ORIENTATION_180: u32 = 4; +pub const ADL_DISPLAY_SLSGRID_ORIENTATION_270: u32 = 8; +pub const ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE: u32 = 1; +pub const ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE: u32 = 2; +pub const ADL_DISPLAY_SLSGRID_PORTAIT_MODE: u32 = 4; +pub const ADL_DISPLAY_SLSGRID_KEEPTARGETROTATION: u32 = 128; +pub const ADL_DISPLAY_SLSGRID_SAMEMODESLS_SUPPORT: u32 = 16; +pub const ADL_DISPLAY_SLSGRID_MIXMODESLS_SUPPORT: u32 = 32; +pub const ADL_DISPLAY_SLSGRID_DISPLAYROTATION_SUPPORT: u32 = 64; +pub const ADL_DISPLAY_SLSGRID_DESKTOPROTATION_SUPPORT: u32 = 128; +pub const ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FIT: u32 = 256; +pub const ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_FILL: u32 = 512; +pub const ADL_DISPLAY_SLSMAP_SLSLAYOUTMODE_EXPAND: u32 = 1024; +pub const ADL_DISPLAY_SLSMAP_IS_SLS: u32 = 4096; +pub const ADL_DISPLAY_SLSMAP_IS_SLSBUILDER: u32 = 8192; +pub const ADL_DISPLAY_SLSMAP_IS_CLONEVT: u32 = 16384; +pub const ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_LANDSCAPE: u32 = 1; +pub const ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_CURRENTANGLE: u32 = 2; +pub const ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_LANDSCAPE: u32 = 1; +pub const ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_CURRENTANGLE: u32 = 2; +pub const ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_LANDSCAPE: u32 = 1; +pub const ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_CURRENTANGLE: u32 = 2; +pub const ADL_SLS_SAMEMODESLS_SUPPORT: u32 = 1; +pub const ADL_SLS_MIXMODESLS_SUPPORT: u32 = 2; +pub const ADL_SLS_DISPLAYROTATIONSLS_SUPPORT: u32 = 4; +pub const ADL_SLS_DESKTOPROTATIONSLS_SUPPORT: u32 = 8; +pub const ADL_SLS_TARGETS_INVALID: u32 = 1; +pub const ADL_SLS_MODES_INVALID: u32 = 2; +pub const ADL_SLS_ROTATIONS_INVALID: u32 = 4; +pub const ADL_SLS_POSITIONS_INVALID: u32 = 8; +pub const ADL_SLS_LAYOUTMODE_INVALID: u32 = 16; +pub const ADL_DISPLAY_SLSDISPLAYOFFSET_VALID: u32 = 2; +pub const ADL_DISPLAY_SLSGRID_RELATIVETO_LANDSCAPE: u32 = 16; +pub const ADL_DISPLAY_SLSGRID_RELATIVETO_CURRENTANGLE: u32 = 32; +pub const ADL_DISPLAY_SLSMAP_BEZELMODE: u32 = 16; +pub const ADL_DISPLAY_SLSMAP_DISPLAYARRANGED: u32 = 2; +pub const ADL_DISPLAY_SLSMAP_CURRENTCONFIG: u32 = 4; +pub const ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE: u32 = 1; +pub const ADL_DISPLAY_BEZELOFFSET_STEPBYSTEPSET: u32 = 4; +pub const ADL_DISPLAY_BEZELOFFSET_COMMIT: u32 = 8; +pub const ADL_PX_CONFIGCAPS_SPLASHSCREEN_SUPPORT: u32 = 1; +pub const ADL_PX_CONFIGCAPS_CF_SUPPORT: u32 = 2; +pub const ADL_PX_CONFIGCAPS_MUXLESS: u32 = 4; +pub const ADL_PX_CONFIGCAPS_PROFILE_COMPLIANT: u32 = 8; +pub const ADL_PX_CONFIGCAPS_NON_AMD_DRIVEN_DISPLAYS: u32 = 16; +pub const ADL_PX_CONFIGCAPS_FIXED_SUPPORT: u32 = 32; +pub const ADL_PX_CONFIGCAPS_DYNAMIC_SUPPORT: u32 = 64; +pub const ADL_PX_CONFIGCAPS_HIDE_AUTO_SWITCH: u32 = 128; +pub const ADL_PX_SCHEMEMASK_FIXED: u32 = 1; +pub const ADL_PX_SCHEMEMASK_DYNAMIC: u32 = 2; +pub const ADL_APP_PROFILE_FILENAME_LENGTH: u32 = 256; +pub const ADL_APP_PROFILE_TIMESTAMP_LENGTH: u32 = 32; +pub const ADL_APP_PROFILE_VERSION_LENGTH: u32 = 32; +pub const ADL_APP_PROFILE_PROPERTY_LENGTH: u32 = 64; +pub const ADL_MAX_RAD_LINK_COUNT: u32 = 15; +pub const ADL_GAMUT_REFERENCE_SOURCE: u32 = 1; +pub const ADL_GAMUT_GAMUT_VIDEO_CONTENT: u32 = 2; +pub const ADL_CUSTOM_WHITE_POINT: u32 = 1; +pub const ADL_CUSTOM_GAMUT: u32 = 2; +pub const ADL_GAMUT_REMAP_ONLY: u32 = 4; +pub const ADL_GAMUT_SPACE_CCIR_709: u32 = 1; +pub const ADL_GAMUT_SPACE_CCIR_601: u32 = 2; +pub const ADL_GAMUT_SPACE_ADOBE_RGB: u32 = 4; +pub const ADL_GAMUT_SPACE_CIE_RGB: u32 = 8; +pub const ADL_GAMUT_SPACE_CUSTOM: u32 = 16; +pub const ADL_GAMUT_SPACE_CCIR_2020: u32 = 32; +pub const ADL_GAMUT_SPACE_APPCTRL: u32 = 64; +pub const ADL_WHITE_POINT_5000K: u32 = 1; +pub const ADL_WHITE_POINT_6500K: u32 = 2; +pub const ADL_WHITE_POINT_7500K: u32 = 4; +pub const ADL_WHITE_POINT_9300K: u32 = 8; +pub const ADL_WHITE_POINT_CUSTOM: u32 = 16; +pub const ADL_GAMUT_WHITEPOINT_DIVIDER: u32 = 10000; +pub const ADL_REGAMMA_COEFFICIENT_A0_DIVIDER: u32 = 10000000; +pub const ADL_REGAMMA_COEFFICIENT_A1A2A3_DIVIDER: u32 = 1000; +pub const ADL_EDID_REGAMMA_COEFFICIENTS: u32 = 1; +pub const ADL_USE_GAMMA_RAMP: u32 = 16; +pub const ADL_APPLY_DEGAMMA: u32 = 32; +pub const ADL_EDID_REGAMMA_PREDEFINED_SRGB: u32 = 2; +pub const ADL_EDID_REGAMMA_PREDEFINED_PQ: u32 = 4; +pub const ADL_EDID_REGAMMA_PREDEFINED_PQ_2084_INTERIM: u32 = 8; +pub const ADL_EDID_REGAMMA_PREDEFINED_36: u32 = 64; +pub const ADL_EDID_REGAMMA_PREDEFINED_BT709: u32 = 128; +pub const ADL_EDID_REGAMMA_PREDEFINED_APPCTRL: u32 = 256; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB656: u32 = 1; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB666: u32 = 2; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB888: u32 = 4; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB101010: u32 = 8; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB161616: u32 = 16; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED1: u32 = 32; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED2: u32 = 64; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_RGB_RESERVED3: u32 = 128; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_XRGB_BIAS101010: u32 = 256; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_8BPCC: u32 = 512; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_10BPCC: u32 = 1024; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR444_12BPCC: u32 = 2048; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_8BPCC: u32 = 4096; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_10BPCC: u32 = 8192; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR422_12BPCC: u32 = 16384; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_8BPCC: u32 = 32768; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_10BPCC: u32 = 65536; +pub const ADL_DISPLAY_DDCINFO_PIXEL_FORMAT_YCBCR420_12BPCC: u32 = 131072; +pub const ADL_TF_sRGB: u32 = 1; +pub const ADL_TF_BT709: u32 = 2; +pub const ADL_TF_PQ2084: u32 = 4; +pub const ADL_TF_PQ2084_INTERIM: u32 = 8; +pub const ADL_TF_LINEAR_0_1: u32 = 16; +pub const ADL_TF_LINEAR_0_125: u32 = 32; +pub const ADL_TF_DOLBYVISION: u32 = 64; +pub const ADL_TF_GAMMA_22: u32 = 128; +pub const ADL_CS_sRGB: u32 = 1; +pub const ADL_CS_BT601: u32 = 2; +pub const ADL_CS_BT709: u32 = 4; +pub const ADL_CS_BT2020: u32 = 8; +pub const ADL_CS_ADOBE: u32 = 16; +pub const ADL_CS_P3: u32 = 32; +pub const ADL_CS_scRGB_MS_REF: u32 = 64; +pub const ADL_CS_DISPLAY_NATIVE: u32 = 128; +pub const ADL_CS_APP_CONTROL: u32 = 256; +pub const ADL_CS_DOLBYVISION: u32 = 512; +pub const ADL_HDR_CEA861_3: u32 = 1; +pub const ADL_HDR_DOLBYVISION: u32 = 2; +pub const ADL_HDR_FREESYNC_HDR: u32 = 4; +pub const ADL_HDR_FREESYNC_BACKLIGHT_SUPPORT: u32 = 1; +pub const ADL_HDR_FREESYNC_LOCAL_DIMMING: u32 = 2; +pub const ADL_SCA_LOCAL_DIMMING_DISABLE: u32 = 1; +pub const ADL_DEEPBITDEPTH_FORCEOFF: u32 = 0; +pub const ADL_DEEPBITDEPTH_10BPP_AUTO: u32 = 1; +pub const ADL_DEEPBITDEPTH_10BPP_FORCEON: u32 = 2; +pub const ADL_ADAPTER_CONFIGMEMORY_DBD: u32 = 1; +pub const ADL_ADAPTER_CONFIGMEMORY_ROTATE: u32 = 2; +pub const ADL_ADAPTER_CONFIGMEMORY_STEREO_PASSIVE: u32 = 4; +pub const ADL_ADAPTER_CONFIGMEMORY_STEREO_ACTIVE: u32 = 8; +pub const ADL_ADAPTER_CONFIGMEMORY_ENHANCEDVSYNC: u32 = 16; +pub const ADL_ADAPTER_CONFIGMEMORY_TEARFREEVSYNC: u32 = 16; +pub const ADL_MEMORYREQTYPE_VISIBLE: u32 = 1; +pub const ADL_MEMORYREQTYPE_INVISIBLE: u32 = 2; +pub const ADL_MEMORYREQTYPE_GPURESERVEDVISIBLE: u32 = 4; +pub const ADL_ADAPTER_TEAR_FREE_ON: u32 = 1; +pub const ADL_ADAPTER_TEAR_FREE_NOTENOUGHMEM: i32 = -1; +pub const ADL_ADAPTER_TEAR_FREE_OFF_ERR_QUADBUFFERSTEREO: i32 = -2; +pub const ADL_ADAPTER_TEAR_FREE_OFF_ERR_MGPUSLD: i32 = -3; +pub const ADL_ADAPTER_TEAR_FREE_OFF: u32 = 0; +pub const ADL_CROSSDISPLAY_PLATFORM: u32 = 1; +pub const ADL_CROSSDISPLAY_PLATFORM_LASSO: u32 = 2; +pub const ADL_CROSSDISPLAY_PLATFORM_DOCKSTATION: u32 = 4; +pub const ADL_CROSSDISPLAY_OPTION_NONE: u32 = 0; +pub const ADL_CROSSDISPLAY_OPTION_FORCESWITCH: u32 = 1; +pub const ADL_ADAPTERCONFIGSTATE_HEADLESS: u32 = 4; +pub const ADL_ADAPTERCONFIGSTATE_REQUISITE_RENDER: u32 = 1; +pub const ADL_ADAPTERCONFIGSTATE_ANCILLARY_RENDER: u32 = 2; +pub const ADL_ADAPTERCONFIGSTATE_SCATTERGATHER: u32 = 16; +pub const ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_POSITION: u32 = 1; +pub const ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_PANLOCK: u32 = 2; +pub const ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_SIZE: u32 = 8; +pub const ADL_MAX_AUDIO_SAMPLE_RATE_COUNT: u32 = 16; +pub const ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION: u32 = 1; +pub const ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION: u32 = 2; +pub const ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR: u32 = 4; +pub const ADL_OD6_CAPABILITY_POWER_CONTROL: u32 = 8; +pub const ADL_OD6_CAPABILITY_VOLTAGE_CONTROL: u32 = 16; +pub const ADL_OD6_CAPABILITY_PERCENT_ADJUSTMENT: u32 = 32; +pub const ADL_OD6_CAPABILITY_THERMAL_LIMIT_UNLOCK: u32 = 64; +pub const ADL_OD6_CAPABILITY_FANSPEED_IN_RPM: u32 = 128; +pub const ADL_OD6_SUPPORTEDSTATE_PERFORMANCE: u32 = 1; +pub const ADL_OD6_SUPPORTEDSTATE_POWER_SAVING: u32 = 2; +pub const ADL_OD6_GETSTATEINFO_DEFAULT_PERFORMANCE: u32 = 1; +pub const ADL_OD6_GETSTATEINFO_DEFAULT_POWER_SAVING: u32 = 2; +pub const ADL_OD6_GETSTATEINFO_CURRENT: u32 = 3; +pub const ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE: u32 = 4; +pub const ADL_OD6_GETSTATEINFO_CUSTOM_POWER_SAVING: u32 = 5; +pub const ADL_OD6_STATE_PERFORMANCE: u32 = 1; +pub const ADL_OD6_SETSTATE_PERFORMANCE: u32 = 1; +pub const ADL_OD6_SETSTATE_POWER_SAVING: u32 = 2; +pub const ADL_OD6_TCCAPS_THERMAL_CONTROLLER: u32 = 1; +pub const ADL_OD6_TCCAPS_FANSPEED_CONTROL: u32 = 2; +pub const ADL_OD6_TCCAPS_FANSPEED_PERCENT_READ: u32 = 256; +pub const ADL_OD6_TCCAPS_FANSPEED_PERCENT_WRITE: u32 = 512; +pub const ADL_OD6_TCCAPS_FANSPEED_RPM_READ: u32 = 1024; +pub const ADL_OD6_TCCAPS_FANSPEED_RPM_WRITE: u32 = 2048; +pub const ADL_OD6_FANSPEED_TYPE_PERCENT: u32 = 1; +pub const ADL_OD6_FANSPEED_TYPE_RPM: u32 = 2; +pub const ADL_OD6_FANSPEED_USER_DEFINED: u32 = 256; +pub const ADL_ODN_EVENTCOUNTER_THERMAL: u32 = 0; +pub const ADL_ODN_EVENTCOUNTER_VPURECOVERY: u32 = 1; +pub const ADL_PMLOG_MAX_SENSORS: u32 = 256; +pub const ADL_BLAYOUT_VALID_NUMBER_OF_SLOTS: u32 = 1; +pub const ADL_BLAYOUT_VALID_SLOT_SIZES: u32 = 2; +pub const ADL_BLAYOUT_VALID_CONNECTOR_OFFSETS: u32 = 4; +pub const ADL_BLAYOUT_VALID_CONNECTOR_LENGTHS: u32 = 8; +pub const ADL_ADAPTER_MAX_SLOTS: u32 = 4; +pub const ADL_ADAPTER_MAX_CONNECTORS: u32 = 10; +pub const ADL_MAX_CONNECTION_TYPES: u32 = 32; +pub const ADL_MAX_RELATIVE_ADDRESS_LINK_COUNT: u32 = 15; +pub const ADL_MAX_DISPLAY_EDID_DATA_SIZE: u32 = 1024; +pub const ADL_MAX_ERROR_RECORDS_COUNT: u32 = 256; +pub const ADL_MAX_POWER_POLICY: u32 = 6; +pub const ADL_CONNECTION_TYPE_VGA: u32 = 0; +pub const ADL_CONNECTION_TYPE_DVI: u32 = 1; +pub const ADL_CONNECTION_TYPE_DVI_SL: u32 = 2; +pub const ADL_CONNECTION_TYPE_HDMI: u32 = 3; +pub const ADL_CONNECTION_TYPE_DISPLAY_PORT: u32 = 4; +pub const ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_SL: u32 = 5; +pub const ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_DVI_DL: u32 = 6; +pub const ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_HDMI: u32 = 7; +pub const ADL_CONNECTION_TYPE_ACTIVE_DONGLE_DP_VGA: u32 = 8; +pub const ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_HDMI: u32 = 9; +pub const ADL_CONNECTION_TYPE_PASSIVE_DONGLE_DP_DVI: u32 = 10; +pub const ADL_CONNECTION_TYPE_MST: u32 = 11; +pub const ADL_CONNECTION_TYPE_ACTIVE_DONGLE: u32 = 12; +pub const ADL_CONNECTION_TYPE_VIRTUAL: u32 = 13; +pub const ADL_CONNECTION_PROPERTY_BITRATE: u32 = 1; +pub const ADL_CONNECTION_PROPERTY_NUMBER_OF_LANES: u32 = 2; +pub const ADL_CONNECTION_PROPERTY_3DCAPS: u32 = 4; +pub const ADL_CONNECTION_PROPERTY_OUTPUT_BANDWIDTH: u32 = 8; +pub const ADL_CONNECTION_PROPERTY_COLORDEPTH: u32 = 16; +pub const ADL_LANECOUNT_UNKNOWN: u32 = 0; +pub const ADL_LANECOUNT_ONE: u32 = 1; +pub const ADL_LANECOUNT_TWO: u32 = 2; +pub const ADL_LANECOUNT_FOUR: u32 = 4; +pub const ADL_LANECOUNT_EIGHT: u32 = 8; +pub const ADL_LANECOUNT_DEF: u32 = 4; +pub const ADL_LINK_BITRATE_UNKNOWN: u32 = 0; +pub const ADL_LINK_BITRATE_1_62_GHZ: u32 = 6; +pub const ADL_LINK_BITRATE_2_7_GHZ: u32 = 10; +pub const ADL_LINK_BITRATE_5_4_GHZ: u32 = 20; +pub const ADL_LINK_BITRATE_8_1_GHZ: u32 = 30; +pub const ADL_LINK_BITRATE_DEF: u32 = 10; +pub const ADL_CONNPROP_S3D_ALTERNATE_TO_FRAME_PACK: u32 = 1; +pub const ADL_COLORDEPTH_UNKNOWN: u32 = 0; +pub const ADL_COLORDEPTH_666: u32 = 1; +pub const ADL_COLORDEPTH_888: u32 = 2; +pub const ADL_COLORDEPTH_101010: u32 = 3; +pub const ADL_COLORDEPTH_121212: u32 = 4; +pub const ADL_COLORDEPTH_141414: u32 = 5; +pub const ADL_COLORDEPTH_161616: u32 = 6; +pub const ADL_COLOR_DEPTH_DEF: u32 = 2; +pub const ADL_EMUL_STATUS_REAL_DEVICE_CONNECTED: u32 = 1; +pub const ADL_EMUL_STATUS_EMULATED_DEVICE_PRESENT: u32 = 2; +pub const ADL_EMUL_STATUS_EMULATED_DEVICE_USED: u32 = 4; +pub const ADL_EMUL_STATUS_LAST_ACTIVE_DEVICE_USED: u32 = 8; +pub const ADL_EMUL_MODE_OFF: u32 = 0; +pub const ADL_EMUL_MODE_ON_CONNECTED: u32 = 1; +pub const ADL_EMUL_MODE_ON_DISCONNECTED: u32 = 2; +pub const ADL_EMUL_MODE_ALWAYS: u32 = 3; +pub const ADL_QUERY_REAL_DATA: u32 = 0; +pub const ADL_QUERY_EMULATED_DATA: u32 = 1; +pub const ADL_QUERY_CURRENT_DATA: u32 = 2; +pub const ADL_EDID_PERSISTANCE_DISABLED: u32 = 0; +pub const ADL_EDID_PERSISTANCE_ENABLED: u32 = 1; +pub const ADL_CONNECTOR_TYPE_UNKNOWN: u32 = 0; +pub const ADL_CONNECTOR_TYPE_VGA: u32 = 1; +pub const ADL_CONNECTOR_TYPE_DVI_D: u32 = 2; +pub const ADL_CONNECTOR_TYPE_DVI_I: u32 = 3; +pub const ADL_CONNECTOR_TYPE_ATICVDONGLE_NA: u32 = 4; +pub const ADL_CONNECTOR_TYPE_ATICVDONGLE_JP: u32 = 5; +pub const ADL_CONNECTOR_TYPE_ATICVDONGLE_NONI2C: u32 = 6; +pub const ADL_CONNECTOR_TYPE_ATICVDONGLE_NONI2C_D: u32 = 7; +pub const ADL_CONNECTOR_TYPE_HDMI_TYPE_A: u32 = 8; +pub const ADL_CONNECTOR_TYPE_HDMI_TYPE_B: u32 = 9; +pub const ADL_CONNECTOR_TYPE_DISPLAYPORT: u32 = 10; +pub const ADL_CONNECTOR_TYPE_EDP: u32 = 11; +pub const ADL_CONNECTOR_TYPE_MINI_DISPLAYPORT: u32 = 12; +pub const ADL_CONNECTOR_TYPE_VIRTUAL: u32 = 13; +pub const ADL_CONNECTOR_TYPE_USB_TYPE_C: u32 = 14; +pub const ADL_FREESYNC_USECASE_STATIC: u32 = 1; +pub const ADL_FREESYNC_USECASE_VIDEO: u32 = 2; +pub const ADL_FREESYNC_USECASE_GAMING: u32 = 4; +pub const ADL_FREESYNC_CAP_SUPPORTED: u32 = 1; +pub const ADL_FREESYNC_CAP_GPUSUPPORTED: u32 = 2; +pub const ADL_FREESYNC_CAP_DISPLAYSUPPORTED: u32 = 4; +pub const ADL_FREESYNC_CAP_CURRENTMODESUPPORTED: u32 = 8; +pub const ADL_FREESYNC_CAP_NOCFXORCFXSUPPORTED: u32 = 16; +pub const ADL_FREESYNC_CAP_NOGENLOCKORGENLOCKSUPPORTED: u32 = 32; +pub const ADL_FREESYNC_CAP_BORDERLESSWINDOWSUPPORTED: u32 = 64; +pub const ADL_FREESYNC_LABEL_UNSUPPORTED: u32 = 0; +pub const ADL_FREESYNC_LABEL_FREESYNC: u32 = 1; +pub const ADL_FREESYNC_LABEL_ADAPTIVE_SYNC: u32 = 2; +pub const ADL_FREESYNC_LABEL_VRR: u32 = 3; +pub const ADL_FREESYNC_LABEL_FREESYNC_PREMIUM: u32 = 4; +pub const ADL_FREESYNC_LABEL_FREESYNC_PREMIUM_PRO: u32 = 5; +pub const ADL_FREESYNC_POWEROPTIMIZATION_SUPPORTED_MASK: u32 = 1; +pub const ADL_FREESYNC_POWEROPTIMIZATION_ENABLED_MASK: u32 = 2; +pub const ADL_FREESYNC_POWEROPTIMIZATION_DEFAULT_VALUE_MASK: u32 = 4; +pub const ADL_MST_COMMANDLINE_PATH_MSG: u32 = 1; +pub const ADL_MST_COMMANDLINE_BROADCAST: u32 = 2; +pub const ADL_CROSSGPUDISPLAYCLONE_AMD_WITH_NONAMD: u32 = 1; +pub const ADL_CROSSGPUDISPLAYCLONE: u32 = 2; +pub const ADL_RADEON_LED_MAX_BRIGHTNESS: u32 = 2; +pub const ADL_RADEON_LED_MAX_SPEED: u32 = 4; +pub const ADL_RADEON_LED_MAX_RGB: u32 = 255; +pub const ADL_RADEON_LED_MAX_MORSE_CODE: u32 = 260; +pub const ADL_RADEON_LED_MAX_LED_ROW_ON_GRID: u32 = 7; +pub const ADL_RADEON_LED_MAX_LED_COLUMN_ON_GRID: u32 = 24; +pub const ADL_REG_DEVICE_FUNCTION_1: u32 = 1; +pub const ADL_FEATURE_NAME_LENGTH: u32 = 16; +pub const ADL_SDK_MAJOR_VERSION: u32 = 17; +pub const ADL_SDK_MINOR_VERSION: u32 = 1; +impl ADLThreadingModel { + #[doc = "< Default behavior. ADL will not enforce serialization of ADL API executions by multiple threads. Multiple threads will be allowed to enter to ADL at the same time. Note that ADL library is not guaranteed to be thread-safe. Client that calls ADL_Main_Control_Create have to provide its own mechanism for ADL calls serialization."] + pub const ADL_THREADING_UNLOCKED: ADLThreadingModel = ADLThreadingModel(0); +} +impl ADLThreadingModel { + #[doc = "< ADL will enforce serialization of ADL API when called by multiple threads. Only single thread will be allowed to enter ADL API at the time. This option makes ADL calls thread-safe. You shouldn't use this option if ADL calls will be executed on Linux on x-server rendering thread. It can cause the application to hung."] + pub const ADL_THREADING_LOCKED: ADLThreadingModel = ADLThreadingModel(1); +} +#[repr(transparent)] +#[doc = "\n \\defgroup thread_model\n Used with \\ref ADL_Main_ControlX2_Create and \\ref ADL2_Main_ControlX2_Create to specify how ADL handles API calls when executed by multiple threads concurrently.\n \\brief Declares ADL threading behavior.\n @{"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLThreadingModel(pub ::std::os::raw::c_int); +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_NORMAL: ADLPurposeCode = ADLPurposeCode(0); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_HIDE_MODE_SWITCH: ADLPurposeCode = ADLPurposeCode(1); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_MODE_SWITCH: ADLPurposeCode = ADLPurposeCode(2); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_ATTATCH_DEVICE: ADLPurposeCode = ADLPurposeCode(3); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_DETACH_DEVICE: ADLPurposeCode = ADLPurposeCode(4); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_SETPRIMARY_DEVICE: ADLPurposeCode = ADLPurposeCode(5); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_GDI_ROTATION: ADLPurposeCode = ADLPurposeCode(6); +} +impl ADLPurposeCode { + pub const ADL_PURPOSECODE_ATI_ROTATION: ADLPurposeCode = ADLPurposeCode(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPurposeCode(pub ::std::os::raw::c_int); +impl ADLAngle { + pub const ADL_ANGLE_LANDSCAPE: ADLAngle = ADLAngle(0); +} +impl ADLAngle { + pub const ADL_ANGLE_ROTATERIGHT: ADLAngle = ADLAngle(90); +} +impl ADLAngle { + pub const ADL_ANGLE_ROTATE180: ADLAngle = ADLAngle(180); +} +impl ADLAngle { + pub const ADL_ANGLE_ROTATELEFT: ADLAngle = ADLAngle(270); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLAngle(pub ::std::os::raw::c_int); +impl ADLOrientationDataType { + pub const ADL_ORIENTATIONTYPE_OSDATATYPE: ADLOrientationDataType = ADLOrientationDataType(0); +} +impl ADLOrientationDataType { + pub const ADL_ORIENTATIONTYPE_NONOSDATATYPE: ADLOrientationDataType = ADLOrientationDataType(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLOrientationDataType(pub ::std::os::raw::c_int); +impl ADLPanningMode { + pub const ADL_PANNINGMODE_NO_PANNING: ADLPanningMode = ADLPanningMode(0); +} +impl ADLPanningMode { + pub const ADL_PANNINGMODE_AT_LEAST_ONE_NO_PANNING: ADLPanningMode = ADLPanningMode(1); +} +impl ADLPanningMode { + pub const ADL_PANNINGMODE_ALLOW_PANNING: ADLPanningMode = ADLPanningMode(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPanningMode(pub ::std::os::raw::c_int); +impl ADLLARGEDESKTOPTYPE { + pub const ADL_LARGEDESKTOPTYPE_NORMALDESKTOP: ADLLARGEDESKTOPTYPE = ADLLARGEDESKTOPTYPE(0); +} +impl ADLLARGEDESKTOPTYPE { + pub const ADL_LARGEDESKTOPTYPE_PSEUDOLARGEDESKTOP: ADLLARGEDESKTOPTYPE = ADLLARGEDESKTOPTYPE(1); +} +impl ADLLARGEDESKTOPTYPE { + pub const ADL_LARGEDESKTOPTYPE_VERYLARGEDESKTOP: ADLLARGEDESKTOPTYPE = ADLLARGEDESKTOPTYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLLARGEDESKTOPTYPE(pub ::std::os::raw::c_int); +impl ADLPlatForm { + pub const GRAPHICS_PLATFORM_DESKTOP: ADLPlatForm = ADLPlatForm(0); +} +impl ADLPlatForm { + pub const GRAPHICS_PLATFORM_MOBILE: ADLPlatForm = ADLPlatForm(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPlatForm(pub ::std::os::raw::c_int); +impl ADLGraphicCoreGeneration { + pub const ADL_GRAPHIC_CORE_GENERATION_UNDEFINED: ADLGraphicCoreGeneration = + ADLGraphicCoreGeneration(0); +} +impl ADLGraphicCoreGeneration { + pub const ADL_GRAPHIC_CORE_GENERATION_PRE_GCN: ADLGraphicCoreGeneration = + ADLGraphicCoreGeneration(1); +} +impl ADLGraphicCoreGeneration { + pub const ADL_GRAPHIC_CORE_GENERATION_GCN: ADLGraphicCoreGeneration = + ADLGraphicCoreGeneration(2); +} +impl ADLGraphicCoreGeneration { + pub const ADL_GRAPHIC_CORE_GENERATION_RDNA: ADLGraphicCoreGeneration = + ADLGraphicCoreGeneration(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLGraphicCoreGeneration(pub ::std::os::raw::c_int); +impl DceSettingsType { + pub const DceSetting_HdmiLq: DceSettingsType = DceSettingsType(0); +} +impl DceSettingsType { + pub const DceSetting_DpSettings: DceSettingsType = DceSettingsType(1); +} +impl DceSettingsType { + pub const DceSetting_Protection: DceSettingsType = DceSettingsType(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct DceSettingsType(pub ::std::os::raw::c_int); +impl DpLinkRate { + pub const DPLinkRate_Unknown: DpLinkRate = DpLinkRate(0); +} +impl DpLinkRate { + pub const DPLinkRate_RBR: DpLinkRate = DpLinkRate(1); +} +impl DpLinkRate { + pub const DPLinkRate_2_16Gbps: DpLinkRate = DpLinkRate(2); +} +impl DpLinkRate { + pub const DPLinkRate_2_43Gbps: DpLinkRate = DpLinkRate(3); +} +impl DpLinkRate { + pub const DPLinkRate_HBR: DpLinkRate = DpLinkRate(4); +} +impl DpLinkRate { + pub const DPLinkRate_4_32Gbps: DpLinkRate = DpLinkRate(5); +} +impl DpLinkRate { + pub const DPLinkRate_HBR2: DpLinkRate = DpLinkRate(6); +} +impl DpLinkRate { + pub const DPLinkRate_HBR3: DpLinkRate = DpLinkRate(7); +} +impl DpLinkRate { + pub const DPLinkRate_UHBR10: DpLinkRate = DpLinkRate(8); +} +impl DpLinkRate { + pub const DPLinkRate_UHBR13D5: DpLinkRate = DpLinkRate(9); +} +impl DpLinkRate { + pub const DPLinkRate_UHBR20: DpLinkRate = DpLinkRate(10); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct DpLinkRate(pub ::std::os::raw::c_int); +impl ADLPXScheme { + pub const ADL_PX_SCHEME_INVALID: ADLPXScheme = ADLPXScheme(0); +} +impl ADLPXScheme { + pub const ADL_PX_SCHEME_FIXED: ADLPXScheme = ADLPXScheme(1); +} +impl ADLPXScheme { + pub const ADL_PX_SCHEME_DYNAMIC: ADLPXScheme = ADLPXScheme(2); +} +#[repr(transparent)] +#[doc = " PX Schemes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPXScheme(pub ::std::os::raw::c_int); +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_BINARY: ADLProfilePropertyType = ADLProfilePropertyType(0); +} +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_BOOLEAN: ADLProfilePropertyType = ADLProfilePropertyType(1); +} +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_DWORD: ADLProfilePropertyType = ADLProfilePropertyType(2); +} +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_QWORD: ADLProfilePropertyType = ADLProfilePropertyType(3); +} +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_ENUMERATED: ADLProfilePropertyType = + ADLProfilePropertyType(4); +} +impl ADLProfilePropertyType { + pub const ADL_PROFILEPROPERTY_TYPE_STRING: ADLProfilePropertyType = ADLProfilePropertyType(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLProfilePropertyType(pub ::std::os::raw::c_int); +impl ADL_VIRTUALDISPLAY_TYPE { + pub const ADL_VIRTUALDISPLAY_NONE: ADL_VIRTUALDISPLAY_TYPE = ADL_VIRTUALDISPLAY_TYPE(0); +} +impl ADL_VIRTUALDISPLAY_TYPE { + pub const ADL_VIRTUALDISPLAY_XINPUT: ADL_VIRTUALDISPLAY_TYPE = ADL_VIRTUALDISPLAY_TYPE(1); +} +impl ADL_VIRTUALDISPLAY_TYPE { + pub const ADL_VIRTUALDISPLAY_REMOTEPLAY: ADL_VIRTUALDISPLAY_TYPE = ADL_VIRTUALDISPLAY_TYPE(2); +} +impl ADL_VIRTUALDISPLAY_TYPE { + pub const ADL_VIRTUALDISPLAY_GENERIC: ADL_VIRTUALDISPLAY_TYPE = ADL_VIRTUALDISPLAY_TYPE(10); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_VIRTUALDISPLAY_TYPE(pub ::std::os::raw::c_int); +impl ADLMultiChannelSplitStateFlag { + pub const ADLMultiChannelSplit_Unitialized: ADLMultiChannelSplitStateFlag = + ADLMultiChannelSplitStateFlag(0); +} +impl ADLMultiChannelSplitStateFlag { + pub const ADLMultiChannelSplit_Disabled: ADLMultiChannelSplitStateFlag = + ADLMultiChannelSplitStateFlag(1); +} +impl ADLMultiChannelSplitStateFlag { + pub const ADLMultiChannelSplit_Enabled: ADLMultiChannelSplitStateFlag = + ADLMultiChannelSplitStateFlag(2); +} +impl ADLMultiChannelSplitStateFlag { + pub const ADLMultiChannelSplit_SaveProfile: ADLMultiChannelSplitStateFlag = + ADLMultiChannelSplitStateFlag(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLMultiChannelSplitStateFlag(pub ::std::os::raw::c_int); +impl ADLSampleRate { + pub const ADLSampleRate_32KHz: ADLSampleRate = ADLSampleRate(0); +} +impl ADLSampleRate { + pub const ADLSampleRate_44P1KHz: ADLSampleRate = ADLSampleRate(1); +} +impl ADLSampleRate { + pub const ADLSampleRate_48KHz: ADLSampleRate = ADLSampleRate(2); +} +impl ADLSampleRate { + pub const ADLSampleRate_88P2KHz: ADLSampleRate = ADLSampleRate(3); +} +impl ADLSampleRate { + pub const ADLSampleRate_96KHz: ADLSampleRate = ADLSampleRate(4); +} +impl ADLSampleRate { + pub const ADLSampleRate_176P4KHz: ADLSampleRate = ADLSampleRate(5); +} +impl ADLSampleRate { + pub const ADLSampleRate_192KHz: ADLSampleRate = ADLSampleRate(6); +} +impl ADLSampleRate { + pub const ADLSampleRate_384KHz: ADLSampleRate = ADLSampleRate(7); +} +impl ADLSampleRate { + pub const ADLSampleRate_768KHz: ADLSampleRate = ADLSampleRate(8); +} +impl ADLSampleRate { + pub const ADLSampleRate_Undefined: ADLSampleRate = ADLSampleRate(9); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLSampleRate(pub ::std::os::raw::c_int); +impl ADLODNControlType { + pub const ODNControlType_Current: ADLODNControlType = ADLODNControlType(0); +} +impl ADLODNControlType { + pub const ODNControlType_Default: ADLODNControlType = ADLODNControlType(1); +} +impl ADLODNControlType { + pub const ODNControlType_Auto: ADLODNControlType = ADLODNControlType(2); +} +impl ADLODNControlType { + pub const ODNControlType_Manual: ADLODNControlType = ADLODNControlType(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNControlType(pub ::std::os::raw::c_int); +impl ADLODNDPMMaskType { + pub const ADL_ODN_DPM_CLOCK: ADLODNDPMMaskType = ADLODNDPMMaskType(1); +} +impl ADLODNDPMMaskType { + pub const ADL_ODN_DPM_VDDC: ADLODNDPMMaskType = ADLODNDPMMaskType(2); +} +impl ADLODNDPMMaskType { + pub const ADL_ODN_DPM_MASK: ADLODNDPMMaskType = ADLODNDPMMaskType(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNDPMMaskType(pub ::std::os::raw::c_int); +impl ADLODNFeatureControl { + pub const ADL_ODN_SCLK_DPM: ADLODNFeatureControl = ADLODNFeatureControl(1); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_MCLK_DPM: ADLODNFeatureControl = ADLODNFeatureControl(2); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_SCLK_VDD: ADLODNFeatureControl = ADLODNFeatureControl(4); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_MCLK_VDD: ADLODNFeatureControl = ADLODNFeatureControl(8); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_FAN_SPEED_MIN: ADLODNFeatureControl = ADLODNFeatureControl(16); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_FAN_SPEED_TARGET: ADLODNFeatureControl = ADLODNFeatureControl(32); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_ACOUSTIC_LIMIT_SCLK: ADLODNFeatureControl = ADLODNFeatureControl(64); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_TEMPERATURE_FAN_MAX: ADLODNFeatureControl = ADLODNFeatureControl(128); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_TEMPERATURE_SYSTEM: ADLODNFeatureControl = ADLODNFeatureControl(256); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_POWER_LIMIT: ADLODNFeatureControl = ADLODNFeatureControl(512); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_SCLK_AUTO_LIMIT: ADLODNFeatureControl = ADLODNFeatureControl(1024); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_MCLK_AUTO_LIMIT: ADLODNFeatureControl = ADLODNFeatureControl(2048); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_SCLK_DPM_MASK_ENABLE: ADLODNFeatureControl = ADLODNFeatureControl(4096); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_MCLK_DPM_MASK_ENABLE: ADLODNFeatureControl = ADLODNFeatureControl(8192); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_MCLK_UNDERCLOCK_ENABLE: ADLODNFeatureControl = ADLODNFeatureControl(16384); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_SCLK_DPM_THROTTLE_NOTIFY: ADLODNFeatureControl = ADLODNFeatureControl(32768); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_POWER_UTILIZATION: ADLODNFeatureControl = ADLODNFeatureControl(65536); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_PERF_TUNING_SLIDER: ADLODNFeatureControl = ADLODNFeatureControl(131072); +} +impl ADLODNFeatureControl { + pub const ADL_ODN_REMOVE_WATTMAN_PAGE: ADLODNFeatureControl = ADLODNFeatureControl(-2147483648); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNFeatureControl(pub ::std::os::raw::c_int); +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_MEMORY_TIMING_TUNE: ADLODNExtFeatureControl = + ADLODNExtFeatureControl(1); +} +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_FAN_ZERO_RPM_CONTROL: ADLODNExtFeatureControl = + ADLODNExtFeatureControl(2); +} +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_AUTO_UV_ENGINE: ADLODNExtFeatureControl = + ADLODNExtFeatureControl(4); +} +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_AUTO_OC_ENGINE: ADLODNExtFeatureControl = + ADLODNExtFeatureControl(8); +} +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_AUTO_OC_MEMORY: ADLODNExtFeatureControl = + ADLODNExtFeatureControl(16); +} +impl ADLODNExtFeatureControl { + pub const ADL_ODN_EXT_FEATURE_FAN_CURVE: ADLODNExtFeatureControl = ADLODNExtFeatureControl(32); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNExtFeatureControl(pub ::std::os::raw::c_int); +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_AC_TIMING: ADLODNExtSettingId = ADLODNExtSettingId(0); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_ZERO_RPM_CONTROL: ADLODNExtSettingId = ADLODNExtSettingId(1); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_AUTO_UV_ENGINE: ADLODNExtSettingId = ADLODNExtSettingId(2); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_AUTO_OC_ENGINE: ADLODNExtSettingId = ADLODNExtSettingId(3); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_AUTO_OC_MEMORY: ADLODNExtSettingId = ADLODNExtSettingId(4); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_1: ADLODNExtSettingId = ADLODNExtSettingId(5); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_SPEED_1: ADLODNExtSettingId = ADLODNExtSettingId(6); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_2: ADLODNExtSettingId = ADLODNExtSettingId(7); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_SPEED_2: ADLODNExtSettingId = ADLODNExtSettingId(8); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_3: ADLODNExtSettingId = ADLODNExtSettingId(9); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_SPEED_3: ADLODNExtSettingId = ADLODNExtSettingId(10); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_4: ADLODNExtSettingId = + ADLODNExtSettingId(11); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_SPEED_4: ADLODNExtSettingId = ADLODNExtSettingId(12); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_TEMPERATURE_5: ADLODNExtSettingId = + ADLODNExtSettingId(13); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_PARAMETER_FAN_CURVE_SPEED_5: ADLODNExtSettingId = ADLODNExtSettingId(14); +} +impl ADLODNExtSettingId { + pub const ADL_ODN_POWERGAUGE: ADLODNExtSettingId = ADLODNExtSettingId(15); +} +impl ADLODNExtSettingId { + pub const ODN_COUNT: ADLODNExtSettingId = ADLODNExtSettingId(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNExtSettingId(pub ::std::os::raw::c_int); +impl ADLOD8FeatureControl { + pub const ADL_OD8_GFXCLK_LIMITS: ADLOD8FeatureControl = ADLOD8FeatureControl(1); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_GFXCLK_CURVE: ADLOD8FeatureControl = ADLOD8FeatureControl(2); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_UCLK_MAX: ADLOD8FeatureControl = ADLOD8FeatureControl(4); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_POWER_LIMIT: ADLOD8FeatureControl = ADLOD8FeatureControl(8); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_ACOUSTIC_LIMIT_SCLK: ADLOD8FeatureControl = ADLOD8FeatureControl(16); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_FAN_SPEED_MIN: ADLOD8FeatureControl = ADLOD8FeatureControl(32); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_TEMPERATURE_FAN: ADLOD8FeatureControl = ADLOD8FeatureControl(64); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_TEMPERATURE_SYSTEM: ADLOD8FeatureControl = ADLOD8FeatureControl(128); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_MEMORY_TIMING_TUNE: ADLOD8FeatureControl = ADLOD8FeatureControl(256); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_FAN_ZERO_RPM_CONTROL: ADLOD8FeatureControl = ADLOD8FeatureControl(512); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_AUTO_UV_ENGINE: ADLOD8FeatureControl = ADLOD8FeatureControl(1024); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_AUTO_OC_ENGINE: ADLOD8FeatureControl = ADLOD8FeatureControl(2048); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_AUTO_OC_MEMORY: ADLOD8FeatureControl = ADLOD8FeatureControl(4096); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_FAN_CURVE: ADLOD8FeatureControl = ADLOD8FeatureControl(8192); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_WS_AUTO_FAN_ACOUSTIC_LIMIT: ADLOD8FeatureControl = + ADLOD8FeatureControl(16384); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_GFXCLK_QUADRATIC_CURVE: ADLOD8FeatureControl = ADLOD8FeatureControl(32768); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_OPTIMIZED_GPU_POWER_MODE: ADLOD8FeatureControl = ADLOD8FeatureControl(65536); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_ODVOLTAGE_LIMIT: ADLOD8FeatureControl = ADLOD8FeatureControl(131072); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_ADV_OC_LIMITS: ADLOD8FeatureControl = ADLOD8FeatureControl(262144); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_PER_ZONE_GFX_VOLTAGE_OFFSET: ADLOD8FeatureControl = + ADLOD8FeatureControl(524288); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_AUTO_CURVE_OPTIMIZER: ADLOD8FeatureControl = ADLOD8FeatureControl(1048576); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_GFX_VOLTAGE_LIMIT: ADLOD8FeatureControl = ADLOD8FeatureControl(2097152); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_TDC_LIMIT: ADLOD8FeatureControl = ADLOD8FeatureControl(4194304); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_FULL_CONTROL_MODE: ADLOD8FeatureControl = ADLOD8FeatureControl(8388608); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_POWER_SAVING_FEATURE_CONTROL: ADLOD8FeatureControl = + ADLOD8FeatureControl(16777216); +} +impl ADLOD8FeatureControl { + pub const ADL_OD8_POWER_GAUGE: ADLOD8FeatureControl = ADLOD8FeatureControl(33554432); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLOD8FeatureControl(pub ::std::os::raw::c_int); +impl ADLOD8SettingId { + pub const OD8_GFXCLK_FMAX: ADLOD8SettingId = ADLOD8SettingId(0); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_FMIN: ADLOD8SettingId = ADLOD8SettingId(1); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_FREQ1: ADLOD8SettingId = ADLOD8SettingId(2); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_VOLTAGE1: ADLOD8SettingId = ADLOD8SettingId(3); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_FREQ2: ADLOD8SettingId = ADLOD8SettingId(4); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_VOLTAGE2: ADLOD8SettingId = ADLOD8SettingId(5); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_FREQ3: ADLOD8SettingId = ADLOD8SettingId(6); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_VOLTAGE3: ADLOD8SettingId = ADLOD8SettingId(7); +} +impl ADLOD8SettingId { + pub const OD8_UCLK_FMAX: ADLOD8SettingId = ADLOD8SettingId(8); +} +impl ADLOD8SettingId { + pub const OD8_POWER_PERCENTAGE: ADLOD8SettingId = ADLOD8SettingId(9); +} +impl ADLOD8SettingId { + pub const OD8_FAN_MIN_SPEED: ADLOD8SettingId = ADLOD8SettingId(10); +} +impl ADLOD8SettingId { + pub const OD8_FAN_ACOUSTIC_LIMIT: ADLOD8SettingId = ADLOD8SettingId(11); +} +impl ADLOD8SettingId { + pub const OD8_FAN_TARGET_TEMP: ADLOD8SettingId = ADLOD8SettingId(12); +} +impl ADLOD8SettingId { + pub const OD8_OPERATING_TEMP_MAX: ADLOD8SettingId = ADLOD8SettingId(13); +} +impl ADLOD8SettingId { + pub const OD8_AC_TIMING: ADLOD8SettingId = ADLOD8SettingId(14); +} +impl ADLOD8SettingId { + pub const OD8_FAN_ZERORPM_CONTROL: ADLOD8SettingId = ADLOD8SettingId(15); +} +impl ADLOD8SettingId { + pub const OD8_AUTO_UV_ENGINE_CONTROL: ADLOD8SettingId = ADLOD8SettingId(16); +} +impl ADLOD8SettingId { + pub const OD8_AUTO_OC_ENGINE_CONTROL: ADLOD8SettingId = ADLOD8SettingId(17); +} +impl ADLOD8SettingId { + pub const OD8_AUTO_OC_MEMORY_CONTROL: ADLOD8SettingId = ADLOD8SettingId(18); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_TEMPERATURE_1: ADLOD8SettingId = ADLOD8SettingId(19); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_SPEED_1: ADLOD8SettingId = ADLOD8SettingId(20); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_TEMPERATURE_2: ADLOD8SettingId = ADLOD8SettingId(21); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_SPEED_2: ADLOD8SettingId = ADLOD8SettingId(22); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_TEMPERATURE_3: ADLOD8SettingId = ADLOD8SettingId(23); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_SPEED_3: ADLOD8SettingId = ADLOD8SettingId(24); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_TEMPERATURE_4: ADLOD8SettingId = ADLOD8SettingId(25); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_SPEED_4: ADLOD8SettingId = ADLOD8SettingId(26); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_TEMPERATURE_5: ADLOD8SettingId = ADLOD8SettingId(27); +} +impl ADLOD8SettingId { + pub const OD8_FAN_CURVE_SPEED_5: ADLOD8SettingId = ADLOD8SettingId(28); +} +impl ADLOD8SettingId { + pub const OD8_WS_FAN_AUTO_FAN_ACOUSTIC_LIMIT: ADLOD8SettingId = ADLOD8SettingId(29); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_CURVE_COEFFICIENT_A: ADLOD8SettingId = ADLOD8SettingId(30); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_CURVE_COEFFICIENT_B: ADLOD8SettingId = ADLOD8SettingId(31); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_CURVE_COEFFICIENT_C: ADLOD8SettingId = ADLOD8SettingId(32); +} +impl ADLOD8SettingId { + pub const OD8_GFXCLK_CURVE_VFT_FMIN: ADLOD8SettingId = ADLOD8SettingId(33); +} +impl ADLOD8SettingId { + pub const OD8_UCLK_FMIN: ADLOD8SettingId = ADLOD8SettingId(34); +} +impl ADLOD8SettingId { + pub const OD8_FAN_ZERO_RPM_STOP_TEMPERATURE: ADLOD8SettingId = ADLOD8SettingId(35); +} +impl ADLOD8SettingId { + pub const OD8_OPTIMZED_POWER_MODE: ADLOD8SettingId = ADLOD8SettingId(36); +} +impl ADLOD8SettingId { + pub const OD8_OD_VOLTAGE: ADLOD8SettingId = ADLOD8SettingId(37); +} +impl ADLOD8SettingId { + pub const OD8_ADV_OC_LIMITS_SETTING: ADLOD8SettingId = ADLOD8SettingId(38); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_1: ADLOD8SettingId = ADLOD8SettingId(39); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_2: ADLOD8SettingId = ADLOD8SettingId(40); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_3: ADLOD8SettingId = ADLOD8SettingId(41); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_4: ADLOD8SettingId = ADLOD8SettingId(42); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_5: ADLOD8SettingId = ADLOD8SettingId(43); +} +impl ADLOD8SettingId { + pub const OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_6: ADLOD8SettingId = ADLOD8SettingId(44); +} +impl ADLOD8SettingId { + pub const OD8_AUTO_CURVE_OPTIMIZER_SETTING: ADLOD8SettingId = ADLOD8SettingId(45); +} +impl ADLOD8SettingId { + pub const OD8_GFX_VOLTAGE_LIMIT_SETTING: ADLOD8SettingId = ADLOD8SettingId(46); +} +impl ADLOD8SettingId { + pub const OD8_TDC_PERCENTAGE: ADLOD8SettingId = ADLOD8SettingId(47); +} +impl ADLOD8SettingId { + pub const OD8_FULL_CONTROL_MODE_SETTING: ADLOD8SettingId = ADLOD8SettingId(48); +} +impl ADLOD8SettingId { + pub const OD8_IDLE_POWER_SAVING_FEATURE_CONTROL: ADLOD8SettingId = ADLOD8SettingId(49); +} +impl ADLOD8SettingId { + pub const OD8_RUNTIME_POWER_SAVING_FEATURE_CONTROL: ADLOD8SettingId = ADLOD8SettingId(50); +} +impl ADLOD8SettingId { + pub const OD8_POWER_GAUGE: ADLOD8SettingId = ADLOD8SettingId(51); +} +impl ADLOD8SettingId { + pub const OD8_COUNT: ADLOD8SettingId = ADLOD8SettingId(52); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLOD8SettingId(pub ::std::os::raw::c_int); +impl ADLSensorType { + pub const SENSOR_MAXTYPES: ADLSensorType = ADLSensorType(0); +} +impl ADLSensorType { + pub const PMLOG_CLK_GFXCLK: ADLSensorType = ADLSensorType(1); +} +impl ADLSensorType { + pub const PMLOG_CLK_MEMCLK: ADLSensorType = ADLSensorType(2); +} +impl ADLSensorType { + pub const PMLOG_CLK_SOCCLK: ADLSensorType = ADLSensorType(3); +} +impl ADLSensorType { + pub const PMLOG_CLK_UVDCLK1: ADLSensorType = ADLSensorType(4); +} +impl ADLSensorType { + pub const PMLOG_CLK_UVDCLK2: ADLSensorType = ADLSensorType(5); +} +impl ADLSensorType { + pub const PMLOG_CLK_VCECLK: ADLSensorType = ADLSensorType(6); +} +impl ADLSensorType { + pub const PMLOG_CLK_VCNCLK: ADLSensorType = ADLSensorType(7); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_EDGE: ADLSensorType = ADLSensorType(8); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_MEM: ADLSensorType = ADLSensorType(9); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_VRVDDC: ADLSensorType = ADLSensorType(10); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_VRMVDD: ADLSensorType = ADLSensorType(11); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_LIQUID: ADLSensorType = ADLSensorType(12); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_PLX: ADLSensorType = ADLSensorType(13); +} +impl ADLSensorType { + pub const PMLOG_FAN_RPM: ADLSensorType = ADLSensorType(14); +} +impl ADLSensorType { + pub const PMLOG_FAN_PERCENTAGE: ADLSensorType = ADLSensorType(15); +} +impl ADLSensorType { + pub const PMLOG_SOC_VOLTAGE: ADLSensorType = ADLSensorType(16); +} +impl ADLSensorType { + pub const PMLOG_SOC_POWER: ADLSensorType = ADLSensorType(17); +} +impl ADLSensorType { + pub const PMLOG_SOC_CURRENT: ADLSensorType = ADLSensorType(18); +} +impl ADLSensorType { + pub const PMLOG_INFO_ACTIVITY_GFX: ADLSensorType = ADLSensorType(19); +} +impl ADLSensorType { + pub const PMLOG_INFO_ACTIVITY_MEM: ADLSensorType = ADLSensorType(20); +} +impl ADLSensorType { + pub const PMLOG_GFX_VOLTAGE: ADLSensorType = ADLSensorType(21); +} +impl ADLSensorType { + pub const PMLOG_MEM_VOLTAGE: ADLSensorType = ADLSensorType(22); +} +impl ADLSensorType { + pub const PMLOG_ASIC_POWER: ADLSensorType = ADLSensorType(23); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_VRSOC: ADLSensorType = ADLSensorType(24); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_VRMVDD0: ADLSensorType = ADLSensorType(25); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_VRMVDD1: ADLSensorType = ADLSensorType(26); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_HOTSPOT: ADLSensorType = ADLSensorType(27); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_GFX: ADLSensorType = ADLSensorType(28); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_SOC: ADLSensorType = ADLSensorType(29); +} +impl ADLSensorType { + pub const PMLOG_GFX_POWER: ADLSensorType = ADLSensorType(30); +} +impl ADLSensorType { + pub const PMLOG_GFX_CURRENT: ADLSensorType = ADLSensorType(31); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_CPU: ADLSensorType = ADLSensorType(32); +} +impl ADLSensorType { + pub const PMLOG_CPU_POWER: ADLSensorType = ADLSensorType(33); +} +impl ADLSensorType { + pub const PMLOG_CLK_CPUCLK: ADLSensorType = ADLSensorType(34); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_STATUS: ADLSensorType = ADLSensorType(35); +} +impl ADLSensorType { + pub const PMLOG_CLK_VCN1CLK1: ADLSensorType = ADLSensorType(36); +} +impl ADLSensorType { + pub const PMLOG_CLK_VCN1CLK2: ADLSensorType = ADLSensorType(37); +} +impl ADLSensorType { + pub const PMLOG_SMART_POWERSHIFT_CPU: ADLSensorType = ADLSensorType(38); +} +impl ADLSensorType { + pub const PMLOG_SMART_POWERSHIFT_DGPU: ADLSensorType = ADLSensorType(39); +} +impl ADLSensorType { + pub const PMLOG_BUS_SPEED: ADLSensorType = ADLSensorType(40); +} +impl ADLSensorType { + pub const PMLOG_BUS_LANES: ADLSensorType = ADLSensorType(41); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_LIQUID0: ADLSensorType = ADLSensorType(42); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_LIQUID1: ADLSensorType = ADLSensorType(43); +} +impl ADLSensorType { + pub const PMLOG_CLK_FCLK: ADLSensorType = ADLSensorType(44); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_STATUS_CPU: ADLSensorType = ADLSensorType(45); +} +impl ADLSensorType { + pub const PMLOG_SSPAIRED_ASICPOWER: ADLSensorType = ADLSensorType(46); +} +impl ADLSensorType { + pub const PMLOG_SSTOTAL_POWERLIMIT: ADLSensorType = ADLSensorType(47); +} +impl ADLSensorType { + pub const PMLOG_SSAPU_POWERLIMIT: ADLSensorType = ADLSensorType(48); +} +impl ADLSensorType { + pub const PMLOG_SSDGPU_POWERLIMIT: ADLSensorType = ADLSensorType(49); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_HOTSPOT_GCD: ADLSensorType = ADLSensorType(50); +} +impl ADLSensorType { + pub const PMLOG_TEMPERATURE_HOTSPOT_MCD: ADLSensorType = ADLSensorType(51); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE: ADLSensorType = ADLSensorType(52); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE: ADLSensorType = ADLSensorType(53); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE: ADLSensorType = ADLSensorType(54); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE: ADLSensorType = ADLSensorType(55); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE: ADLSensorType = ADLSensorType(56); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE: ADLSensorType = ADLSensorType(57); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE: ADLSensorType = ADLSensorType(58); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE: ADLSensorType = ADLSensorType(59); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE: ADLSensorType = ADLSensorType(60); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE: ADLSensorType = ADLSensorType(61); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE: ADLSensorType = ADLSensorType(62); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE: ADLSensorType = ADLSensorType(63); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TDC_GFX_PERCENTAGE: ADLSensorType = ADLSensorType(64); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TDC_SOC_PERCENTAGE: ADLSensorType = ADLSensorType(65); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_TDC_USR_PERCENTAGE: ADLSensorType = ADLSensorType(66); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_PPT0_PERCENTAGE: ADLSensorType = ADLSensorType(67); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_PPT1_PERCENTAGE: ADLSensorType = ADLSensorType(68); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_PPT2_PERCENTAGE: ADLSensorType = ADLSensorType(69); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_PPT3_PERCENTAGE: ADLSensorType = ADLSensorType(70); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_FIT_PERCENTAGE: ADLSensorType = ADLSensorType(71); +} +impl ADLSensorType { + pub const PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE: ADLSensorType = ADLSensorType(72); +} +impl ADLSensorType { + pub const PMLOG_BOARD_POWER: ADLSensorType = ADLSensorType(73); +} +impl ADLSensorType { + pub const PMLOG_MAX_SENSORS_REAL: ADLSensorType = ADLSensorType(74); +} +#[repr(transparent)] +#[doc = " \\deprecated Replaced with ADL_PMLOG_SENSORS"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLSensorType(pub ::std::os::raw::c_int); +impl ADL_THROTTLE_NOTIFICATION { + pub const ADL_PMLOG_THROTTLE_POWER: ADL_THROTTLE_NOTIFICATION = ADL_THROTTLE_NOTIFICATION(1); +} +impl ADL_THROTTLE_NOTIFICATION { + pub const ADL_PMLOG_THROTTLE_THERMAL: ADL_THROTTLE_NOTIFICATION = ADL_THROTTLE_NOTIFICATION(2); +} +impl ADL_THROTTLE_NOTIFICATION { + pub const ADL_PMLOG_THROTTLE_CURRENT: ADL_THROTTLE_NOTIFICATION = ADL_THROTTLE_NOTIFICATION(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_THROTTLE_NOTIFICATION(pub ::std::os::raw::c_int); +impl ADL_PMLOG_SENSORS { + pub const ADL_SENSOR_MAXTYPES: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(0); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_GFXCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(1); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_MEMCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(2); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_SOCCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(3); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_UVDCLK1: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(4); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_UVDCLK2: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(5); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_VCECLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(6); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_VCNCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(7); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_EDGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(8); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_MEM: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(9); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_VRVDDC: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(10); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_VRMVDD: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(11); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_LIQUID: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(12); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_PLX: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(13); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_FAN_RPM: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(14); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_FAN_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(15); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SOC_VOLTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(16); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SOC_POWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(17); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SOC_CURRENT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(18); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_INFO_ACTIVITY_GFX: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(19); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_INFO_ACTIVITY_MEM: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(20); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_GFX_VOLTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(21); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_MEM_VOLTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(22); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_ASIC_POWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(23); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_VRSOC: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(24); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_VRMVDD0: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(25); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_VRMVDD1: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(26); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_HOTSPOT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(27); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_GFX: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(28); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_SOC: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(29); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_GFX_POWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(30); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_GFX_CURRENT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(31); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_CPU: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(32); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CPU_POWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(33); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_CPUCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(34); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_STATUS: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(35); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_VCN1CLK1: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(36); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_VCN1CLK2: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(37); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SMART_POWERSHIFT_CPU: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(38); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SMART_POWERSHIFT_DGPU: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(39); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_BUS_SPEED: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(40); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_BUS_LANES: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(41); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_LIQUID0: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(42); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_LIQUID1: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(43); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_CLK_FCLK: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(44); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_STATUS_CPU: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(45); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SSPAIRED_ASICPOWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(46); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SSTOTAL_POWERLIMIT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(47); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SSAPU_POWERLIMIT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(48); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_SSDGPU_POWERLIMIT: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(49); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_HOTSPOT_GCD: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(50); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_TEMPERATURE_HOTSPOT_MCD: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(51); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(52); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(53); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(54); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(55); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(56); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(57); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(58); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(59); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(60); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(61); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(62); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(63); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TDC_GFX_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(64); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TDC_SOC_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(65); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_TDC_USR_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(66); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_PPT0_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(67); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_PPT1_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(68); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_PPT2_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(69); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_PPT3_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(70); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_FIT_PERCENTAGE: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(71); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE: ADL_PMLOG_SENSORS = + ADL_PMLOG_SENSORS(72); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_BOARD_POWER: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(73); +} +impl ADL_PMLOG_SENSORS { + pub const ADL_PMLOG_MAX_SENSORS_REAL: ADL_PMLOG_SENSORS = ADL_PMLOG_SENSORS(74); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_PMLOG_SENSORS(pub ::std::os::raw::c_int); +#[doc = " \\defgroup define_D3DKMT_HANDLE\n @{\n Handle can be used to create Device Handle when using CreateDevice()"] +pub type ADL_D3DKMT_HANDLE = ::std::os::raw::c_uint; +impl ADL_RAS_ERROR_INJECTION_MODE { + pub const ADL_RAS_ERROR_INJECTION_MODE_SINGLE: ADL_RAS_ERROR_INJECTION_MODE = + ADL_RAS_ERROR_INJECTION_MODE(1); +} +impl ADL_RAS_ERROR_INJECTION_MODE { + pub const ADL_RAS_ERROR_INJECTION_MODE_MULTIPLE: ADL_RAS_ERROR_INJECTION_MODE = + ADL_RAS_ERROR_INJECTION_MODE(2); +} +#[repr(transparent)] +#[doc = " @}"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_RAS_ERROR_INJECTION_MODE(pub ::std::os::raw::c_int); +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_UMC: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(0); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_SDMA: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(1); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_GFX_HUB: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(2); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_MMHUB: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(3); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_ATHUB: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(4); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_PCIE_BIF: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(5); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_HDP: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(6); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_XGMI_WAFL: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(7); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_DF: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(8); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_SMN: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(9); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_SEM: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(10); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_MP0: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(11); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_MP1: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(12); +} +impl ADL_RAS_BLOCK_ID { + pub const ADL_RAS_BLOCK_ID_FUSE: ADL_RAS_BLOCK_ID = ADL_RAS_BLOCK_ID(13); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_RAS_BLOCK_ID(pub ::std::os::raw::c_int); +impl ADL_MEM_SUB_BLOCK_ID { + pub const ADL_RAS__UMC_HBM: ADL_MEM_SUB_BLOCK_ID = ADL_MEM_SUB_BLOCK_ID(0); +} +impl ADL_MEM_SUB_BLOCK_ID { + pub const ADL_RAS__UMC_SRAM: ADL_MEM_SUB_BLOCK_ID = ADL_MEM_SUB_BLOCK_ID(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_MEM_SUB_BLOCK_ID(pub ::std::os::raw::c_int); +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__NONE: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(0); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(1); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__SINGLE_CORRECTABLE: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(2); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(3); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__MULTI_UNCORRECTABLE: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(4); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_MULTI_UNCORRECTABLE: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(5); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(6); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(7); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__POISON: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(8); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_POISON: _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(9); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__SINGLE_CORRECTABLE_POISON: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(10); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_POISON: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(11); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__MULTI_UNCORRECTABLE_POISON: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(12); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_MULTI_UNCORRECTABLE_POISON: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(13); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE_POISON: _ADL_RAS_ERROR_TYPE = + _ADL_RAS_ERROR_TYPE(14); +} +impl _ADL_RAS_ERROR_TYPE { + pub const ADL_RAS_ERROR__PARITY_SINGLE_CORRECTABLE_MULTI_UNCORRECTABLE_POISON: + _ADL_RAS_ERROR_TYPE = _ADL_RAS_ERROR_TYPE(15); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _ADL_RAS_ERROR_TYPE(pub ::std::os::raw::c_int); +pub use self::_ADL_RAS_ERROR_TYPE as ADL_RAS_ERROR_TYPE; +impl ADL_RAS_INJECTION_METHOD { + pub const ADL_RAS_ERROR__UMC_METH_COHERENT: ADL_RAS_INJECTION_METHOD = + ADL_RAS_INJECTION_METHOD(0); +} +impl ADL_RAS_INJECTION_METHOD { + pub const ADL_RAS_ERROR__UMC_METH_SINGLE_SHOT: ADL_RAS_INJECTION_METHOD = + ADL_RAS_INJECTION_METHOD(1); +} +impl ADL_RAS_INJECTION_METHOD { + pub const ADL_RAS_ERROR__UMC_METH_PERSISTENT: ADL_RAS_INJECTION_METHOD = + ADL_RAS_INJECTION_METHOD(2); +} +impl ADL_RAS_INJECTION_METHOD { + pub const ADL_RAS_ERROR__UMC_METH_PERSISTENT_DISABLE: ADL_RAS_INJECTION_METHOD = + ADL_RAS_INJECTION_METHOD(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_RAS_INJECTION_METHOD(pub ::std::os::raw::c_int); +impl ADL_DRIVER_EVENT_TYPE { + pub const ADL_EVENT_ID_AUTO_FEATURE_COMPLETED: ADL_DRIVER_EVENT_TYPE = + ADL_DRIVER_EVENT_TYPE(30); +} +impl ADL_DRIVER_EVENT_TYPE { + pub const ADL_EVENT_ID_FEATURE_AVAILABILITY: ADL_DRIVER_EVENT_TYPE = ADL_DRIVER_EVENT_TYPE(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_DRIVER_EVENT_TYPE(pub ::std::os::raw::c_int); +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_DVR: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(0); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_TURBOSYNC: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(1); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_FRAMEMETRICSMONITOR: ADL_UIFEATURES_GROUP = + ADL_UIFEATURES_GROUP(2); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_FRTC: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(3); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_XVISION: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(4); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_BLOCKCHAIN: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(5); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_GAMEINTELLIGENCE: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(6); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_CHILL: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(7); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_DELAG: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(8); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_BOOST: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(9); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_USU: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(10); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_XGMI: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(11); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_PROVSR: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(12); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_SMA: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(13); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_CAMERA: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(14); +} +impl ADL_UIFEATURES_GROUP { + pub const ADL_UIFEATURES_GROUP_FRTCPRO: ADL_UIFEATURES_GROUP = ADL_UIFEATURES_GROUP(15); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_UIFEATURES_GROUP(pub ::std::os::raw::c_int); +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_OFF: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(0); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Static: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(1); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Rainbow: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(2); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Swirl: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(3); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Chase: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(4); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Bounce: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(5); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_MorseCode: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(6); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_ColorCycle: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(7); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_Breathing: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(8); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_CustomPattern: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(9); +} +impl ADL_RADEON_USB_LED_BAR_CONTROLS { + pub const RadeonLEDBarControl_MAX: ADL_RADEON_USB_LED_BAR_CONTROLS = + ADL_RADEON_USB_LED_BAR_CONTROLS(10); +} +#[repr(transparent)] +#[doc = "\n\\brief\n\n\n\n\n \\nosubgrouping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_RADEON_USB_LED_BAR_CONTROLS(pub ::std::os::raw::c_int); +impl ADL_RADEON_USB_LED_CONTROL_CONFIGS { + pub const RadeonLEDPattern_Speed: ADL_RADEON_USB_LED_CONTROL_CONFIGS = + ADL_RADEON_USB_LED_CONTROL_CONFIGS(0); +} +impl ADL_RADEON_USB_LED_CONTROL_CONFIGS { + pub const RadeonLEDPattern_Brightness: ADL_RADEON_USB_LED_CONTROL_CONFIGS = + ADL_RADEON_USB_LED_CONTROL_CONFIGS(1); +} +impl ADL_RADEON_USB_LED_CONTROL_CONFIGS { + pub const RadeonLEDPattern_Direction: ADL_RADEON_USB_LED_CONTROL_CONFIGS = + ADL_RADEON_USB_LED_CONTROL_CONFIGS(2); +} +impl ADL_RADEON_USB_LED_CONTROL_CONFIGS { + pub const RadeonLEDPattern_Color: ADL_RADEON_USB_LED_CONTROL_CONFIGS = + ADL_RADEON_USB_LED_CONTROL_CONFIGS(3); +} +impl ADL_RADEON_USB_LED_CONTROL_CONFIGS { + pub const RadeonLEDPattern_MAX: ADL_RADEON_USB_LED_CONTROL_CONFIGS = + ADL_RADEON_USB_LED_CONTROL_CONFIGS(4); +} +#[repr(transparent)] +#[doc = "\n\\brief\n\n\n\n\n \\nosubgrouping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_RADEON_USB_LED_CONTROL_CONFIGS(pub ::std::os::raw::c_int); +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_ENHANCEDSYNC: ADL_USER_SETTINGS = ADL_USER_SETTINGS(1); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_CHILL_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(2); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_DELAG_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(4); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_BOOST_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(8); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_USU_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(16); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_CVDC_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(32); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_SCE_PROFILE: ADL_USER_SETTINGS = ADL_USER_SETTINGS(64); +} +impl ADL_USER_SETTINGS { + pub const ADL_USER_SETTINGS_PROVSR: ADL_USER_SETTINGS = ADL_USER_SETTINGS(128); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_USER_SETTINGS(pub ::std::os::raw::c_int); +#[doc = "\n\\brief Structure containing information about the graphics adapter.\n\n This structure is used to store various information about the graphics adapter. This\n information can be returned to the user. Alternatively, it can be used to access various driver calls to set\n or fetch various settings upon the user's request.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct AdapterInfo { + #[doc = " Size of the structure."] + pub iSize: ::std::os::raw::c_int, + #[doc = " The ADL index handle. One GPU may be associated with one or two index handles"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The unique device ID associated with this adapter."] + pub strUDID: [::std::os::raw::c_char; 256usize], + #[doc = " The BUS number associated with this adapter."] + pub iBusNumber: ::std::os::raw::c_int, + #[doc = " The driver number associated with this adapter."] + pub iDeviceNumber: ::std::os::raw::c_int, + #[doc = " The function number."] + pub iFunctionNumber: ::std::os::raw::c_int, + #[doc = " The vendor ID associated with this adapter."] + pub iVendorID: ::std::os::raw::c_int, + #[doc = " Adapter name."] + pub strAdapterName: [::std::os::raw::c_char; 256usize], + #[doc = " Display name. For example, \"\\\\\\\\Display0\" for Windows or \":0:0\" for Linux."] + pub strDisplayName: [::std::os::raw::c_char; 256usize], + #[doc = " Present or not; 1 if present and 0 if not present.It the logical adapter is present, the display name such as \\\\\\\\.\\\\Display1 can be found from OS"] + pub iPresent: ::std::os::raw::c_int, + #[doc = " Exist or not; 1 is exist and 0 is not present."] + pub iExist: ::std::os::raw::c_int, + #[doc = " Driver registry path."] + pub strDriverPath: [::std::os::raw::c_char; 256usize], + #[doc = " Driver registry path Ext for."] + pub strDriverPathExt: [::std::os::raw::c_char; 256usize], + #[doc = " PNP string from Windows."] + pub strPNPString: [::std::os::raw::c_char; 256usize], + #[doc = " It is generated from EnumDisplayDevices."] + pub iOSDisplayIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the graphics adapter.\n\n This structure is used to store various information about the graphics adapter. This\n information can be returned to the user. Alternatively, it can be used to access various driver calls to set\n or fetch various settings upon the user's request.\n \\nosubgrouping\n"] +pub type LPAdapterInfo = *mut AdapterInfo; +#[doc = "\n\\brief Structure containing information about an controller mode\n\n This structure is used to store information of an controller mode\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterCaps { + #[doc = " AdapterID for this adapter"] + pub iAdapterID: ::std::os::raw::c_int, + #[doc = " Number of controllers for this adapter"] + pub iNumControllers: ::std::os::raw::c_int, + #[doc = " Number of displays for this adapter"] + pub iNumDisplays: ::std::os::raw::c_int, + #[doc = " Number of overlays for this adapter"] + pub iNumOverlays: ::std::os::raw::c_int, + #[doc = " Number of GLSyncConnectors"] + pub iNumOfGLSyncConnectors: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the adapter caps"] + pub iCapsMask: ::std::os::raw::c_int, + #[doc = " The bit identifies the adapter caps \\ref define_adapter_caps"] + pub iCapsValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing additional information about the ASIC memory\n\n This structure is used to store additional information about the ASIC memory. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryInfo2 { + #[doc = " Memory size in bytes."] + pub iMemorySize: ::std::os::raw::c_longlong, + #[doc = " Memory type in string."] + pub strMemoryType: [::std::os::raw::c_char; 256usize], + #[doc = " Highest default performance level Memory bandwidth in Mbytes/s"] + pub iMemoryBandwidth: ::std::os::raw::c_longlong, + #[doc = " HyperMemory size in bytes."] + pub iHyperMemorySize: ::std::os::raw::c_longlong, + #[doc = " Invisible Memory size in bytes."] + pub iInvisibleMemorySize: ::std::os::raw::c_longlong, + #[doc = " Visible Memory size in bytes."] + pub iVisibleMemorySize: ::std::os::raw::c_longlong, +} +#[doc = "\n\\brief Structure containing additional information about the ASIC memory\n\n This structure is used to store additional information about the ASIC memory. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryInfo3 { + #[doc = " Memory size in bytes."] + pub iMemorySize: ::std::os::raw::c_longlong, + #[doc = " Memory type in string."] + pub strMemoryType: [::std::os::raw::c_char; 256usize], + #[doc = " Highest default performance level Memory bandwidth in Mbytes/s"] + pub iMemoryBandwidth: ::std::os::raw::c_longlong, + #[doc = " HyperMemory size in bytes."] + pub iHyperMemorySize: ::std::os::raw::c_longlong, + #[doc = " Invisible Memory size in bytes."] + pub iInvisibleMemorySize: ::std::os::raw::c_longlong, + #[doc = " Visible Memory size in bytes."] + pub iVisibleMemorySize: ::std::os::raw::c_longlong, + #[doc = " Vram vendor ID"] + pub iVramVendorRevId: ::std::os::raw::c_longlong, +} +#[doc = "\n\\brief Structure containing additional information about the ASIC memory\n\n This structure is used to store additional information about the ASIC memory. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryInfoX4 { + #[doc = " Memory size in bytes."] + pub iMemorySize: ::std::os::raw::c_longlong, + #[doc = " Memory type in string."] + pub strMemoryType: [::std::os::raw::c_char; 256usize], + #[doc = " Highest default performance level Memory bandwidth in Mbytes/s"] + pub iMemoryBandwidth: ::std::os::raw::c_longlong, + #[doc = " HyperMemory size in bytes."] + pub iHyperMemorySize: ::std::os::raw::c_longlong, + #[doc = " Invisible Memory size in bytes."] + pub iInvisibleMemorySize: ::std::os::raw::c_longlong, + #[doc = " Visible Memory size in bytes."] + pub iVisibleMemorySize: ::std::os::raw::c_longlong, + #[doc = " Vram vendor ID"] + pub iVramVendorRevId: ::std::os::raw::c_longlong, + #[doc = " Memory Bandiwidth that is calculated and finalized on the driver side, grab and go."] + pub iMemoryBandwidthX2: ::std::os::raw::c_longlong, + #[doc = " Memory Bit Rate that is calculated and finalized on the driver side, grab and go."] + pub iMemoryBitRateX2: ::std::os::raw::c_longlong, +} +impl ADLvRamVendors { + pub const ADLvRamVendor_Unsupported: ADLvRamVendors = ADLvRamVendors(0); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_SAMSUNG: ADLvRamVendors = ADLvRamVendors(1); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_INFINEON: ADLvRamVendors = ADLvRamVendors(2); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_ELPIDA: ADLvRamVendors = ADLvRamVendors(3); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_ETRON: ADLvRamVendors = ADLvRamVendors(4); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_NANYA: ADLvRamVendors = ADLvRamVendors(5); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_HYNIX: ADLvRamVendors = ADLvRamVendors(6); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_MOSEL: ADLvRamVendors = ADLvRamVendors(7); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_WINBOND: ADLvRamVendors = ADLvRamVendors(8); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_ESMT: ADLvRamVendors = ADLvRamVendors(9); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_MICRON: ADLvRamVendors = ADLvRamVendors(15); +} +impl ADLvRamVendors { + pub const ADLvRamVendor_Undefined: ADLvRamVendors = ADLvRamVendors(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLvRamVendors(pub ::std::os::raw::c_int); +#[doc = "\n\\brief Structure containing information about components of ASIC GCN architecture\n\n Elements of GCN info are compute units, number of Tex (Texture filtering units) , number of ROPs (render back-ends).\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGcnInfo { + pub CuCount: ::std::os::raw::c_int, + pub TexCount: ::std::os::raw::c_int, + pub RopCount: ::std::os::raw::c_int, + pub ASICFamilyId: ::std::os::raw::c_int, + pub ASICRevisionId: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information related virtual segment config information.\n\n This structure is used to store information related virtual segment config\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLVirtualSegmentSettingsOutput { + pub virtualSegmentSupported: ::std::os::raw::c_int, + pub virtualSegmentDefault: ::std::os::raw::c_int, + pub virtualSegmentCurrent: ::std::os::raw::c_int, + pub iMinSizeInMB: ::std::os::raw::c_int, + pub iMaxSizeInMB: ::std::os::raw::c_int, + pub icurrentSizeInMB: ::std::os::raw::c_int, + pub idefaultSizeInMB: ::std::os::raw::c_int, + pub iMask: ::std::os::raw::c_int, + pub iValue: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about the Chipset.\n\n This structure is used to store various information about the Chipset. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLChipSetInfo { + #[doc = "< Bus type."] + pub iBusType: ::std::os::raw::c_int, + pub iBusSpeedType: ::std::os::raw::c_int, + #[doc = "< Number of PCIE lanes."] + pub iMaxPCIELaneWidth: ::std::os::raw::c_int, + #[doc = "< Current PCIE Lane Width"] + pub iCurrentPCIELaneWidth: ::std::os::raw::c_int, + #[doc = "< Bit mask or AGP transfer speed."] + pub iSupportedAGPSpeeds: ::std::os::raw::c_int, + #[doc = "< Current AGP speed"] + pub iCurrentAGPSpeed: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the ASIC memory.\n\n This structure is used to store various information about the ASIC memory. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryInfo { + #[doc = " Memory size in bytes."] + pub iMemorySize: ::std::os::raw::c_longlong, + #[doc = " Memory type in string."] + pub strMemoryType: [::std::os::raw::c_char; 256usize], + #[doc = " Memory bandwidth in Mbytes/s."] + pub iMemoryBandwidth: ::std::os::raw::c_longlong, +} +#[doc = "\n\\brief Structure containing information about memory required by type\n\n This structure is returned by ADL_Adapter_ConfigMemory_Get, which given a desktop and display configuration\n will return the Memory used.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryRequired { + pub iMemoryReq: ::std::os::raw::c_longlong, + #[doc = " Memory in bytes required"] + pub iType: ::std::os::raw::c_int, + #[doc = " Type of Memory \\ref define_adl_validmemoryrequiredfields"] + pub iDisplayFeatureValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the features associated with a display\n\n This structure is a parameter to ADL_Adapter_ConfigMemory_Get, which given a desktop and display configuration\n will return the Memory used.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMemoryDisplayFeatures { + pub iDisplayIndex: ::std::os::raw::c_int, + #[doc = " ADL Display index"] + pub iDisplayFeatureValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing DDC information.\n\n This structure is used to store various DDC information that can be returned to the user.\n Note that all fields of type int are actually defined as unsigned int types within the driver.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDDCInfo { + #[doc = " Size of the structure"] + pub ulSize: ::std::os::raw::c_int, + #[doc = " Indicates whether the attached display supports DDC. If this field is zero on return, no other DDC information fields will be used."] + pub ulSupportsDDC: ::std::os::raw::c_int, + #[doc = " Returns the manufacturer ID of the display device. Should be zeroed if this information is not available."] + pub ulManufacturerID: ::std::os::raw::c_int, + #[doc = " Returns the product ID of the display device. Should be zeroed if this information is not available."] + pub ulProductID: ::std::os::raw::c_int, + #[doc = " Returns the name of the display device. Should be zeroed if this information is not available."] + pub cDisplayName: [::std::os::raw::c_char; 256usize], + #[doc = " Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available."] + pub ulMaxHResolution: ::std::os::raw::c_int, + #[doc = " Returns the maximum Vertical supported resolution. Should be zeroed if this information is not available."] + pub ulMaxVResolution: ::std::os::raw::c_int, + #[doc = " Returns the maximum supported refresh rate. Should be zeroed if this information is not available."] + pub ulMaxRefresh: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's horizontal resolution."] + pub ulPTMCx: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's vertical resolution."] + pub ulPTMCy: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's refresh rate."] + pub ulPTMRefreshRate: ::std::os::raw::c_int, + #[doc = " Return EDID flags."] + pub ulDDCInfoFlag: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing DDC information.\n\n This structure is used to store various DDC information that can be returned to the user.\n Note that all fields of type int are actually defined as unsigned int types within the driver.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDDCInfo2 { + #[doc = " Size of the structure"] + pub ulSize: ::std::os::raw::c_int, + #[doc = " Indicates whether the attached display supports DDC. If this field is zero on return, no other DDC\n information fields will be used."] + pub ulSupportsDDC: ::std::os::raw::c_int, + #[doc = " Returns the manufacturer ID of the display device. Should be zeroed if this information is not available."] + pub ulManufacturerID: ::std::os::raw::c_int, + #[doc = " Returns the product ID of the display device. Should be zeroed if this information is not available."] + pub ulProductID: ::std::os::raw::c_int, + #[doc = " Returns the name of the display device. Should be zeroed if this information is not available."] + pub cDisplayName: [::std::os::raw::c_char; 256usize], + #[doc = " Returns the maximum Horizontal supported resolution. Should be zeroed if this information is not available."] + pub ulMaxHResolution: ::std::os::raw::c_int, + #[doc = " Returns the maximum Vertical supported resolution. Should be zeroed if this information is not available."] + pub ulMaxVResolution: ::std::os::raw::c_int, + #[doc = " Returns the maximum supported refresh rate. Should be zeroed if this information is not available."] + pub ulMaxRefresh: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's horizontal resolution."] + pub ulPTMCx: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's vertical resolution."] + pub ulPTMCy: ::std::os::raw::c_int, + #[doc = " Returns the display device preferred timing mode's refresh rate."] + pub ulPTMRefreshRate: ::std::os::raw::c_int, + #[doc = " Return EDID flags."] + pub ulDDCInfoFlag: ::std::os::raw::c_int, + #[doc = " Returns 1 if the display supported packed pixel, 0 otherwise"] + pub bPackedPixelSupported: ::std::os::raw::c_int, + #[doc = " Returns the Pixel formats the display supports \\ref define_ddcinfo_pixelformats"] + pub iPanelPixelFormat: ::std::os::raw::c_int, + #[doc = " Return EDID serial ID."] + pub ulSerialID: ::std::os::raw::c_int, + #[doc = " Return minimum monitor luminance data"] + pub ulMinLuminanceData: ::std::os::raw::c_int, + #[doc = " Return average monitor luminance data"] + pub ulAvgLuminanceData: ::std::os::raw::c_int, + #[doc = " Return maximum monitor luminance data"] + pub ulMaxLuminanceData: ::std::os::raw::c_int, + #[doc = " Bit vector of supported transfer functions \\ref define_source_content_TF"] + pub iSupportedTransferFunction: ::std::os::raw::c_int, + #[doc = " Bit vector of supported color spaces \\ref define_source_content_CS"] + pub iSupportedColorSpace: ::std::os::raw::c_int, + #[doc = " Display Red Chromaticity X coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityRedX: ::std::os::raw::c_int, + #[doc = " Display Red Chromaticity Y coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityRedY: ::std::os::raw::c_int, + #[doc = " Display Green Chromaticity X coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityGreenX: ::std::os::raw::c_int, + #[doc = " Display Green Chromaticity Y coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityGreenY: ::std::os::raw::c_int, + #[doc = " Display Blue Chromaticity X coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityBlueX: ::std::os::raw::c_int, + #[doc = " Display Blue Chromaticity Y coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityBlueY: ::std::os::raw::c_int, + #[doc = " Display White Point X coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityWhitePointX: ::std::os::raw::c_int, + #[doc = " Display White Point Y coordinate multiplied by 10000"] + pub iNativeDisplayChromaticityWhitePointY: ::std::os::raw::c_int, + #[doc = " Display diffuse screen reflectance 0-1 (100%) in units of 0.01"] + pub iDiffuseScreenReflectance: ::std::os::raw::c_int, + #[doc = " Display specular screen reflectance 0-1 (100%) in units of 0.01"] + pub iSpecularScreenReflectance: ::std::os::raw::c_int, + #[doc = " Bit vector of supported color spaces \\ref define_HDR_support"] + pub iSupportedHDR: ::std::os::raw::c_int, + #[doc = " Bit vector for freesync flags"] + pub iFreesyncFlags: ::std::os::raw::c_int, + #[doc = " Return minimum monitor luminance without dimming data"] + pub ulMinLuminanceNoDimmingData: ::std::os::raw::c_int, + pub ulMaxBacklightMaxLuminanceData: ::std::os::raw::c_int, + pub ulMinBacklightMaxLuminanceData: ::std::os::raw::c_int, + pub ulMaxBacklightMinLuminanceData: ::std::os::raw::c_int, + pub ulMinBacklightMinLuminanceData: ::std::os::raw::c_int, + pub iReserved: [::std::os::raw::c_int; 4usize], +} +#[doc = "\n\\brief Structure containing information controller Gamma settings.\n\n This structure is used to store the red, green and blue color channel information for the.\n controller gamma setting. This information is returned by ADL, and it can also be used to\n set the controller gamma setting.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGamma { + #[doc = " Red color channel gamma value."] + pub fRed: f32, + #[doc = " Green color channel gamma value."] + pub fGreen: f32, + #[doc = " Blue color channel gamma value."] + pub fBlue: f32, +} +#[doc = "\n\\brief Structure containing information about component video custom modes.\n\n This structure is used to store the component video custom mode.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLCustomMode { + #[doc = " Custom mode flags. They are returned by the ADL driver."] + pub iFlags: ::std::os::raw::c_int, + #[doc = " Custom mode width."] + pub iModeWidth: ::std::os::raw::c_int, + #[doc = " Custom mode height."] + pub iModeHeight: ::std::os::raw::c_int, + #[doc = " Custom mode base width."] + pub iBaseModeWidth: ::std::os::raw::c_int, + #[doc = " Custom mode base height."] + pub iBaseModeHeight: ::std::os::raw::c_int, + #[doc = " Custom mode refresh rate."] + pub iRefreshRate: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing Clock information for OD5 calls.\n\n This structure is used to retrieve clock information for OD5 calls.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGetClocksOUT { + pub ulHighCoreClock: ::std::os::raw::c_long, + pub ulHighMemoryClock: ::std::os::raw::c_long, + pub ulHighVddc: ::std::os::raw::c_long, + pub ulCoreMin: ::std::os::raw::c_long, + pub ulCoreMax: ::std::os::raw::c_long, + pub ulMemoryMin: ::std::os::raw::c_long, + pub ulMemoryMax: ::std::os::raw::c_long, + pub ulActivityPercent: ::std::os::raw::c_long, + pub ulCurrentCoreClock: ::std::os::raw::c_long, + pub ulCurrentMemoryClock: ::std::os::raw::c_long, + pub ulReserved: ::std::os::raw::c_long, +} +#[doc = "\n\\brief Structure containing HDTV information for display calls.\n\n This structure is used to retrieve HDTV information information for display calls.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayConfig { + #[doc = " Size of the structure"] + pub ulSize: ::std::os::raw::c_long, + #[doc = " HDTV connector type."] + pub ulConnectorType: ::std::os::raw::c_long, + #[doc = " HDTV capabilities."] + pub ulDeviceData: ::std::os::raw::c_long, + #[doc = " Overridden HDTV capabilities."] + pub ulOverridedDeviceData: ::std::os::raw::c_long, + #[doc = " Reserved field"] + pub ulReserved: ::std::os::raw::c_long, +} +#[doc = "\n\\brief Structure containing information about the display device.\n\n This structure is used to store display device information\n such as display index, type, name, connection status, mapped adapter and controller indexes,\n whether or not multiple VPUs are supported, local display connections or not (through Lasso), etc.\n This information can be returned to the user. Alternatively, it can be used to access various driver calls to set\n or fetch various display device related settings upon the user's request.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayID { + #[doc = " The logical display index belonging to this adapter."] + pub iDisplayLogicalIndex: ::std::os::raw::c_int, + #[doc = "\\brief The physical display index.\n For example, display index 2 from adapter 2 can be used by current adapter 1.\\n\n So current adapter may enumerate this adapter as logical display 7 but the physical display\n index is still 2."] + pub iDisplayPhysicalIndex: ::std::os::raw::c_int, + #[doc = " The persistent logical adapter index for the display."] + pub iDisplayLogicalAdapterIndex: ::std::os::raw::c_int, + #[doc = "\\brief The persistent physical adapter index for the display.\n It can be the current adapter or a non-local adapter. \\n\n If this adapter index is different than the current adapter,\n the Display Non Local flag is set inside DisplayInfoValue."] + pub iDisplayPhysicalAdapterIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display device.\n\n This structure is used to store various information about the display device. This\n information can be returned to the user, or used to access various driver calls to set\n or fetch various display-device-related settings upon the user's request\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayInfo { + #[doc = " The DisplayID structure"] + pub displayID: ADLDisplayID, + #[doc = "\\deprecated The controller index to which the display is mapped.\\n Will not be used in the future\\n"] + pub iDisplayControllerIndex: ::std::os::raw::c_int, + #[doc = " The display's EDID name."] + pub strDisplayName: [::std::os::raw::c_char; 256usize], + #[doc = " The display's manufacturer name."] + pub strDisplayManufacturerName: [::std::os::raw::c_char; 256usize], + #[doc = " The Display type. For example: CRT, TV, CV, DFP."] + pub iDisplayType: ::std::os::raw::c_int, + #[doc = " The display output type. For example: HDMI, SVIDEO, COMPONMNET VIDEO."] + pub iDisplayOutputType: ::std::os::raw::c_int, + #[doc = " The connector type for the device."] + pub iDisplayConnector: ::std::os::raw::c_int, + #[doc = "\\brief The bit mask identifies the number of bits ADLDisplayInfo is currently using. \\n\n It will be the sum all the bit definitions in ADL_DISPLAY_DISPLAYINFO_xxx."] + pub iDisplayInfoMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display status. \\ref define_displayinfomask"] + pub iDisplayInfoValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display port MST device.\n\n This structure is used to store various MST information about the display port device. This\n information can be returned to the user, or used to access various driver calls to\n fetch various display-device-related settings upon the user's request\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayDPMSTInfo { + #[doc = " The ADLDisplayID structure"] + pub displayID: ADLDisplayID, + #[doc = " total bandwidth available on the DP connector"] + pub iTotalAvailableBandwidthInMpbs: ::std::os::raw::c_int, + #[doc = " bandwidth allocated to this display"] + pub iAllocatedBandwidthInMbps: ::std::os::raw::c_int, + #[doc = " string identifier for the display"] + pub strGlobalUniqueIdentifier: [::std::os::raw::c_char; 256usize], + #[doc = " The link count of relative address, rad[0] upto rad[linkCount] are valid"] + pub radLinkCount: ::std::os::raw::c_int, + #[doc = " The physical connector ID, used to identify the physical DP port"] + pub iPhysicalConnectorID: ::std::os::raw::c_int, + #[doc = " Relative address, address scheme starts from source side"] + pub rad: [::std::os::raw::c_char; 15usize], +} +#[doc = "\n\\brief Structure containing the display mode definition used per controller.\n\n This structure is used to store the display mode definition used per controller.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayMode { + #[doc = " Vertical resolution (in pixels)."] + pub iPelsHeight: ::std::os::raw::c_int, + #[doc = " Horizontal resolution (in pixels)."] + pub iPelsWidth: ::std::os::raw::c_int, + #[doc = " Color depth."] + pub iBitsPerPel: ::std::os::raw::c_int, + #[doc = " Refresh rate."] + pub iDisplayFrequency: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing detailed timing parameters.\n\n This structure is used to store the detailed timing parameters.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDetailedTiming { + #[doc = " Size of the structure."] + pub iSize: ::std::os::raw::c_int, + #[doc = " Timing flags. \\ref define_detailed_timing_flags"] + pub sTimingFlags: ::std::os::raw::c_short, + #[doc = " Total width (columns)."] + pub sHTotal: ::std::os::raw::c_short, + #[doc = " Displayed width."] + pub sHDisplay: ::std::os::raw::c_short, + #[doc = " Horizontal sync signal offset."] + pub sHSyncStart: ::std::os::raw::c_short, + #[doc = " Horizontal sync signal width."] + pub sHSyncWidth: ::std::os::raw::c_short, + #[doc = " Total height (rows)."] + pub sVTotal: ::std::os::raw::c_short, + #[doc = " Displayed height."] + pub sVDisplay: ::std::os::raw::c_short, + #[doc = " Vertical sync signal offset."] + pub sVSyncStart: ::std::os::raw::c_short, + #[doc = " Vertical sync signal width."] + pub sVSyncWidth: ::std::os::raw::c_short, + #[doc = " Pixel clock value."] + pub sPixelClock: ::std::os::raw::c_short, + #[doc = " Overscan right."] + pub sHOverscanRight: ::std::os::raw::c_short, + #[doc = " Overscan left."] + pub sHOverscanLeft: ::std::os::raw::c_short, + #[doc = " Overscan bottom."] + pub sVOverscanBottom: ::std::os::raw::c_short, + #[doc = " Overscan top."] + pub sVOverscanTop: ::std::os::raw::c_short, + pub sOverscan8B: ::std::os::raw::c_short, + pub sOverscanGR: ::std::os::raw::c_short, +} +#[doc = "\n\\brief Structure containing display mode information.\n\n This structure is used to store the display mode information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayModeInfo { + #[doc = " Timing standard of the current mode. \\ref define_modetiming_standard"] + pub iTimingStandard: ::std::os::raw::c_int, + #[doc = " Applicable timing standards for the current mode."] + pub iPossibleStandard: ::std::os::raw::c_int, + #[doc = " Refresh rate factor."] + pub iRefreshRate: ::std::os::raw::c_int, + #[doc = " Num of pixels in a row."] + pub iPelsWidth: ::std::os::raw::c_int, + #[doc = " Num of pixels in a column."] + pub iPelsHeight: ::std::os::raw::c_int, + #[doc = " Detailed timing parameters."] + pub sDetailedTiming: ADLDetailedTiming, +} +#[doc = "\n \\brief Structure containing information about display property.\n\n This structure is used to store the display property for the current adapter.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayProperty { + #[doc = " Must be set to sizeof the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Must be set to \\ref ADL_DL_DISPLAYPROPERTY_TYPE_EXPANSIONMODE or \\ref ADL_DL_DISPLAYPROPERTY_TYPE_USEUNDERSCANSCALING"] + pub iPropertyType: ::std::os::raw::c_int, + #[doc = " Get or Set \\ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_CENTER or \\ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_FULLSCREEN or \\ref ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_ASPECTRATIO or \\ref ADL_DL_DISPLAYPROPERTY_TYPE_ITCFLAGENABLE"] + pub iExpansionMode: ::std::os::raw::c_int, + #[doc = " Display Property supported? 1: Supported, 0: Not supported"] + pub iSupport: ::std::os::raw::c_int, + #[doc = " Display Property current value"] + pub iCurrent: ::std::os::raw::c_int, + #[doc = " Display Property Default value"] + pub iDefault: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Clock.\n\n This structure is used to store the clock information for the current adapter\n such as core clock and memory clock info.\n\\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLClockInfo { + #[doc = " Core clock in 10 KHz."] + pub iCoreClock: ::std::os::raw::c_int, + #[doc = " Memory clock in 10 KHz."] + pub iMemoryClock: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about I2C.\n\n This structure is used to store the I2C information for the current adapter.\n This structure is used by the ADL_Display_WriteAndReadI2C() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLI2C { + #[doc = " Size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Numerical value representing hardware I2C."] + pub iLine: ::std::os::raw::c_int, + #[doc = " The 7-bit I2C slave device address, shifted one bit to the left."] + pub iAddress: ::std::os::raw::c_int, + #[doc = " The offset of the data from the address."] + pub iOffset: ::std::os::raw::c_int, + #[doc = " Read from or write to slave device. \\ref ADL_DL_I2C_ACTIONREAD or \\ref ADL_DL_I2C_ACTIONWRITE or \\ref ADL_DL_I2C_ACTIONREAD_REPEATEDSTART"] + pub iAction: ::std::os::raw::c_int, + #[doc = " I2C clock speed in KHz."] + pub iSpeed: ::std::os::raw::c_int, + #[doc = " A numerical value representing the number of bytes to be sent or received on the I2C bus."] + pub iDataSize: ::std::os::raw::c_int, + #[doc = " Address of the characters which are to be sent or received on the I2C bus."] + pub pcData: *mut ::std::os::raw::c_char, +} +#[doc = "\n\\brief Structure containing information about EDID data.\n\n This structure is used to store the information about EDID data for the adapter.\n This structure is used by the ADL_Display_EdidData_Get() and ADL_Display_EdidData_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayEDIDData { + #[doc = " Size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Set to 0"] + pub iFlag: ::std::os::raw::c_int, + #[doc = " Size of cEDIDData. Set by ADL_Display_EdidData_Get() upon return"] + pub iEDIDSize: ::std::os::raw::c_int, + #[doc = " 0, 1 or 2. If set to 3 or above an error ADL_ERR_INVALID_PARAM is generated"] + pub iBlockIndex: ::std::os::raw::c_int, + #[doc = " EDID data"] + pub cEDIDData: [::std::os::raw::c_char; 256usize], + #[doc = " Reserved"] + pub iReserved: [::std::os::raw::c_int; 4usize], +} +#[doc = "\n\\brief Structure containing information about input of controller overlay adjustment.\n\n This structure is used to store the information about input of controller overlay adjustment for the adapter.\n This structure is used by the ADL_Display_ControllerOverlayAdjustmentCaps_Get, ADL_Display_ControllerOverlayAdjustmentData_Get, and\n ADL_Display_ControllerOverlayAdjustmentData_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLControllerOverlayInput { + #[doc = " Should be set to the sizeof the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = "\\ref ADL_DL_CONTROLLER_OVERLAY_ALPHA or \\ref ADL_DL_CONTROLLER_OVERLAY_ALPHAPERPIX"] + pub iOverlayAdjust: ::std::os::raw::c_int, + #[doc = " Data."] + pub iValue: ::std::os::raw::c_int, + #[doc = " Should be 0."] + pub iReserved: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about overlay adjustment.\n\n This structure is used to store the information about overlay adjustment for the adapter.\n This structure is used by the ADLControllerOverlayInfo() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdjustmentinfo { + #[doc = " Default value"] + pub iDefault: ::std::os::raw::c_int, + #[doc = " Minimum value"] + pub iMin: ::std::os::raw::c_int, + #[doc = " Maximum Value"] + pub iMax: ::std::os::raw::c_int, + #[doc = " Step value"] + pub iStep: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about controller overlay information.\n\n This structure is used to store information about controller overlay info for the adapter.\n This structure is used by the ADL_Display_ControllerOverlayAdjustmentCaps_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLControllerOverlayInfo { + #[doc = " Should be set to the sizeof the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Data."] + pub sOverlayInfo: ADLAdjustmentinfo, + #[doc = " Should be 0."] + pub iReserved: [::std::os::raw::c_int; 3usize], +} +#[doc = "\n\\brief Structure containing GL-Sync module information.\n\n This structure is used to retrieve GL-Sync module information for\n Workstation Framelock/Genlock.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGLSyncModuleID { + #[doc = " Unique GL-Sync module ID."] + pub iModuleID: ::std::os::raw::c_int, + #[doc = " GL-Sync GPU port index (to be passed into ADLGLSyncGenlockConfig.lSignalSource and ADLGlSyncPortControl.lSignalSource)."] + pub iGlSyncGPUPort: ::std::os::raw::c_int, + #[doc = " GL-Sync module firmware version of Boot Sector."] + pub iFWBootSectorVersion: ::std::os::raw::c_int, + #[doc = " GL-Sync module firmware version of User Sector."] + pub iFWUserSectorVersion: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync ports capabilities.\n\n This structure is used to retrieve hardware capabilities for the ports of the GL-Sync module\n for Workstation Framelock/Genlock (such as port type and number of associated LEDs).\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGLSyncPortCaps { + #[doc = " Port type. Bitfield of ADL_GLSYNC_PORTTYPE_* \\ref define_glsync"] + pub iPortType: ::std::os::raw::c_int, + #[doc = " Number of LEDs associated for this port."] + pub iNumOfLEDs: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync Genlock settings.\n\n This structure is used to get and set genlock settings for the GPU ports of the GL-Sync module\n for Workstation Framelock/Genlock.\\n\n \\see define_glsync\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGLSyncGenlockConfig { + #[doc = " Specifies what fields in this structure are valid \\ref define_glsync"] + pub iValidMask: ::std::os::raw::c_int, + #[doc = " Delay (ms) generating a sync signal."] + pub iSyncDelay: ::std::os::raw::c_int, + #[doc = " Vector of framelock control bits. Bitfield of ADL_GLSYNC_FRAMELOCKCNTL_* \\ref define_glsync"] + pub iFramelockCntlVector: ::std::os::raw::c_int, + #[doc = " Source of the sync signal. Either GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_* \\ref define_glsync"] + pub iSignalSource: ::std::os::raw::c_int, + #[doc = " Use sampled sync signal. A value of 0 specifies no sampling."] + pub iSampleRate: ::std::os::raw::c_int, + #[doc = " For interlaced sync signals, the value can be ADL_GLSYNC_SYNCFIELD_1 or *_BOTH \\ref define_glsync"] + pub iSyncField: ::std::os::raw::c_int, + #[doc = " The signal edge that should trigger synchronization. ADL_GLSYNC_TRIGGEREDGE_* \\ref define_glsync"] + pub iTriggerEdge: ::std::os::raw::c_int, + #[doc = " Scan rate multiplier applied to the sync signal. ADL_GLSYNC_SCANRATECOEFF_* \\ref define_glsync"] + pub iScanRateCoeff: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync port information.\n\n This structure is used to get status of the GL-Sync ports (BNC or RJ45s)\n for Workstation Framelock/Genlock.\n \\see define_glsync\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGlSyncPortInfo { + #[doc = " Type of GL-Sync port (ADL_GLSYNC_PORT_*)."] + pub iPortType: ::std::os::raw::c_int, + #[doc = " The number of LEDs for this port. It's also filled within ADLGLSyncPortCaps."] + pub iNumOfLEDs: ::std::os::raw::c_int, + #[doc = " Port state ADL_GLSYNC_PORTSTATE_* \\ref define_glsync"] + pub iPortState: ::std::os::raw::c_int, + #[doc = " Scanned frequency for this port (vertical refresh rate in milliHz; 60000 means 60 Hz)."] + pub iFrequency: ::std::os::raw::c_int, + #[doc = " Used for ADL_GLSYNC_PORT_BNC. It is ADL_GLSYNC_SIGNALTYPE_* \\ref define_glsync"] + pub iSignalType: ::std::os::raw::c_int, + #[doc = " Used for ADL_GLSYNC_PORT_RJ45PORT*. It is GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_*. \\ref define_glsync"] + pub iSignalSource: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync port control settings.\n\n This structure is used to configure the GL-Sync ports (RJ45s only)\n for Workstation Framelock/Genlock.\n \\see define_glsync\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGlSyncPortControl { + #[doc = " Port to control ADL_GLSYNC_PORT_RJ45PORT1 or ADL_GLSYNC_PORT_RJ45PORT2 \\ref define_glsync"] + pub iPortType: ::std::os::raw::c_int, + #[doc = " Port control data ADL_GLSYNC_PORTCNTL_* \\ref define_glsync"] + pub iControlVector: ::std::os::raw::c_int, + #[doc = " Source of the sync signal. Either GL_Sync GPU Port index or ADL_GLSYNC_SIGNALSOURCE_* \\ref define_glsync"] + pub iSignalSource: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync mode of a display.\n\n This structure is used to get and set GL-Sync mode settings for a display connected to\n an adapter attached to a GL-Sync module for Workstation Framelock/Genlock.\n \\see define_glsync\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGlSyncMode { + #[doc = " Mode control vector. Bitfield of ADL_GLSYNC_MODECNTL_* \\ref define_glsync"] + pub iControlVector: ::std::os::raw::c_int, + #[doc = " Mode status vector. Bitfield of ADL_GLSYNC_MODECNTL_STATUS_* \\ref define_glsync"] + pub iStatusVector: ::std::os::raw::c_int, + #[doc = " Index of GL-Sync connector used to genlock the display/controller."] + pub iGLSyncConnectorIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing GL-Sync mode of a display.\n\n This structure is used to get and set GL-Sync mode settings for a display connected to\n an adapter attached to a GL-Sync module for Workstation Framelock/Genlock.\n \\see define_glsync\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGlSyncMode2 { + #[doc = " Mode control vector. Bitfield of ADL_GLSYNC_MODECNTL_* \\ref define_glsync"] + pub iControlVector: ::std::os::raw::c_int, + #[doc = " Mode status vector. Bitfield of ADL_GLSYNC_MODECNTL_STATUS_* \\ref define_glsync"] + pub iStatusVector: ::std::os::raw::c_int, + #[doc = " Index of GL-Sync connector used to genlock the display/controller."] + pub iGLSyncConnectorIndex: ::std::os::raw::c_int, + #[doc = " Index of the display to which this GLSync applies to."] + pub iDisplayIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing the packet info of a display.\n\n This structure is used to get and set the packet information of a display.\n This structure is used by ADLDisplayDataPacket.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLInfoPacket { + pub hb0: ::std::os::raw::c_char, + pub hb1: ::std::os::raw::c_char, + pub hb2: ::std::os::raw::c_char, + #[doc = " sb0~sb27"] + pub sb: [::std::os::raw::c_char; 28usize], +} +#[doc = "\n\\brief Structure containing the AVI packet info of a display.\n\n This structure is used to get and set AVI the packet info of a display.\n This structure is used by ADLDisplayDataPacket.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAVIInfoPacket { + #[doc = " byte 3, bit 7"] + pub bPB3_ITC: ::std::os::raw::c_char, + #[doc = " byte 5, bit [7:4]."] + pub bPB5: ::std::os::raw::c_char, +} +#[doc = "\n\\brief Structure containing the Overdrive clock setting.\n\n This structure is used to get the Overdrive clock setting.\n This structure is used by ADLAdapterODClockInfo.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODClockSetting { + #[doc = " Deafult clock"] + pub iDefaultClock: ::std::os::raw::c_int, + #[doc = " Current clock"] + pub iCurrentClock: ::std::os::raw::c_int, + #[doc = " Maximum clcok"] + pub iMaxClock: ::std::os::raw::c_int, + #[doc = " Minimum clock"] + pub iMinClock: ::std::os::raw::c_int, + #[doc = " Requested clcock"] + pub iRequestedClock: ::std::os::raw::c_int, + #[doc = " Step"] + pub iStepClock: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing the Overdrive clock information.\n\n This structure is used to get the Overdrive clock information.\n This structure is used by the ADL_Display_ODClockInfo_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterODClockInfo { + #[doc = " Size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Flag \\ref define_clockinfo_flags"] + pub iFlags: ::std::os::raw::c_int, + #[doc = " Memory Clock"] + pub sMemoryClock: ADLODClockSetting, + #[doc = " Engine Clock"] + pub sEngineClock: ADLODClockSetting, +} +#[doc = "\n\\brief Structure containing the Overdrive clock configuration.\n\n This structure is used to set the Overdrive clock configuration.\n This structure is used by the ADL_Display_ODClockConfig_Set() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterODClockConfig { + #[doc = " Size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Flag \\ref define_clockinfo_flags"] + pub iFlags: ::std::os::raw::c_int, + #[doc = " Memory Clock"] + pub iMemoryClock: ::std::os::raw::c_int, + #[doc = " Engine Clock"] + pub iEngineClock: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about current power management related activity.\n\n This structure is used to store information about current power management related activity.\n This structure (Overdrive 5 interfaces) is used by the ADL_PM_CurrentActivity_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMActivity { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Current engine clock."] + pub iEngineClock: ::std::os::raw::c_int, + #[doc = " Current memory clock."] + pub iMemoryClock: ::std::os::raw::c_int, + #[doc = " Current core voltage."] + pub iVddc: ::std::os::raw::c_int, + #[doc = " GPU utilization."] + pub iActivityPercent: ::std::os::raw::c_int, + #[doc = " Performance level index."] + pub iCurrentPerformanceLevel: ::std::os::raw::c_int, + #[doc = " Current PCIE bus speed."] + pub iCurrentBusSpeed: ::std::os::raw::c_int, + #[doc = " Number of PCIE bus lanes."] + pub iCurrentBusLanes: ::std::os::raw::c_int, + #[doc = " Maximum number of PCIE bus lanes."] + pub iMaximumBusLanes: ::std::os::raw::c_int, + #[doc = " Reserved for future purposes."] + pub iReserved: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about thermal controller.\n\n This structure is used to store information about thermal controller.\n This structure is used by ADL_PM_ThermalDevices_Enum.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLThermalControllerInfo { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Possible valies: \\ref ADL_DL_THERMAL_DOMAIN_OTHER or \\ref ADL_DL_THERMAL_DOMAIN_GPU."] + pub iThermalDomain: ::std::os::raw::c_int, + #[doc = " GPU 0, 1, etc."] + pub iDomainIndex: ::std::os::raw::c_int, + #[doc = " Possible valies: \\ref ADL_DL_THERMAL_FLAG_INTERRUPT or \\ref ADL_DL_THERMAL_FLAG_FANCONTROL"] + pub iFlags: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about thermal controller temperature.\n\n This structure is used to store information about thermal controller temperature.\n This structure is used by the ADL_PM_Temperature_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLTemperature { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Temperature in millidegrees Celsius."] + pub iTemperature: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about thermal controller fan speed.\n\n This structure is used to store information about thermal controller fan speed.\n This structure is used by the ADL_PM_FanSpeedInfo_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFanSpeedInfo { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " \\ref define_fanctrl"] + pub iFlags: ::std::os::raw::c_int, + #[doc = " Minimum possible fan speed value in percents."] + pub iMinPercent: ::std::os::raw::c_int, + #[doc = " Maximum possible fan speed value in percents."] + pub iMaxPercent: ::std::os::raw::c_int, + #[doc = " Minimum possible fan speed value in RPM."] + pub iMinRPM: ::std::os::raw::c_int, + #[doc = " Maximum possible fan speed value in RPM."] + pub iMaxRPM: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about fan speed reported by thermal controller.\n\n This structure is used to store information about fan speed reported by thermal controller.\n This structure is used by the ADL_Overdrive5_FanSpeed_Get() and ADL_Overdrive5_FanSpeed_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFanSpeedValue { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Possible valies: \\ref ADL_DL_FANCTRL_SPEED_TYPE_PERCENT or \\ref ADL_DL_FANCTRL_SPEED_TYPE_RPM"] + pub iSpeedType: ::std::os::raw::c_int, + #[doc = " Fan speed value"] + pub iFanSpeed: ::std::os::raw::c_int, + #[doc = " The only flag for now is: \\ref ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED"] + pub iFlags: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing the range of Overdrive parameter.\n\n This structure is used to store information about the range of Overdrive parameter.\n This structure is used by ADLODParameters.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODParameterRange { + #[doc = " Minimum parameter value."] + pub iMin: ::std::os::raw::c_int, + #[doc = " Maximum parameter value."] + pub iMax: ::std::os::raw::c_int, + #[doc = " Parameter step value."] + pub iStep: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive parameters.\n\n This structure is used to store information about Overdrive parameters.\n This structure is used by the ADL_Overdrive5_ODParameters_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODParameters { + #[doc = " Must be set to the size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Number of standard performance states."] + pub iNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Indicates whether the GPU is capable to measure its activity."] + pub iActivityReportingSupported: ::std::os::raw::c_int, + #[doc = " Indicates whether the GPU supports discrete performance levels or performance range."] + pub iDiscretePerformanceLevels: ::std::os::raw::c_int, + #[doc = " Reserved for future use."] + pub iReserved: ::std::os::raw::c_int, + #[doc = " Engine clock range."] + pub sEngineClock: ADLODParameterRange, + #[doc = " Memory clock range."] + pub sMemoryClock: ADLODParameterRange, + #[doc = " Core voltage range."] + pub sVddc: ADLODParameterRange, +} +#[doc = "\n\\brief Structure containing information about Overdrive level.\n\n This structure is used to store information about Overdrive level.\n This structure is used by ADLODPerformanceLevels.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODPerformanceLevel { + #[doc = " Engine clock."] + pub iEngineClock: ::std::os::raw::c_int, + #[doc = " Memory clock."] + pub iMemoryClock: ::std::os::raw::c_int, + #[doc = " Core voltage."] + pub iVddc: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive performance levels.\n\n This structure is used to store information about Overdrive performance levels.\n This structure is used by the ADL_Overdrive5_ODPerformanceLevels_Get() and ADL_Overdrive5_ODPerformanceLevels_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODPerformanceLevels { + #[doc = " Must be set to sizeof( \\ref ADLODPerformanceLevels ) + sizeof( \\ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1)"] + pub iSize: ::std::os::raw::c_int, + pub iReserved: ::std::os::raw::c_int, + #[doc = " Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements."] + pub aLevels: [ADLODPerformanceLevel; 1usize], +} +#[doc = "\n\\brief Structure containing information about the proper CrossfireX chains combinations.\n\n This structure is used to store information about the CrossfireX chains combination for a particular adapter.\n This structure is used by the ADL_Adapter_Crossfire_Caps(), ADL_Adapter_Crossfire_Get(), and ADL_Adapter_Crossfire_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLCrossfireComb { + #[doc = " Number of adapters in this combination."] + pub iNumLinkAdapter: ::std::os::raw::c_int, + #[doc = " A list of ADL indexes of the linked adapters in this combination."] + pub iAdaptLink: [::std::os::raw::c_int; 3usize], +} +#[doc = "\n\\brief Structure containing CrossfireX state and error information.\n\n This structure is used to store state and error information about a particular adapter CrossfireX combination.\n This structure is used by the ADL_Adapter_Crossfire_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLCrossfireInfo { + #[doc = " Current error code of this CrossfireX combination."] + pub iErrorCode: ::std::os::raw::c_int, + #[doc = " Current \\ref define_crossfirestate"] + pub iState: ::std::os::raw::c_int, + #[doc = " If CrossfireX is supported by this combination. The value is either \\ref ADL_TRUE or \\ref ADL_FALSE."] + pub iSupported: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about the BIOS.\n\n This structure is used to store various information about the Chipset. This\n information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLBiosInfo { + #[doc = "< Part number."] + pub strPartNumber: [::std::os::raw::c_char; 256usize], + #[doc = "< Version number."] + pub strVersion: [::std::os::raw::c_char; 256usize], + #[doc = "< BIOS date in yyyy/mm/dd hh:mm format."] + pub strDate: [::std::os::raw::c_char; 256usize], +} +#[doc = "\n \\brief Structure containing information about adapter location.\n\n This structure is used to store information about adapter location.\n This structure is used by ADLMVPUStatus.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterLocation { + #[doc = " PCI Bus number : 8 bits"] + pub iBus: ::std::os::raw::c_int, + #[doc = " Device number : 5 bits"] + pub iDevice: ::std::os::raw::c_int, + #[doc = " Function number : 3 bits"] + pub iFunction: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about adapter location.\n\n This structure is used to store information about adapter location.\n This structure is used by ADLMVPUStatus.\n \\nosubgrouping\n"] +pub type ADLBdf = ADLAdapterLocation; +#[doc = "\n \\brief Structure containing version information\n\n This structure is used to store software version information, description of the display device and a web link to the latest installed Catalyst drivers.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLVersionsInfo { + #[doc = " Driver Release (Packaging) Version (e.g. 8.71-100128n-094835E-ATI)"] + pub strDriverVer: [::std::os::raw::c_char; 256usize], + #[doc = " Catalyst Version(e.g. \"10.1\")."] + pub strCatalystVersion: [::std::os::raw::c_char; 256usize], + #[doc = " Web link to an XML file with information about the latest AMD drivers and locations (e.g. \"http://www.amd.com/us/driverxml\" )"] + pub strCatalystWebLink: [::std::os::raw::c_char; 256usize], +} +#[doc = "\n \\brief Structure containing version information\n\n This structure is used to store software version information, description of the display device and a web link to the latest installed Catalyst drivers.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLVersionsInfoX2 { + #[doc = " Driver Release (Packaging) Version (e.g. \"16.20.1035-160621a-303814C\")"] + pub strDriverVer: [::std::os::raw::c_char; 256usize], + #[doc = " Catalyst Version(e.g. \"15.8\")."] + pub strCatalystVersion: [::std::os::raw::c_char; 256usize], + #[doc = " Crimson Version(e.g. \"16.6.2\")."] + pub strCrimsonVersion: [::std::os::raw::c_char; 256usize], + #[doc = " Web link to an XML file with information about the latest AMD drivers and locations (e.g. \"http://support.amd.com/drivers/xml/driver_09_us.xml\" )"] + pub strCatalystWebLink: [::std::os::raw::c_char; 256usize], +} +#[doc = "\n \\brief Structure containing information about MultiVPU capabilities.\n\n This structure is used to store information about MultiVPU capabilities.\n This structure is used by the ADL_Display_MVPUCaps_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMVPUCaps { + #[doc = " Must be set to sizeof( ADLMVPUCaps )."] + pub iSize: ::std::os::raw::c_int, + #[doc = " Number of adapters."] + pub iAdapterCount: ::std::os::raw::c_int, + #[doc = " Bits set for all possible MVPU masters. \\ref MVPU_ADAPTER_0 .. \\ref MVPU_ADAPTER_3"] + pub iPossibleMVPUMasters: ::std::os::raw::c_int, + #[doc = " Bits set for all possible MVPU slaves. \\ref MVPU_ADAPTER_0 .. \\ref MVPU_ADAPTER_3"] + pub iPossibleMVPUSlaves: ::std::os::raw::c_int, + #[doc = " Registry path for each adapter."] + pub cAdapterPath: [[::std::os::raw::c_char; 256usize]; 4usize], +} +#[doc = "\n \\brief Structure containing information about MultiVPU status.\n\n This structure is used to store information about MultiVPU status.\n Ths structure is used by the ADL_Display_MVPUStatus_Get() function.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMVPUStatus { + #[doc = " Must be set to sizeof( ADLMVPUStatus )."] + pub iSize: ::std::os::raw::c_int, + #[doc = " Number of active adapters."] + pub iActiveAdapterCount: ::std::os::raw::c_int, + #[doc = " MVPU status."] + pub iStatus: ::std::os::raw::c_int, + #[doc = " PCI Bus/Device/Function for each active adapter participating in MVPU."] + pub aAdapterLocation: [ADLAdapterLocation; 4usize], +} +#[doc = "\n \\brief Structure containing information about the activatable source.\n\n This structure is used to store activatable source information\n This information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLActivatableSource { + #[doc = " The Persistent logical Adapter Index."] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The number of Activatable Sources."] + pub iNumActivatableSources: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits ActivatableSourceValue is using. (Not currnetly used)"] + pub iActivatableSourceMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the status. (Not currnetly used)"] + pub iActivatableSourceValue: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about display mode.\n\n This structure is used to store the display mode for the current adapter\n such as X, Y positions, screen resolutions, orientation,\n color depth, refresh rate, progressive or interlace mode, etc.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMode { + #[doc = " Adapter index."] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " Display IDs."] + pub displayID: ADLDisplayID, + #[doc = " Screen position X coordinate."] + pub iXPos: ::std::os::raw::c_int, + #[doc = " Screen position Y coordinate."] + pub iYPos: ::std::os::raw::c_int, + #[doc = " Screen resolution Width."] + pub iXRes: ::std::os::raw::c_int, + #[doc = " Screen resolution Height."] + pub iYRes: ::std::os::raw::c_int, + #[doc = " Screen Color Depth. E.g., 16, 32."] + pub iColourDepth: ::std::os::raw::c_int, + #[doc = " Screen refresh rate. Could be fractional E.g. 59.97"] + pub fRefreshRate: f32, + #[doc = " Screen orientation. E.g., 0, 90, 180, 270."] + pub iOrientation: ::std::os::raw::c_int, + #[doc = " Vista mode flag indicating Progressive or Interlaced mode."] + pub iModeFlag: ::std::os::raw::c_int, + #[doc = " The bit mask identifying the number of bits this Mode is currently using. It is the sum of all the bit definitions defined in \\ref define_displaymode"] + pub iModeMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifying the display status. The detailed definition is in \\ref define_displaymode"] + pub iModeValue: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about display target information.\n\n This structure is used to store the display target information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayTarget { + #[doc = " The Display ID."] + pub displayID: ADLDisplayID, + #[doc = " The display map index identify this manner and the desktop surface."] + pub iDisplayMapIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits DisplayTarget is currently using. It is the sum of all the bit definitions defined in \\ref ADL_DISPLAY_DISPLAYTARGET_PREFERRED."] + pub iDisplayTargetMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display status. The detailed definition is in \\ref ADL_DISPLAY_DISPLAYTARGET_PREFERRED."] + pub iDisplayTargetValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS bezel Mode information.\n\n This structure is used to store the display SLS bezel Mode information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct tagADLBezelTransientMode { + #[doc = " Adapter Index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " SLS Map Index"] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " The mode index"] + pub iSLSModeIndex: ::std::os::raw::c_int, + #[doc = " The mode"] + pub displayMode: ADLMode, + #[doc = " The number of bezel offsets belongs to this map"] + pub iNumBezelOffset: ::std::os::raw::c_int, + #[doc = " The first bezel offset array index in the native mode array"] + pub iFirstBezelOffsetArrayIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the bits this structure is currently using. It will be the total OR of all the bit definitions."] + pub iSLSBezelTransientModeMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display status. The detail definition is defined below."] + pub iSLSBezelTransientModeValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS bezel Mode information.\n\n This structure is used to store the display SLS bezel Mode information.\n \\nosubgrouping\n"] +pub type ADLBezelTransientMode = tagADLBezelTransientMode; +#[doc = "\n \\brief Structure containing information about the adapter display manner.\n\n This structure is used to store adapter display manner information\n This information can be returned to the user. Alternatively, it can be used to access various driver calls to\n fetch various display device related display manner settings upon the user's request.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterDisplayCap { + #[doc = " The Persistent logical Adapter Index."] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits AdapterDisplayCap is currently using. Sum all the bits defined in ADL_ADAPTER_DISPLAYCAP_XXX"] + pub iAdapterDisplayCapMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the status. Refer to ADL_ADAPTER_DISPLAYCAP_XXX"] + pub iAdapterDisplayCapValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about display mapping.\n\n This structure is used to store the display mapping data such as display manner.\n For displays with horizontal or vertical stretch manner,\n this structure also stores the display order, display row, and column data.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayMap { + #[doc = " The current display map index. It is the OS desktop index. For example, if the OS index 1 is showing clone mode, the display map will be 1."] + pub iDisplayMapIndex: ::std::os::raw::c_int, + #[doc = " The Display Mode for the current map"] + pub displayMode: ADLMode, + #[doc = " The number of display targets belongs to this map\\n"] + pub iNumDisplayTarget: ::std::os::raw::c_int, + #[doc = " The first target array index in the Target array\\n"] + pub iFirstDisplayTargetArrayIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits DisplayMap is currently using. It is the sum of all the bit definitions defined in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx."] + pub iDisplayMapMask: ::std::os::raw::c_int, + #[doc = "The bit mask identifies the display status. The detailed definition is in ADL_DISPLAY_DISPLAYMAP_MANNER_xxx."] + pub iDisplayMapValue: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about the display device possible map for one GPU\n\n This structure is used to store the display device possible map\n This information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPossibleMap { + #[doc = " The current PossibleMap index. Each PossibleMap is assigned an index"] + pub iIndex: ::std::os::raw::c_int, + #[doc = " The adapter index identifying the GPU for which to validate these Maps & Targets"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " Number of display Maps for this GPU to be validated"] + pub iNumDisplayMap: ::std::os::raw::c_int, + #[doc = " The display Maps list to validate"] + pub displayMap: *mut ADLDisplayMap, + #[doc = " the number of display Targets for these display Maps"] + pub iNumDisplayTarget: ::std::os::raw::c_int, + #[doc = " The display Targets list for these display Maps to be validated."] + pub displayTarget: *mut ADLDisplayTarget, +} +#[doc = "\n \\brief Structure containing information about display possible mapping.\n\n This structure is used to store the display possible mapping's controller index for the current display.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPossibleMapping { + #[doc = "< The display index. Each display is assigned an index."] + pub iDisplayIndex: ::std::os::raw::c_int, + #[doc = "< The controller index to which display is mapped."] + pub iDisplayControllerIndex: ::std::os::raw::c_int, + #[doc = "< The supported display manner."] + pub iDisplayMannerSupported: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing information about the validated display device possible map result.\n\n This structure is used to store the validated display device possible map result\n This information can be returned to the user.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPossibleMapResult { + #[doc = " The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1."] + pub iIndex: ::std::os::raw::c_int, + pub iPossibleMapResultMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the possible map result. The detail definition is defined in ADL_DISPLAY_POSSIBLEMAPRESULT_XXX."] + pub iPossibleMapResultValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS Grid information.\n\n This structure is used to store the display SLS Grid information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSGrid { + #[doc = " The Adapter index."] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The grid index."] + pub iSLSGridIndex: ::std::os::raw::c_int, + #[doc = " The grid row."] + pub iSLSGridRow: ::std::os::raw::c_int, + #[doc = " The grid column."] + pub iSLSGridColumn: ::std::os::raw::c_int, + #[doc = " The grid bit mask identifies the number of bits DisplayMap is currently using. Sum of all bits defined in ADL_DISPLAY_SLSGRID_ORIENTATION_XXX"] + pub iSLSGridMask: ::std::os::raw::c_int, + #[doc = " The grid bit value identifies the display status. Refer to ADL_DISPLAY_SLSGRID_ORIENTATION_XXX"] + pub iSLSGridValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS Map information.\n\n This structure is used to store the display SLS Map information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSMap { + #[doc = " The Adapter Index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1."] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " Indicate the current grid"] + pub grid: ADLSLSGrid, + #[doc = " OS surface index"] + pub iSurfaceMapIndex: ::std::os::raw::c_int, + #[doc = " Screen orientation. E.g., 0, 90, 180, 270"] + pub iOrientation: ::std::os::raw::c_int, + #[doc = " The number of display targets belongs to this map"] + pub iNumSLSTarget: ::std::os::raw::c_int, + #[doc = " The first target array index in the Target array"] + pub iFirstSLSTargetArrayIndex: ::std::os::raw::c_int, + #[doc = " The number of native modes belongs to this map"] + pub iNumNativeMode: ::std::os::raw::c_int, + #[doc = " The first native mode array index in the native mode array"] + pub iFirstNativeModeArrayIndex: ::std::os::raw::c_int, + #[doc = " The number of bezel modes belongs to this map"] + pub iNumBezelMode: ::std::os::raw::c_int, + #[doc = " The first bezel mode array index in the native mode array"] + pub iFirstBezelModeArrayIndex: ::std::os::raw::c_int, + #[doc = " The number of bezel offsets belongs to this map"] + pub iNumBezelOffset: ::std::os::raw::c_int, + #[doc = " The first bezel offset array index in the"] + pub iFirstBezelOffsetArrayIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits DisplayMap is currently using. Sum all the bit definitions defined in ADL_DISPLAY_SLSMAP_XXX."] + pub iSLSMapMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display map status. Refer to ADL_DISPLAY_SLSMAP_XXX"] + pub iSLSMapValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS Offset information.\n\n This structure is used to store the display SLS Offset information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSOffset { + #[doc = " The Adapter Index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1."] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " The Display ID."] + pub displayID: ADLDisplayID, + #[doc = " SLS Bezel Mode Index"] + pub iBezelModeIndex: ::std::os::raw::c_int, + #[doc = " SLS Bezel Offset X"] + pub iBezelOffsetX: ::std::os::raw::c_int, + #[doc = " SLS Bezel Offset Y"] + pub iBezelOffsetY: ::std::os::raw::c_int, + #[doc = " SLS Display Width"] + pub iDisplayWidth: ::std::os::raw::c_int, + #[doc = " SLS Display Height"] + pub iDisplayHeight: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits Offset is currently using."] + pub iBezelOffsetMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display status."] + pub iBezelffsetValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display SLS Mode information.\n\n This structure is used to store the display SLS Mode information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSMode { + #[doc = " The Adapter Index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The current display map index. It is the OS Desktop index. For example, OS Index 1 showing clone mode. The Display Map will be 1."] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " The mode index"] + pub iSLSModeIndex: ::std::os::raw::c_int, + #[doc = " The mode for this map."] + pub displayMode: ADLMode, + #[doc = " The bit mask identifies the number of bits Mode is currently using."] + pub iSLSNativeModeMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the display status."] + pub iSLSNativeModeValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the display Possible SLS Map information.\n\n This structure is used to store the display Possible SLS Map information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPossibleSLSMap { + #[doc = " The current display map index. It is the OS Desktop index.\n For example, OS Index 1 showing clone mode. The Display Map will be 1."] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " Number of display map to be validated."] + pub iNumSLSMap: ::std::os::raw::c_int, + #[doc = " The display map list for validation"] + pub lpSLSMap: *mut ADLSLSMap, + #[doc = " the number of display map config to be validated."] + pub iNumSLSTarget: ::std::os::raw::c_int, + #[doc = " The display target list for validation."] + pub lpDisplayTarget: *mut ADLDisplayTarget, +} +#[doc = "\n\\brief Structure containing information about the SLS targets.\n\n This structure is used to store the SLS targets information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSTarget { + #[doc = " the logic adapter index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The SLS map index"] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " The target ID"] + pub displayTarget: ADLDisplayTarget, + #[doc = " Target postion X in SLS grid"] + pub iSLSGridPositionX: ::std::os::raw::c_int, + #[doc = " Target postion Y in SLS grid"] + pub iSLSGridPositionY: ::std::os::raw::c_int, + #[doc = " The view size width, height and rotation angle per SLS Target"] + pub viewSize: ADLMode, + #[doc = " The bit mask identifies the bits in iSLSTargetValue are currently used"] + pub iSLSTargetMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies status info. It is for function extension purpose"] + pub iSLSTargetValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the Adapter offset stepping size.\n\n This structure is used to store the Adapter offset stepping size information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLBezelOffsetSteppingSize { + #[doc = " the logic adapter index"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The SLS map index"] + pub iSLSMapIndex: ::std::os::raw::c_int, + #[doc = " Bezel X stepping size offset"] + pub iBezelOffsetSteppingSizeX: ::std::os::raw::c_int, + #[doc = " Bezel Y stepping size offset"] + pub iBezelOffsetSteppingSizeY: ::std::os::raw::c_int, + #[doc = " Identifies the bits this structure is currently using. It will be the total OR of all the bit definitions."] + pub iBezelOffsetSteppingSizeMask: ::std::os::raw::c_int, + #[doc = " Bit mask identifies the display status."] + pub iBezelOffsetSteppingSizeValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the overlap offset info for all the displays for each SLS mode.\n\n This structure is used to store the no. of overlapped modes for each SLS Mode once user finishes the configuration from Overlap Widget\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSLSOverlappedMode { + #[doc = " the SLS mode for which the overlap is configured"] + pub SLSMode: ADLMode, + #[doc = " the number of target displays in SLS."] + pub iNumSLSTarget: ::std::os::raw::c_int, + #[doc = " the first target array index in the target array"] + pub iFirstTargetArrayIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about the overlap offset info for all the displays for each SLS mode.\n\n This structure is used to store the no. of overlapped modes for each SLS Mode once user finishes the configuration from Overlap Widget\n \\nosubgrouping\n"] +pub type ADLSLSTargetOverlap = ADLSLSOverlappedMode; +#[doc = "\n\\brief Structure containing information about driver supported PowerExpress Config Caps\n\n This structure is used to store the driver supported PowerExpress Config Caps\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPXConfigCaps { + #[doc = " The Persistent logical Adapter Index."] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the number of bits PowerExpress Config Caps is currently using. It is the sum of all the bit definitions defined in ADL_PX_CONFIGCAPS_XXXX /ref define_powerxpress_constants."] + pub iPXConfigCapMask: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the PowerExpress Config Caps value. The detailed definition is in ADL_PX_CONFIGCAPS_XXXX /ref define_powerxpress_constants."] + pub iPXConfigCapValue: ::std::os::raw::c_int, +} +impl ADLPxType { + pub const ADL_PX_NONE: ADLPxType = ADLPxType(0); +} +impl ADLPxType { + pub const ADL_SWITCHABLE_AMDAMD: ADLPxType = ADLPxType(1); +} +impl ADLPxType { + pub const ADL_HG_AMDAMD: ADLPxType = ADLPxType(2); +} +impl ADLPxType { + pub const ADL_SWITCHABLE_AMDOTHER: ADLPxType = ADLPxType(3); +} +impl ADLPxType { + pub const ADL_HG_AMDOTHER: ADLPxType = ADLPxType(4); +} +#[repr(transparent)] +#[doc = "\n\\brief Enum containing PX or HG type\n\n This enum is used to get PX or hG type\n\n \\nosubgrouping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPxType(pub ::std::os::raw::c_int); +#[doc = "\n\\brief Structure containing information about an application\n\n This structure is used to store basic information of an application\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLApplicationData { + #[doc = " Path Name"] + pub strPathName: [::std::os::raw::c_char; 256usize], + #[doc = " File Name"] + pub strFileName: [::std::os::raw::c_char; 256usize], + #[doc = " Creation timestamp"] + pub strTimeStamp: [::std::os::raw::c_char; 32usize], + #[doc = " Version"] + pub strVersion: [::std::os::raw::c_char; 32usize], +} +#[doc = "\n\\brief Structure containing information about an application\n\n This structure is used to store basic information of an application\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLApplicationDataX2 { + #[doc = " Path Name"] + pub strPathName: [u16; 256usize], + #[doc = " File Name"] + pub strFileName: [u16; 256usize], + #[doc = " Creation timestamp"] + pub strTimeStamp: [u16; 32usize], + #[doc = " Version"] + pub strVersion: [u16; 32usize], +} +#[doc = "\n\\brief Structure containing information about an application\n\n This structure is used to store basic information of an application including process id\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLApplicationDataX3 { + #[doc = " Path Name"] + pub strPathName: [u16; 256usize], + #[doc = " File Name"] + pub strFileName: [u16; 256usize], + #[doc = " Creation timestamp"] + pub strTimeStamp: [u16; 32usize], + #[doc = " Version"] + pub strVersion: [u16; 32usize], + pub iProcessId: ::std::os::raw::c_uint, +} +#[doc = "\n\\brief Structure containing information of a property of an application profile\n\n This structure is used to store property information of an application profile\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PropertyRecord { + #[doc = " Property Name"] + pub strName: [::std::os::raw::c_char; 64usize], + #[doc = " Property Type"] + pub eType: ADLProfilePropertyType, + #[doc = " Data Size in bytes"] + pub iDataSize: ::std::os::raw::c_int, + #[doc = " Property Value, can be any data type"] + pub uData: [::std::os::raw::c_uchar; 1usize], +} +#[doc = "\n\\brief Structure containing information about an application profile\n\n This structure is used to store information of an application profile\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLApplicationProfile { + #[doc = " Number of properties"] + pub iCount: ::std::os::raw::c_int, + #[doc = " Buffer to store all property records"] + pub record: [PropertyRecord; 1usize], +} +#[doc = "\n\\brief Structure containing information about an OD5 Power Control feature\n\n This structure is used to store information of an Power Control feature\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPowerControlInfo { + #[doc = " Minimum value."] + pub iMinValue: ::std::os::raw::c_int, + #[doc = " Maximum value."] + pub iMaxValue: ::std::os::raw::c_int, + #[doc = " The minimum change in between minValue and maxValue."] + pub iStepValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about an controller mode\n\n This structure is used to store information of an controller mode\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLControllerMode { + #[doc = " This falg indicates actions that will be applied by set viewport\n The value can be a combination of ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_POSITION,\n ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_PANLOCK and ADL_CONTROLLERMODE_CM_MODIFIER_VIEW_SIZE"] + pub iModifiers: ::std::os::raw::c_int, + #[doc = " Horizontal view starting position"] + pub iViewPositionCx: ::std::os::raw::c_int, + #[doc = " Vertical view starting position"] + pub iViewPositionCy: ::std::os::raw::c_int, + #[doc = " Horizontal left panlock position"] + pub iViewPanLockLeft: ::std::os::raw::c_int, + #[doc = " Horizontal right panlock position"] + pub iViewPanLockRight: ::std::os::raw::c_int, + #[doc = " Vertical top panlock position"] + pub iViewPanLockTop: ::std::os::raw::c_int, + #[doc = " Vertical bottom panlock position"] + pub iViewPanLockBottom: ::std::os::raw::c_int, + #[doc = " View resolution in pixels (width)"] + pub iViewResolutionCx: ::std::os::raw::c_int, + #[doc = " View resolution in pixels (hight)"] + pub iViewResolutionCy: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about a display\n\n This structure is used to store information about a display\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayIdentifier { + #[doc = " ADL display index"] + pub ulDisplayIndex: ::std::os::raw::c_long, + #[doc = " manufacturer ID of the display"] + pub ulManufacturerId: ::std::os::raw::c_long, + #[doc = " product ID of the display"] + pub ulProductId: ::std::os::raw::c_long, + #[doc = " serial number of the display"] + pub ulSerialNo: ::std::os::raw::c_long, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 clock range\n\n This structure is used to store information about Overdrive 6 clock range\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6ParameterRange { + #[doc = " The starting value of the clock range"] + pub iMin: ::std::os::raw::c_int, + #[doc = " The ending value of the clock range"] + pub iMax: ::std::os::raw::c_int, + #[doc = " The minimum increment between clock values"] + pub iStep: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 capabilities\n\n This structure is used to store information about Overdrive 6 capabilities\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6Capabilities { + #[doc = " Contains a bitmap of the OD6 capability flags. Possible values: \\ref ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION,\n \\ref ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION, \\ref ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR"] + pub iCapabilities: ::std::os::raw::c_int, + #[doc = " Contains a bitmap indicating the power states\n supported by OD6. Currently only the performance state\n is supported. Possible Values: \\ref ADL_OD6_SUPPORTEDSTATE_PERFORMANCE"] + pub iSupportedStates: ::std::os::raw::c_int, + #[doc = " Number of levels. OD6 will always use 2 levels, which describe\n the minimum to maximum clock ranges.\n The 1st level indicates the minimum clocks, and the 2nd level\n indicates the maximum clocks."] + pub iNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Contains the hard limits of the sclk range. Overdrive\n clocks cannot be set outside this range."] + pub sEngineClockRange: ADLOD6ParameterRange, + #[doc = " Contains the hard limits of the mclk range. Overdrive\n clocks cannot be set outside this range."] + pub sMemoryClockRange: ADLOD6ParameterRange, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 clock values.\n\n This structure is used to store information about Overdrive 6 clock values.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6PerformanceLevel { + #[doc = " Engine (core) clock."] + pub iEngineClock: ::std::os::raw::c_int, + #[doc = " Memory clock."] + pub iMemoryClock: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 clocks.\n\n This structure is used to store information about Overdrive 6 clocks. This is a\n variable-sized structure. iNumberOfPerformanceLevels indicate how many elements\n are contained in the aLevels array.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6StateInfo { + #[doc = " Number of levels. OD6 uses clock ranges instead of discrete performance levels.\n iNumberOfPerformanceLevels is always 2. The 1st level indicates the minimum clocks\n in the range. The 2nd level indicates the maximum clocks in the range."] + pub iNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, + #[doc = " Variable-sized array of levels.\n The number of elements in the array is specified by iNumberofPerformanceLevels."] + pub aLevels: [ADLOD6PerformanceLevel; 1usize], +} +#[doc = "\n\\brief Structure containing information about current Overdrive 6 performance status.\n\n This structure is used to store information about current Overdrive 6 performance status.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6CurrentStatus { + #[doc = " Current engine clock in 10 KHz."] + pub iEngineClock: ::std::os::raw::c_int, + #[doc = " Current memory clock in 10 KHz."] + pub iMemoryClock: ::std::os::raw::c_int, + #[doc = " Current GPU activity in percent. This\n indicates how \"busy\" the GPU is."] + pub iActivityPercent: ::std::os::raw::c_int, + #[doc = " Not used. Reserved for future use."] + pub iCurrentPerformanceLevel: ::std::os::raw::c_int, + #[doc = " Current PCI-E bus speed"] + pub iCurrentBusSpeed: ::std::os::raw::c_int, + #[doc = " Current PCI-E bus # of lanes"] + pub iCurrentBusLanes: ::std::os::raw::c_int, + #[doc = " Maximum possible PCI-E bus # of lanes"] + pub iMaximumBusLanes: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 thermal contoller capabilities\n\n This structure is used to store information about Overdrive 6 thermal controller capabilities\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6ThermalControllerCaps { + #[doc = " Contains a bitmap of thermal controller capability flags. Possible values: \\ref ADL_OD6_TCCAPS_THERMAL_CONTROLLER, \\ref ADL_OD6_TCCAPS_FANSPEED_CONTROL,\n \\ref ADL_OD6_TCCAPS_FANSPEED_PERCENT_READ, \\ref ADL_OD6_TCCAPS_FANSPEED_PERCENT_WRITE, \\ref ADL_OD6_TCCAPS_FANSPEED_RPM_READ, \\ref ADL_OD6_TCCAPS_FANSPEED_RPM_WRITE"] + pub iCapabilities: ::std::os::raw::c_int, + #[doc = " Minimum fan speed expressed as a percentage"] + pub iFanMinPercent: ::std::os::raw::c_int, + #[doc = " Maximum fan speed expressed as a percentage"] + pub iFanMaxPercent: ::std::os::raw::c_int, + #[doc = " Minimum fan speed expressed in revolutions-per-minute"] + pub iFanMinRPM: ::std::os::raw::c_int, + #[doc = " Maximum fan speed expressed in revolutions-per-minute"] + pub iFanMaxRPM: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 fan speed information\n\n This structure is used to store information about Overdrive 6 fan speed information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6FanSpeedInfo { + #[doc = " Contains a bitmap of the valid fan speed type flags. Possible values: \\ref ADL_OD6_FANSPEED_TYPE_PERCENT, \\ref ADL_OD6_FANSPEED_TYPE_RPM, \\ref ADL_OD6_FANSPEED_USER_DEFINED"] + pub iSpeedType: ::std::os::raw::c_int, + #[doc = " Contains current fan speed in percent (if valid flag exists in iSpeedType)"] + pub iFanSpeedPercent: ::std::os::raw::c_int, + #[doc = " Contains current fan speed in RPM (if valid flag exists in iSpeedType)"] + pub iFanSpeedRPM: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 fan speed value\n\n This structure is used to store information about Overdrive 6 fan speed value\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6FanSpeedValue { + #[doc = " Indicates the units of the fan speed. Possible values: \\ref ADL_OD6_FANSPEED_TYPE_PERCENT, \\ref ADL_OD6_FANSPEED_TYPE_RPM"] + pub iSpeedType: ::std::os::raw::c_int, + #[doc = " Fan speed value (units as indicated above)"] + pub iFanSpeed: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 PowerControl settings.\n\n This structure is used to store information about Overdrive 6 PowerControl settings.\n PowerControl is the feature which allows the performance characteristics of the GPU\n to be adjusted by changing the PowerTune power limits.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6PowerControlInfo { + #[doc = " The minimum PowerControl adjustment value"] + pub iMinValue: ::std::os::raw::c_int, + #[doc = " The maximum PowerControl adjustment value"] + pub iMaxValue: ::std::os::raw::c_int, + #[doc = " The minimum difference between PowerControl adjustment values"] + pub iStepValue: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 PowerControl settings.\n\n This structure is used to store information about Overdrive 6 PowerControl settings.\n PowerControl is the feature which allows the performance characteristics of the GPU\n to be adjusted by changing the PowerTune power limits.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6VoltageControlInfo { + #[doc = " The minimum VoltageControl adjustment value"] + pub iMinValue: ::std::os::raw::c_int, + #[doc = " The maximum VoltageControl adjustment value"] + pub iMaxValue: ::std::os::raw::c_int, + #[doc = " The minimum difference between VoltageControl adjustment values"] + pub iStepValue: ::std::os::raw::c_int, + #[doc = " Value for future extension"] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Mask for future extension"] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing ECC statistics namely SEC counts and DED counts\n Single error count - count of errors that can be corrected\n Doubt Error Detect - count of errors that cannot be corrected\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLECCData { + pub iSec: ::std::os::raw::c_int, + pub iDed: ::std::os::raw::c_int, +} +#[doc = " \\brief Handle to ADL client context.\n\n ADL clients obtain context handle from initial call to \\ref ADL2_Main_Control_Create.\n Clients have to pass the handle to each subsequent ADL call and finally destroy\n the context with call to \\ref ADL2_Main_Control_Destroy\n \\nosubgrouping"] +pub type ADL_CONTEXT_HANDLE = *mut ::std::os::raw::c_void; +#[doc = " \\brief Handle to ADL Frame Monitor Token.\n\n Frame Monitor clients obtain handle from initial call to \\ref ADL2_Adapter_FrameMetrics_FrameDuration_Enable\n Clients have to pass the handle to each subsequent ADL call to \\ref ADL2_Adapter_FrameMetrics_FrameDuration_Get\n and finally destroy the token with call to \\ref ADL2_Adapter_FrameMetrics_FrameDuration_Disable\n \\nosubgrouping"] +pub type ADL_FRAME_DURATION_HANDLE = *mut ::std::os::raw::c_void; +#[doc = "\n\\brief Structure containing the display mode definition used per controller.\n\n This structure is used to store the display mode definition used per controller.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayModeX2 { + #[doc = " Horizontal resolution (in pixels)."] + pub iWidth: ::std::os::raw::c_int, + #[doc = " Vertical resolution (in lines)."] + pub iHeight: ::std::os::raw::c_int, + #[doc = " Interlaced/Progressive. The value will be set for Interlaced as ADL_DL_TIMINGFLAG_INTERLACED. If not set it is progressive. Refer define_detailed_timing_flags."] + pub iScanType: ::std::os::raw::c_int, + #[doc = " Refresh rate."] + pub iRefreshRate: ::std::os::raw::c_int, + #[doc = " Timing Standard. Refer define_modetiming_standard."] + pub iTimingStandard: ::std::os::raw::c_int, +} +impl ADLAppProcessState { + pub const APP_PROC_INVALID: ADLAppProcessState = ADLAppProcessState(0); +} +impl ADLAppProcessState { + pub const APP_PROC_PREMPTION: ADLAppProcessState = ADLAppProcessState(1); +} +impl ADLAppProcessState { + pub const APP_PROC_CREATION: ADLAppProcessState = ADLAppProcessState(2); +} +impl ADLAppProcessState { + pub const APP_PROC_READ: ADLAppProcessState = ADLAppProcessState(3); +} +impl ADLAppProcessState { + pub const APP_PROC_WAIT: ADLAppProcessState = ADLAppProcessState(4); +} +impl ADLAppProcessState { + pub const APP_PROC_RUNNING: ADLAppProcessState = ADLAppProcessState(5); +} +impl ADLAppProcessState { + pub const APP_PROC_TERMINATE: ADLAppProcessState = ADLAppProcessState(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLAppProcessState(pub ::std::os::raw::c_int); +impl ADLAppInterceptionListType { + pub const ADL_INVALID_FORMAT: ADLAppInterceptionListType = ADLAppInterceptionListType(0); +} +impl ADLAppInterceptionListType { + pub const ADL_IMAGEFILEFORMAT: ADLAppInterceptionListType = ADLAppInterceptionListType(1); +} +impl ADLAppInterceptionListType { + pub const ADL_ENVVAR: ADLAppInterceptionListType = ADLAppInterceptionListType(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLAppInterceptionListType(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAppInterceptionInfo { + pub AppName: [u16; 256usize], + pub ProcessId: ::std::os::raw::c_uint, + pub AppFormat: ADLAppInterceptionListType, + pub AppState: ADLAppProcessState, +} +impl ADL_AP_DATABASE { + pub const ADL_AP_DATABASE__SYSTEM: ADL_AP_DATABASE = ADL_AP_DATABASE(0); +} +impl ADL_AP_DATABASE { + pub const ADL_AP_DATABASE__USER: ADL_AP_DATABASE = ADL_AP_DATABASE(1); +} +impl ADL_AP_DATABASE { + pub const ADL_AP_DATABASE__OEM: ADL_AP_DATABASE = ADL_AP_DATABASE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_AP_DATABASE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAppInterceptionInfoX2 { + pub AppName: [u16; 256usize], + pub ProcessId: ::std::os::raw::c_uint, + pub WaitForResumeNeeded: ::std::os::raw::c_uint, + pub CommandLine: [u16; 256usize], + pub AppFormat: ADLAppInterceptionListType, + pub AppState: ADLAppProcessState, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAppInterceptionInfoX3 { + pub AppName: [u16; 256usize], + pub ProcessId: ::std::os::raw::c_uint, + pub WaitForResumeNeeded: ::std::os::raw::c_uint, + pub RayTracingStatus: ::std::os::raw::c_uint, + pub CommandLine: [u16; 256usize], + pub AppFormat: ADLAppInterceptionListType, + pub AppState: ADLAppProcessState, +} +#[doc = "\n\\brief Structure containing information info for a property record in a profile\n\n This structure is used to store info for a property record in a profile\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPropertyRecordCreate { + #[doc = " Name of the property"] + pub strPropertyName: *mut u16, + #[doc = " Data type of the property"] + pub eType: ADLProfilePropertyType, + pub strPropertyValue: *mut u16, +} +#[doc = "\n\\brief Structure containing information info for an application record\n\n This structure is used to store info for an application record\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLApplicationRecord { + #[doc = " Title of the application"] + pub strTitle: *mut u16, + #[doc = " File path of the application"] + pub strPathName: *mut u16, + #[doc = " File name of the application"] + pub strFileName: *mut u16, + #[doc = " File versin the application"] + pub strVersion: *mut u16, + #[doc = " Nostes on the application"] + pub strNotes: *mut u16, + #[doc = " Driver area which the application uses"] + pub strArea: *mut u16, + #[doc = " Name of profile assigned to the application"] + pub strProfileName: *mut u16, + pub recordSource: ADL_AP_DATABASE, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 extension capabilities\n\n This structure is used to store information about Overdrive 6 extension capabilities\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6CapabilitiesEx { + #[doc = " Contains a bitmap of the OD6 extension capability flags. Possible values: \\ref ADL_OD6_CAPABILITY_SCLK_CUSTOMIZATION,\n \\ref ADL_OD6_CAPABILITY_MCLK_CUSTOMIZATION, \\ref ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR,\n \\ref ADL_OD6_CAPABILITY_POWER_CONTROL, \\ref ADL_OD6_CAPABILITY_VOLTAGE_CONTROL, \\ref ADL_OD6_CAPABILITY_PERCENT_ADJUSTMENT,\n \\ref ADL_OD6_CAPABILITY_THERMAL_LIMIT_UNLOCK"] + pub iCapabilities: ::std::os::raw::c_int, + #[doc = " The Power states that support clock and power customization. Only performance state is currently supported.\n Possible Values: \\ref ADL_OD6_SUPPORTEDSTATE_PERFORMANCE"] + pub iSupportedStates: ::std::os::raw::c_int, + #[doc = " Returns the hard limits of the SCLK overdrive adjustment range. Overdrive clocks should not be adjusted outside of this range. The values are specified as +/- percentages."] + pub sEngineClockPercent: ADLOD6ParameterRange, + #[doc = " Returns the hard limits of the MCLK overdrive adjustment range. Overdrive clocks should not be adjusted outside of this range. The values are specified as +/- percentages."] + pub sMemoryClockPercent: ADLOD6ParameterRange, + #[doc = " Returns the hard limits of the Power Limit adjustment range. Power limit should not be adjusted outside this range. The values are specified as +/- percentages."] + pub sPowerControlPercent: ADLOD6ParameterRange, + #[doc = " Reserved for future expansion of the structure."] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Reserved for future expansion of the structure."] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 extension state information\n\n This structure is used to store information about Overdrive 6 extension state information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6StateEx { + #[doc = " The current engine clock adjustment value, specified as a +/- percent."] + pub iEngineClockPercent: ::std::os::raw::c_int, + #[doc = " The current memory clock adjustment value, specified as a +/- percent."] + pub iMemoryClockPercent: ::std::os::raw::c_int, + #[doc = " The current power control adjustment value, specified as a +/- percent."] + pub iPowerControlPercent: ::std::os::raw::c_int, + #[doc = " Reserved for future expansion of the structure."] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Reserved for future expansion of the structure."] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive 6 extension recommended maximum clock adjustment values\n\n This structure is used to store information about Overdrive 6 extension recommended maximum clock adjustment values\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD6MaxClockAdjust { + #[doc = " The recommended maximum engine clock adjustment in percent, for the specified power limit value."] + pub iEngineClockMax: ::std::os::raw::c_int, + #[doc = " The recommended maximum memory clock adjustment in percent, for the specified power limit value.\n Currently the memory is independent of the Power Limit setting, so iMemoryClockMax will always return the maximum\n possible adjustment value. This field is here for future enhancement in case we add a dependency between Memory Clock\n adjustment and Power Limit setting."] + pub iMemoryClockMax: ::std::os::raw::c_int, + #[doc = " Reserved for future expansion of the structure."] + pub iExtValue: ::std::os::raw::c_int, + #[doc = " Reserved for future expansion of the structure."] + pub iExtMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing the Connector information\n\n this structure is used to get the connector information like length, positions & etc.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLConnectorInfo { + #[doc = "index of the connector(0-based)"] + pub iConnectorIndex: ::std::os::raw::c_int, + #[doc = "used for disply identification/ordering"] + pub iConnectorId: ::std::os::raw::c_int, + #[doc = "index of the slot, 0-based index."] + pub iSlotIndex: ::std::os::raw::c_int, + #[doc = "Type of the connector. \\ref define_connector_types"] + pub iType: ::std::os::raw::c_int, + #[doc = "Position of the connector(in millimeters), from the right side of the slot."] + pub iOffset: ::std::os::raw::c_int, + #[doc = "Length of the connector(in millimeters)."] + pub iLength: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing the slot information\n\n this structure is used to get the slot information like length of the slot, no of connectors on the slot & etc.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLBracketSlotInfo { + #[doc = "index of the slot, 0-based index."] + pub iSlotIndex: ::std::os::raw::c_int, + #[doc = "length of the slot(in millimeters)."] + pub iLength: ::std::os::raw::c_int, + #[doc = "width of the slot(in millimeters)."] + pub iWidth: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing MST branch information\n\n this structure is used to store the MST branch information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMSTRad { + #[doc = "depth of the link."] + pub iLinkNumber: ::std::os::raw::c_int, + #[doc = " Relative address, address scheme starts from source side"] + pub rad: [::std::os::raw::c_char; 15usize], +} +#[doc = "\n\\brief Structure containing port information\n\n this structure is used to get the display or MST branch information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDevicePort { + #[doc = "index of the connector."] + pub iConnectorIndex: ::std::os::raw::c_int, + #[doc = "Relative MST address. If MST RAD contains 0 it means DP or Root of the MST topology. For non DP connectors MST RAD is ignored."] + pub aMSTRad: ADLMSTRad, +} +#[doc = "\n\\brief Structure containing supported connection types and properties\n\n this structure is used to get the supported connection types and supported properties of given connector\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSupportedConnections { + #[doc = "Bit vector of supported connections. Bitmask is defined in constants section. \\ref define_connection_types"] + pub iSupportedConnections: ::std::os::raw::c_int, + #[doc = "Array of bitvectors. Each bit vector represents supported properties for one connection type. Index of this array is connection type (bit number in mask)."] + pub iSupportedProperties: [::std::os::raw::c_int; 32usize], +} +#[doc = "\n\\brief Structure containing connection state of the connector\n\n this structure is used to get the current Emulation status and mode of the given connector\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLConnectionState { + #[doc = "The value is bit vector. Each bit represents status. See masks constants for details. \\ref define_emulation_status"] + pub iEmulationStatus: ::std::os::raw::c_int, + #[doc = "It contains information about current emulation mode. See constants for details. \\ref define_emulation_mode"] + pub iEmulationMode: ::std::os::raw::c_int, + #[doc = "If connection is active it will contain display id, otherwise CWDDEDI_INVALID_DISPLAY_INDEX"] + pub iDisplayIndex: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing connection properties information\n\n this structure is used to retrieve the properties of connection type\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLConnectionProperties { + pub iValidProperties: ::std::os::raw::c_int, + pub iBitrate: ::std::os::raw::c_int, + pub iNumberOfLanes: ::std::os::raw::c_int, + pub iColorDepth: ::std::os::raw::c_int, + pub iStereo3DCaps: ::std::os::raw::c_int, + #[doc = "Output Bandwidth. Could be used for MST branch, DP or DP Active dongle. \\ref define_linkrate_constants"] + pub iOutputBandwidth: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing connection information\n\n this structure is used to retrieve the data from driver which includes\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLConnectionData { + #[doc = "Connection type. based on the connection type either iNumberofPorts or IDataSize,EDIDdata is valid, \\ref define_connection_types"] + pub iConnectionType: ::std::os::raw::c_int, + #[doc = "Specifies the connection properties."] + pub aConnectionProperties: ADLConnectionProperties, + #[doc = "Number of ports"] + pub iNumberofPorts: ::std::os::raw::c_int, + #[doc = "Number of Active Connections"] + pub iActiveConnections: ::std::os::raw::c_int, + #[doc = "actual size of EDID data block size."] + pub iDataSize: ::std::os::raw::c_int, + #[doc = "EDID Data"] + pub EdidData: [::std::os::raw::c_char; 1024usize], +} +#[doc = "\n\\brief Structure containing information about an controller mode including Number of Connectors\n\n This structure is used to store information of an controller mode\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLAdapterCapsX2 { + #[doc = " AdapterID for this adapter"] + pub iAdapterID: ::std::os::raw::c_int, + #[doc = " Number of controllers for this adapter"] + pub iNumControllers: ::std::os::raw::c_int, + #[doc = " Number of displays for this adapter"] + pub iNumDisplays: ::std::os::raw::c_int, + #[doc = " Number of overlays for this adapter"] + pub iNumOverlays: ::std::os::raw::c_int, + #[doc = " Number of GLSyncConnectors"] + pub iNumOfGLSyncConnectors: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the adapter caps"] + pub iCapsMask: ::std::os::raw::c_int, + #[doc = " The bit identifies the adapter caps \\ref define_adapter_caps"] + pub iCapsValue: ::std::os::raw::c_int, + #[doc = " Number of Connectors for this adapter"] + pub iNumConnectors: ::std::os::raw::c_int, +} +impl ADL_ERROR_RECORD_SEVERITY { + pub const ADL_GLOBALLY_UNCORRECTED: ADL_ERROR_RECORD_SEVERITY = ADL_ERROR_RECORD_SEVERITY(1); +} +impl ADL_ERROR_RECORD_SEVERITY { + pub const ADL_LOCALLY_UNCORRECTED: ADL_ERROR_RECORD_SEVERITY = ADL_ERROR_RECORD_SEVERITY(2); +} +impl ADL_ERROR_RECORD_SEVERITY { + pub const ADL_DEFFERRED: ADL_ERROR_RECORD_SEVERITY = ADL_ERROR_RECORD_SEVERITY(3); +} +impl ADL_ERROR_RECORD_SEVERITY { + pub const ADL_CORRECTED: ADL_ERROR_RECORD_SEVERITY = ADL_ERROR_RECORD_SEVERITY(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_ERROR_RECORD_SEVERITY(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub union _ADL_ECC_EDC_FLAG { + pub bits: _ADL_ECC_EDC_FLAG__bindgen_ty_1, + pub u32All: ::std::os::raw::c_uint, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _ADL_ECC_EDC_FLAG__bindgen_ty_1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _ADL_ECC_EDC_FLAG__bindgen_ty_1 { + #[inline] + pub fn isEccAccessing(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEccAccessing(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEccAccessing: ::std::os::raw::c_uint, + reserved: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEccAccessing: u32 = unsafe { ::std::mem::transmute(isEccAccessing) }; + isEccAccessing as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type ADL_ECC_EDC_FLAG = _ADL_ECC_EDC_FLAG; +#[doc = "\n\\brief Structure containing information about EDC Error Record\n\n This structure is used to store EDC Error Record\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLErrorRecord { + pub Severity: ADL_ERROR_RECORD_SEVERITY, + pub countValid: ::std::os::raw::c_int, + pub count: ::std::os::raw::c_uint, + pub locationValid: ::std::os::raw::c_int, + pub CU: ::std::os::raw::c_uint, + pub StructureName: [::std::os::raw::c_char; 32usize], + pub tiestamp: [::std::os::raw::c_char; 32usize], + pub padding: [::std::os::raw::c_uint; 3usize], +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_SQCIS: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(1); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_SQCDS: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(2); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_SGPR: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(3); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_VGPR: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(4); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_LDS: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(5); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_GDS: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(6); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_TCL1: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(7); +} +impl ADL_EDC_BLOCK_ID { + pub const ADL_EDC_BLOCK_ID_TCL2: ADL_EDC_BLOCK_ID = ADL_EDC_BLOCK_ID(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_EDC_BLOCK_ID(pub ::std::os::raw::c_int); +impl ADL_ERROR_INJECTION_MODE { + pub const ADL_ERROR_INJECTION_MODE_SINGLE: ADL_ERROR_INJECTION_MODE = + ADL_ERROR_INJECTION_MODE(1); +} +impl ADL_ERROR_INJECTION_MODE { + pub const ADL_ERROR_INJECTION_MODE_MULTIPLE: ADL_ERROR_INJECTION_MODE = + ADL_ERROR_INJECTION_MODE(2); +} +impl ADL_ERROR_INJECTION_MODE { + pub const ADL_ERROR_INJECTION_MODE_ADDRESS: ADL_ERROR_INJECTION_MODE = + ADL_ERROR_INJECTION_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADL_ERROR_INJECTION_MODE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub union _ADL_ERROR_PATTERN { + pub bits: _ADL_ERROR_PATTERN__bindgen_ty_1, + pub u64Value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _ADL_ERROR_PATTERN__bindgen_ty_1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 12usize]>, +} +impl _ADL_ERROR_PATTERN__bindgen_ty_1 { + #[inline] + pub fn EccInjVector(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) } + } + #[inline] + pub fn set_EccInjVector(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) + } + } + #[inline] + pub fn EccInjEn(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 9u8) as u32) } + } + #[inline] + pub fn set_EccInjEn(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 9u8, val as u64) + } + } + #[inline] + pub fn EccBeatEn(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 4u8) as u32) } + } + #[inline] + pub fn set_EccBeatEn(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 4u8, val as u64) + } + } + #[inline] + pub fn EccChEn(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 4u8) as u32) } + } + #[inline] + pub fn set_EccChEn(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 4u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(64usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + EccInjVector: ::std::os::raw::c_ulong, + EccInjEn: ::std::os::raw::c_ulong, + EccBeatEn: ::std::os::raw::c_ulong, + EccChEn: ::std::os::raw::c_ulong, + reserved: ::std::os::raw::c_ulong, + ) -> __BindgenBitfieldUnit<[u8; 12usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 12usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 16u8, { + let EccInjVector: u32 = unsafe { ::std::mem::transmute(EccInjVector) }; + EccInjVector as u64 + }); + __bindgen_bitfield_unit.set(16usize, 9u8, { + let EccInjEn: u32 = unsafe { ::std::mem::transmute(EccInjEn) }; + EccInjEn as u64 + }); + __bindgen_bitfield_unit.set(25usize, 4u8, { + let EccBeatEn: u32 = unsafe { ::std::mem::transmute(EccBeatEn) }; + EccBeatEn as u64 + }); + __bindgen_bitfield_unit.set(32usize, 4u8, { + let EccChEn: u32 = unsafe { ::std::mem::transmute(EccChEn) }; + EccChEn as u64 + }); + __bindgen_bitfield_unit.set(64usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type ADL_ERROR_PATTERN = _ADL_ERROR_PATTERN; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_ERROR_INJECTION_DATA { + pub errorAddress: ::std::os::raw::c_ulonglong, + pub errorPattern: ADL_ERROR_PATTERN, +} +#[doc = "\n\\brief Structure containing information about EDC Error Injection\n\n This structure is used to store EDC Error Injection\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLErrorInjection { + pub blockId: ADL_EDC_BLOCK_ID, + pub errorInjectionMode: ADL_ERROR_INJECTION_MODE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLErrorInjectionX2 { + pub blockId: ADL_EDC_BLOCK_ID, + pub errorInjectionMode: ADL_ERROR_INJECTION_MODE, + pub errorInjectionData: ADL_ERROR_INJECTION_DATA, +} +#[doc = "\n\\brief Structure containing per display FreeSync capability information.\n\n This structure is used to store the FreeSync capability of both the display and\n the GPU the display is connected to.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFreeSyncCap { + #[doc = " FreeSync capability flags. \\ref define_freesync_caps"] + pub iCaps: ::std::os::raw::c_int, + #[doc = " Reports minimum FreeSync refresh rate supported by the display in micro hertz"] + pub iMinRefreshRateInMicroHz: ::std::os::raw::c_int, + #[doc = " Reports maximum FreeSync refresh rate supported by the display in micro hertz"] + pub iMaxRefreshRateInMicroHz: ::std::os::raw::c_int, + #[doc = " Index of FreeSync Label to use: ADL_FREESYNC_LABEL_*"] + pub ucLabelIndex: ::std::os::raw::c_uchar, + #[doc = " Reserved"] + pub cReserved: [::std::os::raw::c_char; 3usize], + pub iReserved: [::std::os::raw::c_int; 4usize], +} +#[doc = "\n\\brief Structure containing per display Display Connectivty Experience Settings\n\n This structure is used to store the Display Connectivity Experience settings of a\n display\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDceSettings { + pub type_: DceSettingsType, + pub Settings: ADLDceSettings__bindgen_ty_1, + pub iReserved: [::std::os::raw::c_int; 15usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ADLDceSettings__bindgen_ty_1 { + pub HdmiLq: ADLDceSettings__bindgen_ty_1__bindgen_ty_1, + pub DpLink: ADLDceSettings__bindgen_ty_1__bindgen_ty_2, + pub Protection: ADLDceSettings__bindgen_ty_1__bindgen_ty_3, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDceSettings__bindgen_ty_1__bindgen_ty_1 { + pub qualityDetectionEnabled: bool, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDceSettings__bindgen_ty_1__bindgen_ty_2 { + pub linkRate: DpLinkRate, + pub numberOfActiveLanes: ::std::os::raw::c_uint, + pub numberofTotalLanes: ::std::os::raw::c_uint, + pub relativePreEmphasis: ::std::os::raw::c_int, + pub relativeVoltageSwing: ::std::os::raw::c_int, + pub persistFlag: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDceSettings__bindgen_ty_1__bindgen_ty_3 { + pub linkProtectionEnabled: bool, +} +#[doc = "\n\\brief Structure containing information about Graphic Core\n\n This structure is used to get Graphic Core Info\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGraphicCoreInfo { + #[doc = " indicate the graphic core generation"] + pub iGCGen: ::std::os::raw::c_int, + pub __bindgen_anon_1: ADLGraphicCoreInfo__bindgen_ty_1, + pub __bindgen_anon_2: ADLGraphicCoreInfo__bindgen_ty_2, + #[doc = " Total number of SIMDs. Valid for Pre GCN (iGCGen == Pre-GCN)"] + pub iNumSIMDs: ::std::os::raw::c_int, + #[doc = " Total number of ROPs. Valid for both GCN and Pre GCN"] + pub iNumROPs: ::std::os::raw::c_int, + #[doc = " reserved for future use"] + pub iReserved: [::std::os::raw::c_int; 11usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ADLGraphicCoreInfo__bindgen_ty_1 { + #[doc = " Total number of CUs. Valid for GCN (iGCGen == GCN)"] + pub iNumCUs: ::std::os::raw::c_int, + #[doc = " Total number of WGPs. Valid for RDNA (iGCGen == RDNA)"] + pub iNumWGPs: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ADLGraphicCoreInfo__bindgen_ty_2 { + #[doc = " Number of processing elements per CU. Valid for GCN (iGCGen == GCN)"] + pub iNumPEsPerCU: ::std::os::raw::c_int, + #[doc = " Number of processing elements per WGP. Valid for RDNA (iGCGen == RDNA)"] + pub iNumPEsPerWGP: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive N clock range\n\n This structure is used to store information about Overdrive N clock range\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNParameterRange { + #[doc = " The starting value of the clock range"] + pub iMode: ::std::os::raw::c_int, + #[doc = " The starting value of the clock range"] + pub iMin: ::std::os::raw::c_int, + #[doc = " The ending value of the clock range"] + pub iMax: ::std::os::raw::c_int, + #[doc = " The minimum increment between clock values"] + pub iStep: ::std::os::raw::c_int, + #[doc = " The default clock values"] + pub iDefault: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive N capabilities\n\n This structure is used to store information about Overdrive N capabilities\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNCapabilities { + #[doc = " Number of levels which describe the minimum to maximum clock ranges.\n The 1st level indicates the minimum clocks, and the 2nd level\n indicates the maximum clocks."] + pub iMaximumNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Contains the hard limits of the sclk range. Overdrive\n clocks cannot be set outside this range."] + pub sEngineClockRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the mclk range. Overdrive\n clocks cannot be set outside this range."] + pub sMemoryClockRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the vddc range. Overdrive\n clocks cannot be set outside this range."] + pub svddcRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the power range. Overdrive\n clocks cannot be set outside this range."] + pub power: ADLODNParameterRange, + #[doc = " Contains the hard limits of the power range. Overdrive\n clocks cannot be set outside this range."] + pub powerTuneTemperature: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Temperature range. Overdrive\n clocks cannot be set outside this range."] + pub fanTemperature: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Fan range. Overdrive\n clocks cannot be set outside this range."] + pub fanSpeed: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Fan range. Overdrive\n clocks cannot be set outside this range."] + pub minimumPerformanceClock: ADLODNParameterRange, +} +#[doc = "\n\\brief Structure containing information about Overdrive N capabilities\n\n This structure is used to store information about Overdrive N capabilities\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNCapabilitiesX2 { + #[doc = " Number of levels which describe the minimum to maximum clock ranges.\n The 1st level indicates the minimum clocks, and the 2nd level\n indicates the maximum clocks."] + pub iMaximumNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " bit vector, which tells what are the features are supported.\n \\ref: ADLODNFEATURECONTROL"] + pub iFlags: ::std::os::raw::c_int, + #[doc = " Contains the hard limits of the sclk range. Overdrive\n clocks cannot be set outside this range."] + pub sEngineClockRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the mclk range. Overdrive\n clocks cannot be set outside this range."] + pub sMemoryClockRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the vddc range. Overdrive\n clocks cannot be set outside this range."] + pub svddcRange: ADLODNParameterRange, + #[doc = " Contains the hard limits of the power range. Overdrive\n clocks cannot be set outside this range."] + pub power: ADLODNParameterRange, + #[doc = " Contains the hard limits of the power range. Overdrive\n clocks cannot be set outside this range."] + pub powerTuneTemperature: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Temperature range. Overdrive\n clocks cannot be set outside this range."] + pub fanTemperature: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Fan range. Overdrive\n clocks cannot be set outside this range."] + pub fanSpeed: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Fan range. Overdrive\n clocks cannot be set outside this range."] + pub minimumPerformanceClock: ADLODNParameterRange, + #[doc = " Contains the hard limits of the throttleNotification"] + pub throttleNotificaion: ADLODNParameterRange, + #[doc = " Contains the hard limits of the Auto Systemclock"] + pub autoSystemClock: ADLODNParameterRange, +} +#[doc = "\n\\brief Structure containing information about Overdrive level.\n\n This structure is used to store information about Overdrive level.\n This structure is used by ADLODPerformanceLevels.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPerformanceLevel { + #[doc = " clock."] + pub iClock: ::std::os::raw::c_int, + #[doc = " VDCC."] + pub iVddc: ::std::os::raw::c_int, + #[doc = " enabled"] + pub iEnabled: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive N performance levels.\n\n This structure is used to store information about Overdrive performance levels.\n This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPerformanceLevels { + pub iSize: ::std::os::raw::c_int, + pub iMode: ::std::os::raw::c_int, + #[doc = " Must be set to sizeof( \\ref ADLODPerformanceLevels ) + sizeof( \\ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1)"] + pub iNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements."] + pub aLevels: [ADLODNPerformanceLevel; 1usize], +} +#[doc = "\n\\brief Structure containing information about Overdrive N Fan Speed.\n\n This structure is used to store information about Overdrive Fan control .\n This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNFanControl { + pub iMode: ::std::os::raw::c_int, + pub iFanControlMode: ::std::os::raw::c_int, + pub iCurrentFanSpeedMode: ::std::os::raw::c_int, + pub iCurrentFanSpeed: ::std::os::raw::c_int, + pub iTargetFanSpeed: ::std::os::raw::c_int, + pub iTargetTemperature: ::std::os::raw::c_int, + pub iMinPerformanceClock: ::std::os::raw::c_int, + pub iMinFanLimit: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive N power limit.\n\n This structure is used to store information about Overdrive power limit.\n This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPowerLimitSetting { + pub iMode: ::std::os::raw::c_int, + pub iTDPLimit: ::std::os::raw::c_int, + pub iMaxOperatingTemperature: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPerformanceStatus { + pub iCoreClock: ::std::os::raw::c_int, + pub iMemoryClock: ::std::os::raw::c_int, + pub iDCEFClock: ::std::os::raw::c_int, + pub iGFXClock: ::std::os::raw::c_int, + pub iUVDClock: ::std::os::raw::c_int, + pub iVCEClock: ::std::os::raw::c_int, + pub iGPUActivityPercent: ::std::os::raw::c_int, + pub iCurrentCorePerformanceLevel: ::std::os::raw::c_int, + pub iCurrentMemoryPerformanceLevel: ::std::os::raw::c_int, + pub iCurrentDCEFPerformanceLevel: ::std::os::raw::c_int, + pub iCurrentGFXPerformanceLevel: ::std::os::raw::c_int, + pub iUVDPerformanceLevel: ::std::os::raw::c_int, + pub iVCEPerformanceLevel: ::std::os::raw::c_int, + pub iCurrentBusSpeed: ::std::os::raw::c_int, + pub iCurrentBusLanes: ::std::os::raw::c_int, + pub iMaximumBusLanes: ::std::os::raw::c_int, + pub iVDDC: ::std::os::raw::c_int, + pub iVDDCI: ::std::os::raw::c_int, +} +#[doc = "\\brief Structure containing information about Overdrive level.\n\n This structure is used to store information about Overdrive level.\n This structure is used by ADLODPerformanceLevels.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPerformanceLevelX2 { + #[doc = " clock."] + pub iClock: ::std::os::raw::c_int, + #[doc = " VDCC."] + pub iVddc: ::std::os::raw::c_int, + #[doc = " enabled"] + pub iEnabled: ::std::os::raw::c_int, + #[doc = " MASK"] + pub iControl: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive N performance levels.\n\n This structure is used to store information about Overdrive performance levels.\n This structure is used by the ADL_OverdriveN_ODPerformanceLevels_Get() and ADL_OverdriveN_ODPerformanceLevels_Set() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNPerformanceLevelsX2 { + pub iSize: ::std::os::raw::c_int, + pub iMode: ::std::os::raw::c_int, + #[doc = " Must be set to sizeof( \\ref ADLODPerformanceLevels ) + sizeof( \\ref ADLODPerformanceLevel ) * (ADLODParameters.iNumberOfPerformanceLevels - 1)"] + pub iNumberOfPerformanceLevels: ::std::os::raw::c_int, + #[doc = " Array of performance state descriptors. Must have ADLODParameters.iNumberOfPerformanceLevels elements."] + pub aLevels: [ADLODNPerformanceLevelX2; 1usize], +} +impl ADLODNCurrentPowerType { + pub const ODN_GPU_TOTAL_POWER: ADLODNCurrentPowerType = ADLODNCurrentPowerType(0); +} +impl ADLODNCurrentPowerType { + pub const ODN_GPU_PPT_POWER: ADLODNCurrentPowerType = ADLODNCurrentPowerType(1); +} +impl ADLODNCurrentPowerType { + pub const ODN_GPU_SOCKET_POWER: ADLODNCurrentPowerType = ADLODNCurrentPowerType(2); +} +impl ADLODNCurrentPowerType { + pub const ODN_GPU_CHIP_POWER: ADLODNCurrentPowerType = ADLODNCurrentPowerType(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLODNCurrentPowerType(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNCurrentPowerParameters { + pub size: ::std::os::raw::c_int, + pub powerType: ADLODNCurrentPowerType, + pub currentPower: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLODNExtSingleInitSetting { + pub mode: ::std::os::raw::c_int, + pub minValue: ::std::os::raw::c_int, + pub maxValue: ::std::os::raw::c_int, + pub step: ::std::os::raw::c_int, + pub defaultValue: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD8SingleInitSetting { + pub featureID: ::std::os::raw::c_int, + pub minValue: ::std::os::raw::c_int, + pub maxValue: ::std::os::raw::c_int, + pub defaultValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Overdrive8 initial setting\n\n This structure is used to store information about Overdrive8 initial setting\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD8InitSetting { + pub count: ::std::os::raw::c_int, + pub overdrive8Capabilities: ::std::os::raw::c_int, + pub od8SettingTable: [ADLOD8SingleInitSetting; 52usize], +} +#[doc = "\n\\brief Structure containing information about Overdrive8 current setting\n\n This structure is used to store information about Overdrive8 current setting\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD8CurrentSetting { + pub count: ::std::os::raw::c_int, + pub Od8SettingTable: [::std::os::raw::c_int; 52usize], +} +#[doc = "\n\\brief Structure containing information about Overdrive8 set setting\n\n This structure is used to store information about Overdrive8 set setting\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD8SingleSetSetting { + pub value: ::std::os::raw::c_int, + pub requested: ::std::os::raw::c_int, + pub reset: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLOD8SetSetting { + pub count: ::std::os::raw::c_int, + pub od8SettingTable: [ADLOD8SingleSetSetting; 52usize], +} +#[doc = "\n\\brief Structure containing information about Performance Metrics data\n\n This structure is used to store information about Performance Metrics data output\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSingleSensorData { + pub supported: ::std::os::raw::c_int, + pub value: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogDataOutput { + pub size: ::std::os::raw::c_int, + pub sensors: [ADLSingleSensorData; 256usize], +} +#[doc = "\n\\brief Structure containing information about PPLog settings.\n\n This structure is used to store information about PPLog settings.\n This structure is used by the ADL2_PPLogSettings_Set() and ADL2_PPLogSettings_Get() functions.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPPLogSettings { + pub BreakOnAssert: ::std::os::raw::c_int, + pub BreakOnWarn: ::std::os::raw::c_int, + pub LogEnabled: ::std::os::raw::c_int, + pub LogFieldMask: ::std::os::raw::c_int, + pub LogDestinations: ::std::os::raw::c_int, + pub LogSeverityEnabled: ::std::os::raw::c_int, + pub LogSourceMask: ::std::os::raw::c_int, + pub PowerProfilingEnabled: ::std::os::raw::c_int, + pub PowerProfilingTimeInterval: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information related Frames Per Second for AC and DC.\n\n This structure is used to store information related AC and DC Frames Per Second settings\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFPSSettingsOutput { + #[doc = " size"] + pub ulSize: ::std::os::raw::c_int, + #[doc = " FPS Monitor is enabled in the AC state if 1"] + pub bACFPSEnabled: ::std::os::raw::c_int, + #[doc = " FPS Monitor is enabled in the DC state if 1"] + pub bDCFPSEnabled: ::std::os::raw::c_int, + #[doc = " Current Value of FPS Monitor in AC state"] + pub ulACFPSCurrent: ::std::os::raw::c_int, + #[doc = " Current Value of FPS Monitor in DC state"] + pub ulDCFPSCurrent: ::std::os::raw::c_int, + #[doc = " Maximum FPS Threshold allowed in PPLib for AC"] + pub ulACFPSMaximum: ::std::os::raw::c_int, + #[doc = " Minimum FPS Threshold allowed in PPLib for AC"] + pub ulACFPSMinimum: ::std::os::raw::c_int, + #[doc = " Maximum FPS Threshold allowed in PPLib for DC"] + pub ulDCFPSMaximum: ::std::os::raw::c_int, + #[doc = " Minimum FPS Threshold allowed in PPLib for DC"] + pub ulDCFPSMinimum: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information related Frames Per Second for AC and DC.\n\n This structure is used to store information related AC and DC Frames Per Second settings\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFPSSettingsInput { + #[doc = " size"] + pub ulSize: ::std::os::raw::c_int, + #[doc = " Settings are for Global FPS (used by CCC)"] + pub bGlobalSettings: ::std::os::raw::c_int, + #[doc = " Current Value of FPS Monitor in AC state"] + pub ulACFPSCurrent: ::std::os::raw::c_int, + #[doc = " Current Value of FPS Monitor in DC state"] + pub ulDCFPSCurrent: ::std::os::raw::c_int, + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_int; 6usize], +} +pub const ADL_PMLOG_MAX_SUPPORTED_SENSORS: _bindgen_ty_1 = _bindgen_ty_1(256); +#[repr(transparent)] +#[doc = "\n\\brief Structure containing information related power management logging.\n\n This structure is used to store support information for power management logging.\n \\nosubgrouping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _bindgen_ty_1(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogSupportInfo { + #[doc = " list of sensors defined by ADL_PMLOG_SENSORS"] + pub usSensors: [::std::os::raw::c_ushort; 256usize], + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_int; 16usize], +} +#[doc = "\n\\brief Structure containing information to start power management logging.\n\n This structure is used as input to ADL2_Adapter_PMLog_Start\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogStartInput { + #[doc = " list of sensors defined by ADL_PMLOG_SENSORS"] + pub usSensors: [::std::os::raw::c_ushort; 256usize], + #[doc = " Sample rate in milliseconds"] + pub ulSampleRate: ::std::os::raw::c_ulong, + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_int; 15usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogData { + #[doc = " Structure version"] + pub ulVersion: ::std::os::raw::c_uint, + #[doc = " Current driver sample rate"] + pub ulActiveSampleRate: ::std::os::raw::c_uint, + #[doc = " Timestamp of last update"] + pub ulLastUpdated: ::std::os::raw::c_ulonglong, + #[doc = " 2D array of senesor and values"] + pub ulValues: [[::std::os::raw::c_uint; 2usize]; 256usize], + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_uint; 256usize], +} +#[doc = "\n\\brief Structure containing information to start power management logging.\n\n This structure is returned as output from ADL2_Adapter_PMLog_Start\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogStartOutput { + pub __bindgen_anon_1: ADLPMLogStartOutput__bindgen_ty_1, + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_int; 14usize], +} +#[doc = " Pointer to memory address containing logging data"] +#[repr(C)] +#[derive(Copy, Clone)] +pub union ADLPMLogStartOutput__bindgen_ty_1 { + pub pLoggingAddress: *mut ::std::os::raw::c_void, + pub ptr_LoggingAddress: ::std::os::raw::c_ulonglong, +} +#[doc = "\n\\brief Structure containing information to query limts of power management logging.\n\n This structure is returned as output from ADL2_Adapter_PMLog_SensorLimits_Get\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPMLogSensorLimits { + pub SensorLimits: [[::std::os::raw::c_int; 2usize]; 256usize], +} +#[doc = "\n\\brief Structure containing information related RAS Get Error Counts Information\n\n This structure is used to store RAS Error Counts Get Input Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASGetErrorCountsInput { + pub Reserved: [::std::os::raw::c_uint; 16usize], +} +#[doc = "\n\\brief Structure containing information related RAS Get Error Counts Information\n\n This structure is used to store RAS Error Counts Get Output Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASGetErrorCountsOutput { + pub CorrectedErrors: ::std::os::raw::c_uint, + pub UnCorrectedErrors: ::std::os::raw::c_uint, + pub Reserved: [::std::os::raw::c_uint; 14usize], +} +#[doc = "\n\\brief Structure containing information related RAS Get Error Counts Information\n\n This structure is used to store RAS Error Counts Get Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASGetErrorCounts { + pub InputSize: ::std::os::raw::c_uint, + pub Input: ADLRASGetErrorCountsInput, + pub OutputSize: ::std::os::raw::c_uint, + pub Output: ADLRASGetErrorCountsOutput, +} +#[doc = "\n\\brief Structure containing information related RAS Error Counts Reset Information\n\n This structure is used to store RAS Error Counts Reset Input Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASResetErrorCountsInput { + pub Reserved: [::std::os::raw::c_uint; 8usize], +} +#[doc = "\n\\brief Structure containing information related RAS Error Counts Reset Information\n\n This structure is used to store RAS Error Counts Reset Output Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASResetErrorCountsOutput { + pub Reserved: [::std::os::raw::c_uint; 8usize], +} +#[doc = "\n\\brief Structure containing information related RAS Error Counts Reset Information\n\n This structure is used to store RAS Error Counts Reset Information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASResetErrorCounts { + pub InputSize: ::std::os::raw::c_uint, + pub Input: ADLRASResetErrorCountsInput, + pub OutputSize: ::std::os::raw::c_uint, + pub Output: ADLRASResetErrorCountsOutput, +} +#[doc = "\n\\brief Structure containing information related RAS Error Injection information\n\n This structure is used to store RAS Error Injection input information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASErrorInjectonInput { + pub Address: ::std::os::raw::c_ulonglong, + pub Value: ADL_RAS_INJECTION_METHOD, + pub BlockId: ADL_RAS_BLOCK_ID, + pub InjectErrorType: ADL_RAS_ERROR_TYPE, + pub SubBlockIndex: ADL_MEM_SUB_BLOCK_ID, + pub padding: [::std::os::raw::c_uint; 9usize], +} +#[doc = "\n\\brief Structure containing information related RAS Error Injection information\n\n This structure is used to store RAS Error Injection output information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASErrorInjectionOutput { + pub ErrorInjectionStatus: ::std::os::raw::c_uint, + pub padding: [::std::os::raw::c_uint; 15usize], +} +#[doc = "\n\\brief Structure containing information related RAS Error Injection information\n\n This structure is used to store RAS Error Injection information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLRASErrorInjection { + pub InputSize: ::std::os::raw::c_uint, + pub Input: ADLRASErrorInjectonInput, + pub OutputSize: ::std::os::raw::c_uint, + pub Output: ADLRASErrorInjectionOutput, +} +#[doc = "\n\\brief Structure containing information about an application\n\n This structure is used to store basic information of a recently ran or currently running application\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSGApplicationInfo { + #[doc = " Application file name"] + pub strFileName: [u16; 256usize], + #[doc = " Application file path"] + pub strFilePath: [u16; 256usize], + #[doc = " Application version"] + pub strVersion: [u16; 256usize], + #[doc = " Timestamp at which application has run"] + pub timeStamp: ::std::os::raw::c_longlong, + #[doc = " Holds whether the applicaition profile exists or not"] + pub iProfileExists: ::std::os::raw::c_uint, + #[doc = " The GPU on which application runs"] + pub iGPUAffinity: ::std::os::raw::c_uint, + #[doc = " The BDF of the GPU on which application runs"] + pub GPUBdf: ADLBdf, +} +pub const ADLPreFlipPostProcessingInfoInvalidLUTIndex: _bindgen_ty_2 = _bindgen_ty_2(-1); +#[repr(transparent)] +#[doc = "\n\\brief Structure containing information related Frames Per Second for AC and DC.\n\n This structure is used to store information related AC and DC Frames Per Second settings\n \\nosubgrouping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _bindgen_ty_2(pub ::std::os::raw::c_int); +impl ADLPreFlipPostProcessingLUTAlgorithm { + pub const ADLPreFlipPostProcessingLUTAlgorithm_Default: ADLPreFlipPostProcessingLUTAlgorithm = + ADLPreFlipPostProcessingLUTAlgorithm(0); +} +impl ADLPreFlipPostProcessingLUTAlgorithm { + pub const ADLPreFlipPostProcessingLUTAlgorithm_Full: ADLPreFlipPostProcessingLUTAlgorithm = + ADLPreFlipPostProcessingLUTAlgorithm(1); +} +impl ADLPreFlipPostProcessingLUTAlgorithm { + pub const ADLPreFlipPostProcessingLUTAlgorithm_Approximation: + ADLPreFlipPostProcessingLUTAlgorithm = ADLPreFlipPostProcessingLUTAlgorithm(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ADLPreFlipPostProcessingLUTAlgorithm(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPreFlipPostProcessingInfo { + #[doc = " size"] + pub ulSize: ::std::os::raw::c_int, + #[doc = " Current active state"] + pub bEnabled: ::std::os::raw::c_int, + #[doc = " Current selected LUT index. 0xFFFFFFF returned if nothing selected."] + pub ulSelectedLUTIndex: ::std::os::raw::c_int, + #[doc = " Current selected LUT Algorithm"] + pub ulSelectedLUTAlgorithm: ::std::os::raw::c_int, + #[doc = " Reserved"] + pub ulReserved: [::std::os::raw::c_int; 12usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_ERROR_REASON { + pub boost: ::std::os::raw::c_int, + pub delag: ::std::os::raw::c_int, + pub chill: ::std::os::raw::c_int, + pub proVsr: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_ERROR_REASON2 { + pub boost: ::std::os::raw::c_int, + pub delag: ::std::os::raw::c_int, + pub chill: ::std::os::raw::c_int, + pub proVsr: ::std::os::raw::c_int, + pub upscale: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about DELAG Settings change reason\n\n Elements of DELAG settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_DELAG_NOTFICATION_REASON { + pub HotkeyChanged: ::std::os::raw::c_int, + pub GlobalEnableChanged: ::std::os::raw::c_int, + pub GlobalLimitFPSChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about DELAG Settings\n\n Elements of DELAG settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_DELAG_SETTINGS { + pub Hotkey: ::std::os::raw::c_int, + pub GlobalEnable: ::std::os::raw::c_int, + pub GlobalLimitFPS: ::std::os::raw::c_int, + pub GlobalLimitFPS_MinLimit: ::std::os::raw::c_int, + pub GlobalLimitFPS_MaxLimit: ::std::os::raw::c_int, + pub GlobalLimitFPS_Step: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about BOOST Settings change reason\n\n Elements of BOOST settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_BOOST_NOTFICATION_REASON { + pub HotkeyChanged: ::std::os::raw::c_int, + pub GlobalEnableChanged: ::std::os::raw::c_int, + pub GlobalMinResChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about BOOST Settings\n\n Elements of BOOST settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_BOOST_SETTINGS { + pub Hotkey: ::std::os::raw::c_int, + pub GlobalEnable: ::std::os::raw::c_int, + pub GlobalMinRes: ::std::os::raw::c_int, + pub GlobalMinRes_MinLimit: ::std::os::raw::c_int, + pub GlobalMinRes_MaxLimit: ::std::os::raw::c_int, + pub GlobalMinRes_Step: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about ProVSR Settings change reason\n\n Elements of ProVSR settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_PROVSR_NOTFICATION_REASON { + pub HotkeyChanged: ::std::os::raw::c_int, + pub GlobalEnableChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Pro VSR Settings\n\n Elements of ProVSR settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_PROVSR_SETTINGS { + pub Hotkey: ::std::os::raw::c_int, + pub GlobalEnable: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about Image Boost(OGL) Settings change reason\n\n Elements of Image Boost settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_IMAGE_BOOST_NOTFICATION_REASON { + pub HotkeyChanged: ::std::os::raw::c_int, + pub GlobalEnableChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about OGL IMAGE BOOST Settings\n\n Elements of OGL IMAGE BOOST settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_IMAGE_BOOST_SETTINGS { + pub Hotkey: ::std::os::raw::c_int, + pub GlobalEnable: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about RIS Settings change reason\n\n Elements of RIS settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_RIS_NOTFICATION_REASON { + pub GlobalEnableChanged: ::std::os::raw::c_uint, + pub GlobalSharpeningDegreeChanged: ::std::os::raw::c_uint, +} +#[doc = "\n\\brief Structure containing information about RIS Settings\n\n Elements of RIS settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_RIS_SETTINGS { + pub GlobalEnable: ::std::os::raw::c_int, + pub GlobalSharpeningDegree: ::std::os::raw::c_int, + pub GlobalSharpeningDegree_MinLimit: ::std::os::raw::c_int, + pub GlobalSharpeningDegree_MaxLimit: ::std::os::raw::c_int, + pub GlobalSharpeningDegree_Step: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about CHILL Settings change reason\n\n Elements of Chiil settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_CHILL_NOTFICATION_REASON { + pub HotkeyChanged: ::std::os::raw::c_int, + pub GlobalEnableChanged: ::std::os::raw::c_int, + pub GlobalMinFPSChanged: ::std::os::raw::c_int, + pub GlobalMaxFPSChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about CHILL Settings\n\n Elements of Chill settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_CHILL_SETTINGS { + pub Hotkey: ::std::os::raw::c_int, + pub GlobalEnable: ::std::os::raw::c_int, + pub GlobalMinFPS: ::std::os::raw::c_int, + pub GlobalMaxFPS: ::std::os::raw::c_int, + pub GlobalFPS_MinLimit: ::std::os::raw::c_int, + pub GlobalFPS_MaxLimit: ::std::os::raw::c_int, + pub GlobalFPS_Step: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about DRIVERUPSCALE Settings change reason\n\n Elements of DRIVERUPSCALE settings changed reason.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_DRIVERUPSCALE_NOTFICATION_REASON { + pub ModeOverrideEnabledChanged: ::std::os::raw::c_int, + pub GlobalEnabledChanged: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about DRIVERUPSCALE Settings\n\n Elements of DRIVERUPSCALE settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_DRIVERUPSCALE_SETTINGS { + pub ModeOverrideEnabled: ::std::os::raw::c_int, + pub GlobalEnabled: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure Containing R G B values for Radeon USB LED Bar\n\n Elements of RGB Values.\n \\nosubgrouping\n"] +#[repr(C)] +#[repr(align(2))] +#[derive(Copy, Clone)] +pub struct ADL_RADEON_LED_COLOR_CONFIG { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub __bindgen_padding_0: u8, +} +impl ADL_RADEON_LED_COLOR_CONFIG { + #[inline] + pub fn R(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u16) } + } + #[inline] + pub fn set_R(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn G(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u16) } + } + #[inline] + pub fn set_G(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn B(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } + } + #[inline] + pub fn set_B(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + R: ::std::os::raw::c_ushort, + G: ::std::os::raw::c_ushort, + B: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let R: u16 = unsafe { ::std::mem::transmute(R) }; + R as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let G: u16 = unsafe { ::std::mem::transmute(G) }; + G as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let B: u16 = unsafe { ::std::mem::transmute(B) }; + B as u64 + }); + __bindgen_bitfield_unit + } +} +#[doc = "\n\\brief Structure Containing All Generic LED configuration for user requested LED pattern. The driver will apply the confgiuration as requested\n\n Elements of Radeon USB LED configuration.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_RADEON_LED_PATTERN_CONFIG_GENERIC { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub directionCounterClockWise: bool, + pub colorConfig: ADL_RADEON_LED_COLOR_CONFIG, + pub morseCodeText: [::std::os::raw::c_char; 260usize], + pub morseCodeTextOutPut: [::std::os::raw::c_char; 260usize], + pub morseCodeTextOutPutLen: ::std::os::raw::c_int, +} +impl ADL_RADEON_LED_PATTERN_CONFIG_GENERIC { + #[inline] + pub fn brightness(&self) -> ::std::os::raw::c_short { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u16) } + } + #[inline] + pub fn set_brightness(&mut self, val: ::std::os::raw::c_short) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn speed(&self) -> ::std::os::raw::c_short { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u16) } + } + #[inline] + pub fn set_speed(&mut self, val: ::std::os::raw::c_short) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + brightness: ::std::os::raw::c_short, + speed: ::std::os::raw::c_short, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let brightness: u16 = unsafe { ::std::mem::transmute(brightness) }; + brightness as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let speed: u16 = unsafe { ::std::mem::transmute(speed) }; + speed as u64 + }); + __bindgen_bitfield_unit + } +} +#[doc = "\n\\brief Structure Containing All custom grid pattern LED configuration for user requested LED grid pattern. The driver will apply the confgiuration as requested\n\n Elements of Radeon USB LED custom grid configuration.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_RADEON_LED_CUSTOM_LED_CONFIG { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub colorConfig: [[ADL_RADEON_LED_COLOR_CONFIG; 24usize]; 7usize], +} +impl ADL_RADEON_LED_CUSTOM_LED_CONFIG { + #[inline] + pub fn brightness(&self) -> ::std::os::raw::c_short { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u16) } + } + #[inline] + pub fn set_brightness(&mut self, val: ::std::os::raw::c_short) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + brightness: ::std::os::raw::c_short, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let brightness: u16 = unsafe { ::std::mem::transmute(brightness) }; + brightness as u64 + }); + __bindgen_bitfield_unit + } +} +#[doc = "\n\\brief Structure Containing All custom grid pattern LED configuration for user requested LED grid pattern. The driver will apply the confgiuration as requested\n\n Elements of Radeon USB LED custom grid configuration.\n \\nosubgrouping\n"] +pub type ADL_RADEON_LED_CUSTOM_GRID_LED_CONFIG = ADL_RADEON_LED_CUSTOM_LED_CONFIG; +#[doc = "\n\\brief Structure Containing All Radeon USB LED requests and controls.\n\n Elements of Radeon USB LED Controls.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_RADEON_LED_PATTERN_CONFIG { + pub control: ADL_RADEON_USB_LED_BAR_CONTROLS, + pub __bindgen_anon_1: ADL_RADEON_LED_PATTERN_CONFIG__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ADL_RADEON_LED_PATTERN_CONFIG__bindgen_ty_1 { + pub genericPararmeters: ADL_RADEON_LED_PATTERN_CONFIG_GENERIC, + pub customGridConfig: ADL_RADEON_LED_CUSTOM_GRID_LED_CONFIG, +} +#[doc = "\n\\brief Structure containing information about the graphics adapter with extended caps\n\n This structure is used to store various information about the graphics adapter. This\n information can be returned to the user. Alternatively, it can be used to access various driver calls to set\n or fetch various settings upon the user's request.\n This AdapterInfoX2 struct extends the AdapterInfo struct in adl_structures.h\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct AdapterInfoX2 { + #[doc = " Size of the structure."] + pub iSize: ::std::os::raw::c_int, + #[doc = " The ADL index handle. One GPU may be associated with one or two index handles"] + pub iAdapterIndex: ::std::os::raw::c_int, + #[doc = " The unique device ID associated with this adapter."] + pub strUDID: [::std::os::raw::c_char; 256usize], + #[doc = " The BUS number associated with this adapter."] + pub iBusNumber: ::std::os::raw::c_int, + #[doc = " The driver number associated with this adapter."] + pub iDeviceNumber: ::std::os::raw::c_int, + #[doc = " The function number."] + pub iFunctionNumber: ::std::os::raw::c_int, + #[doc = " The vendor ID associated with this adapter."] + pub iVendorID: ::std::os::raw::c_int, + #[doc = " Adapter name."] + pub strAdapterName: [::std::os::raw::c_char; 256usize], + #[doc = " Display name. For example, \"\\\\\\\\Display0\""] + pub strDisplayName: [::std::os::raw::c_char; 256usize], + #[doc = " Present or not; 1 if present and 0 if not present.It the logical adapter is present, the display name such as \\\\\\\\.\\\\Display1 can be found from OS"] + pub iPresent: ::std::os::raw::c_int, + #[doc = " Exist or not; 1 is exist and 0 is not present."] + pub iExist: ::std::os::raw::c_int, + #[doc = " Driver registry path."] + pub strDriverPath: [::std::os::raw::c_char; 256usize], + #[doc = " Driver registry path Ext for."] + pub strDriverPathExt: [::std::os::raw::c_char; 256usize], + #[doc = " PNP string from Windows."] + pub strPNPString: [::std::os::raw::c_char; 256usize], + #[doc = " It is generated from EnumDisplayDevices."] + pub iOSDisplayIndex: ::std::os::raw::c_int, + #[doc = " The bit mask identifies the adapter info"] + pub iInfoMask: ::std::os::raw::c_int, + #[doc = " The bit identifies the adapter info \\ref define_adapter_info"] + pub iInfoValue: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about driver gamut space , whether it is related to source or to destination, overlay or graphics\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGamutReference { + #[doc = " mask whether it is related to source or to destination, overlay or graphics"] + pub iGamutRef: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about driver supported gamut spaces , capability method\n\n This structure is used to get driver all supported gamut spaces\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGamutInfo { + #[doc = "Any combination of following ADL_GAMUT_SPACE_CCIR_709 - ADL_GAMUT_SPACE_CUSTOM"] + pub SupportedGamutSpace: ::std::os::raw::c_int, + #[doc = "Any combination of following ADL_WHITE_POINT_5000K - ADL_WHITE_POINT_CUSTOM"] + pub SupportedWhitePoint: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about driver point coordinates\n\n This structure is used to store the driver point coodinates for gamut and white point\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLPoint { + #[doc = " x coordinate"] + pub iX: ::std::os::raw::c_int, + #[doc = " y coordinate"] + pub iY: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about driver supported gamut coordinates\n\n This structure is used to store the driver supported supported gamut coordinates\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGamutCoordinates { + #[doc = " red channel chromasity coordinate"] + pub Red: ADLPoint, + #[doc = " green channel chromasity coordinate"] + pub Green: ADLPoint, + #[doc = " blue channel chromasity coordinate"] + pub Blue: ADLPoint, +} +#[doc = "\n\\brief Structure containing information about driver current gamut space , parent struct for ADLGamutCoordinates and ADLWhitePoint\n This structure is used to get/set driver supported gamut space\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLGamutData { + #[doc = "used as mask and could be 4 options\nBIT_0 If flag ADL_GAMUT_REFERENCE_SOURCE is asserted set operation is related to gamut source ,\nif not gamut destination\nBIT_1 If flag ADL_GAMUT_GAMUT_VIDEO_CONTENT is asserted\nBIT_2,BIT_3 used as mask and could be 4 options custom (2) + predefined (2)\n0. Gamut predefined, white point predefined -> 0 | 0\n1. Gamut predefined, white point custom -> 0 | ADL_CUSTOM_WHITE_POINT\n2. White point predefined, gamut custom -> 0 | ADL_CUSTOM_GAMUT\n3. White point custom, gamut custom -> ADL_CUSTOM_GAMUT | ADL_CUSTOM_WHITE_POINT"] + pub iFeature: ::std::os::raw::c_int, + #[doc = "one of ADL_GAMUT_SPACE_CCIR_709 - ADL_GAMUT_SPACE_CIE_RGB"] + pub iPredefinedGamut: ::std::os::raw::c_int, + #[doc = "one of ADL_WHITE_POINT_5000K - ADL_WHITE_POINT_9300K"] + pub iPredefinedWhitePoint: ::std::os::raw::c_int, + #[doc = "valid when in mask avails ADL_CUSTOM_WHITE_POINT"] + pub CustomWhitePoint: ADLPoint, + #[doc = "valid when in mask avails ADL_CUSTOM_GAMUT"] + pub CustomGamut: ADLGamutCoordinates, +} +#[doc = "\n\\brief Structure containing detailed timing parameters.\n\n This structure is used to store the detailed timing parameters.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDetailedTimingX2 { + #[doc = " Size of the structure."] + pub iSize: ::std::os::raw::c_int, + #[doc = " Timing flags. \\ref define_detailed_timing_flags"] + pub sTimingFlags: ::std::os::raw::c_int, + #[doc = " Total width (columns)."] + pub sHTotal: ::std::os::raw::c_int, + #[doc = " Displayed width."] + pub sHDisplay: ::std::os::raw::c_int, + #[doc = " Horizontal sync signal offset."] + pub sHSyncStart: ::std::os::raw::c_int, + #[doc = " Horizontal sync signal width."] + pub sHSyncWidth: ::std::os::raw::c_int, + #[doc = " Total height (rows)."] + pub sVTotal: ::std::os::raw::c_int, + #[doc = " Displayed height."] + pub sVDisplay: ::std::os::raw::c_int, + #[doc = " Vertical sync signal offset."] + pub sVSyncStart: ::std::os::raw::c_int, + #[doc = " Vertical sync signal width."] + pub sVSyncWidth: ::std::os::raw::c_int, + #[doc = " Pixel clock value."] + pub sPixelClock: ::std::os::raw::c_int, + #[doc = " Overscan right."] + pub sHOverscanRight: ::std::os::raw::c_short, + #[doc = " Overscan left."] + pub sHOverscanLeft: ::std::os::raw::c_short, + #[doc = " Overscan bottom."] + pub sVOverscanBottom: ::std::os::raw::c_short, + #[doc = " Overscan top."] + pub sVOverscanTop: ::std::os::raw::c_short, + pub sOverscan8B: ::std::os::raw::c_short, + pub sOverscanGR: ::std::os::raw::c_short, +} +#[doc = "\n\\brief Structure containing display mode information.\n\n This structure is used to store the display mode information.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLDisplayModeInfoX2 { + #[doc = " Timing standard of the current mode. \\ref define_modetiming_standard"] + pub iTimingStandard: ::std::os::raw::c_int, + #[doc = " Applicable timing standards for the current mode."] + pub iPossibleStandard: ::std::os::raw::c_int, + #[doc = " Refresh rate factor."] + pub iRefreshRate: ::std::os::raw::c_int, + #[doc = " Num of pixels in a row."] + pub iPelsWidth: ::std::os::raw::c_int, + #[doc = " Num of pixels in a column."] + pub iPelsHeight: ::std::os::raw::c_int, + #[doc = " Detailed timing parameters."] + pub sDetailedTiming: ADLDetailedTimingX2, +} +#[doc = "\n\\brief Structure containing information about I2C.\n\n This structure is used to store the I2C information for the current adapter.\n This structure is used by \\ref ADL_Display_WriteAndReadI2CLargePayload\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLI2CLargePayload { + #[doc = " Size of the structure"] + pub iSize: ::std::os::raw::c_int, + #[doc = " Numerical value representing hardware I2C."] + pub iLine: ::std::os::raw::c_int, + #[doc = " The 7-bit I2C slave device address."] + pub iAddress: ::std::os::raw::c_int, + #[doc = " The offset of the data from the address."] + pub iOffset: ::std::os::raw::c_int, + #[doc = " Read from or write to slave device. \\ref ADL_DL_I2C_ACTIONREAD or \\ref ADL_DL_I2C_ACTIONWRITE"] + pub iAction: ::std::os::raw::c_int, + #[doc = " I2C clock speed in KHz."] + pub iSpeed: ::std::os::raw::c_int, + #[doc = " I2C option flags. \\ref define_ADLI2CLargePayload"] + pub iFlags: ::std::os::raw::c_int, + #[doc = " A numerical value representing the number of bytes to be sent or received on the I2C bus."] + pub iDataSize: ::std::os::raw::c_int, + #[doc = " Address of the characters which are to be sent or received on the I2C bus."] + pub pcData: *mut ::std::os::raw::c_char, +} +#[doc = "\n\\brief Structure containing the Multimedia Feature Name\n\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFeatureName { + #[doc = " The Feature Name"] + pub FeatureName: [::std::os::raw::c_char; 16usize], +} +#[doc = "\n\\brief Structure containing information about MM Feature Capabilities.\n\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFeatureCaps { + #[doc = " The Feature Name"] + pub Name: ADLFeatureName, + #[doc = " Group ID. All Features in the same group are shown sequentially in the same UI Page."] + pub iGroupID: ::std::os::raw::c_int, + #[doc = " Visual ID. Places one or more features in a Group Box. If zero, no Group Box is added."] + pub iVisualID: ::std::os::raw::c_int, + #[doc = " Page ID. All Features with the same Page ID value are shown together on the same UI page."] + pub iPageID: ::std::os::raw::c_int, + #[doc = " Feature Property Mask. Indicates which are the valid bits for iFeatureProperties."] + pub iFeatureMask: ::std::os::raw::c_int, + #[doc = " Feature Property Values. See definitions for ADL_FEATURE_PROPERTIES_XXX"] + pub iFeatureProperties: ::std::os::raw::c_int, + #[doc = " Apperance of the User-Controlled Boolean."] + pub iControlType: ::std::os::raw::c_int, + #[doc = " Style of the User-Controlled Boolean."] + pub iControlStyle: ::std::os::raw::c_int, + #[doc = " Apperance of the Adjustment Controls."] + pub iAdjustmentType: ::std::os::raw::c_int, + #[doc = " Style of the Adjustment Controls."] + pub iAdjustmentStyle: ::std::os::raw::c_int, + #[doc = " Default user-controlled boolean value. Valid only if ADLFeatureCaps supports user-controlled boolean."] + pub bDefault: ::std::os::raw::c_int, + #[doc = " Minimum integer value. Valid only if ADLFeatureCaps indicates support for integers."] + pub iMin: ::std::os::raw::c_int, + #[doc = " Maximum integer value. Valid only if ADLFeatureCaps indicates support for integers."] + pub iMax: ::std::os::raw::c_int, + #[doc = " Step integer value. Valid only if ADLFeatureCaps indicates support for integers."] + pub iStep: ::std::os::raw::c_int, + #[doc = " Default integer value. Valid only if ADLFeatureCaps indicates support for integers."] + pub iDefault: ::std::os::raw::c_int, + #[doc = " Minimum float value. Valid only if ADLFeatureCaps indicates support for floats."] + pub fMin: f32, + #[doc = " Maximum float value. Valid only if ADLFeatureCaps indicates support for floats."] + pub fMax: f32, + #[doc = " Step float value. Valid only if ADLFeatureCaps indicates support for floats."] + pub fStep: f32, + #[doc = " Default float value. Valid only if ADLFeatureCaps indicates support for floats."] + pub fDefault: f32, + #[doc = " The Mask for available bits for enumerated values.(If ADLFeatureCaps supports ENUM values)"] + pub EnumMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about MM Feature Values.\n\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLFeatureValues { + #[doc = " The Feature Name"] + pub Name: ADLFeatureName, + #[doc = " User controlled Boolean current value. Valid only if ADLFeatureCaps supports Boolean."] + pub bCurrent: ::std::os::raw::c_int, + #[doc = " Current integer value. Valid only if ADLFeatureCaps indicates support for integers."] + pub iCurrent: ::std::os::raw::c_int, + #[doc = " Current float value. Valid only if ADLFeatureCaps indicates support for floats."] + pub fCurrent: f32, + #[doc = " The States for the available bits for enumerated values."] + pub EnumStates: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing HDCP Settings info\n\n This structure is used to store the HDCP settings of a\n display\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLHDCPSettings { + pub iHDCPProtectionVersion: ::std::os::raw::c_int, + pub iHDCPCaps: ::std::os::raw::c_int, + pub iAllowAll: ::std::os::raw::c_int, + pub iHDCPVale: ::std::os::raw::c_int, + pub iHDCPMask: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing Mantle App info\n\n This structure is used to store the Mantle Driver information\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLMantleAppInfo { + #[doc = " mantle api version"] + pub apiVersion: ::std::os::raw::c_int, + #[doc = " mantle driver version"] + pub driverVersion: ::std::os::raw::c_long, + #[doc = " mantle vendroe id"] + pub vendorId: ::std::os::raw::c_long, + #[doc = " mantle device id"] + pub deviceId: ::std::os::raw::c_long, + #[doc = " mantle gpu type;"] + pub gpuType: ::std::os::raw::c_int, + #[doc = " gpu name"] + pub gpuName: [::std::os::raw::c_char; 256usize], + #[doc = " mem size"] + pub maxMemRefsPerSubmission: ::std::os::raw::c_int, + #[doc = " virtual mem size"] + pub virtualMemPageSize: ::std::os::raw::c_longlong, + #[doc = " mem update"] + pub maxInlineMemoryUpdateSize: ::std::os::raw::c_longlong, + #[doc = " bound descriptot"] + pub maxBoundDescriptorSets: ::std::os::raw::c_long, + #[doc = " thread group size"] + pub maxThreadGroupSize: ::std::os::raw::c_long, + #[doc = " time stamp frequency"] + pub timestampFrequency: ::std::os::raw::c_longlong, + #[doc = " color target"] + pub multiColorTargetClears: ::std::os::raw::c_long, +} +#[doc = "\n\\brief Structure containing information about SDIData\nThis structure is used to store information about the state of the SDI whether it is on\nor off and the current size of the segment or aperture size.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSDIData { + #[doc = " The SDI state, ADL_SDI_ON or ADL_SDI_OFF, for the current SDI mode"] + pub iSDIState: ::std::os::raw::c_int, + #[doc = " Size of the memory segment for SDI (in MB)."] + pub iSizeofSDISegment: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information about FRTCPRO Settings\n\n Elements of FRTCPRO settings.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_FRTCPRO_Settings { + pub DefaultState: ::std::os::raw::c_int, + pub CurrentState: ::std::os::raw::c_int, + pub DefaultValue: ::std::os::raw::c_uint, + pub CurrentValue: ::std::os::raw::c_uint, + pub maxSupportedFps: ::std::os::raw::c_uint, + pub minSupportedFps: ::std::os::raw::c_uint, +} +#[doc = "\n\\brief Structure containing information about FRTCPRO Settings changed reason\n\n Reason of FRTCPRO changed.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_FRTCPRO_CHANGED_REASON { + pub StateChanged: ::std::os::raw::c_int, + pub ValueChanged: ::std::os::raw::c_int, +} +#[doc = "\n \\brief Structure containing the display mode definition used per controller.\n\n This structure is used to store the display mode definition used per controller.\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADL_DL_DISPLAY_MODE { + pub iPelsHeight: ::std::os::raw::c_int, + pub iPelsWidth: ::std::os::raw::c_int, + pub iBitsPerPel: ::std::os::raw::c_int, + pub iDisplayFrequency: ::std::os::raw::c_int, +} +#[doc = "\n\\brief Structure containing information related DCE support\n\n This structure is used to store a bit vector of possible DCE support\n\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub union _ADLDCESupport { + pub bits: _ADLDCESupport__bindgen_ty_1, + pub u32All: ::std::os::raw::c_uint, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _ADLDCESupport__bindgen_ty_1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _ADLDCESupport__bindgen_ty_1 { + #[inline] + pub fn PrePhasis(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_PrePhasis(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn voltageSwing(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_voltageSwing(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + PrePhasis: ::std::os::raw::c_uint, + voltageSwing: ::std::os::raw::c_uint, + reserved: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let PrePhasis: u32 = unsafe { ::std::mem::transmute(PrePhasis) }; + PrePhasis as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let voltageSwing: u32 = unsafe { ::std::mem::transmute(voltageSwing) }; + voltageSwing as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[doc = "\n\\brief Structure containing information related DCE support\n\n This structure is used to store a bit vector of possible DCE support\n\n \\nosubgrouping\n"] +pub type ADLDCESupport = _ADLDCESupport; +#[doc = "\n \\brief Structure for Smart shift 2.0 settings\n\n This structure is used to return the smart shift settings\n \\nosubgrouping\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ADLSmartShiftSettings { + pub iMinRange: ::std::os::raw::c_int, + pub iMaxRange: ::std::os::raw::c_int, + pub iDefaultMode: ::std::os::raw::c_int, + pub iDefaultValue: ::std::os::raw::c_int, + pub iCurrentMode: ::std::os::raw::c_int, + pub iCurrentValue: ::std::os::raw::c_int, + pub iFlags: ::std::os::raw::c_int, +} +#[doc = " Memory Allocation Call back"] +pub type ADL_MAIN_MALLOC_CALLBACK = ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void, +>; +extern "C" { + pub fn ADL2_Adapter_ObservedClockInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCoreClock: *mut ::std::os::raw::c_int, + lpMemoryClock: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Active_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStatus: ::std::os::raw::c_int, + lpNewlyActivate: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Active_SetPrefer( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStatus: ::std::os::raw::c_int, + iNumPreferTarget: ::std::os::raw::c_int, + lpPreferTarget: *mut ADLDisplayTarget, + lpNewlyActivate: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Primary_Get( + context: ADL_CONTEXT_HANDLE, + lpPrimaryAdapterIndex: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Primary_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ModeSwitch( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Active_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpStatus: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Aspects_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpAspects: *mut ::std::os::raw::c_char, + iSize: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_NumberOfAdapters_Get( + context: ADL_CONTEXT_HANDLE, + lpNumAdapters: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Flush_Driver_Data( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AdapterInfo_Get( + context: ADL_CONTEXT_HANDLE, + lpInfo: LPAdapterInfo, + iInputSize: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VerndorID_Int_get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AdapterInfoX2_Get( + context: ADL_CONTEXT_HANDLE, + lppAdapterInfo: *mut *mut AdapterInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_RegValueString_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDriverPathOption: ::std::os::raw::c_int, + szSubKey: *mut ::std::os::raw::c_char, + szKeyName: *mut ::std::os::raw::c_char, + iSize: ::std::os::raw::c_int, + lpKeyValue: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_RegValueString_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDriverPathOption: ::std::os::raw::c_int, + szSubKey: *mut ::std::os::raw::c_char, + szKeyName: *mut ::std::os::raw::c_char, + iSize: ::std::os::raw::c_int, + lpKeyValue: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_RegValueInt_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDriverPathOption: ::std::os::raw::c_int, + szSubKey: *mut ::std::os::raw::c_char, + szKeyName: *mut ::std::os::raw::c_char, + lpKeyValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_RegValueInt_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDriverPathOption: ::std::os::raw::c_int, + szSubKey: *mut ::std::os::raw::c_char, + szKeyName: *mut ::std::os::raw::c_char, + iKeyValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ASICFamilyType_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpAsicTypes: *mut ::std::os::raw::c_int, + lpValids: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Speed_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCaps: *mut ::std::os::raw::c_int, + lpValid: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Speed_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Speed_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSpeed: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Accessibility_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpAccessibility: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VideoBiosInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpBiosInfo: *mut ADLBiosInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ID_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpAdapterID: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_AdapterX2_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + adapterCaps: *mut ADLAdapterCapsX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Stress_Test_Cap( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSupported: *mut ::std::os::raw::c_int, + iEnabled: *mut ::std::os::raw::c_int, + iVersion: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Throttle_Notification_Cap( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSupported: *mut ::std::os::raw::c_int, + iEnabled: *mut ::std::os::raw::c_int, + iVersion: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AceDefaults_Restore( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AdapterInfoX4_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + numAdapters: *mut ::std::os::raw::c_int, + lppAdapterInfoX2: *mut *mut AdapterInfoX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AdapterInfoX3_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + numAdapters: *mut ::std::os::raw::c_int, + lppAdapterInfo: *mut *mut AdapterInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_AdapterList_Disable( + context: ADL_CONTEXT_HANDLE, + iNumAdapters: ::std::os::raw::c_int, + lpAdapterIndexList: *mut ::std::os::raw::c_int, + isSkipSaveDB: bool, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_BigSw_Info_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpBigSwSupportMajor: *mut ::std::os::raw::c_int, + lpBigSwSupportMinor: *mut ::std::os::raw::c_int, + lpRedStoneSupport: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + adapterCaps: *mut ADLAdapterCaps, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ChipSetInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpChipSetInfo: *mut ADLChipSetInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Feature_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iFeatureID: ADL_UIFEATURES_GROUP, + iIsFeatureSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_HBC_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpHbcCapable: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Headless_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpHeadless: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_IsGamingDriver_Info_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCwgSupport: *mut ::std::os::raw::c_int, + lpIsGamingMode: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_MemoryInfo2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpMemoryInfo2: *mut ADLMemoryInfo2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_TRNG_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iTRNGSize: ::std::os::raw::c_int, + iTRNGBufferSize: ::std::os::raw::c_int, + lpTRNGBuffer: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Modes_ReEnumerate(context: ADL_CONTEXT_HANDLE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Feature_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iFeatureID: ADL_UIFEATURES_GROUP, + iCurrent: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Feature_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iFeatureID: ADL_UIFEATURES_GROUP, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_GcnAsicInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + gcnInfo: *mut ADLGcnInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_GPUVMPageSize_Info_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iVMPageSizeSupport: *mut ::std::os::raw::c_int, + iVMPageSizeType: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_GPUVMPageSize_Info_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iVMPageSizeType: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VRAMUsage_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iVRAMUsageInMB: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_DedicatedVRAMUsage_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iVRAMUsageInMB: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VideoTheaterModeInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverlayDisplayMode: *mut ::std::os::raw::c_int, + lpSavedSettings: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VideoTheaterModeInfo_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iOverlayDisplayMode: ::std::os::raw::c_int, + iSavedSettings: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_MMD_Features_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lppFeatureCaps: *mut *mut ADLFeatureCaps, + lpFeatureCount: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_MMD_FeatureValues_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lppFeatureValues: *mut *mut ADLFeatureValues, + lpFeatureCount: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_MMD_FeatureValues_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFeatureValues: *mut ADLFeatureValues, + iFeatureCount: ::std::os::raw::c_int, + ClientID: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PageMigration_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpVirtualSegSettings: *mut ADLVirtualSegmentSettingsOutput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PageMigration_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iEnabled: ::std::os::raw::c_int, + iNewSize: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Crossfire_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpPreferred: *mut ::std::os::raw::c_int, + lpNumComb: *mut ::std::os::raw::c_int, + ppCrossfireComb: *mut *mut ADLCrossfireComb, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Crossfire_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCrossfireComb: *mut ADLCrossfireComb, + lpCrossfireInfo: *mut ADLCrossfireInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_Crossfire_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCrossfireComb: *mut ADLCrossfireComb, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_MVPU_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iState: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_CrossfireX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCrossfireComb: *mut ADLCrossfireComb, + lpCrossfireInfo: *mut ADLCrossfireInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_BoardLayout_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpValidFlags: *mut ::std::os::raw::c_int, + lpNumberSlots: *mut ::std::os::raw::c_int, + lppBracketSlot: *mut *mut ADLBracketSlotInfo, + lpNumberConnector: *mut ::std::os::raw::c_int, + lppConnector: *mut *mut ADLConnectorInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_SupportedConnections_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + lpADLSupportedConnections: *mut ADLSupportedConnections, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ConnectionState_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + lpADLConnectionState: *mut ADLConnectionState, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_EmulationMode_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + iEmulationMode: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ConnectionData_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + ConnectionData: ADLConnectionData, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ConnectionData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + iQueryType: ::std::os::raw::c_int, + lpConnectionData: *mut ADLConnectionData, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ConnectionData_Remove( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + devicePort: ADLDevicePort, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_EDIDManagement_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Workstation_GlobalEDIDPersistence_Get( + context: ADL_CONTEXT_HANDLE, + lpCurResultValue: *mut ::std::os::raw::c_int, + lpDefResultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Workstation_GlobalEDIDPersistence_Set( + context: ADL_CONTEXT_HANDLE, + iCurState: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_ElmCompatibilityMode_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_ElmCompatibilityMode_Status_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_ElmCompatibilityMode_Status_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_FPS_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + lpVersion: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_FPS_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFPSSettings: *mut ADLFPSSettingsOutput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_FPS_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFPSSettings: ADLFPSSettingsInput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_FPS_Settings_Reset( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_RIS_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: ADL_RIS_SETTINGS, + changeReason: ADL_RIS_NOTFICATION_REASON, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_RIS_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: *mut ADL_RIS_SETTINGS, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CHILL_SettingsX2_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: ADL_CHILL_SETTINGS, + changeReason: ADL_CHILL_NOTFICATION_REASON, + errorReason: *mut ADL_ERROR_REASON, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CHILL_SettingsX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: *mut ADL_CHILL_SETTINGS, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DELAG_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: ADL_DELAG_SETTINGS, + changeReason: ADL_DELAG_NOTFICATION_REASON, + errorReason: *mut ADL_ERROR_REASON, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DELAG_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: *mut ADL_DELAG_SETTINGS, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_BOOST_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: ADL_BOOST_SETTINGS, + changeReason: ADL_BOOST_NOTFICATION_REASON, + errorReason: *mut ADL_ERROR_REASON, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_BOOST_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: *mut ADL_BOOST_SETTINGS, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PROVSR_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: ADL_PROVSR_SETTINGS, + changeReason: ADL_PROVSR_NOTFICATION_REASON, + errorReason: *mut ADL_ERROR_REASON, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PROVSR_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + settings: *mut ADL_PROVSR_SETTINGS, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Chill_Settings_Notify( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iChanged: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Chill_Settings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iEnabled: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Chill_Settings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpEnabled: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Chill_Caps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSupported: *mut ::std::os::raw::c_int, + iCheckCaps: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PerformanceTuning_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PerfTuning_Status_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpPTuningValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PerfTuning_Status_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpPTuningValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PPW_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PPW_Status_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFPWValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PPW_Status_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iFPWValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iIsFrameMonitorSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_Start( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + VidPnSourceId: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_Stop( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + VidPnSourceId: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + VidPnSourceId: ::std::os::raw::c_int, + iFramesPerSecond: *mut f32, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_FrameDuration_Enable( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + frameDurationHandle: *mut ADL_FRAME_DURATION_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_FrameDuration_Disable( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + frameDurationHandle: *mut ADL_FRAME_DURATION_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_FrameDuration_Start( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + VidPnSourceId: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_FrameDuration_Stop( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + VidPnSourceId: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_FrameMetrics_FrameDuration_Get( + context: ADL_CONTEXT_HANDLE, + frameDurationHandle: ADL_FRAME_DURATION_HANDLE, + pFrameDurationsArr: *mut ::std::os::raw::c_ulonglong, + frameDurationsArrSize: ::std::os::raw::c_uint, + elementsCopied: *mut ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ClockInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpClockInfo: *mut ADLClockInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_AdapterID_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpAdapterID: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_EDC_ErrorRecords_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + pErrorrecordCount: *mut ::std::os::raw::c_int, + errorRecords: *mut ADLErrorRecord, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_EDC_ErrorInjection_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + errorInjection: *mut ADLErrorInjection, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_VirtualType_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iVirtualType: *mut ADL_VIRTUALDISPLAY_TYPE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_WriteAndReadI2CLargePayload( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + plI2C: *mut ADLI2CLargePayload, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_HDCP_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpHDCPSettings: *mut ADLHDCPSettings, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_HDCP_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iSetToDefault: ::std::os::raw::c_int, + iEnable: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_HDRState_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + iSupport: *mut ::std::os::raw::c_int, + iEnable: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_HDRState_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + iEnable: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Limits_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpMaxHRes: *mut ::std::os::raw::c_int, + lpMaxVRes: *mut ::std::os::raw::c_int, + lpMaxRefresh: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PreferredMode_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpNumModes: *mut ::std::os::raw::c_int, + lppModes: *mut *mut ADLMode, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DisplayInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumDisplays: *mut ::std::os::raw::c_int, + lppInfo: *mut *mut ADLDisplayInfo, + iForceDetect: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DpMstInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumDisplays: *mut ::std::os::raw::c_int, + lppDisplayDPMstInfo: *mut *mut ADLDisplayDPMSTInfo, + iForceDetect: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_NumberOfDisplays_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumDisplays: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PreservedAspectRatio_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PreservedAspectRatio_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ImageExpansion_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ImageExpansion_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Position_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpX: *mut ::std::os::raw::c_int, + lpY: *mut ::std::os::raw::c_int, + lpXDefault: *mut ::std::os::raw::c_int, + lpYDefault: *mut ::std::os::raw::c_int, + lpMinX: *mut ::std::os::raw::c_int, + lpMinY: *mut ::std::os::raw::c_int, + lpMaxX: *mut ::std::os::raw::c_int, + lpMaxY: *mut ::std::os::raw::c_int, + lpStepX: *mut ::std::os::raw::c_int, + lpStepY: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Position_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iX: ::std::os::raw::c_int, + iY: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Size_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpWidth: *mut ::std::os::raw::c_int, + lpHeight: *mut ::std::os::raw::c_int, + lpDefaultWidth: *mut ::std::os::raw::c_int, + lpDefaultHeight: *mut ::std::os::raw::c_int, + lpMinWidth: *mut ::std::os::raw::c_int, + lpMinHeight: *mut ::std::os::raw::c_int, + lpMaxWidth: *mut ::std::os::raw::c_int, + lpMaxHeight: *mut ::std::os::raw::c_int, + lpStepWidth: *mut ::std::os::raw::c_int, + lpStepHeight: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Size_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iWidth: ::std::os::raw::c_int, + iHeight: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_AdjustCaps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpInfo: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Capabilities_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumberOfControlers: *mut ::std::os::raw::c_int, + lpNumberOfDisplays: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ConnectedDisplays_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpConnections: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DeviceConfig_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDisplayConfig: *mut ADLDisplayConfig, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Property_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDisplayProperty: *mut ADLDisplayProperty, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Property_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDisplayProperty: *mut ADLDisplayProperty, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_SwitchingCapability_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpResult: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DitherState_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDitherState: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DitherState_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iDitherState: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_SupportedPixelFormat_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpPixelFormat: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PixelFormat_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpPixelFormat: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PixelFormatDefault_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDefPixelFormat: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_PixelFormat_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iPixelFormat: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_SupportedColorDepth_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpColorDepth: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorDepth_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpColorDepth: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorDepth_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iColorDepth: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ODClockInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOdClockInfo: *mut ADLAdapterODClockInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ODClockConfig_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOdClockConfig: *mut ADLAdapterODClockConfig, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_AdjustmentCoherent_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpAdjustmentCoherentCurrent: *mut ::std::os::raw::c_int, + lpAdjustmentCoherentDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_AdjustmentCoherent_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iAdjustmentCoherent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ReducedBlanking_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpReducedBlankingCurrent: *mut ::std::os::raw::c_int, + lpReducedBlankingDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ReducedBlanking_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iReducedBlanking: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FormatsOverride_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSettingsSupported: *mut ::std::os::raw::c_int, + lpSettingsSupportedEx: *mut ::std::os::raw::c_int, + lpCurSettings: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FormatsOverride_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iOverrideSettings: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_MVPUCaps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpMvpuCaps: *mut ADLMVPUCaps, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_MVPUStatus_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpMvpuStatus: *mut ADLMVPUStatus, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DummyVirtual_Get( + context: ADL_CONTEXT_HANDLE, + iVirtualDisplayType: ::std::os::raw::c_int, + iTargetID: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DummyVirtual_Destroy( + context: ADL_CONTEXT_HANDLE, + iTargetID: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VariBright_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSupported: *mut ::std::os::raw::c_int, + iEnabled: *mut ::std::os::raw::c_int, + iVersion: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VariBrightEnable_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iEnabled: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VariBrightLevel_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDefaultLevel: *mut ::std::os::raw::c_int, + iNumberOfLevels: *mut ::std::os::raw::c_int, + iStep: *mut ::std::os::raw::c_int, + iCurrentLevel: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_VariBrightLevel_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iCurrentLevel: ::std::os::raw::c_int, + iApplyImmediately: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ControllerOverlayAdjustmentCaps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverlayInput: *mut ADLControllerOverlayInput, + lpCapsInfo: *mut ADLControllerOverlayInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ControllerOverlayAdjustmentData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverlay: *mut ADLControllerOverlayInput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ControllerOverlayAdjustmentData_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverlay: *mut ADLControllerOverlayInput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ViewPort_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpControllerMode: *mut ADLControllerMode, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ViewPort_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpControllerMode: *mut ADLControllerMode, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ViewPort_Cap( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_WriteAndReadI2CRev_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpMajor: *mut ::std::os::raw::c_int, + lpMinor: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_WriteAndReadI2C( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + plI2C: *mut ADLI2C, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DDCBlockAccess_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iOption: ::std::os::raw::c_int, + iCommandIndex: ::std::os::raw::c_int, + iSendMsgLen: ::std::os::raw::c_int, + lpucSendMsgBuf: *mut ::std::os::raw::c_char, + lpulRecvMsgLen: *mut ::std::os::raw::c_int, + lpucRecvMsgBuf: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DDCInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpInfo: *mut ADLDDCInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DDCInfo2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpInfo: *mut ADLDDCInfo2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_EdidData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpEDIDData: *mut ADLDisplayEDIDData, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorCaps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCaps: *mut ::std::os::raw::c_int, + lpValids: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Color_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iColorType: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Color_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iColorType: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorTemperatureSource_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpTempSource: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorTemperatureSourceDefault_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpTempSourceDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ColorTemperatureSource_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iTempSource: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Gamut_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + gamut: ADLGamutReference, + lpCap: *mut ADLGamutInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Gamut_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + gamut: ADLGamutReference, + lpSource: *mut ADLGamutData, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Gamut_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + gamut: ADLGamutReference, + lpSource: *const ADLGamutData, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverride_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpModeIn: *mut ADLDisplayMode, + lpModeInfoOut: *mut ADLDisplayModeInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverride_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpMode: *mut ADLDisplayModeInfo, + iForceUpdate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideList_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iMaxNumOfOverrides: ::std::os::raw::c_int, + lpModeInfoList: *mut ADLDisplayModeInfo, + lpNumOfOverrides: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideX2_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpMode: *mut ADLDisplayModeInfoX2, + iForceUpdate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideX3_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpModeIn: *mut ADLDisplayModeX2, + lpModeInfoOut: *mut ADLDisplayModeInfoX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideListX3_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpNumOfModes: *mut ::std::os::raw::c_int, + lpModeInfoList: *mut *mut ADLDisplayModeInfoX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_ModeTimingOverride_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpModeIn: *mut ADLDisplayModeX2, + lpModeInfoOut: *mut ADLDisplayModeInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverrideListX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpNumOfModes: *mut ::std::os::raw::c_int, + lpModeInfoList: *mut *mut ADLDisplayModeInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_ModeTimingOverride_Delete( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpMode: *mut ADLDisplayModeX2, + iForceUpdate: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_CustomizedModeListNum_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpListNum: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_CustomizedModeList_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCustomModeList: *mut ADLCustomMode, + iBuffSize: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_CustomizedMode_Add( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + customMode: ADLCustomMode, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_CustomizedMode_Delete( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_CustomizedMode_Validate( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + customMode: ADLCustomMode, + lpValid: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_UnderscanSupport_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_UnderscanState_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_UnderscanState_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iUnderscanEnabled: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Underscan_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Underscan_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Overscan_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Overscan_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefualt: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_BaseAudioSupport_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_HDMISupport_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_MVPUAnalogSupport_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_PixelFormat_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpValidBits: *mut ::std::os::raw::c_int, + lpValidCaps: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_PixelFormat_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurState: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_PixelFormat_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iState: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_GPUScalingEnable_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_GPUScalingEnable_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_AllowOnlyCETimings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_DFP_AllowOnlyCETimings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_TVCaps_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpcaps: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_TV_Standard_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_TV_Standard_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpSupportedStandards: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CV_DongleSettings_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpDongleSetting: *mut ::std::os::raw::c_int, + lpOverrideSettingsSupported: *mut ::std::os::raw::c_int, + lpCurOverrideSettings: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CV_DongleSettings_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iOverrideSettings: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CV_DongleSettings_Reset( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_UnderScan_Auto_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_UnderScan_Auto_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Deflicker_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Deflicker_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayindex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FilterSVideo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMin: *mut ::std::os::raw::c_int, + lpMax: *mut ::std::os::raw::c_int, + lpStep: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FilterSVideo_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DisplayContent_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iContent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DisplayContent_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + piContent: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DisplayContent_Cap( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + pCapContent: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_TargetTiming_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpModeInfoOut: *mut ADLDisplayModeInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_TargetTimingX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + displayID: ADLDisplayID, + lpModeInfoOut: *mut ADLDisplayModeInfoX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_Downscaling_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayID: ::std::os::raw::c_int, + lpCaps: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FreeSyncState_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + lpMinRefreshRateInMicroHz: *mut ::std::os::raw::c_int, + lpMaxRefreshRateInMicroHz: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FreeSyncState_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + iSetting: ::std::os::raw::c_int, + iRefreshRateInMicroHz: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DCE_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpADLDceSettings: *mut ADLDceSettings, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_DCE_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpADLDceSettings: *mut ADLDceSettings, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Display_FreeSync_Cap( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDisplayIndex: ::std::os::raw::c_int, + lpFreeSyncCaps: *mut ADLFreeSyncCap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CDS_UnsafeMode_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + unsafeMode: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_TurboSyncSupport_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iTurboSyncSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_User_Settings_Notify( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSetting: ADL_USER_SETTINGS, + iChanged: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_ControlX2_Create( + callback: ADL_MAIN_MALLOC_CALLBACK, + iEnumConnectedAdapters: ::std::os::raw::c_int, + context: *mut ADL_CONTEXT_HANDLE, + threadingModel: ADLThreadingModel, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_ControlX3_Create( + callback: ADL_MAIN_MALLOC_CALLBACK, + iEnumConnectedAdapters: ::std::os::raw::c_int, + context: *mut ADL_CONTEXT_HANDLE, + threadingModel: ADLThreadingModel, + adlCreateOptions: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_Control_Create( + callback: ADL_MAIN_MALLOC_CALLBACK, + iEnumConnectedAdapters: ::std::os::raw::c_int, + context: *mut ADL_CONTEXT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_Control_Refresh(context: ADL_CONTEXT_HANDLE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_Control_Destroy(context: ADL_CONTEXT_HANDLE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Main_Control_GetProcAddress( + context: ADL_CONTEXT_HANDLE, + lpModule: *mut ::std::os::raw::c_void, + lpProcName: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn ADL2_RegisterEvent( + context: ADL_CONTEXT_HANDLE, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_UnRegisterEvent( + context: ADL_CONTEXT_HANDLE, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_RegisterEventX2( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + clientID: ::std::os::raw::c_int, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_UnRegisterEventX2( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + clientID: ::std::os::raw::c_int, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PerGPU_GDEvent_Register( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + clientID: ::std::os::raw::c_int, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_PerGPU_GDEvent_UnRegister( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + clientID: ::std::os::raw::c_int, + eventID: ::std::os::raw::c_int, + evntHandle: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_CurrentActivity_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpActivity: *mut ADLPMActivity, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_ThermalDevices_Enum( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + lpThermalControllerInfo: *mut ADLThermalControllerInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_Temperature_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + lpTemperature: *mut ADLTemperature, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_FanSpeedInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + lpFanSpeedInfo: *mut ADLFanSpeedInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_FanSpeed_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + lpFanSpeedValue: *mut ADLFanSpeedValue, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_FanSpeed_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + lpFanSpeedValue: *mut ADLFanSpeedValue, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_FanSpeedToDefault_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iThermalControllerIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_ODParameters_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOdParameters: *mut ADLODParameters, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_ODPerformanceLevels_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iDefault: ::std::os::raw::c_int, + lpOdPerformanceLevels: *mut ADLODPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_ODPerformanceLevels_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOdPerformanceLevels: *mut ADLODPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_PowerControl_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_PowerControlInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpPowerControlInfo: *mut ADLPowerControlInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_PowerControl_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive5_PowerControl_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSupported: *mut ::std::os::raw::c_int, + iEnabled: *mut ::std::os::raw::c_int, + iVersion: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_Capabilities_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODCapabilities: *mut ADLOD6Capabilities, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_StateInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + lpStateInfo: *mut ADLOD6StateInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_State_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + lpStateInfo: *mut ADLOD6StateInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_State_Reset( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_CurrentStatus_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentStatus: *mut ADLOD6CurrentStatus, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_ThermalController_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpThermalControllerCaps: *mut ADLOD6ThermalControllerCaps, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_Temperature_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpTemperature: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanSpeed_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFanSpeedInfo: *mut ADLOD6FanSpeedInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanSpeed_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFanSpeedValue: *mut ADLOD6FanSpeedValue, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanSpeed_Reset( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_PowerControl_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_PowerControlInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpPowerControlInfo: *mut ADLOD6PowerControlInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_PowerControl_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_PowerControl_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_VoltageControlInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpVoltageControlInfo: *mut ADLOD6VoltageControlInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_VoltageControl_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_VoltageControl_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_CapabilitiesEx_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODCapabilities: *mut ADLOD6CapabilitiesEx, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_StateEx_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + lpODState: *mut ADLOD6StateEx, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_StateEx_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + lpODState: *mut ADLOD6StateEx, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_ThermalLimitUnlock_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + iEnable: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_ThermalLimitUnlock_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStateType: ::std::os::raw::c_int, + pEnabled: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_AdvancedFan_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_TargetTemperatureRangeInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpTargetTemperatureInfo: *mut ADLOD6ParameterRange, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_TargetTemperatureData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_TargetTemperatureData_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iCurrentValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanPWMLimitRangeInfo_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFanPWMLimitInfo: *mut ADLOD6ParameterRange, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanPWMLimitData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FanPWMLimitData_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iCurrentValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_CurrentPower_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iPowerType: ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_ControlI2C( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iControl: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive6_FuzzyController_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_Capabilities_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODCapabilities: *mut ADLODNCapabilities, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_CapabilitiesX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODCapabilities: *mut ADLODNCapabilitiesX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SystemClocks_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SystemClocks_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SystemClocksX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevelsX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SystemClocksX2_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevelsX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryClocksX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevelsX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryClocksX2_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevelsX2, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryClocks_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryClocks_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceLevels: *mut ADLODNPerformanceLevels, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_FanControl_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODFanSpeed: *mut ADLODNFanControl, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_FanControl_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODFanControl: *mut ADLODNFanControl, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_PowerLimit_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPowerLimit: *mut ADLODNPowerLimitSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_PowerLimit_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPowerLimit: *mut ADLODNPowerLimitSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_Temperature_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iTemperatureType: ::std::os::raw::c_int, + iTemperature: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_PerformanceStatus_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODPerformanceStatus: *mut ADLODNPerformanceStatus, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CustomFan_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CustomFan_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODFanControl: *mut ADLODNFanControl, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_CustomFan_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpODFanControl: *mut ADLODNFanControl, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryTimingLevel_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + lpNumberLevels: *mut ::std::os::raw::c_int, + lppLevelList: *mut *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_MemoryTimingLevel_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + currentValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_ZeroRPMFan_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupport: *mut ::std::os::raw::c_int, + lpCurrentValue: *mut ::std::os::raw::c_int, + lpDefaultValue: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_ZeroRPMFan_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + currentValue: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SettingsExt_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverdriveNExtCapabilities: *mut ::std::os::raw::c_int, + lpNumberOfODNExtFeatures: *mut ::std::os::raw::c_int, + lppInitSettingList: *mut *mut ADLODNExtSingleInitSetting, + lppCurrentSettingList: *mut *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SettingsExt_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iNumberOfODNExtFeatures: ::std::os::raw::c_int, + itemValueValidList: *mut ::std::os::raw::c_int, + lpItemValueList: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_AutoWattman_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + lpDefault: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_AutoWattman_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrent: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_AutoWattman_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iCurrent: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_CountOfEvents_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + eventcounterType: ::std::os::raw::c_int, + eventCount: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SCLKAutoOverClock_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpStatus: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_SCLKAutoOverClock_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iStatus: ::std::os::raw::c_int, + iFlags: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_Test_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iEnabled: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_OverdriveN_ThrottleNotification_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpStatus: *mut ::std::os::raw::c_int, + lpThrottleFlags: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Init_Setting_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpInitSetting: *mut ADLOD8InitSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Current_Setting_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpCurrentSetting: *mut ADLOD8CurrentSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Setting_Set( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSetSetting: *mut ADLOD8SetSetting, + lpCurrentSetting: *mut ADLOD8CurrentSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_New_QueryPMLogData_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpDataOutput: *mut ADLPMLogDataOutput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Init_SettingX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpOverdrive8Capabilities: *mut ::std::os::raw::c_int, + lpNumberOfFeatures: *mut ::std::os::raw::c_int, + lppInitSettingList: *mut *mut ADLOD8SingleInitSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Current_SettingX2_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumberOfFeatures: *mut ::std::os::raw::c_int, + lppCurrentSettingList: *mut *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_AutoTuningResult_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpDataOutput: *mut bool, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLogSenorRange_Caps( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumberOfSupportedSensorRange: *mut ::std::os::raw::c_int, + lppSenorRangeCapsList: *mut *mut ADLOD8SingleInitSetting, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLogSenorType_Support_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpNumOfSupportedSensorType: *mut ::std::os::raw::c_int, + lppSenroTypesList: *mut *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLog_ShareMemory_Support( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpSupported: *mut ::std::os::raw::c_int, + option: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLog_ShareMemory_Start( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iSampleRate: ::std::os::raw::c_int, + iNumofPMLogSendorList: ::std::os::raw::c_int, + lpPMLogSendorList: *mut ::std::os::raw::c_int, + lpHDevice: *mut ADL_D3DKMT_HANDLE, + lppSharedMemory: *mut *mut ::std::os::raw::c_void, + iOption: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLog_ShareMemory_Read( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + iNumSensor: ::std::os::raw::c_int, + lpSensorList: *mut ::std::os::raw::c_int, + lppSharedMemory: *mut *mut ::std::os::raw::c_void, + lpDataOutput: *mut ADLPMLogDataOutput, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_PMLog_ShareMemory_Stop( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpHDevice: *mut ADL_D3DKMT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Device_PMLog_Device_Create( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + pDevice: *mut ADL_D3DKMT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Device_PMLog_Device_Destroy( + context: ADL_CONTEXT_HANDLE, + hDevice: ADL_D3DKMT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Overdrive8_Current_SettingX3_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpFeatureNotAdjustableBits: *mut ::std::os::raw::c_int, + lpNumberOfSettings: *mut ::std::os::raw::c_int, + lppCurrentSettingList: *mut *mut ::std::os::raw::c_int, + iOption: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_PMLog_Support_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + pPMLogSupportInfo: *mut ADLPMLogSupportInfo, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_PMLog_Start( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + pPMLogStartInput: *mut ADLPMLogStartInput, + pPMLogStartOutput: *mut ADLPMLogStartOutput, + hDevice: ADL_D3DKMT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_PMLog_Stop( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + hDevice: ADL_D3DKMT_HANDLE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ADL2_Adapter_PMLog_SensorLimits_Get( + context: ADL_CONTEXT_HANDLE, + iAdapterIndex: ::std::os::raw::c_int, + lpDataOutput: *mut ADLPMLogSensorLimits, + ) -> ::std::os::raw::c_int; +} diff --git a/atiadlxx-sys/src/lib.rs b/atiadlxx-sys/src/lib.rs new file mode 100644 index 0000000..40eb178 --- /dev/null +++ b/atiadlxx-sys/src/lib.rs @@ -0,0 +1,5 @@ +#[allow(non_camel_case_types)] +#[allow(non_snake_case)] +#[allow(non_upper_case_globals)] +mod adl; +pub use adl::*; diff --git a/comgr/Cargo.toml b/comgr/Cargo.toml new file mode 100644 index 0000000..68a4a1e --- /dev/null +++ b/comgr/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "comgr" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] + +[dependencies] +libloading = "0.8" +hip_common = { path = "../hip_common" } +itertools = "0.10.5" \ No newline at end of file diff --git a/comgr/README b/comgr/README new file mode 100644 index 0000000..51959b9 --- /dev/null +++ b/comgr/README @@ -0,0 +1 @@ +bindgen .\include\amd_comgr.h --size_t-is-usize --must-use-type "amd_comgr_status_t" --no-layout-tests --no-derive-debug --default-enum-style=newtype --dynamic-loading LibComgr --dynamic-link-require-all -o src/amd_comgr.rs --whitelist-function="^amd_comgr_action_data_get_data$|^amd_comgr_action_info_set_isa_name$|^amd_comgr_action_info_set_option_list$|^amd_comgr_create_action_info$|^amd_comgr_create_data$|^amd_comgr_create_data_set$|^amd_comgr_data_set_add$|^amd_comgr_destroy_action_info$|^amd_comgr_destroy_data_set$|^amd_comgr_do_action$|^amd_comgr_get_data$|^amd_comgr_release_data$|^amd_comgr_set_data$|^amd_comgr_set_data_name$|^amd_comgr_action_info_set_language$|^amd_comgr_set_data_name$" diff --git a/comgr/include/amd_comgr.h b/comgr/include/amd_comgr.h new file mode 100644 index 0000000..1727e38 --- /dev/null +++ b/comgr/include/amd_comgr.h @@ -0,0 +1,2344 @@ +/******************************************************************************* +* +* University of Illinois/NCSA +* Open Source License +* +* Copyright (c) 2018 Advanced Micro Devices, Inc. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* with 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: +* +* * Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimers. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimers in the +* documentation and/or other materials provided with the distribution. +* +* * Neither the names of Advanced Micro Devices, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from +* this Software without specific prior written permission. +* +* 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 +* CONTRIBUTORS 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 WITH +* THE SOFTWARE. +* +*******************************************************************************/ + +#ifndef AMD_COMGR_H_ +#define AMD_COMGR_H_ + +#include /* size_t */ +#include + +#ifndef __cplusplus +#include /* bool */ +#endif /* __cplusplus */ + +/* Placeholder for calling convention and import/export macros */ +#ifndef AMD_COMGR_CALL +#define AMD_COMGR_CALL +#endif + +#ifndef AMD_COMGR_EXPORT_DECORATOR +#ifdef __GNUC__ +#define AMD_COMGR_EXPORT_DECORATOR __attribute__ ((visibility ("default"))) +#else +#define AMD_COMGR_EXPORT_DECORATOR __declspec(dllexport) +#endif +#endif + +#ifndef AMD_COMGR_IMPORT_DECORATOR +#ifdef __GNUC__ +#define AMD_COMGR_IMPORT_DECORATOR +#else +#define AMD_COMGR_IMPORT_DECORATOR __declspec(dllimport) +#endif +#endif + +#define AMD_COMGR_API_EXPORT AMD_COMGR_EXPORT_DECORATOR AMD_COMGR_CALL +#define AMD_COMGR_API_IMPORT AMD_COMGR_IMPORT_DECORATOR AMD_COMGR_CALL + +#ifndef AMD_COMGR_API +#ifdef AMD_COMGR_EXPORT +#define AMD_COMGR_API AMD_COMGR_API_EXPORT +#else +#define AMD_COMGR_API AMD_COMGR_API_IMPORT +#endif +#endif + +#define AMD_COMGR_INTERFACE_VERSION_MAJOR @amd_comgr_VERSION_MAJOR@ +#define AMD_COMGR_INTERFACE_VERSION_MINOR @amd_comgr_VERSION_MINOR@ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** \defgroup codeobjectmanager Code Object Manager + * @{ + * + * @brief The code object manager is a callable library that provides + * operations for creating and inspecting code objects. + * + * The library provides handles to various objects. Concurrent execution of + * operations is supported provided all objects accessed by each concurrent + * operation are disjoint. For example, the @p amd_comgr_data_set_t handles + * passed to operations must be disjoint, together with all the @p + * amd_comgr_data_t handles that have been added to it. The exception is that + * the default device library data object handles can be non-disjoint as they + * are imutable. + * + * The library supports generating and inspecting code objects that + * contain machine code for a certain set of instruction set + * arhitectures (isa). The set of isa supported and information about + * the properties of the isa can be queried. + * + * The library supports performing an action that can take data + * objects of one kind, and generate new data objects of another kind. + * + * Data objects are referenced using handles using @p + * amd_comgr_data_t. The kinds of data objects are given + * by @p amd_comgr_data_kind_t. + * + * To perform an action, two @p amd_comgr_data_set_t + * objects are created. One is used to hold all the data objects + * needed by an action, and other is updated by the action with all + * the result data objects. In addition, an @p + * amd_comgr_action_info_t is created to hold + * information that controls the action. These are then passed to @p + * amd_comgr_do_action to perform an action specified by + * @p amd_comgr_action_kind_t. + * + * Some data objects can have associated metadata. There are + * operations for querying this metadata. + * + * The default device library that satisfies the requirements of the + * compiler action can be obtained. + * + * The library inspects some environment variables to aid in debugging. These + * include: + * - @p AMD_COMGR_SAVE_TEMPS: If this is set, and is not "0", the library does + * not delete temporary files generated while executing compilation actions. + * These files do not appear in the current working directory, but are + * instead left in a platform-specific temporary directory (/tmp on Linux and + * C:\Temp or the path found in the TEMP environment variable on Windows). + * - @p AMD_COMGR_REDIRECT_LOGS: If this is not set, or is set to "0", logs are + * returned to the caller as normal. If this is set to "stdout"/"-" or + * "stderr", logs are instead redirected to the standard output or error + * stream, respectively. If this is set to any other value, it is interpreted + * as a filename which logs should be appended to. Logs may be redirected + * irrespective of whether logging is enabled. + * - @p AMD_COMGR_EMIT_VERBOSE_LOGS: If this is set, and is not "0", logs will + * include additional Comgr-specific informational messages. + */ + + +/** \defgroup symbol_versions_group Symbol Versions + * + * The names used for the shared library versioned symbols. + * + * Every function is annotated with one of the version macros defined in this + * section. Each macro specifies a corresponding symbol version string. After + * dynamically loading the shared library with \p dlopen, the address of each + * function can be obtained using \p dlvsym with the name of the function and + * its corresponding symbol version string. An error will be reported by \p + * dlvsym if the installed library does not support the version for the + * function specified in this version of the interface. + * + * @{ + */ + +/** + * The function was introduced in version 1.8 of the interface and has the + * symbol version string of ``"@amd_comgr_NAME@_1.8"``. + */ +#define AMD_COMGR_VERSION_1_8 + +/** + * The function was introduced or changed in version 2.0 of the interface + * and has the symbol version string of ``"@amd_comgr_NAME@_2.0"``. + */ +#define AMD_COMGR_VERSION_2_0 + +/** + * The function was introduced or changed in version 2.2 of the interface + * and has the symbol version string of ``"@amd_comgr_NAME@_2.2"``. + */ +#define AMD_COMGR_VERSION_2_2 + +/** + * The function was introduced or changed in version 2.3 of the interface + * and has the symbol version string of ``"@amd_comgr_NAME@_2.3"``. + */ +#define AMD_COMGR_VERSION_2_3 + +/** + * The function was introduced or changed in version 2.4 of the interface + * and has the symbol version string of ``"@amd_comgr_NAME@_2.4"``. + */ +#define AMD_COMGR_VERSION_2_4 + +/** @} */ + +/** + * @brief Status codes. + */ +typedef enum amd_comgr_status_s { + /** + * The function has been executed successfully. + */ + AMD_COMGR_STATUS_SUCCESS = 0x0, + /** + * A generic error has occurred. + */ + AMD_COMGR_STATUS_ERROR = 0x1, + /** + * One of the actual arguments does not meet a precondition stated + * in the documentation of the corresponding formal argument. + */ + AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT = 0x2, + /** + * Failed to allocate the necessary resources. + */ + AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES = 0x3, +} amd_comgr_status_t; + +/** + * @brief The source languages supported by the compiler. + */ +typedef enum amd_comgr_language_s { + /** + * No high level language. + */ + AMD_COMGR_LANGUAGE_NONE = 0x0, + /** + * OpenCL 1.2. + */ + AMD_COMGR_LANGUAGE_OPENCL_1_2 = 0x1, + /** + * OpenCL 2.0. + */ + AMD_COMGR_LANGUAGE_OPENCL_2_0 = 0x2, + /** + * AMD Hetrogeneous C++ (HC). + */ + AMD_COMGR_LANGUAGE_HC = 0x3, + /** + * HIP. + */ + AMD_COMGR_LANGUAGE_HIP = 0x4, + /** + * Marker for last valid language. + */ + AMD_COMGR_LANGUAGE_LAST = AMD_COMGR_LANGUAGE_HIP +} amd_comgr_language_t; + +/** + * @brief Query additional information about a status code. + * + * @param[in] status Status code. + * + * @param[out] status_string A NUL-terminated string that describes + * the error status. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * status is an invalid status code, or @p status_string is NULL. + */ +amd_comgr_status_t AMD_COMGR_API amd_comgr_status_string( + amd_comgr_status_t status, + const char ** status_string) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the version of the code object manager interface + * supported. + * + * An interface is backwards compatible with an implementation with an + * equal major version, and a greater than or equal minor version. + * + * @param[out] major Major version number. + * + * @param[out] minor Minor version number. + */ +void AMD_COMGR_API amd_comgr_get_version( + size_t *major, + size_t *minor) AMD_COMGR_VERSION_1_8; + +/** + * @brief The kinds of data supported. + */ +typedef enum amd_comgr_data_kind_s { + /** + * No data is available. + */ + AMD_COMGR_DATA_KIND_UNDEF = 0x0, + /** + * The data is a textual main source. + */ + AMD_COMGR_DATA_KIND_SOURCE = 0x1, + /** + * The data is a textual source that is included in the main source + * or other include source. + */ + AMD_COMGR_DATA_KIND_INCLUDE = 0x2, + /** + * The data is a precompiled-header source that is included in the main + * source or other include source. + */ + AMD_COMGR_DATA_KIND_PRECOMPILED_HEADER = 0x3, + /** + * The data is a diagnostic output. + */ + AMD_COMGR_DATA_KIND_DIAGNOSTIC = 0x4, + /** + * The data is a textual log output. + */ + AMD_COMGR_DATA_KIND_LOG = 0x5, + /** + * The data is compiler LLVM IR bit code for a specific isa. + */ + AMD_COMGR_DATA_KIND_BC = 0x6, + /** + * The data is a relocatable machine code object for a specific isa. + */ + AMD_COMGR_DATA_KIND_RELOCATABLE = 0x7, + /** + * The data is an executable machine code object for a specific + * isa. An executable is the kind of code object that can be loaded + * and executed. + */ + AMD_COMGR_DATA_KIND_EXECUTABLE = 0x8, + /** + * The data is a block of bytes. + */ + AMD_COMGR_DATA_KIND_BYTES = 0x9, + /** + * The data is a fat binary (clang-offload-bundler output). + */ + AMD_COMGR_DATA_KIND_FATBIN = 0x10, + /** + * Marker for last valid data kind. + */ + AMD_COMGR_DATA_KIND_LAST = AMD_COMGR_DATA_KIND_FATBIN +} amd_comgr_data_kind_t; + +/** + * @brief A handle to a data object. + * + * Data objects are used to hold the data which is either an input or + * output of a code object manager action. + */ +typedef struct amd_comgr_data_s { + uint64_t handle; +} amd_comgr_data_t; + +/** + * @brief A handle to an action data object. + * + * An action data object holds a set of data objects. These can be + * used as inputs to an action, or produced as the result of an + * action. + */ +typedef struct amd_comgr_data_set_s { + uint64_t handle; +} amd_comgr_data_set_t; + +/** + * @brief A handle to an action information object. + * + * An action information object holds all the necessary information, + * excluding the input data objects, required to perform an action. + */ +typedef struct amd_comgr_action_info_s { + uint64_t handle; +} amd_comgr_action_info_t; + +/** + * @brief A handle to a metadata node. + * + * A metadata node handle is used to traverse the metadata associated + * with a data node. + */ +typedef struct amd_comgr_metadata_node_s { + uint64_t handle; +} amd_comgr_metadata_node_t; + +/** + * @brief A handle to a machine code object symbol. + * + * A symbol handle is used to obtain the properties of symbols of a machine code + * object. A symbol handle is invalidated when the data object containing the + * symbol is destroyed. + */ +typedef struct amd_comgr_symbol_s { + uint64_t handle; +} amd_comgr_symbol_t; + +/** + * @brief A handle to a disassembly information object. + * + * A disassembly information object holds all the necessary information, + * excluding the input data, required to perform disassembly. + */ +typedef struct amd_comgr_disassembly_info_s { + uint64_t handle; +} amd_comgr_disassembly_info_t; + +/** + * @brief A handle to a symbolizer information object. + * + * A symbolizer information object holds all the necessary information + * required to perform symbolization. + */ +typedef struct amd_comgr_symbolizer_info_s { + uint64_t handle; +} amd_comgr_symbolizer_info_t; + +/** + * @brief Return the number of isa names supported by this version of + * the code object manager library. + * + * The isa name specifies the instruction set architecture that should + * be used in the actions that involve machine code generation or + * inspection. + * + * @param[out] count The number of isa names supported. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * count is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_isa_count( + size_t *count) AMD_COMGR_VERSION_2_0; + +/** + * @brief Return the Nth isa name supported by this version of the + * code object manager library. + * + * @param[in] index The index of the isa name to be returned. The + * first isa name is index 0. + * + * @param[out] isa_name A null terminated string that is the isa name + * being requested. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * index is greater than the number of isa name supported by this + * version of the code object manager library. @p isa_name is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_isa_name( + size_t index, + const char **isa_name) AMD_COMGR_VERSION_2_0; + + /** + * @brief Get a handle to the metadata of an isa name. + * + * The structure of the returned metadata is isa name specific and versioned + * with details specified in README.md. It can include information about the + * limits for resources such as registers and memory addressing. + * + * @param[in] isa_name The isa name to query. + * + * @param[out] metadata A handle to the metadata of the isa name. If + * the isa name has no metadata then the returned handle has a kind of + * @p AMD_COMGR_METADATA_KIND_NULL. The handle must be destroyed + * using @c amd_comgr_destroy_metadata. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * name is NULL or is not an isa name supported by this version of the + * code object manager library. @p metadata is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_isa_metadata( + const char *isa_name, + amd_comgr_metadata_node_t *metadata) AMD_COMGR_VERSION_2_0; + +/** + * @brief Create a data object that can hold data of a specified kind. + * + * Data objects are reference counted and are destroyed when the + * reference count reaches 0. When a data object is created its + * reference count is 1, it has 0 bytes of data, it has an empty name, + * and it has no metadata. + * + * @param[in] kind The kind of data the object is intended to hold. + * + * @param[out] data A handle to the data object created. Its reference + * count is set to 1. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * kind is an invalid data kind, or @p + * AMD_COMGR_DATA_KIND_UNDEF. @p data is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to create the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_create_data( + amd_comgr_data_kind_t kind, + amd_comgr_data_t *data) AMD_COMGR_VERSION_1_8; + + /** + * @brief Indicate that no longer using a data object handle. + * + * The reference count of the associated data object is + * decremented. If it reaches 0 it is destroyed. + * + * @param[in] data The data object to release. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_release_data( + amd_comgr_data_t data) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the kind of the data object. + * + * @param[in] data The data object to query. + * + * @param[out] kind The kind of data the object. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object. @p kind is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to create the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_data_kind( + amd_comgr_data_t data, + amd_comgr_data_kind_t *kind) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set the data content of a data object to the specified + * bytes. + * + * Any previous value of the data object is overwritten. Any metadata + * associated with the data object is also replaced which invalidates + * all metadata handles to the old metadata. + * + * @param[in] data The data object to update. + * + * @param[in] size The number of bytes in the data specified by @p bytes. + * + * @param[in] bytes The bytes to set the data object to. The bytes are + * copied into the data object and can be freed after the call. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_set_data( + amd_comgr_data_t data, + size_t size, + const char* bytes) AMD_COMGR_VERSION_1_8; + +/** + * @brief For the given open posix file descriptor, map a slice of the + * file into the data object. The slice is specified by @p offset and @p size. + * Internally this API calls amd_comgr_set_data and resets data object's + * current state. + * + * @param[in, out] data The data object to update. + * + * @param[in] file_descriptor The native file descriptor for an open file. + * The @p file_descriptor must not be passed into a system I/O function + * by any other thread while this function is executing. The offset in + * the file descriptor may be updated based on the requested size and + * underlying platform. The @p file_descriptor may be closed immediately + * after this function returns. + * + * @param[in] offset position relative to the start of the file + * specifying the beginning of the slice in @p file_descriptor. + * + * @param[in] size Size in bytes of the slice. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The operation is successful. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid or + * the map operation failed. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_set_data_from_file_slice( + amd_comgr_data_t data, + int file_descriptor, + uint64_t offset, + uint64_t size) AMD_COMGR_VERSION_2_3; + +/** + * @brief Set the name associated with a data object. + * + * When compiling, the fle name of an include directive is used to + * reference the contents of the include data object with the same + * name. The name may also be used for other data objects in log and + * diagnostic output. + * + * @param[in] data The data object to update. + * + * @param[in] name A null terminated string that specifies the name to + * use for the data object. If NULL then the name is set to the empty + * string. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_set_data_name( + amd_comgr_data_t data, + const char* name) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the data contents, and/or the size of the data + * associated with a data object. + * + * @param[in] data The data object to query. + * + * @param[in, out] size On entry, the size of @p bytes. On return, if @p bytes + * is NULL, set to the size of the data object contents. + * + * @param[out] bytes If not NULL, then the first @p size bytes of the + * data object contents is copied. If NULL, no data is copied, and + * only @p size is updated (useful in order to find the size of buffer + * required to copy the data). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_data( + amd_comgr_data_t data, + size_t *size, + char *bytes) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the data object name and/or name length. + * + * @param[in] data The data object to query. + * + * @param[in, out] size On entry, the size of @p name. On return, the size of + * the data object name including the terminating null character. + * + * @param[out] name If not NULL, then the first @p size characters of the + * data object name are copied. If @p name is NULL, only @p size is updated + * (useful in order to find the size of buffer required to copy the name). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_data_name( + amd_comgr_data_t data, + size_t *size, + char *name) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the data object isa name and/or isa name length. + * + * @param[in] data The data object to query. + * + * @param[in, out] size On entry, the size of @p isa_name. On return, if @p + * isa_name is NULL, set to the size of the isa name including the terminating + * null character. + * + * @param[out] isa_name If not NULL, then the first @p size characters + * of the isa name are copied. If NULL, no isa name is copied, and + * only @p size is updated (useful in order to find the size of buffer + * required to copy the isa name). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, has kind @p + * AMD_COMGR_DATA_KIND_UNDEF, or is not an isa specific + * kind. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_data_isa_name( + amd_comgr_data_t data, + size_t *size, + char *isa_name) AMD_COMGR_VERSION_2_0; + +/** + * @brief Create a symbolizer info object. + * + * @param[in] code_object A data object denoting a code object for which + * symbolization should be performed. The kind of this object must be + * ::AMD_COMGR_DATA_KIND_RELOCATABLE, ::AMD_COMGR_DATA_KIND_EXECUTABLE, + * or ::AMD_COMGR_DATA_KIND_BYTES. + * + * @param[in] print_symbol_callback Function called by a successfull + * symbolize query. @p symbol is a null-terminated string containing the + * symbolization of the address and @p user_data is an arbitary user data. + * The callback does not own @p symbol, and it cannot be referenced once + * the callback returns. + * + * @param[out] symbolizer_info A handle to the symbolizer info object created. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if @p code_object is + * invalid or @p print_symbol_callback is null. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to create @p symbolizer_info as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_create_symbolizer_info( + amd_comgr_data_t code_object, + void (*print_symbol_callback)( + const char *symbol, + void *user_data), + amd_comgr_symbolizer_info_t *symbolizer_info) AMD_COMGR_VERSION_2_4; + +/** + * @brief Destroy symbolizer info object. + * + * @param[in] symbolizer_info A handle to symbolizer info object to destroy. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS on successful execution. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if @p + * symbolizer_info is invalid. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_destroy_symbolizer_info( + amd_comgr_symbolizer_info_t symbolizer_info) AMD_COMGR_VERSION_2_4; + +/** + * @brief Symbolize an address. + * + * The @p address is symbolized using the symbol definitions of the + * @p code_object specified when the @p symbolizer_info was created. + * The @p print_symbol_callback callback function specified when the + * @p symbolizer_info was created is called passing the + * symbolization result as @p symbol and @p user_data value. + * + * If symbolization is not possible ::AMD_COMGR_STATUS_SUCCESS is returned and + * the string passed to the @p symbol argument of the @p print_symbol_callback + * specified when the @p symbolizer_info was created contains the text + * "" or "??". This is consistent with `llvm-symbolizer` utility. + * + * @param[in] symbolizer_info A handle to symbolizer info object which should be + * used to symbolize the @p address. + * + * @param[in] address An unrelocated ELF address to which symbolization + * query should be performed. + * + * @param[in] is_code if true, the symbolizer symbolize the address as code + * and the symbolization result contains filename, function name, line number + * and column number, else the symbolizer symbolize the address as data and + * the symbolizaion result contains symbol name, symbol's starting address + * and symbol size. + * + * @param[in] user_data Arbitrary user-data passed to @p print_symbol_callback + * callback as described for @p symbolizer_info argument. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * symbolizer_info is an invalid data object. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_symbolize( + amd_comgr_symbolizer_info_t symbolizer_info, + uint64_t address, + bool is_code, + void *user_data) AMD_COMGR_VERSION_2_4; + + /** + * @brief Get a handle to the metadata of a data object. + * + * @param[in] data The data object to query. + * + * @param[out] metadata A handle to the metadata of the data + * object. If the data object has no metadata then the returned handle + * has a kind of @p AMD_COMGR_METADATA_KIND_NULL. The + * handle must be destroyed using @c amd_comgr_destroy_metadata. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * data is an invalid data object, or has kind @p + * AMD_COMGR_DATA_KIND_UNDEF. @p metadata is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_data_metadata( + amd_comgr_data_t data, + amd_comgr_metadata_node_t *metadata) AMD_COMGR_VERSION_1_8; + +/** + * @brief Destroy a metadata handle. + * + * @param[in] metadata A metadata handle to destroy. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p metadata is an invalid + * metadata handle. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update metadata + * handle as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_destroy_metadata(amd_comgr_metadata_node_t metadata) AMD_COMGR_VERSION_1_8; + +/** + * @brief Create a data set object. + * + * @param[out] data_set A handle to the data set created. Initially it + * contains no data objects. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to create the data + * set object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_create_data_set( + amd_comgr_data_set_t *data_set) AMD_COMGR_VERSION_1_8; + +/** + * @brief Destroy a data set object. + * + * The reference counts of any associated data objects are decremented. Any + * handles to the data set object become invalid. + * + * @param[in] data_set A handle to the data set object to destroy. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid + * data set object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_destroy_data_set( + amd_comgr_data_set_t data_set) AMD_COMGR_VERSION_1_8; + +/** + * @brief Add a data object to a data set object if it is not already added. + * + * The reference count of the data object is incremented. + * + * @param[in] data_set A handle to the data set object to be updated. + * + * @param[in] data A handle to the data object to be added. If @p data_set + * already has the specified handle present, then it is not added. The order + * that data objects are added is preserved. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid + * data set object. @p data is an invalid data object; has undef kind; has + * include kind but does not have a name. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_data_set_add( + amd_comgr_data_set_t data_set, + amd_comgr_data_t data) AMD_COMGR_VERSION_1_8; + +/** + * @brief Remove all data objects of a specified kind from a data set object. + * + * The reference count of the removed data objects is decremented. + * + * @param[in] data_set A handle to the data set object to be updated. + * + * @param[in] data_kind The data kind of the data objects to be removed. If @p + * AMD_COMGR_DATA_KIND_UNDEF is specified then all data objects are removed. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid + * data set object. @p data_kind is an invalid data kind. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_data_set_remove( + amd_comgr_data_set_t data_set, + amd_comgr_data_kind_t data_kind) AMD_COMGR_VERSION_1_8; + +/** + * @brief Return the number of data objects of a specified data kind that are + * added to a data set object. + * + * @param[in] data_set A handle to the data set object to be queried. + * + * @param[in] data_kind The data kind of the data objects to be counted. + * + * @param[out] count The number of data objects of data kind @p data_kind. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid + * data set object. @p data_kind is an invalid data kind or @p + * AMD_COMGR_DATA_KIND_UNDEF. @p count is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query data set + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_data_count( + amd_comgr_data_set_t data_set, + amd_comgr_data_kind_t data_kind, + size_t *count) AMD_COMGR_VERSION_1_8; + +/** + * @brief Return the Nth data object of a specified data kind that is added to a + * data set object. + * + * The reference count of the returned data object is incremented. + * + * @param[in] data_set A handle to the data set object to be queried. + * + * @param[in] data_kind The data kind of the data object to be returned. + * + * @param[in] index The index of the data object of data kind @data_kind to be + * returned. The first data object is index 0. The order of data objects matches + * the order that they were added to the data set object. + * + * @param[out] data The data object being requested. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid + * data set object. @p data_kind is an invalid data kind or @p + * AMD_COMGR_DATA_KIND_UNDEF. @p index is greater than the number of data + * objects of kind @p data_kind. @p data is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query data set + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_data_get_data( + amd_comgr_data_set_t data_set, + amd_comgr_data_kind_t data_kind, + size_t index, + amd_comgr_data_t *data) AMD_COMGR_VERSION_1_8; + +/** + * @brief Create an action info object. + * + * @param[out] action_info A handle to the action info object created. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to create the action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_create_action_info( + amd_comgr_action_info_t *action_info) AMD_COMGR_VERSION_1_8; + +/** + * @brief Destroy an action info object. + * + * @param[in] action_info A handle to the action info object to destroy. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_destroy_action_info( + amd_comgr_action_info_t action_info) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set the isa name of an action info object. + * + * When an action info object is created it has no isa name. Some + * actions require that the action info object has an isa name + * defined. + * + * @param[in] action_info A handle to the action info object to be + * updated. + * + * @param[in] isa_name A null terminated string that is the isa name. If NULL + * or the empty string then the isa name is cleared. The isa name is defined as + * the Code Object Target Identification string, described at + * https://llvm.org/docs/AMDGPUUsage.html#code-object-target-identification + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p isa_name is not an + * isa name supported by this version of the code object manager + * library. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_isa_name( + amd_comgr_action_info_t action_info, + const char *isa_name) AMD_COMGR_VERSION_2_0; + +/** + * @brief Get the isa name and/or isa name length. + * + * @param[in] action_info The action info object to query. + * + * @param[in, out] size On entry, the size of @p isa_name. On return, if @p + * isa_name is NULL, set to the size of the isa name including the terminating + * null character. + * + * @param[out] isa_name If not NULL, then the first @p size characters of the + * isa name are copied into @p isa_name. If the isa name is not set then an + * empty string is copied into @p isa_name. If NULL, no name is copied, and + * only @p size is updated (useful in order to find the size of buffer required + * to copy the name). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_isa_name( + amd_comgr_action_info_t action_info, + size_t *size, + char *isa_name) AMD_COMGR_VERSION_2_0; + +/** + * @brief Set the source language of an action info object. + * + * When an action info object is created it has no language defined + * which is represented by @p + * AMD_COMGR_LANGUAGE_NONE. Some actions require that + * the action info object has a source language defined. + * + * @param[in] action_info A handle to the action info object to be + * updated. + * + * @param[in] language The language to set. If @p + * AMD_COMGR_LANGUAGE_NONE then the language is cleared. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p language is an + * invalid language. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_language( + amd_comgr_action_info_t action_info, + amd_comgr_language_t language) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the language for an action info object. + * + * @param[in] action_info The action info object to query. + * + * @param[out] language The language of the action info opject. @p + * AMD_COMGR_LANGUAGE_NONE if not defined, + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p language is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_language( + amd_comgr_action_info_t action_info, + amd_comgr_language_t *language) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set the options string of an action info object. + * + * When an action info object is created it has an empty options string. + * + * This overrides any option strings or arrays previously set by calls to this + * function or @p amd_comgr_action_info_set_option_list. + * + * An @p action_info object which had its options set with this function can + * only have its option inspected with @p amd_comgr_action_info_get_options. + * + * @param[in] action_info A handle to the action info object to be + * updated. + * + * @param[in] options A null terminated string that is the options. If + * NULL or the empty string then the options are cleared. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + * + * @deprecated since 1.3 + * @see amd_comgr_action_info_set_option_list + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_options( + amd_comgr_action_info_t action_info, + const char *options) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the options string and/or options strings length of an action + * info object. + * + * The @p action_info object must have had its options set with @p + * amd_comgr_action_info_set_options. + * + * @param[in] action_info The action info object to query. + * + * @param[in, out] size On entry, the size of @p options. On return, if @p + * options is NULL, set to the size of the options including the terminating + * null character. + * + * @param[out] options If not NULL, then the first @p size characters of + * the options are copied. If the options are not set then an empty + * string is copied. If NULL, options is not copied, and only @p size + * is updated (useful inorder to find the size of buffer required to + * copy the options). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were not set + * with @p amd_comgr_action_info_set_options. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + * + * @deprecated since 1.3 + * @see amd_comgr_action_info_get_option_list_count and + * amd_comgr_action_info_get_option_list_item + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_options( + amd_comgr_action_info_t action_info, + size_t *size, + char *options) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set the options array of an action info object. + * + * This overrides any option strings or arrays previously set by calls to this + * function or @p amd_comgr_action_info_set_options. + * + * An @p action_info object which had its options set with this function can + * only have its option inspected with @p + * amd_comgr_action_info_get_option_list_count and @p + * amd_comgr_action_info_get_option_list_item. + * + * @param[in] action_info A handle to the action info object to be updated. + * + * @param[in] options An array of null terminated strings. May be NULL if @p + * count is zero, which will result in an empty options array. + * + * @param[in] count The number of null terminated strings in @p options. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an + * invalid action info object, or @p options is NULL and @p count is non-zero. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update action + * info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_option_list( + amd_comgr_action_info_t action_info, + const char *options[], + size_t count) AMD_COMGR_VERSION_1_8; + +/** + * @brief Return the number of options in the options array. + * + * The @p action_info object must have had its options set with @p + * amd_comgr_action_info_set_option_list. + * + * @param[in] action_info The action info object to query. + * + * @param[out] count The number of options in the options array. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were never + * set, or not set with @p amd_comgr_action_info_set_option_list. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an + * invalid action info object, or @p count is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query the data + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_option_list_count( + amd_comgr_action_info_t action_info, + size_t *count) AMD_COMGR_VERSION_1_8; + +/** + * @brief Return the Nth option string in the options array and/or that + * option's length. + * + * The @p action_info object must have had its options set with @p + * amd_comgr_action_info_set_option_list. + * + * @param[in] action_info The action info object to query. + * + * @param[in] index The index of the option to be returned. The first option + * index is 0. The order is the same as the options when they were added in @p + * amd_comgr_action_info_set_options. + * + * @param[in, out] size On entry, the size of @p option. On return, if @option + * is NULL, set to the size of the Nth option string including the terminating + * null character. + * + * @param[out] option If not NULL, then the first @p size characters of the Nth + * option string are copied into @p option. If NULL, no option string is + * copied, and only @p size is updated (useful in order to find the size of + * buffer required to copy the option string). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were never + * set, or not set with @p amd_comgr_action_info_set_option_list. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an + * invalid action info object, @p index is invalid, or @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query the data + * object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_option_list_item( + amd_comgr_action_info_t action_info, + size_t index, + size_t *size, + char *option) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set the working directory of an action info object. + * + * When an action info object is created it has an empty working + * directory. Some actions use the working directory to resolve + * relative file paths. + * + * @param[in] action_info A handle to the action info object to be + * updated. + * + * @param[in] path A null terminated string that is the working + * directory path. If NULL or the empty string then the working + * directory is cleared. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_working_directory_path( + amd_comgr_action_info_t action_info, + const char *path) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the working directory path and/or working directory path + * length of an action info object. + * + * @param[in] action_info The action info object to query. + * + * @param[in, out] size On entry, the size of @p path. On return, if @p path is + * NULL, set to the size of the working directory path including the + * terminating null character. + * + * @param[out] path If not NULL, then the first @p size characters of + * the working directory path is copied. If the working directory path + * is not set then an empty string is copied. If NULL, the working + * directory path is not copied, and only @p size is updated (useful + * in order to find the size of buffer required to copy the working + * directory path). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_working_directory_path( + amd_comgr_action_info_t action_info, + size_t *size, + char *path) AMD_COMGR_VERSION_1_8; + +/** + * @brief Set whether logging is enabled for an action info object. + * + * @param[in] action_info A handle to the action info object to be + * updated. + * + * @param[in] logging Whether logging should be enabled or disable. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_set_logging( + amd_comgr_action_info_t action_info, + bool logging) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get whether logging is enabled for an action info object. + * + * @param[in] action_info The action info object to query. + * + * @param[out] logging Whether logging is enabled. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * action_info is an invalid action info object. @p logging is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_action_info_get_logging( + amd_comgr_action_info_t action_info, + bool *logging) AMD_COMGR_VERSION_1_8; + +/** + * @brief The kinds of actions that can be performed. + */ +typedef enum amd_comgr_action_kind_s { + /** + * Preprocess each source data object in @p input in order. For each + * successful preprocessor invocation, add a source data object to @p result. + * Resolve any include source names using the names of include data objects + * in @p input. Resolve any include relative path names using the working + * directory path in @p info. Preprocess the source for the language in @p + * info. + * + * Return @p AMD_COMGR_STATUS_ERROR if any preprocessing fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name or language is not set in @p info. + */ + AMD_COMGR_ACTION_SOURCE_TO_PREPROCESSOR = 0x0, + /** + * Copy all existing data objects in @p input to @p output, then add the + * device-specific and language-specific precompiled headers required for + * compilation. + * + * Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2 + * and @p AMD_COMGR_LANGUAGE_OPENCL_2_0. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language + * is not set in @p info, or the language is not supported. + */ + AMD_COMGR_ACTION_ADD_PRECOMPILED_HEADERS = 0x1, + /** + * Compile each source data object in @p input in order. For each + * successful compilation add a bc data object to @p result. Resolve + * any include source names using the names of include data objects + * in @p input. Resolve any include relative path names using the + * working directory path in @p info. Produce bc for isa name in @p + * info. Compile the source for the language in @p info. + * + * Return @p AMD_COMGR_STATUS_ERROR if any compilation + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name or language is not set in @p info. + */ + AMD_COMGR_ACTION_COMPILE_SOURCE_TO_BC = 0x2, + /** + * Copy all existing data objects in @p input to @p output, then add the + * device-specific and language-specific bitcode libraries required for + * compilation. + * + * Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2, + * @p AMD_COMGR_LANGUAGE_OPENCL_2_0, and @p AMD_COMGR_LANGUAGE_HIP. + * + * The options in @p info should be set to a set of language-specific flags. + * For OpenCL and HIP these include: + * + * correctly_rounded_sqrt + * daz_opt + * finite_only + * unsafe_math + * wavefrontsize64 + * + * For example, to enable daz_opt and unsafe_math, the options should be set + * as: + * + * const char *options[] = {"daz_opt, "unsafe_math"}; + * size_t optionsCount = sizeof(options) / sizeof(options[0]); + * amd_comgr_action_info_set_option_list(info, options, optionsCount); + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language + * is not set in @p info, the language is not supported, an unknown + * language-specific flag is supplied, or a language-specific flag is + * repeated. + * + * @deprecated since 1.7 + * @warning This action, followed by @c AMD_COMGR_ACTION_LINK_BC_TO_BC, may + * result in subtle bugs due to incorrect linking of the device libraries. + * The @c AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC action can + * be used as a workaround which ensures the link occurs correctly. + */ + AMD_COMGR_ACTION_ADD_DEVICE_LIBRARIES = 0x3, + /** + * Link each bc data object in @p input together and add the linked + * bc data object to @p result. Any device library bc data object + * must be explicitly added to @p input if needed. + * + * Return @p AMD_COMGR_STATUS_ERROR if the link fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all bc data objects in @p input. + */ + AMD_COMGR_ACTION_LINK_BC_TO_BC = 0x4, + /** + * Optimize each bc data object in @p input and create an optimized bc data + * object to @p result. + * + * Return @p AMD_COMGR_STATUS_ERROR if the optimization fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all bc data objects in @p input. + */ + AMD_COMGR_ACTION_OPTIMIZE_BC_TO_BC = 0x5, + /** + * Perform code generation for each bc data object in @p input in + * order. For each successful code generation add a relocatable data + * object to @p result. + * + * Return @p AMD_COMGR_STATUS_ERROR if any code + * generation fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all bc data objects in @p input. + */ + AMD_COMGR_ACTION_CODEGEN_BC_TO_RELOCATABLE = 0x6, + /** + * Perform code generation for each bc data object in @p input in + * order. For each successful code generation add an assembly source data + * object to @p result. + * + * Return @p AMD_COMGR_STATUS_ERROR if any code + * generation fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all bc data objects in @p input. + */ + AMD_COMGR_ACTION_CODEGEN_BC_TO_ASSEMBLY = 0x7, + /** + * Link each relocatable data object in @p input together and add + * the linked relocatable data object to @p result. Any device + * library relocatable data object must be explicitly added to @p + * input if needed. + * + * Return @p AMD_COMGR_STATUS_ERROR if the link fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all relocatable data objects in @p input. + */ + AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_RELOCATABLE = 0x8, + /** + * Link each relocatable data object in @p input together and add + * the linked executable data object to @p result. Any device + * library relocatable data object must be explicitly added to @p + * input if needed. + * + * Return @p AMD_COMGR_STATUS_ERROR if the link fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all relocatable data objects in @p input. + */ + AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_EXECUTABLE = 0x9, + /** + * Assemble each source data object in @p input in order into machine code. + * For each successful assembly add a relocatable data object to @p result. + * Resolve any include source names using the names of include data objects in + * @p input. Resolve any include relative path names using the working + * directory path in @p info. Produce relocatable for isa name in @p info. + * + * Return @p AMD_COMGR_STATUS_ERROR if any assembly fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name is not set in + * @p info. + */ + AMD_COMGR_ACTION_ASSEMBLE_SOURCE_TO_RELOCATABLE = 0xA, + /** + * Disassemble each relocatable data object in @p input in + * order. For each successful disassembly add a source data object to + * @p result. + * + * Return @p AMD_COMGR_STATUS_ERROR if any disassembly + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all relocatable data objects in @p input. + */ + AMD_COMGR_ACTION_DISASSEMBLE_RELOCATABLE_TO_SOURCE = 0xB, + /** + * Disassemble each executable data object in @p input in order. For + * each successful disassembly add a source data object to @p result. + * + * Return @p AMD_COMGR_STATUS_ERROR if any disassembly + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info and does not match the isa name + * of all relocatable data objects in @p input. + */ + AMD_COMGR_ACTION_DISASSEMBLE_EXECUTABLE_TO_SOURCE = 0xC, + /** + * Disassemble each bytes data object in @p input in order. For each + * successful disassembly add a source data object to @p + * result. Only simple assembly language commands are generate that + * corresponf to raw bytes are supported, not any directives that + * control the code object layout, or symbolic branch targets or + * names. + * + * Return @p AMD_COMGR_STATUS_ERROR if any disassembly + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name is not set in @p info + */ + AMD_COMGR_ACTION_DISASSEMBLE_BYTES_TO_SOURCE = 0xD, + /** + * Compile each source data object in @p input in order. For each + * successful compilation add a fat binary to @p result. Resolve + * any include source names using the names of include data objects + * in @p input. Resolve any include relative path names using the + * working directory path in @p info. Produce fat binary for isa name in @p + * info. Compile the source for the language in @p info. + * + * Return @p AMD_COMGR_STATUS_ERROR if any compilation + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name or language is not set in @p info. + */ + AMD_COMGR_ACTION_COMPILE_SOURCE_TO_FATBIN = 0xE, + /** + * Compile each source data object in @p input in order. For each + * successful compilation add a bc data object to @p result. Resolve + * any include source names using the names of include data objects + * in @p input. Resolve any include relative path names using the + * working directory path in @p info. Produce bc for isa name in @p + * info. Compile the source for the language in @p info. Link against + * the device-specific and language-specific bitcode device libraries + * required for compilation. + * + * Return @p AMD_COMGR_STATUS_ERROR if any compilation + * fails. + * + * Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT + * if isa name or language is not set in @p info. + */ + AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC = 0xF, + /** + * Marker for last valid action kind. + */ + AMD_COMGR_ACTION_LAST = AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC +} amd_comgr_action_kind_t; + +/** + * @brief Perform an action. + * + * Each action ignores any data objects in @p input that it does not + * use. If logging is enabled in @info then @p result will have a log + * data object added. Any diagnostic data objects produced by the + * action will be added to @p result. See the description of each + * action in @p amd_comgr_action_kind_t. + * + * @param[in] kind The action to perform. + * + * @param[in] info The action info to use when performing the action. + * + * @param[in] input The input data objects to the @p kind action. + * + * @param[out] result Any data objects are removed before performing + * the action which then adds all data objects produced by the action. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR An error was + * reported when executing the action. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * kind is an invalid action kind. @p input_data or @p result_data are + * invalid action data object handles. See the description of each + * action in @p amd_comgr_action_kind_t for other + * conditions that result in this status. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_do_action( + amd_comgr_action_kind_t kind, + amd_comgr_action_info_t info, + amd_comgr_data_set_t input, + amd_comgr_data_set_t result) AMD_COMGR_VERSION_1_8; + +/** + * @brief The kinds of metadata nodes. + */ +typedef enum amd_comgr_metadata_kind_s { + /** + * The NULL metadata handle. + */ + AMD_COMGR_METADATA_KIND_NULL = 0x0, + /** + * A sting value. + */ + AMD_COMGR_METADATA_KIND_STRING = 0x1, + /** + * A map that consists of a set of key and value pairs. + */ + AMD_COMGR_METADATA_KIND_MAP = 0x2, + /** + * A list that consists of a sequence of values. + */ + AMD_COMGR_METADATA_KIND_LIST = 0x3, + /** + * Marker for last valid metadata kind. + */ + AMD_COMGR_METADATA_KIND_LAST = AMD_COMGR_METADATA_KIND_LIST +} amd_comgr_metadata_kind_t; + +/** + * @brief Get the kind of the metadata node. + * + * @param[in] metadata The metadata node to query. + * + * @param[out] kind The kind of the metadata node. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node. @p kind is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to create the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_metadata_kind( + amd_comgr_metadata_node_t metadata, + amd_comgr_metadata_kind_t *kind) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the string and/or string length from a metadata string + * node. + * + * @param[in] metadata The metadata node to query. + * + * @param[in, out] size On entry, the size of @p string. On return, if @p + * string is NULL, set to the size of the string including the terminating null + * character. + * + * @param[out] string If not NULL, then the first @p size characters + * of the string are copied. If NULL, no string is copied, and only @p + * size is updated (useful in order to find the size of buffer required + * to copy the string). + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node, or does not have kind @p + * AMD_COMGR_METADATA_KIND_STRING. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_metadata_string( + amd_comgr_metadata_node_t metadata, + size_t *size, + char *string) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the map size from a metadata map node. + * + * @param[in] metadata The metadata node to query. + * + * @param[out] size The number of entries in the map. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node, or not of kind @p + * AMD_COMGR_METADATA_KIND_MAP. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_metadata_map_size( + amd_comgr_metadata_node_t metadata, + size_t *size) AMD_COMGR_VERSION_1_8; + +/** + * @brief Iterate over the elements a metadata map node. + * + * @warning The metadata nodes which are passed to the callback are not owned + * by the callback, and are freed just after the callback returns. The callback + * must not save any references to its parameters between iterations. + * + * @param[in] metadata The metadata node to query. + * + * @param[in] callback The function to call for each entry in the map. The + * entry's key is passed in @p key, the entry's value is passed in @p value, and + * @p user_data is passed as @p user_data. If the function returns with a status + * other than @p AMD_COMGR_STATUS_SUCCESS then iteration is stopped. + * + * @param[in] user_data The value to pass to each invocation of @p + * callback. Allows context to be passed into the call back function. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR An error was + * reported by @p callback. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node, or not of kind @p + * AMD_COMGR_METADATA_KIND_MAP. @p callback is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to iterate the metadata as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_iterate_map_metadata( + amd_comgr_metadata_node_t metadata, + amd_comgr_status_t (*callback)( + amd_comgr_metadata_node_t key, + amd_comgr_metadata_node_t value, + void *user_data), + void *user_data) AMD_COMGR_VERSION_1_8; + +/** + * @brief Use a string key to lookup an element of a metadata map + * node and return the entry value. + * + * @param[in] metadata The metadata node to query. + * + * @param[in] key A null terminated string that is the key to lookup. + * + * @param[out] value The metadata node of the @p key element of the + * @p metadata map metadata node. The handle must be destroyed + * using @c amd_comgr_destroy_metadata. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The map has no entry + * with a string key with the value @p key. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node, or not of kind @p + * AMD_COMGR_METADATA_KIND_MAP. @p key or @p value is + * NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to lookup metadata as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_metadata_lookup( + amd_comgr_metadata_node_t metadata, + const char *key, + amd_comgr_metadata_node_t *value) AMD_COMGR_VERSION_1_8; + +/** + * @brief Get the list size from a metadata list node. + * + * @param[in] metadata The metadata node to query. + * + * @param[out] size The number of entries in the list. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node, or does nopt have kind @p + * AMD_COMGR_METADATA_KIND_LIST. @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_get_metadata_list_size( + amd_comgr_metadata_node_t metadata, + size_t *size) AMD_COMGR_VERSION_1_8; + +/** + * @brief Return the Nth metadata node of a list metadata node. + * + * @param[in] metadata The metadata node to query. + * + * @param[in] index The index being requested. The first list element + * is index 0. + * + * @param[out] value The metadata node of the @p index element of the + * @p metadata list metadata node. The handle must be destroyed + * using @c amd_comgr_destroy_metadata. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p + * metadata is an invalid metadata node or not of kind @p + * AMD_COMGR_METADATA_INFO_LIST. @p index is greater + * than the number of list elements. @p value is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to update action data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_index_list_metadata( + amd_comgr_metadata_node_t metadata, + size_t index, + amd_comgr_metadata_node_t *value) AMD_COMGR_VERSION_1_8; + +/** + * @brief Iterate over the symbols of a machine code object. + * + * For a AMD_COMGR_DATA_KIND_RELOCATABLE the symbols in the ELF symtab section + * are iterated. For a AMD_COMGR_DATA_KIND_EXECUTABLE the symbols in the ELF + * dynsymtab are iterated. + * + * @param[in] data The data object to query. + * + * @param[in] callback The function to call for each symbol in the machine code + * data object. The symbol handle is passed in @p symbol and @p user_data is + * passed as @p user_data. If the function returns with a status other than @p + * AMD_COMGR_STATUS_SUCCESS then iteration is stopped. + * + * @param[in] user_data The value to pass to each invocation of @p + * callback. Allows context to be passed into the call back function. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR An error was + * reported by @p callback. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid data + * object, or not of kind @p AMD_COMGR_DATA_KIND_RELOCATABLE or + * AMD_COMGR_DATA_KIND_EXECUTABLE. @p callback is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to iterate the data object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_iterate_symbols( + amd_comgr_data_t data, + amd_comgr_status_t (*callback)( + amd_comgr_symbol_t symbol, + void *user_data), + void *user_data) AMD_COMGR_VERSION_1_8; + +/** + * @brief Lookup a symbol in a machine code object by name. + * + * For a AMD_COMGR_DATA_KIND_RELOCATABLE the symbols in the ELF symtab section + * are inspected. For a AMD_COMGR_DATA_KIND_EXECUTABLE the symbols in the ELF + * dynsymtab are inspected. + * + * @param[in] data The data object to query. + * + * @param[in] name A null terminated string that is the symbol name to lookup. + * + * @param[out] symbol The symbol with the @p name. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The machine code object has no symbol + * with @p name. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid data + * object, or not of kind @p AMD_COMGR_DATA_KIND_RELOCATABLE or + * AMD_COMGR_DATA_KIND_EXECUTABLE. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to lookup symbol as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_symbol_lookup( + amd_comgr_data_t data, + const char *name, + amd_comgr_symbol_t *symbol) AMD_COMGR_VERSION_1_8; + +/** + * @brief Machine code object symbol type. + */ +typedef enum amd_comgr_symbol_type_s { + /** + * The symbol's type is unknown. + * + * The user should not infer any specific type for symbols which return + * `AMD_COMGR_SYMBOL_TYPE_UNKNOWN`, and these symbols may return different + * types in future releases. + */ + AMD_COMGR_SYMBOL_TYPE_UNKNOWN = -0x1, + + /** + * The symbol's type is not specified. + */ + AMD_COMGR_SYMBOL_TYPE_NOTYPE = 0x0, + + /** + * The symbol is associated with a data object, such as a variable, an array, + * and so on. + */ + AMD_COMGR_SYMBOL_TYPE_OBJECT = 0x1, + + /** + * The symbol is associated with a function or other executable code. + */ + AMD_COMGR_SYMBOL_TYPE_FUNC = 0x2, + + /** + * The symbol is associated with a section. Symbol table entries of this type + * exist primarily for relocation. + */ + AMD_COMGR_SYMBOL_TYPE_SECTION = 0x3, + + /** + * Conventionally, the symbol's name gives the name of the source file + * associated with the object file. + */ + AMD_COMGR_SYMBOL_TYPE_FILE = 0x4, + + /** + * The symbol labels an uninitialized common block. + */ + AMD_COMGR_SYMBOL_TYPE_COMMON = 0x5, + + /** + * The symbol is associated with an AMDGPU Code Object V2 kernel function. + */ + AMD_COMGR_SYMBOL_TYPE_AMDGPU_HSA_KERNEL = 0xa +} amd_comgr_symbol_type_t; + +/** + * @brief Machine code object symbol attributes. + */ +typedef enum amd_comgr_symbol_info_s { + /** + * The length of the symbol name in bytes. Does not include the NUL + * terminator. The type of this attribute is uint64_t. + */ + AMD_COMGR_SYMBOL_INFO_NAME_LENGTH = 0x0, + + /** + * The name of the symbol. The type of this attribute is character array with + * the length equal to the value of the @p AMD_COMGR_SYMBOL_INFO_NAME_LENGTH + * attribute plus 1 for a NUL terminator. + */ + AMD_COMGR_SYMBOL_INFO_NAME = 0x1, + + /** + * The kind of the symbol. The type of this attribute is @p + * amd_comgr_symbol_type_t. + */ + AMD_COMGR_SYMBOL_INFO_TYPE = 0x2, + + /** + * Size of the variable. The value of this attribute is undefined if the + * symbol is not a variable. The type of this attribute is uint64_t. + */ + AMD_COMGR_SYMBOL_INFO_SIZE = 0x3, + + /** + * Indicates whether the symbol is undefined. The type of this attribute is + * bool. + */ + AMD_COMGR_SYMBOL_INFO_IS_UNDEFINED = 0x4, + + /** + * The value of the symbol. The type of this attribute is uint64_t. + */ + AMD_COMGR_SYMBOL_INFO_VALUE = 0x5, + + /** + * Marker for last valid symbol info. + */ + AMD_COMGR_SYMBOL_INFO_LAST = AMD_COMGR_SYMBOL_INFO_VALUE +} amd_comgr_symbol_info_t; + +/** + * @brief Query information about a machine code object symbol. + * + * @param[in] symbol The symbol to query. + * + * @param[in] attribute Attribute to query. + * + * @param[out] value Pointer to an application-allocated buffer where to store + * the value of the attribute. If the buffer passed by the application is not + * large enough to hold the value of attribute, the behavior is undefined. The + * type of value returned is specified by @p amd_comgr_symbol_info_t. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has + * been executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The @p symbol does not have the requested @p + * attribute. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p symbol is an invalid + * symbol. @p attribute is an invalid value. @p value is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES + * Unable to query symbol as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_symbol_get_info( + amd_comgr_symbol_t symbol, + amd_comgr_symbol_info_t attribute, + void *value) AMD_COMGR_VERSION_1_8; + +/** + * @brief Create a disassembly info object. + * + * @param[in] isa_name A null terminated string that is the isa name of the + * target to disassemble for. The isa name is defined as the Code Object Target + * Identification string, described at + * https://llvm.org/docs/AMDGPUUsage.html#code-object-target-identification + * + * @param[in] read_memory_callback Function called to request @p size bytes + * from the program address space at @p from be read into @p to. The requested + * @p size is never zero. Returns the number of bytes which could be read, with + * the guarantee that no additional bytes will be available in any subsequent + * call. + * + * @param[in] print_instruction_callback Function called after a successful + * disassembly. @p instruction is a null terminated string containing the + * disassembled instruction. The callback does not own @p instruction, and it + * cannot be referenced once the callback returns. + * + * @param[in] print_address_annotation_callback Function called after @c + * print_instruction_callback returns, once for each instruction operand which + * was resolved to an absolute address. @p address is the absolute address in + * the program address space. It is intended to append a symbolic + * form of the address, perhaps as a comment, after the instruction disassembly + * produced by @c print_instruction_callback. + * + * @param[out] disassembly_info A handle to the disassembly info object + * created. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly info object was created. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p isa_name is NULL or + * invalid; or @p read_memory_callback, @p print_instruction_callback, + * or @p print_address_annotation_callback is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to create the + * disassembly info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_create_disassembly_info( + const char *isa_name, + uint64_t (*read_memory_callback)( + uint64_t from, + char *to, + uint64_t size, + void *user_data), + void (*print_instruction_callback)( + const char *instruction, + void *user_data), + void (*print_address_annotation_callback)( + uint64_t address, + void *user_data), + amd_comgr_disassembly_info_t *disassembly_info) AMD_COMGR_VERSION_2_0; + +/** + * @brief Destroy a disassembly info object. + * + * @param[in] disassembly_info A handle to the disassembly info object to + * destroy. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly info object was + * destroyed. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p disassembly_info is an + * invalid disassembly info object. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to destroy the + * disassembly info object as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_destroy_disassembly_info( + amd_comgr_disassembly_info_t disassembly_info) AMD_COMGR_VERSION_1_8; + +/** + * @brief Disassemble a single instruction. + * + * @param[in] address The address of the first byte of the instruction in the + * program address space. + * + * @param[in] user_data Arbitrary user-data passed to each callback function + * during disassembly. + * + * @param[out] size The number of bytes consumed to decode the + * instruction, or consumed while failing to decode an invalid instruction. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly was successful. + * + * @retval ::AMD_COMGR_STATUS_ERROR The disassembly failed. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p disassembly_info is + * invalid or @p size is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to disassemble the + * instruction as out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_disassemble_instruction( + amd_comgr_disassembly_info_t disassembly_info, + uint64_t address, + void *user_data, + uint64_t *size) AMD_COMGR_VERSION_1_8; + +/** + * @brief Demangle a symbol name. + * + * @param[in] mangled_symbol_name A data object of kind @p + * AMD_COMGR_DATA_KIND_BYTES containing the mangled symbol name. + * + * @param[out] demangled_symbol_name A handle to the data object of kind @p + * AMD_COMGR_DATA_KIND_BYTES created and set to contain the demangled symbol + * name in case of successful completion. The handle must be released using + * @c amd_comgr_release_data. @p demangled_symbol_name is not updated for + * an error case. + * + * @note If the @p mangled_symbol_name cannot be demangled, it will be copied + * without changes to the @p demangled_symbol_name and AMD_COMGR_STATUS_SUCCESS + * is returned. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p mangled_symbol_name is + * an invalid data object or not of kind @p AMD_COMGR_DATA_KIND_BYTES or + * @p demangled_symbol_name is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Out of resources. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_demangle_symbol_name( + amd_comgr_data_t mangled_symbol_name, + amd_comgr_data_t *demangled_symbol_name) AMD_COMGR_VERSION_2_2; + +/** + * @brief A data structure for Code object information. + */ +typedef struct code_object_info_s { + /** + * ISA name representing the code object. + */ + const char *isa; + /** + * The size of the code object. + */ + size_t size; + /* + * The location of code object from the beginning + * of code object bundle. + */ + uint64_t offset; +} amd_comgr_code_object_info_t; + +/** + * @ brief Given a bundled code object and list of target id strings, extract + * correponding code object information. + * + * @param[in] data The data object for bundled code object. This should be + * of kind AMD_COMGR_DATA_KIND_FATBIN or AMD_COMGR_DATA_KIND_EXECUTABLE or + * AMD_COMGR_DATA_KIND_BYTES. The API interprets the data object of kind + * AMD_COMGR_DATA_KIND_FATBIN as a clang offload bundle and of kind + * AMD_COMGR_DATA_KIND_EXECUTABLE as an executable shared object. For a data + * object of type AMD_COMGR_DATA_KIND_BYTES the API first inspects the data + * passed to determine if it is a fatbin or an executable and performs + * the lookup. + * + * @param[in, out] info_list A list of code object information structure + * initialized with null terminated target id strings. If the target id + * is matched in the code object bundle the corresponding code object + * information is updated with offset and size of the code object. If the + * target id is not found the offset and size are set to 0. + * + * @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed + * successfully. + * + * @retval ::AMD_COMGR_STATUS_ERROR The code object bundle header is incorrect + * or reading bundle entries failed. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is not of + * kind AMD_COMGR_DATA_KIND_FATBIN, or AMD_COMGR_DATA_KIND_BYTES or + * AMD_COMGR_DATA_KIND_EXECUTABLE or either @p info_list is NULL. + * + * @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if the @p data has + * invalid data. + */ +amd_comgr_status_t AMD_COMGR_API +amd_comgr_lookup_code_object( + amd_comgr_data_t data, + amd_comgr_code_object_info_t *info_list, + size_t info_list_size) AMD_COMGR_VERSION_2_3; + +/** @} */ + +#ifdef __cplusplus +} /* end extern "C" block */ +#endif + +#endif /* header guard */ diff --git a/comgr/src/amd_comgr.rs b/comgr/src/amd_comgr.rs new file mode 100644 index 0000000..cae7fa6 --- /dev/null +++ b/comgr/src/amd_comgr.rs @@ -0,0 +1,1004 @@ +/* automatically generated by rust-bindgen 0.60.1 */ + +impl amd_comgr_status_s { + #[doc = " The function has been executed successfully."] + pub const AMD_COMGR_STATUS_SUCCESS: amd_comgr_status_s = amd_comgr_status_s(0); +} +impl amd_comgr_status_s { + #[doc = " A generic error has occurred."] + pub const AMD_COMGR_STATUS_ERROR: amd_comgr_status_s = amd_comgr_status_s(1); +} +impl amd_comgr_status_s { + #[doc = " One of the actual arguments does not meet a precondition stated"] + #[doc = " in the documentation of the corresponding formal argument."] + pub const AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT: amd_comgr_status_s = amd_comgr_status_s(2); +} +impl amd_comgr_status_s { + #[doc = " Failed to allocate the necessary resources."] + pub const AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES: amd_comgr_status_s = amd_comgr_status_s(3); +} +#[repr(transparent)] +#[doc = " @brief Status codes."] +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub struct amd_comgr_status_s(pub ::std::os::raw::c_uint); +#[doc = " @brief Status codes."] +pub use self::amd_comgr_status_s as amd_comgr_status_t; +impl amd_comgr_language_s { + #[doc = " No high level language."] + pub const AMD_COMGR_LANGUAGE_NONE: amd_comgr_language_s = amd_comgr_language_s(0); +} +impl amd_comgr_language_s { + #[doc = " OpenCL 1.2."] + pub const AMD_COMGR_LANGUAGE_OPENCL_1_2: amd_comgr_language_s = amd_comgr_language_s(1); +} +impl amd_comgr_language_s { + #[doc = " OpenCL 2.0."] + pub const AMD_COMGR_LANGUAGE_OPENCL_2_0: amd_comgr_language_s = amd_comgr_language_s(2); +} +impl amd_comgr_language_s { + #[doc = " AMD Hetrogeneous C++ (HC)."] + pub const AMD_COMGR_LANGUAGE_HC: amd_comgr_language_s = amd_comgr_language_s(3); +} +impl amd_comgr_language_s { + #[doc = " HIP."] + pub const AMD_COMGR_LANGUAGE_HIP: amd_comgr_language_s = amd_comgr_language_s(4); +} +impl amd_comgr_language_s { + #[doc = " Marker for last valid language."] + pub const AMD_COMGR_LANGUAGE_LAST: amd_comgr_language_s = amd_comgr_language_s(4); +} +#[repr(transparent)] +#[doc = " @brief The source languages supported by the compiler."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct amd_comgr_language_s(pub ::std::os::raw::c_uint); +#[doc = " @brief The source languages supported by the compiler."] +pub use self::amd_comgr_language_s as amd_comgr_language_t; +impl amd_comgr_data_kind_s { + #[doc = " No data is available."] + pub const AMD_COMGR_DATA_KIND_UNDEF: amd_comgr_data_kind_s = amd_comgr_data_kind_s(0); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a textual main source."] + pub const AMD_COMGR_DATA_KIND_SOURCE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(1); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a textual source that is included in the main source"] + #[doc = " or other include source."] + pub const AMD_COMGR_DATA_KIND_INCLUDE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(2); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a precompiled-header source that is included in the main"] + #[doc = " source or other include source."] + pub const AMD_COMGR_DATA_KIND_PRECOMPILED_HEADER: amd_comgr_data_kind_s = + amd_comgr_data_kind_s(3); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a diagnostic output."] + pub const AMD_COMGR_DATA_KIND_DIAGNOSTIC: amd_comgr_data_kind_s = amd_comgr_data_kind_s(4); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a textual log output."] + pub const AMD_COMGR_DATA_KIND_LOG: amd_comgr_data_kind_s = amd_comgr_data_kind_s(5); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is compiler LLVM IR bit code for a specific isa."] + pub const AMD_COMGR_DATA_KIND_BC: amd_comgr_data_kind_s = amd_comgr_data_kind_s(6); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a relocatable machine code object for a specific isa."] + pub const AMD_COMGR_DATA_KIND_RELOCATABLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(7); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is an executable machine code object for a specific"] + #[doc = " isa. An executable is the kind of code object that can be loaded"] + #[doc = " and executed."] + pub const AMD_COMGR_DATA_KIND_EXECUTABLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(8); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a block of bytes."] + pub const AMD_COMGR_DATA_KIND_BYTES: amd_comgr_data_kind_s = amd_comgr_data_kind_s(9); +} +impl amd_comgr_data_kind_s { + #[doc = " The data is a fat binary (clang-offload-bundler output)."] + pub const AMD_COMGR_DATA_KIND_FATBIN: amd_comgr_data_kind_s = amd_comgr_data_kind_s(16); +} +impl amd_comgr_data_kind_s { + #[doc = " Marker for last valid data kind."] + pub const AMD_COMGR_DATA_KIND_LAST: amd_comgr_data_kind_s = amd_comgr_data_kind_s(16); +} +#[repr(transparent)] +#[doc = " @brief The kinds of data supported."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct amd_comgr_data_kind_s(pub ::std::os::raw::c_uint); +#[doc = " @brief The kinds of data supported."] +pub use self::amd_comgr_data_kind_s as amd_comgr_data_kind_t; +#[doc = " @brief A handle to a data object."] +#[doc = ""] +#[doc = " Data objects are used to hold the data which is either an input or"] +#[doc = " output of a code object manager action."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct amd_comgr_data_s { + pub handle: u64, +} +#[doc = " @brief A handle to a data object."] +#[doc = ""] +#[doc = " Data objects are used to hold the data which is either an input or"] +#[doc = " output of a code object manager action."] +pub type amd_comgr_data_t = amd_comgr_data_s; +#[doc = " @brief A handle to an action data object."] +#[doc = ""] +#[doc = " An action data object holds a set of data objects. These can be"] +#[doc = " used as inputs to an action, or produced as the result of an"] +#[doc = " action."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct amd_comgr_data_set_s { + pub handle: u64, +} +#[doc = " @brief A handle to an action data object."] +#[doc = ""] +#[doc = " An action data object holds a set of data objects. These can be"] +#[doc = " used as inputs to an action, or produced as the result of an"] +#[doc = " action."] +pub type amd_comgr_data_set_t = amd_comgr_data_set_s; +#[doc = " @brief A handle to an action information object."] +#[doc = ""] +#[doc = " An action information object holds all the necessary information,"] +#[doc = " excluding the input data objects, required to perform an action."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct amd_comgr_action_info_s { + pub handle: u64, +} +#[doc = " @brief A handle to an action information object."] +#[doc = ""] +#[doc = " An action information object holds all the necessary information,"] +#[doc = " excluding the input data objects, required to perform an action."] +pub type amd_comgr_action_info_t = amd_comgr_action_info_s; +impl amd_comgr_action_kind_s { + #[doc = " Preprocess each source data object in @p input in order. For each"] + #[doc = " successful preprocessor invocation, add a source data object to @p result."] + #[doc = " Resolve any include source names using the names of include data objects"] + #[doc = " in @p input. Resolve any include relative path names using the working"] + #[doc = " directory path in @p info. Preprocess the source for the language in @p"] + #[doc = " info."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any preprocessing fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name or language is not set in @p info."] + pub const AMD_COMGR_ACTION_SOURCE_TO_PREPROCESSOR: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(0); +} +impl amd_comgr_action_kind_s { + #[doc = " Copy all existing data objects in @p input to @p output, then add the"] + #[doc = " device-specific and language-specific precompiled headers required for"] + #[doc = " compilation."] + #[doc = ""] + #[doc = " Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2"] + #[doc = " and @p AMD_COMGR_LANGUAGE_OPENCL_2_0."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language"] + #[doc = " is not set in @p info, or the language is not supported."] + pub const AMD_COMGR_ACTION_ADD_PRECOMPILED_HEADERS: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(1); +} +impl amd_comgr_action_kind_s { + #[doc = " Compile each source data object in @p input in order. For each"] + #[doc = " successful compilation add a bc data object to @p result. Resolve"] + #[doc = " any include source names using the names of include data objects"] + #[doc = " in @p input. Resolve any include relative path names using the"] + #[doc = " working directory path in @p info. Produce bc for isa name in @p"] + #[doc = " info. Compile the source for the language in @p info."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any compilation"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name or language is not set in @p info."] + pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_BC: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(2); +} +impl amd_comgr_action_kind_s { + #[doc = " Copy all existing data objects in @p input to @p output, then add the"] + #[doc = " device-specific and language-specific bitcode libraries required for"] + #[doc = " compilation."] + #[doc = ""] + #[doc = " Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2,"] + #[doc = " @p AMD_COMGR_LANGUAGE_OPENCL_2_0, and @p AMD_COMGR_LANGUAGE_HIP."] + #[doc = ""] + #[doc = " The options in @p info should be set to a set of language-specific flags."] + #[doc = " For OpenCL and HIP these include:"] + #[doc = ""] + #[doc = " correctly_rounded_sqrt"] + #[doc = " daz_opt"] + #[doc = " finite_only"] + #[doc = " unsafe_math"] + #[doc = " wavefrontsize64"] + #[doc = ""] + #[doc = " For example, to enable daz_opt and unsafe_math, the options should be set"] + #[doc = " as:"] + #[doc = ""] + #[doc = " const char *options[] = {\"daz_opt, \"unsafe_math\"};"] + #[doc = " size_t optionsCount = sizeof(options) / sizeof(options[0]);"] + #[doc = " amd_comgr_action_info_set_option_list(info, options, optionsCount);"] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language"] + #[doc = " is not set in @p info, the language is not supported, an unknown"] + #[doc = " language-specific flag is supplied, or a language-specific flag is"] + #[doc = " repeated."] + #[doc = ""] + #[doc = " @deprecated since 1.7"] + #[doc = " @warning This action, followed by @c AMD_COMGR_ACTION_LINK_BC_TO_BC, may"] + #[doc = " result in subtle bugs due to incorrect linking of the device libraries."] + #[doc = " The @c AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC action can"] + #[doc = " be used as a workaround which ensures the link occurs correctly."] + pub const AMD_COMGR_ACTION_ADD_DEVICE_LIBRARIES: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(3); +} +impl amd_comgr_action_kind_s { + #[doc = " Link each bc data object in @p input together and add the linked"] + #[doc = " bc data object to @p result. Any device library bc data object"] + #[doc = " must be explicitly added to @p input if needed."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if the link fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all bc data objects in @p input."] + pub const AMD_COMGR_ACTION_LINK_BC_TO_BC: amd_comgr_action_kind_s = amd_comgr_action_kind_s(4); +} +impl amd_comgr_action_kind_s { + #[doc = " Optimize each bc data object in @p input and create an optimized bc data"] + #[doc = " object to @p result."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if the optimization fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all bc data objects in @p input."] + pub const AMD_COMGR_ACTION_OPTIMIZE_BC_TO_BC: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(5); +} +impl amd_comgr_action_kind_s { + #[doc = " Perform code generation for each bc data object in @p input in"] + #[doc = " order. For each successful code generation add a relocatable data"] + #[doc = " object to @p result."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any code"] + #[doc = " generation fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all bc data objects in @p input."] + pub const AMD_COMGR_ACTION_CODEGEN_BC_TO_RELOCATABLE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(6); +} +impl amd_comgr_action_kind_s { + #[doc = " Perform code generation for each bc data object in @p input in"] + #[doc = " order. For each successful code generation add an assembly source data"] + #[doc = " object to @p result."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any code"] + #[doc = " generation fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all bc data objects in @p input."] + pub const AMD_COMGR_ACTION_CODEGEN_BC_TO_ASSEMBLY: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(7); +} +impl amd_comgr_action_kind_s { + #[doc = " Link each relocatable data object in @p input together and add"] + #[doc = " the linked relocatable data object to @p result. Any device"] + #[doc = " library relocatable data object must be explicitly added to @p"] + #[doc = " input if needed."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if the link fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all relocatable data objects in @p input."] + pub const AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_RELOCATABLE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(8); +} +impl amd_comgr_action_kind_s { + #[doc = " Link each relocatable data object in @p input together and add"] + #[doc = " the linked executable data object to @p result. Any device"] + #[doc = " library relocatable data object must be explicitly added to @p"] + #[doc = " input if needed."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if the link fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all relocatable data objects in @p input."] + pub const AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_EXECUTABLE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(9); +} +impl amd_comgr_action_kind_s { + #[doc = " Assemble each source data object in @p input in order into machine code."] + #[doc = " For each successful assembly add a relocatable data object to @p result."] + #[doc = " Resolve any include source names using the names of include data objects in"] + #[doc = " @p input. Resolve any include relative path names using the working"] + #[doc = " directory path in @p info. Produce relocatable for isa name in @p info."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any assembly fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name is not set in"] + #[doc = " @p info."] + pub const AMD_COMGR_ACTION_ASSEMBLE_SOURCE_TO_RELOCATABLE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(10); +} +impl amd_comgr_action_kind_s { + #[doc = " Disassemble each relocatable data object in @p input in"] + #[doc = " order. For each successful disassembly add a source data object to"] + #[doc = " @p result."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any disassembly"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all relocatable data objects in @p input."] + pub const AMD_COMGR_ACTION_DISASSEMBLE_RELOCATABLE_TO_SOURCE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(11); +} +impl amd_comgr_action_kind_s { + #[doc = " Disassemble each executable data object in @p input in order. For"] + #[doc = " each successful disassembly add a source data object to @p result."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any disassembly"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info and does not match the isa name"] + #[doc = " of all relocatable data objects in @p input."] + pub const AMD_COMGR_ACTION_DISASSEMBLE_EXECUTABLE_TO_SOURCE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(12); +} +impl amd_comgr_action_kind_s { + #[doc = " Disassemble each bytes data object in @p input in order. For each"] + #[doc = " successful disassembly add a source data object to @p"] + #[doc = " result. Only simple assembly language commands are generate that"] + #[doc = " corresponf to raw bytes are supported, not any directives that"] + #[doc = " control the code object layout, or symbolic branch targets or"] + #[doc = " names."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any disassembly"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name is not set in @p info"] + pub const AMD_COMGR_ACTION_DISASSEMBLE_BYTES_TO_SOURCE: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(13); +} +impl amd_comgr_action_kind_s { + #[doc = " Compile each source data object in @p input in order. For each"] + #[doc = " successful compilation add a fat binary to @p result. Resolve"] + #[doc = " any include source names using the names of include data objects"] + #[doc = " in @p input. Resolve any include relative path names using the"] + #[doc = " working directory path in @p info. Produce fat binary for isa name in @p"] + #[doc = " info. Compile the source for the language in @p info."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any compilation"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name or language is not set in @p info."] + pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_FATBIN: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(14); +} +impl amd_comgr_action_kind_s { + #[doc = " Compile each source data object in @p input in order. For each"] + #[doc = " successful compilation add a bc data object to @p result. Resolve"] + #[doc = " any include source names using the names of include data objects"] + #[doc = " in @p input. Resolve any include relative path names using the"] + #[doc = " working directory path in @p info. Produce bc for isa name in @p"] + #[doc = " info. Compile the source for the language in @p info. Link against"] + #[doc = " the device-specific and language-specific bitcode device libraries"] + #[doc = " required for compilation."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR if any compilation"] + #[doc = " fails."] + #[doc = ""] + #[doc = " Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT"] + #[doc = " if isa name or language is not set in @p info."] + pub const AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC: amd_comgr_action_kind_s = + amd_comgr_action_kind_s(15); +} +impl amd_comgr_action_kind_s { + #[doc = " Marker for last valid action kind."] + pub const AMD_COMGR_ACTION_LAST: amd_comgr_action_kind_s = amd_comgr_action_kind_s(15); +} +#[repr(transparent)] +#[doc = " @brief The kinds of actions that can be performed."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct amd_comgr_action_kind_s(pub ::std::os::raw::c_uint); +#[doc = " @brief The kinds of actions that can be performed."] +pub use self::amd_comgr_action_kind_s as amd_comgr_action_kind_t; +extern crate libloading; +pub struct LibComgr { + __library: ::libloading::Library, + pub amd_comgr_create_data: unsafe extern "C" fn( + kind: amd_comgr_data_kind_t, + data: *mut amd_comgr_data_t, + ) -> amd_comgr_status_t, + pub amd_comgr_release_data: unsafe extern "C" fn(data: amd_comgr_data_t) -> amd_comgr_status_t, + pub amd_comgr_set_data: unsafe extern "C" fn( + data: amd_comgr_data_t, + size: usize, + bytes: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t, + pub amd_comgr_set_data_name: unsafe extern "C" fn( + data: amd_comgr_data_t, + name: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t, + pub amd_comgr_get_data: unsafe extern "C" fn( + data: amd_comgr_data_t, + size: *mut usize, + bytes: *mut ::std::os::raw::c_char, + ) -> amd_comgr_status_t, + pub amd_comgr_get_data_name: unsafe extern "C" fn( + data: amd_comgr_data_t, + size: *mut usize, + name: *mut ::std::os::raw::c_char, + ) -> amd_comgr_status_t, + pub amd_comgr_create_data_set: + unsafe extern "C" fn(data_set: *mut amd_comgr_data_set_t) -> amd_comgr_status_t, + pub amd_comgr_destroy_data_set: + unsafe extern "C" fn(data_set: amd_comgr_data_set_t) -> amd_comgr_status_t, + pub amd_comgr_data_set_add: unsafe extern "C" fn( + data_set: amd_comgr_data_set_t, + data: amd_comgr_data_t, + ) -> amd_comgr_status_t, + pub amd_comgr_action_data_get_data: unsafe extern "C" fn( + data_set: amd_comgr_data_set_t, + data_kind: amd_comgr_data_kind_t, + index: usize, + data: *mut amd_comgr_data_t, + ) -> amd_comgr_status_t, + pub amd_comgr_create_action_info: + unsafe extern "C" fn(action_info: *mut amd_comgr_action_info_t) -> amd_comgr_status_t, + pub amd_comgr_destroy_action_info: + unsafe extern "C" fn(action_info: amd_comgr_action_info_t) -> amd_comgr_status_t, + pub amd_comgr_action_info_set_isa_name: unsafe extern "C" fn( + action_info: amd_comgr_action_info_t, + isa_name: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t, + pub amd_comgr_action_info_set_language: unsafe extern "C" fn( + action_info: amd_comgr_action_info_t, + language: amd_comgr_language_t, + ) -> amd_comgr_status_t, + pub amd_comgr_action_info_set_option_list: unsafe extern "C" fn( + action_info: amd_comgr_action_info_t, + options: *mut *const ::std::os::raw::c_char, + count: usize, + ) -> amd_comgr_status_t, + pub amd_comgr_do_action: unsafe extern "C" fn( + kind: amd_comgr_action_kind_t, + info: amd_comgr_action_info_t, + input: amd_comgr_data_set_t, + result: amd_comgr_data_set_t, + ) -> amd_comgr_status_t, +} +impl LibComgr { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let amd_comgr_create_data = __library.get(b"amd_comgr_create_data\0").map(|sym| *sym)?; + let amd_comgr_release_data = __library.get(b"amd_comgr_release_data\0").map(|sym| *sym)?; + let amd_comgr_set_data = __library.get(b"amd_comgr_set_data\0").map(|sym| *sym)?; + let amd_comgr_set_data_name = __library + .get(b"amd_comgr_set_data_name\0") + .map(|sym| *sym)?; + let amd_comgr_get_data = __library.get(b"amd_comgr_get_data\0").map(|sym| *sym)?; + let amd_comgr_get_data_name = __library + .get(b"amd_comgr_get_data_name\0") + .map(|sym| *sym)?; + let amd_comgr_create_data_set = __library + .get(b"amd_comgr_create_data_set\0") + .map(|sym| *sym)?; + let amd_comgr_destroy_data_set = __library + .get(b"amd_comgr_destroy_data_set\0") + .map(|sym| *sym)?; + let amd_comgr_data_set_add = __library.get(b"amd_comgr_data_set_add\0").map(|sym| *sym)?; + let amd_comgr_action_data_get_data = __library + .get(b"amd_comgr_action_data_get_data\0") + .map(|sym| *sym)?; + let amd_comgr_create_action_info = __library + .get(b"amd_comgr_create_action_info\0") + .map(|sym| *sym)?; + let amd_comgr_destroy_action_info = __library + .get(b"amd_comgr_destroy_action_info\0") + .map(|sym| *sym)?; + let amd_comgr_action_info_set_isa_name = __library + .get(b"amd_comgr_action_info_set_isa_name\0") + .map(|sym| *sym)?; + let amd_comgr_action_info_set_language = __library + .get(b"amd_comgr_action_info_set_language\0") + .map(|sym| *sym)?; + let amd_comgr_action_info_set_option_list = __library + .get(b"amd_comgr_action_info_set_option_list\0") + .map(|sym| *sym)?; + let amd_comgr_do_action = __library.get(b"amd_comgr_do_action\0").map(|sym| *sym)?; + Ok(LibComgr { + __library, + amd_comgr_create_data, + amd_comgr_release_data, + amd_comgr_set_data, + amd_comgr_set_data_name, + amd_comgr_get_data, + amd_comgr_get_data_name, + amd_comgr_create_data_set, + amd_comgr_destroy_data_set, + amd_comgr_data_set_add, + amd_comgr_action_data_get_data, + amd_comgr_create_action_info, + amd_comgr_destroy_action_info, + amd_comgr_action_info_set_isa_name, + amd_comgr_action_info_set_language, + amd_comgr_action_info_set_option_list, + amd_comgr_do_action, + }) + } + #[must_use] + #[doc = " @brief Create a data object that can hold data of a specified kind."] + #[doc = ""] + #[doc = " Data objects are reference counted and are destroyed when the"] + #[doc = " reference count reaches 0. When a data object is created its"] + #[doc = " reference count is 1, it has 0 bytes of data, it has an empty name,"] + #[doc = " and it has no metadata."] + #[doc = ""] + #[doc = " @param[in] kind The kind of data the object is intended to hold."] + #[doc = ""] + #[doc = " @param[out] data A handle to the data object created. Its reference"] + #[doc = " count is set to 1."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " kind is an invalid data kind, or @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF. @p data is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to create the data object as out of resources."] + pub unsafe fn amd_comgr_create_data( + &self, + kind: amd_comgr_data_kind_t, + data: *mut amd_comgr_data_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_create_data)(kind, data) + } + #[must_use] + #[doc = " @brief Indicate that no longer using a data object handle."] + #[doc = ""] + #[doc = " The reference count of the associated data object is"] + #[doc = " decremented. If it reaches 0 it is destroyed."] + #[doc = ""] + #[doc = " @param[in] data The data object to release."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " data is an invalid data object, or has kind @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_release_data(&self, data: amd_comgr_data_t) -> amd_comgr_status_t { + (self.amd_comgr_release_data)(data) + } + #[must_use] + #[doc = " @brief Set the data content of a data object to the specified"] + #[doc = " bytes."] + #[doc = ""] + #[doc = " Any previous value of the data object is overwritten. Any metadata"] + #[doc = " associated with the data object is also replaced which invalidates"] + #[doc = " all metadata handles to the old metadata."] + #[doc = ""] + #[doc = " @param[in] data The data object to update."] + #[doc = ""] + #[doc = " @param[in] size The number of bytes in the data specified by @p bytes."] + #[doc = ""] + #[doc = " @param[in] bytes The bytes to set the data object to. The bytes are"] + #[doc = " copied into the data object and can be freed after the call."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " data is an invalid data object, or has kind @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_set_data( + &self, + data: amd_comgr_data_t, + size: usize, + bytes: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t { + (self.amd_comgr_set_data)(data, size, bytes) + } + #[must_use] + #[doc = " @brief Set the name associated with a data object."] + #[doc = ""] + #[doc = " When compiling, the fle name of an include directive is used to"] + #[doc = " reference the contents of the include data object with the same"] + #[doc = " name. The name may also be used for other data objects in log and"] + #[doc = " diagnostic output."] + #[doc = ""] + #[doc = " @param[in] data The data object to update."] + #[doc = ""] + #[doc = " @param[in] name A null terminated string that specifies the name to"] + #[doc = " use for the data object. If NULL then the name is set to the empty"] + #[doc = " string."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " data is an invalid data object, or has kind @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_set_data_name( + &self, + data: amd_comgr_data_t, + name: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t { + (self.amd_comgr_set_data_name)(data, name) + } + #[must_use] + #[doc = " @brief Get the data contents, and/or the size of the data"] + #[doc = " associated with a data object."] + #[doc = ""] + #[doc = " @param[in] data The data object to query."] + #[doc = ""] + #[doc = " @param[in, out] size On entry, the size of @p bytes. On return, if @p bytes"] + #[doc = " is NULL, set to the size of the data object contents."] + #[doc = ""] + #[doc = " @param[out] bytes If not NULL, then the first @p size bytes of the"] + #[doc = " data object contents is copied. If NULL, no data is copied, and"] + #[doc = " only @p size is updated (useful in order to find the size of buffer"] + #[doc = " required to copy the data)."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " data is an invalid data object, or has kind @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_get_data( + &self, + data: amd_comgr_data_t, + size: *mut usize, + bytes: *mut ::std::os::raw::c_char, + ) -> amd_comgr_status_t { + (self.amd_comgr_get_data)(data, size, bytes) + } + #[must_use] + #[doc = " @brief Get the data object name and/or name length."] + #[doc = ""] + #[doc = " @param[in] data The data object to query."] + #[doc = ""] + #[doc = " @param[in, out] size On entry, the size of @p name. On return, the size of"] + #[doc = " the data object name including the terminating null character."] + #[doc = ""] + #[doc = " @param[out] name If not NULL, then the first @p size characters of the"] + #[doc = " data object name are copied. If @p name is NULL, only @p size is updated"] + #[doc = " (useful in order to find the size of buffer required to copy the name)."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " data is an invalid data object, or has kind @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_get_data_name( + &self, + data: amd_comgr_data_t, + size: *mut usize, + name: *mut ::std::os::raw::c_char, + ) -> amd_comgr_status_t { + (self.amd_comgr_get_data_name)(data, size, name) + } + #[must_use] + #[doc = " @brief Create a data set object."] + #[doc = ""] + #[doc = " @param[out] data_set A handle to the data set created. Initially it"] + #[doc = " contains no data objects."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed"] + #[doc = " successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to create the data"] + #[doc = " set object as out of resources."] + pub unsafe fn amd_comgr_create_data_set( + &self, + data_set: *mut amd_comgr_data_set_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_create_data_set)(data_set) + } + #[must_use] + #[doc = " @brief Destroy a data set object."] + #[doc = ""] + #[doc = " The reference counts of any associated data objects are decremented. Any"] + #[doc = " handles to the data set object become invalid."] + #[doc = ""] + #[doc = " @param[in] data_set A handle to the data set object to destroy."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed"] + #[doc = " successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid"] + #[doc = " data set object."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set"] + #[doc = " object as out of resources."] + pub unsafe fn amd_comgr_destroy_data_set( + &self, + data_set: amd_comgr_data_set_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_destroy_data_set)(data_set) + } + #[must_use] + #[doc = " @brief Add a data object to a data set object if it is not already added."] + #[doc = ""] + #[doc = " The reference count of the data object is incremented."] + #[doc = ""] + #[doc = " @param[in] data_set A handle to the data set object to be updated."] + #[doc = ""] + #[doc = " @param[in] data A handle to the data object to be added. If @p data_set"] + #[doc = " already has the specified handle present, then it is not added. The order"] + #[doc = " that data objects are added is preserved."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed"] + #[doc = " successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid"] + #[doc = " data set object. @p data is an invalid data object; has undef kind; has"] + #[doc = " include kind but does not have a name."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set"] + #[doc = " object as out of resources."] + pub unsafe fn amd_comgr_data_set_add( + &self, + data_set: amd_comgr_data_set_t, + data: amd_comgr_data_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_data_set_add)(data_set, data) + } + #[must_use] + #[doc = " @brief Return the Nth data object of a specified data kind that is added to a"] + #[doc = " data set object."] + #[doc = ""] + #[doc = " The reference count of the returned data object is incremented."] + #[doc = ""] + #[doc = " @param[in] data_set A handle to the data set object to be queried."] + #[doc = ""] + #[doc = " @param[in] data_kind The data kind of the data object to be returned."] + #[doc = ""] + #[doc = " @param[in] index The index of the data object of data kind @data_kind to be"] + #[doc = " returned. The first data object is index 0. The order of data objects matches"] + #[doc = " the order that they were added to the data set object."] + #[doc = ""] + #[doc = " @param[out] data The data object being requested."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed"] + #[doc = " successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid"] + #[doc = " data set object. @p data_kind is an invalid data kind or @p"] + #[doc = " AMD_COMGR_DATA_KIND_UNDEF. @p index is greater than the number of data"] + #[doc = " objects of kind @p data_kind. @p data is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query data set"] + #[doc = " object as out of resources."] + pub unsafe fn amd_comgr_action_data_get_data( + &self, + data_set: amd_comgr_data_set_t, + data_kind: amd_comgr_data_kind_t, + index: usize, + data: *mut amd_comgr_data_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_action_data_get_data)(data_set, data_kind, index, data) + } + #[must_use] + #[doc = " @brief Create an action info object."] + #[doc = ""] + #[doc = " @param[out] action_info A handle to the action info object created."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " action_info is NULL."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to create the action info object as out of resources."] + pub unsafe fn amd_comgr_create_action_info( + &self, + action_info: *mut amd_comgr_action_info_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_create_action_info)(action_info) + } + #[must_use] + #[doc = " @brief Destroy an action info object."] + #[doc = ""] + #[doc = " @param[in] action_info A handle to the action info object to destroy."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " action_info is an invalid action info object."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update action info object as out of resources."] + pub unsafe fn amd_comgr_destroy_action_info( + &self, + action_info: amd_comgr_action_info_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_destroy_action_info)(action_info) + } + #[must_use] + #[doc = " @brief Set the isa name of an action info object."] + #[doc = ""] + #[doc = " When an action info object is created it has no isa name. Some"] + #[doc = " actions require that the action info object has an isa name"] + #[doc = " defined."] + #[doc = ""] + #[doc = " @param[in] action_info A handle to the action info object to be"] + #[doc = " updated."] + #[doc = ""] + #[doc = " @param[in] isa_name A null terminated string that is the isa name. If NULL"] + #[doc = " or the empty string then the isa name is cleared. The isa name is defined as"] + #[doc = " the Code Object Target Identification string, described at"] + #[doc = " https://llvm.org/docs/AMDGPUUsage.html#code-object-target-identification"] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " action_info is an invalid action info object. @p isa_name is not an"] + #[doc = " isa name supported by this version of the code object manager"] + #[doc = " library."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update action info object as out of resources."] + pub unsafe fn amd_comgr_action_info_set_isa_name( + &self, + action_info: amd_comgr_action_info_t, + isa_name: *const ::std::os::raw::c_char, + ) -> amd_comgr_status_t { + (self.amd_comgr_action_info_set_isa_name)(action_info, isa_name) + } + #[must_use] + #[doc = " @brief Set the source language of an action info object."] + #[doc = ""] + #[doc = " When an action info object is created it has no language defined"] + #[doc = " which is represented by @p"] + #[doc = " AMD_COMGR_LANGUAGE_NONE. Some actions require that"] + #[doc = " the action info object has a source language defined."] + #[doc = ""] + #[doc = " @param[in] action_info A handle to the action info object to be"] + #[doc = " updated."] + #[doc = ""] + #[doc = " @param[in] language The language to set. If @p"] + #[doc = " AMD_COMGR_LANGUAGE_NONE then the language is cleared."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " action_info is an invalid action info object. @p language is an"] + #[doc = " invalid language."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update action info object as out of resources."] + pub unsafe fn amd_comgr_action_info_set_language( + &self, + action_info: amd_comgr_action_info_t, + language: amd_comgr_language_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_action_info_set_language)(action_info, language) + } + #[must_use] + #[doc = " @brief Set the options array of an action info object."] + #[doc = ""] + #[doc = " This overrides any option strings or arrays previously set by calls to this"] + #[doc = " function or @p amd_comgr_action_info_set_options."] + #[doc = ""] + #[doc = " An @p action_info object which had its options set with this function can"] + #[doc = " only have its option inspected with @p"] + #[doc = " amd_comgr_action_info_get_option_list_count and @p"] + #[doc = " amd_comgr_action_info_get_option_list_item."] + #[doc = ""] + #[doc = " @param[in] action_info A handle to the action info object to be updated."] + #[doc = ""] + #[doc = " @param[in] options An array of null terminated strings. May be NULL if @p"] + #[doc = " count is zero, which will result in an empty options array."] + #[doc = ""] + #[doc = " @param[in] count The number of null terminated strings in @p options."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed"] + #[doc = " successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an"] + #[doc = " invalid action info object, or @p options is NULL and @p count is non-zero."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update action"] + #[doc = " info object as out of resources."] + pub unsafe fn amd_comgr_action_info_set_option_list( + &self, + action_info: amd_comgr_action_info_t, + options: *mut *const ::std::os::raw::c_char, + count: usize, + ) -> amd_comgr_status_t { + (self.amd_comgr_action_info_set_option_list)(action_info, options, count) + } + #[must_use] + #[doc = " @brief Perform an action."] + #[doc = ""] + #[doc = " Each action ignores any data objects in @p input that it does not"] + #[doc = " use. If logging is enabled in @info then @p result will have a log"] + #[doc = " data object added. Any diagnostic data objects produced by the"] + #[doc = " action will be added to @p result. See the description of each"] + #[doc = " action in @p amd_comgr_action_kind_t."] + #[doc = ""] + #[doc = " @param[in] kind The action to perform."] + #[doc = ""] + #[doc = " @param[in] info The action info to use when performing the action."] + #[doc = ""] + #[doc = " @param[in] input The input data objects to the @p kind action."] + #[doc = ""] + #[doc = " @param[out] result Any data objects are removed before performing"] + #[doc = " the action which then adds all data objects produced by the action."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_SUCCESS The function has"] + #[doc = " been executed successfully."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR An error was"] + #[doc = " reported when executing the action."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p"] + #[doc = " kind is an invalid action kind. @p input_data or @p result_data are"] + #[doc = " invalid action data object handles. See the description of each"] + #[doc = " action in @p amd_comgr_action_kind_t for other"] + #[doc = " conditions that result in this status."] + #[doc = ""] + #[doc = " @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES"] + #[doc = " Unable to update the data object as out of resources."] + pub unsafe fn amd_comgr_do_action( + &self, + kind: amd_comgr_action_kind_t, + info: amd_comgr_action_info_t, + input: amd_comgr_data_set_t, + result: amd_comgr_data_set_t, + ) -> amd_comgr_status_t { + (self.amd_comgr_do_action)(kind, info, input, result) + } +} diff --git a/comgr/src/double_wave32_on_wave64.ll b/comgr/src/double_wave32_on_wave64.ll new file mode 100644 index 0000000..c7a9d0a --- /dev/null +++ b/comgr/src/double_wave32_on_wave64.ll @@ -0,0 +1,4 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@__zluda_ptx_impl__COMPILATION_MODE = linkonce_odr local_unnamed_addr addrspace(4) constant i8 3, align 1 diff --git a/comgr/src/lib.rs b/comgr/src/lib.rs new file mode 100644 index 0000000..9e188f2 --- /dev/null +++ b/comgr/src/lib.rs @@ -0,0 +1,626 @@ +#[allow(non_camel_case_types)] +#[allow(dead_code)] +#[path = "amd_comgr.rs"] +pub mod sys; + +use hip_common::CompilationMode; +use itertools::Either; +use std::{ + borrow::Borrow, + ffi::{CStr, CString}, + iter, mem, ptr, + rc::Rc, + sync::atomic::{AtomicU64, Ordering}, +}; +use sys::LibComgr; + +#[cfg(windows)] +static CODE_OBJECT_VERSION_FLAG_COMGR: &'static [u8] = b"code_object_v4\0"; // Code Object v5 is broken as of Adrenaline 23.11.1 +#[cfg(windows)] +static CODE_OBJECT_VERSION_FLAG_CLANG: &'static [u8] = b"-mcode-object-version=4\0"; // Code Object v5 is broken as of Adrenaline 23.11.1 +#[cfg(not(windows))] +static CODE_OBJECT_VERSION_FLAG_COMGR: &'static [u8] = b"code_object_v5\0"; +#[cfg(not(windows))] +static CODE_OBJECT_VERSION_FLAG_CLANG: &'static [u8] = b"-mcode-object-version=5\0"; + +macro_rules! call { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + unsafe { + let result = $expr; + if result != sys::amd_comgr_status_t::AMD_COMGR_STATUS_SUCCESS { + return Err(result); + } + } + } + }; +} + +pub type Result = std::result::Result; + +pub struct Comgr(LibComgr, AtomicU64); + +static WAVE32_MODULE: &'static [u8] = include_bytes!("wave32.ll"); +static WAVE32_ON_WAVE64_MODULE: &'static [u8] = include_bytes!("wave32_on_wave64.ll"); +static DOUBLE_WAVE32_ON_WAVE64_MODULE: &'static [u8] = include_bytes!("double_wave32_on_wave64.ll"); + +#[cfg(windows)] +static OS_MODULE: &'static [u8] = include_bytes!("windows.ll"); +#[cfg(not(windows))] +static OS_MODULE: &'static [u8] = include_bytes!("linux.ll"); + +impl Comgr { + pub fn find_and_load() -> Result { + match unsafe { Self::load_library() } { + Ok(libcomgr) => Ok(Self(libcomgr, AtomicU64::new(1))), + Err(_) => Err(sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR), + } + } + + #[cfg(windows)] + unsafe fn load_library() -> std::result::Result { + LibComgr::new("amd_comgr.dll") + } + + #[cfg(not(windows))] + unsafe fn load_library() -> std::result::Result { + LibComgr::new("libamd_comgr.so.2") + .or_else(|_| LibComgr::new("/opt/rocm/lib/libamd_comgr.so.2")) + } + + fn get(&self) -> &LibComgr { + &self.0 + } + + pub fn compile<'a>( + &self, + compilation_mode: CompilationMode, + isa: &'a CStr, + input_bitcode: impl Iterator, impl AsRef)>, + linker_module: &[u8], + ) -> Result> { + let bitcode = self.link_bitcode_impl(compilation_mode, isa, input_bitcode)?; + let relocatable = self.build_relocatable_impl(compilation_mode, isa, &bitcode)?; + if !linker_module.is_empty() { + let source = self.assemble_source(isa, linker_module)?; + self.link_relocatable_impl( + isa, + IntoIterator::into_iter([ + &relocatable.get_data( + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + 0, + )?, + &source, + ]), + ) + } else { + self.link_relocatable_impl( + isa, + iter::once(&relocatable.get_data( + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + 0, + )?), + ) + } + } + + pub fn link_bitcode<'this, 'a>( + &'this self, + compilation_mode: CompilationMode, + isa: &'a CStr, + input_bitcode: impl Iterator, &'a CStr)>, + ) -> Result> { + let data_set_bitcode = self.link_bitcode_impl(compilation_mode, isa, input_bitcode)?; + Ok(Bitcode(data_set_bitcode)) + } + + pub fn bitcode_to_relocatable<'a>( + self: &Rc, + compilation_mode: CompilationMode, + isa: &'a CStr, + bc: &Bitcode, + ) -> Result { + let data_set_relocatable = self.build_relocatable_impl(compilation_mode, isa, &bc.0)?; + Ok(Relocatable::from_data(data_set_relocatable.get_data_rc( + self.clone(), + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + 0, + )?)?) + } + + pub fn build_relocatable<'a>( + self: &Rc, + compilation_mode: CompilationMode, + isa: &'a CStr, + input_bitcode: impl Iterator, &'a CStr)>, + ) -> Result { + let bitcode = self.link_bitcode_impl(compilation_mode, isa, input_bitcode)?; + let data_set_relocatable = self.build_relocatable_impl(compilation_mode, isa, &bitcode)?; + Ok(Relocatable::from_data(data_set_relocatable.get_data_rc( + self.clone(), + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + 0, + )?)?) + } + + pub fn link_relocatable<'a>( + self: &Rc, + isa: &'a CStr, + modules: impl Iterator, + ) -> Result> { + self.link_relocatable_impl(isa, modules.map(|reloc| &reloc.0)) + } + + pub fn version(&self) -> Result { + let mut data_set = DataSet::new(self)?; + let data = Data::new( + self, + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_SOURCE, + b"__VERSION__", + unsafe { CStr::from_bytes_with_nul_unchecked(b"version.h\0") }, + )?; + data_set.add(&data)?; + let result = self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_SOURCE_TO_PREPROCESSOR, + &data_set, + unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") }, + iter::once(unsafe { CStr::from_bytes_with_nul_unchecked(b"-nogpuinc\0") }), + Some(sys::amd_comgr_language_t::AMD_COMGR_LANGUAGE_HIP), + )?; + let result = result.get_data(sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_SOURCE, 0)?; + let result = result.get_data()?; + let end_quote = result + .iter() + .copied() + .rposition(|c| c as char == '"') + .ok_or(sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR)?; + let start_quote = result[..end_quote] + .iter() + .copied() + .rposition(|c| c as char == '"') + .ok_or(sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR)?; + String::from_utf8(result[start_quote + 1..end_quote].to_vec()) + .map_err(|_| sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR) + } + + fn link_bitcode_impl<'this, 'a>( + &'this self, + compilation_mode: CompilationMode, + isa: &'a CStr, + input_bitcode: impl Iterator, impl AsRef)>, + ) -> Result> { + let mut bitcode_modules = DataSet::new(self)?; + for (bc, name) in input_bitcode { + bitcode_modules.add(&Data::new( + self, + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC, + bc.as_ref(), + name.as_ref(), + )?)?; + } + let wave_module_text = match compilation_mode { + CompilationMode::Wave32 => WAVE32_MODULE, + CompilationMode::Wave32OnWave64 => WAVE32_ON_WAVE64_MODULE, + CompilationMode::DoubleWave32OnWave64 => DOUBLE_WAVE32_ON_WAVE64_MODULE, + }; + let wave_module = Data::new( + self, + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC, + wave_module_text, + unsafe { CStr::from_bytes_with_nul_unchecked(b"wave.ll\0") }, + )?; + bitcode_modules.add(&wave_module)?; + let os_module = Data::new( + self, + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC, + OS_MODULE, + unsafe { CStr::from_bytes_with_nul_unchecked(b"os.ll\0") }, + )?; + bitcode_modules.add(&os_module)?; + let lib_options = unsafe { + match compilation_mode { + CompilationMode::Wave32 => Either::Left([CStr::from_bytes_with_nul_unchecked( + CODE_OBJECT_VERSION_FLAG_COMGR, + )]), + CompilationMode::Wave32OnWave64 | CompilationMode::DoubleWave32OnWave64 => { + Either::Right([ + CStr::from_bytes_with_nul_unchecked(CODE_OBJECT_VERSION_FLAG_COMGR), + CStr::from_bytes_with_nul_unchecked(b"wavefrontsize64\0"), + ]) + } + } + }; + let device_linking_output: DataSet<'_> = self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_ADD_DEVICE_LIBRARIES, + &bitcode_modules, + isa, + lib_options.into_iter(), + Some(sys::amd_comgr_language_t::AMD_COMGR_LANGUAGE_OPENCL_2_0), + )?; + self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_LINK_BC_TO_BC, + &device_linking_output, + isa, + unsafe { + [CStr::from_bytes_with_nul_unchecked( + CODE_OBJECT_VERSION_FLAG_COMGR, + )] + .iter() + .copied() + }, + None, + ) + } + + fn build_relocatable_impl<'this, 'a>( + &'this self, + compilation_mode: CompilationMode, + isa: &'a CStr, + bc_linking_output: &DataSet<'this>, + ) -> Result> { + let debug_level = if cfg!(debug_assertions) { + unsafe { + [ + CStr::from_bytes_with_nul_unchecked(b"-g\0"), + CStr::from_bytes_with_nul_unchecked(b"\0"), + CStr::from_bytes_with_nul_unchecked(b"\0"), + ] + } + } else { + unsafe { + [ + CStr::from_bytes_with_nul_unchecked(b"-g0\0"), + // TODO: tweak and measure impact + CStr::from_bytes_with_nul_unchecked(b"-mllvm\0"), + CStr::from_bytes_with_nul_unchecked(b"-inline-threshold=5000\0"), + ] + } + }; + let compilation_mode = unsafe { + if compilation_mode == CompilationMode::Wave32 { + CStr::from_bytes_with_nul_unchecked(b"-mno-wavefrontsize64\0") + } else { + CStr::from_bytes_with_nul_unchecked(b"-mwavefrontsize64\0") + } + }; + let relocatable = self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_CODEGEN_BC_TO_RELOCATABLE, + bc_linking_output, + isa, + unsafe { + [ + compilation_mode, + CStr::from_bytes_with_nul_unchecked(CODE_OBJECT_VERSION_FLAG_CLANG), + CStr::from_bytes_with_nul_unchecked(b"-O3\0"), + // TODO: measure more + // Slightly more efficient in Blender + CStr::from_bytes_with_nul_unchecked(b"-mcumode\0"), + CStr::from_bytes_with_nul_unchecked(b"-ffp-contract=off\0"), + CStr::from_bytes_with_nul_unchecked(b"-mllvm\0"), + CStr::from_bytes_with_nul_unchecked(b"-amdgpu-internalize-symbols\0"), + // TODO: This emits scratch_ instead of buffer_ instructions + // for stack spills&fills, measure impact + // CStr::from_bytes_with_nul_unchecked(b"-Xclang\0"), + // CStr::from_bytes_with_nul_unchecked(b"-target-feature\0"), + // CStr::from_bytes_with_nul_unchecked(b"-Xclang\0"), + // CStr::from_bytes_with_nul_unchecked(b"+enable-flat-scratch\0"), + // Useful for debugging miscompilations + // CStr::from_bytes_with_nul_unchecked(b"-mllvm\0"), + // CStr::from_bytes_with_nul_unchecked(b"-opt-bisect-limit=-1\0"), + ] + } + .iter() + .copied() + .chain(debug_level.iter().copied()), + None, + )?; + Ok(relocatable) + } + + fn link_relocatable_impl<'this, 'a, C: Borrow + 'a>( + &'this self, + isa: &'a CStr, + modules: impl Iterator>, + ) -> Result> { + let mut input = DataSet::new(self)?; + for module in modules { + input.add(module)?; + } + let executable_set: DataSet = self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_EXECUTABLE, + &input, + isa, + unsafe { + [ + CStr::from_bytes_with_nul_unchecked(b"-Xlinker\0"), + CStr::from_bytes_with_nul_unchecked(b"--no-undefined\0"), + ] + } + .iter() + .copied(), + None, + )?; + let executable_data = executable_set.get_data( + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_EXECUTABLE, + 0, + )?; + executable_data.get_data() + } + + fn assemble_source(&self, isa: &CStr, src: &[u8]) -> Result> { + let data = Data::new( + self, + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_SOURCE, + src, + unsafe { CStr::from_bytes_with_nul_unchecked(b"input.s\0") }, + )?; + let mut data_set = DataSet::new(self)?; + data_set.add(&data)?; + let assembled = self.do_action( + sys::amd_comgr_action_kind_t::AMD_COMGR_ACTION_ASSEMBLE_SOURCE_TO_RELOCATABLE, + &data_set, + isa, + iter::once(unsafe { + CStr::from_bytes_with_nul_unchecked(CODE_OBJECT_VERSION_FLAG_CLANG) + }), + None, + )?; + assembled.get_data( + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + 0, + ) + } + + fn do_action<'a, 'cstr>( + &'a self, + kind: sys::amd_comgr_action_kind_t, + input: &DataSet, + isa: &CStr, + options: impl Iterator, + language: Option, + ) -> Result> { + let output = DataSet::new(self)?; + let action = ActionInfo::new(self, isa)?; + if options.size_hint().1.unwrap() > 0 { + action.set_options(options)?; + } + if let Some(lang) = language { + action.set_language(lang)?; + } + action.execute(kind, &input, &output)?; + Ok(output) + } +} + +pub struct Bitcode<'a>(DataSet<'a>); + +impl<'a> Bitcode<'a> { + pub fn get_data(&self) -> Result> { + self.0 + .get_data(sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC, 0)? + .get_data() + } +} + +pub struct Relocatable(Data>); + +impl Relocatable { + fn from_data(data: Data>) -> Result { + let suffix = data.1 .1.fetch_add(1, Ordering::Relaxed); + let new_name = format!("reloc_{}.o\0", suffix); + call!(data + .1 + .get() + .amd_comgr_set_data_name(data.0, new_name.as_ptr() as _)); + Ok(Self(data)) + } + + pub fn new(comgr: &Rc, vec: &[u8]) -> Result { + let suffix = comgr.1.fetch_add(1, Ordering::Relaxed); + let new_name = format!("reloc_{}.o", suffix); + let data = Data::new( + comgr.clone(), + sys::amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_RELOCATABLE, + vec, + &CString::new(new_name).map_err(|_| sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR)?, + )?; + Ok(Self(data)) + } + + pub fn get_data(&self) -> Result> { + self.0.get_data() + } +} + +struct ActionInfo<'a>(sys::amd_comgr_action_info_t, &'a Comgr); + +impl<'a> ActionInfo<'a> { + fn new(comgr: &'a Comgr, isa: &'a CStr) -> Result { + unsafe { + let mut action_info = mem::zeroed(); + call!(comgr.get().amd_comgr_create_action_info(&mut action_info)); + call!(comgr + .get() + .amd_comgr_action_info_set_isa_name(action_info, isa.as_ptr() as _)); + Ok(ActionInfo(action_info, comgr)) + } + } + + fn get(&self) -> sys::amd_comgr_action_info_t { + self.0 + } + + fn set_options<'cstr>(&self, options: impl Iterator) -> Result<()> { + let mut options_c = options.map(CStr::as_ptr).collect::>(); + call!(self.1.get().amd_comgr_action_info_set_option_list( + self.get(), + options_c.as_mut_ptr(), + options_c.len() + )); + Ok(()) + } + + fn set_language(&self, lang: sys::amd_comgr_language_t) -> Result<()> { + call!(self + .1 + .get() + .amd_comgr_action_info_set_language(self.get(), lang)); + Ok(()) + } + + fn execute( + &self, + kind: sys::amd_comgr_action_kind_t, + input: &DataSet<'a>, + output: &DataSet<'a>, + ) -> Result<()> { + call!(self + .1 + .get() + .amd_comgr_do_action(kind, self.get(), input.get(), output.get())); + Ok(()) + } +} + +#[allow(unused_must_use)] +impl<'a> Drop for ActionInfo<'a> { + fn drop(&mut self) { + unsafe { self.1.get().amd_comgr_destroy_action_info(self.get()) }; + } +} + +struct DataSet<'a> { + base: sys::amd_comgr_data_set_t, + comgr: &'a Comgr, +} + +impl<'a> DataSet<'a> { + fn new(comgr: &'a Comgr) -> Result> { + unsafe { + let mut base = mem::zeroed(); + call!(comgr.get().amd_comgr_create_data_set(&mut base)); + Ok(DataSet { base, comgr }) + } + } + + fn add>(&mut self, data: &Data) -> Result<()> { + call!(self + .comgr + .get() + .amd_comgr_data_set_add(self.base, data.get())); + Ok(()) + } + + fn get_data(&self, kind: sys::amd_comgr_data_kind_t, index: usize) -> Result> { + let mut output = unsafe { mem::zeroed() }; + call!(self.comgr.get().amd_comgr_action_data_get_data( + self.get(), + kind, + index, + &mut output + )); + Ok(Data(output, self.comgr)) + } + + fn get_data_rc( + &self, + comgr: Rc, + kind: sys::amd_comgr_data_kind_t, + index: usize, + ) -> Result>> { + assert!(std::ptr::eq::(self.comgr as *const _, &*comgr)); + let mut output = unsafe { mem::zeroed() }; + call!(self.comgr.get().amd_comgr_action_data_get_data( + self.get(), + kind, + index, + &mut output + )); + Ok(Data(output, comgr)) + } + + fn get(&self) -> sys::amd_comgr_data_set_t { + self.base + } +} + +#[allow(unused_must_use)] +impl<'a> Drop for DataSet<'a> { + fn drop(&mut self) { + unsafe { self.comgr.get().amd_comgr_destroy_data_set(self.get()) }; + } +} + +struct Data>(sys::amd_comgr_data_t, C); + +impl> Data { + fn new( + comgr: C, + kind: sys::amd_comgr_data_kind_t, + data: &[u8], + name: &CStr, + ) -> Result> { + let mut comgr_data = unsafe { mem::zeroed() }; + call!(comgr + .borrow() + .get() + .amd_comgr_create_data(kind, &mut comgr_data)); + call!(comgr + .borrow() + .get() + .amd_comgr_set_data_name(comgr_data, name.as_ptr() as _)); + call!(comgr + .borrow() + .get() + .amd_comgr_set_data(comgr_data, data.len(), data.as_ptr() as _)); + Ok(Self(comgr_data, comgr)) + } + + fn get(&self) -> sys::amd_comgr_data_t { + self.0 + } + + fn get_data(&self) -> Result> { + let mut size = 0; + call!(self + .1 + .borrow() + .get() + .amd_comgr_get_data(self.get(), &mut size, ptr::null_mut())); + let mut output = vec![0u8; size]; + call!(self.1.borrow().get().amd_comgr_get_data( + self.get(), + &mut size, + output.as_mut_ptr() as _ + )); + Ok(output) + } +} + +impl + Clone> Clone for Data { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1.clone()) + } +} + +#[allow(unused_must_use)] +impl> Drop for Data { + fn drop(&mut self) { + unsafe { self.1.borrow().get().amd_comgr_release_data(self.get()) }; + } +} + +#[cfg(test)] +mod tests { + use crate::Comgr; + + #[test] + fn version() { + let comgr = Comgr::find_and_load().unwrap(); + let version = comgr.version().unwrap(); + assert!(version.contains("Clang")); + assert!(!version.contains("\"")); + assert!(!version.contains("\n")); + } +} diff --git a/comgr/src/linux.ll b/comgr/src/linux.ll new file mode 100644 index 0000000..2d33142 --- /dev/null +++ b/comgr/src/linux.ll @@ -0,0 +1,4 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@__zluda_ptx_impl__IS_WINDOWS = linkonce_odr local_unnamed_addr addrspace(4) constant i1 0 diff --git a/comgr/src/wave32.ll b/comgr/src/wave32.ll new file mode 100644 index 0000000..bc0ef4d --- /dev/null +++ b/comgr/src/wave32.ll @@ -0,0 +1,4 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@__zluda_ptx_impl__COMPILATION_MODE = linkonce_odr local_unnamed_addr addrspace(4) constant i8 1, align 1 diff --git a/comgr/src/wave32_on_wave64.ll b/comgr/src/wave32_on_wave64.ll new file mode 100644 index 0000000..2ad4574 --- /dev/null +++ b/comgr/src/wave32_on_wave64.ll @@ -0,0 +1,4 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@__zluda_ptx_impl__COMPILATION_MODE = linkonce_odr local_unnamed_addr addrspace(4) constant i8 2, align 1 diff --git a/comgr/src/windows.ll b/comgr/src/windows.ll new file mode 100644 index 0000000..bb70f73 --- /dev/null +++ b/comgr/src/windows.ll @@ -0,0 +1,4 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@__zluda_ptx_impl__IS_WINDOWS = linkonce_odr local_unnamed_addr addrspace(4) constant i1 1 diff --git a/cuda_base/Cargo.toml b/cuda_base/Cargo.toml new file mode 100644 index 0000000..a7ea693 --- /dev/null +++ b/cuda_base/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cuda_base" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0" +syn = { version = "1.0.93", features = ["full", "visit", "visit-mut"] } +proc-macro2 = "1.0" +rustc-hash = "1.1" diff --git a/cuda_base/README b/cuda_base/README new file mode 100644 index 0000000..448198b --- /dev/null +++ b/cuda_base/README @@ -0,0 +1 @@ +bindgen build/wrapper.h -o src/cuda.rs --no-partialeq "CUDA_HOST_NODE_PARAMS_st" --no-partialeq "CUDA_HOST_NODE_PARAMS_v2_st" --with-derive-eq --allowlist-function="^cu.*" --allowlist-var="^CU.*" --default-enum-style=newtype --no-layout-tests --no-doc-comments --new-type-alias "^CUdevice_v\d+$|^CUdeviceptr_v\d+$" --must-use-type "cudaError_enum" -- -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.2\include" diff --git a/cuda_base/build/wrapper.h b/cuda_base/build/wrapper.h new file mode 100644 index 0000000..ff34cac --- /dev/null +++ b/cuda_base/build/wrapper.h @@ -0,0 +1,7 @@ +#define __CUDA_API_VERSION_INTERNAL +#ifdef _WIN32 + #include +#endif +#include +#include +#include \ No newline at end of file diff --git a/zluda_dump/src/cuda.rs b/cuda_base/src/cuda.rs similarity index 51% rename from zluda_dump/src/cuda.rs rename to cuda_base/src/cuda.rs index 208b59b..232762d 100644 --- a/zluda_dump/src/cuda.rs +++ b/cuda_base/src/cuda.rs @@ -1,4072 +1,7076 @@ -/* automatically generated by rust-bindgen 0.56.0 */ - -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 usize); -#[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)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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_SPARSE_CUDA_ARRAY_SUPPORTED: CUdevice_attribute_enum = - CUdevice_attribute_enum(112); -} -impl CUdevice_attribute_enum { - pub const CU_DEVICE_ATTRIBUTE_READ_ONLY_HOST_REGISTER_SUPPORTED: CUdevice_attribute_enum = - CUdevice_attribute_enum(113); -} -impl CUdevice_attribute_enum { - pub const CU_DEVICE_ATTRIBUTE_MAX: CUdevice_attribute_enum = CUdevice_attribute_enum(114); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -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); -} -impl CUpointer_attribute_enum { - pub const CU_POINTER_ATTRIBUTE_ACCESS_FLAGS: CUpointer_attribute_enum = - CUpointer_attribute_enum(16); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUresourcetype_enum(pub ::std::os::raw::c_uint); -pub use self::CUresourcetype_enum as CUresourcetype; -pub type CUhostFn = - ::std::option::Option; -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(Copy, Clone, Hash, PartialEq, Eq)] -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); -} -impl CUgraphNodeType_enum { - pub const CU_GRAPH_NODE_TYPE_WAIT_EVENT: CUgraphNodeType_enum = CUgraphNodeType_enum(6); -} -impl CUgraphNodeType_enum { - pub const CU_GRAPH_NODE_TYPE_EVENT_RECORD: CUgraphNodeType_enum = CUgraphNodeType_enum(7); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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_STUB_LIBRARY: cudaError_enum = cudaError_enum(34); -} -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_DEVICE_NOT_LICENSED: cudaError_enum = cudaError_enum(102); -} -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_UNSUPPORTED_PTX_VERSION: cudaError_enum = cudaError_enum(222); -} -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(Copy, Clone, Hash, PartialEq, Eq, Debug)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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 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_ARRAY_SPARSE_PROPERTIES_st { - pub tileExtent: CUDA_ARRAY_SPARSE_PROPERTIES_st__bindgen_ty_1, - pub miptailFirstLevel: ::std::os::raw::c_uint, - pub miptailSize: ::std::os::raw::c_ulonglong, - pub flags: ::std::os::raw::c_uint, - pub reserved: [::std::os::raw::c_uint; 4usize], -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CUDA_ARRAY_SPARSE_PROPERTIES_st__bindgen_ty_1 { - pub width: ::std::os::raw::c_uint, - pub height: ::std::os::raw::c_uint, - pub depth: ::std::os::raw::c_uint, -} -pub type CUDA_ARRAY_SPARSE_PROPERTIES = CUDA_ARRAY_SPARSE_PROPERTIES_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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -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(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUmemAllocationGranularity_flags_enum(pub ::std::os::raw::c_uint); -pub use self::CUmemAllocationGranularity_flags_enum as CUmemAllocationGranularity_flags; -impl CUarraySparseSubresourceType_enum { - pub const CU_ARRAY_SPARSE_SUBRESOURCE_TYPE_SPARSE_LEVEL: CUarraySparseSubresourceType_enum = - CUarraySparseSubresourceType_enum(0); -} -impl CUarraySparseSubresourceType_enum { - pub const CU_ARRAY_SPARSE_SUBRESOURCE_TYPE_MIPTAIL: CUarraySparseSubresourceType_enum = - CUarraySparseSubresourceType_enum(1); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUarraySparseSubresourceType_enum(pub ::std::os::raw::c_uint); -pub use self::CUarraySparseSubresourceType_enum as CUarraySparseSubresourceType; -impl CUmemOperationType_enum { - pub const CU_MEM_OPERATION_TYPE_MAP: CUmemOperationType_enum = CUmemOperationType_enum(1); -} -impl CUmemOperationType_enum { - pub const CU_MEM_OPERATION_TYPE_UNMAP: CUmemOperationType_enum = CUmemOperationType_enum(2); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUmemOperationType_enum(pub ::std::os::raw::c_uint); -pub use self::CUmemOperationType_enum as CUmemOperationType; -impl CUmemHandleType_enum { - pub const CU_MEM_HANDLE_TYPE_GENERIC: CUmemHandleType_enum = CUmemHandleType_enum(0); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUmemHandleType_enum(pub ::std::os::raw::c_uint); -pub use self::CUmemHandleType_enum as CUmemHandleType; -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CUarrayMapInfo_st { - pub resourceType: CUresourcetype, - pub resource: CUarrayMapInfo_st__bindgen_ty_1, - pub subresourceType: CUarraySparseSubresourceType, - pub subresource: CUarrayMapInfo_st__bindgen_ty_2, - pub memOperationType: CUmemOperationType, - pub memHandleType: CUmemHandleType, - pub memHandle: CUarrayMapInfo_st__bindgen_ty_3, - pub offset: ::std::os::raw::c_ulonglong, - pub deviceBitMask: ::std::os::raw::c_uint, - pub flags: ::std::os::raw::c_uint, - pub reserved: [::std::os::raw::c_uint; 2usize], -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union CUarrayMapInfo_st__bindgen_ty_1 { - pub mipmap: CUmipmappedArray, - pub array: CUarray, - _bindgen_union_align: u64, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union CUarrayMapInfo_st__bindgen_ty_2 { - pub sparseLevel: CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_1, - pub miptail: CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_2, - _bindgen_union_align: [u64; 4usize], -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_1 { - pub level: ::std::os::raw::c_uint, - pub layer: ::std::os::raw::c_uint, - pub offsetX: ::std::os::raw::c_uint, - pub offsetY: ::std::os::raw::c_uint, - pub offsetZ: ::std::os::raw::c_uint, - pub extentWidth: ::std::os::raw::c_uint, - pub extentHeight: ::std::os::raw::c_uint, - pub extentDepth: ::std::os::raw::c_uint, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_2 { - pub layer: ::std::os::raw::c_uint, - pub offset: ::std::os::raw::c_ulonglong, - pub size: ::std::os::raw::c_ulonglong, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union CUarrayMapInfo_st__bindgen_ty_3 { - pub memHandle: CUmemGenericAllocationHandle, - _bindgen_union_align: u64, -} -pub type CUarrayMapInfo = CUarrayMapInfo_st; -#[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 usage: ::std::os::raw::c_ushort, - pub reserved: [::std::os::raw::c_uchar; 4usize], -} -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(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUgraphExecUpdateResult_enum(pub ::std::os::raw::c_uint); -pub use self::CUgraphExecUpdateResult_enum as CUgraphExecUpdateResult; -extern_redirect! { - pub fn cuGetErrorString(error: CUresult, pStr: *mut *const ::std::os::raw::c_char) -> CUresult; -} -extern_redirect! { - pub fn cuGetErrorName(error: CUresult, pStr: *mut *const ::std::os::raw::c_char) -> CUresult; -} -extern_redirect! { - pub fn cuInit(Flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuDriverGetVersion(driverVersion: *mut ::std::os::raw::c_int) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGet(device: *mut CUdevice, ordinal: ::std::os::raw::c_int) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetCount(count: *mut ::std::os::raw::c_int) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetName( - name: *mut ::std::os::raw::c_char, - len: ::std::os::raw::c_int, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetLuid( - luid: *mut ::std::os::raw::c_char, - deviceNodeMask: *mut ::std::os::raw::c_uint, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceTotalMem_v2(bytes: *mut usize, dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetTexture1DLinearMaxWidth( - maxWidthInElements: *mut usize, - format: CUarray_format, - numChannels: ::std::os::raw::c_uint, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetAttribute( - pi: *mut ::std::os::raw::c_int, - attrib: CUdevice_attribute, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetNvSciSyncAttributes( - nvSciSyncAttrList: *mut ::std::os::raw::c_void, - dev: CUdevice, - flags: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetProperties(prop: *mut CUdevprop, dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceComputeCapability( - major: *mut ::std::os::raw::c_int, - minor: *mut ::std::os::raw::c_int, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxRetain(pctx: *mut CUcontext, dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxRelease(dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxRelease_v2(dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxSetFlags(dev: CUdevice, flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxSetFlags_v2(dev: CUdevice, flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxGetState( - dev: CUdevice, - flags: *mut ::std::os::raw::c_uint, - active: *mut ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxReset(dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuDevicePrimaryCtxReset_v2(dev: CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuCtxCreate_v2( - pctx: *mut CUcontext, - flags: ::std::os::raw::c_uint, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuCtxDestroy_v2(ctx: CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuCtxPushCurrent_v2(ctx: CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuCtxPopCurrent_v2(pctx: *mut CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuCtxSetCurrent(ctx: CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetCurrent(pctx: *mut CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetDevice(device: *mut CUdevice) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetFlags(flags: *mut ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuCtxSynchronize() -> CUresult; -} -extern_redirect! { - pub fn cuCtxSetLimit(limit: CUlimit, value: usize) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetLimit(pvalue: *mut usize, limit: CUlimit) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetCacheConfig(pconfig: *mut CUfunc_cache) -> CUresult; -} -extern_redirect! { - pub fn cuCtxSetCacheConfig(config: CUfunc_cache) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetSharedMemConfig(pConfig: *mut CUsharedconfig) -> CUresult; -} -extern_redirect! { - pub fn cuCtxSetSharedMemConfig(config: CUsharedconfig) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetApiVersion(ctx: CUcontext, version: *mut ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuCtxGetStreamPriorityRange( - leastPriority: *mut ::std::os::raw::c_int, - greatestPriority: *mut ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuCtxResetPersistingL2Cache() -> CUresult; -} -extern_redirect! { - pub fn cuCtxAttach(pctx: *mut CUcontext, flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuCtxDetach(ctx: CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuModuleLoad(module: *mut CUmodule, fname: *const ::std::os::raw::c_char) -> CUresult; -} -extern_redirect_with! { - pub fn cuModuleLoadData( - module: *mut CUmodule, - image: *const ::std::os::raw::c_void, - ) -> CUresult; - super::cuModuleLoadData; -} -extern_redirect_with! { - pub 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; - super::cuModuleLoadDataEx; -} -extern_redirect! { - pub fn cuModuleLoadFatBinary( - module: *mut CUmodule, - fatCubin: *const ::std::os::raw::c_void, - ) -> CUresult; -} -extern_redirect! { - pub fn cuModuleUnload(hmod: CUmodule) -> CUresult; -} -extern_redirect_with! { - pub fn cuModuleGetFunction( - hfunc: *mut CUfunction, - hmod: CUmodule, - name: *const ::std::os::raw::c_char, - ) -> CUresult; - super::cuModuleGetFunction; -} -extern_redirect! { - pub fn cuModuleGetGlobal_v2( - dptr: *mut CUdeviceptr, - bytes: *mut usize, - hmod: CUmodule, - name: *const ::std::os::raw::c_char, - ) -> CUresult; -} -extern_redirect! { - pub fn cuModuleGetTexRef( - pTexRef: *mut CUtexref, - hmod: CUmodule, - name: *const ::std::os::raw::c_char, - ) -> CUresult; -} -extern_redirect! { - pub fn cuModuleGetSurfRef( - pSurfRef: *mut CUsurfref, - hmod: CUmodule, - name: *const ::std::os::raw::c_char, - ) -> CUresult; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub fn cuLinkComplete( - state: CUlinkState, - cubinOut: *mut *mut ::std::os::raw::c_void, - sizeOut: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuLinkDestroy(state: CUlinkState) -> CUresult; -} -extern_redirect! { - pub fn cuMemGetInfo_v2(free: *mut usize, total: *mut usize) -> CUresult; -} -extern_redirect_with! { - pub fn cuMemAlloc_v2(dptr: *mut CUdeviceptr, bytesize: usize) -> CUresult; - super::cuMemAlloc_v2; -} -extern_redirect! { - pub fn cuMemAllocPitch_v2( - dptr: *mut CUdeviceptr, - pPitch: *mut usize, - WidthInBytes: usize, - Height: usize, - ElementSizeBytes: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemFree_v2(dptr: CUdeviceptr) -> CUresult; -} -extern_redirect! { - pub fn cuMemGetAddressRange_v2( - pbase: *mut CUdeviceptr, - psize: *mut usize, - dptr: CUdeviceptr, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemAllocHost_v2(pp: *mut *mut ::std::os::raw::c_void, bytesize: usize) -> CUresult; -} -extern_redirect! { - pub fn cuMemFreeHost(p: *mut ::std::os::raw::c_void) -> CUresult; -} -extern_redirect! { - pub fn cuMemHostAlloc( - pp: *mut *mut ::std::os::raw::c_void, - bytesize: usize, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemHostGetDevicePointer_v2( - pdptr: *mut CUdeviceptr, - p: *mut ::std::os::raw::c_void, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemHostGetFlags( - pFlags: *mut ::std::os::raw::c_uint, - p: *mut ::std::os::raw::c_void, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemAllocManaged( - dptr: *mut CUdeviceptr, - bytesize: usize, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetByPCIBusId( - dev: *mut CUdevice, - pciBusId: *const ::std::os::raw::c_char, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetPCIBusId( - pciBusId: *mut ::std::os::raw::c_char, - len: ::std::os::raw::c_int, - dev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuIpcGetEventHandle(pHandle: *mut CUipcEventHandle, event: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuIpcOpenEventHandle(phEvent: *mut CUevent, handle: CUipcEventHandle) -> CUresult; -} -extern_redirect! { - pub fn cuIpcGetMemHandle(pHandle: *mut CUipcMemHandle, dptr: CUdeviceptr) -> CUresult; -} -extern_redirect! { - pub fn cuIpcOpenMemHandle( - pdptr: *mut CUdeviceptr, - handle: CUipcMemHandle, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuIpcOpenMemHandle_v2( - pdptr: *mut CUdeviceptr, - handle: CUipcMemHandle, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuIpcCloseMemHandle(dptr: CUdeviceptr) -> CUresult; -} -extern_redirect! { - pub fn cuMemHostRegister_v2( - p: *mut ::std::os::raw::c_void, - bytesize: usize, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemHostUnregister(p: *mut ::std::os::raw::c_void) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy(dst: CUdeviceptr, src: CUdeviceptr, ByteCount: usize) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyPeer( - dstDevice: CUdeviceptr, - dstContext: CUcontext, - srcDevice: CUdeviceptr, - srcContext: CUcontext, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyHtoD_v2( - dstDevice: CUdeviceptr, - srcHost: *const ::std::os::raw::c_void, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyDtoH_v2( - dstHost: *mut ::std::os::raw::c_void, - srcDevice: CUdeviceptr, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyDtoD_v2( - dstDevice: CUdeviceptr, - srcDevice: CUdeviceptr, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyDtoA_v2( - dstArray: CUarray, - dstOffset: usize, - srcDevice: CUdeviceptr, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyAtoD_v2( - dstDevice: CUdeviceptr, - srcArray: CUarray, - srcOffset: usize, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyHtoA_v2( - dstArray: CUarray, - dstOffset: usize, - srcHost: *const ::std::os::raw::c_void, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyAtoH_v2( - dstHost: *mut ::std::os::raw::c_void, - srcArray: CUarray, - srcOffset: usize, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyAtoA_v2( - dstArray: CUarray, - dstOffset: usize, - srcArray: CUarray, - srcOffset: usize, - ByteCount: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy2D_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy2DUnaligned_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy3D_v2(pCopy: *const CUDA_MEMCPY3D) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy3DPeer(pCopy: *const CUDA_MEMCPY3D_PEER) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyAsync( - dst: CUdeviceptr, - src: CUdeviceptr, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyPeerAsync( - dstDevice: CUdeviceptr, - dstContext: CUcontext, - srcDevice: CUdeviceptr, - srcContext: CUcontext, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyHtoDAsync_v2( - dstDevice: CUdeviceptr, - srcHost: *const ::std::os::raw::c_void, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyDtoHAsync_v2( - dstHost: *mut ::std::os::raw::c_void, - srcDevice: CUdeviceptr, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyDtoDAsync_v2( - dstDevice: CUdeviceptr, - srcDevice: CUdeviceptr, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyHtoAAsync_v2( - dstArray: CUarray, - dstOffset: usize, - srcHost: *const ::std::os::raw::c_void, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpyAtoHAsync_v2( - dstHost: *mut ::std::os::raw::c_void, - srcArray: CUarray, - srcOffset: usize, - ByteCount: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy2DAsync_v2(pCopy: *const CUDA_MEMCPY2D, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy3DAsync_v2(pCopy: *const CUDA_MEMCPY3D, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuMemcpy3DPeerAsync(pCopy: *const CUDA_MEMCPY3D_PEER, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD8_v2(dstDevice: CUdeviceptr, uc: ::std::os::raw::c_uchar, N: usize) - -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD16_v2( - dstDevice: CUdeviceptr, - us: ::std::os::raw::c_ushort, - N: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD32_v2(dstDevice: CUdeviceptr, ui: ::std::os::raw::c_uint, N: usize) - -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D8_v2( - dstDevice: CUdeviceptr, - dstPitch: usize, - uc: ::std::os::raw::c_uchar, - Width: usize, - Height: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D16_v2( - dstDevice: CUdeviceptr, - dstPitch: usize, - us: ::std::os::raw::c_ushort, - Width: usize, - Height: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D32_v2( - dstDevice: CUdeviceptr, - dstPitch: usize, - ui: ::std::os::raw::c_uint, - Width: usize, - Height: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD8Async( - dstDevice: CUdeviceptr, - uc: ::std::os::raw::c_uchar, - N: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD16Async( - dstDevice: CUdeviceptr, - us: ::std::os::raw::c_ushort, - N: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD32Async( - dstDevice: CUdeviceptr, - ui: ::std::os::raw::c_uint, - N: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D8Async( - dstDevice: CUdeviceptr, - dstPitch: usize, - uc: ::std::os::raw::c_uchar, - Width: usize, - Height: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D16Async( - dstDevice: CUdeviceptr, - dstPitch: usize, - us: ::std::os::raw::c_ushort, - Width: usize, - Height: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemsetD2D32Async( - dstDevice: CUdeviceptr, - dstPitch: usize, - ui: ::std::os::raw::c_uint, - Width: usize, - Height: usize, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuArrayCreate_v2( - pHandle: *mut CUarray, - pAllocateArray: *const CUDA_ARRAY_DESCRIPTOR, - ) -> CUresult; -} -extern_redirect! { - pub fn cuArrayGetDescriptor_v2( - pArrayDescriptor: *mut CUDA_ARRAY_DESCRIPTOR, - hArray: CUarray, - ) -> CUresult; -} -extern_redirect! { - pub fn cuArrayGetSparseProperties( - sparseProperties: *mut CUDA_ARRAY_SPARSE_PROPERTIES, - array: CUarray, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMipmappedArrayGetSparseProperties( - sparseProperties: *mut CUDA_ARRAY_SPARSE_PROPERTIES, - mipmap: CUmipmappedArray, - ) -> CUresult; -} -extern_redirect! { - pub fn cuArrayDestroy(hArray: CUarray) -> CUresult; -} -extern_redirect! { - pub fn cuArray3DCreate_v2( - pHandle: *mut CUarray, - pAllocateArray: *const CUDA_ARRAY3D_DESCRIPTOR, - ) -> CUresult; -} -extern_redirect! { - pub fn cuArray3DGetDescriptor_v2( - pArrayDescriptor: *mut CUDA_ARRAY3D_DESCRIPTOR, - hArray: CUarray, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMipmappedArrayCreate( - pHandle: *mut CUmipmappedArray, - pMipmappedArrayDesc: *const CUDA_ARRAY3D_DESCRIPTOR, - numMipmapLevels: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMipmappedArrayGetLevel( - pLevelArray: *mut CUarray, - hMipmappedArray: CUmipmappedArray, - level: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMipmappedArrayDestroy(hMipmappedArray: CUmipmappedArray) -> CUresult; -} -extern_redirect! { - pub fn cuMemAddressReserve( - ptr: *mut CUdeviceptr, - size: usize, - alignment: usize, - addr: CUdeviceptr, - flags: ::std::os::raw::c_ulonglong, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemAddressFree(ptr: CUdeviceptr, size: usize) -> CUresult; -} -extern_redirect! { - pub fn cuMemCreate( - handle: *mut CUmemGenericAllocationHandle, - size: usize, - prop: *const CUmemAllocationProp, - flags: ::std::os::raw::c_ulonglong, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemRelease(handle: CUmemGenericAllocationHandle) -> CUresult; -} -extern_redirect! { - pub fn cuMemMap( - ptr: CUdeviceptr, - size: usize, - offset: usize, - handle: CUmemGenericAllocationHandle, - flags: ::std::os::raw::c_ulonglong, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemMapArrayAsync( - mapInfoList: *mut CUarrayMapInfo, - count: ::std::os::raw::c_uint, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemUnmap(ptr: CUdeviceptr, size: usize) -> CUresult; -} -extern_redirect! { - pub fn cuMemSetAccess( - ptr: CUdeviceptr, - size: usize, - desc: *const CUmemAccessDesc, - count: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemGetAccess( - flags: *mut ::std::os::raw::c_ulonglong, - location: *const CUmemLocation, - ptr: CUdeviceptr, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemExportToShareableHandle( - shareableHandle: *mut ::std::os::raw::c_void, - handle: CUmemGenericAllocationHandle, - handleType: CUmemAllocationHandleType, - flags: ::std::os::raw::c_ulonglong, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemImportFromShareableHandle( - handle: *mut CUmemGenericAllocationHandle, - osHandle: *mut ::std::os::raw::c_void, - shHandleType: CUmemAllocationHandleType, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemGetAllocationGranularity( - granularity: *mut usize, - prop: *const CUmemAllocationProp, - option: CUmemAllocationGranularity_flags, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemGetAllocationPropertiesFromHandle( - prop: *mut CUmemAllocationProp, - handle: CUmemGenericAllocationHandle, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemRetainAllocationHandle( - handle: *mut CUmemGenericAllocationHandle, - addr: *mut ::std::os::raw::c_void, - ) -> CUresult; -} -extern_redirect! { - pub fn cuPointerGetAttribute( - data: *mut ::std::os::raw::c_void, - attribute: CUpointer_attribute, - ptr: CUdeviceptr, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemPrefetchAsync( - devPtr: CUdeviceptr, - count: usize, - dstDevice: CUdevice, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemAdvise( - devPtr: CUdeviceptr, - count: usize, - advice: CUmem_advise, - device: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuMemRangeGetAttribute( - data: *mut ::std::os::raw::c_void, - dataSize: usize, - attribute: CUmem_range_attribute, - devPtr: CUdeviceptr, - count: usize, - ) -> CUresult; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub fn cuPointerSetAttribute( - value: *const ::std::os::raw::c_void, - attribute: CUpointer_attribute, - ptr: CUdeviceptr, - ) -> CUresult; -} -extern_redirect! { - pub fn cuPointerGetAttributes( - numAttributes: ::std::os::raw::c_uint, - attributes: *mut CUpointer_attribute, - data: *mut *mut ::std::os::raw::c_void, - ptr: CUdeviceptr, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamCreate(phStream: *mut CUstream, Flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuStreamCreateWithPriority( - phStream: *mut CUstream, - flags: ::std::os::raw::c_uint, - priority: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamGetPriority(hStream: CUstream, priority: *mut ::std::os::raw::c_int) - -> CUresult; -} -extern_redirect! { - pub fn cuStreamGetFlags(hStream: CUstream, flags: *mut ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuStreamGetCtx(hStream: CUstream, pctx: *mut CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuStreamWaitEvent( - hStream: CUstream, - hEvent: CUevent, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamAddCallback( - hStream: CUstream, - callback: CUstreamCallback, - userData: *mut ::std::os::raw::c_void, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamBeginCapture_v2(hStream: CUstream, mode: CUstreamCaptureMode) -> CUresult; -} -extern_redirect! { - pub fn cuThreadExchangeStreamCaptureMode(mode: *mut CUstreamCaptureMode) -> CUresult; -} -extern_redirect! { - pub fn cuStreamEndCapture(hStream: CUstream, phGraph: *mut CUgraph) -> CUresult; -} -extern_redirect! { - pub fn cuStreamIsCapturing( - hStream: CUstream, - captureStatus: *mut CUstreamCaptureStatus, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamGetCaptureInfo( - hStream: CUstream, - captureStatus: *mut CUstreamCaptureStatus, - id: *mut cuuint64_t, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamAttachMemAsync( - hStream: CUstream, - dptr: CUdeviceptr, - length: usize, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamQuery(hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuStreamSynchronize(hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuStreamDestroy_v2(hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuStreamCopyAttributes(dst: CUstream, src: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuStreamGetAttribute( - hStream: CUstream, - attr: CUstreamAttrID, - value_out: *mut CUstreamAttrValue, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamSetAttribute( - hStream: CUstream, - attr: CUstreamAttrID, - value: *const CUstreamAttrValue, - ) -> CUresult; -} -extern_redirect! { - pub fn cuEventCreate(phEvent: *mut CUevent, Flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuEventRecord(hEvent: CUevent, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuEventRecordWithFlags( - hEvent: CUevent, - hStream: CUstream, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuEventQuery(hEvent: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuEventSynchronize(hEvent: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuEventDestroy_v2(hEvent: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuEventElapsedTime(pMilliseconds: *mut f32, hStart: CUevent, hEnd: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuImportExternalMemory( - extMem_out: *mut CUexternalMemory, - memHandleDesc: *const CUDA_EXTERNAL_MEMORY_HANDLE_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuExternalMemoryGetMappedBuffer( - devPtr: *mut CUdeviceptr, - extMem: CUexternalMemory, - bufferDesc: *const CUDA_EXTERNAL_MEMORY_BUFFER_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuExternalMemoryGetMappedMipmappedArray( - mipmap: *mut CUmipmappedArray, - extMem: CUexternalMemory, - mipmapDesc: *const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDestroyExternalMemory(extMem: CUexternalMemory) -> CUresult; -} -extern_redirect! { - pub fn cuImportExternalSemaphore( - extSem_out: *mut CUexternalSemaphore, - semHandleDesc: *const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuSignalExternalSemaphoresAsync( - extSemArray: *const CUexternalSemaphore, - paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS, - numExtSems: ::std::os::raw::c_uint, - stream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuWaitExternalSemaphoresAsync( - extSemArray: *const CUexternalSemaphore, - paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS, - numExtSems: ::std::os::raw::c_uint, - stream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDestroyExternalSemaphore(extSem: CUexternalSemaphore) -> CUresult; -} -extern_redirect! { - pub fn cuStreamWaitValue32( - stream: CUstream, - addr: CUdeviceptr, - value: cuuint32_t, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamWaitValue64( - stream: CUstream, - addr: CUdeviceptr, - value: cuuint64_t, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamWriteValue32( - stream: CUstream, - addr: CUdeviceptr, - value: cuuint32_t, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamWriteValue64( - stream: CUstream, - addr: CUdeviceptr, - value: cuuint64_t, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuStreamBatchMemOp( - stream: CUstream, - count: ::std::os::raw::c_uint, - paramArray: *mut CUstreamBatchMemOpParams, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuFuncGetAttribute( - pi: *mut ::std::os::raw::c_int, - attrib: CUfunction_attribute, - hfunc: CUfunction, - ) -> CUresult; -} -extern_redirect! { - pub fn cuFuncSetAttribute( - hfunc: CUfunction, - attrib: CUfunction_attribute, - value: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuFuncSetCacheConfig(hfunc: CUfunction, config: CUfunc_cache) -> CUresult; -} -extern_redirect! { - pub fn cuFuncSetSharedMemConfig(hfunc: CUfunction, config: CUsharedconfig) -> CUresult; -} -extern_redirect_with! { - pub 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; - super::cuLaunchKernel; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub fn cuLaunchCooperativeKernelMultiDevice( - launchParamsList: *mut CUDA_LAUNCH_PARAMS, - numDevices: ::std::os::raw::c_uint, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuLaunchHostFunc( - hStream: CUstream, - fn_: CUhostFn, - userData: *mut ::std::os::raw::c_void, - ) -> CUresult; -} -extern_redirect! { - pub fn cuFuncSetBlockShape( - hfunc: CUfunction, - x: ::std::os::raw::c_int, - y: ::std::os::raw::c_int, - z: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuFuncSetSharedSize(hfunc: CUfunction, bytes: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuParamSetSize(hfunc: CUfunction, numbytes: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuParamSeti( - hfunc: CUfunction, - offset: ::std::os::raw::c_int, - value: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuParamSetf(hfunc: CUfunction, offset: ::std::os::raw::c_int, value: f32) -> CUresult; -} -extern_redirect! { - pub fn cuParamSetv( - hfunc: CUfunction, - offset: ::std::os::raw::c_int, - ptr: *mut ::std::os::raw::c_void, - numbytes: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuLaunch(f: CUfunction) -> CUresult; -} -extern_redirect! { - pub fn cuLaunchGrid( - f: CUfunction, - grid_width: ::std::os::raw::c_int, - grid_height: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuLaunchGridAsync( - f: CUfunction, - grid_width: ::std::os::raw::c_int, - grid_height: ::std::os::raw::c_int, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuParamSetTexRef( - hfunc: CUfunction, - texunit: ::std::os::raw::c_int, - hTexRef: CUtexref, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphCreate(phGraph: *mut CUgraph, flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddKernelNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - nodeParams: *const CUDA_KERNEL_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphKernelNodeGetParams( - hNode: CUgraphNode, - nodeParams: *mut CUDA_KERNEL_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphKernelNodeSetParams( - hNode: CUgraphNode, - nodeParams: *const CUDA_KERNEL_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddMemcpyNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - copyParams: *const CUDA_MEMCPY3D, - ctx: CUcontext, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphMemcpyNodeGetParams( - hNode: CUgraphNode, - nodeParams: *mut CUDA_MEMCPY3D, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphMemcpyNodeSetParams( - hNode: CUgraphNode, - nodeParams: *const CUDA_MEMCPY3D, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddMemsetNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - memsetParams: *const CUDA_MEMSET_NODE_PARAMS, - ctx: CUcontext, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphMemsetNodeGetParams( - hNode: CUgraphNode, - nodeParams: *mut CUDA_MEMSET_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphMemsetNodeSetParams( - hNode: CUgraphNode, - nodeParams: *const CUDA_MEMSET_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddHostNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - nodeParams: *const CUDA_HOST_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphHostNodeGetParams( - hNode: CUgraphNode, - nodeParams: *mut CUDA_HOST_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphHostNodeSetParams( - hNode: CUgraphNode, - nodeParams: *const CUDA_HOST_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddChildGraphNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - childGraph: CUgraph, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphChildGraphNodeGetGraph(hNode: CUgraphNode, phGraph: *mut CUgraph) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddEmptyNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddEventRecordNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - event: CUevent, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphEventRecordNodeGetEvent(hNode: CUgraphNode, event_out: *mut CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuGraphEventRecordNodeSetEvent(hNode: CUgraphNode, event: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddEventWaitNode( - phGraphNode: *mut CUgraphNode, - hGraph: CUgraph, - dependencies: *const CUgraphNode, - numDependencies: usize, - event: CUevent, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphEventWaitNodeGetEvent(hNode: CUgraphNode, event_out: *mut CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuGraphEventWaitNodeSetEvent(hNode: CUgraphNode, event: CUevent) -> CUresult; -} -extern_redirect! { - pub fn cuGraphClone(phGraphClone: *mut CUgraph, originalGraph: CUgraph) -> CUresult; -} -extern_redirect! { - pub fn cuGraphNodeFindInClone( - phNode: *mut CUgraphNode, - hOriginalNode: CUgraphNode, - hClonedGraph: CUgraph, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphNodeGetType(hNode: CUgraphNode, type_: *mut CUgraphNodeType) -> CUresult; -} -extern_redirect! { - pub fn cuGraphGetNodes( - hGraph: CUgraph, - nodes: *mut CUgraphNode, - numNodes: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphGetRootNodes( - hGraph: CUgraph, - rootNodes: *mut CUgraphNode, - numRootNodes: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphGetEdges( - hGraph: CUgraph, - from: *mut CUgraphNode, - to: *mut CUgraphNode, - numEdges: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphNodeGetDependencies( - hNode: CUgraphNode, - dependencies: *mut CUgraphNode, - numDependencies: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphNodeGetDependentNodes( - hNode: CUgraphNode, - dependentNodes: *mut CUgraphNode, - numDependentNodes: *mut usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphAddDependencies( - hGraph: CUgraph, - from: *const CUgraphNode, - to: *const CUgraphNode, - numDependencies: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphRemoveDependencies( - hGraph: CUgraph, - from: *const CUgraphNode, - to: *const CUgraphNode, - numDependencies: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphDestroyNode(hNode: CUgraphNode) -> CUresult; -} -extern_redirect! { - pub fn cuGraphInstantiate_v2( - phGraphExec: *mut CUgraphExec, - hGraph: CUgraph, - phErrorNode: *mut CUgraphNode, - logBuffer: *mut ::std::os::raw::c_char, - bufferSize: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecKernelNodeSetParams( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - nodeParams: *const CUDA_KERNEL_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecMemcpyNodeSetParams( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - copyParams: *const CUDA_MEMCPY3D, - ctx: CUcontext, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecMemsetNodeSetParams( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - memsetParams: *const CUDA_MEMSET_NODE_PARAMS, - ctx: CUcontext, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecHostNodeSetParams( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - nodeParams: *const CUDA_HOST_NODE_PARAMS, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecChildGraphNodeSetParams( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - childGraph: CUgraph, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecEventRecordNodeSetEvent( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - event: CUevent, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecEventWaitNodeSetEvent( - hGraphExec: CUgraphExec, - hNode: CUgraphNode, - event: CUevent, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphUpload(hGraphExec: CUgraphExec, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuGraphLaunch(hGraphExec: CUgraphExec, hStream: CUstream) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecDestroy(hGraphExec: CUgraphExec) -> CUresult; -} -extern_redirect! { - pub fn cuGraphDestroy(hGraph: CUgraph) -> CUresult; -} -extern_redirect! { - pub fn cuGraphExecUpdate( - hGraphExec: CUgraphExec, - hGraph: CUgraph, - hErrorNode_out: *mut CUgraphNode, - updateResult_out: *mut CUgraphExecUpdateResult, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphKernelNodeCopyAttributes(dst: CUgraphNode, src: CUgraphNode) -> CUresult; -} -extern_redirect! { - pub fn cuGraphKernelNodeGetAttribute( - hNode: CUgraphNode, - attr: CUkernelNodeAttrID, - value_out: *mut CUkernelNodeAttrValue, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphKernelNodeSetAttribute( - hNode: CUgraphNode, - attr: CUkernelNodeAttrID, - value: *const CUkernelNodeAttrValue, - ) -> CUresult; -} -extern_redirect! { - pub fn cuOccupancyMaxActiveBlocksPerMultiprocessor( - numBlocks: *mut ::std::os::raw::c_int, - func: CUfunction, - blockSize: ::std::os::raw::c_int, - dynamicSMemSize: usize, - ) -> CUresult; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub 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; -} -extern_redirect! { - pub fn cuOccupancyAvailableDynamicSMemPerBlock( - dynamicSmemSize: *mut usize, - func: CUfunction, - numBlocks: ::std::os::raw::c_int, - blockSize: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetArray( - hTexRef: CUtexref, - hArray: CUarray, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetMipmappedArray( - hTexRef: CUtexref, - hMipmappedArray: CUmipmappedArray, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetAddress_v2( - ByteOffset: *mut usize, - hTexRef: CUtexref, - dptr: CUdeviceptr, - bytes: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetAddress2D_v3( - hTexRef: CUtexref, - desc: *const CUDA_ARRAY_DESCRIPTOR, - dptr: CUdeviceptr, - Pitch: usize, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetFormat( - hTexRef: CUtexref, - fmt: CUarray_format, - NumPackedComponents: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetAddressMode( - hTexRef: CUtexref, - dim: ::std::os::raw::c_int, - am: CUaddress_mode, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetMipmapFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetMipmapLevelBias(hTexRef: CUtexref, bias: f32) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetMipmapLevelClamp( - hTexRef: CUtexref, - minMipmapLevelClamp: f32, - maxMipmapLevelClamp: f32, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetMaxAnisotropy( - hTexRef: CUtexref, - maxAniso: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetBorderColor(hTexRef: CUtexref, pBorderColor: *mut f32) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefSetFlags(hTexRef: CUtexref, Flags: ::std::os::raw::c_uint) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetAddress_v2(pdptr: *mut CUdeviceptr, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetArray(phArray: *mut CUarray, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetMipmappedArray( - phMipmappedArray: *mut CUmipmappedArray, - hTexRef: CUtexref, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetAddressMode( - pam: *mut CUaddress_mode, - hTexRef: CUtexref, - dim: ::std::os::raw::c_int, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetFilterMode(pfm: *mut CUfilter_mode, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetFormat( - pFormat: *mut CUarray_format, - pNumChannels: *mut ::std::os::raw::c_int, - hTexRef: CUtexref, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetMipmapFilterMode(pfm: *mut CUfilter_mode, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetMipmapLevelBias(pbias: *mut f32, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetMipmapLevelClamp( - pminMipmapLevelClamp: *mut f32, - pmaxMipmapLevelClamp: *mut f32, - hTexRef: CUtexref, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetMaxAnisotropy( - pmaxAniso: *mut ::std::os::raw::c_int, - hTexRef: CUtexref, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetBorderColor(pBorderColor: *mut f32, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefGetFlags(pFlags: *mut ::std::os::raw::c_uint, hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefCreate(pTexRef: *mut CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuTexRefDestroy(hTexRef: CUtexref) -> CUresult; -} -extern_redirect! { - pub fn cuSurfRefSetArray( - hSurfRef: CUsurfref, - hArray: CUarray, - Flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuSurfRefGetArray(phArray: *mut CUarray, hSurfRef: CUsurfref) -> CUresult; -} -extern_redirect! { - pub fn cuTexObjectCreate( - pTexObject: *mut CUtexObject, - pResDesc: *const CUDA_RESOURCE_DESC, - pTexDesc: *const CUDA_TEXTURE_DESC, - pResViewDesc: *const CUDA_RESOURCE_VIEW_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexObjectDestroy(texObject: CUtexObject) -> CUresult; -} -extern_redirect! { - pub fn cuTexObjectGetResourceDesc( - pResDesc: *mut CUDA_RESOURCE_DESC, - texObject: CUtexObject, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexObjectGetTextureDesc( - pTexDesc: *mut CUDA_TEXTURE_DESC, - texObject: CUtexObject, - ) -> CUresult; -} -extern_redirect! { - pub fn cuTexObjectGetResourceViewDesc( - pResViewDesc: *mut CUDA_RESOURCE_VIEW_DESC, - texObject: CUtexObject, - ) -> CUresult; -} -extern_redirect! { - pub fn cuSurfObjectCreate( - pSurfObject: *mut CUsurfObject, - pResDesc: *const CUDA_RESOURCE_DESC, - ) -> CUresult; -} -extern_redirect! { - pub fn cuSurfObjectDestroy(surfObject: CUsurfObject) -> CUresult; -} -extern_redirect! { - pub fn cuSurfObjectGetResourceDesc( - pResDesc: *mut CUDA_RESOURCE_DESC, - surfObject: CUsurfObject, - ) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceCanAccessPeer( - canAccessPeer: *mut ::std::os::raw::c_int, - dev: CUdevice, - peerDev: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuCtxEnablePeerAccess(peerContext: CUcontext, Flags: ::std::os::raw::c_uint) - -> CUresult; -} -extern_redirect! { - pub fn cuCtxDisablePeerAccess(peerContext: CUcontext) -> CUresult; -} -extern_redirect! { - pub fn cuDeviceGetP2PAttribute( - value: *mut ::std::os::raw::c_int, - attrib: CUdevice_P2PAttribute, - srcDevice: CUdevice, - dstDevice: CUdevice, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsUnregisterResource(resource: CUgraphicsResource) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsSubResourceGetMappedArray( - pArray: *mut CUarray, - resource: CUgraphicsResource, - arrayIndex: ::std::os::raw::c_uint, - mipLevel: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsResourceGetMappedMipmappedArray( - pMipmappedArray: *mut CUmipmappedArray, - resource: CUgraphicsResource, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsResourceGetMappedPointer_v2( - pDevPtr: *mut CUdeviceptr, - pSize: *mut usize, - resource: CUgraphicsResource, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsResourceSetMapFlags_v2( - resource: CUgraphicsResource, - flags: ::std::os::raw::c_uint, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsMapResources( - count: ::std::os::raw::c_uint, - resources: *mut CUgraphicsResource, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect! { - pub fn cuGraphicsUnmapResources( - count: ::std::os::raw::c_uint, - resources: *mut CUgraphicsResource, - hStream: CUstream, - ) -> CUresult; -} -extern_redirect_with! { - pub fn cuGetExportTable( - ppExportTable: *mut *const ::std::os::raw::c_void, - pExportTableId: *const CUuuid, - ) -> CUresult; - super::cuGetExportTable; -} -extern_redirect! { - pub fn cuFuncGetModule(hmod: *mut CUmodule, hfunc: CUfunction) -> CUresult; -} +/* automatically generated by rust-bindgen 0.66.1 */ + +pub const CUDA_VERSION: u32 = 12020; +pub const CU_IPC_HANDLE_SIZE: u32 = 64; +pub const CU_COMPUTE_ACCELERATED_TARGET_BASE: u32 = 65536; +pub const CU_MEMHOSTALLOC_PORTABLE: u32 = 1; +pub const CU_MEMHOSTALLOC_DEVICEMAP: u32 = 2; +pub const CU_MEMHOSTALLOC_WRITECOMBINED: u32 = 4; +pub const CU_MEMHOSTREGISTER_PORTABLE: u32 = 1; +pub const CU_MEMHOSTREGISTER_DEVICEMAP: u32 = 2; +pub const CU_MEMHOSTREGISTER_IOMEMORY: u32 = 4; +pub const CU_MEMHOSTREGISTER_READ_ONLY: u32 = 8; +pub const CU_ARRAY_SPARSE_PROPERTIES_SINGLE_MIPTAIL: u32 = 1; +pub const CU_TENSOR_MAP_NUM_QWORDS: u32 = 16; +pub const CUDA_EXTERNAL_MEMORY_DEDICATED: u32 = 1; +pub const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_SKIP_NVSCIBUF_MEMSYNC: u32 = 1; +pub const CUDA_EXTERNAL_SEMAPHORE_WAIT_SKIP_NVSCIBUF_MEMSYNC: u32 = 2; +pub const CUDA_NVSCISYNC_ATTR_SIGNAL: u32 = 1; +pub const CUDA_NVSCISYNC_ATTR_WAIT: u32 = 2; +pub const CU_MEM_CREATE_USAGE_TILE_POOL: u32 = 1; +pub const CUDA_COOPERATIVE_LAUNCH_MULTI_DEVICE_NO_PRE_LAUNCH_SYNC: u32 = 1; +pub const CUDA_COOPERATIVE_LAUNCH_MULTI_DEVICE_NO_POST_LAUNCH_SYNC: u32 = 2; +pub const CUDA_ARRAY3D_LAYERED: u32 = 1; +pub const CUDA_ARRAY3D_2DARRAY: u32 = 1; +pub const CUDA_ARRAY3D_SURFACE_LDST: u32 = 2; +pub const CUDA_ARRAY3D_CUBEMAP: u32 = 4; +pub const CUDA_ARRAY3D_TEXTURE_GATHER: u32 = 8; +pub const CUDA_ARRAY3D_DEPTH_TEXTURE: u32 = 16; +pub const CUDA_ARRAY3D_COLOR_ATTACHMENT: u32 = 32; +pub const CUDA_ARRAY3D_SPARSE: u32 = 64; +pub const CUDA_ARRAY3D_DEFERRED_MAPPING: u32 = 128; +pub const CU_TRSA_OVERRIDE_FORMAT: u32 = 1; +pub const CU_TRSF_READ_AS_INTEGER: u32 = 1; +pub const CU_TRSF_NORMALIZED_COORDINATES: u32 = 2; +pub const CU_TRSF_SRGB: u32 = 16; +pub const CU_TRSF_DISABLE_TRILINEAR_OPTIMIZATION: u32 = 32; +pub const CU_TRSF_SEAMLESS_CUBEMAP: u32 = 64; +pub const CU_LAUNCH_PARAM_END_AS_INT: u32 = 0; +pub const CU_LAUNCH_PARAM_BUFFER_POINTER_AS_INT: u32 = 1; +pub const CU_LAUNCH_PARAM_BUFFER_SIZE_AS_INT: u32 = 2; +pub const CU_PARAM_TR_DEFAULT: i32 = -1; +pub type cuuint32_t = ::std::os::raw::c_uint; +pub type cuuint64_t = ::std::os::raw::c_ulonglong; +#[repr(transparent)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUdeviceptr_v2(pub ::std::os::raw::c_ulonglong); +pub type CUdeviceptr = CUdeviceptr_v2; +#[repr(transparent)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUdevice_v1(pub ::std::os::raw::c_int); +pub type CUdevice = CUdevice_v1; +#[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 CUlib_st { + _unused: [u8; 0], +} +pub type CUlibrary = *mut CUlib_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUkern_st { + _unused: [u8; 0], +} +pub type CUkernel = *mut CUkern_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_v1 = ::std::os::raw::c_ulonglong; +pub type CUtexObject = CUtexObject_v1; +pub type CUsurfObject_v1 = ::std::os::raw::c_ulonglong; +pub type CUsurfObject = CUsurfObject_v1; +#[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)] +pub struct CUmemPoolHandle_st { + _unused: [u8; 0], +} +pub type CUmemoryPool = *mut CUmemPoolHandle_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUuserObject_st { + _unused: [u8; 0], +} +pub type CUuserObject = *mut CUuserObject_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUuuid_st { + pub bytes: [::std::os::raw::c_char; 16usize], +} +pub type CUuuid = CUuuid_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUipcEventHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +pub type CUipcEventHandle_v1 = CUipcEventHandle_st; +pub type CUipcEventHandle = CUipcEventHandle_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUipcMemHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +pub type CUipcMemHandle_v1 = CUipcMemHandle_st; +pub type CUipcMemHandle = CUipcMemHandle_v1; +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_BARRIER: CUstreamBatchMemOpType_enum = + CUstreamBatchMemOpType_enum(6); +} +impl CUstreamBatchMemOpType_enum { + pub const CU_STREAM_MEM_OP_FLUSH_REMOTE_WRITES: CUstreamBatchMemOpType_enum = + CUstreamBatchMemOpType_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUstreamBatchMemOpType_enum(pub ::std::os::raw::c_int); +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 memoryBarrier: CUstreamBatchMemOpParams_union_CUstreamMemOpMemoryBarrierParams_st, + pub pad: [cuuint64_t; 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, +} +#[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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUstreamBatchMemOpParams_union_CUstreamMemOpFlushRemoteWritesParams_st { + pub operation: CUstreamBatchMemOpType, + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUstreamBatchMemOpParams_union_CUstreamMemOpMemoryBarrierParams_st { + pub operation: CUstreamBatchMemOpType, + pub flags: ::std::os::raw::c_uint, +} +pub type CUstreamBatchMemOpParams_v1 = CUstreamBatchMemOpParams_union; +pub type CUstreamBatchMemOpParams = CUstreamBatchMemOpParams_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_BATCH_MEM_OP_NODE_PARAMS_v1_st { + pub ctx: CUcontext, + pub count: ::std::os::raw::c_uint, + pub paramArray: *mut CUstreamBatchMemOpParams, + pub flags: ::std::os::raw::c_uint, +} +pub type CUDA_BATCH_MEM_OP_NODE_PARAMS_v1 = CUDA_BATCH_MEM_OP_NODE_PARAMS_v1_st; +pub type CUDA_BATCH_MEM_OP_NODE_PARAMS = CUDA_BATCH_MEM_OP_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_BATCH_MEM_OP_NODE_PARAMS_v2_st { + pub ctx: CUcontext, + pub count: ::std::os::raw::c_uint, + pub paramArray: *mut CUstreamBatchMemOpParams, + pub flags: ::std::os::raw::c_uint, +} +pub type CUDA_BATCH_MEM_OP_NODE_PARAMS_v2 = CUDA_BATCH_MEM_OP_NODE_PARAMS_v2_st; +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); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_NV12: CUarray_format_enum = CUarray_format_enum(176); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT8X1: CUarray_format_enum = CUarray_format_enum(192); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT8X2: CUarray_format_enum = CUarray_format_enum(193); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT8X4: CUarray_format_enum = CUarray_format_enum(194); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT16X1: CUarray_format_enum = CUarray_format_enum(195); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT16X2: CUarray_format_enum = CUarray_format_enum(196); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_UNORM_INT16X4: CUarray_format_enum = CUarray_format_enum(197); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT8X1: CUarray_format_enum = CUarray_format_enum(198); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT8X2: CUarray_format_enum = CUarray_format_enum(199); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT8X4: CUarray_format_enum = CUarray_format_enum(200); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT16X1: CUarray_format_enum = CUarray_format_enum(201); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT16X2: CUarray_format_enum = CUarray_format_enum(202); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_SNORM_INT16X4: CUarray_format_enum = CUarray_format_enum(203); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC1_UNORM: CUarray_format_enum = CUarray_format_enum(145); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC1_UNORM_SRGB: CUarray_format_enum = CUarray_format_enum(146); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC2_UNORM: CUarray_format_enum = CUarray_format_enum(147); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC2_UNORM_SRGB: CUarray_format_enum = CUarray_format_enum(148); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC3_UNORM: CUarray_format_enum = CUarray_format_enum(149); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC3_UNORM_SRGB: CUarray_format_enum = CUarray_format_enum(150); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC4_UNORM: CUarray_format_enum = CUarray_format_enum(151); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC4_SNORM: CUarray_format_enum = CUarray_format_enum(152); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC5_UNORM: CUarray_format_enum = CUarray_format_enum(153); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC5_SNORM: CUarray_format_enum = CUarray_format_enum(154); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC6H_UF16: CUarray_format_enum = CUarray_format_enum(155); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC6H_SF16: CUarray_format_enum = CUarray_format_enum(156); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC7_UNORM: CUarray_format_enum = CUarray_format_enum(157); +} +impl CUarray_format_enum { + pub const CU_AD_FORMAT_BC7_UNORM_SRGB: CUarray_format_enum = CUarray_format_enum(158); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub struct CUarray_format_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUaddress_mode_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUfilter_mode_enum(pub ::std::os::raw::c_int); +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_V1: CUdevice_attribute_enum = + CUdevice_attribute_enum(92); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_CAN_USE_64_BIT_STREAM_MEM_OPS_V1: CUdevice_attribute_enum = + CUdevice_attribute_enum(93); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR_V1: 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_VIRTUAL_MEMORY_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_SPARSE_CUDA_ARRAY_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(112); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_READ_ONLY_HOST_REGISTER_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(113); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_TIMELINE_SEMAPHORE_INTEROP_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(114); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_MEMORY_POOLS_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(115); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(116); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_FLUSH_WRITES_OPTIONS: CUdevice_attribute_enum = + CUdevice_attribute_enum(117); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_WRITES_ORDERING: CUdevice_attribute_enum = + CUdevice_attribute_enum(118); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_MEMPOOL_SUPPORTED_HANDLE_TYPES: CUdevice_attribute_enum = + CUdevice_attribute_enum(119); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_CLUSTER_LAUNCH: CUdevice_attribute_enum = + CUdevice_attribute_enum(120); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_DEFERRED_MAPPING_CUDA_ARRAY_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(121); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_CAN_USE_64_BIT_STREAM_MEM_OPS: CUdevice_attribute_enum = + CUdevice_attribute_enum(122); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR: CUdevice_attribute_enum = + CUdevice_attribute_enum(123); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(124); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(125); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_MEM_SYNC_DOMAIN_COUNT: CUdevice_attribute_enum = + CUdevice_attribute_enum(126); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_TENSOR_MAP_ACCESS_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(127); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_UNIFIED_FUNCTION_POINTERS: CUdevice_attribute_enum = + CUdevice_attribute_enum(129); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_NUMA_CONFIG: CUdevice_attribute_enum = + CUdevice_attribute_enum(130); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_NUMA_ID: CUdevice_attribute_enum = CUdevice_attribute_enum(131); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED: CUdevice_attribute_enum = + CUdevice_attribute_enum(132); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_HOST_NUMA_ID: CUdevice_attribute_enum = + CUdevice_attribute_enum(134); +} +impl CUdevice_attribute_enum { + pub const CU_DEVICE_ATTRIBUTE_MAX: CUdevice_attribute_enum = CUdevice_attribute_enum(135); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUdevice_attribute_enum(pub ::std::os::raw::c_int); +pub use self::CUdevice_attribute_enum as CUdevice_attribute; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUdevprop_st; +pub type CUdevprop = CUdevprop_v1; +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); +} +impl CUpointer_attribute_enum { + pub const CU_POINTER_ATTRIBUTE_ACCESS_FLAGS: CUpointer_attribute_enum = + CUpointer_attribute_enum(16); +} +impl CUpointer_attribute_enum { + pub const CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE: CUpointer_attribute_enum = + CUpointer_attribute_enum(17); +} +impl CUpointer_attribute_enum { + pub const CU_POINTER_ATTRIBUTE_MAPPING_SIZE: CUpointer_attribute_enum = + CUpointer_attribute_enum(18); +} +impl CUpointer_attribute_enum { + pub const CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR: CUpointer_attribute_enum = + CUpointer_attribute_enum(19); +} +impl CUpointer_attribute_enum { + pub const CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID: CUpointer_attribute_enum = + CUpointer_attribute_enum(20); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUpointer_attribute_enum(pub ::std::os::raw::c_int); +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_CLUSTER_SIZE_MUST_BE_SET: CUfunction_attribute_enum = + CUfunction_attribute_enum(10); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_WIDTH: CUfunction_attribute_enum = + CUfunction_attribute_enum(11); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_HEIGHT: CUfunction_attribute_enum = + CUfunction_attribute_enum(12); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_DEPTH: CUfunction_attribute_enum = + CUfunction_attribute_enum(13); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_NON_PORTABLE_CLUSTER_SIZE_ALLOWED: CUfunction_attribute_enum = + CUfunction_attribute_enum(14); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE: CUfunction_attribute_enum = + CUfunction_attribute_enum(15); +} +impl CUfunction_attribute_enum { + pub const CU_FUNC_ATTRIBUTE_MAX: CUfunction_attribute_enum = CUfunction_attribute_enum(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUfunction_attribute_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUfunc_cache_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUsharedconfig_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemorytype_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmem_advise_enum(pub ::std::os::raw::c_int); +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); +} +impl CUmem_range_attribute_enum { + pub const CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_TYPE: CUmem_range_attribute_enum = + CUmem_range_attribute_enum(5); +} +impl CUmem_range_attribute_enum { + pub const CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION_ID: CUmem_range_attribute_enum = + CUmem_range_attribute_enum(6); +} +impl CUmem_range_attribute_enum { + pub const CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_TYPE: CUmem_range_attribute_enum = + CUmem_range_attribute_enum(7); +} +impl CUmem_range_attribute_enum { + pub const CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION_ID: CUmem_range_attribute_enum = + CUmem_range_attribute_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmem_range_attribute_enum(pub ::std::os::raw::c_int); +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_LTO: CUjit_option_enum = CUjit_option_enum(20); +} +impl CUjit_option_enum { + pub const CU_JIT_FTZ: CUjit_option_enum = CUjit_option_enum(21); +} +impl CUjit_option_enum { + pub const CU_JIT_PREC_DIV: CUjit_option_enum = CUjit_option_enum(22); +} +impl CUjit_option_enum { + pub const CU_JIT_PREC_SQRT: CUjit_option_enum = CUjit_option_enum(23); +} +impl CUjit_option_enum { + pub const CU_JIT_FMA: CUjit_option_enum = CUjit_option_enum(24); +} +impl CUjit_option_enum { + pub const CU_JIT_REFERENCED_KERNEL_NAMES: CUjit_option_enum = CUjit_option_enum(25); +} +impl CUjit_option_enum { + pub const CU_JIT_REFERENCED_KERNEL_COUNT: CUjit_option_enum = CUjit_option_enum(26); +} +impl CUjit_option_enum { + pub const CU_JIT_REFERENCED_VARIABLE_NAMES: CUjit_option_enum = CUjit_option_enum(27); +} +impl CUjit_option_enum { + pub const CU_JIT_REFERENCED_VARIABLE_COUNT: CUjit_option_enum = CUjit_option_enum(28); +} +impl CUjit_option_enum { + pub const CU_JIT_OPTIMIZE_UNUSED_DEVICE_VARIABLES: CUjit_option_enum = CUjit_option_enum(29); +} +impl CUjit_option_enum { + pub const CU_JIT_POSITION_INDEPENDENT_CODE: CUjit_option_enum = CUjit_option_enum(30); +} +impl CUjit_option_enum { + pub const CU_JIT_NUM_OPTIONS: CUjit_option_enum = CUjit_option_enum(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUjit_option_enum(pub ::std::os::raw::c_int); +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_INPUT_NVVM: CUjitInputType_enum = CUjitInputType_enum(5); +} +impl CUjitInputType_enum { + pub const CU_JIT_NUM_INPUT_TYPES: CUjitInputType_enum = CUjitInputType_enum(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUjitInputType_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUlimit_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUresourcetype_enum(pub ::std::os::raw::c_int); +pub use self::CUresourcetype_enum as CUresourcetype; +pub type CUhostFn = + ::std::option::Option; +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUaccessProperty_enum(pub ::std::os::raw::c_int); +pub use self::CUaccessProperty_enum as CUaccessProperty; +#[repr(C)] +#[derive(Copy, Clone, PartialEq)] +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_v1 = CUaccessPolicyWindow_st; +pub type CUaccessPolicyWindow = CUaccessPolicyWindow_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_KERNEL_NODE_PARAMS_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_KERNEL_NODE_PARAMS_v2_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 kern: CUkernel, + pub ctx: CUcontext, +} +pub type CUDA_KERNEL_NODE_PARAMS_v2 = CUDA_KERNEL_NODE_PARAMS_v2_st; +pub type CUDA_KERNEL_NODE_PARAMS = CUDA_KERNEL_NODE_PARAMS_v2; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_KERNEL_NODE_PARAMS_v3_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 kern: CUkernel, + pub ctx: CUcontext, +} +pub type CUDA_KERNEL_NODE_PARAMS_v3 = CUDA_KERNEL_NODE_PARAMS_v3_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_MEMSET_NODE_PARAMS_st; +pub type CUDA_MEMSET_NODE_PARAMS = CUDA_MEMSET_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEMSET_NODE_PARAMS_v2_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 ctx: CUcontext, +} +pub type CUDA_MEMSET_NODE_PARAMS_v2 = CUDA_MEMSET_NODE_PARAMS_v2_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_v1 = CUDA_HOST_NODE_PARAMS_st; +pub type CUDA_HOST_NODE_PARAMS = CUDA_HOST_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUDA_HOST_NODE_PARAMS_v2_st { + pub fn_: CUhostFn, + pub userData: *mut ::std::os::raw::c_void, +} +pub type CUDA_HOST_NODE_PARAMS_v2 = CUDA_HOST_NODE_PARAMS_v2_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); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_WAIT_EVENT: CUgraphNodeType_enum = CUgraphNodeType_enum(6); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_EVENT_RECORD: CUgraphNodeType_enum = CUgraphNodeType_enum(7); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_EXT_SEMAS_SIGNAL: CUgraphNodeType_enum = CUgraphNodeType_enum(8); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_EXT_SEMAS_WAIT: CUgraphNodeType_enum = CUgraphNodeType_enum(9); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_MEM_ALLOC: CUgraphNodeType_enum = CUgraphNodeType_enum(10); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_MEM_FREE: CUgraphNodeType_enum = CUgraphNodeType_enum(11); +} +impl CUgraphNodeType_enum { + pub const CU_GRAPH_NODE_TYPE_BATCH_MEM_OP: CUgraphNodeType_enum = CUgraphNodeType_enum(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUgraphNodeType_enum(pub ::std::os::raw::c_int); +pub use self::CUgraphNodeType_enum as CUgraphNodeType; +impl CUgraphInstantiateResult_enum { + pub const CUDA_GRAPH_INSTANTIATE_SUCCESS: CUgraphInstantiateResult_enum = + CUgraphInstantiateResult_enum(0); +} +impl CUgraphInstantiateResult_enum { + pub const CUDA_GRAPH_INSTANTIATE_ERROR: CUgraphInstantiateResult_enum = + CUgraphInstantiateResult_enum(1); +} +impl CUgraphInstantiateResult_enum { + pub const CUDA_GRAPH_INSTANTIATE_INVALID_STRUCTURE: CUgraphInstantiateResult_enum = + CUgraphInstantiateResult_enum(2); +} +impl CUgraphInstantiateResult_enum { + pub const CUDA_GRAPH_INSTANTIATE_NODE_OPERATION_NOT_SUPPORTED: CUgraphInstantiateResult_enum = + CUgraphInstantiateResult_enum(3); +} +impl CUgraphInstantiateResult_enum { + pub const CUDA_GRAPH_INSTANTIATE_MULTIPLE_CTXS_NOT_SUPPORTED: CUgraphInstantiateResult_enum = + CUgraphInstantiateResult_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUgraphInstantiateResult_enum(pub ::std::os::raw::c_int); +pub use self::CUgraphInstantiateResult_enum as CUgraphInstantiateResult; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_GRAPH_INSTANTIATE_PARAMS_st { + pub flags: cuuint64_t, + pub hUploadStream: CUstream, + pub hErrNode_out: CUgraphNode, + pub result_out: CUgraphInstantiateResult, +} +pub type CUDA_GRAPH_INSTANTIATE_PARAMS = CUDA_GRAPH_INSTANTIATE_PARAMS_st; +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUsynchronizationPolicy_enum(pub ::std::os::raw::c_int); +pub use self::CUsynchronizationPolicy_enum as CUsynchronizationPolicy; +impl CUclusterSchedulingPolicy_enum { + pub const CU_CLUSTER_SCHEDULING_POLICY_DEFAULT: CUclusterSchedulingPolicy_enum = + CUclusterSchedulingPolicy_enum(0); +} +impl CUclusterSchedulingPolicy_enum { + pub const CU_CLUSTER_SCHEDULING_POLICY_SPREAD: CUclusterSchedulingPolicy_enum = + CUclusterSchedulingPolicy_enum(1); +} +impl CUclusterSchedulingPolicy_enum { + pub const CU_CLUSTER_SCHEDULING_POLICY_LOAD_BALANCING: CUclusterSchedulingPolicy_enum = + CUclusterSchedulingPolicy_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUclusterSchedulingPolicy_enum(pub ::std::os::raw::c_int); +pub use self::CUclusterSchedulingPolicy_enum as CUclusterSchedulingPolicy; +impl CUlaunchMemSyncDomain_enum { + pub const CU_LAUNCH_MEM_SYNC_DOMAIN_DEFAULT: CUlaunchMemSyncDomain_enum = + CUlaunchMemSyncDomain_enum(0); +} +impl CUlaunchMemSyncDomain_enum { + pub const CU_LAUNCH_MEM_SYNC_DOMAIN_REMOTE: CUlaunchMemSyncDomain_enum = + CUlaunchMemSyncDomain_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUlaunchMemSyncDomain_enum(pub ::std::os::raw::c_int); +pub use self::CUlaunchMemSyncDomain_enum as CUlaunchMemSyncDomain; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUlaunchMemSyncDomainMap_st { + pub default_: ::std::os::raw::c_uchar, + pub remote: ::std::os::raw::c_uchar, +} +pub type CUlaunchMemSyncDomainMap = CUlaunchMemSyncDomainMap_st; +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_IGNORE: CUlaunchAttributeID_enum = CUlaunchAttributeID_enum(0); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_ACCESS_POLICY_WINDOW: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(1); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_COOPERATIVE: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(2); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_SYNCHRONIZATION_POLICY: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(3); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_CLUSTER_DIMENSION: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(4); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(5); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_PROGRAMMATIC_STREAM_SERIALIZATION: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(6); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_PROGRAMMATIC_EVENT: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(7); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_PRIORITY: CUlaunchAttributeID_enum = CUlaunchAttributeID_enum(8); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_MEM_SYNC_DOMAIN_MAP: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(9); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_MEM_SYNC_DOMAIN: CUlaunchAttributeID_enum = + CUlaunchAttributeID_enum(10); +} +impl CUlaunchAttributeID_enum { + pub const CU_LAUNCH_ATTRIBUTE_MAX: CUlaunchAttributeID_enum = CUlaunchAttributeID_enum(11); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUlaunchAttributeID_enum(pub ::std::os::raw::c_int); +pub use self::CUlaunchAttributeID_enum as CUlaunchAttributeID; +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUlaunchAttributeValue_union { + pub pad: [::std::os::raw::c_char; 64usize], + pub accessPolicyWindow: CUaccessPolicyWindow, + pub cooperative: ::std::os::raw::c_int, + pub syncPolicy: CUsynchronizationPolicy, + pub clusterDim: CUlaunchAttributeValue_union__bindgen_ty_1, + pub clusterSchedulingPolicyPreference: CUclusterSchedulingPolicy, + pub programmaticStreamSerializationAllowed: ::std::os::raw::c_int, + pub programmaticEvent: CUlaunchAttributeValue_union__bindgen_ty_2, + pub priority: ::std::os::raw::c_int, + pub memSyncDomainMap: CUlaunchMemSyncDomainMap, + pub memSyncDomain: CUlaunchMemSyncDomain, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUlaunchAttributeValue_union__bindgen_ty_1 { + pub x: ::std::os::raw::c_uint, + pub y: ::std::os::raw::c_uint, + pub z: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUlaunchAttributeValue_union__bindgen_ty_2 { + pub event: CUevent, + pub flags: ::std::os::raw::c_int, + pub triggerAtBlockStart: ::std::os::raw::c_int, +} +pub type CUlaunchAttributeValue = CUlaunchAttributeValue_union; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUlaunchAttribute_st { + pub id: CUlaunchAttributeID, + pub pad: [::std::os::raw::c_char; 4usize], + pub value: CUlaunchAttributeValue, +} +pub type CUlaunchAttribute = CUlaunchAttribute_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUlaunchConfig_st { + 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 attrs: *mut CUlaunchAttribute, + pub numAttrs: ::std::os::raw::c_uint, +} +pub type CUlaunchConfig = CUlaunchConfig_st; +pub use self::CUlaunchAttributeID as CUkernelNodeAttrID; +pub type CUkernelNodeAttrValue_v1 = CUlaunchAttributeValue; +pub type CUkernelNodeAttrValue = CUkernelNodeAttrValue_v1; +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUstreamCaptureStatus_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUstreamCaptureMode_enum(pub ::std::os::raw::c_int); +pub use self::CUlaunchAttributeID as CUstreamAttrID; +pub use self::CUstreamCaptureMode_enum as CUstreamCaptureMode; +pub type CUstreamAttrValue_v1 = CUlaunchAttributeValue; +pub type CUstreamAttrValue = CUstreamAttrValue_v1; +impl CUdriverProcAddressQueryResult_enum { + pub const CU_GET_PROC_ADDRESS_SUCCESS: CUdriverProcAddressQueryResult_enum = + CUdriverProcAddressQueryResult_enum(0); +} +impl CUdriverProcAddressQueryResult_enum { + pub const CU_GET_PROC_ADDRESS_SYMBOL_NOT_FOUND: CUdriverProcAddressQueryResult_enum = + CUdriverProcAddressQueryResult_enum(1); +} +impl CUdriverProcAddressQueryResult_enum { + pub const CU_GET_PROC_ADDRESS_VERSION_NOT_SUFFICIENT: CUdriverProcAddressQueryResult_enum = + CUdriverProcAddressQueryResult_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUdriverProcAddressQueryResult_enum(pub ::std::os::raw::c_int); +pub use self::CUdriverProcAddressQueryResult_enum as CUdriverProcAddressQueryResult; +impl CUexecAffinityType_enum { + pub const CU_EXEC_AFFINITY_TYPE_SM_COUNT: CUexecAffinityType_enum = CUexecAffinityType_enum(0); +} +impl CUexecAffinityType_enum { + pub const CU_EXEC_AFFINITY_TYPE_MAX: CUexecAffinityType_enum = CUexecAffinityType_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUexecAffinityType_enum(pub ::std::os::raw::c_int); +pub use self::CUexecAffinityType_enum as CUexecAffinityType; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUexecAffinitySmCount_st { + pub val: ::std::os::raw::c_uint, +} +pub type CUexecAffinitySmCount_v1 = CUexecAffinitySmCount_st; +pub type CUexecAffinitySmCount = CUexecAffinitySmCount_v1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUexecAffinityParam_st { + pub type_: CUexecAffinityType, + pub param: CUexecAffinityParam_st__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUexecAffinityParam_st__bindgen_ty_1 { + pub smCount: CUexecAffinitySmCount, +} +pub type CUexecAffinityParam_v1 = CUexecAffinityParam_st; +pub type CUexecAffinityParam = CUexecAffinityParam_v1; +impl CUlibraryOption_enum { + pub const CU_LIBRARY_HOST_UNIVERSAL_FUNCTION_AND_DATA_TABLE: CUlibraryOption_enum = + CUlibraryOption_enum(0); +} +impl CUlibraryOption_enum { + pub const CU_LIBRARY_BINARY_IS_PRESERVED: CUlibraryOption_enum = CUlibraryOption_enum(1); +} +impl CUlibraryOption_enum { + pub const CU_LIBRARY_NUM_OPTIONS: CUlibraryOption_enum = CUlibraryOption_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUlibraryOption_enum(pub ::std::os::raw::c_int); +pub use self::CUlibraryOption_enum as CUlibraryOption; +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_STUB_LIBRARY: cudaError_enum = cudaError_enum(34); +} +impl cudaError_enum { + pub const CUDA_ERROR_DEVICE_UNAVAILABLE: cudaError_enum = cudaError_enum(46); +} +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_DEVICE_NOT_LICENSED: cudaError_enum = cudaError_enum(102); +} +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_UNSUPPORTED_PTX_VERSION: cudaError_enum = cudaError_enum(222); +} +impl cudaError_enum { + pub const CUDA_ERROR_JIT_COMPILATION_DISABLED: cudaError_enum = cudaError_enum(223); +} +impl cudaError_enum { + pub const CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY: cudaError_enum = cudaError_enum(224); +} +impl cudaError_enum { + pub const CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC: cudaError_enum = cudaError_enum(225); +} +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_MPS_CONNECTION_FAILED: cudaError_enum = cudaError_enum(805); +} +impl cudaError_enum { + pub const CUDA_ERROR_MPS_RPC_FAILURE: cudaError_enum = cudaError_enum(806); +} +impl cudaError_enum { + pub const CUDA_ERROR_MPS_SERVER_NOT_READY: cudaError_enum = cudaError_enum(807); +} +impl cudaError_enum { + pub const CUDA_ERROR_MPS_MAX_CLIENTS_REACHED: cudaError_enum = cudaError_enum(808); +} +impl cudaError_enum { + pub const CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED: cudaError_enum = cudaError_enum(809); +} +impl cudaError_enum { + pub const CUDA_ERROR_MPS_CLIENT_TERMINATED: cudaError_enum = cudaError_enum(810); +} +impl cudaError_enum { + pub const CUDA_ERROR_CDP_NOT_SUPPORTED: cudaError_enum = cudaError_enum(811); +} +impl cudaError_enum { + pub const CUDA_ERROR_CDP_VERSION_MISMATCH: cudaError_enum = cudaError_enum(812); +} +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_EXTERNAL_DEVICE: cudaError_enum = cudaError_enum(911); +} +impl cudaError_enum { + pub const CUDA_ERROR_INVALID_CLUSTER_SIZE: cudaError_enum = cudaError_enum(912); +} +impl cudaError_enum { + pub const CUDA_ERROR_UNKNOWN: cudaError_enum = cudaError_enum(999); +} +#[repr(transparent)] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] +pub struct cudaError_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUdevice_P2PAttribute_enum(pub ::std::os::raw::c_int); +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 usize>; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v2 = CUDA_MEMCPY2D_st; +pub type CUDA_MEMCPY2D = CUDA_MEMCPY2D_v2; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v2 = CUDA_MEMCPY3D_st; +pub type CUDA_MEMCPY3D = CUDA_MEMCPY3D_v2; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_MEMCPY3D_PEER_st; +pub type CUDA_MEMCPY3D_PEER = CUDA_MEMCPY3D_PEER_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEMCPY_NODE_PARAMS_st { + pub flags: ::std::os::raw::c_int, + pub reserved: ::std::os::raw::c_int, + pub copyCtx: CUcontext, + pub copyParams: CUDA_MEMCPY3D, +} +pub type CUDA_MEMCPY_NODE_PARAMS = CUDA_MEMCPY_NODE_PARAMS_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v2 = CUDA_ARRAY_DESCRIPTOR_st; +pub type CUDA_ARRAY_DESCRIPTOR = CUDA_ARRAY_DESCRIPTOR_v2; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v2 = CUDA_ARRAY3D_DESCRIPTOR_st; +pub type CUDA_ARRAY3D_DESCRIPTOR = CUDA_ARRAY3D_DESCRIPTOR_v2; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_ARRAY_SPARSE_PROPERTIES_st { + pub tileExtent: CUDA_ARRAY_SPARSE_PROPERTIES_st__bindgen_ty_1, + pub miptailFirstLevel: ::std::os::raw::c_uint, + pub miptailSize: ::std::os::raw::c_ulonglong, + pub flags: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_ARRAY_SPARSE_PROPERTIES_st__bindgen_ty_1 { + pub width: ::std::os::raw::c_uint, + pub height: ::std::os::raw::c_uint, + pub depth: ::std::os::raw::c_uint, +} +pub type CUDA_ARRAY_SPARSE_PROPERTIES_v1 = CUDA_ARRAY_SPARSE_PROPERTIES_st; +pub type CUDA_ARRAY_SPARSE_PROPERTIES = CUDA_ARRAY_SPARSE_PROPERTIES_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_ARRAY_MEMORY_REQUIREMENTS_st { + pub size: usize, + pub alignment: usize, + pub reserved: [::std::os::raw::c_uint; 4usize], +} +pub type CUDA_ARRAY_MEMORY_REQUIREMENTS_v1 = CUDA_ARRAY_MEMORY_REQUIREMENTS_st; +pub type CUDA_ARRAY_MEMORY_REQUIREMENTS = CUDA_ARRAY_MEMORY_REQUIREMENTS_v1; +#[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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_1 { + pub hArray: CUarray, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_2 { + pub hMipmappedArray: CUmipmappedArray, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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, PartialEq, Eq)] +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, PartialEq, Eq)] +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_v1 = CUDA_RESOURCE_DESC_st; +pub type CUDA_RESOURCE_DESC = CUDA_RESOURCE_DESC_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq)] +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_v1 = CUDA_TEXTURE_DESC_st; +pub type CUDA_TEXTURE_DESC = CUDA_TEXTURE_DESC_v1; +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUresourceViewFormat_enum(pub ::std::os::raw::c_int); +pub use self::CUresourceViewFormat_enum as CUresourceViewFormat; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_RESOURCE_VIEW_DESC_st; +pub type CUDA_RESOURCE_VIEW_DESC = CUDA_RESOURCE_VIEW_DESC_v1; +#[repr(C)] +#[repr(align(64))] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUtensorMap_st { + pub opaque: [cuuint64_t; 16usize], +} +pub type CUtensorMap = CUtensorMap_st; +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_UINT8: CUtensorMapDataType_enum = CUtensorMapDataType_enum(0); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_UINT16: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(1); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_UINT32: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(2); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_INT32: CUtensorMapDataType_enum = CUtensorMapDataType_enum(3); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_UINT64: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(4); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_INT64: CUtensorMapDataType_enum = CUtensorMapDataType_enum(5); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_FLOAT16: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(6); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_FLOAT32: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(7); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_FLOAT64: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(8); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_BFLOAT16: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(9); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_FLOAT32_FTZ: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(10); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_TFLOAT32: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(11); +} +impl CUtensorMapDataType_enum { + pub const CU_TENSOR_MAP_DATA_TYPE_TFLOAT32_FTZ: CUtensorMapDataType_enum = + CUtensorMapDataType_enum(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUtensorMapDataType_enum(pub ::std::os::raw::c_int); +pub use self::CUtensorMapDataType_enum as CUtensorMapDataType; +impl CUtensorMapInterleave_enum { + pub const CU_TENSOR_MAP_INTERLEAVE_NONE: CUtensorMapInterleave_enum = + CUtensorMapInterleave_enum(0); +} +impl CUtensorMapInterleave_enum { + pub const CU_TENSOR_MAP_INTERLEAVE_16B: CUtensorMapInterleave_enum = + CUtensorMapInterleave_enum(1); +} +impl CUtensorMapInterleave_enum { + pub const CU_TENSOR_MAP_INTERLEAVE_32B: CUtensorMapInterleave_enum = + CUtensorMapInterleave_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUtensorMapInterleave_enum(pub ::std::os::raw::c_int); +pub use self::CUtensorMapInterleave_enum as CUtensorMapInterleave; +impl CUtensorMapSwizzle_enum { + pub const CU_TENSOR_MAP_SWIZZLE_NONE: CUtensorMapSwizzle_enum = CUtensorMapSwizzle_enum(0); +} +impl CUtensorMapSwizzle_enum { + pub const CU_TENSOR_MAP_SWIZZLE_32B: CUtensorMapSwizzle_enum = CUtensorMapSwizzle_enum(1); +} +impl CUtensorMapSwizzle_enum { + pub const CU_TENSOR_MAP_SWIZZLE_64B: CUtensorMapSwizzle_enum = CUtensorMapSwizzle_enum(2); +} +impl CUtensorMapSwizzle_enum { + pub const CU_TENSOR_MAP_SWIZZLE_128B: CUtensorMapSwizzle_enum = CUtensorMapSwizzle_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUtensorMapSwizzle_enum(pub ::std::os::raw::c_int); +pub use self::CUtensorMapSwizzle_enum as CUtensorMapSwizzle; +impl CUtensorMapL2promotion_enum { + pub const CU_TENSOR_MAP_L2_PROMOTION_NONE: CUtensorMapL2promotion_enum = + CUtensorMapL2promotion_enum(0); +} +impl CUtensorMapL2promotion_enum { + pub const CU_TENSOR_MAP_L2_PROMOTION_L2_64B: CUtensorMapL2promotion_enum = + CUtensorMapL2promotion_enum(1); +} +impl CUtensorMapL2promotion_enum { + pub const CU_TENSOR_MAP_L2_PROMOTION_L2_128B: CUtensorMapL2promotion_enum = + CUtensorMapL2promotion_enum(2); +} +impl CUtensorMapL2promotion_enum { + pub const CU_TENSOR_MAP_L2_PROMOTION_L2_256B: CUtensorMapL2promotion_enum = + CUtensorMapL2promotion_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUtensorMapL2promotion_enum(pub ::std::os::raw::c_int); +pub use self::CUtensorMapL2promotion_enum as CUtensorMapL2promotion; +impl CUtensorMapFloatOOBfill_enum { + pub const CU_TENSOR_MAP_FLOAT_OOB_FILL_NONE: CUtensorMapFloatOOBfill_enum = + CUtensorMapFloatOOBfill_enum(0); +} +impl CUtensorMapFloatOOBfill_enum { + pub const CU_TENSOR_MAP_FLOAT_OOB_FILL_NAN_REQUEST_ZERO_FMA: CUtensorMapFloatOOBfill_enum = + CUtensorMapFloatOOBfill_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUtensorMapFloatOOBfill_enum(pub ::std::os::raw::c_int); +pub use self::CUtensorMapFloatOOBfill_enum as CUtensorMapFloatOOBfill; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_LAUNCH_PARAMS_st; +pub type CUDA_LAUNCH_PARAMS = CUDA_LAUNCH_PARAMS_v1; +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUexternalMemoryHandleType_enum(pub ::std::os::raw::c_int); +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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st; +pub type CUDA_EXTERNAL_MEMORY_HANDLE_DESC = CUDA_EXTERNAL_MEMORY_HANDLE_DESC_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_EXTERNAL_MEMORY_BUFFER_DESC_st; +pub type CUDA_EXTERNAL_MEMORY_BUFFER_DESC = CUDA_EXTERNAL_MEMORY_BUFFER_DESC_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = + CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC_st; +pub type CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC = CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC_v1; +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); +} +impl CUexternalSemaphoreHandleType_enum { + pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_FD: + CUexternalSemaphoreHandleType_enum = CUexternalSemaphoreHandleType_enum(9); +} +impl CUexternalSemaphoreHandleType_enum { + pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TIMELINE_SEMAPHORE_WIN32: + CUexternalSemaphoreHandleType_enum = CUexternalSemaphoreHandleType_enum(10); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUexternalSemaphoreHandleType_enum(pub ::std::os::raw::c_int); +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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st; +pub type CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC = CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_v1; +#[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, PartialEq, Eq)] +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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st; +pub type CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS = CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_v1; +#[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, PartialEq, Eq)] +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, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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_v1 = CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st; +pub type CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS = CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_st { + pub extSemArray: *mut CUexternalSemaphore, + pub paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS, + pub numExtSems: ::std::os::raw::c_uint, +} +pub type CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v1 = CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_st; +pub type CUDA_EXT_SEM_SIGNAL_NODE_PARAMS = CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v2_st { + pub extSemArray: *mut CUexternalSemaphore, + pub paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS, + pub numExtSems: ::std::os::raw::c_uint, +} +pub type CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v2 = CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v2_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EXT_SEM_WAIT_NODE_PARAMS_st { + pub extSemArray: *mut CUexternalSemaphore, + pub paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS, + pub numExtSems: ::std::os::raw::c_uint, +} +pub type CUDA_EXT_SEM_WAIT_NODE_PARAMS_v1 = CUDA_EXT_SEM_WAIT_NODE_PARAMS_st; +pub type CUDA_EXT_SEM_WAIT_NODE_PARAMS = CUDA_EXT_SEM_WAIT_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EXT_SEM_WAIT_NODE_PARAMS_v2_st { + pub extSemArray: *mut CUexternalSemaphore, + pub paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS, + pub numExtSems: ::std::os::raw::c_uint, +} +pub type CUDA_EXT_SEM_WAIT_NODE_PARAMS_v2 = CUDA_EXT_SEM_WAIT_NODE_PARAMS_v2_st; +pub type CUmemGenericAllocationHandle_v1 = ::std::os::raw::c_ulonglong; +pub type CUmemGenericAllocationHandle = CUmemGenericAllocationHandle_v1; +impl CUmemAllocationHandleType_enum { + pub const CU_MEM_HANDLE_TYPE_NONE: CUmemAllocationHandleType_enum = + CUmemAllocationHandleType_enum(0); +} +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(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemAllocationHandleType_enum(pub ::std::os::raw::c_int); +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(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemAccess_flags_enum(pub ::std::os::raw::c_int); +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_HOST: CUmemLocationType_enum = CUmemLocationType_enum(2); +} +impl CUmemLocationType_enum { + pub const CU_MEM_LOCATION_TYPE_HOST_NUMA: CUmemLocationType_enum = CUmemLocationType_enum(3); +} +impl CUmemLocationType_enum { + pub const CU_MEM_LOCATION_TYPE_HOST_NUMA_CURRENT: CUmemLocationType_enum = + CUmemLocationType_enum(4); +} +impl CUmemLocationType_enum { + pub const CU_MEM_LOCATION_TYPE_MAX: CUmemLocationType_enum = CUmemLocationType_enum(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemLocationType_enum(pub ::std::os::raw::c_int); +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(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemAllocationType_enum(pub ::std::os::raw::c_int); +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(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemAllocationGranularity_flags_enum(pub ::std::os::raw::c_int); +pub use self::CUmemAllocationGranularity_flags_enum as CUmemAllocationGranularity_flags; +impl CUmemRangeHandleType_enum { + pub const CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD: CUmemRangeHandleType_enum = + CUmemRangeHandleType_enum(1); +} +impl CUmemRangeHandleType_enum { + pub const CU_MEM_RANGE_HANDLE_TYPE_MAX: CUmemRangeHandleType_enum = + CUmemRangeHandleType_enum(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemRangeHandleType_enum(pub ::std::os::raw::c_int); +pub use self::CUmemRangeHandleType_enum as CUmemRangeHandleType; +impl CUarraySparseSubresourceType_enum { + pub const CU_ARRAY_SPARSE_SUBRESOURCE_TYPE_SPARSE_LEVEL: CUarraySparseSubresourceType_enum = + CUarraySparseSubresourceType_enum(0); +} +impl CUarraySparseSubresourceType_enum { + pub const CU_ARRAY_SPARSE_SUBRESOURCE_TYPE_MIPTAIL: CUarraySparseSubresourceType_enum = + CUarraySparseSubresourceType_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUarraySparseSubresourceType_enum(pub ::std::os::raw::c_int); +pub use self::CUarraySparseSubresourceType_enum as CUarraySparseSubresourceType; +impl CUmemOperationType_enum { + pub const CU_MEM_OPERATION_TYPE_MAP: CUmemOperationType_enum = CUmemOperationType_enum(1); +} +impl CUmemOperationType_enum { + pub const CU_MEM_OPERATION_TYPE_UNMAP: CUmemOperationType_enum = CUmemOperationType_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemOperationType_enum(pub ::std::os::raw::c_int); +pub use self::CUmemOperationType_enum as CUmemOperationType; +impl CUmemHandleType_enum { + pub const CU_MEM_HANDLE_TYPE_GENERIC: CUmemHandleType_enum = CUmemHandleType_enum(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemHandleType_enum(pub ::std::os::raw::c_int); +pub use self::CUmemHandleType_enum as CUmemHandleType; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUarrayMapInfo_st { + pub resourceType: CUresourcetype, + pub resource: CUarrayMapInfo_st__bindgen_ty_1, + pub subresourceType: CUarraySparseSubresourceType, + pub subresource: CUarrayMapInfo_st__bindgen_ty_2, + pub memOperationType: CUmemOperationType, + pub memHandleType: CUmemHandleType, + pub memHandle: CUarrayMapInfo_st__bindgen_ty_3, + pub offset: ::std::os::raw::c_ulonglong, + pub deviceBitMask: ::std::os::raw::c_uint, + pub flags: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUarrayMapInfo_st__bindgen_ty_1 { + pub mipmap: CUmipmappedArray, + pub array: CUarray, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUarrayMapInfo_st__bindgen_ty_2 { + pub sparseLevel: CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_1, + pub miptail: CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_1 { + pub level: ::std::os::raw::c_uint, + pub layer: ::std::os::raw::c_uint, + pub offsetX: ::std::os::raw::c_uint, + pub offsetY: ::std::os::raw::c_uint, + pub offsetZ: ::std::os::raw::c_uint, + pub extentWidth: ::std::os::raw::c_uint, + pub extentHeight: ::std::os::raw::c_uint, + pub extentDepth: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUarrayMapInfo_st__bindgen_ty_2__bindgen_ty_2 { + pub layer: ::std::os::raw::c_uint, + pub offset: ::std::os::raw::c_ulonglong, + pub size: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUarrayMapInfo_st__bindgen_ty_3 { + pub memHandle: CUmemGenericAllocationHandle, +} +pub type CUarrayMapInfo_v1 = CUarrayMapInfo_st; +pub type CUarrayMapInfo = CUarrayMapInfo_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUmemLocation_st { + pub type_: CUmemLocationType, + pub id: ::std::os::raw::c_int, +} +pub type CUmemLocation_v1 = CUmemLocation_st; +pub type CUmemLocation = CUmemLocation_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +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, PartialEq, Eq)] +pub struct CUmemAllocationProp_st__bindgen_ty_1 { + pub compressionType: ::std::os::raw::c_uchar, + pub gpuDirectRDMACapable: ::std::os::raw::c_uchar, + pub usage: ::std::os::raw::c_ushort, + pub reserved: [::std::os::raw::c_uchar; 4usize], +} +pub type CUmemAllocationProp_v1 = CUmemAllocationProp_st; +pub type CUmemAllocationProp = CUmemAllocationProp_v1; +impl CUmulticastGranularity_flags_enum { + pub const CU_MULTICAST_GRANULARITY_MINIMUM: CUmulticastGranularity_flags_enum = + CUmulticastGranularity_flags_enum(0); +} +impl CUmulticastGranularity_flags_enum { + pub const CU_MULTICAST_GRANULARITY_RECOMMENDED: CUmulticastGranularity_flags_enum = + CUmulticastGranularity_flags_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmulticastGranularity_flags_enum(pub ::std::os::raw::c_int); +pub use self::CUmulticastGranularity_flags_enum as CUmulticastGranularity_flags; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUmulticastObjectProp_st { + pub numDevices: ::std::os::raw::c_uint, + pub size: usize, + pub handleTypes: ::std::os::raw::c_ulonglong, + pub flags: ::std::os::raw::c_ulonglong, +} +pub type CUmulticastObjectProp_v1 = CUmulticastObjectProp_st; +pub type CUmulticastObjectProp = CUmulticastObjectProp_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUmemAccessDesc_st { + pub location: CUmemLocation, + pub flags: CUmemAccess_flags, +} +pub type CUmemAccessDesc_v1 = CUmemAccessDesc_st; +pub type CUmemAccessDesc = CUmemAccessDesc_v1; +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); +} +impl CUgraphExecUpdateResult_enum { + pub const CU_GRAPH_EXEC_UPDATE_ERROR_UNSUPPORTED_FUNCTION_CHANGE: CUgraphExecUpdateResult_enum = + CUgraphExecUpdateResult_enum(7); +} +impl CUgraphExecUpdateResult_enum { + pub const CU_GRAPH_EXEC_UPDATE_ERROR_ATTRIBUTES_CHANGED: CUgraphExecUpdateResult_enum = + CUgraphExecUpdateResult_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUgraphExecUpdateResult_enum(pub ::std::os::raw::c_int); +pub use self::CUgraphExecUpdateResult_enum as CUgraphExecUpdateResult; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUgraphExecUpdateResultInfo_st { + pub result: CUgraphExecUpdateResult, + pub errorNode: CUgraphNode, + pub errorFromNode: CUgraphNode, +} +pub type CUgraphExecUpdateResultInfo_v1 = CUgraphExecUpdateResultInfo_st; +pub type CUgraphExecUpdateResultInfo = CUgraphExecUpdateResultInfo_v1; +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_REUSE_FOLLOW_EVENT_DEPENDENCIES: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(1); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_REUSE_ALLOW_OPPORTUNISTIC: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(2); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_REUSE_ALLOW_INTERNAL_DEPENDENCIES: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(3); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_RELEASE_THRESHOLD: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(4); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(5); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(6); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_USED_MEM_CURRENT: CUmemPool_attribute_enum = + CUmemPool_attribute_enum(7); +} +impl CUmemPool_attribute_enum { + pub const CU_MEMPOOL_ATTR_USED_MEM_HIGH: CUmemPool_attribute_enum = CUmemPool_attribute_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmemPool_attribute_enum(pub ::std::os::raw::c_int); +pub use self::CUmemPool_attribute_enum as CUmemPool_attribute; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUmemPoolProps_st { + pub allocType: CUmemAllocationType, + pub handleTypes: CUmemAllocationHandleType, + pub location: CUmemLocation, + pub win32SecurityAttributes: *mut ::std::os::raw::c_void, + pub maxSize: usize, + pub reserved: [::std::os::raw::c_uchar; 56usize], +} +pub type CUmemPoolProps_v1 = CUmemPoolProps_st; +pub type CUmemPoolProps = CUmemPoolProps_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUmemPoolPtrExportData_st { + pub reserved: [::std::os::raw::c_uchar; 64usize], +} +pub type CUmemPoolPtrExportData_v1 = CUmemPoolPtrExportData_st; +pub type CUmemPoolPtrExportData = CUmemPoolPtrExportData_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEM_ALLOC_NODE_PARAMS_v1_st { + pub poolProps: CUmemPoolProps, + pub accessDescs: *const CUmemAccessDesc, + pub accessDescCount: usize, + pub bytesize: usize, + pub dptr: CUdeviceptr, +} +pub type CUDA_MEM_ALLOC_NODE_PARAMS_v1 = CUDA_MEM_ALLOC_NODE_PARAMS_v1_st; +pub type CUDA_MEM_ALLOC_NODE_PARAMS = CUDA_MEM_ALLOC_NODE_PARAMS_v1; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEM_ALLOC_NODE_PARAMS_v2_st { + pub poolProps: CUmemPoolProps, + pub accessDescs: *const CUmemAccessDesc, + pub accessDescCount: usize, + pub bytesize: usize, + pub dptr: CUdeviceptr, +} +pub type CUDA_MEM_ALLOC_NODE_PARAMS_v2 = CUDA_MEM_ALLOC_NODE_PARAMS_v2_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEM_FREE_NODE_PARAMS_st { + pub dptr: CUdeviceptr, +} +pub type CUDA_MEM_FREE_NODE_PARAMS = CUDA_MEM_FREE_NODE_PARAMS_st; +impl CUgraphMem_attribute_enum { + pub const CU_GRAPH_MEM_ATTR_USED_MEM_CURRENT: CUgraphMem_attribute_enum = + CUgraphMem_attribute_enum(0); +} +impl CUgraphMem_attribute_enum { + pub const CU_GRAPH_MEM_ATTR_USED_MEM_HIGH: CUgraphMem_attribute_enum = + CUgraphMem_attribute_enum(1); +} +impl CUgraphMem_attribute_enum { + pub const CU_GRAPH_MEM_ATTR_RESERVED_MEM_CURRENT: CUgraphMem_attribute_enum = + CUgraphMem_attribute_enum(2); +} +impl CUgraphMem_attribute_enum { + pub const CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH: CUgraphMem_attribute_enum = + CUgraphMem_attribute_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUgraphMem_attribute_enum(pub ::std::os::raw::c_int); +pub use self::CUgraphMem_attribute_enum as CUgraphMem_attribute; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_CHILD_GRAPH_NODE_PARAMS_st { + pub graph: CUgraph, +} +pub type CUDA_CHILD_GRAPH_NODE_PARAMS = CUDA_CHILD_GRAPH_NODE_PARAMS_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EVENT_RECORD_NODE_PARAMS_st { + pub event: CUevent, +} +pub type CUDA_EVENT_RECORD_NODE_PARAMS = CUDA_EVENT_RECORD_NODE_PARAMS_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_EVENT_WAIT_NODE_PARAMS_st { + pub event: CUevent, +} +pub type CUDA_EVENT_WAIT_NODE_PARAMS = CUDA_EVENT_WAIT_NODE_PARAMS_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUgraphNodeParams_st { + pub type_: CUgraphNodeType, + pub reserved0: [::std::os::raw::c_int; 3usize], + pub __bindgen_anon_1: CUgraphNodeParams_st__bindgen_ty_1, + pub reserved2: ::std::os::raw::c_longlong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union CUgraphNodeParams_st__bindgen_ty_1 { + pub reserved1: [::std::os::raw::c_longlong; 29usize], + pub kernel: CUDA_KERNEL_NODE_PARAMS_v3, + pub memcpy: CUDA_MEMCPY_NODE_PARAMS, + pub memset: CUDA_MEMSET_NODE_PARAMS_v2, + pub host: CUDA_HOST_NODE_PARAMS_v2, + pub graph: CUDA_CHILD_GRAPH_NODE_PARAMS, + pub eventWait: CUDA_EVENT_WAIT_NODE_PARAMS, + pub eventRecord: CUDA_EVENT_RECORD_NODE_PARAMS, + pub extSemSignal: CUDA_EXT_SEM_SIGNAL_NODE_PARAMS_v2, + pub extSemWait: CUDA_EXT_SEM_WAIT_NODE_PARAMS_v2, + pub alloc: CUDA_MEM_ALLOC_NODE_PARAMS_v2, + pub free: CUDA_MEM_FREE_NODE_PARAMS, + pub memOp: CUDA_BATCH_MEM_OP_NODE_PARAMS_v2, +} +pub type CUgraphNodeParams = CUgraphNodeParams_st; +impl CUflushGPUDirectRDMAWritesScope_enum { + pub const CU_FLUSH_GPU_DIRECT_RDMA_WRITES_TO_OWNER: CUflushGPUDirectRDMAWritesScope_enum = + CUflushGPUDirectRDMAWritesScope_enum(100); +} +impl CUflushGPUDirectRDMAWritesScope_enum { + pub const CU_FLUSH_GPU_DIRECT_RDMA_WRITES_TO_ALL_DEVICES: CUflushGPUDirectRDMAWritesScope_enum = + CUflushGPUDirectRDMAWritesScope_enum(200); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUflushGPUDirectRDMAWritesScope_enum(pub ::std::os::raw::c_int); +pub use self::CUflushGPUDirectRDMAWritesScope_enum as CUflushGPUDirectRDMAWritesScope; +impl CUflushGPUDirectRDMAWritesTarget_enum { + pub const CU_FLUSH_GPU_DIRECT_RDMA_WRITES_TARGET_CURRENT_CTX: + CUflushGPUDirectRDMAWritesTarget_enum = CUflushGPUDirectRDMAWritesTarget_enum(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUflushGPUDirectRDMAWritesTarget_enum(pub ::std::os::raw::c_int); +pub use self::CUflushGPUDirectRDMAWritesTarget_enum as CUflushGPUDirectRDMAWritesTarget; +extern "C" { + pub fn cuGetErrorString(error: CUresult, pStr: *mut *const ::std::os::raw::c_char) -> CUresult; +} +extern "C" { + pub fn cuGetErrorName(error: CUresult, pStr: *mut *const ::std::os::raw::c_char) -> CUresult; +} +extern "C" { + pub fn cuInit(Flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuDriverGetVersion(driverVersion: *mut ::std::os::raw::c_int) -> CUresult; +} +extern "C" { + pub fn cuDeviceGet(device: *mut CUdevice, ordinal: ::std::os::raw::c_int) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetCount(count: *mut ::std::os::raw::c_int) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetName( + name: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetUuid_v2(uuid: *mut CUuuid, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetLuid( + luid: *mut ::std::os::raw::c_char, + deviceNodeMask: *mut ::std::os::raw::c_uint, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceTotalMem_v2(bytes: *mut usize, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetTexture1DLinearMaxWidth( + maxWidthInElements: *mut usize, + format: CUarray_format, + numChannels: ::std::os::raw::c_uint, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetAttribute( + pi: *mut ::std::os::raw::c_int, + attrib: CUdevice_attribute, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetNvSciSyncAttributes( + nvSciSyncAttrList: *mut ::std::os::raw::c_void, + dev: CUdevice, + flags: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceSetMemPool(dev: CUdevice, pool: CUmemoryPool) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetMemPool(pool: *mut CUmemoryPool, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetDefaultMemPool(pool_out: *mut CUmemoryPool, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetExecAffinitySupport( + pi: *mut ::std::os::raw::c_int, + type_: CUexecAffinityType, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuFlushGPUDirectRDMAWrites( + target: CUflushGPUDirectRDMAWritesTarget, + scope: CUflushGPUDirectRDMAWritesScope, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetProperties(prop: *mut CUdevprop, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceComputeCapability( + major: *mut ::std::os::raw::c_int, + minor: *mut ::std::os::raw::c_int, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxRetain(pctx: *mut CUcontext, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxRelease_v2(dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxSetFlags_v2(dev: CUdevice, flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxGetState( + dev: CUdevice, + flags: *mut ::std::os::raw::c_uint, + active: *mut ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxReset_v2(dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuCtxCreate_v2( + pctx: *mut CUcontext, + flags: ::std::os::raw::c_uint, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxCreate_v3( + pctx: *mut CUcontext, + paramsArray: *mut CUexecAffinityParam, + numParams: ::std::os::raw::c_int, + flags: ::std::os::raw::c_uint, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxDestroy_v2(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxPushCurrent_v2(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxPopCurrent_v2(pctx: *mut CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxSetCurrent(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxGetCurrent(pctx: *mut CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxGetDevice(device: *mut CUdevice) -> CUresult; +} +extern "C" { + pub fn cuCtxGetFlags(flags: *mut ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuCtxSetFlags(flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuCtxGetId(ctx: CUcontext, ctxId: *mut ::std::os::raw::c_ulonglong) -> CUresult; +} +extern "C" { + pub fn cuCtxSynchronize() -> CUresult; +} +extern "C" { + pub fn cuCtxSetLimit(limit: CUlimit, value: usize) -> CUresult; +} +extern "C" { + pub fn cuCtxGetLimit(pvalue: *mut usize, limit: CUlimit) -> CUresult; +} +extern "C" { + pub fn cuCtxGetCacheConfig(pconfig: *mut CUfunc_cache) -> CUresult; +} +extern "C" { + pub fn cuCtxSetCacheConfig(config: CUfunc_cache) -> CUresult; +} +extern "C" { + pub fn cuCtxGetSharedMemConfig(pConfig: *mut CUsharedconfig) -> CUresult; +} +extern "C" { + pub fn cuCtxSetSharedMemConfig(config: CUsharedconfig) -> CUresult; +} +extern "C" { + pub fn cuCtxGetApiVersion(ctx: CUcontext, version: *mut ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuCtxGetStreamPriorityRange( + leastPriority: *mut ::std::os::raw::c_int, + greatestPriority: *mut ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxResetPersistingL2Cache() -> CUresult; +} +extern "C" { + pub fn cuCtxGetExecAffinity( + pExecAffinity: *mut CUexecAffinityParam, + type_: CUexecAffinityType, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxAttach(pctx: *mut CUcontext, flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuCtxDetach(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuModuleLoad(module: *mut CUmodule, fname: *const ::std::os::raw::c_char) -> CUresult; +} +extern "C" { + pub fn cuModuleLoadData( + module: *mut CUmodule, + image: *const ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuModuleLoadFatBinary( + module: *mut CUmodule, + fatCubin: *const ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuModuleUnload(hmod: CUmodule) -> CUresult; +} +impl CUmoduleLoadingMode_enum { + pub const CU_MODULE_EAGER_LOADING: CUmoduleLoadingMode_enum = CUmoduleLoadingMode_enum(1); +} +impl CUmoduleLoadingMode_enum { + pub const CU_MODULE_LAZY_LOADING: CUmoduleLoadingMode_enum = CUmoduleLoadingMode_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUmoduleLoadingMode_enum(pub ::std::os::raw::c_int); +pub use self::CUmoduleLoadingMode_enum as CUmoduleLoadingMode; +extern "C" { + pub fn cuModuleGetLoadingMode(mode: *mut CUmoduleLoadingMode) -> CUresult; +} +extern "C" { + pub fn cuModuleGetFunction( + hfunc: *mut CUfunction, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuModuleGetGlobal_v2( + dptr: *mut CUdeviceptr, + bytes: *mut usize, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub 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; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuLinkComplete( + state: CUlinkState, + cubinOut: *mut *mut ::std::os::raw::c_void, + sizeOut: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuLinkDestroy(state: CUlinkState) -> CUresult; +} +extern "C" { + pub fn cuModuleGetTexRef( + pTexRef: *mut CUtexref, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuModuleGetSurfRef( + pSurfRef: *mut CUsurfref, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryLoadData( + library: *mut CUlibrary, + code: *const ::std::os::raw::c_void, + jitOptions: *mut CUjit_option, + jitOptionsValues: *mut *mut ::std::os::raw::c_void, + numJitOptions: ::std::os::raw::c_uint, + libraryOptions: *mut CUlibraryOption, + libraryOptionValues: *mut *mut ::std::os::raw::c_void, + numLibraryOptions: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryLoadFromFile( + library: *mut CUlibrary, + fileName: *const ::std::os::raw::c_char, + jitOptions: *mut CUjit_option, + jitOptionsValues: *mut *mut ::std::os::raw::c_void, + numJitOptions: ::std::os::raw::c_uint, + libraryOptions: *mut CUlibraryOption, + libraryOptionValues: *mut *mut ::std::os::raw::c_void, + numLibraryOptions: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryUnload(library: CUlibrary) -> CUresult; +} +extern "C" { + pub fn cuLibraryGetKernel( + pKernel: *mut CUkernel, + library: CUlibrary, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryGetModule(pMod: *mut CUmodule, library: CUlibrary) -> CUresult; +} +extern "C" { + pub fn cuKernelGetFunction(pFunc: *mut CUfunction, kernel: CUkernel) -> CUresult; +} +extern "C" { + pub fn cuLibraryGetGlobal( + dptr: *mut CUdeviceptr, + bytes: *mut usize, + library: CUlibrary, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryGetManaged( + dptr: *mut CUdeviceptr, + bytes: *mut usize, + library: CUlibrary, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuLibraryGetUnifiedFunction( + fptr: *mut *mut ::std::os::raw::c_void, + library: CUlibrary, + symbol: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuKernelGetAttribute( + pi: *mut ::std::os::raw::c_int, + attrib: CUfunction_attribute, + kernel: CUkernel, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuKernelSetAttribute( + attrib: CUfunction_attribute, + val: ::std::os::raw::c_int, + kernel: CUkernel, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuKernelSetCacheConfig( + kernel: CUkernel, + config: CUfunc_cache, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuMemGetInfo_v2(free: *mut usize, total: *mut usize) -> CUresult; +} +extern "C" { + pub fn cuMemAlloc_v2(dptr: *mut CUdeviceptr, bytesize: usize) -> CUresult; +} +extern "C" { + pub fn cuMemAllocPitch_v2( + dptr: *mut CUdeviceptr, + pPitch: *mut usize, + WidthInBytes: usize, + Height: usize, + ElementSizeBytes: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemFree_v2(dptr: CUdeviceptr) -> CUresult; +} +extern "C" { + pub fn cuMemGetAddressRange_v2( + pbase: *mut CUdeviceptr, + psize: *mut usize, + dptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAllocHost_v2(pp: *mut *mut ::std::os::raw::c_void, bytesize: usize) -> CUresult; +} +extern "C" { + pub fn cuMemFreeHost(p: *mut ::std::os::raw::c_void) -> CUresult; +} +extern "C" { + pub fn cuMemHostAlloc( + pp: *mut *mut ::std::os::raw::c_void, + bytesize: usize, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemHostGetDevicePointer_v2( + pdptr: *mut CUdeviceptr, + p: *mut ::std::os::raw::c_void, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemHostGetFlags( + pFlags: *mut ::std::os::raw::c_uint, + p: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAllocManaged( + dptr: *mut CUdeviceptr, + bytesize: usize, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetByPCIBusId( + dev: *mut CUdevice, + pciBusId: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetPCIBusId( + pciBusId: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuIpcGetEventHandle(pHandle: *mut CUipcEventHandle, event: CUevent) -> CUresult; +} +extern "C" { + pub fn cuIpcOpenEventHandle(phEvent: *mut CUevent, handle: CUipcEventHandle) -> CUresult; +} +extern "C" { + pub fn cuIpcGetMemHandle(pHandle: *mut CUipcMemHandle, dptr: CUdeviceptr) -> CUresult; +} +extern "C" { + pub fn cuIpcOpenMemHandle_v2( + pdptr: *mut CUdeviceptr, + handle: CUipcMemHandle, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuIpcCloseMemHandle(dptr: CUdeviceptr) -> CUresult; +} +extern "C" { + pub fn cuMemHostRegister_v2( + p: *mut ::std::os::raw::c_void, + bytesize: usize, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemHostUnregister(p: *mut ::std::os::raw::c_void) -> CUresult; +} +extern "C" { + pub fn cuMemcpy_ptds(dst: CUdeviceptr, src: CUdeviceptr, ByteCount: usize) -> CUresult; +} +extern "C" { + pub fn cuMemcpyPeer_ptds( + dstDevice: CUdeviceptr, + dstContext: CUcontext, + srcDevice: CUdeviceptr, + srcContext: CUcontext, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoD_v2_ptds( + dstDevice: CUdeviceptr, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoH_v2_ptds( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoD_v2_ptds( + dstDevice: CUdeviceptr, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoA_v2_ptds( + dstArray: CUarray, + dstOffset: usize, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoD_v2_ptds( + dstDevice: CUdeviceptr, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoA_v2_ptds( + dstArray: CUarray, + dstOffset: usize, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoH_v2_ptds( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoA_v2_ptds( + dstArray: CUarray, + dstOffset: usize, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2D_v2_ptds(pCopy: *const CUDA_MEMCPY2D) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DUnaligned_v2_ptds(pCopy: *const CUDA_MEMCPY2D) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3D_v2_ptds(pCopy: *const CUDA_MEMCPY3D) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DPeer_ptds(pCopy: *const CUDA_MEMCPY3D_PEER) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAsync_ptsz( + dst: CUdeviceptr, + src: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyPeerAsync_ptsz( + dstDevice: CUdeviceptr, + dstContext: CUcontext, + srcDevice: CUdeviceptr, + srcContext: CUcontext, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoDAsync_v2_ptsz( + dstDevice: CUdeviceptr, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoHAsync_v2_ptsz( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoDAsync_v2_ptsz( + dstDevice: CUdeviceptr, + srcDevice: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoAAsync_v2_ptsz( + dstArray: CUarray, + dstOffset: usize, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoHAsync_v2_ptsz( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DAsync_v2_ptsz(pCopy: *const CUDA_MEMCPY2D, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DAsync_v2_ptsz(pCopy: *const CUDA_MEMCPY3D, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DPeerAsync_ptsz( + pCopy: *const CUDA_MEMCPY3D_PEER, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD8_v2_ptds( + dstDevice: CUdeviceptr, + uc: ::std::os::raw::c_uchar, + N: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD16_v2_ptds( + dstDevice: CUdeviceptr, + us: ::std::os::raw::c_ushort, + N: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD32_v2_ptds( + dstDevice: CUdeviceptr, + ui: ::std::os::raw::c_uint, + N: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D8_v2_ptds( + dstDevice: CUdeviceptr, + dstPitch: usize, + uc: ::std::os::raw::c_uchar, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D16_v2_ptds( + dstDevice: CUdeviceptr, + dstPitch: usize, + us: ::std::os::raw::c_ushort, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D32_v2_ptds( + dstDevice: CUdeviceptr, + dstPitch: usize, + ui: ::std::os::raw::c_uint, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD8Async_ptsz( + dstDevice: CUdeviceptr, + uc: ::std::os::raw::c_uchar, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD16Async_ptsz( + dstDevice: CUdeviceptr, + us: ::std::os::raw::c_ushort, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD32Async_ptsz( + dstDevice: CUdeviceptr, + ui: ::std::os::raw::c_uint, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D8Async_ptsz( + dstDevice: CUdeviceptr, + dstPitch: usize, + uc: ::std::os::raw::c_uchar, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D16Async_ptsz( + dstDevice: CUdeviceptr, + dstPitch: usize, + us: ::std::os::raw::c_ushort, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D32Async_ptsz( + dstDevice: CUdeviceptr, + dstPitch: usize, + ui: ::std::os::raw::c_uint, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayCreate_v2( + pHandle: *mut CUarray, + pAllocateArray: *const CUDA_ARRAY_DESCRIPTOR, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayGetDescriptor_v2( + pArrayDescriptor: *mut CUDA_ARRAY_DESCRIPTOR, + hArray: CUarray, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayGetSparseProperties( + sparseProperties: *mut CUDA_ARRAY_SPARSE_PROPERTIES, + array: CUarray, + ) -> CUresult; +} +extern "C" { + pub fn cuMipmappedArrayGetSparseProperties( + sparseProperties: *mut CUDA_ARRAY_SPARSE_PROPERTIES, + mipmap: CUmipmappedArray, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayGetMemoryRequirements( + memoryRequirements: *mut CUDA_ARRAY_MEMORY_REQUIREMENTS, + array: CUarray, + device: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuMipmappedArrayGetMemoryRequirements( + memoryRequirements: *mut CUDA_ARRAY_MEMORY_REQUIREMENTS, + mipmap: CUmipmappedArray, + device: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayGetPlane( + pPlaneArray: *mut CUarray, + hArray: CUarray, + planeIdx: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayDestroy(hArray: CUarray) -> CUresult; +} +extern "C" { + pub fn cuArray3DCreate_v2( + pHandle: *mut CUarray, + pAllocateArray: *const CUDA_ARRAY3D_DESCRIPTOR, + ) -> CUresult; +} +extern "C" { + pub fn cuArray3DGetDescriptor_v2( + pArrayDescriptor: *mut CUDA_ARRAY3D_DESCRIPTOR, + hArray: CUarray, + ) -> CUresult; +} +extern "C" { + pub fn cuMipmappedArrayCreate( + pHandle: *mut CUmipmappedArray, + pMipmappedArrayDesc: *const CUDA_ARRAY3D_DESCRIPTOR, + numMipmapLevels: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMipmappedArrayGetLevel( + pLevelArray: *mut CUarray, + hMipmappedArray: CUmipmappedArray, + level: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMipmappedArrayDestroy(hMipmappedArray: CUmipmappedArray) -> CUresult; +} +extern "C" { + pub fn cuMemGetHandleForAddressRange( + handle: *mut ::std::os::raw::c_void, + dptr: CUdeviceptr, + size: usize, + handleType: CUmemRangeHandleType, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAddressReserve( + ptr: *mut CUdeviceptr, + size: usize, + alignment: usize, + addr: CUdeviceptr, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAddressFree(ptr: CUdeviceptr, size: usize) -> CUresult; +} +extern "C" { + pub fn cuMemCreate( + handle: *mut CUmemGenericAllocationHandle, + size: usize, + prop: *const CUmemAllocationProp, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemRelease(handle: CUmemGenericAllocationHandle) -> CUresult; +} +extern "C" { + pub fn cuMemMap( + ptr: CUdeviceptr, + size: usize, + offset: usize, + handle: CUmemGenericAllocationHandle, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemMapArrayAsync_ptsz( + mapInfoList: *mut CUarrayMapInfo, + count: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemUnmap(ptr: CUdeviceptr, size: usize) -> CUresult; +} +extern "C" { + pub fn cuMemSetAccess( + ptr: CUdeviceptr, + size: usize, + desc: *const CUmemAccessDesc, + count: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemGetAccess( + flags: *mut ::std::os::raw::c_ulonglong, + location: *const CUmemLocation, + ptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuMemExportToShareableHandle( + shareableHandle: *mut ::std::os::raw::c_void, + handle: CUmemGenericAllocationHandle, + handleType: CUmemAllocationHandleType, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemImportFromShareableHandle( + handle: *mut CUmemGenericAllocationHandle, + osHandle: *mut ::std::os::raw::c_void, + shHandleType: CUmemAllocationHandleType, + ) -> CUresult; +} +extern "C" { + pub fn cuMemGetAllocationGranularity( + granularity: *mut usize, + prop: *const CUmemAllocationProp, + option: CUmemAllocationGranularity_flags, + ) -> CUresult; +} +extern "C" { + pub fn cuMemGetAllocationPropertiesFromHandle( + prop: *mut CUmemAllocationProp, + handle: CUmemGenericAllocationHandle, + ) -> CUresult; +} +extern "C" { + pub fn cuMemRetainAllocationHandle( + handle: *mut CUmemGenericAllocationHandle, + addr: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuMemFreeAsync_ptsz(dptr: CUdeviceptr, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemAllocAsync_ptsz( + dptr: *mut CUdeviceptr, + bytesize: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolTrimTo(pool: CUmemoryPool, minBytesToKeep: usize) -> CUresult; +} +extern "C" { + pub fn cuMemPoolSetAttribute( + pool: CUmemoryPool, + attr: CUmemPool_attribute, + value: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolGetAttribute( + pool: CUmemoryPool, + attr: CUmemPool_attribute, + value: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolSetAccess( + pool: CUmemoryPool, + map: *const CUmemAccessDesc, + count: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolGetAccess( + flags: *mut CUmemAccess_flags, + memPool: CUmemoryPool, + location: *mut CUmemLocation, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolCreate(pool: *mut CUmemoryPool, poolProps: *const CUmemPoolProps) -> CUresult; +} +extern "C" { + pub fn cuMemPoolDestroy(pool: CUmemoryPool) -> CUresult; +} +extern "C" { + pub fn cuMemAllocFromPoolAsync_ptsz( + dptr: *mut CUdeviceptr, + bytesize: usize, + pool: CUmemoryPool, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolExportToShareableHandle( + handle_out: *mut ::std::os::raw::c_void, + pool: CUmemoryPool, + handleType: CUmemAllocationHandleType, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolImportFromShareableHandle( + pool_out: *mut CUmemoryPool, + handle: *mut ::std::os::raw::c_void, + handleType: CUmemAllocationHandleType, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolExportPointer( + shareData_out: *mut CUmemPoolPtrExportData, + ptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPoolImportPointer( + ptr_out: *mut CUdeviceptr, + pool: CUmemoryPool, + shareData: *mut CUmemPoolPtrExportData, + ) -> CUresult; +} +extern "C" { + pub fn cuMulticastCreate( + mcHandle: *mut CUmemGenericAllocationHandle, + prop: *const CUmulticastObjectProp, + ) -> CUresult; +} +extern "C" { + pub fn cuMulticastAddDevice(mcHandle: CUmemGenericAllocationHandle, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuMulticastBindMem( + mcHandle: CUmemGenericAllocationHandle, + mcOffset: usize, + memHandle: CUmemGenericAllocationHandle, + memOffset: usize, + size: usize, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMulticastBindAddr( + mcHandle: CUmemGenericAllocationHandle, + mcOffset: usize, + memptr: CUdeviceptr, + size: usize, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuMulticastUnbind( + mcHandle: CUmemGenericAllocationHandle, + dev: CUdevice, + mcOffset: usize, + size: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMulticastGetGranularity( + granularity: *mut usize, + prop: *const CUmulticastObjectProp, + option: CUmulticastGranularity_flags, + ) -> CUresult; +} +extern "C" { + pub fn cuPointerGetAttribute( + data: *mut ::std::os::raw::c_void, + attribute: CUpointer_attribute, + ptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPrefetchAsync_ptsz( + devPtr: CUdeviceptr, + count: usize, + dstDevice: CUdevice, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPrefetchAsync_v2_ptsz( + devPtr: CUdeviceptr, + count: usize, + location: CUmemLocation, + flags: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAdvise( + devPtr: CUdeviceptr, + count: usize, + advice: CUmem_advise, + device: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAdvise_v2( + devPtr: CUdeviceptr, + count: usize, + advice: CUmem_advise, + location: CUmemLocation, + ) -> CUresult; +} +extern "C" { + pub fn cuMemRangeGetAttribute( + data: *mut ::std::os::raw::c_void, + dataSize: usize, + attribute: CUmem_range_attribute, + devPtr: CUdeviceptr, + count: usize, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuPointerSetAttribute( + value: *const ::std::os::raw::c_void, + attribute: CUpointer_attribute, + ptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuPointerGetAttributes( + numAttributes: ::std::os::raw::c_uint, + attributes: *mut CUpointer_attribute, + data: *mut *mut ::std::os::raw::c_void, + ptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamCreate(phStream: *mut CUstream, Flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuStreamCreateWithPriority( + phStream: *mut CUstream, + flags: ::std::os::raw::c_uint, + priority: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetPriority_ptsz( + hStream: CUstream, + priority: *mut ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetFlags_ptsz(hStream: CUstream, flags: *mut ::std::os::raw::c_uint) + -> CUresult; +} +extern "C" { + pub fn cuStreamGetId_ptsz( + hStream: CUstream, + streamId: *mut ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCtx_ptsz(hStream: CUstream, pctx: *mut CUcontext) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitEvent_ptsz( + hStream: CUstream, + hEvent: CUevent, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamAddCallback_ptsz( + hStream: CUstream, + callback: CUstreamCallback, + userData: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBeginCapture_v2_ptsz(hStream: CUstream, mode: CUstreamCaptureMode) -> CUresult; +} +extern "C" { + pub fn cuThreadExchangeStreamCaptureMode(mode: *mut CUstreamCaptureMode) -> CUresult; +} +extern "C" { + pub fn cuStreamEndCapture_ptsz(hStream: CUstream, phGraph: *mut CUgraph) -> CUresult; +} +extern "C" { + pub fn cuStreamIsCapturing_ptsz( + hStream: CUstream, + captureStatus: *mut CUstreamCaptureStatus, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCaptureInfo_v2_ptsz( + hStream: CUstream, + captureStatus_out: *mut CUstreamCaptureStatus, + id_out: *mut cuuint64_t, + graph_out: *mut CUgraph, + dependencies_out: *mut *const CUgraphNode, + numDependencies_out: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamUpdateCaptureDependencies_ptsz( + hStream: CUstream, + dependencies: *mut CUgraphNode, + numDependencies: usize, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamAttachMemAsync_ptsz( + hStream: CUstream, + dptr: CUdeviceptr, + length: usize, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamQuery_ptsz(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamSynchronize_ptsz(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamDestroy_v2(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamCopyAttributes_ptsz(dst: CUstream, src: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamGetAttribute_ptsz( + hStream: CUstream, + attr: CUstreamAttrID, + value_out: *mut CUstreamAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamSetAttribute_ptsz( + hStream: CUstream, + attr: CUstreamAttrID, + value: *const CUstreamAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuEventCreate(phEvent: *mut CUevent, Flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuEventRecord_ptsz(hEvent: CUevent, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuEventRecordWithFlags_ptsz( + hEvent: CUevent, + hStream: CUstream, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuEventQuery(hEvent: CUevent) -> CUresult; +} +extern "C" { + pub fn cuEventSynchronize(hEvent: CUevent) -> CUresult; +} +extern "C" { + pub fn cuEventDestroy_v2(hEvent: CUevent) -> CUresult; +} +extern "C" { + pub fn cuEventElapsedTime(pMilliseconds: *mut f32, hStart: CUevent, hEnd: CUevent) -> CUresult; +} +extern "C" { + pub fn cuImportExternalMemory( + extMem_out: *mut CUexternalMemory, + memHandleDesc: *const CUDA_EXTERNAL_MEMORY_HANDLE_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuExternalMemoryGetMappedBuffer( + devPtr: *mut CUdeviceptr, + extMem: CUexternalMemory, + bufferDesc: *const CUDA_EXTERNAL_MEMORY_BUFFER_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuExternalMemoryGetMappedMipmappedArray( + mipmap: *mut CUmipmappedArray, + extMem: CUexternalMemory, + mipmapDesc: *const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuDestroyExternalMemory(extMem: CUexternalMemory) -> CUresult; +} +extern "C" { + pub fn cuImportExternalSemaphore( + extSem_out: *mut CUexternalSemaphore, + semHandleDesc: *const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuSignalExternalSemaphoresAsync_ptsz( + extSemArray: *const CUexternalSemaphore, + paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS, + numExtSems: ::std::os::raw::c_uint, + stream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuWaitExternalSemaphoresAsync_ptsz( + extSemArray: *const CUexternalSemaphore, + paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS, + numExtSems: ::std::os::raw::c_uint, + stream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuDestroyExternalSemaphore(extSem: CUexternalSemaphore) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue32_v2_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue64_v2_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue32_v2_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue64_v2_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBatchMemOp_v2_ptsz( + stream: CUstream, + count: ::std::os::raw::c_uint, + paramArray: *mut CUstreamBatchMemOpParams, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuFuncGetAttribute( + pi: *mut ::std::os::raw::c_int, + attrib: CUfunction_attribute, + hfunc: CUfunction, + ) -> CUresult; +} +extern "C" { + pub fn cuFuncSetAttribute( + hfunc: CUfunction, + attrib: CUfunction_attribute, + value: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuFuncSetCacheConfig(hfunc: CUfunction, config: CUfunc_cache) -> CUresult; +} +extern "C" { + pub fn cuFuncSetSharedMemConfig(hfunc: CUfunction, config: CUsharedconfig) -> CUresult; +} +extern "C" { + pub fn cuFuncGetModule(hmod: *mut CUmodule, hfunc: CUfunction) -> CUresult; +} +extern "C" { + pub fn cuLaunchKernel_ptsz( + 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; +} +extern "C" { + pub fn cuLaunchKernelEx_ptsz( + config: *const CUlaunchConfig, + f: CUfunction, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuLaunchCooperativeKernel_ptsz( + 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; +} +extern "C" { + pub fn cuLaunchCooperativeKernelMultiDevice( + launchParamsList: *mut CUDA_LAUNCH_PARAMS, + numDevices: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuLaunchHostFunc_ptsz( + hStream: CUstream, + fn_: CUhostFn, + userData: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuFuncSetBlockShape( + hfunc: CUfunction, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + z: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuFuncSetSharedSize(hfunc: CUfunction, bytes: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuParamSetSize(hfunc: CUfunction, numbytes: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuParamSeti( + hfunc: CUfunction, + offset: ::std::os::raw::c_int, + value: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuParamSetf(hfunc: CUfunction, offset: ::std::os::raw::c_int, value: f32) -> CUresult; +} +extern "C" { + pub fn cuParamSetv( + hfunc: CUfunction, + offset: ::std::os::raw::c_int, + ptr: *mut ::std::os::raw::c_void, + numbytes: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuLaunch(f: CUfunction) -> CUresult; +} +extern "C" { + pub fn cuLaunchGrid( + f: CUfunction, + grid_width: ::std::os::raw::c_int, + grid_height: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuLaunchGridAsync( + f: CUfunction, + grid_width: ::std::os::raw::c_int, + grid_height: ::std::os::raw::c_int, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuParamSetTexRef( + hfunc: CUfunction, + texunit: ::std::os::raw::c_int, + hTexRef: CUtexref, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphCreate(phGraph: *mut CUgraph, flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuGraphAddKernelNode_v2( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeGetParams_v2( + hNode: CUgraphNode, + nodeParams: *mut CUDA_KERNEL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeSetParams_v2( + hNode: CUgraphNode, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddMemcpyNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + copyParams: *const CUDA_MEMCPY3D, + ctx: CUcontext, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemcpyNodeGetParams( + hNode: CUgraphNode, + nodeParams: *mut CUDA_MEMCPY3D, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemcpyNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_MEMCPY3D, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddMemsetNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + memsetParams: *const CUDA_MEMSET_NODE_PARAMS, + ctx: CUcontext, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemsetNodeGetParams( + hNode: CUgraphNode, + nodeParams: *mut CUDA_MEMSET_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemsetNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_MEMSET_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddHostNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_HOST_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphHostNodeGetParams( + hNode: CUgraphNode, + nodeParams: *mut CUDA_HOST_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphHostNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_HOST_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddChildGraphNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + childGraph: CUgraph, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphChildGraphNodeGetGraph(hNode: CUgraphNode, phGraph: *mut CUgraph) -> CUresult; +} +extern "C" { + pub fn cuGraphAddEmptyNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddEventRecordNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + event: CUevent, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphEventRecordNodeGetEvent(hNode: CUgraphNode, event_out: *mut CUevent) -> CUresult; +} +extern "C" { + pub fn cuGraphEventRecordNodeSetEvent(hNode: CUgraphNode, event: CUevent) -> CUresult; +} +extern "C" { + pub fn cuGraphAddEventWaitNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + event: CUevent, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphEventWaitNodeGetEvent(hNode: CUgraphNode, event_out: *mut CUevent) -> CUresult; +} +extern "C" { + pub fn cuGraphEventWaitNodeSetEvent(hNode: CUgraphNode, event: CUevent) -> CUresult; +} +extern "C" { + pub fn cuGraphAddExternalSemaphoresSignalNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExternalSemaphoresSignalNodeGetParams( + hNode: CUgraphNode, + params_out: *mut CUDA_EXT_SEM_SIGNAL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExternalSemaphoresSignalNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddExternalSemaphoresWaitNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExternalSemaphoresWaitNodeGetParams( + hNode: CUgraphNode, + params_out: *mut CUDA_EXT_SEM_WAIT_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExternalSemaphoresWaitNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddBatchMemOpNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_BATCH_MEM_OP_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphBatchMemOpNodeGetParams( + hNode: CUgraphNode, + nodeParams_out: *mut CUDA_BATCH_MEM_OP_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphBatchMemOpNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_BATCH_MEM_OP_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecBatchMemOpNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_BATCH_MEM_OP_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddMemAllocNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *mut CUDA_MEM_ALLOC_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemAllocNodeGetParams( + hNode: CUgraphNode, + params_out: *mut CUDA_MEM_ALLOC_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddMemFreeNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + dptr: CUdeviceptr, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphMemFreeNodeGetParams(hNode: CUgraphNode, dptr_out: *mut CUdeviceptr) -> CUresult; +} +extern "C" { + pub fn cuDeviceGraphMemTrim(device: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetGraphMemAttribute( + device: CUdevice, + attr: CUgraphMem_attribute, + value: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceSetGraphMemAttribute( + device: CUdevice, + attr: CUgraphMem_attribute, + value: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphClone(phGraphClone: *mut CUgraph, originalGraph: CUgraph) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeFindInClone( + phNode: *mut CUgraphNode, + hOriginalNode: CUgraphNode, + hClonedGraph: CUgraph, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeGetType(hNode: CUgraphNode, type_: *mut CUgraphNodeType) -> CUresult; +} +extern "C" { + pub fn cuGraphGetNodes( + hGraph: CUgraph, + nodes: *mut CUgraphNode, + numNodes: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphGetRootNodes( + hGraph: CUgraph, + rootNodes: *mut CUgraphNode, + numRootNodes: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphGetEdges( + hGraph: CUgraph, + from: *mut CUgraphNode, + to: *mut CUgraphNode, + numEdges: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeGetDependencies( + hNode: CUgraphNode, + dependencies: *mut CUgraphNode, + numDependencies: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeGetDependentNodes( + hNode: CUgraphNode, + dependentNodes: *mut CUgraphNode, + numDependentNodes: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddDependencies( + hGraph: CUgraph, + from: *const CUgraphNode, + to: *const CUgraphNode, + numDependencies: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphRemoveDependencies( + hGraph: CUgraph, + from: *const CUgraphNode, + to: *const CUgraphNode, + numDependencies: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphDestroyNode(hNode: CUgraphNode) -> CUresult; +} +extern "C" { + pub fn cuGraphInstantiateWithFlags( + phGraphExec: *mut CUgraphExec, + hGraph: CUgraph, + flags: ::std::os::raw::c_ulonglong, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphInstantiateWithParams_ptsz( + phGraphExec: *mut CUgraphExec, + hGraph: CUgraph, + instantiateParams: *mut CUDA_GRAPH_INSTANTIATE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecGetFlags(hGraphExec: CUgraphExec, flags: *mut cuuint64_t) -> CUresult; +} +extern "C" { + pub fn cuGraphExecKernelNodeSetParams_v2( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecMemcpyNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + copyParams: *const CUDA_MEMCPY3D, + ctx: CUcontext, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecMemsetNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + memsetParams: *const CUDA_MEMSET_NODE_PARAMS, + ctx: CUcontext, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecHostNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_HOST_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecChildGraphNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + childGraph: CUgraph, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecEventRecordNodeSetEvent( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + event: CUevent, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecEventWaitNodeSetEvent( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + event: CUevent, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecExternalSemaphoresSignalNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecExternalSemaphoresWaitNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeSetEnabled( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + isEnabled: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeGetEnabled( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + isEnabled: *mut ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphUpload_ptsz(hGraphExec: CUgraphExec, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuGraphLaunch_ptsz(hGraphExec: CUgraphExec, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuGraphExecDestroy(hGraphExec: CUgraphExec) -> CUresult; +} +extern "C" { + pub fn cuGraphDestroy(hGraph: CUgraph) -> CUresult; +} +extern "C" { + pub fn cuGraphExecUpdate_v2( + hGraphExec: CUgraphExec, + hGraph: CUgraph, + resultInfo: *mut CUgraphExecUpdateResultInfo, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeCopyAttributes(dst: CUgraphNode, src: CUgraphNode) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeGetAttribute( + hNode: CUgraphNode, + attr: CUkernelNodeAttrID, + value_out: *mut CUkernelNodeAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeSetAttribute( + hNode: CUgraphNode, + attr: CUkernelNodeAttrID, + value: *const CUkernelNodeAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphDebugDotPrint( + hGraph: CUgraph, + path: *const ::std::os::raw::c_char, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuUserObjectCreate( + object_out: *mut CUuserObject, + ptr: *mut ::std::os::raw::c_void, + destroy: CUhostFn, + initialRefcount: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuUserObjectRetain(object: CUuserObject, count: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuUserObjectRelease(object: CUuserObject, count: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuGraphRetainUserObject( + graph: CUgraph, + object: CUuserObject, + count: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphReleaseUserObject( + graph: CUgraph, + object: CUuserObject, + count: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *mut CUgraphNodeParams, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphNodeSetParams(hNode: CUgraphNode, nodeParams: *mut CUgraphNodeParams) + -> CUresult; +} +extern "C" { + pub fn cuGraphExecNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *mut CUgraphNodeParams, + ) -> CUresult; +} +extern "C" { + pub fn cuOccupancyMaxActiveBlocksPerMultiprocessor( + numBlocks: *mut ::std::os::raw::c_int, + func: CUfunction, + blockSize: ::std::os::raw::c_int, + dynamicSMemSize: usize, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub 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; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuOccupancyAvailableDynamicSMemPerBlock( + dynamicSmemSize: *mut usize, + func: CUfunction, + numBlocks: ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuOccupancyMaxPotentialClusterSize( + clusterSize: *mut ::std::os::raw::c_int, + func: CUfunction, + config: *const CUlaunchConfig, + ) -> CUresult; +} +extern "C" { + pub fn cuOccupancyMaxActiveClusters( + numClusters: *mut ::std::os::raw::c_int, + func: CUfunction, + config: *const CUlaunchConfig, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetArray( + hTexRef: CUtexref, + hArray: CUarray, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetMipmappedArray( + hTexRef: CUtexref, + hMipmappedArray: CUmipmappedArray, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetAddress_v2( + ByteOffset: *mut usize, + hTexRef: CUtexref, + dptr: CUdeviceptr, + bytes: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetAddress2D_v3( + hTexRef: CUtexref, + desc: *const CUDA_ARRAY_DESCRIPTOR, + dptr: CUdeviceptr, + Pitch: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetFormat( + hTexRef: CUtexref, + fmt: CUarray_format, + NumPackedComponents: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetAddressMode( + hTexRef: CUtexref, + dim: ::std::os::raw::c_int, + am: CUaddress_mode, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetMipmapFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetMipmapLevelBias(hTexRef: CUtexref, bias: f32) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetMipmapLevelClamp( + hTexRef: CUtexref, + minMipmapLevelClamp: f32, + maxMipmapLevelClamp: f32, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetMaxAnisotropy( + hTexRef: CUtexref, + maxAniso: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetBorderColor(hTexRef: CUtexref, pBorderColor: *mut f32) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetFlags(hTexRef: CUtexref, Flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetAddress_v2(pdptr: *mut CUdeviceptr, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetArray(phArray: *mut CUarray, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetMipmappedArray( + phMipmappedArray: *mut CUmipmappedArray, + hTexRef: CUtexref, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetAddressMode( + pam: *mut CUaddress_mode, + hTexRef: CUtexref, + dim: ::std::os::raw::c_int, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetFilterMode(pfm: *mut CUfilter_mode, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetFormat( + pFormat: *mut CUarray_format, + pNumChannels: *mut ::std::os::raw::c_int, + hTexRef: CUtexref, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetMipmapFilterMode(pfm: *mut CUfilter_mode, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetMipmapLevelBias(pbias: *mut f32, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetMipmapLevelClamp( + pminMipmapLevelClamp: *mut f32, + pmaxMipmapLevelClamp: *mut f32, + hTexRef: CUtexref, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetMaxAnisotropy( + pmaxAniso: *mut ::std::os::raw::c_int, + hTexRef: CUtexref, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetBorderColor(pBorderColor: *mut f32, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetFlags(pFlags: *mut ::std::os::raw::c_uint, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefCreate(pTexRef: *mut CUtexref) -> CUresult; +} +extern "C" { + pub fn cuTexRefDestroy(hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuSurfRefSetArray( + hSurfRef: CUsurfref, + hArray: CUarray, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuSurfRefGetArray(phArray: *mut CUarray, hSurfRef: CUsurfref) -> CUresult; +} +extern "C" { + pub fn cuTexObjectCreate( + pTexObject: *mut CUtexObject, + pResDesc: *const CUDA_RESOURCE_DESC, + pTexDesc: *const CUDA_TEXTURE_DESC, + pResViewDesc: *const CUDA_RESOURCE_VIEW_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuTexObjectDestroy(texObject: CUtexObject) -> CUresult; +} +extern "C" { + pub fn cuTexObjectGetResourceDesc( + pResDesc: *mut CUDA_RESOURCE_DESC, + texObject: CUtexObject, + ) -> CUresult; +} +extern "C" { + pub fn cuTexObjectGetTextureDesc( + pTexDesc: *mut CUDA_TEXTURE_DESC, + texObject: CUtexObject, + ) -> CUresult; +} +extern "C" { + pub fn cuTexObjectGetResourceViewDesc( + pResViewDesc: *mut CUDA_RESOURCE_VIEW_DESC, + texObject: CUtexObject, + ) -> CUresult; +} +extern "C" { + pub fn cuSurfObjectCreate( + pSurfObject: *mut CUsurfObject, + pResDesc: *const CUDA_RESOURCE_DESC, + ) -> CUresult; +} +extern "C" { + pub fn cuSurfObjectDestroy(surfObject: CUsurfObject) -> CUresult; +} +extern "C" { + pub fn cuSurfObjectGetResourceDesc( + pResDesc: *mut CUDA_RESOURCE_DESC, + surfObject: CUsurfObject, + ) -> CUresult; +} +extern "C" { + pub fn cuTensorMapEncodeTiled( + tensorMap: *mut CUtensorMap, + tensorDataType: CUtensorMapDataType, + tensorRank: cuuint32_t, + globalAddress: *mut ::std::os::raw::c_void, + globalDim: *const cuuint64_t, + globalStrides: *const cuuint64_t, + boxDim: *const cuuint32_t, + elementStrides: *const cuuint32_t, + interleave: CUtensorMapInterleave, + swizzle: CUtensorMapSwizzle, + l2Promotion: CUtensorMapL2promotion, + oobFill: CUtensorMapFloatOOBfill, + ) -> CUresult; +} +extern "C" { + pub fn cuTensorMapEncodeIm2col( + tensorMap: *mut CUtensorMap, + tensorDataType: CUtensorMapDataType, + tensorRank: cuuint32_t, + globalAddress: *mut ::std::os::raw::c_void, + globalDim: *const cuuint64_t, + globalStrides: *const cuuint64_t, + pixelBoxLowerCorner: *const ::std::os::raw::c_int, + pixelBoxUpperCorner: *const ::std::os::raw::c_int, + channelsPerPixel: cuuint32_t, + pixelsPerColumn: cuuint32_t, + elementStrides: *const cuuint32_t, + interleave: CUtensorMapInterleave, + swizzle: CUtensorMapSwizzle, + l2Promotion: CUtensorMapL2promotion, + oobFill: CUtensorMapFloatOOBfill, + ) -> CUresult; +} +extern "C" { + pub fn cuTensorMapReplaceAddress( + tensorMap: *mut CUtensorMap, + globalAddress: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuDeviceCanAccessPeer( + canAccessPeer: *mut ::std::os::raw::c_int, + dev: CUdevice, + peerDev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxEnablePeerAccess(peerContext: CUcontext, Flags: ::std::os::raw::c_uint) + -> CUresult; +} +extern "C" { + pub fn cuCtxDisablePeerAccess(peerContext: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuDeviceGetP2PAttribute( + value: *mut ::std::os::raw::c_int, + attrib: CUdevice_P2PAttribute, + srcDevice: CUdevice, + dstDevice: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsUnregisterResource(resource: CUgraphicsResource) -> CUresult; +} +extern "C" { + pub fn cuGraphicsSubResourceGetMappedArray( + pArray: *mut CUarray, + resource: CUgraphicsResource, + arrayIndex: ::std::os::raw::c_uint, + mipLevel: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsResourceGetMappedMipmappedArray( + pMipmappedArray: *mut CUmipmappedArray, + resource: CUgraphicsResource, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsResourceGetMappedPointer_v2( + pDevPtr: *mut CUdeviceptr, + pSize: *mut usize, + resource: CUgraphicsResource, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsResourceSetMapFlags_v2( + resource: CUgraphicsResource, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsMapResources_ptsz( + count: ::std::os::raw::c_uint, + resources: *mut CUgraphicsResource, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsUnmapResources_ptsz( + count: ::std::os::raw::c_uint, + resources: *mut CUgraphicsResource, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuGetProcAddress_v2( + symbol: *const ::std::os::raw::c_char, + pfn: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + symbolStatus: *mut CUdriverProcAddressQueryResult, + ) -> CUresult; +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_ENABLE_ON_EXCEPTION: CUcoredumpSettings_enum = CUcoredumpSettings_enum(1); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_TRIGGER_HOST: CUcoredumpSettings_enum = CUcoredumpSettings_enum(2); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_LIGHTWEIGHT: CUcoredumpSettings_enum = CUcoredumpSettings_enum(3); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_ENABLE_USER_TRIGGER: CUcoredumpSettings_enum = CUcoredumpSettings_enum(4); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_FILE: CUcoredumpSettings_enum = CUcoredumpSettings_enum(5); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_PIPE: CUcoredumpSettings_enum = CUcoredumpSettings_enum(6); +} +impl CUcoredumpSettings_enum { + pub const CU_COREDUMP_MAX: CUcoredumpSettings_enum = CUcoredumpSettings_enum(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUcoredumpSettings_enum(pub ::std::os::raw::c_int); +pub use self::CUcoredumpSettings_enum as CUcoredumpSettings; +extern "C" { + pub fn cuCoredumpGetAttribute( + attrib: CUcoredumpSettings, + value: *mut ::std::os::raw::c_void, + size: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuCoredumpGetAttributeGlobal( + attrib: CUcoredumpSettings, + value: *mut ::std::os::raw::c_void, + size: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuCoredumpSetAttribute( + attrib: CUcoredumpSettings, + value: *mut ::std::os::raw::c_void, + size: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuCoredumpSetAttributeGlobal( + attrib: CUcoredumpSettings, + value: *mut ::std::os::raw::c_void, + size: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGetExportTable( + ppExportTable: *mut *const ::std::os::raw::c_void, + pExportTableId: *const CUuuid, + ) -> CUresult; +} +extern "C" { + pub fn cuMemHostRegister( + p: *mut ::std::os::raw::c_void, + bytesize: usize, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsResourceSetMapFlags( + resource: CUgraphicsResource, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuLinkCreate( + numOptions: ::std::os::raw::c_uint, + options: *mut CUjit_option, + optionValues: *mut *mut ::std::os::raw::c_void, + stateOut: *mut CUlinkState, + ) -> CUresult; +} +extern "C" { + pub fn cuLinkAddData( + 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; +} +extern "C" { + pub fn cuLinkAddFile( + 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; +} +extern "C" { + pub fn cuTexRefSetAddress2D_v2( + hTexRef: CUtexref, + desc: *const CUDA_ARRAY_DESCRIPTOR, + dptr: CUdeviceptr, + Pitch: usize, + ) -> CUresult; +} +#[repr(transparent)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUdeviceptr_v1(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEMCPY2D_v1_st { + pub srcXInBytes: ::std::os::raw::c_uint, + pub srcY: ::std::os::raw::c_uint, + pub srcMemoryType: CUmemorytype, + pub srcHost: *const ::std::os::raw::c_void, + pub srcDevice: CUdeviceptr_v1, + pub srcArray: CUarray, + pub srcPitch: ::std::os::raw::c_uint, + pub dstXInBytes: ::std::os::raw::c_uint, + pub dstY: ::std::os::raw::c_uint, + pub dstMemoryType: CUmemorytype, + pub dstHost: *mut ::std::os::raw::c_void, + pub dstDevice: CUdeviceptr_v1, + pub dstArray: CUarray, + pub dstPitch: ::std::os::raw::c_uint, + pub WidthInBytes: ::std::os::raw::c_uint, + pub Height: ::std::os::raw::c_uint, +} +pub type CUDA_MEMCPY2D_v1 = CUDA_MEMCPY2D_v1_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_MEMCPY3D_v1_st { + pub srcXInBytes: ::std::os::raw::c_uint, + pub srcY: ::std::os::raw::c_uint, + pub srcZ: ::std::os::raw::c_uint, + pub srcLOD: ::std::os::raw::c_uint, + pub srcMemoryType: CUmemorytype, + pub srcHost: *const ::std::os::raw::c_void, + pub srcDevice: CUdeviceptr_v1, + pub srcArray: CUarray, + pub reserved0: *mut ::std::os::raw::c_void, + pub srcPitch: ::std::os::raw::c_uint, + pub srcHeight: ::std::os::raw::c_uint, + pub dstXInBytes: ::std::os::raw::c_uint, + pub dstY: ::std::os::raw::c_uint, + pub dstZ: ::std::os::raw::c_uint, + pub dstLOD: ::std::os::raw::c_uint, + pub dstMemoryType: CUmemorytype, + pub dstHost: *mut ::std::os::raw::c_void, + pub dstDevice: CUdeviceptr_v1, + pub dstArray: CUarray, + pub reserved1: *mut ::std::os::raw::c_void, + pub dstPitch: ::std::os::raw::c_uint, + pub dstHeight: ::std::os::raw::c_uint, + pub WidthInBytes: ::std::os::raw::c_uint, + pub Height: ::std::os::raw::c_uint, + pub Depth: ::std::os::raw::c_uint, +} +pub type CUDA_MEMCPY3D_v1 = CUDA_MEMCPY3D_v1_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_ARRAY_DESCRIPTOR_v1_st { + pub Width: ::std::os::raw::c_uint, + pub Height: ::std::os::raw::c_uint, + pub Format: CUarray_format, + pub NumChannels: ::std::os::raw::c_uint, +} +pub type CUDA_ARRAY_DESCRIPTOR_v1 = CUDA_ARRAY_DESCRIPTOR_v1_st; +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct CUDA_ARRAY3D_DESCRIPTOR_v1_st { + pub Width: ::std::os::raw::c_uint, + pub Height: ::std::os::raw::c_uint, + pub Depth: ::std::os::raw::c_uint, + pub Format: CUarray_format, + pub NumChannels: ::std::os::raw::c_uint, + pub Flags: ::std::os::raw::c_uint, +} +pub type CUDA_ARRAY3D_DESCRIPTOR_v1 = CUDA_ARRAY3D_DESCRIPTOR_v1_st; +extern "C" { + pub fn cuDeviceTotalMem(bytes: *mut ::std::os::raw::c_uint, dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuCtxCreate( + pctx: *mut CUcontext, + flags: ::std::os::raw::c_uint, + dev: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuModuleGetGlobal( + dptr: *mut CUdeviceptr_v1, + bytes: *mut ::std::os::raw::c_uint, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + ) -> CUresult; +} +extern "C" { + pub fn cuMemGetInfo( + free: *mut ::std::os::raw::c_uint, + total: *mut ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAlloc(dptr: *mut CUdeviceptr_v1, bytesize: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuMemAllocPitch( + dptr: *mut CUdeviceptr_v1, + pPitch: *mut ::std::os::raw::c_uint, + WidthInBytes: ::std::os::raw::c_uint, + Height: ::std::os::raw::c_uint, + ElementSizeBytes: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemFree(dptr: CUdeviceptr_v1) -> CUresult; +} +extern "C" { + pub fn cuMemGetAddressRange( + pbase: *mut CUdeviceptr_v1, + psize: *mut ::std::os::raw::c_uint, + dptr: CUdeviceptr_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuMemAllocHost( + pp: *mut *mut ::std::os::raw::c_void, + bytesize: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemHostGetDevicePointer( + pdptr: *mut CUdeviceptr_v1, + p: *mut ::std::os::raw::c_void, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoD( + dstDevice: CUdeviceptr_v1, + srcHost: *const ::std::os::raw::c_void, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoH( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr_v1, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoD( + dstDevice: CUdeviceptr_v1, + srcDevice: CUdeviceptr_v1, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoA( + dstArray: CUarray, + dstOffset: ::std::os::raw::c_uint, + srcDevice: CUdeviceptr_v1, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoD( + dstDevice: CUdeviceptr_v1, + srcArray: CUarray, + srcOffset: ::std::os::raw::c_uint, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoA( + dstArray: CUarray, + dstOffset: ::std::os::raw::c_uint, + srcHost: *const ::std::os::raw::c_void, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoH( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: ::std::os::raw::c_uint, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoA( + dstArray: CUarray, + dstOffset: ::std::os::raw::c_uint, + srcArray: CUarray, + srcOffset: ::std::os::raw::c_uint, + ByteCount: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoAAsync( + dstArray: CUarray, + dstOffset: ::std::os::raw::c_uint, + srcHost: *const ::std::os::raw::c_void, + ByteCount: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoHAsync( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: ::std::os::raw::c_uint, + ByteCount: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2D(pCopy: *const CUDA_MEMCPY2D_v1) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DUnaligned(pCopy: *const CUDA_MEMCPY2D_v1) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3D(pCopy: *const CUDA_MEMCPY3D_v1) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoDAsync( + dstDevice: CUdeviceptr_v1, + srcHost: *const ::std::os::raw::c_void, + ByteCount: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoHAsync( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr_v1, + ByteCount: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoDAsync( + dstDevice: CUdeviceptr_v1, + srcDevice: CUdeviceptr_v1, + ByteCount: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DAsync(pCopy: *const CUDA_MEMCPY2D_v1, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DAsync(pCopy: *const CUDA_MEMCPY3D_v1, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemsetD8( + dstDevice: CUdeviceptr_v1, + uc: ::std::os::raw::c_uchar, + N: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD16( + dstDevice: CUdeviceptr_v1, + us: ::std::os::raw::c_ushort, + N: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD32( + dstDevice: CUdeviceptr_v1, + ui: ::std::os::raw::c_uint, + N: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D8( + dstDevice: CUdeviceptr_v1, + dstPitch: ::std::os::raw::c_uint, + uc: ::std::os::raw::c_uchar, + Width: ::std::os::raw::c_uint, + Height: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D16( + dstDevice: CUdeviceptr_v1, + dstPitch: ::std::os::raw::c_uint, + us: ::std::os::raw::c_ushort, + Width: ::std::os::raw::c_uint, + Height: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D32( + dstDevice: CUdeviceptr_v1, + dstPitch: ::std::os::raw::c_uint, + ui: ::std::os::raw::c_uint, + Width: ::std::os::raw::c_uint, + Height: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayCreate( + pHandle: *mut CUarray, + pAllocateArray: *const CUDA_ARRAY_DESCRIPTOR_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuArrayGetDescriptor( + pArrayDescriptor: *mut CUDA_ARRAY_DESCRIPTOR_v1, + hArray: CUarray, + ) -> CUresult; +} +extern "C" { + pub fn cuArray3DCreate( + pHandle: *mut CUarray, + pAllocateArray: *const CUDA_ARRAY3D_DESCRIPTOR_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuArray3DGetDescriptor( + pArrayDescriptor: *mut CUDA_ARRAY3D_DESCRIPTOR_v1, + hArray: CUarray, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetAddress( + ByteOffset: *mut ::std::os::raw::c_uint, + hTexRef: CUtexref, + dptr: CUdeviceptr_v1, + bytes: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefSetAddress2D( + hTexRef: CUtexref, + desc: *const CUDA_ARRAY_DESCRIPTOR_v1, + dptr: CUdeviceptr_v1, + Pitch: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuTexRefGetAddress(pdptr: *mut CUdeviceptr_v1, hTexRef: CUtexref) -> CUresult; +} +extern "C" { + pub fn cuGraphicsResourceGetMappedPointer( + pDevPtr: *mut CUdeviceptr_v1, + pSize: *mut ::std::os::raw::c_uint, + resource: CUgraphicsResource, + ) -> CUresult; +} +extern "C" { + pub fn cuCtxDestroy(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxPopCurrent(pctx: *mut CUcontext) -> CUresult; +} +extern "C" { + pub fn cuCtxPushCurrent(ctx: CUcontext) -> CUresult; +} +extern "C" { + pub fn cuStreamDestroy(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuEventDestroy(hEvent: CUevent) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxRelease(dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxReset(dev: CUdevice) -> CUresult; +} +extern "C" { + pub fn cuDevicePrimaryCtxSetFlags(dev: CUdevice, flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoD_v2( + dstDevice: CUdeviceptr, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoH_v2( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoD_v2( + dstDevice: CUdeviceptr, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoA_v2( + dstArray: CUarray, + dstOffset: usize, + srcDevice: CUdeviceptr, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoD_v2( + dstDevice: CUdeviceptr, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoA_v2( + dstArray: CUarray, + dstOffset: usize, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoH_v2( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoA_v2( + dstArray: CUarray, + dstOffset: usize, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoAAsync_v2( + dstArray: CUarray, + dstOffset: usize, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAtoHAsync_v2( + dstHost: *mut ::std::os::raw::c_void, + srcArray: CUarray, + srcOffset: usize, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2D_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DUnaligned_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3D_v2(pCopy: *const CUDA_MEMCPY3D) -> CUresult; +} +extern "C" { + pub fn cuMemcpyHtoDAsync_v2( + dstDevice: CUdeviceptr, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoHAsync_v2( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyDtoDAsync_v2( + dstDevice: CUdeviceptr, + srcDevice: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy2DAsync_v2(pCopy: *const CUDA_MEMCPY2D, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DAsync_v2(pCopy: *const CUDA_MEMCPY3D, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemsetD8_v2(dstDevice: CUdeviceptr, uc: ::std::os::raw::c_uchar, N: usize) + -> CUresult; +} +extern "C" { + pub fn cuMemsetD16_v2( + dstDevice: CUdeviceptr, + us: ::std::os::raw::c_ushort, + N: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD32_v2(dstDevice: CUdeviceptr, ui: ::std::os::raw::c_uint, N: usize) + -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D8_v2( + dstDevice: CUdeviceptr, + dstPitch: usize, + uc: ::std::os::raw::c_uchar, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D16_v2( + dstDevice: CUdeviceptr, + dstPitch: usize, + us: ::std::os::raw::c_ushort, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D32_v2( + dstDevice: CUdeviceptr, + dstPitch: usize, + ui: ::std::os::raw::c_uint, + Width: usize, + Height: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy(dst: CUdeviceptr, src: CUdeviceptr, ByteCount: usize) -> CUresult; +} +extern "C" { + pub fn cuMemcpyAsync( + dst: CUdeviceptr, + src: CUdeviceptr, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyPeer( + dstDevice: CUdeviceptr, + dstContext: CUcontext, + srcDevice: CUdeviceptr, + srcContext: CUcontext, + ByteCount: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpyPeerAsync( + dstDevice: CUdeviceptr, + dstContext: CUcontext, + srcDevice: CUdeviceptr, + srcContext: CUcontext, + ByteCount: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DPeer(pCopy: *const CUDA_MEMCPY3D_PEER) -> CUresult; +} +extern "C" { + pub fn cuMemcpy3DPeerAsync(pCopy: *const CUDA_MEMCPY3D_PEER, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemsetD8Async( + dstDevice: CUdeviceptr, + uc: ::std::os::raw::c_uchar, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD16Async( + dstDevice: CUdeviceptr, + us: ::std::os::raw::c_ushort, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD32Async( + dstDevice: CUdeviceptr, + ui: ::std::os::raw::c_uint, + N: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D8Async( + dstDevice: CUdeviceptr, + dstPitch: usize, + uc: ::std::os::raw::c_uchar, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D16Async( + dstDevice: CUdeviceptr, + dstPitch: usize, + us: ::std::os::raw::c_ushort, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemsetD2D32Async( + dstDevice: CUdeviceptr, + dstPitch: usize, + ui: ::std::os::raw::c_uint, + Width: usize, + Height: usize, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetPriority(hStream: CUstream, priority: *mut ::std::os::raw::c_int) + -> CUresult; +} +extern "C" { + pub fn cuStreamGetId(hStream: CUstream, streamId: *mut ::std::os::raw::c_ulonglong) + -> CUresult; +} +extern "C" { + pub fn cuStreamGetFlags(hStream: CUstream, flags: *mut ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCtx(hStream: CUstream, pctx: *mut CUcontext) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitEvent( + hStream: CUstream, + hEvent: CUevent, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamAddCallback( + hStream: CUstream, + callback: CUstreamCallback, + userData: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamAttachMemAsync( + hStream: CUstream, + dptr: CUdeviceptr, + length: usize, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamQuery(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamSynchronize(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuEventRecord(hEvent: CUevent, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuEventRecordWithFlags( + hEvent: CUevent, + hStream: CUstream, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuLaunchKernelEx( + config: *const CUlaunchConfig, + f: CUfunction, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuLaunchHostFunc( + hStream: CUstream, + fn_: CUhostFn, + userData: *mut ::std::os::raw::c_void, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsMapResources( + count: ::std::os::raw::c_uint, + resources: *mut CUgraphicsResource, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsUnmapResources( + count: ::std::os::raw::c_uint, + resources: *mut CUgraphicsResource, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue32( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue32( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue64( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue64( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBatchMemOp( + stream: CUstream, + count: ::std::os::raw::c_uint, + paramArray: *mut CUstreamBatchMemOpParams, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue32_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue32_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue64_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue64_ptsz( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBatchMemOp_ptsz( + stream: CUstream, + count: ::std::os::raw::c_uint, + paramArray: *mut CUstreamBatchMemOpParams, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue32_v2( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue32_v2( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint32_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWriteValue64_v2( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamWaitValue64_v2( + stream: CUstream, + addr: CUdeviceptr, + value: cuuint64_t, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBatchMemOp_v2( + stream: CUstream, + count: ::std::os::raw::c_uint, + paramArray: *mut CUstreamBatchMemOpParams, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPrefetchAsync( + devPtr: CUdeviceptr, + count: usize, + dstDevice: CUdevice, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemPrefetchAsync_v2( + devPtr: CUdeviceptr, + count: usize, + location: CUmemLocation, + flags: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub 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; +} +extern "C" { + pub fn cuSignalExternalSemaphoresAsync( + extSemArray: *const CUexternalSemaphore, + paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS, + numExtSems: ::std::os::raw::c_uint, + stream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuWaitExternalSemaphoresAsync( + extSemArray: *const CUexternalSemaphore, + paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS, + numExtSems: ::std::os::raw::c_uint, + stream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamBeginCapture(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamBeginCapture_ptsz(hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamBeginCapture_v2(hStream: CUstream, mode: CUstreamCaptureMode) -> CUresult; +} +extern "C" { + pub fn cuStreamEndCapture(hStream: CUstream, phGraph: *mut CUgraph) -> CUresult; +} +extern "C" { + pub fn cuStreamIsCapturing( + hStream: CUstream, + captureStatus: *mut CUstreamCaptureStatus, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCaptureInfo( + hStream: CUstream, + captureStatus_out: *mut CUstreamCaptureStatus, + id_out: *mut cuuint64_t, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCaptureInfo_ptsz( + hStream: CUstream, + captureStatus_out: *mut CUstreamCaptureStatus, + id_out: *mut cuuint64_t, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamGetCaptureInfo_v2( + hStream: CUstream, + captureStatus_out: *mut CUstreamCaptureStatus, + id_out: *mut cuuint64_t, + graph_out: *mut CUgraph, + dependencies_out: *mut *const CUgraphNode, + numDependencies_out: *mut usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphAddKernelNode( + phGraphNode: *mut CUgraphNode, + hGraph: CUgraph, + dependencies: *const CUgraphNode, + numDependencies: usize, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeGetParams( + hNode: CUgraphNode, + nodeParams: *mut CUDA_KERNEL_NODE_PARAMS_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphKernelNodeSetParams( + hNode: CUgraphNode, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecKernelNodeSetParams( + hGraphExec: CUgraphExec, + hNode: CUgraphNode, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS_v1, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphInstantiateWithParams( + phGraphExec: *mut CUgraphExec, + hGraph: CUgraph, + instantiateParams: *mut CUDA_GRAPH_INSTANTIATE_PARAMS, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphExecUpdate( + hGraphExec: CUgraphExec, + hGraph: CUgraph, + hErrorNode_out: *mut CUgraphNode, + updateResult_out: *mut CUgraphExecUpdateResult, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphUpload(hGraph: CUgraphExec, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuGraphLaunch(hGraph: CUgraphExec, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamCopyAttributes(dstStream: CUstream, srcStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuStreamGetAttribute( + hStream: CUstream, + attr: CUstreamAttrID, + value: *mut CUstreamAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamSetAttribute( + hStream: CUstream, + attr: CUstreamAttrID, + param: *const CUstreamAttrValue, + ) -> CUresult; +} +extern "C" { + pub fn cuIpcOpenMemHandle( + pdptr: *mut CUdeviceptr, + handle: CUipcMemHandle, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphInstantiate( + phGraphExec: *mut CUgraphExec, + hGraph: CUgraph, + phErrorNode: *mut CUgraphNode, + logBuffer: *mut ::std::os::raw::c_char, + bufferSize: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphInstantiate_v2( + phGraphExec: *mut CUgraphExec, + hGraph: CUgraph, + phErrorNode: *mut CUgraphNode, + logBuffer: *mut ::std::os::raw::c_char, + bufferSize: usize, + ) -> CUresult; +} +extern "C" { + pub fn cuMemMapArrayAsync( + mapInfoList: *mut CUarrayMapInfo, + count: ::std::os::raw::c_uint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuMemFreeAsync(dptr: CUdeviceptr, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemAllocAsync(dptr: *mut CUdeviceptr, bytesize: usize, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuMemAllocFromPoolAsync( + dptr: *mut CUdeviceptr, + bytesize: usize, + pool: CUmemoryPool, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuStreamUpdateCaptureDependencies( + hStream: CUstream, + dependencies: *mut CUgraphNode, + numDependencies: usize, + flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGetProcAddress( + symbol: *const ::std::os::raw::c_char, + pfn: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + ) -> CUresult; +} +pub type GLenum = ::std::os::raw::c_uint; +pub type GLuint = ::std::os::raw::c_uint; +pub type HGPUNV = *mut ::std::os::raw::c_void; +extern "C" { + pub fn cuGraphicsGLRegisterBuffer( + pCudaResource: *mut CUgraphicsResource, + buffer: GLuint, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuGraphicsGLRegisterImage( + pCudaResource: *mut CUgraphicsResource, + image: GLuint, + target: GLenum, + Flags: ::std::os::raw::c_uint, + ) -> CUresult; +} +extern "C" { + pub fn cuWGLGetDevice(pDevice: *mut CUdevice, hGpu: HGPUNV) -> CUresult; +} +impl CUGLDeviceList_enum { + pub const CU_GL_DEVICE_LIST_ALL: CUGLDeviceList_enum = CUGLDeviceList_enum(1); +} +impl CUGLDeviceList_enum { + pub const CU_GL_DEVICE_LIST_CURRENT_FRAME: CUGLDeviceList_enum = CUGLDeviceList_enum(2); +} +impl CUGLDeviceList_enum { + pub const CU_GL_DEVICE_LIST_NEXT_FRAME: CUGLDeviceList_enum = CUGLDeviceList_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUGLDeviceList_enum(pub ::std::os::raw::c_int); +pub use self::CUGLDeviceList_enum as CUGLDeviceList; +extern "C" { + pub fn cuGLGetDevices_v2( + pCudaDeviceCount: *mut ::std::os::raw::c_uint, + pCudaDevices: *mut CUdevice, + cudaDeviceCount: ::std::os::raw::c_uint, + deviceList: CUGLDeviceList, + ) -> CUresult; +} +extern "C" { + pub fn cuGLCtxCreate_v2( + pCtx: *mut CUcontext, + Flags: ::std::os::raw::c_uint, + device: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuGLInit() -> CUresult; +} +extern "C" { + pub fn cuGLRegisterBufferObject(buffer: GLuint) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObject_v2_ptds( + dptr: *mut CUdeviceptr, + size: *mut usize, + buffer: GLuint, + ) -> CUresult; +} +extern "C" { + pub fn cuGLUnmapBufferObject(buffer: GLuint) -> CUresult; +} +extern "C" { + pub fn cuGLUnregisterBufferObject(buffer: GLuint) -> CUresult; +} +extern "C" { + pub fn cuGLSetBufferObjectMapFlags(buffer: GLuint, Flags: ::std::os::raw::c_uint) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObjectAsync_v2_ptsz( + dptr: *mut CUdeviceptr, + size: *mut usize, + buffer: GLuint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuGLUnmapBufferObjectAsync(buffer: GLuint, hStream: CUstream) -> CUresult; +} +extern "C" { + pub fn cuGLGetDevices( + pCudaDeviceCount: *mut ::std::os::raw::c_uint, + pCudaDevices: *mut CUdevice, + cudaDeviceCount: ::std::os::raw::c_uint, + deviceList: CUGLDeviceList, + ) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObject_v2( + dptr: *mut CUdeviceptr, + size: *mut usize, + buffer: GLuint, + ) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObjectAsync_v2( + dptr: *mut CUdeviceptr, + size: *mut usize, + buffer: GLuint, + hStream: CUstream, + ) -> CUresult; +} +extern "C" { + pub fn cuGLCtxCreate( + pCtx: *mut CUcontext, + Flags: ::std::os::raw::c_uint, + device: CUdevice, + ) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObject( + dptr: *mut CUdeviceptr_v1, + size: *mut ::std::os::raw::c_uint, + buffer: GLuint, + ) -> CUresult; +} +extern "C" { + pub fn cuGLMapBufferObjectAsync( + dptr: *mut CUdeviceptr_v1, + size: *mut ::std::os::raw::c_uint, + buffer: GLuint, + hStream: CUstream, + ) -> CUresult; +} +impl CUoutput_mode_enum { + pub const CU_OUT_KEY_VALUE_PAIR: CUoutput_mode_enum = CUoutput_mode_enum(0); +} +impl CUoutput_mode_enum { + pub const CU_OUT_CSV: CUoutput_mode_enum = CUoutput_mode_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct CUoutput_mode_enum(pub ::std::os::raw::c_int); +pub use self::CUoutput_mode_enum as CUoutput_mode; +extern "C" { + pub fn cuProfilerInitialize( + configFile: *const ::std::os::raw::c_char, + outputFile: *const ::std::os::raw::c_char, + outputMode: CUoutput_mode, + ) -> CUresult; +} +extern "C" { + pub fn cuProfilerStart() -> CUresult; +} +extern "C" { + pub fn cuProfilerStop() -> CUresult; +} diff --git a/cuda_base/src/lib.rs b/cuda_base/src/lib.rs new file mode 100644 index 0000000..3fa7aeb --- /dev/null +++ b/cuda_base/src/lib.rs @@ -0,0 +1,556 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::{format_ident, quote, ToTokens}; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::collections::hash_map; +use std::iter; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::visit::Visit; +use syn::visit_mut::VisitMut; +use syn::{ + bracketed, parse_macro_input, Abi, Fields, File, FnArg, ForeignItem, ForeignItemFn, Ident, + Item, ItemEnum, ItemForeignMod, ItemStruct, ItemUnion, LitStr, PatType, Path, PathArguments, + PathSegment, ReturnType, Signature, Token, Type, TypeArray, TypePath, TypePtr, +}; + +const CUDA_RS: &'static str = include_str! {"cuda.rs"}; + +// This macro copies cuda.rs as-is with some changes: +// * All function declarations are filtered out +// * CUdeviceptr_v2 is redefined from `unsigned long long` to `*void` +// * `extern "C"` gets replaced by `extern "system"` +// * CUuuid_st is redefined to use uchar instead of char +// * Every type except anything graph-related is marked as Send and Sync +// TODO: Improve Send/Sync generation. Currently types that are defined as +// pointers (which is 99% of useful types) can't be marked as Send&Sync +// Their definition should be changed to newtype with a null() function +// and all code should be updated accordingly +#[proc_macro] +pub fn cuda_type_declarations(_: TokenStream) -> TokenStream { + let mut cuda_module = syn::parse_str::(CUDA_RS).unwrap(); + cuda_module.items = cuda_module + .items + .into_iter() + .filter_map(|item| match item { + Item::ForeignMod(_) => None, + Item::Struct(mut struct_) => { + if "CUdeviceptr_v2" == struct_.ident.to_string() { + match &mut struct_.fields { + Fields::Unnamed(ref mut fields) => { + fields.unnamed[0].ty = + absolute_path_to_mut_ptr(&["std", "os", "raw", "c_void"]) + } + _ => unreachable!(), + } + } else if "CUuuid_st" == struct_.ident.to_string() { + match &mut struct_.fields { + Fields::Named(ref mut fields) => match fields.named[0].ty { + Type::Array(TypeArray { ref mut elem, .. }) => { + *elem = Box::new(Type::Path(TypePath { + qself: None, + path: segments_to_path(&["std", "os", "raw", "c_uchar"]), + })) + } + _ => unreachable!(), + }, + _ => panic!(), + } + } + Some(Item::Struct(struct_)) + } + i => Some(i), + }) + .collect::>(); + mark_types_as_send_sync(&mut cuda_module); + syn::visit_mut::visit_file_mut(&mut FixAbi, &mut cuda_module); + cuda_module.into_token_stream().into() +} + +fn mark_types_as_send_sync(cuda_module: &mut File) { + let mut types_for_send_sync = CollectTypesForSendSync { types: Vec::new() }; + syn::visit::visit_file(&mut types_for_send_sync, &cuda_module); + for type_ in types_for_send_sync.types { + let send: Item = syn::parse_quote! { + unsafe impl Send for #type_ {} + }; + cuda_module.items.push(send); + let sync: Item = syn::parse_quote! { + unsafe impl Sync for #type_ {} + }; + cuda_module.items.push(sync); + } +} + +fn segments_to_path(path: &[&'static str]) -> Path { + let mut segments = Punctuated::new(); + for ident in path { + let ident = PathSegment { + ident: Ident::new(ident, Span::call_site()), + arguments: PathArguments::None, + }; + segments.push(ident); + } + Path { + leading_colon: Some(Token![::](Span::call_site())), + segments, + } +} + +fn absolute_path_to_mut_ptr(path: &[&'static str]) -> Type { + Type::Ptr(TypePtr { + star_token: Token![*](Span::call_site()), + const_token: None, + mutability: Some(Token![mut](Span::call_site())), + elem: Box::new(Type::Path(TypePath { + qself: None, + path: segments_to_path(path), + })), + }) +} + +struct FixAbi; + +impl VisitMut for FixAbi { + fn visit_abi_mut(&mut self, i: &mut Abi) { + if let Some(ref mut name) = i.name { + *name = LitStr::new("system", Span::call_site()); + } + } +} + +struct CollectTypesForSendSync { + types: Vec, +} + +impl CollectTypesForSendSync { + fn try_add(&mut self, ident: &Ident) { + let mut name = ident.to_string(); + name.make_ascii_lowercase(); + if name.contains("graph") { + return; + } + self.types.push(ident.clone()); + } +} + +impl<'ast> Visit<'ast> for CollectTypesForSendSync { + fn visit_item_struct(&mut self, item_struct: &'ast ItemStruct) { + self.try_add(&item_struct.ident); + } + + fn visit_item_union(&mut self, item_struct: &'ast ItemUnion) { + self.try_add(&item_struct.ident); + } + + fn visit_item_enum(&mut self, item_struct: &'ast ItemEnum) { + self.try_add(&item_struct.ident); + } +} + +// This macro accepts following arguments: +// * `type_path`: path to the module with type definitions (in the module tree) +// * `normal_macro`: ident for a normal macro +// * `override_macro`: ident for an override macro +// * `override_fns`: list of override functions +// Then macro goes through every function in rust.rs, and for every fn `foo`: +// * if `foo` is contained in `override_fns` then pass it into `override_macro` +// * if `foo` is not contained in `override_fns` pass it to `normal_macro` +// Both `override_macro` and `normal_macro` expect semicolon-separated list: +// macro_foo!( +// "system" fn cuCtxDetach(ctx: CUcontext) -> CUresult; +// "system" fn cuCtxDetach(ctx: CUcontext) -> CUresult +// ) +// Additionally, it does a fixup of CUDA types so they get prefixed with `type_path` +#[proc_macro] +pub fn cuda_function_declarations(tokens: TokenStream) -> TokenStream { + let input = parse_macro_input!(tokens as FnDeclInput); + let cuda_module = syn::parse_str::(CUDA_RS).unwrap(); + let override_fns = input + .override_fns + .iter() + .map(ToString::to_string) + .collect::>(); + let (normal_macro_args, override_macro_args): (Vec<_>, Vec<_>) = cuda_module + .items + .into_iter() + .filter_map(|item| match item { + Item::ForeignMod(ItemForeignMod { mut items, .. }) => match items.pop().unwrap() { + ForeignItem::Fn(ForeignItemFn { + sig: + Signature { + ident, + inputs, + output, + .. + }, + .. + }) => { + let use_normal_macro = !override_fns.contains(&ident.to_string()); + let inputs = inputs + .into_iter() + .map(|fn_arg| match fn_arg { + FnArg::Typed(mut pat_type) => { + pat_type.ty = + prepend_cuda_path_to_type(&input.type_path, pat_type.ty); + FnArg::Typed(pat_type) + } + _ => unreachable!(), + }) + .collect::>(); + let output = match output { + ReturnType::Type(_, type_) => type_, + ReturnType::Default => unreachable!(), + }; + let type_path = input.type_path.clone(); + Some(( + quote! { + "system" fn #ident(#inputs) -> #type_path :: #output + }, + use_normal_macro, + )) + } + _ => unreachable!(), + }, + _ => None, + }) + .partition(|(_, use_normal_macro)| *use_normal_macro); + let mut result = proc_macro2::TokenStream::new(); + if !normal_macro_args.is_empty() { + let punctuated_normal_macro_args = to_punctuated::(normal_macro_args); + let macro_ = &input.normal_macro; + result.extend(iter::once(quote! { + #macro_ ! (#punctuated_normal_macro_args); + })); + } + if !override_macro_args.is_empty() { + let punctuated_override_macro_args = to_punctuated::(override_macro_args); + let macro_ = &input.override_macro; + result.extend(iter::once(quote! { + #macro_ ! (#punctuated_override_macro_args); + })); + } + result.into() +} + +fn to_punctuated( + elms: Vec<(proc_macro2::TokenStream, bool)>, +) -> proc_macro2::TokenStream { + let mut collection = Punctuated::::new(); + collection.extend(elms.into_iter().map(|(token_stream, _)| token_stream)); + collection.into_token_stream() +} + +fn prepend_cuda_path_to_type(base_path: &Path, type_: Box) -> Box { + match *type_ { + Type::Path(mut type_path) => { + type_path.path = prepend_cuda_path_to_path(base_path, type_path.path); + Box::new(Type::Path(type_path)) + } + Type::Ptr(mut type_ptr) => { + type_ptr.elem = prepend_cuda_path_to_type(base_path, type_ptr.elem); + Box::new(Type::Ptr(type_ptr)) + } + _ => unreachable!(), + } +} + +fn prepend_cuda_path_to_path(base_path: &Path, path: Path) -> Path { + if path.leading_colon.is_some() { + return path; + } + if path.segments.len() == 1 { + let ident = path.segments[0].ident.to_string(); + if ident.starts_with("CU") + || ident.starts_with("cu") + || ident.starts_with("GL") + || ident == "HGPUNV" + { + let mut base_path = base_path.clone(); + base_path.segments.extend(path.segments); + return base_path; + } + } + path +} + +struct FnDeclInput { + type_path: Path, + normal_macro: Path, + override_macro: Path, + override_fns: Punctuated, +} + +impl Parse for FnDeclInput { + fn parse(input: ParseStream) -> syn::Result { + let type_path = input.parse::()?; + input.parse::()?; + let normal_macro = input.parse::()?; + input.parse::()?; + let override_macro = input.parse::()?; + input.parse::()?; + let override_fns_content; + bracketed!(override_fns_content in input); + let override_fns = override_fns_content.parse_terminated(Ident::parse)?; + Ok(Self { + type_path, + normal_macro, + override_macro, + override_fns, + }) + } +} + +// This trait accepts following parameters: +// * `type_path`: path to the module with type definitions (in the module tree) +// * `trait_`: name of the trait to be derived +// * `ignore_types`: bracketed list of types to ignore +// * `ignore_fns`: bracketed list of fns to ignore +#[proc_macro] +pub fn cuda_derive_display_trait(tokens: TokenStream) -> TokenStream { + let input = parse_macro_input!(tokens as DeriveDisplayInput); + let cuda_module = syn::parse_str::(CUDA_RS).unwrap(); + let mut derive_state = DeriveDisplayState::new(input); + cuda_module + .items + .into_iter() + .filter_map(|i| cuda_derive_display_trait_for_item(&mut derive_state, i)) + .collect::() + .into() +} + +fn cuda_derive_display_trait_for_item( + state: &mut DeriveDisplayState, + item: Item, +) -> Option { + let path_prefix = &state.type_path; + let path_prefix_iter = iter::repeat(&path_prefix); + let trait_ = &state.trait_; + let trait_iter = iter::repeat(&state.trait_); + match item { + Item::Const(_) => None, + Item::ForeignMod(ItemForeignMod { mut items, .. }) => match items.pop().unwrap() { + ForeignItem::Fn(ForeignItemFn { + sig: Signature { ident, inputs, .. }, + .. + }) => { + if state.ignore_fns.contains(&ident) { + return None; + } + let inputs = inputs + .into_iter() + .map(|fn_arg| match fn_arg { + FnArg::Typed(mut pat_type) => { + pat_type.ty = prepend_cuda_path_to_type(path_prefix, pat_type.ty); + FnArg::Typed(pat_type) + } + _ => unreachable!(), + }) + .collect::>(); + let inputs_iter = inputs.iter(); + let mut arg_name_iter = inputs.iter().map(|fn_arg| match fn_arg { + FnArg::Typed(PatType { pat, .. }) => pat, + _ => unreachable!(), + }); + let fn_name = format_ident!("write_{}", ident); + let original_fn_name = ident.to_string(); + Some(match arg_name_iter.next() { + Some(first_arg_name) => quote! { + pub fn #fn_name(writer: &mut (impl std::io::Write + ?Sized), #(#inputs_iter,)*) -> std::io::Result<()> { + writer.write_all(concat!("(", stringify!(#first_arg_name), ": ").as_bytes())?; + let mut arg_idx = 0usize; + CudaDisplay::write(&#first_arg_name, #original_fn_name, arg_idx, writer)?; + #( + writer.write_all(b", ")?; + writer.write_all(concat!(stringify!(#arg_name_iter), ": ").as_bytes())?; + CudaDisplay::write(&#arg_name_iter, #original_fn_name, arg_idx, writer)?; + arg_idx += 1; + )* + writer.write_all(b")") + } + }, + None => quote! { + pub fn #fn_name(writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + writer.write_all(b"()") + } + }, + }) + } + _ => unreachable!(), + }, + Item::Impl(mut item_impl) => { + let enum_ = match *(item_impl.self_ty) { + Type::Path(mut path) => path.path.segments.pop().unwrap().into_value().ident, + _ => unreachable!(), + }; + let variant_ = match item_impl.items.pop().unwrap() { + syn::ImplItem::Const(item_const) => item_const.ident, + _ => unreachable!(), + }; + state.record_enum_variant(enum_, variant_); + None + } + Item::Struct(item_struct) => { + let item_struct_name = item_struct.ident.to_string(); + if state.ignore_types.contains(&item_struct.ident) { + return None; + } + if item_struct_name.ends_with("_enum") { + let enum_ = &item_struct.ident; + let enum_iter = iter::repeat(&item_struct.ident); + let variants = state.enums.get(&item_struct.ident).unwrap().iter(); + Some(quote! { + impl #trait_ for #path_prefix :: #enum_ { + fn write(&self, _fn_name: &'static str, _index: usize, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + match self { + #(& #path_prefix_iter :: #enum_iter :: #variants => writer.write_all(stringify!(#variants).as_bytes()),)* + _ => write!(writer, "{}", self.0) + } + } + } + }) + } else { + let struct_ = &item_struct.ident; + let (first_field, rest_of_fields) = match item_struct.fields { + Fields::Named(fields) => { + let mut all_idents = fields.named.into_iter().filter_map(|f| { + let f_ident = f.ident.unwrap(); + let name = f_ident.to_string(); + if name.starts_with("reserved") || name == "_unused" { + None + } else { + Some(f_ident) + } + }); + let first = match all_idents.next() { + Some(f) => f, + None => return None, + }; + (first, all_idents) + } + _ => return None, + }; + Some(quote! { + impl #trait_ for #path_prefix :: #struct_ { + fn write(&self, _fn_name: &'static str, _index: usize, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + writer.write_all(concat!("{ ", stringify!(#first_field), ": ").as_bytes())?; + #trait_::write(&self.#first_field, "", 0, writer)?; + #( + writer.write_all(concat!(", ", stringify!(#rest_of_fields), ": ").as_bytes())?; + #trait_iter::write(&self.#rest_of_fields, "", 0, writer)?; + )* + writer.write_all(b" }") + } + } + }) + } + } + Item::Type(item_type) => { + if state.ignore_types.contains(&item_type.ident) { + return None; + }; + match *(item_type.ty) { + Type::Ptr(_) => { + let type_ = item_type.ident; + Some(quote! { + impl #trait_ for #path_prefix :: #type_ { + fn write(&self, _fn_name: &'static str, _index: usize, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + write!(writer, "{:p}", *self) + } + } + }) + } + Type::Path(type_path) => { + if type_path.path.leading_colon.is_some() { + let option_seg = type_path.path.segments.last().unwrap(); + if option_seg.ident == "Option" { + match &option_seg.arguments { + PathArguments::AngleBracketed(generic) => match generic.args[0] { + syn::GenericArgument::Type(Type::BareFn(_)) => { + let type_ = &item_type.ident; + return Some(quote! { + impl #trait_ for #path_prefix :: #type_ { + fn write(&self, _fn_name: &'static str, _index: usize, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + write!(writer, "{:p}", unsafe { std::mem::transmute::<#path_prefix :: #type_, *mut ::std::ffi::c_void>(*self) }) + } + } + }); + } + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + } + None + } + _ => unreachable!(), + } + } + Item::Union(_) => None, + Item::Use(_) => None, + _ => unreachable!(), + } +} + +struct DeriveDisplayState { + type_path: Path, + trait_: Path, + ignore_types: FxHashSet, + ignore_fns: FxHashSet, + enums: FxHashMap>, +} + +impl DeriveDisplayState { + fn new(input: DeriveDisplayInput) -> Self { + DeriveDisplayState { + type_path: input.type_path, + trait_: input.trait_, + ignore_types: input.ignore_types.into_iter().collect(), + ignore_fns: input.ignore_fns.into_iter().collect(), + enums: Default::default(), + } + } + + fn record_enum_variant(&mut self, enum_: Ident, variant: Ident) { + match self.enums.entry(enum_) { + hash_map::Entry::Occupied(mut entry) => { + entry.get_mut().push(variant); + } + hash_map::Entry::Vacant(entry) => { + entry.insert(vec![variant]); + } + } + } +} + +struct DeriveDisplayInput { + type_path: Path, + trait_: Path, + ignore_types: Punctuated, + ignore_fns: Punctuated, +} + +impl Parse for DeriveDisplayInput { + fn parse(input: ParseStream) -> syn::Result { + let type_path = input.parse::()?; + input.parse::()?; + let trait_ = input.parse::()?; + input.parse::()?; + let ignore_types_buffer; + bracketed!(ignore_types_buffer in input); + let ignore_types = ignore_types_buffer.parse_terminated(Ident::parse)?; + input.parse::()?; + let ignore_fns_buffer; + bracketed!(ignore_fns_buffer in input); + let ignore_fns = ignore_fns_buffer.parse_terminated(Ident::parse)?; + Ok(Self { + type_path, + trait_, + ignore_types, + ignore_fns, + }) + } +} diff --git a/cuda_types/Cargo.toml b/cuda_types/Cargo.toml new file mode 100644 index 0000000..e779830 --- /dev/null +++ b/cuda_types/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "cuda_types" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[dependencies] +cuda_base = { path = "../cuda_base" } diff --git a/cuda_types/src/lib.rs b/cuda_types/src/lib.rs new file mode 100644 index 0000000..96e2d34 --- /dev/null +++ b/cuda_types/src/lib.rs @@ -0,0 +1,12 @@ +use cuda_base::cuda_type_declarations; + +cuda_type_declarations!(); + +impl From for Result<(), CUresult> { + fn from(value: CUresult) -> Self { + match value { + CUresult::CUDA_SUCCESS => Ok(()), + err => Err(err), + } + } +} diff --git a/detours-sys/src/bundled_bindings.rs b/detours-sys/src/bundled_bindings.rs index 7262bc8..1ae9395 100644 --- a/detours-sys/src/bundled_bindings.rs +++ b/detours-sys/src/bundled_bindings.rs @@ -1,5 +1,5 @@ -/* automatically generated by rust-bindgen 0.56.0 */ - +/* automatically generated by rust-bindgen 0.56.0 */ + pub type wchar_t = ::std::os::raw::c_ushort; pub type ULONG = ::std::os::raw::c_ulong; pub type DWORD = ::std::os::raw::c_ulong; @@ -28,88 +28,12 @@ pub struct _GUID { pub Data3: ::std::os::raw::c_ushort, pub Data4: [::std::os::raw::c_uchar; 8usize], } -#[test] -fn bindgen_test_layout__GUID() { - assert_eq!( - ::std::mem::size_of::<_GUID>(), - 16usize, - concat!("Size of: ", stringify!(_GUID)) - ); - assert_eq!( - ::std::mem::align_of::<_GUID>(), - 4usize, - concat!("Alignment of ", stringify!(_GUID)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_GUID>())).Data1 as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_GUID), - "::", - stringify!(Data1) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_GUID>())).Data2 as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(_GUID), - "::", - stringify!(Data2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_GUID>())).Data3 as *const _ as usize }, - 6usize, - concat!( - "Offset of field: ", - stringify!(_GUID), - "::", - stringify!(Data3) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_GUID>())).Data4 as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_GUID), - "::", - stringify!(Data4) - ) - ); -} pub type GUID = _GUID; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct HINSTANCE__ { pub unused: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_HINSTANCE__() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(HINSTANCE__)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(HINSTANCE__)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).unused as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(HINSTANCE__), - "::", - stringify!(unused) - ) - ); -} pub type HINSTANCE = *mut HINSTANCE__; pub type HMODULE = HINSTANCE; #[repr(C)] @@ -117,29 +41,6 @@ pub type HMODULE = HINSTANCE; pub struct HWND__ { pub unused: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_HWND__() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(HWND__)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(HWND__)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).unused as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(HWND__), - "::", - stringify!(unused) - ) - ); -} pub type HWND = *mut HWND__; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -148,54 +49,6 @@ pub struct _SECURITY_ATTRIBUTES { pub lpSecurityDescriptor: LPVOID, pub bInheritHandle: BOOL, } -#[test] -fn bindgen_test_layout__SECURITY_ATTRIBUTES() { - assert_eq!( - ::std::mem::size_of::<_SECURITY_ATTRIBUTES>(), - 24usize, - concat!("Size of: ", stringify!(_SECURITY_ATTRIBUTES)) - ); - assert_eq!( - ::std::mem::align_of::<_SECURITY_ATTRIBUTES>(), - 8usize, - concat!("Alignment of ", stringify!(_SECURITY_ATTRIBUTES)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_SECURITY_ATTRIBUTES>())).nLength as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_SECURITY_ATTRIBUTES), - "::", - stringify!(nLength) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_SECURITY_ATTRIBUTES>())).lpSecurityDescriptor as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_SECURITY_ATTRIBUTES), - "::", - stringify!(lpSecurityDescriptor) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_SECURITY_ATTRIBUTES>())).bInheritHandle as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_SECURITY_ATTRIBUTES), - "::", - stringify!(bInheritHandle) - ) - ); -} pub type LPSECURITY_ATTRIBUTES = *mut _SECURITY_ATTRIBUTES; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -205,61 +58,6 @@ pub struct _PROCESS_INFORMATION { pub dwProcessId: DWORD, pub dwThreadId: DWORD, } -#[test] -fn bindgen_test_layout__PROCESS_INFORMATION() { - assert_eq!( - ::std::mem::size_of::<_PROCESS_INFORMATION>(), - 24usize, - concat!("Size of: ", stringify!(_PROCESS_INFORMATION)) - ); - assert_eq!( - ::std::mem::align_of::<_PROCESS_INFORMATION>(), - 8usize, - concat!("Alignment of ", stringify!(_PROCESS_INFORMATION)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_PROCESS_INFORMATION>())).hProcess as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_PROCESS_INFORMATION), - "::", - stringify!(hProcess) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_PROCESS_INFORMATION>())).hThread as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_PROCESS_INFORMATION), - "::", - stringify!(hThread) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_PROCESS_INFORMATION>())).dwProcessId as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_PROCESS_INFORMATION), - "::", - stringify!(dwProcessId) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_PROCESS_INFORMATION>())).dwThreadId as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(_PROCESS_INFORMATION), - "::", - stringify!(dwThreadId) - ) - ); -} pub type LPPROCESS_INFORMATION = *mut _PROCESS_INFORMATION; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -283,199 +81,6 @@ pub struct _STARTUPINFOA { pub hStdOutput: HANDLE, pub hStdError: HANDLE, } -#[test] -fn bindgen_test_layout__STARTUPINFOA() { - assert_eq!( - ::std::mem::size_of::<_STARTUPINFOA>(), - 104usize, - concat!("Size of: ", stringify!(_STARTUPINFOA)) - ); - assert_eq!( - ::std::mem::align_of::<_STARTUPINFOA>(), - 8usize, - concat!("Alignment of ", stringify!(_STARTUPINFOA)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).cb as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(cb) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).lpReserved as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(lpReserved) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).lpDesktop as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(lpDesktop) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).lpTitle as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(lpTitle) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwX as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwX) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwY as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwY) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwXSize as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwXSize) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwYSize as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwYSize) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwXCountChars as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwXCountChars) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwYCountChars as *const _ as usize }, - 52usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwYCountChars) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwFillAttribute as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwFillAttribute) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).dwFlags as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(dwFlags) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).wShowWindow as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(wShowWindow) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).cbReserved2 as *const _ as usize }, - 66usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(cbReserved2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).lpReserved2 as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(lpReserved2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).hStdInput as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(hStdInput) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).hStdOutput as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(hStdOutput) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOA>())).hStdError as *const _ as usize }, - 96usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOA), - "::", - stringify!(hStdError) - ) - ); -} pub type LPSTARTUPINFOA = *mut _STARTUPINFOA; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -499,199 +104,6 @@ pub struct _STARTUPINFOW { pub hStdOutput: HANDLE, pub hStdError: HANDLE, } -#[test] -fn bindgen_test_layout__STARTUPINFOW() { - assert_eq!( - ::std::mem::size_of::<_STARTUPINFOW>(), - 104usize, - concat!("Size of: ", stringify!(_STARTUPINFOW)) - ); - assert_eq!( - ::std::mem::align_of::<_STARTUPINFOW>(), - 8usize, - concat!("Alignment of ", stringify!(_STARTUPINFOW)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).cb as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(cb) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).lpReserved as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(lpReserved) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).lpDesktop as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(lpDesktop) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).lpTitle as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(lpTitle) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwX as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwX) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwY as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwY) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwXSize as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwXSize) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwYSize as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwYSize) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwXCountChars as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwXCountChars) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwYCountChars as *const _ as usize }, - 52usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwYCountChars) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwFillAttribute as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwFillAttribute) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).dwFlags as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(dwFlags) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).wShowWindow as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(wShowWindow) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).cbReserved2 as *const _ as usize }, - 66usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(cbReserved2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).lpReserved2 as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(lpReserved2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).hStdInput as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(hStdInput) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).hStdOutput as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(hStdOutput) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_STARTUPINFOW>())).hStdError as *const _ as usize }, - 96usize, - concat!( - "Offset of field: ", - stringify!(_STARTUPINFOW), - "::", - stringify!(hStdError) - ) - ); -} pub type LPSTARTUPINFOW = *mut _STARTUPINFOW; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -701,10 +113,10 @@ pub struct _DETOUR_TRAMPOLINE { pub type PDETOUR_TRAMPOLINE = *mut _DETOUR_TRAMPOLINE; #[doc = " Binary Typedefs."] pub type PF_DETOUR_BINARY_BYWAY_CALLBACK = ::std::option::Option< - unsafe extern "C" fn(pContext: PVOID, pszFile: LPCSTR, ppszOutFile: *mut LPCSTR) -> BOOL, + unsafe extern "stdcall" fn(pContext: PVOID, pszFile: LPCSTR, ppszOutFile: *mut LPCSTR) -> BOOL, >; pub type PF_DETOUR_BINARY_FILE_CALLBACK = ::std::option::Option< - unsafe extern "C" fn( + unsafe extern "stdcall" fn( pContext: PVOID, pszOrigFile: LPCSTR, pszFile: LPCSTR, @@ -712,7 +124,7 @@ pub type PF_DETOUR_BINARY_FILE_CALLBACK = ::std::option::Option< ) -> BOOL, >; pub type PF_DETOUR_BINARY_SYMBOL_CALLBACK = ::std::option::Option< - unsafe extern "C" fn( + unsafe extern "stdcall" fn( pContext: PVOID, nOrigOrdinal: ULONG, nOrdinal: ULONG, @@ -723,18 +135,18 @@ pub type PF_DETOUR_BINARY_SYMBOL_CALLBACK = ::std::option::Option< ) -> BOOL, >; pub type PF_DETOUR_BINARY_COMMIT_CALLBACK = - ::std::option::Option BOOL>; + ::std::option::Option BOOL>; pub type PF_DETOUR_ENUMERATE_EXPORT_CALLBACK = ::std::option::Option< - unsafe extern "C" fn(pContext: PVOID, nOrdinal: ULONG, pszName: LPCSTR, pCode: PVOID) -> BOOL, + unsafe extern "stdcall" fn(pContext: PVOID, nOrdinal: ULONG, pszName: LPCSTR, pCode: PVOID) -> BOOL, >; pub type PF_DETOUR_IMPORT_FILE_CALLBACK = ::std::option::Option< - unsafe extern "C" fn(pContext: PVOID, hModule: HMODULE, pszFile: LPCSTR) -> BOOL, + unsafe extern "stdcall" fn(pContext: PVOID, hModule: HMODULE, pszFile: LPCSTR) -> BOOL, >; pub type PF_DETOUR_IMPORT_FUNC_CALLBACK = ::std::option::Option< - unsafe extern "C" fn(pContext: PVOID, nOrdinal: DWORD, pszFunc: LPCSTR, pvFunc: PVOID) -> BOOL, + unsafe extern "stdcall" fn(pContext: PVOID, nOrdinal: DWORD, pszFunc: LPCSTR, pvFunc: PVOID) -> BOOL, >; pub type PF_DETOUR_IMPORT_FUNC_CALLBACK_EX = ::std::option::Option< - unsafe extern "C" fn( + unsafe extern "stdcall" fn( pContext: PVOID, nOrdinal: DWORD, pszFunc: LPCSTR, @@ -742,26 +154,26 @@ pub type PF_DETOUR_IMPORT_FUNC_CALLBACK_EX = ::std::option::Option< ) -> BOOL, >; pub type PDETOUR_BINARY = *mut ::std::os::raw::c_void; -extern "C" { +extern "stdcall" { #[doc = " Transaction APIs."] pub fn DetourTransactionBegin() -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourTransactionAbort() -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourTransactionCommit() -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourTransactionCommitEx(pppFailedPointer: *mut *mut PVOID) -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourUpdateThread(hThread: HANDLE) -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourAttach(ppPointer: *mut PVOID, pDetour: PVOID) -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourAttachEx( ppPointer: *mut PVOID, pDetour: PVOID, @@ -770,29 +182,29 @@ extern "C" { ppRealDetour: *mut PVOID, ) -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourDetach(ppPointer: *mut PVOID, pDetour: PVOID) -> LONG; } -extern "C" { +extern "stdcall" { pub fn DetourSetIgnoreTooSmall(fIgnore: BOOL) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourSetRetainRegions(fRetain: BOOL) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourSetSystemRegionLowerBound(pSystemRegionLowerBound: PVOID) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourSetSystemRegionUpperBound(pSystemRegionUpperBound: PVOID) -> PVOID; } -extern "C" { +extern "stdcall" { #[doc = " Code Functions."] pub fn DetourFindFunction(pszModule: LPCSTR, pszFunction: LPCSTR) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourCodeFromPointer(pPointer: PVOID, ppGlobals: *mut PVOID) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourCopyInstruction( pDst: PVOID, ppDstPool: *mut PVOID, @@ -801,36 +213,36 @@ extern "C" { plExtra: *mut LONG, ) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourSetCodeModule(hModule: HMODULE, fLimitReferencesToModule: BOOL) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourAllocateRegionWithinJumpBounds( pbTarget: LPCVOID, pcbAllocatedSize: PDWORD, ) -> PVOID; } -extern "C" { +extern "stdcall" { #[doc = " Loaded Binary Functions."] pub fn DetourGetContainingModule(pvAddr: PVOID) -> HMODULE; } -extern "C" { +extern "stdcall" { pub fn DetourEnumerateModules(hModuleLast: HMODULE) -> HMODULE; } -extern "C" { +extern "stdcall" { pub fn DetourGetEntryPoint(hModule: HMODULE) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourGetModuleSize(hModule: HMODULE) -> ULONG; } -extern "C" { +extern "stdcall" { pub fn DetourEnumerateExports( hModule: HMODULE, pContext: PVOID, pfExport: PF_DETOUR_ENUMERATE_EXPORT_CALLBACK, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourEnumerateImports( hModule: HMODULE, pContext: PVOID, @@ -838,7 +250,7 @@ extern "C" { pfImportFunc: PF_DETOUR_IMPORT_FUNC_CALLBACK, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourEnumerateImportsEx( hModule: HMODULE, pContext: PVOID, @@ -846,20 +258,20 @@ extern "C" { pfImportFuncEx: PF_DETOUR_IMPORT_FUNC_CALLBACK_EX, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourFindPayload(hModule: HMODULE, rguid: *const GUID, pcbData: *mut DWORD) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourFindPayloadEx(rguid: *const GUID, pcbData: *mut DWORD) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourGetSizeOfPayloads(hModule: HMODULE) -> DWORD; } -extern "C" { +extern "stdcall" { #[doc = " Persistent Binary Functions."] pub fn DetourBinaryOpen(hFile: HANDLE) -> PDETOUR_BINARY; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryEnumeratePayloads( pBinary: PDETOUR_BINARY, pGuid: *mut GUID, @@ -867,14 +279,14 @@ extern "C" { pnIterator: *mut DWORD, ) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryFindPayload( pBinary: PDETOUR_BINARY, rguid: *const GUID, pcbData: *mut DWORD, ) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourBinarySetPayload( pBinary: PDETOUR_BINARY, rguid: *const GUID, @@ -882,16 +294,16 @@ extern "C" { cbData: DWORD, ) -> PVOID; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryDeletePayload(pBinary: PDETOUR_BINARY, rguid: *const GUID) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryPurgePayloads(pBinary: PDETOUR_BINARY) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryResetImports(pBinary: PDETOUR_BINARY) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryEditImports( pBinary: PDETOUR_BINARY, pContext: PVOID, @@ -901,15 +313,15 @@ extern "C" { pfCommit: PF_DETOUR_BINARY_COMMIT_CALLBACK, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryWrite(pBinary: PDETOUR_BINARY, hFile: HANDLE) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourBinaryClose(pBinary: PDETOUR_BINARY) -> BOOL; } #[doc = " Create Process & Load Dll."] pub type PDETOUR_CREATE_PROCESS_ROUTINEA = ::std::option::Option< - unsafe extern "C" fn( + unsafe extern "stdcall" fn( lpApplicationName: LPCSTR, lpCommandLine: LPSTR, lpProcessAttributes: LPSECURITY_ATTRIBUTES, @@ -923,7 +335,7 @@ pub type PDETOUR_CREATE_PROCESS_ROUTINEA = ::std::option::Option< ) -> BOOL, >; pub type PDETOUR_CREATE_PROCESS_ROUTINEW = ::std::option::Option< - unsafe extern "C" fn( + unsafe extern "stdcall" fn( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, lpProcessAttributes: LPSECURITY_ATTRIBUTES, @@ -936,7 +348,7 @@ pub type PDETOUR_CREATE_PROCESS_ROUTINEW = ::std::option::Option< lpProcessInformation: LPPROCESS_INFORMATION, ) -> BOOL, >; -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllA( lpApplicationName: LPCSTR, lpCommandLine: LPSTR, @@ -952,7 +364,7 @@ extern "C" { pfCreateProcessA: PDETOUR_CREATE_PROCESS_ROUTINEA, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllW( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, @@ -968,7 +380,7 @@ extern "C" { pfCreateProcessW: PDETOUR_CREATE_PROCESS_ROUTINEW, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllExA( lpApplicationName: LPCSTR, lpCommandLine: LPSTR, @@ -984,7 +396,7 @@ extern "C" { pfCreateProcessA: PDETOUR_CREATE_PROCESS_ROUTINEA, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllExW( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, @@ -1000,7 +412,7 @@ extern "C" { pfCreateProcessW: PDETOUR_CREATE_PROCESS_ROUTINEW, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllsA( lpApplicationName: LPCSTR, lpCommandLine: LPSTR, @@ -1017,7 +429,7 @@ extern "C" { pfCreateProcessA: PDETOUR_CREATE_PROCESS_ROUTINEA, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCreateProcessWithDllsW( lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, @@ -1034,21 +446,21 @@ extern "C" { pfCreateProcessW: PDETOUR_CREATE_PROCESS_ROUTINEW, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourProcessViaHelperA( dwTargetPid: DWORD, lpDllName: LPCSTR, pfCreateProcessA: PDETOUR_CREATE_PROCESS_ROUTINEA, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourProcessViaHelperW( dwTargetPid: DWORD, lpDllName: LPCSTR, pfCreateProcessW: PDETOUR_CREATE_PROCESS_ROUTINEW, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourProcessViaHelperDllsA( dwTargetPid: DWORD, nDlls: DWORD, @@ -1056,7 +468,7 @@ extern "C" { pfCreateProcessA: PDETOUR_CREATE_PROCESS_ROUTINEA, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourProcessViaHelperDllsW( dwTargetPid: DWORD, nDlls: DWORD, @@ -1064,11 +476,11 @@ extern "C" { pfCreateProcessW: PDETOUR_CREATE_PROCESS_ROUTINEW, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourUpdateProcessWithDll(hProcess: HANDLE, rlpDlls: *mut LPCSTR, nDlls: DWORD) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourUpdateProcessWithDllEx( hProcess: HANDLE, hImage: HMODULE, @@ -1077,7 +489,7 @@ extern "C" { nDlls: DWORD, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourCopyPayloadToProcess( hProcess: HANDLE, rguid: *const GUID, @@ -1085,15 +497,15 @@ extern "C" { cbData: DWORD, ) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourRestoreAfterWith() -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourRestoreAfterWithEx(pvData: PVOID, cbData: DWORD) -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourIsHelperProcess() -> BOOL; } -extern "C" { +extern "stdcall" { pub fn DetourFinishHelperProcess(arg1: HWND, arg2: HINSTANCE, arg3: LPSTR, arg4: INT); } diff --git a/ext/llvm-project b/ext/llvm-project new file mode 160000 index 0000000..8dfdcc7 --- /dev/null +++ b/ext/llvm-project @@ -0,0 +1 @@ +Subproject commit 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a diff --git a/ext/llvm-sys.rs/.gitignore b/ext/llvm-sys.rs/.gitignore new file mode 100644 index 0000000..c6613a1 --- /dev/null +++ b/ext/llvm-sys.rs/.gitignore @@ -0,0 +1,3 @@ +# Generated by Cargo. +/target +Cargo.lock diff --git a/ext/llvm-sys.rs/.gitlab-ci.yml b/ext/llvm-sys.rs/.gitlab-ci.yml new file mode 100644 index 0000000..b5cb4ae --- /dev/null +++ b/ext/llvm-sys.rs/.gitlab-ci.yml @@ -0,0 +1,19 @@ +image: rust:buster + +variables: + LLVM_SYS_150_FFI_WORKAROUND: "YES" + +before_script: + - apt-get update -qq && apt-get install -qq -y lsb-release software-properties-common + - wget https://apt.llvm.org/llvm.sh + - chmod +x llvm.sh + - ./llvm.sh 15 + - apt-get install libpolly-15-dev + +test: + script: + - cargo build + - cargo test + - cargo run --example nop-function + - cargo run --example jit-function + - echo "Hello, world!" | cargo run --example disassembler diff --git a/ext/llvm-sys.rs/Cargo.toml b/ext/llvm-sys.rs/Cargo.toml new file mode 100644 index 0000000..72e84fe --- /dev/null +++ b/ext/llvm-sys.rs/Cargo.toml @@ -0,0 +1,21 @@ +[package] +description = "Bindings to LLVM's C API" +repository = "https://gitlab.com/taricorp/llvm-sys.rs" +readme = "README.md" +license = "MIT" +keywords = ["bindings", "llvm"] +categories = ["external-ffi-bindings"] +links = "llvm-15" +name = "llvm-sys" +version = "150.1.2" +authors = [ + "Peter Marheine ", +] +build = "build.rs" + +[dependencies] +libc = "0.2" + +[build-dependencies] +cmake = "0.1" +convert_case = "0.5" diff --git a/ext/llvm-sys.rs/LICENSE b/ext/llvm-sys.rs/LICENSE new file mode 100644 index 0000000..91b97a6 --- /dev/null +++ b/ext/llvm-sys.rs/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Peter Marheine + +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/ext/llvm-sys.rs/README.md b/ext/llvm-sys.rs/README.md new file mode 100644 index 0000000..70e53d0 --- /dev/null +++ b/ext/llvm-sys.rs/README.md @@ -0,0 +1,188 @@ +Rust bindings to LLVM's C API. + +# Usage + +```toml +[dependencies] +llvm-sys = "150" +``` + +There must be a compatible version of LLVM available. By default `llvm-sys` +will look for `llvm-config` on `PATH` to find a system-wide copy of LLVM and +use that if it is a compatible version. Custom options for finding LLVM +on your system can be specified via environment variables. See +[LLVM compatibility](#llvm-compatibility) for more information. + +## Documentation + +See the `examples` directory in this repository for API examples. There also +exist some other projects using these bindings which may be +informative or useful: + + * Safe, "Rusty" APIs for using LLVM: + * [Inkwell](https://github.com/TheDan64/inkwell) + * [llvm-ir](https://github.com/cdisselkoen/llvm-ir) + * [Tari's merthc](https://bitbucket.org/tari/merthc) + * [Wilfred's BF compiler](https://crates.io/crates/bfc) + * Jay Phelps wrote about [building a minimal compiler targeting + WebAssembly](https://medium.com/@jayphelps/93e8c193fdb4) + +Most of the interfaces are not documented in these bindings. Refer to the +[LLVM documentation](http://llvm.org/docs/) for more information, particularly +the [generated API documentation](http://llvm.org/doxygen/). + +If you have your own project using these bindings that you think is worth +mentioning here, by all means let me know. + +## LLVM compatibility + +Because the LLVM C [API stability guarantees][c-api-stability] are relatively +weak, this crate enforces that the LLVM release in use match the one it was made +for. The crate version is constructed by treating the LLVM version as a real +number and multiplying by 10, ignoring any fractional part. Thus `llvm-sys` +version 37 is compatible with LLVM 3.7.x, and `llvm-sys` 41 would be compatible +with LLVM 4.1.x. + +[c-api-stability]: http://llvm.org/docs/DeveloperPolicy.html#c-api-changes + +The build scripts will not enforce this compatibility matrix strictly, +permitting compilation against any version of LLVM that is at least as new as +the crate target version. This is safe in most cases because the LLVM C API is +meant to maintain binary compatibility across releases with the exception of +when functions are deprecated and later removed. An incompatible LLVM version +will generally fail to compile with a link-time error, rather than cause runtime +errors. Where versions are known to break binary compatibility, the build script +will prevent compilation. + +Depending on your use of the C API, your program may require that only a +version of LLVM exactly matching your crate version be allowed. This can be set +with the cargo feature flag `strict-versioning` or by setting the environment +variable `LLVM_SYS__STRICT_VERSIONING` (where `` is the target +crate version) to any value. + +llvm-sys blocklists some versions of LLVM that are known to be +binary-incompatible. If you're feeling lucky, setting +`LLVM_SYS__IGNORE_BLOCKLIST` to "YES" will permit the use of +blocklisted library versions (which may cause vexing bugs). + +--- + +This crate declares that it links to `llvm-`, not just `llvm`. +This makes it possible to declare a crate that depends on multiple +versions of `llvm-sys` (corresponding to different versions of LLVM) as long as +only one of them is actually used: + +```toml +llvm-sys-90 = { package = "llvm-sys", version = "90", optional = true } +llvm-sys-100 = { package = "llvm-sys", version = "100", optional = true } +``` + +This requires that the target LLVM version (`llvm-10` for instance) be declared +as the linking target rather than just `llvm` because Cargo requires that all +linked libraries be unique regardless of what is actually enabled. Note that +although Cargo will not prevent you from enabling multiple versions of LLVM at +once as a result, doing so will likely cause errors at link time. + +--- + +It may be difficult or even impossible to provide a compatible LLVM version +system-wide for a given project (consider a program using two libraries that +internally use different versions of LLVM!) so environment variables can be set +to help the build scripts find your copy of the libraries. This is also helpful +if you are unable to provide a system-wide version of LLVM but can still +compile it yourself. + +`LLVM_SYS__PREFIX` specifies the install prefix for a compiled and +installed copy of the libraries, where `` is the major version of +`llvm-sys` (for example, `LLVM_SYS_37_PREFIX`). For information on compiling +a copy of LLVM yourself, see [Compiling LLVM](#compiling-llvm). + +In the future this library may offer the ability to download and compile LLVM +automatically, but such a feature should only be considered for building +one-off releases because its high cost is ill-suited to repeated builds. + +## Compiling LLVM + +If you need to compile LLVM or manage multiple versions, +[llvmenv](https://crates.io/crates/llvmenv) may simplify the process. Consider +using it if you don't have special requirements or previous experience with +LLVM! + +While the [getting started guide](http://llvm.org/docs/GettingStarted.html) is +the official guide to compiling LLVM, this section will attempt to provide +minimum guidance in creating usable libraries. If you encounter problems, refer +to the official documentation. + +### Download sources + +Download and unpack a copy of the source for the required version. + +```sh +wget https://llvm.org/releases/3.9.0/llvm-3.9.0.src.tar.xz +tar xJf llvm-3.9.0.src.tar.xz +``` + +Note that you do not need to compile Clang or the test suite. + +### Configure + +Configure the build using [CMake][cmake] (you will need a copy of CMake +installed). + +[cmake]: https://cmake.org/ + +```sh +mkdir -p llvm-3.9.0.src/build +cd llvm-3.9.0.src/build +cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/llvm-3.9.0 +``` + +Some of the useful options that can be specified at configuration-time +(via `-D` passed to CMake): + + * `CMAKE_INSTALL_PREFIX` sets the location to install everything in the install + step (later). In the above example this is under your home directory. + * `CMAKE_BUILD_TYPE` specifies the build mode, one of Debug, Release, + MinSizeRel or RelWithDebInfo. Unless you plan to debug LLVM itself, + Release or MinSizeRel is probably a good choice. + * `LLVM_ENABLE_ASSERTIONS` enables internal sanity checks, highly recommended + when writing and debugging your own program that uses LLVM because it can + detect many usage errors that could otherwise result in hard-to-debug + crashes. + +Passing `-G ` to CMake will make it use a different build system, but +by default it will select one appropriate to your system. If you have +[ninja][ninja] available, it is recommended due to its speed (`-G Ninja`). + +[ninja]: https://ninja-build.org/ + +### Compile and install + +```sh +cmake --build . --target install +``` + +This will automatically invoke the build system and copy binaries into the +prefix specified at configuration-time when done. Then you can compile llvm-sys +against it. + +```sh +cd your/crate/path +LLVM_SYS_39_PREFIX=$HOME/llvm-3.9.0 cargo build +``` + +Some build tools (like Visual Studio on Windows) support all configurations +concurrently so you also need to specify the build type (which defaults to Debug +on Windows), adding an option like `--config MinSizeRel` to this invocation of +cmake. + +## Windows + +You must use a version of Rust that uses the same compiler as you build LLVM +with, either MSVC or MinGW. Fortunately, a mismatch like this will cause errors +at compile-time when llvm-config provides options which are supported by only +one of them, so if you're using the other it will cause the build to fail. + +## Cross-compilation + +Will theoretically work, but hasn't been tested. Let us know if you try. diff --git a/ext/llvm-sys.rs/appveyor.yml b/ext/llvm-sys.rs/appveyor.yml new file mode 100644 index 0000000..db5e257 --- /dev/null +++ b/ext/llvm-sys.rs/appveyor.yml @@ -0,0 +1,20 @@ +version: 1.0.{build} + +image: macos +install: + - sh: >- + brew install llvm + - sh: >- + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup.sh && sh rustup.sh -y +build: off +test_script: + - sh: | + export PATH=/usr/local/bin:$PATH + source ~/.cargo/env + export LLVM_SYS_110_PREFIX=/usr/local/opt/llvm + export LLVM_CONFIG_PATH=${LLVM_SYS_110_PREFIX}/bin/llvm-config + + cargo test + cargo run --example nop-function + cargo run --example jit-function + echo "Hello, world!" | cargo run --example disassembler diff --git a/ext/llvm-sys.rs/build.cmake b/ext/llvm-sys.rs/build.cmake new file mode 100644 index 0000000..da09740 --- /dev/null +++ b/ext/llvm-sys.rs/build.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0091 NEW) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") diff --git a/ext/llvm-sys.rs/build.rs b/ext/llvm-sys.rs/build.rs new file mode 100644 index 0000000..a7363a9 --- /dev/null +++ b/ext/llvm-sys.rs/build.rs @@ -0,0 +1,140 @@ +extern crate cmake; +extern crate convert_case; + +use convert_case::{Case, Casing, StateConverter}; +use std::{ + env, + path::PathBuf, + process::{Command, Stdio}, +}; + +use cmake::Config; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + let llvm_components = ["core", "analysis", "bit_reader", "bit_writer", "i_r_reader"] + .iter() + .map(|comp| comp.from_case(Case::Snake)); + let msvc = is_msvc(); + let (llvm_dir, additonal_cmake_file) = get_llvm_dir(); + let out_dir = build_cmake_targets(llvm_components.clone(), llvm_dir, additonal_cmake_file); + emit_compile_and_linking_information(llvm_components, out_dir, msvc) +} + +fn is_msvc() -> bool { + env::var("CARGO_CFG_TARGET_ENV").unwrap() == "msvc" +} + +fn get_llvm_dir() -> (PathBuf, PathBuf) { + let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let mut additional_cmake_file = manifest_dir.clone(); + additional_cmake_file.push("build.cmake"); + let mut llvm_dir = manifest_dir.parent().unwrap().to_path_buf(); + llvm_dir.push("llvm-project"); + llvm_dir.push("llvm"); + println!("cargo:rerun-if-changed={}", llvm_dir.display()); + println!("cargo:rerun-if-changed={}", additional_cmake_file.display()); + (llvm_dir, additional_cmake_file) +} + +fn build_cmake_targets<'a>( + components: impl Iterator>, + llvm_dir: PathBuf, + additional_cmake_file: PathBuf, +) -> PathBuf { + let mut cmake = Config::new(llvm_dir); + use_ninja(&mut cmake); + cmake + .always_configure(true) + .define("LLVM_ENABLE_TERMINFO", "OFF") + .define("LLVM_BUILD_TOOLS", "OFF") + .define("LLVM_TARGETS_TO_BUILD", "") + .define("LLVM_ENABLE_PROJECTS", "") + .define("CMAKE_PROJECT_INCLUDE_BEFORE", additional_cmake_file); + // Unfortunately CMake crate does not support building mutliple targets at once + for component in components { + cmake + .build_target(&format!("LLVM{}", component.to_case(Case::Pascal))) + .build(); + } + cmake.build_target("llvm-config").build() +} + +fn use_ninja(cmake: &mut Config) { + if let Ok(exit_status) = Command::new("ninja") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .arg("--version") + .status() + { + if !exit_status.success() { + return; + } + cmake.generator("Ninja"); + } +} + +fn emit_compile_and_linking_information<'a>( + llvm_components: impl Iterator>, + out_dir: PathBuf, + is_msvc: bool, +) { + let mut llvm_config_path = out_dir.clone(); + llvm_config_path.push("build"); + llvm_config_path.push("bin"); + llvm_config_path.push("llvm-config"); + let mut llvm_config_cmd = Command::new(&llvm_config_path); + llvm_config_cmd.args([ + "--cxxflags", + "--ldflags", + "--libdir", + "--libnames", + "--system-libs", + "--link-static", + ]); + for component in llvm_components { + llvm_config_cmd.arg(&component.to_case(Case::Flat)); + } + let llvm_config_output = llvm_config_cmd + .stdin(Stdio::null()) + .stderr(Stdio::null()) + .output() + .unwrap(); + if !llvm_config_output.status.success() { + panic!() + } + let output = String::from_utf8_lossy(&llvm_config_output.stdout); + let lines = (&output).lines().collect::>(); + let (cxxflags, ldflags, libdir, libnames, system_libs) = match &*lines { + [cxxflags, ldflags, libdir, libnames, system_libs, ..] => { + (cxxflags, ldflags, libdir, libnames, system_libs) + } + _ => panic!(), + }; + println!("cargo:cxxflags={}", cxxflags); + println!("cargo:rustc-link-arg={}", ldflags); + println!("cargo:rustc-link-search={}", libdir); + for lib in libnames.split_ascii_whitespace() { + let lib = if is_msvc { + // For some reason rustc appends .lib twice on msvc + &lib[..lib.len() - 4] + } else { + // On Linux, we get "libLLVMIRReader.a", so we cut "lib" and ".a" + &lib[3..lib.len() - 2] + }; + println!("cargo:rustc-link-lib=static={}", lib); + } + for lib in system_libs.split_ascii_whitespace() { + let lib = if is_msvc { + &lib[..lib.len() - 4] + } else { + // On Linux, we get it as "-lxml2", so we cut "-l" part + &lib[2..] + }; + println!("cargo:rustc-link-lib={}", lib); + } + if !is_msvc { + println!("cargo:rustc-link-lib=stdc++"); + } +} diff --git a/ext/llvm-sys.rs/scripts/RELEASE_CHECKLIST.md b/ext/llvm-sys.rs/scripts/RELEASE_CHECKLIST.md new file mode 100644 index 0000000..57ed876 --- /dev/null +++ b/ext/llvm-sys.rs/scripts/RELEASE_CHECKLIST.md @@ -0,0 +1,24 @@ +For new LLVM major versions: + + * [ ] Diff llvm/include/llvm-c/ between previous and current release. + This requires a local repo that's in sync with the remote, and tags + will be needed. A bare repository is fine, however. + + ``` + git clone --mirror https://github.com/llvm/llvm-project.git + git diff llvmorg-9.0.0 llvmorg-10.0.0 -- llvm/include/llvm-c/ + ``` + + Apply matching changes to Rust bindings. + * [ ] Update `links` key in Cargo.toml for new LLVM version + * [ ] Update usage example in README.md for new crate version + * [ ] Update CI to refer to new version + +For all versions: + + * [ ] Update `version` key in Cargo.toml for new crate version + * [ ] Commit changes + * [ ] Tag new version; `git tag v100.1.0` + * [ ] Update latest branch to follow master: `git branch -f llvm-10.0 master` + * [ ] Test and publish + * [ ] Push changes and tags; `git push --all && git push --tags` diff --git a/ext/llvm-sys.rs/scripts/build-binaries.sh b/ext/llvm-sys.rs/scripts/build-binaries.sh new file mode 100644 index 0000000..b1c95d3 --- /dev/null +++ b/ext/llvm-sys.rs/scripts/build-binaries.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e + +if [ $? -lt 1 ] +then + echo "Usage: $0 " >&2 + echo "Example: $0 3.9.1" >&2 + exit 1 +fi + +VERSION=$1 + +# Dependencies (for Ubuntu): +# * wget +# * xz-utils +# * ninja-build +# * cmake +# * build-essential +# * python + +wget http://releases.llvm.org/$VERSION/llvm-$VERSION.src.tar.xz +tar xJf llvm-$VERSION.src.tar.xz +mkdir build llvm-$VERSION +cd build +cmake -G Ninja ../llvm-$VERSION.src -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE=MinSizeRel -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-$VERSION -DCMAKE_INSTALL_UTILS +cmake --build . --target install +cd .. +tar cJf llvm-$VERSION.linux.tar.xz /usr/local/llvm-$VERSION + +# Additional flags for MSVC +# (CXX) /GL /Gy /Gw +# (link) /LTCG /OPT:REF,ICF diff --git a/ext/llvm-sys.rs/src/analysis.rs b/ext/llvm-sys.rs/src/analysis.rs new file mode 100644 index 0000000..3284fe3 --- /dev/null +++ b/ext/llvm-sys.rs/src/analysis.rs @@ -0,0 +1,35 @@ +//! Various analyses of the LLVM IR. + +use super::prelude::*; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMVerifierFailureAction { + /// Print to stderr and abort the process. + LLVMAbortProcessAction = 0, + /// Print to stderr and return 1. + LLVMPrintMessageAction = 1, + /// Return 1 and print nothing. + LLVMReturnStatusAction = 2, +} + +extern "C" { + /// Verify that a module is valid, taking the specified action if not. + /// + /// Optionally returns a human-readable description of any invalid constructs, + /// which must be disposed with `LLVMDisposeMessage`. + pub fn LLVMVerifyModule( + M: LLVMModuleRef, + Action: LLVMVerifierFailureAction, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + /// Verify that a single function is valid, taking the specified action. + /// + /// Useful for debugging. + pub fn LLVMVerifyFunction(Fn: LLVMValueRef, Action: LLVMVerifierFailureAction) -> LLVMBool; + /// Open a ghostview window displaying the CFG of the given function. + /// + /// Useful for debugging. + pub fn LLVMViewFunctionCFG(Fn: LLVMValueRef); + pub fn LLVMViewFunctionCFGOnly(Fn: LLVMValueRef); +} diff --git a/ext/llvm-sys.rs/src/bit_reader.rs b/ext/llvm-sys.rs/src/bit_reader.rs new file mode 100644 index 0000000..5ca7f45 --- /dev/null +++ b/ext/llvm-sys.rs/src/bit_reader.rs @@ -0,0 +1,70 @@ +//! Input of the LLVM bitcode format. + +use super::prelude::*; + +extern "C" { + ///// Build a module from the bitcode in the specified memory buffer. + ///// + ///// Returns 0 on success and the generated module in `OutModule`. + ///// Optionally returns a human-readable error message in `OutMessage`. + //#[deprecated(since = "3.8", note = "Use LLVMParseBitcode2")] + //pub fn LLVMParseBitcode( + // MemBuf: LLVMMemoryBufferRef, + // OutModule: *mut LLVMModuleRef, + // OutMessage: *mut *mut ::libc::c_char, + //) -> LLVMBool; + ///// Build a module from the bitcode in the specified memory buffer. + ///// + ///// Returns the created module in OutModule, returns 0 on success. + //pub fn LLVMParseBitcode2( + // MemBuf: LLVMMemoryBufferRef, + // OutModule: *mut LLVMModuleRef, + //) -> LLVMBool; + + #[deprecated(since = "3.8", note = "Use LLVMParseBitcodeInContext2")] + pub fn LLVMParseBitcodeInContext( + ContextRef: LLVMContextRef, + MemBuf: LLVMMemoryBufferRef, + OutModule: *mut LLVMModuleRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMParseBitcodeInContext2( + ContextRef: LLVMContextRef, + MemBuf: LLVMMemoryBufferRef, + OutModule: *mut LLVMModuleRef, + ) -> LLVMBool; + + /// Read a module from the specified path, returning a module provider + /// performing lazy deserialization. + /// + /// Returns 0 on success and an optional error message. + #[deprecated(since = "3.8", note = "Use LLVMGetBitcodeModuleInContext2")] + pub fn LLVMGetBitcodeModuleInContext( + ContextRef: LLVMContextRef, + MemBuf: LLVMMemoryBufferRef, + OutM: *mut LLVMModuleRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + /// Read a module from the specified path, returning a module provider + /// performing lazy deserialization. + /// + /// Returns 0 on success. + pub fn LLVMGetBitcodeModuleInContext2( + ContextRef: LLVMContextRef, + MemBuf: LLVMMemoryBufferRef, + OutM: *mut LLVMModuleRef, + ) -> LLVMBool; + + #[deprecated(since = "3.8", note = "Use LLVMGetBitcodeModule2")] + pub fn LLVMGetBitcodeModule( + MemBuf: LLVMMemoryBufferRef, + OutM: *mut LLVMModuleRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + /// Read a module from the specified path. + /// + /// Outputs a module provider which performs lazy deserialization. + /// Returns 0 on success. + pub fn LLVMGetBitcodeModule2(MemBuf: LLVMMemoryBufferRef, OutM: *mut LLVMModuleRef) + -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/bit_writer.rs b/ext/llvm-sys.rs/src/bit_writer.rs new file mode 100644 index 0000000..cd4d794 --- /dev/null +++ b/ext/llvm-sys.rs/src/bit_writer.rs @@ -0,0 +1,23 @@ +//! Output of the LLVM bitcode format. + +use super::prelude::*; + +extern "C" { + /// Write a module to the specified path. + /// + /// Returns 0 on success. + pub fn LLVMWriteBitcodeToFile(M: LLVMModuleRef, Path: *const ::libc::c_char) -> ::libc::c_int; + /// Write a module to an open file descriptor. + /// + /// Returns 0 on success. + pub fn LLVMWriteBitcodeToFD( + M: LLVMModuleRef, + FD: ::libc::c_int, + ShouldClose: ::libc::c_int, + Unbuffered: ::libc::c_int, + ) -> ::libc::c_int; + /// Deprecated: use LLVMWriteBitcodeToFD + pub fn LLVMWriteBitcodeToFileHandle(M: LLVMModuleRef, Handle: ::libc::c_int) -> ::libc::c_int; + /// Writes a module to a new memory buffer. + pub fn LLVMWriteBitcodeToMemoryBuffer(M: LLVMModuleRef) -> LLVMMemoryBufferRef; +} diff --git a/ext/llvm-sys.rs/src/blake3.rs b/ext/llvm-sys.rs/src/blake3.rs new file mode 100644 index 0000000..dfa86d1 --- /dev/null +++ b/ext/llvm-sys.rs/src/blake3.rs @@ -0,0 +1,66 @@ +//! LLVM's BLAKE3 implementation. +//! Original BLAKE3 C API: + +pub const LLVM_BLAKE3_VERSION_STRING: &str = "1.3.1"; +pub const LLVM_BLAKE3_KEY_LEN: usize = 32; +pub const LLVM_BLAKE3_OUT_LEN: usize = 32; +pub const LLVM_BLAKE3_BLOCK_LEN: usize = 64; +pub const LLVM_BLAKE3_CHUNK_LEN: usize = 1024; +pub const LLVM_BLAKE3_MAX_DEPTH: usize = 54; + +/// This struct is a private implementation detail. It has to be here because +/// it's part of llvm_blake3_hasher below. +#[repr(C)] +struct llvm_blake3_chunk_state { + cv: [u32; 8], + chunk_counter: u64, + buf: [u8; LLVM_BLAKE3_BLOCK_LEN], + buf_len: u8, + blocks_compressed: u8, + flags: u8, +} + +#[repr(C)] +pub struct llvm_blake3_hasher { + key: [u32; 8], + chunk: llvm_blake3_chunk_state, + cv_stack_len: u8, + /// The stack size is MAX_DEPTH + 1 because we do lazy merging. For example, + /// with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk + /// requires a 4th entry, rather than merging everything down to 1, because we + /// don't know whether more input is coming. This is different from how the + /// reference implementation does things. + cv_stack: [u8; (LLVM_BLAKE3_MAX_DEPTH + 1) * LLVM_BLAKE3_OUT_LEN], +} + +extern "C" { + pub fn llvm_blake3_version() -> *const ::libc::c_char; + pub fn llvm_blake3_hasher_init(hasher: *mut llvm_blake3_hasher); + pub fn llvm_blake3_hasher_init_keyed(hasher: *mut llvm_blake3_hasher, key: *const u8); + pub fn llvm_blake3_hasher_init_derive_key( + hasher: *mut llvm_blake3_hasher, + context: *const ::libc::c_char, + ); + pub fn llvm_blake3_hasher_init_derive_key_raw( + hasher: *mut llvm_blake3_hasher, + context: *const ::libc::c_char, + context_len: usize, + ); + pub fn llvm_blake3_hasher_update( + hasher: *mut llvm_blake3_hasher, + input: *const ::libc::c_void, + input_len: usize, + ); + pub fn llvm_blake3_hasher_finalize( + hasher: *mut llvm_blake3_hasher, + out: *mut u8, + out_len: usize, + ); + pub fn llvm_blake3_hasher_finalize_seek( + hasher: *mut llvm_blake3_hasher, + seek: u64, + out: *mut u8, + out_len: usize, + ); + pub fn llvm_blake3_hasher_reset(hasher: *mut llvm_blake3_hasher); +} diff --git a/ext/llvm-sys.rs/src/comdat.rs b/ext/llvm-sys.rs/src/comdat.rs new file mode 100644 index 0000000..31a4b15 --- /dev/null +++ b/ext/llvm-sys.rs/src/comdat.rs @@ -0,0 +1,34 @@ +//! COMDAT +use super::*; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMComdatSelectionKind { + /// The linker may choose any COMDAT. + LLVMAnyComdatSelectionKind, + /// The data referenced by the COMDAT must be the same. + LLVMExactMatchComdatSelectionKind, + /// The linker will choose the largest COMDAT. + LLVMLargestComdatSelectionKind, + /// No deduplication is performed. + LLVMNoDuplicatesComdatSelectionKind, + /// The data referenced by the COMDAT must be the same size. + LLVMSameSizeComdatSelectionKind, +} + +extern "C" { + /// Return the Comdat in the module with the specified name. It is created if it didn't already exist. + pub fn LLVMGetOrInsertComdat(M: LLVMModuleRef, Name: *const ::libc::c_char) -> LLVMComdatRef; + + /// Get the Comdat assigned to the given global object. + pub fn LLVMGetComdat(V: LLVMValueRef) -> LLVMComdatRef; + + /// Assign the Comdat to the given global object. + pub fn LLVMSetComdat(V: LLVMValueRef, C: LLVMComdatRef); + + /// Get the conflict resolution selection kind for the Comdat. + pub fn LLVMGetComdatSelectionKind(C: LLVMComdatRef) -> LLVMComdatSelectionKind; + + /// Set the conflict resolution selection kind for the Comdat. + pub fn LLVMSetComdatSelectionKind(C: LLVMComdatRef, Kind: LLVMComdatSelectionKind); +} diff --git a/ext/llvm-sys.rs/src/core.rs b/ext/llvm-sys.rs/src/core.rs new file mode 100644 index 0000000..f1523f0 --- /dev/null +++ b/ext/llvm-sys.rs/src/core.rs @@ -0,0 +1,2095 @@ +//! The LLVM intermediate representation. + +use super::*; + +// Core +extern "C" { + pub fn LLVMShutdown(); + pub fn LLVMCreateMessage(Message: *const ::libc::c_char) -> *mut ::libc::c_char; + pub fn LLVMDisposeMessage(Message: *mut ::libc::c_char); +} + +// Core->Contexts +extern "C" { + pub fn LLVMContextCreate() -> LLVMContextRef; + //pub fn LLVMGetGlobalContext() -> LLVMContextRef; + pub fn LLVMContextSetDiagnosticHandler( + C: LLVMContextRef, + Handler: LLVMDiagnosticHandler, + DiagnosticContext: *mut ::libc::c_void, + ); + /// Get the diagnostic handler of this context. + pub fn LLVMContextGetDiagnosticHandler(C: LLVMContextRef) -> LLVMDiagnosticHandler; + /// Get the diagnostic context of this context. + pub fn LLVMContextGetDiagnosticContext(C: LLVMContextRef) -> *mut ::libc::c_void; + pub fn LLVMContextSetYieldCallback( + C: LLVMContextRef, + Callback: LLVMYieldCallback, + OpaqueHandle: *mut ::libc::c_void, + ); + pub fn LLVMContextShouldDiscardValueNames(C: LLVMContextRef) -> LLVMBool; + pub fn LLVMContextSetDiscardValueNames(C: LLVMContextRef, Discard: LLVMBool); + /// Set whether the given context is in opaque pointer mode. + pub fn LLVMContextSetOpaquePointers(C: LLVMContextRef, OpaquePointers: LLVMBool); + pub fn LLVMContextDispose(C: LLVMContextRef); + pub fn LLVMGetDiagInfoDescription(DI: LLVMDiagnosticInfoRef) -> *mut ::libc::c_char; + pub fn LLVMGetDiagInfoSeverity(DI: LLVMDiagnosticInfoRef) -> LLVMDiagnosticSeverity; + pub fn LLVMGetMDKindIDInContext( + C: LLVMContextRef, + Name: *const ::libc::c_char, + SLen: ::libc::c_uint, + ) -> ::libc::c_uint; + //pub fn LLVMGetMDKindID(Name: *const ::libc::c_char, SLen: ::libc::c_uint) -> ::libc::c_uint; + + /// Return a unique id given the name of an enum attribute, or 0 if no attribute + /// by that name exists. + /// + /// See + /// and + /// for the list of available attributes. + /// + /// Note that attribute names and IDs are not subject to the same stability + /// guarantees as this API. + pub fn LLVMGetEnumAttributeKindForName( + Name: *const ::libc::c_char, + SLen: ::libc::size_t, + ) -> ::libc::c_uint; + pub fn LLVMGetLastEnumAttributeKind() -> ::libc::c_uint; + + /// Create an enum attribute. + pub fn LLVMCreateEnumAttribute( + C: LLVMContextRef, + KindID: ::libc::c_uint, + Val: u64, + ) -> LLVMAttributeRef; + /// Get the unique id corresponding to the provided enum attribute. + pub fn LLVMGetEnumAttributeKind(A: LLVMAttributeRef) -> ::libc::c_uint; + /// Get the value of an enum attribute. + /// + /// Returns 0 if none exists. + pub fn LLVMGetEnumAttributeValue(A: LLVMAttributeRef) -> u64; + + /// Create a type attribute. + pub fn LLVMCreateTypeAttribute( + C: LLVMContextRef, + KindID: ::libc::c_uint, + type_ref: LLVMTypeRef, + ) -> LLVMAttributeRef; + /// Get the type attribute's value. + pub fn LLVMGetTypeAttributeValue(A: LLVMAttributeRef) -> LLVMTypeRef; + + /// Create a string attribute. + pub fn LLVMCreateStringAttribute( + C: LLVMContextRef, + K: *const ::libc::c_char, + KLength: ::libc::c_uint, + V: *const ::libc::c_char, + VLength: ::libc::c_uint, + ) -> LLVMAttributeRef; + /// Get a string attribute's kind. + pub fn LLVMGetStringAttributeKind( + A: LLVMAttributeRef, + Length: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + /// Get a string attribute's value. + pub fn LLVMGetStringAttributeValue( + A: LLVMAttributeRef, + Length: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + pub fn LLVMIsEnumAttribute(A: LLVMAttributeRef) -> LLVMBool; + pub fn LLVMIsStringAttribute(A: LLVMAttributeRef) -> LLVMBool; + pub fn LLVMIsTypeAttribute(A: LLVMAttributeRef) -> LLVMBool; + + /// Obtain a Type from a context by its registered name. + pub fn LLVMGetTypeByName2(C: LLVMContextRef, Name: *const ::libc::c_char) -> LLVMTypeRef; +} + +// Core->Modules +extern "C" { + //pub fn LLVMModuleCreateWithName(ModuleID: *const ::libc::c_char) -> LLVMModuleRef; + pub fn LLVMModuleCreateWithNameInContext( + ModuleID: *const ::libc::c_char, + C: LLVMContextRef, + ) -> LLVMModuleRef; + pub fn LLVMCloneModule(M: LLVMModuleRef) -> LLVMModuleRef; + pub fn LLVMDisposeModule(M: LLVMModuleRef); + /// Get the identifier of a module. + /// + /// `Len` is written to contains the length of the returned string. + pub fn LLVMGetModuleIdentifier( + M: LLVMModuleRef, + Len: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + /// Set the identifier of a module. + /// + /// `Len` is the length of the string pointed to by `Ident`. + pub fn LLVMSetModuleIdentifier( + M: LLVMModuleRef, + Ident: *const ::libc::c_char, + Len: ::libc::size_t, + ); + + /// Obtain the module's original source file name. + /// + /// Len holds the length of the returned string, returns the original source file name of M. + pub fn LLVMGetSourceFileName( + M: LLVMModuleRef, + Len: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + /// Set the original source file name of a module to a string Name with length Len. + pub fn LLVMSetSourceFileName( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + Len: ::libc::size_t, + ); + + #[deprecated(since = "3.9", note = "Confusingly named. Use LLVMGetDataLayoutStr.")] + pub fn LLVMGetDataLayout(M: LLVMModuleRef) -> *const ::libc::c_char; + /// Obtain the data layout for a module. + pub fn LLVMGetDataLayoutStr(M: LLVMModuleRef) -> *const ::libc::c_char; + pub fn LLVMSetDataLayout(M: LLVMModuleRef, DataLayoutStr: *const ::libc::c_char); + pub fn LLVMGetTarget(M: LLVMModuleRef) -> *const ::libc::c_char; + pub fn LLVMSetTarget(M: LLVMModuleRef, Triple: *const ::libc::c_char); + + /// Returns the module flags as an array of flag-key-value triples. The caller is responsible for freeing this array by calling LLVMDisposeModuleFlagsMetadata. + pub fn LLVMCopyModuleFlagsMetadata( + M: LLVMModuleRef, + Len: *mut ::libc::size_t, + ) -> *mut LLVMModuleFlagEntry; + /// Destroys module flags metadata entries. + pub fn LLVMDisposeModuleFlagsMetadata(Entries: *mut LLVMModuleFlagEntry); + /// Returns the flag behavior for a module flag entry at a specific index. + pub fn LLVMModuleFlagEntriesGetFlagBehavior( + Entries: *mut LLVMModuleFlagEntry, + Index: ::libc::c_uint, + ) -> LLVMModuleFlagBehavior; + /// Returns the key for a module flag entry at a specific index. + pub fn LLVMModuleFlagEntriesGetKey( + Entries: *mut LLVMModuleFlagEntry, + Index: ::libc::c_uint, + Len: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + /// Returns the metadata for a module flag entry at a specific index. + pub fn LLVMModuleFlagEntriesGetMetadata( + Entries: *mut LLVMModuleFlagEntry, + Index: ::libc::c_uint, + ) -> LLVMMetadataRef; + /// Add a module-level flag to the module-level flags metadata if it doesn't already exist. + pub fn LLVMGetModuleFlag( + M: LLVMModuleRef, + Key: *const ::libc::c_char, + KeyLen: ::libc::size_t, + ) -> LLVMMetadataRef; + /// Add a module-level flag to the module-level flags metadata if it doesn't already exist. + pub fn LLVMAddModuleFlag( + M: LLVMModuleRef, + Behavior: LLVMModuleFlagBehavior, + Key: *const ::libc::c_char, + KeyLen: ::libc::size_t, + Val: LLVMMetadataRef, + ); + + pub fn LLVMDumpModule(M: LLVMModuleRef); + pub fn LLVMPrintModuleToFile( + M: LLVMModuleRef, + Filename: *const ::libc::c_char, + ErrorMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMPrintModuleToString(M: LLVMModuleRef) -> *mut ::libc::c_char; + + pub fn LLVMGetModuleInlineAsm( + M: LLVMModuleRef, + Len: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + #[deprecated(since = "7.0", note = "Use LLVMSetModuleInlineAsm2 instead")] + pub fn LLVMSetModuleInlineAsm(M: LLVMModuleRef, Asm: *const ::libc::c_char); + pub fn LLVMSetModuleInlineAsm2( + M: LLVMModuleRef, + Asm: *const ::libc::c_char, + Len: ::libc::size_t, + ); + pub fn LLVMAppendModuleInlineAsm( + M: LLVMModuleRef, + Asm: *const ::libc::c_char, + Len: ::libc::size_t, + ); + pub fn LLVMGetInlineAsm( + Ty: LLVMTypeRef, + AsmString: *mut ::libc::c_char, + AsmStringSize: ::libc::size_t, + Constraints: *mut ::libc::c_char, + ConstraintsSize: ::libc::size_t, + HasSideEffects: LLVMBool, + IsAlignStack: LLVMBool, + Dialect: LLVMInlineAsmDialect, + CanThrow: LLVMBool, + ) -> LLVMValueRef; + + pub fn LLVMGetModuleContext(M: LLVMModuleRef) -> LLVMContextRef; + #[deprecated(since = "12.0.0", note = "Use LLVMGetTypeByName2 instead")] + pub fn LLVMGetTypeByName(M: LLVMModuleRef, Name: *const ::libc::c_char) -> LLVMTypeRef; + pub fn LLVMGetFirstNamedMetadata(M: LLVMModuleRef) -> LLVMNamedMDNodeRef; + pub fn LLVMGetLastNamedMetadata(M: LLVMModuleRef) -> LLVMNamedMDNodeRef; + pub fn LLVMGetNextNamedMetadata(NamedMDNode: LLVMNamedMDNodeRef) -> LLVMNamedMDNodeRef; + pub fn LLVMGetPreviousNamedMetadata(NamedMDNode: LLVMNamedMDNodeRef) -> LLVMNamedMDNodeRef; + pub fn LLVMGetNamedMetadata( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMNamedMDNodeRef; + pub fn LLVMGetOrInsertNamedMetadata( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMNamedMDNodeRef; + pub fn LLVMGetNamedMetadataName( + NamedMD: LLVMNamedMDNodeRef, + NameLen: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + pub fn LLVMGetNamedMetadataNumOperands( + M: LLVMModuleRef, + name: *const ::libc::c_char, + ) -> ::libc::c_uint; + pub fn LLVMGetNamedMetadataOperands( + M: LLVMModuleRef, + name: *const ::libc::c_char, + Dest: *mut LLVMValueRef, + ); + pub fn LLVMAddNamedMetadataOperand( + M: LLVMModuleRef, + name: *const ::libc::c_char, + Val: LLVMValueRef, + ); + pub fn LLVMGetDebugLocDirectory( + Val: LLVMValueRef, + Length: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + pub fn LLVMGetDebugLocFilename( + Val: LLVMValueRef, + Length: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + pub fn LLVMGetDebugLocLine(Val: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetDebugLocColumn(Val: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMAddFunction( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + FunctionTy: LLVMTypeRef, + ) -> LLVMValueRef; + pub fn LLVMGetNamedFunction(M: LLVMModuleRef, Name: *const ::libc::c_char) -> LLVMValueRef; + pub fn LLVMGetFirstFunction(M: LLVMModuleRef) -> LLVMValueRef; + pub fn LLVMGetLastFunction(M: LLVMModuleRef) -> LLVMValueRef; + pub fn LLVMGetNextFunction(Fn: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetPreviousFunction(Fn: LLVMValueRef) -> LLVMValueRef; +} + +// Core->Types +extern "C" { + pub fn LLVMGetTypeKind(Ty: LLVMTypeRef) -> LLVMTypeKind; + pub fn LLVMTypeIsSized(Ty: LLVMTypeRef) -> LLVMBool; + pub fn LLVMGetTypeContext(Ty: LLVMTypeRef) -> LLVMContextRef; + pub fn LLVMDumpType(Val: LLVMTypeRef); + pub fn LLVMPrintTypeToString(Val: LLVMTypeRef) -> *mut ::libc::c_char; + + // Core->Types->Integer + pub fn LLVMInt1TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMInt8TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMInt16TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMInt32TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMInt64TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMInt128TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMIntTypeInContext(C: LLVMContextRef, NumBits: ::libc::c_uint) -> LLVMTypeRef; + //pub fn LLVMInt1Type() -> LLVMTypeRef; + //pub fn LLVMInt8Type() -> LLVMTypeRef; + //pub fn LLVMInt16Type() -> LLVMTypeRef; + //pub fn LLVMInt32Type() -> LLVMTypeRef; + //pub fn LLVMInt64Type() -> LLVMTypeRef; + //pub fn LLVMInt128Type() -> LLVMTypeRef; + //pub fn LLVMIntType(NumBits: ::libc::c_uint) -> LLVMTypeRef; + pub fn LLVMGetIntTypeWidth(IntegerTy: LLVMTypeRef) -> ::libc::c_uint; + + // Core->Types->Floating-Point + pub fn LLVMHalfTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMBFloatTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMFloatTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMDoubleTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMX86FP80TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMFP128TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMPPCFP128TypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + //pub fn LLVMHalfType() -> LLVMTypeRef; + //pub fn LLVMBFloatType() -> LLVMTypeRef; + //pub fn LLVMFloatType() -> LLVMTypeRef; + //pub fn LLVMDoubleType() -> LLVMTypeRef; + //pub fn LLVMX86FP80Type() -> LLVMTypeRef; + //pub fn LLVMFP128Type() -> LLVMTypeRef; + //pub fn LLVMPPCFP128Type() -> LLVMTypeRef; + + // Core->Types->Function + pub fn LLVMFunctionType( + ReturnType: LLVMTypeRef, + ParamTypes: *mut LLVMTypeRef, + ParamCount: ::libc::c_uint, + IsVarArg: LLVMBool, + ) -> LLVMTypeRef; + pub fn LLVMIsFunctionVarArg(FunctionTy: LLVMTypeRef) -> LLVMBool; + pub fn LLVMGetReturnType(FunctionTy: LLVMTypeRef) -> LLVMTypeRef; + pub fn LLVMCountParamTypes(FunctionTy: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMGetParamTypes(FunctionTy: LLVMTypeRef, Dest: *mut LLVMTypeRef); + + // Core->Types->Struct + pub fn LLVMStructTypeInContext( + C: LLVMContextRef, + ElementTypes: *mut LLVMTypeRef, + ElementCount: ::libc::c_uint, + Packed: LLVMBool, + ) -> LLVMTypeRef; + //pub fn LLVMStructType( + // ElementTypes: *mut LLVMTypeRef, + // ElementCount: ::libc::c_uint, + // Packed: LLVMBool, + //) -> LLVMTypeRef; + pub fn LLVMStructCreateNamed(C: LLVMContextRef, Name: *const ::libc::c_char) -> LLVMTypeRef; + pub fn LLVMGetStructName(Ty: LLVMTypeRef) -> *const ::libc::c_char; + pub fn LLVMStructSetBody( + StructTy: LLVMTypeRef, + ElementTypes: *mut LLVMTypeRef, + ElementCount: ::libc::c_uint, + Packed: LLVMBool, + ); + pub fn LLVMCountStructElementTypes(StructTy: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMGetStructElementTypes(StructTy: LLVMTypeRef, Dest: *mut LLVMTypeRef); + /// Get the type of the element at the given index in a structure. + /// + /// Added in LLVM 3.7. + pub fn LLVMStructGetTypeAtIndex(StructTy: LLVMTypeRef, i: ::libc::c_uint) -> LLVMTypeRef; + /// Determine whether a structure is packed. + pub fn LLVMIsPackedStruct(StructTy: LLVMTypeRef) -> LLVMBool; + pub fn LLVMIsOpaqueStruct(StructTy: LLVMTypeRef) -> LLVMBool; + pub fn LLVMIsLiteralStruct(StructTy: LLVMTypeRef) -> LLVMBool; + + // Core->Types->Sequential + pub fn LLVMGetElementType(Ty: LLVMTypeRef) -> LLVMTypeRef; + /// Get the subtypes of the given type. + pub fn LLVMGetSubtypes(Tp: LLVMTypeRef, Arr: *mut LLVMTypeRef); + /// Return the number of types in the derived type. + pub fn LLVMGetNumContainedTypes(Tp: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMArrayType(ElementType: LLVMTypeRef, ElementCount: ::libc::c_uint) -> LLVMTypeRef; + pub fn LLVMGetArrayLength(ArrayTy: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMPointerType(ElementType: LLVMTypeRef, AddressSpace: ::libc::c_uint) -> LLVMTypeRef; + /// Determine whether a pointer is opaque. + /// + /// True if this is an instance of an opaque PointerType. + pub fn LLVMPointerTypeIsOpaque(Ty: LLVMTypeRef) -> LLVMBool; + /// Create an opaque pointer type in a context. + pub fn LLVMPointerTypeInContext(C: LLVMContextRef, AddressSpace: ::libc::c_uint) -> LLVMTypeRef; + pub fn LLVMGetPointerAddressSpace(PointerTy: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMVectorType(ElementType: LLVMTypeRef, ElementCount: ::libc::c_uint) -> LLVMTypeRef; + /// Create a vector type that contains a defined type and has a scalable + /// number of elements. + /// + /// The created type will exist in the context that its element type + /// exists in. + pub fn LLVMScalableVectorType( + ElementType: LLVMTypeRef, + ElementCount: ::libc::c_uint, + ) -> LLVMTypeRef; + /// Obtain the (possibly scalable) number of elements in a vector type. + pub fn LLVMGetVectorSize(VectorTy: LLVMTypeRef) -> ::libc::c_uint; + + // Core->Types->Other + pub fn LLVMVoidTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMLabelTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMX86MMXTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMX86AMXTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMTokenTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + pub fn LLVMMetadataTypeInContext(C: LLVMContextRef) -> LLVMTypeRef; + //pub fn LLVMVoidType() -> LLVMTypeRef; + //pub fn LLVMLabelType() -> LLVMTypeRef; + //pub fn LLVMX86MMXType() -> LLVMTypeRef; + //pub fn LLVMX86AMXType() -> LLVMTypeRef; +} + +// Core->Values +extern "C" { + // Core->Values->General + // Get the enumerated kind of a Value instance. + pub fn LLVMGetValueKind(Val: LLVMValueRef) -> LLVMValueKind; + pub fn LLVMTypeOf(Val: LLVMValueRef) -> LLVMTypeRef; + + #[deprecated(since = "7.0", note = "Use LLVMGetValueName2 instead")] + pub fn LLVMGetValueName(Val: LLVMValueRef) -> *const ::libc::c_char; + pub fn LLVMGetValueName2( + Val: LLVMValueRef, + Length: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + #[deprecated(since = "7.0", note = "Use LLVMSetValueName2 instead")] + pub fn LLVMSetValueName(Val: LLVMValueRef, Name: *const ::libc::c_char); + pub fn LLVMSetValueName2( + Val: LLVMValueRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ); + + pub fn LLVMDumpValue(Val: LLVMValueRef); + pub fn LLVMPrintValueToString(Val: LLVMValueRef) -> *mut ::libc::c_char; + pub fn LLVMReplaceAllUsesWith(OldVal: LLVMValueRef, NewVal: LLVMValueRef); + /// Determine whether the specified value instance is constant. + pub fn LLVMIsConstant(Val: LLVMValueRef) -> LLVMBool; + pub fn LLVMIsUndef(Val: LLVMValueRef) -> LLVMBool; + /// Determine whether a value instance is poisonous. + pub fn LLVMIsPoison(Val: LLVMValueRef) -> LLVMBool; + pub fn LLVMIsAMDNode(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAMDString(Val: LLVMValueRef) -> LLVMValueRef; + + // Core->Values->Usage + pub fn LLVMGetFirstUse(Val: LLVMValueRef) -> LLVMUseRef; + pub fn LLVMGetNextUse(U: LLVMUseRef) -> LLVMUseRef; + pub fn LLVMGetUser(U: LLVMUseRef) -> LLVMValueRef; + pub fn LLVMGetUsedValue(U: LLVMUseRef) -> LLVMValueRef; + + // Core->Values->User value + pub fn LLVMGetOperand(Val: LLVMValueRef, Index: ::libc::c_uint) -> LLVMValueRef; + pub fn LLVMGetOperandUse(Val: LLVMValueRef, Index: ::libc::c_uint) -> LLVMUseRef; + pub fn LLVMSetOperand(User: LLVMValueRef, Index: ::libc::c_uint, Val: LLVMValueRef); + pub fn LLVMGetNumOperands(Val: LLVMValueRef) -> ::libc::c_int; + + // Core->Values->Constants + pub fn LLVMConstNull(Ty: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstAllOnes(Ty: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMGetUndef(Ty: LLVMTypeRef) -> LLVMValueRef; + /// Obtain a constant value referring to a poison value of a type. + pub fn LLVMGetPoison(Ty: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMIsNull(Val: LLVMValueRef) -> LLVMBool; + pub fn LLVMConstPointerNull(Ty: LLVMTypeRef) -> LLVMValueRef; + + // Core->Values->Constants->Scalar + pub fn LLVMConstInt( + IntTy: LLVMTypeRef, + N: ::libc::c_ulonglong, + SignExtend: LLVMBool, + ) -> LLVMValueRef; + pub fn LLVMConstIntOfArbitraryPrecision( + IntTy: LLVMTypeRef, + NumWords: ::libc::c_uint, + Words: *const u64, + ) -> LLVMValueRef; + pub fn LLVMConstIntOfString( + IntTy: LLVMTypeRef, + Text: *const ::libc::c_char, + Radix: u8, + ) -> LLVMValueRef; + pub fn LLVMConstIntOfStringAndSize( + IntTy: LLVMTypeRef, + Text: *const ::libc::c_char, + SLen: ::libc::c_uint, + Radix: u8, + ) -> LLVMValueRef; + pub fn LLVMConstReal(RealTy: LLVMTypeRef, N: ::libc::c_double) -> LLVMValueRef; + pub fn LLVMConstRealOfString(RealTy: LLVMTypeRef, Text: *const ::libc::c_char) -> LLVMValueRef; + pub fn LLVMConstRealOfStringAndSize( + RealTy: LLVMTypeRef, + Text: *const ::libc::c_char, + SLen: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMConstIntGetZExtValue(ConstantVal: LLVMValueRef) -> ::libc::c_ulonglong; + pub fn LLVMConstIntGetSExtValue(ConstantVal: LLVMValueRef) -> ::libc::c_longlong; + pub fn LLVMConstRealGetDouble( + ConstantVal: LLVMValueRef, + losesInfo: *mut LLVMBool, + ) -> ::libc::c_double; + + // Core->Values->Constants->Composite + pub fn LLVMConstStringInContext( + C: LLVMContextRef, + Str: *const ::libc::c_char, + Length: ::libc::c_uint, + DontNullTerminate: LLVMBool, + ) -> LLVMValueRef; + //pub fn LLVMConstString( + // Str: *const ::libc::c_char, + // Length: ::libc::c_uint, + // DontNullTerminate: LLVMBool, + //) -> LLVMValueRef; + pub fn LLVMIsConstantString(c: LLVMValueRef) -> LLVMBool; + pub fn LLVMGetAsString(C: LLVMValueRef, Length: *mut ::libc::size_t) -> *const ::libc::c_char; + pub fn LLVMConstStructInContext( + C: LLVMContextRef, + ConstantVals: *mut LLVMValueRef, + Count: ::libc::c_uint, + Packed: LLVMBool, + ) -> LLVMValueRef; + //pub fn LLVMConstStruct( + // ConstantVals: *mut LLVMValueRef, + // Count: ::libc::c_uint, + // Packed: LLVMBool, + //) -> LLVMValueRef; + pub fn LLVMConstArray( + ElementTy: LLVMTypeRef, + ConstantVals: *mut LLVMValueRef, + Length: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMConstNamedStruct( + StructTy: LLVMTypeRef, + ConstantVals: *mut LLVMValueRef, + Count: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMGetAggregateElement(C: LLVMValueRef, idx: ::libc::c_uint) -> LLVMValueRef; + #[deprecated(since = "15.0", note = "Use LLVMGetAggregateElement instead")] + pub fn LLVMGetElementAsConstant(C: LLVMValueRef, idx: ::libc::c_uint) -> LLVMValueRef; + pub fn LLVMConstVector( + ScalarConstantVals: *mut LLVMValueRef, + Size: ::libc::c_uint, + ) -> LLVMValueRef; + + // Core->Values->Constants->Constant expressions + pub fn LLVMGetConstOpcode(ConstantVal: LLVMValueRef) -> LLVMOpcode; + pub fn LLVMAlignOf(Ty: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMSizeOf(Ty: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstNeg(ConstantVal: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNSWNeg(ConstantVal: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNUWNeg(ConstantVal: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstFNeg(ConstantVal: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNot(ConstantVal: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstAdd(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNSWAdd(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNUWAdd(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstSub(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNSWSub(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNUWSub(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstMul(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNSWMul(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstNUWMul(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstAnd(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstOr(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstXor(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstICmp( + Predicate: LLVMIntPredicate, + LHSConstant: LLVMValueRef, + RHSConstant: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMConstFCmp( + Predicate: LLVMRealPredicate, + LHSConstant: LLVMValueRef, + RHSConstant: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMConstShl(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstLShr(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMConstAShr(LHSConstant: LLVMValueRef, RHSConstant: LLVMValueRef) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMConstGEP2 instead to support opaque pointers." + )] + pub fn LLVMConstGEP( + ConstantVal: LLVMValueRef, + ConstantIndices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMConstGEP2( + Ty: LLVMTypeRef, + ConstantVal: LLVMValueRef, + ConstantIndices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMConstInBoundsGEP2 instead to support opaque pointers." + )] + pub fn LLVMConstInBoundsGEP( + ConstantVal: LLVMValueRef, + ConstantIndices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMConstInBoundsGEP2( + Ty: LLVMTypeRef, + ConstantVal: LLVMValueRef, + ConstantIndices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMConstTrunc(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstSExt(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstZExt(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstFPTrunc(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstFPExt(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstUIToFP(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstSIToFP(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstFPToUI(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstFPToSI(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstPtrToInt(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstIntToPtr(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstBitCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstAddrSpaceCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstZExtOrBitCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstSExtOrBitCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstTruncOrBitCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstPointerCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstIntCast( + ConstantVal: LLVMValueRef, + ToType: LLVMTypeRef, + isSigned: LLVMBool, + ) -> LLVMValueRef; + pub fn LLVMConstFPCast(ConstantVal: LLVMValueRef, ToType: LLVMTypeRef) -> LLVMValueRef; + pub fn LLVMConstSelect( + ConstantCondition: LLVMValueRef, + ConstantIfTrue: LLVMValueRef, + ConstantIfFalse: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMConstExtractElement( + VectorConstant: LLVMValueRef, + IndexConstant: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMConstInsertElement( + VectorConstant: LLVMValueRef, + ElementValueConstant: LLVMValueRef, + IndexConstant: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMConstShuffleVector( + VectorAConstant: LLVMValueRef, + VectorBConstant: LLVMValueRef, + MaskConstant: LLVMValueRef, + ) -> LLVMValueRef; + #[deprecated(since = "7.0", note = "Use LLVMGetInlineAsm instead")] + pub fn LLVMConstInlineAsm( + Ty: LLVMTypeRef, + AsmString: *const ::libc::c_char, + Constraints: *const ::libc::c_char, + HasSideEffects: LLVMBool, + IsAlignStack: LLVMBool, + ) -> LLVMValueRef; + pub fn LLVMBlockAddress(F: LLVMValueRef, BB: LLVMBasicBlockRef) -> LLVMValueRef; + + // Core->Values->Constants->Global Values + pub fn LLVMGetGlobalParent(Global: LLVMValueRef) -> LLVMModuleRef; + pub fn LLVMIsDeclaration(Global: LLVMValueRef) -> LLVMBool; + pub fn LLVMGetLinkage(Global: LLVMValueRef) -> LLVMLinkage; + pub fn LLVMSetLinkage(Global: LLVMValueRef, Linkage: LLVMLinkage); + pub fn LLVMGetSection(Global: LLVMValueRef) -> *const ::libc::c_char; + pub fn LLVMSetSection(Global: LLVMValueRef, Section: *const ::libc::c_char); + pub fn LLVMGetVisibility(Global: LLVMValueRef) -> LLVMVisibility; + pub fn LLVMSetVisibility(Global: LLVMValueRef, Viz: LLVMVisibility); + pub fn LLVMGetDLLStorageClass(Global: LLVMValueRef) -> LLVMDLLStorageClass; + pub fn LLVMSetDLLStorageClass(Global: LLVMValueRef, Class: LLVMDLLStorageClass); + + pub fn LLVMGetUnnamedAddress(Global: LLVMValueRef) -> LLVMUnnamedAddr; + pub fn LLVMSetUnnamedAddress(Global: LLVMValueRef, UnnamedAddr: LLVMUnnamedAddr); + pub fn LLVMGlobalGetValueType(Global: LLVMValueRef) -> LLVMTypeRef; + #[deprecated(since = "7.0", note = "Use LLVMGetUnnamedAddress instead")] + pub fn LLVMHasUnnamedAddr(Global: LLVMValueRef) -> LLVMBool; + #[deprecated(since = "7.0", note = "Use LLVMSetUnnamedAddress instead")] + pub fn LLVMSetUnnamedAddr(Global: LLVMValueRef, HasUnnamedAddr: LLVMBool); + + pub fn LLVMGetAlignment(V: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMSetAlignment(V: LLVMValueRef, Bytes: ::libc::c_uint); + + pub fn LLVMGlobalSetMetadata(Global: LLVMValueRef, Kind: ::libc::c_uint, MD: LLVMMetadataRef); + pub fn LLVMGlobalEraseMetadata(Global: LLVMValueRef, Kind: ::libc::c_uint); + pub fn LLVMGlobalClearMetadata(Global: LLVMValueRef); + pub fn LLVMGlobalCopyAllMetadata( + Value: LLVMValueRef, + NumEntries: *mut ::libc::size_t, + ) -> *mut LLVMValueMetadataEntry; + pub fn LLVMDisposeValueMetadataEntries(Entries: *mut LLVMValueMetadataEntry); + pub fn LLVMValueMetadataEntriesGetKind( + Entries: *mut LLVMValueMetadataEntry, + Index: ::libc::c_uint, + ) -> ::libc::c_uint; + pub fn LLVMValueMetadataEntriesGetMetadata( + Entries: *mut LLVMValueMetadataEntry, + Index: ::libc::c_uint, + ) -> LLVMMetadataRef; + + // Core->Values->Constants->Global Variables + pub fn LLVMAddGlobal( + M: LLVMModuleRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMAddGlobalInAddressSpace( + M: LLVMModuleRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + AddressSpace: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMGetNamedGlobal(M: LLVMModuleRef, Name: *const ::libc::c_char) -> LLVMValueRef; + pub fn LLVMGetFirstGlobal(M: LLVMModuleRef) -> LLVMValueRef; + pub fn LLVMGetLastGlobal(M: LLVMModuleRef) -> LLVMValueRef; + pub fn LLVMGetNextGlobal(GlobalVar: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetPreviousGlobal(GlobalVar: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMDeleteGlobal(GlobalVar: LLVMValueRef); + pub fn LLVMGetInitializer(GlobalVar: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMSetInitializer(GlobalVar: LLVMValueRef, ConstantVal: LLVMValueRef); + pub fn LLVMIsThreadLocal(GlobalVar: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetThreadLocal(GlobalVar: LLVMValueRef, IsThreadLocal: LLVMBool); + pub fn LLVMIsGlobalConstant(GlobalVar: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetGlobalConstant(GlobalVar: LLVMValueRef, IsConstant: LLVMBool); + pub fn LLVMGetThreadLocalMode(GlobalVar: LLVMValueRef) -> LLVMThreadLocalMode; + pub fn LLVMSetThreadLocalMode(GlobalVar: LLVMValueRef, Mode: LLVMThreadLocalMode); + pub fn LLVMIsExternallyInitialized(GlobalVar: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetExternallyInitialized(GlobalVar: LLVMValueRef, IsExtInit: LLVMBool); + + // Core->Values->Constants->Global Aliases + /// Obtain a GlobalAlias value from a Module by its name. + /// + /// The returned value corresponds to a llvm::GlobalAlias value. + pub fn LLVMGetNamedGlobalAlias( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMValueRef; + /// Obtain an iterator to the first GlobalAlias in a Module. + pub fn LLVMGetFirstGlobalAlias(M: LLVMModuleRef) -> LLVMValueRef; + /// Obtain an iterator to the last GlobalAlias in a Module. + pub fn LLVMGetLastGlobalAlias(M: LLVMModuleRef) -> LLVMValueRef; + /// Advance a GlobalAlias iterator to the next GlobalAlias. + /// + /// Returns NULL if the iterator was already at the end and there are no more global aliases. + pub fn LLVMGetNextGlobalAlias(GA: LLVMValueRef) -> LLVMValueRef; + /// Decrement a GlobalAlias iterator to the previous GlobalAlias. + /// + /// Returns NULL if the iterator was already at the beginning and there are no previous global aliases. + pub fn LLVMGetPreviousGlobalAlias(GA: LLVMValueRef) -> LLVMValueRef; + /// Retrieve the target value of an alias. + pub fn LLVMAliasGetAliasee(Alias: LLVMValueRef) -> LLVMValueRef; + /// Set the target value of an alias. + pub fn LLVMAliasSetAliasee(Alias: LLVMValueRef, Aliasee: LLVMValueRef); + + #[deprecated( + since = "14.0", + note = "Use LLVMAddAlias2 instead to support opaque pointers." + )] + pub fn LLVMAddAlias( + M: LLVMModuleRef, + Ty: LLVMTypeRef, + Aliasee: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + + pub fn LLVMAddAlias2( + M: LLVMModuleRef, + ValueTy: LLVMTypeRef, + AddrSpace: ::libc::c_uint, + Aliasee: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + + // ..->Function Values + pub fn LLVMDeleteFunction(Fn: LLVMValueRef); + /// Check whether the given function has a personality function. + pub fn LLVMHasPersonalityFn(Fn: LLVMValueRef) -> LLVMBool; + /// Obtain the personality function attached to the function. + /// + /// Added in LLVM 3.7. + pub fn LLVMGetPersonalityFn(Fn: LLVMValueRef) -> LLVMValueRef; + /// Set the personality function attached to the function. + /// + /// Added in LLVM 3.7. + pub fn LLVMSetPersonalityFn(Fn: LLVMValueRef, PersonalityFn: LLVMValueRef); + /// Obtain the intrinsic ID number which matches the given function name. + pub fn LLVMLookupIntrinsicID( + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> ::libc::c_uint; + /// Obtain the ID number from a function instance. + pub fn LLVMGetIntrinsicID(Fn: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetIntrinsicDeclaration( + Mod: LLVMModuleRef, + ID: ::libc::c_uint, + ParamTypes: *mut LLVMTypeRef, + ParamCount: ::libc::size_t, + ) -> LLVMValueRef; + pub fn LLVMIntrinsicGetType( + Ctx: LLVMContextRef, + ID: ::libc::c_uint, + ParamTypes: *mut LLVMTypeRef, + ParamCount: ::libc::size_t, + ) -> LLVMTypeRef; + pub fn LLVMIntrinsicGetName( + ID: ::libc::c_uint, + NameLength: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + #[deprecated = "Use LLVMIntrinsicCopyOverloadedName2 instead."] + pub fn LLVMIntrinsicCopyOverloadedName( + ID: ::libc::c_uint, + ParamTypes: *mut LLVMTypeRef, + ParamCount: ::libc::size_t, + NameLength: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + pub fn LLVMIntrinsicCopyOverloadedName2( + Mod: LLVMModuleRef, + ID: ::libc::c_uint, + ParamTypes: *mut LLVMTypeRef, + ParamCount: ::libc::size_t, + NameLength: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + pub fn LLVMIntrinsicIsOverloaded(ID: ::libc::c_uint) -> LLVMBool; + pub fn LLVMGetFunctionCallConv(Fn: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMSetFunctionCallConv(Fn: LLVMValueRef, CC: ::libc::c_uint); + pub fn LLVMGetGC(Fn: LLVMValueRef) -> *const ::libc::c_char; + pub fn LLVMSetGC(Fn: LLVMValueRef, Name: *const ::libc::c_char); + pub fn LLVMAddAttributeAtIndex(F: LLVMValueRef, Idx: LLVMAttributeIndex, A: LLVMAttributeRef); + pub fn LLVMGetAttributeCountAtIndex(F: LLVMValueRef, Idx: LLVMAttributeIndex) + -> ::libc::c_uint; + pub fn LLVMGetAttributesAtIndex( + F: LLVMValueRef, + Idx: LLVMAttributeIndex, + Attrs: *mut LLVMAttributeRef, + ); + pub fn LLVMGetEnumAttributeAtIndex( + F: LLVMValueRef, + Idx: LLVMAttributeIndex, + KindID: ::libc::c_uint, + ) -> LLVMAttributeRef; + pub fn LLVMGetStringAttributeAtIndex( + F: LLVMValueRef, + Idx: LLVMAttributeIndex, + K: *const ::libc::c_char, + KLen: ::libc::c_uint, + ) -> LLVMAttributeRef; + pub fn LLVMRemoveEnumAttributeAtIndex( + F: LLVMValueRef, + Idx: LLVMAttributeIndex, + KindID: ::libc::c_uint, + ); + pub fn LLVMRemoveStringAttributeAtIndex( + F: LLVMValueRef, + Idx: LLVMAttributeIndex, + K: *const ::libc::c_char, + KLen: ::libc::c_uint, + ); + pub fn LLVMAddTargetDependentFunctionAttr( + Fn: LLVMValueRef, + A: *const ::libc::c_char, + V: *const ::libc::c_char, + ); + + // ..->Function Values->Function Parameters + pub fn LLVMCountParams(Fn: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetParams(Fn: LLVMValueRef, Params: *mut LLVMValueRef); + pub fn LLVMGetParam(Fn: LLVMValueRef, Index: ::libc::c_uint) -> LLVMValueRef; + pub fn LLVMGetParamParent(Inst: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetFirstParam(Fn: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetLastParam(Fn: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetNextParam(Arg: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetPreviousParam(Arg: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMSetParamAlignment(Arg: LLVMValueRef, Align: ::libc::c_uint); +} + +// Core->Metadata +extern "C" { + #[deprecated(since = "LLVM 9.0", note = "Use LLVMMDStringInContext2 instead.")] + pub fn LLVMMDStringInContext( + C: LLVMContextRef, + Str: *const ::libc::c_char, + SLen: ::libc::c_uint, + ) -> LLVMValueRef; + //#[deprecated(since = "LLVM 9.0", note = "Use LLVMMDStringInContext2 instead.")] + //pub fn LLVMMDString(Str: *const ::libc::c_char, SLen: ::libc::c_uint) -> LLVMValueRef; + #[deprecated(since = "LLVM 9.0", note = "Use LLVMMDNodeInContext2 instead.")] + pub fn LLVMMDNodeInContext( + C: LLVMContextRef, + Vals: *mut LLVMValueRef, + Count: ::libc::c_uint, + ) -> LLVMValueRef; + //#[deprecated(since = "LLVM 9.0", note = "Use LLVMMDNodeInContext2 instead.")] + //pub fn LLVMMDNode(Vals: *mut LLVMValueRef, Count: ::libc::c_uint) -> LLVMValueRef; + + /// Add a global indirect function to a module under a specified name. + pub fn LLVMAddGlobalIFunc( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Ty: LLVMTypeRef, + AddrSpace: ::libc::c_uint, + Resolver: LLVMValueRef, + ) -> LLVMValueRef; + + /// Obtain a GlobalIFunc value from a Module by its name. + pub fn LLVMGetNamedGlobalIFunc( + M: LLVMModuleRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMValueRef; + + /// Obtain an iterator to the first GlobalIFunc in a Module. + pub fn LLVMGetFirstGlobalIFunc(M: LLVMModuleRef) -> LLVMValueRef; + + /// Obtain an iterator to the last GlobalIFunc in a Module. + pub fn LLVMGetLastGlobalIFunc(M: LLVMModuleRef) -> LLVMValueRef; + + /// Advance a GlobalIFunc iterator to the next GlobalIFunc. + pub fn LLVMGetNextGlobalIFunc(IFunc: LLVMValueRef) -> LLVMValueRef; + + /// Decrement a GlobalIFunc iterator to the previous GlobalIFunc. + pub fn LLVMGetPreviousGlobalIFunc(IFunc: LLVMValueRef) -> LLVMValueRef; + + /// Retrieves the resolver function associated with this indirect function, or + /// NULL if it doesn't not exist. + pub fn LLVMGetGlobalIFuncResolver(IFunc: LLVMValueRef) -> LLVMValueRef; + + /// Sets the resolver function associated with this indirect function. + pub fn LLVMSetGlobalIFuncResolver(IFunc: LLVMValueRef, Resolver: LLVMValueRef); + + /// Remove a global indirect function from its parent module and delete it. + pub fn LLVMEraseGlobalIFunc(IFunc: LLVMValueRef); + + /// Remove a global indirect function from its parent module. + pub fn LLVMRemoveGlobalIFunc(IFunc: LLVMValueRef); + + /// Create an MDString value from a given string value. + pub fn LLVMMDStringInContext2( + C: LLVMContextRef, + Str: *const ::libc::c_char, + SLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create an MDNode value with the given array of operands. + pub fn LLVMMDNodeInContext2( + C: LLVMContextRef, + MDs: *mut LLVMMetadataRef, + Count: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Obtain Metadata as a Value. + pub fn LLVMMetadataAsValue(C: LLVMContextRef, MD: LLVMMetadataRef) -> LLVMValueRef; + /// Obtain a Value as Metadata. + pub fn LLVMValueAsMetadata(Val: LLVMValueRef) -> LLVMMetadataRef; + /// Obtain the underlying string from a MDString value. + /// + /// `Len` is written to contain the length of the returned string. + pub fn LLVMGetMDString(V: LLVMValueRef, Len: *mut ::libc::c_uint) -> *const ::libc::c_char; + pub fn LLVMGetMDNodeNumOperands(V: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetMDNodeOperands(V: LLVMValueRef, Dest: *mut LLVMValueRef); +} + +// Core->Basic Block +extern "C" { + pub fn LLVMBasicBlockAsValue(BB: LLVMBasicBlockRef) -> LLVMValueRef; + pub fn LLVMValueIsBasicBlock(Val: LLVMValueRef) -> LLVMBool; + pub fn LLVMValueAsBasicBlock(Val: LLVMValueRef) -> LLVMBasicBlockRef; + /// Get the string name of a basic block. + pub fn LLVMGetBasicBlockName(BB: LLVMBasicBlockRef) -> *const ::libc::c_char; + pub fn LLVMGetBasicBlockParent(BB: LLVMBasicBlockRef) -> LLVMValueRef; + pub fn LLVMGetBasicBlockTerminator(BB: LLVMBasicBlockRef) -> LLVMValueRef; + pub fn LLVMCountBasicBlocks(Fn: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetBasicBlocks(Fn: LLVMValueRef, BasicBlocks: *mut LLVMBasicBlockRef); + pub fn LLVMGetFirstBasicBlock(Fn: LLVMValueRef) -> LLVMBasicBlockRef; + pub fn LLVMGetLastBasicBlock(Fn: LLVMValueRef) -> LLVMBasicBlockRef; + pub fn LLVMGetNextBasicBlock(BB: LLVMBasicBlockRef) -> LLVMBasicBlockRef; + pub fn LLVMGetPreviousBasicBlock(BB: LLVMBasicBlockRef) -> LLVMBasicBlockRef; + pub fn LLVMGetEntryBasicBlock(Fn: LLVMValueRef) -> LLVMBasicBlockRef; + /// Insert the given basic block after the insertion point of the given builder. + pub fn LLVMInsertExistingBasicBlockAfterInsertBlock( + Builder: LLVMBuilderRef, + BB: LLVMBasicBlockRef, + ); + /// Append the given basic block to the basic block list of the given function. + pub fn LLVMAppendExistingBasicBlock(Fn: LLVMValueRef, BB: LLVMBasicBlockRef); + pub fn LLVMCreateBasicBlockInContext( + C: LLVMContextRef, + Name: *const ::libc::c_char, + ) -> LLVMBasicBlockRef; + pub fn LLVMAppendBasicBlockInContext( + C: LLVMContextRef, + Fn: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMBasicBlockRef; + //pub fn LLVMAppendBasicBlock(Fn: LLVMValueRef, Name: *const ::libc::c_char) + // -> LLVMBasicBlockRef; + pub fn LLVMInsertBasicBlockInContext( + C: LLVMContextRef, + BB: LLVMBasicBlockRef, + Name: *const ::libc::c_char, + ) -> LLVMBasicBlockRef; + //pub fn LLVMInsertBasicBlock( + // InsertBeforeBB: LLVMBasicBlockRef, + // Name: *const ::libc::c_char, + //) -> LLVMBasicBlockRef; + pub fn LLVMDeleteBasicBlock(BB: LLVMBasicBlockRef); + pub fn LLVMRemoveBasicBlockFromParent(BB: LLVMBasicBlockRef); + pub fn LLVMMoveBasicBlockBefore(BB: LLVMBasicBlockRef, MovePos: LLVMBasicBlockRef); + pub fn LLVMMoveBasicBlockAfter(BB: LLVMBasicBlockRef, MovePos: LLVMBasicBlockRef); + pub fn LLVMGetFirstInstruction(BB: LLVMBasicBlockRef) -> LLVMValueRef; + pub fn LLVMGetLastInstruction(BB: LLVMBasicBlockRef) -> LLVMValueRef; +} + +// Core->Instructions +extern "C" { + pub fn LLVMHasMetadata(Val: LLVMValueRef) -> ::libc::c_int; + pub fn LLVMGetMetadata(Val: LLVMValueRef, KindID: ::libc::c_uint) -> LLVMValueRef; + pub fn LLVMSetMetadata(Val: LLVMValueRef, KindID: ::libc::c_uint, Node: LLVMValueRef); + pub fn LLVMInstructionGetAllMetadataOtherThanDebugLoc( + Instr: LLVMValueRef, + NumEntries: *mut ::libc::size_t, + ) -> *mut LLVMValueMetadataEntry; + pub fn LLVMGetInstructionParent(Inst: LLVMValueRef) -> LLVMBasicBlockRef; + pub fn LLVMGetNextInstruction(Inst: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMGetPreviousInstruction(Inst: LLVMValueRef) -> LLVMValueRef; + /// Remove the given instruction from its containing building block but + /// kept alive. + pub fn LLVMInstructionRemoveFromParent(Inst: LLVMValueRef); + /// Remove the given instruction from its containing building block and + /// delete it. + pub fn LLVMInstructionEraseFromParent(Inst: LLVMValueRef); + /// Remove the given instruction that is not inserted into a basic block. + /// It must have previously been removed from its containing building block. + pub fn LLVMDeleteInstruction(Inst: LLVMValueRef); + pub fn LLVMGetInstructionOpcode(Inst: LLVMValueRef) -> LLVMOpcode; + pub fn LLVMGetICmpPredicate(Inst: LLVMValueRef) -> LLVMIntPredicate; + pub fn LLVMGetFCmpPredicate(Inst: LLVMValueRef) -> LLVMRealPredicate; + pub fn LLVMInstructionClone(Inst: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsATerminatorInst(Inst: LLVMValueRef) -> LLVMValueRef; + + // Instructions->Call Sites and Invocations + // Obtain the argument count for a call instruction. + // + // The provided value should be either a CallInst, InvokeInst or FuncletPadInst. + pub fn LLVMGetNumArgOperands(Instr: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMSetInstructionCallConv(Instr: LLVMValueRef, CC: ::libc::c_uint); + pub fn LLVMGetInstructionCallConv(Instr: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMSetInstrParamAlignment( + Instr: LLVMValueRef, + Idx: LLVMAttributeIndex, + Align: ::libc::c_uint, + ); + pub fn LLVMAddCallSiteAttribute(C: LLVMValueRef, Idx: LLVMAttributeIndex, A: LLVMAttributeRef); + pub fn LLVMGetCallSiteAttributeCount( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + ) -> ::libc::c_uint; + pub fn LLVMGetCallSiteAttributes( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + Attrs: *mut LLVMAttributeRef, + ); + pub fn LLVMGetCallSiteEnumAttribute( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + KindID: ::libc::c_uint, + ) -> LLVMAttributeRef; + pub fn LLVMGetCallSiteStringAttribute( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + K: *const ::libc::c_char, + KLen: ::libc::c_uint, + ) -> LLVMAttributeRef; + pub fn LLVMRemoveCallSiteEnumAttribute( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + KindID: ::libc::c_uint, + ); + pub fn LLVMRemoveCallSiteStringAttribute( + C: LLVMValueRef, + Idx: LLVMAttributeIndex, + K: *const ::libc::c_char, + KLen: ::libc::c_uint, + ); + pub fn LLVMGetCalledFunctionType(C: LLVMValueRef) -> LLVMTypeRef; + /// Get a pointer to the function invoked by this instruction. + /// + /// The provided value should be a CallInst or InvokeInst. + pub fn LLVMGetCalledValue(Instr: LLVMValueRef) -> LLVMValueRef; + /// Get whether a call instruction is a tail call. + pub fn LLVMIsTailCall(CallInst: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetTailCall(CallInst: LLVMValueRef, IsTailCall: LLVMBool); + /// Return the normal destination basic block of an invoke instruction. + pub fn LLVMGetNormalDest(InvokeInst: LLVMValueRef) -> LLVMBasicBlockRef; + /// Return the unwind destination basic block. + pub fn LLVMGetUnwindDest(InvokeInst: LLVMValueRef) -> LLVMBasicBlockRef; + /// Set the normal destination basic block. + pub fn LLVMSetNormalDest(InvokeInst: LLVMValueRef, B: LLVMBasicBlockRef); + /// Set the unwind destination basic block. + pub fn LLVMSetUnwindDest(InvokeInst: LLVMValueRef, B: LLVMBasicBlockRef); + + // Instructions->Terminators + pub fn LLVMGetNumSuccessors(Term: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetSuccessor(Term: LLVMValueRef, i: ::libc::c_uint) -> LLVMBasicBlockRef; + pub fn LLVMSetSuccessor(Term: LLVMValueRef, i: ::libc::c_uint, block: LLVMBasicBlockRef); + pub fn LLVMIsConditional(Branch: LLVMValueRef) -> LLVMBool; + pub fn LLVMGetCondition(Branch: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMSetCondition(Branch: LLVMValueRef, Cond: LLVMValueRef); + pub fn LLVMGetSwitchDefaultDest(SwitchInstr: LLVMValueRef) -> LLVMBasicBlockRef; + + // Instructions->Allocas + // Obtain the type being allocated by an alloca instruction. + pub fn LLVMGetAllocatedType(Alloca: LLVMValueRef) -> LLVMTypeRef; + + // Instructions->GEPs + // Check whether the given GEP operator is inbounds. + pub fn LLVMIsInBounds(GEP: LLVMValueRef) -> LLVMBool; + /// Set the given GEP instruction to be inbounds or not. + pub fn LLVMSetIsInBounds(GEP: LLVMValueRef, InBounds: LLVMBool); + + /// Get the source element type of the given GEP operator. + pub fn LLVMGetGEPSourceElementType(GEP: LLVMValueRef) -> LLVMTypeRef; + + // Instruction->PHI Nodes + pub fn LLVMAddIncoming( + PhiNode: LLVMValueRef, + IncomingValues: *mut LLVMValueRef, + IncomingBlocks: *mut LLVMBasicBlockRef, + Count: ::libc::c_uint, + ); + pub fn LLVMCountIncoming(PhiNode: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetIncomingValue(PhiNode: LLVMValueRef, Index: ::libc::c_uint) -> LLVMValueRef; + pub fn LLVMGetIncomingBlock(PhiNode: LLVMValueRef, Index: ::libc::c_uint) -> LLVMBasicBlockRef; + +} + +// Core->Values again; these don't appear in Doxygen because they're macro-generated. +extern "C" { + pub fn LLVMIsAArgument(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsABasicBlock(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAInlineAsm(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUser(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstant(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsABlockAddress(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantAggregateZero(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantArray(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantDataSequential(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantDataArray(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantDataVector(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantExpr(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantFP(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantInt(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantPointerNull(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantStruct(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantTokenNone(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAConstantVector(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGlobalValue(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGlobalAlias(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGlobalIFunc(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGlobalObject(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFunction(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGlobalVariable(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUndefValue(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAPoisonValue(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAInstruction(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUnaryOperator(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsABinaryOperator(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACallInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAIntrinsicInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsADbgInfoIntrinsic(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsADbgVariableIntrinsic(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsADbgDeclareInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsADbgLabelInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAMemIntrinsic(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAMemCpyInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAMemMoveInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAMemSetInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACmpInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFCmpInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAICmpInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAExtractElementInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAGetElementPtrInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAInsertElementInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAInsertValueInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsALandingPadInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAPHINode(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsASelectInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAShuffleVectorInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAStoreInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsABranchInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAIndirectBrInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAInvokeInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAReturnInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsASwitchInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUnreachableInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAResumeInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACleanupReturnInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACatchReturnInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACatchSwitchInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACallBrInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFuncletPadInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACatchPadInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACleanupPadInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUnaryInstruction(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAAllocaInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsACastInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAAddrSpaceCastInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsABitCastInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFPExtInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFPToSIInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFPToUIInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFPTruncInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAIntToPtrInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAPtrToIntInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsASExtInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsASIToFPInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsATruncInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAUIToFPInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAZExtInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAExtractValueInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsALoadInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAVAArgInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFreezeInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAAtomicCmpXchgInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAAtomicRMWInst(Val: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMIsAFenceInst(Val: LLVMValueRef) -> LLVMValueRef; +} + +// Core->Extract/Insert Value +extern "C" { + /// Get the number of indices on an ExtractValue, InsertValue or GEP operator. + pub fn LLVMGetNumIndices(Inst: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetIndices(Inst: LLVMValueRef) -> *const ::libc::c_uint; +} + +// Core->Instruction Builders +extern "C" { + pub fn LLVMCreateBuilderInContext(C: LLVMContextRef) -> LLVMBuilderRef; + //pub fn LLVMCreateBuilder() -> LLVMBuilderRef; + pub fn LLVMPositionBuilder( + Builder: LLVMBuilderRef, + Block: LLVMBasicBlockRef, + Instr: LLVMValueRef, + ); + pub fn LLVMPositionBuilderBefore(Builder: LLVMBuilderRef, Instr: LLVMValueRef); + pub fn LLVMPositionBuilderAtEnd(Builder: LLVMBuilderRef, Block: LLVMBasicBlockRef); + pub fn LLVMGetInsertBlock(Builder: LLVMBuilderRef) -> LLVMBasicBlockRef; + pub fn LLVMClearInsertionPosition(Builder: LLVMBuilderRef); + pub fn LLVMInsertIntoBuilder(Builder: LLVMBuilderRef, Instr: LLVMValueRef); + pub fn LLVMInsertIntoBuilderWithName( + Builder: LLVMBuilderRef, + Instr: LLVMValueRef, + Name: *const ::libc::c_char, + ); + pub fn LLVMDisposeBuilder(Builder: LLVMBuilderRef); + + // Metadata + /// Get location information used by debugging information. + pub fn LLVMGetCurrentDebugLocation2(Builder: LLVMBuilderRef) -> LLVMMetadataRef; + /// Set location information used by debugging information. + pub fn LLVMSetCurrentDebugLocation2(Builder: LLVMBuilderRef, Loc: LLVMMetadataRef); + /// Attempts to set the debug location for the given instruction using the + /// current debug location for the given builder. If the builder has no current + /// debug location, this function is a no-op. + #[deprecated( + since = "14.0", + note = "Deprecated in favor of the more general LLVMAddMetadataToInst." + )] + pub fn LLVMSetInstDebugLocation(Builder: LLVMBuilderRef, Inst: LLVMValueRef); + /// Adds the metadata registered with the given builder to the given instruction. + pub fn LLVMAddMetadataToInst(Builder: LLVMBuilderRef, Inst: LLVMValueRef); + /// Get the dafult floating-point math metadata for a given builder. + pub fn LLVMBuilderGetDefaultFPMathTag(Builder: LLVMBuilderRef) -> LLVMMetadataRef; + /// Set the default floating-point math metadata for the given builder. + pub fn LLVMBuilderSetDefaultFPMathTag(Builder: LLVMBuilderRef, FPMathTag: LLVMMetadataRef); + #[deprecated(since = "LLVM 9.0", note = "Use LLVMGetCurrentDebugLocation2 instead.")] + pub fn LLVMSetCurrentDebugLocation(Builder: LLVMBuilderRef, L: LLVMValueRef); + pub fn LLVMGetCurrentDebugLocation(Builder: LLVMBuilderRef) -> LLVMValueRef; + + // Terminators + pub fn LLVMBuildRetVoid(arg1: LLVMBuilderRef) -> LLVMValueRef; + pub fn LLVMBuildRet(arg1: LLVMBuilderRef, V: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMBuildAggregateRet( + arg1: LLVMBuilderRef, + RetVals: *mut LLVMValueRef, + N: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMBuildBr(arg1: LLVMBuilderRef, Dest: LLVMBasicBlockRef) -> LLVMValueRef; + pub fn LLVMBuildCondBr( + arg1: LLVMBuilderRef, + If: LLVMValueRef, + Then: LLVMBasicBlockRef, + Else: LLVMBasicBlockRef, + ) -> LLVMValueRef; + pub fn LLVMBuildSwitch( + arg1: LLVMBuilderRef, + V: LLVMValueRef, + Else: LLVMBasicBlockRef, + NumCases: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMBuildIndirectBr( + B: LLVMBuilderRef, + Addr: LLVMValueRef, + NumDests: ::libc::c_uint, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildInvoke2 instead to support opaque pointers." + )] + pub fn LLVMBuildInvoke( + arg1: LLVMBuilderRef, + Fn: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Then: LLVMBasicBlockRef, + Catch: LLVMBasicBlockRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildInvoke2( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Fn: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Then: LLVMBasicBlockRef, + Catch: LLVMBasicBlockRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildUnreachable(B: LLVMBuilderRef) -> LLVMValueRef; + + pub fn LLVMBuildResume(B: LLVMBuilderRef, Exn: LLVMValueRef) -> LLVMValueRef; + pub fn LLVMBuildLandingPad( + B: LLVMBuilderRef, + Ty: LLVMTypeRef, + PersFn: LLVMValueRef, + NumClauses: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildCleanupRet( + B: LLVMBuilderRef, + CatchPad: LLVMValueRef, + BB: LLVMBasicBlockRef, + ) -> LLVMValueRef; + pub fn LLVMBuildCatchRet( + B: LLVMBuilderRef, + CatchPad: LLVMValueRef, + BB: LLVMBasicBlockRef, + ) -> LLVMValueRef; + pub fn LLVMBuildCatchPad( + B: LLVMBuilderRef, + ParentPad: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildCleanupPad( + B: LLVMBuilderRef, + ParentPad: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildCatchSwitch( + B: LLVMBuilderRef, + ParentPad: LLVMValueRef, + UnwindBB: LLVMBasicBlockRef, + NumHandler: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + + /// Add a case to a `switch` instruction + pub fn LLVMAddCase(Switch: LLVMValueRef, OnVal: LLVMValueRef, Dest: LLVMBasicBlockRef); + + /// Add a destination to an `indirectbr` instruction + pub fn LLVMAddDestination(IndirectBr: LLVMValueRef, Dest: LLVMBasicBlockRef); + + /// Get the number of clauses on a landingpad instruction. + pub fn LLVMGetNumClauses(LandingPad: LLVMValueRef) -> ::libc::c_uint; + + /// Get the value of the clause with the given index on a landingpad instruction. + pub fn LLVMGetClause(LandingPad: LLVMValueRef, Idx: ::libc::c_uint) -> LLVMValueRef; + + /// Add a catch or filter clause to a `landingpad` instruction + pub fn LLVMAddClause(LandingPad: LLVMValueRef, ClauseVal: LLVMValueRef); + + /// Get the cleanup flag in a landingpad instruction. + pub fn LLVMIsCleanup(LandingPad: LLVMValueRef) -> LLVMBool; + + /// Set the cleanup flag in a `landingpad` instruction. + pub fn LLVMSetCleanup(LandingPad: LLVMValueRef, Val: LLVMBool); + + /// Add a destination to the catchswitch instruction + pub fn LLVMAddHandler(CatchSwitch: LLVMValueRef, Dest: LLVMBasicBlockRef); + + /// Get the number of handlers on the catchswitch instruction + pub fn LLVMGetNumHandlers(CatchSwitch: LLVMValueRef) -> ::libc::c_uint; + + /// Obtain the basic blocks acting as handlers for a catchswitch instruction. + /// + /// The Handlers parameter should point to a pre-allocated array of LLVMBasicBlockRefs at least LLVMGetNumHandlers() large. On return, the first LLVMGetNumHandlers() entries in the array will be populated with LLVMBasicBlockRef instances. + pub fn LLVMGetHandlers(CatchSwitch: LLVMValueRef, Handlers: *mut LLVMBasicBlockRef); + + // Funclets + /// Get the number of funcletpad arguments. + pub fn LLVMGetArgOperand(Funclet: LLVMValueRef, i: ::libc::c_uint) -> LLVMValueRef; + + /// Set a funcletpad argument at the given index. + pub fn LLVMSetArgOperand(Funclet: LLVMValueRef, i: ::libc::c_uint, value: LLVMValueRef); + + /// Get the parent catchswitch instruction of a catchpad instruction. + /// + /// This only works on llvm::CatchPadInst instructions. + pub fn LLVMGetParentCatchSwitch(CatchPad: LLVMValueRef) -> LLVMValueRef; + + /// Set the parent catchswitch instruction of a catchpad instruction. + /// This only works on llvm::CatchPadInst instructions. + pub fn LLVMSetParentCatchSwitch(CatchPad: LLVMValueRef, CatchSwitch: LLVMValueRef); + + // Arithmetic + pub fn LLVMBuildAdd( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNSWAdd( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNUWAdd( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFAdd( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSub( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNSWSub( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNUWSub( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFSub( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildMul( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNSWMul( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNUWMul( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFMul( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildUDiv( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildExactUDiv( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSDiv( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildExactSDiv( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFDiv( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildURem( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSRem( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFRem( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildShl( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildLShr( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildAShr( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildAnd( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildOr( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildXor( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildBinOp( + B: LLVMBuilderRef, + Op: LLVMOpcode, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNeg( + arg1: LLVMBuilderRef, + V: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNSWNeg( + B: LLVMBuilderRef, + V: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNUWNeg( + B: LLVMBuilderRef, + V: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFNeg( + arg1: LLVMBuilderRef, + V: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildNot( + arg1: LLVMBuilderRef, + V: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + + // Memory + pub fn LLVMBuildMalloc( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildArrayMalloc( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Val: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildMemSet( + B: LLVMBuilderRef, + Ptr: LLVMValueRef, + Val: LLVMValueRef, + Len: LLVMValueRef, + Align: ::libc::c_uint, + ) -> LLVMValueRef; + pub fn LLVMBuildMemCpy( + B: LLVMBuilderRef, + Dst: LLVMValueRef, + DstAlign: ::libc::c_uint, + Src: LLVMValueRef, + SrcAlign: ::libc::c_uint, + Size: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMBuildMemMove( + B: LLVMBuilderRef, + Dst: LLVMValueRef, + DstAlign: ::libc::c_uint, + Src: LLVMValueRef, + SrcAlign: ::libc::c_uint, + Size: LLVMValueRef, + ) -> LLVMValueRef; + pub fn LLVMBuildAlloca( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildArrayAlloca( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Val: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFree(arg1: LLVMBuilderRef, PointerVal: LLVMValueRef) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildLoad2 instead to support opaque pointers." + )] + pub fn LLVMBuildLoad( + arg1: LLVMBuilderRef, + PointerVal: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildLoad2( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + PointerVal: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildStore( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + Ptr: LLVMValueRef, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildGEP2 instead to support opaque pointers." + )] + pub fn LLVMBuildGEP( + B: LLVMBuilderRef, + Pointer: LLVMValueRef, + Indices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildInBoundsGEP2 instead to support opaque pointers." + )] + pub fn LLVMBuildInBoundsGEP( + B: LLVMBuilderRef, + Pointer: LLVMValueRef, + Indices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildStructGEP2 instead to support opaque pointers." + )] + pub fn LLVMBuildStructGEP( + B: LLVMBuilderRef, + Pointer: LLVMValueRef, + Idx: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildGEP2( + B: LLVMBuilderRef, + Ty: LLVMTypeRef, + Pointer: LLVMValueRef, + Indices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildInBoundsGEP2( + B: LLVMBuilderRef, + Ty: LLVMTypeRef, + Pointer: LLVMValueRef, + Indices: *mut LLVMValueRef, + NumIndices: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildStructGEP2( + B: LLVMBuilderRef, + Ty: LLVMTypeRef, + Pointer: LLVMValueRef, + Idx: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildGlobalString( + B: LLVMBuilderRef, + Str: *const ::libc::c_char, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildGlobalStringPtr( + B: LLVMBuilderRef, + Str: *const ::libc::c_char, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMGetVolatile(MemoryAccessInst: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetVolatile(MemoryAccessInst: LLVMValueRef, IsVolatile: LLVMBool); + pub fn LLVMGetWeak(CmpXchgInst: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetWeak(CmpXchgInst: LLVMValueRef, IsWeak: LLVMBool); + pub fn LLVMGetOrdering(MemoryAccessInst: LLVMValueRef) -> LLVMAtomicOrdering; + pub fn LLVMSetOrdering(MemoryAccessInst: LLVMValueRef, Ordering: LLVMAtomicOrdering); + pub fn LLVMGetAtomicRMWBinOp(AtomicRMWInst: LLVMValueRef) -> LLVMAtomicRMWBinOp; + pub fn LLVMSetAtomicRMWBinOp(AtomicRMWInst: LLVMValueRef, BinOp: LLVMAtomicRMWBinOp); + + // Casts + pub fn LLVMBuildTrunc( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildZExt( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSExt( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFPToUI( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFPToSI( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildUIToFP( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSIToFP( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFPTrunc( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFPExt( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildPtrToInt( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildIntToPtr( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildBitCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildAddrSpaceCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildZExtOrBitCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSExtOrBitCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildTruncOrBitCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildCast( + B: LLVMBuilderRef, + Op: LLVMOpcode, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildPointerCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildIntCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildIntCast2( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + IsSigned: LLVMBool, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFPCast( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + DestTy: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMGetCastOpcode( + arg1: LLVMValueRef, + SrcIsSigned: LLVMBool, + DestTy: LLVMTypeRef, + DestIsSigned: LLVMBool, + ) -> LLVMOpcode; + + // Comparisons + pub fn LLVMBuildICmp( + arg1: LLVMBuilderRef, + Op: LLVMIntPredicate, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFCmp( + arg1: LLVMBuilderRef, + Op: LLVMRealPredicate, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + + // Miscellaneous instructions + pub fn LLVMBuildPhi( + arg1: LLVMBuilderRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildCall2 instead to support opaque pointers." + )] + pub fn LLVMBuildCall( + arg1: LLVMBuilderRef, + Fn: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildCall2( + arg1: LLVMBuilderRef, + arg2: LLVMTypeRef, + Fn: LLVMValueRef, + Args: *mut LLVMValueRef, + NumArgs: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildSelect( + arg1: LLVMBuilderRef, + If: LLVMValueRef, + Then: LLVMValueRef, + Else: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildVAArg( + arg1: LLVMBuilderRef, + List: LLVMValueRef, + Ty: LLVMTypeRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildExtractElement( + arg1: LLVMBuilderRef, + VecVal: LLVMValueRef, + Index: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildInsertElement( + arg1: LLVMBuilderRef, + VecVal: LLVMValueRef, + EltVal: LLVMValueRef, + Index: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildShuffleVector( + arg1: LLVMBuilderRef, + V1: LLVMValueRef, + V2: LLVMValueRef, + Mask: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildExtractValue( + arg1: LLVMBuilderRef, + AggVal: LLVMValueRef, + Index: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildInsertValue( + arg1: LLVMBuilderRef, + AggVal: LLVMValueRef, + EltVal: LLVMValueRef, + Index: ::libc::c_uint, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFreeze( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildIsNull( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildIsNotNull( + arg1: LLVMBuilderRef, + Val: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + #[deprecated( + since = "14.0", + note = "Use LLVMBuildPtrDiff2 instead to support opaque pointers." + )] + pub fn LLVMBuildPtrDiff( + arg1: LLVMBuilderRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildPtrDiff2( + arg1: LLVMBuilderRef, + ElemTy: LLVMTypeRef, + LHS: LLVMValueRef, + RHS: LLVMValueRef, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildFence( + B: LLVMBuilderRef, + ordering: LLVMAtomicOrdering, + singleThread: LLVMBool, + Name: *const ::libc::c_char, + ) -> LLVMValueRef; + pub fn LLVMBuildAtomicRMW( + B: LLVMBuilderRef, + op: LLVMAtomicRMWBinOp, + PTR: LLVMValueRef, + Val: LLVMValueRef, + ordering: LLVMAtomicOrdering, + singleThread: LLVMBool, + ) -> LLVMValueRef; + pub fn LLVMBuildAtomicCmpXchg( + B: LLVMBuilderRef, + Ptr: LLVMValueRef, + Cmp: LLVMValueRef, + New: LLVMValueRef, + SuccessOrdering: LLVMAtomicOrdering, + FailureOrdering: LLVMAtomicOrdering, + SingleThread: LLVMBool, + ) -> LLVMValueRef; + pub fn LLVMGetNumMaskElements(ShuffleVectorInst: LLVMValueRef) -> ::libc::c_uint; + pub fn LLVMGetUndefMaskElem() -> ::libc::c_int; + pub fn LLVMGetMaskValue(ShuffleVectorInst: LLVMValueRef, Elt: ::libc::c_uint) -> ::libc::c_int; + pub fn LLVMIsAtomicSingleThread(AtomicInst: LLVMValueRef) -> LLVMBool; + pub fn LLVMSetAtomicSingleThread(AtomicInst: LLVMValueRef, SingleThread: LLVMBool); + pub fn LLVMGetCmpXchgSuccessOrdering(CmpXchgInst: LLVMValueRef) -> LLVMAtomicOrdering; + pub fn LLVMSetCmpXchgSuccessOrdering(CmpXchgInst: LLVMValueRef, Ordering: LLVMAtomicOrdering); + pub fn LLVMGetCmpXchgFailureOrdering(CmpXchgInst: LLVMValueRef) -> LLVMAtomicOrdering; + pub fn LLVMSetCmpXchgFailureOrdering(CmpXchgInst: LLVMValueRef, Ordering: LLVMAtomicOrdering); +} + +// Core->Module Providers +extern "C" { + pub fn LLVMCreateModuleProviderForExistingModule(M: LLVMModuleRef) -> LLVMModuleProviderRef; + pub fn LLVMDisposeModuleProvider(M: LLVMModuleProviderRef); +} + +// Core->Memory Buffers +extern "C" { + pub fn LLVMCreateMemoryBufferWithContentsOfFile( + Path: *const ::libc::c_char, + OutMemBuf: *mut LLVMMemoryBufferRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMCreateMemoryBufferWithSTDIN( + OutMemBuf: *mut LLVMMemoryBufferRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMCreateMemoryBufferWithMemoryRange( + InputData: *const ::libc::c_char, + InputDataLength: ::libc::size_t, + BufferName: *const ::libc::c_char, + RequiresNullTerminator: LLVMBool, + ) -> LLVMMemoryBufferRef; + pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy( + InputData: *const ::libc::c_char, + InputDataLength: ::libc::size_t, + BufferName: *const ::libc::c_char, + ) -> LLVMMemoryBufferRef; + pub fn LLVMGetBufferStart(MemBuf: LLVMMemoryBufferRef) -> *const ::libc::c_char; + pub fn LLVMGetBufferSize(MemBuf: LLVMMemoryBufferRef) -> ::libc::size_t; + pub fn LLVMDisposeMemoryBuffer(MemBuf: LLVMMemoryBufferRef); +} + +// Core->pass registry +extern "C" { + pub fn LLVMGetGlobalPassRegistry() -> LLVMPassRegistryRef; +} + +// Core->Pass managers +extern "C" { + pub fn LLVMCreatePassManager() -> LLVMPassManagerRef; + pub fn LLVMCreateFunctionPassManagerForModule(M: LLVMModuleRef) -> LLVMPassManagerRef; + pub fn LLVMCreateFunctionPassManager(MP: LLVMModuleProviderRef) -> LLVMPassManagerRef; + pub fn LLVMRunPassManager(PM: LLVMPassManagerRef, M: LLVMModuleRef) -> LLVMBool; + pub fn LLVMInitializeFunctionPassManager(FPM: LLVMPassManagerRef) -> LLVMBool; + pub fn LLVMRunFunctionPassManager(FPM: LLVMPassManagerRef, F: LLVMValueRef) -> LLVMBool; + pub fn LLVMFinalizeFunctionPassManager(FPM: LLVMPassManagerRef) -> LLVMBool; + pub fn LLVMDisposePassManager(PM: LLVMPassManagerRef); +} + +// Core->Threading +extern "C" { + /// Deprecated: LLVM threading is configured at compile-time with `LLVM_ENABLE_THREADS` + pub fn LLVMStartMultithreaded() -> LLVMBool; + /// Deprecated: LLVM threading is configured at compile-time with `LLVM_ENABLE_THREADS` + pub fn LLVMStopMultithreaded(); + pub fn LLVMIsMultithreaded() -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/debuginfo.rs b/ext/llvm-sys.rs/src/debuginfo.rs new file mode 100644 index 0000000..ba906d9 --- /dev/null +++ b/ext/llvm-sys.rs/src/debuginfo.rs @@ -0,0 +1,880 @@ +//! Generation of DWARF debug info. +use super::*; + +// Debug info flags. +pub type LLVMDIFlags = ::libc::c_int; +pub const LLVMDIFlagZero: LLVMDIFlags = 0; +pub const LLVMDIFlagPrivate: LLVMDIFlags = 1; +pub const LLVMDIFlagProtected: LLVMDIFlags = 2; +pub const LLVMDIFlagPublic: LLVMDIFlags = 3; +pub const LLVMDIFlagFwdDecl: LLVMDIFlags = 1 << 2; +pub const LLVMDIFlagAppleBlock: LLVMDIFlags = 1 << 3; +pub const LLVMDIFlagReservedBit4: LLVMDIFlags = 1 << 4; +pub const LLVMDIFlagVirtual: LLVMDIFlags = 1 << 5; +pub const LLVMDIFlagArtificial: LLVMDIFlags = 1 << 6; +pub const LLVMDIFlagExplicit: LLVMDIFlags = 1 << 7; +pub const LLVMDIFlagPrototyped: LLVMDIFlags = 1 << 8; +pub const LLVMDIFlagObjcClassComplete: LLVMDIFlags = 1 << 9; +pub const LLVMDIFlagObjectPointer: LLVMDIFlags = 1 << 10; +pub const LLVMDIFlagVector: LLVMDIFlags = 1 << 11; +pub const LLVMDIFlagStaticMember: LLVMDIFlags = 1 << 12; +pub const LLVMDIFlagLValueReference: LLVMDIFlags = 1 << 13; +pub const LLVMDIFlagRValueReference: LLVMDIFlags = 1 << 14; +pub const LLVMDIFlagReserved: LLVMDIFlags = 1 << 15; +pub const LLVMDIFlagSingleInheritance: LLVMDIFlags = 1 << 16; +pub const LLVMDIFlagMultipleInheritance: LLVMDIFlags = 2 << 16; +pub const LLVMDIFlagVirtualInheritance: LLVMDIFlags = 3 << 16; +pub const LLVMDIFlagIntroducedVirtual: LLVMDIFlags = 1 << 18; +pub const LLVMDIFlagBitField: LLVMDIFlags = 1 << 19; +pub const LLVMDIFlagNoReturn: LLVMDIFlags = 1 << 20; +pub const LLVMDIFlagTypePassByValue: LLVMDIFlags = 1 << 22; +pub const LLVMDIFlagTypePassByReference: LLVMDIFlags = 1 << 23; +pub const LLVMDIFlagEnumClass: LLVMDIFlags = 1 << 24; +pub const LLVMDIFlagThunk: LLVMDIFlags = 1 << 25; +pub const LLVMDIFlagNonTrivial: LLVMDIFlags = 1 << 26; +pub const LLVMDIFlagBigendian: LLVMDIFlags = 1 << 27; +pub const LLVMDIFlagLittleEndian: LLVMDIFlags = 1 << 28; +pub const LLVMDIFlagIndirectVirtualBase: LLVMDIFlags = (1 << 2) | (1 << 5); +pub const LLVMDIFlagAccessibility: LLVMDIFlags = + LLVMDIFlagProtected | LLVMDIFlagPrivate | LLVMDIFlagPublic; +pub const LLVMDIFlagPtrToMemberRep: LLVMDIFlags = + LLVMDIFlagSingleInheritance | LLVMDIFlagMultipleInheritance | LLVMDIFlagVirtualInheritance; + +/// Source languages known by DWARF. +#[repr(C)] +#[derive(Debug)] +pub enum LLVMDWARFSourceLanguage { + LLVMDWARFSourceLanguageC89, + LLVMDWARFSourceLanguageC, + LLVMDWARFSourceLanguageAda83, + LLVMDWARFSourceLanguageC_plus_plus, + LLVMDWARFSourceLanguageCobol74, + LLVMDWARFSourceLanguageCobol85, + LLVMDWARFSourceLanguageFortran77, + LLVMDWARFSourceLanguageFortran90, + LLVMDWARFSourceLanguagePascal83, + LLVMDWARFSourceLanguageModula2, + // New in DWARF v3: + LLVMDWARFSourceLanguageJava, + LLVMDWARFSourceLanguageC99, + LLVMDWARFSourceLanguageAda95, + LLVMDWARFSourceLanguageFortran95, + LLVMDWARFSourceLanguagePLI, + LLVMDWARFSourceLanguageObjC, + LLVMDWARFSourceLanguageObjC_plus_plus, + LLVMDWARFSourceLanguageUPC, + LLVMDWARFSourceLanguageD, + // New in DWARF v4: + LLVMDWARFSourceLanguagePython, + // New in DWARF v5: + LLVMDWARFSourceLanguageOpenCL, + LLVMDWARFSourceLanguageGo, + LLVMDWARFSourceLanguageModula3, + LLVMDWARFSourceLanguageHaskell, + LLVMDWARFSourceLanguageC_plus_plus_03, + LLVMDWARFSourceLanguageC_plus_plus_11, + LLVMDWARFSourceLanguageOCaml, + LLVMDWARFSourceLanguageRust, + LLVMDWARFSourceLanguageC11, + LLVMDWARFSourceLanguageSwift, + LLVMDWARFSourceLanguageJulia, + LLVMDWARFSourceLanguageDylan, + LLVMDWARFSourceLanguageC_plus_plus_14, + LLVMDWARFSourceLanguageFortran03, + LLVMDWARFSourceLanguageFortran08, + LLVMDWARFSourceLanguageRenderScript, + LLVMDWARFSourceLanguageBLISS, + // Vendor extensions: + LLVMDWARFSourceLanguageMips_Assembler, + LLVMDWARFSourceLanguageGOOGLE_RenderScript, + LLVMDWARFSourceLanguageBORLAND_Delphi, +} + +/// The amount of debug information to emit. +#[repr(C)] +#[derive(Debug)] +pub enum LLVMDWARFEmissionKind { + LLVMDWARFEmissionKindNone = 0, + LLVMDWARFEmissionKindFull, + LLVMDWARFEmissionKindLineTablesOnly, +} + +#[repr(C)] +#[derive(Debug)] +pub enum LLVMMetadataKind { + LLVMMDStringMetadataKind, + LLVMConstantAsMetadataMetadataKind, + LLVMLocalAsMetadataMetadataKind, + LLVMDistinctMDOperandPlaceholderMetadataKind, + LLVMMDTupleMetadataKind, + LLVMDILocationMetadataKind, + LLVMDIExpressionMetadataKind, + LLVMDIGlobalVariableExpressionMetadataKind, + LLVMGenericDINodeMetadataKind, + LLVMDISubrangeMetadataKind, + LLVMDIEnumeratorMetadataKind, + LLVMDIBasicTypeMetadataKind, + LLVMDIDerivedTypeMetadataKind, + LLVMDICompositeTypeMetadataKind, + LLVMDISubroutineTypeMetadataKind, + LLVMDIFileMetadataKind, + LLVMDICompileUnitMetadataKind, + LLVMDISubprogramMetadataKind, + LLVMDILexicalBlockMetadataKind, + LLVMDILexicalBlockFileMetadataKind, + LLVMDINamespaceMetadataKind, + LLVMDIModuleMetadataKind, + LLVMDITemplateTypeParameterMetadataKind, + LLVMDITemplateValueParameterMetadataKind, + LLVMDIGlobalVariableMetadataKind, + LLVMDILocalVariableMetadataKind, + LLVMDILabelMetadataKind, + LLVMDIObjCPropertyMetadataKind, + LLVMDIImportedEntityMetadataKind, + LLVMDIMacroMetadataKind, + LLVMDIMacroFileMetadataKind, + LLVMDICommonBlockMetadataKind, + LLVMDIStringTypeMetadataKind, + LLVMDIGenericSubrangeMetadataKind, + LLVMDIArgListMetadataKind, +} + +pub type LLVMDWARFTypeEncoding = ::libc::c_uint; + +#[repr(C)] +#[derive(Debug)] +pub enum LLVMDWARFMacinfoRecordType { + LLVMDWARFMacinfoRecordTypeDefine = 0x01, + LLVMDWARFMacinfoRecordTypeMacro = 0x02, + LLVMDWARFMacinfoRecordTypeStartFile = 0x03, + LLVMDWARFMacinfoRecordTypeEndFile = 0x04, + LLVMDWARFMacinfoRecordTypeVendorExt = 0xff, +} + +extern "C" { + /// The current debug metadata version number. + pub fn LLVMDebugMetadataVersion() -> ::libc::c_uint; + /// The version of debug metadata that's present in the provided Module. + pub fn LLVMGetModuleDebugMetadataVersion(Module: LLVMModuleRef) -> ::libc::c_uint; + /// Strip debug info in the module if it exists. + pub fn LLVMStripModuleDebugInfo(Module: LLVMModuleRef) -> LLVMBool; + /// Construct a builder for a module, do not allow unresolved nodes. + pub fn LLVMCreateDIBuilderDisallowUnresolved(M: LLVMModuleRef) -> LLVMDIBuilderRef; + /// Construct a builder for a module and collect unresolved nodes. + pub fn LLVMCreateDIBuilder(M: LLVMModuleRef) -> LLVMDIBuilderRef; + /// Deallocate a builder and everything it owns. + /// + /// The builder must be finalized before this. + pub fn LLVMDisposeDIBuilder(Builder: LLVMDIBuilderRef); + /// Construct any deferred debug info descriptors. + pub fn LLVMDIBuilderFinalize(Builder: LLVMDIBuilderRef); + /// Finalize a specific subprogram. + /// No new variables may be added to this subprogram afterwards. + pub fn LLVMDIBuilderFinalizeSubprogram(Builder: LLVMDIBuilderRef, Subprogram: LLVMMetadataRef); + pub fn LLVMDIBuilderCreateCompileUnit( + Builder: LLVMDIBuilderRef, + Lang: LLVMDWARFSourceLanguage, + FileRef: LLVMMetadataRef, + Producer: *const ::libc::c_char, + ProducerLen: ::libc::size_t, + isOptimized: LLVMBool, + Flags: *const ::libc::c_char, + FlagsLen: ::libc::size_t, + RuntimeVer: ::libc::c_uint, + SplitName: *const ::libc::c_char, + SplitNameLen: ::libc::size_t, + Kind: LLVMDWARFEmissionKind, + DWOId: ::libc::c_uint, + SplitDebugInlining: LLVMBool, + DebugInfoForProfiling: LLVMBool, + SysRoot: *const ::libc::c_char, + SysRootLen: ::libc::size_t, + SDK: *const ::libc::c_char, + SDKLen: ::libc::size_t, + ) -> LLVMMetadataRef; + /// Create a file descriptor to hold debugging information for a file. + pub fn LLVMDIBuilderCreateFile( + Builder: LLVMDIBuilderRef, + Filename: *const ::libc::c_char, + FilenameLen: ::libc::size_t, + Directory: *const ::libc::c_char, + DirectoryLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Creates a new descriptor for a module with the specified parent scope. + pub fn LLVMDIBuilderCreateModule( + Builder: LLVMDIBuilderRef, + ParentScope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ConfigMacros: *const ::libc::c_char, + ConfigMacrosLen: ::libc::size_t, + IncludePath: *const ::libc::c_char, + IncludePathLen: ::libc::size_t, + APINotesFile: *const ::libc::c_char, + APINotesFileLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Creates a new descriptor for a namespace with the specified parent scope. + pub fn LLVMDIBuilderCreateNameSpace( + Builder: LLVMDIBuilderRef, + ParentScope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ExportSymbols: LLVMBool, + ) -> LLVMMetadataRef; + + /// Create a new descriptor for the specified subprogram. + pub fn LLVMDIBuilderCreateFunction( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + LinkageName: *const ::libc::c_char, + LinkageNameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Ty: LLVMMetadataRef, + IsLocalToUnit: LLVMBool, + IsDefinition: LLVMBool, + ScopeLine: ::libc::c_uint, + Flags: LLVMDIFlags, + IsOptimized: LLVMBool, + ) -> LLVMMetadataRef; + + /// Create a descriptor for a lexical block with the specified parent context. + pub fn LLVMDIBuilderCreateLexicalBlock( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + Column: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a descriptor for a lexical block with a new file attached. + pub fn LLVMDIBuilderCreateLexicalBlockFile( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + File: LLVMMetadataRef, + Discriminator: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a descriptor for an imported namespace. Suitable for e.g. C++ using declarations. + pub fn LLVMDIBuilderCreateImportedModuleFromNamespace( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + NS: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a descriptor for an imported module that aliases another imported entity descriptor. + pub fn LLVMDIBuilderCreateImportedModuleFromAlias( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + ImportedEntity: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a descriptor for an imported module. + pub fn LLVMDIBuilderCreateImportedModuleFromModule( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + M: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a descriptor for an imported function, type, or variable. + /// + /// Suitable for e.g. FORTRAN-style USE declarations. + pub fn LLVMDIBuilderCreateImportedDeclaration( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Decl: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Creates a new DebugLocation that describes a source location. + pub fn LLVMDIBuilderCreateDebugLocation( + Ctx: LLVMContextRef, + Line: ::libc::c_uint, + Column: ::libc::c_uint, + Scope: LLVMMetadataRef, + InlinedAt: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Get the line number of this debug location. + pub fn LLVMDILocationGetLine(Location: LLVMMetadataRef) -> ::libc::c_uint; + + /// Get the column number of this debug location. + pub fn LLVMDILocationGetColumn(Location: LLVMMetadataRef) -> ::libc::c_uint; + + /// Get the local scope associated with this debug location. + pub fn LLVMDILocationGetScope(Location: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Get the "inline at" location associated with this debug location. + pub fn LLVMDILocationGetInlinedAt(Location: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Get the metadata of the file associated with a given scope. + pub fn LLVMDIScopeGetFile(Scope: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Get the directory of a given file. + pub fn LLVMDIFileGetDirectory( + File: LLVMMetadataRef, + Len: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + + /// Get the name of a given file. + pub fn LLVMDIFileGetFilename( + File: LLVMMetadataRef, + Len: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + + /// Get the source of a given file. + pub fn LLVMDIFileGetSource( + File: LLVMMetadataRef, + Len: *mut ::libc::c_uint, + ) -> *const ::libc::c_char; + + /// Create a type array. + pub fn LLVMDIBuilderGetOrCreateTypeArray( + Builder: LLVMDIBuilderRef, + Data: *mut LLVMMetadataRef, + NumElements: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create subroutine type. + pub fn LLVMDIBuilderCreateSubroutineType( + Builder: LLVMDIBuilderRef, + File: LLVMMetadataRef, + ParameterTypes: *mut LLVMMetadataRef, + NumParameterTypes: ::libc::c_uint, + Flags: LLVMDIFlags, + ) -> LLVMMetadataRef; + + pub fn LLVMDIBuilderCreateMacro( + Builder: LLVMDIBuilderRef, + ParentMacroFile: LLVMMetadataRef, + Line: ::libc::c_uint, + RecordType: LLVMDWARFMacinfoRecordType, + Name: *const ::libc::c_char, + NameLen: usize, + Value: *const ::libc::c_char, + ValueLen: usize, + ) -> LLVMMetadataRef; + + pub fn LLVMDIBuilderCreateTempMacroFile( + Builder: LLVMDIBuilderRef, + ParentMacroFile: LLVMMetadataRef, + Line: ::libc::c_uint, + File: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for an enumerator. + pub fn LLVMDIBuilderCreateEnumerator( + Builder: LLVMDIBuilderRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Value: i64, + IsUnsigned: LLVMBool, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for an enumeration. + pub fn LLVMDIBuilderCreateEnumerationType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + ClassTy: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a union. + pub fn LLVMDIBuilderCreateUnionType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: LLVMDIFlags, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + RunTimeLang: ::libc::c_uint, + UniqueId: *const ::libc::c_char, + UniqueIdLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for an array. + pub fn LLVMDIBuilderCreateArrayType( + Builder: LLVMDIBuilderRef, + Size: u64, + AlignInBits: u32, + Ty: LLVMMetadataRef, + Subscripts: *mut LLVMMetadataRef, + NumSubscripts: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a vector type. + pub fn LLVMDIBuilderCreateVectorType( + Builder: LLVMDIBuilderRef, + Size: u64, + AlignInBits: u32, + Ty: LLVMMetadataRef, + Subscripts: *mut LLVMMetadataRef, + NumSubscripts: ::libc::c_uint, + ) -> LLVMMetadataRef; + + /// Create a DWARF unspecified type. + pub fn LLVMDIBuilderCreateUnspecifiedType( + Builder: LLVMDIBuilderRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a basic type. + pub fn LLVMDIBuilderCreateBasicType( + Builder: LLVMDIBuilderRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + SizeInBits: u64, + Encoding: LLVMDWARFTypeEncoding, + Flags: LLVMDIFlags, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a pointer. + pub fn LLVMDIBuilderCreatePointerType( + Builder: LLVMDIBuilderRef, + PointeeTy: LLVMMetadataRef, + SizeInBits: u64, + AlignInBits: u32, + AddressSpace: ::libc::c_uint, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a struct. + pub fn LLVMDIBuilderCreateStructType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: LLVMDIFlags, + DerivedFrom: LLVMMetadataRef, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + RunTimeLang: ::libc::c_uint, + VTableHolder: LLVMMetadataRef, + UniqueId: *const ::libc::c_char, + UniqueIdLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a member. + pub fn LLVMDIBuilderCreateMemberType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: LLVMDIFlags, + Ty: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a C++ static data member. + pub fn LLVMDIBuilderCreateStaticMemberType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + Type: LLVMMetadataRef, + Flags: LLVMDIFlags, + ConstantVal: LLVMValueRef, + AlignInBits: u32, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a pointer to member. + pub fn LLVMDIBuilderCreateMemberPointerType( + Builder: LLVMDIBuilderRef, + PointeeType: LLVMMetadataRef, + ClassType: LLVMMetadataRef, + SizeInBits: u64, + AlignInBits: u32, + Flags: LLVMDIFlags, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for Objective-C instance variable. + pub fn LLVMDIBuilderCreateObjCIVar( + Builder: LLVMDIBuilderRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: LLVMDIFlags, + Ty: LLVMMetadataRef, + PropertyNode: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for Objective-C property. + pub fn LLVMDIBuilderCreateObjCProperty( + Builder: LLVMDIBuilderRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + GetterName: *const ::libc::c_char, + GetterNameLen: ::libc::size_t, + SetterName: *const ::libc::c_char, + SetterNameLen: ::libc::size_t, + PropertyAttributes: ::libc::c_uint, + Ty: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set. + pub fn LLVMDIBuilderCreateObjectPointerType( + Builder: LLVMDIBuilderRef, + Type: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a qualified type, e.g. 'const int'. + pub fn LLVMDIBuilderCreateQualifiedType( + Builder: LLVMDIBuilderRef, + Tag: ::libc::c_uint, + Type: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a c++ style reference or rvalue reference type. + pub fn LLVMDIBuilderCreateReferenceType( + Builder: LLVMDIBuilderRef, + Tag: ::libc::c_uint, + Type: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create C++11 nullptr type. + pub fn LLVMDIBuilderCreateNullPtrType(Builder: LLVMDIBuilderRef) -> LLVMMetadataRef; + + /// Create debugging information entry for a typedef. + pub fn LLVMDIBuilderCreateTypedef( + Builder: LLVMDIBuilderRef, + Type: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Scope: LLVMMetadataRef, + AlignInBits: u32, + ) -> LLVMMetadataRef; + + /// Create debugging information entry to establish inheritance relationship between two types. + pub fn LLVMDIBuilderCreateInheritance( + Builder: LLVMDIBuilderRef, + Ty: LLVMMetadataRef, + BaseTy: LLVMMetadataRef, + BaseOffset: u64, + VBPtrOffset: u32, + Flags: LLVMDIFlags, + ) -> LLVMMetadataRef; + + /// Create a permanent forward-declared type. + pub fn LLVMDIBuilderCreateForwardDecl( + Builder: LLVMDIBuilderRef, + Tag: ::libc::c_uint, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Scope: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + RuntimeLang: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + UniqueIdentifier: *const ::libc::c_char, + UniqueIdentifierLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create a temporary forward-declared type. + pub fn LLVMDIBuilderCreateReplaceableCompositeType( + Builder: LLVMDIBuilderRef, + Tag: ::libc::c_uint, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Scope: LLVMMetadataRef, + File: LLVMMetadataRef, + Line: ::libc::c_uint, + RuntimeLang: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: LLVMDIFlags, + UniqueIdentifier: *const ::libc::c_char, + UniqueIdentifierLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a bit field member. + pub fn LLVMDIBuilderCreateBitFieldMemberType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + SizeInBits: u64, + OffsetInBits: u64, + StorageOffsetInBits: u64, + Flags: LLVMDIFlags, + Type: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Create debugging information entry for a class. + pub fn LLVMDIBuilderCreateClassType( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNumber: ::libc::c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: LLVMDIFlags, + DerivedFrom: LLVMMetadataRef, + Elements: *mut LLVMMetadataRef, + NumElements: ::libc::c_uint, + VTableHolder: LLVMMetadataRef, + TemplateParamsNode: LLVMMetadataRef, + UniqueIdentifier: *const ::libc::c_char, + UniqueIdentifierLen: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create a uniqued DIType* clone with FlagArtificial set. + pub fn LLVMDIBuilderCreateArtificialType( + Builder: LLVMDIBuilderRef, + Type: LLVMMetadataRef, + ) -> LLVMMetadataRef; + + /// Get the name of this DIType. + pub fn LLVMDITypeGetName( + DType: LLVMMetadataRef, + Length: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + + /// Get the size of this DIType in bits. + pub fn LLVMDITypeGetSizeInBits(DType: LLVMMetadataRef) -> u64; + + /// Get the offset of this DIType in bits. + pub fn LLVMDITypeGetOffsetInBits(DType: LLVMMetadataRef) -> u64; + + /// Get the alignment of this DIType in bits. + pub fn LLVMDITypeGetAlignInBits(DType: LLVMMetadataRef) -> u32; + + /// Get the source line where this DIType is declared. + pub fn LLVMDITypeGetLine(DType: LLVMMetadataRef) -> ::libc::c_uint; + + /// Get the flags associated with this DIType. + pub fn LLVMDITypeGetFlags(DType: LLVMMetadataRef) -> LLVMDIFlags; + + /// Create a descriptor for a value range. + pub fn LLVMDIBuilderGetOrCreateSubrange( + Builder: LLVMDIBuilderRef, + LowerBound: i64, + Count: i64, + ) -> LLVMMetadataRef; + + /// Create an array of DI Nodes. + pub fn LLVMDIBuilderGetOrCreateArray( + Builder: LLVMDIBuilderRef, + Data: *mut LLVMMetadataRef, + NumElements: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create a new descriptor for the specified variable which has a complex + pub fn LLVMDIBuilderCreateExpression( + Builder: LLVMDIBuilderRef, + Addr: *mut u64, + Length: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Create a new descriptor for the specified variable that does not have an + pub fn LLVMDIBuilderCreateConstantValueExpression( + Builder: LLVMDIBuilderRef, + Value: u64, + ) -> LLVMMetadataRef; + + /// Create a new descriptor for the specified variable. + pub fn LLVMDIBuilderCreateGlobalVariableExpression( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Linkage: *const ::libc::c_char, + LinkLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Ty: LLVMMetadataRef, + LocalToUnit: LLVMBool, + Expr: LLVMMetadataRef, + Decl: LLVMMetadataRef, + AlignInBits: u32, + ) -> LLVMMetadataRef; + + /// Retrieves the DIVariable associated with this global variable expression. + pub fn LLVMDIGlobalVariableExpressionGetVariable(GVE: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Retrieves the DIExpression associated with this global variable expression. + pub fn LLVMDIGlobalVariableExpressionGetExpression(GVE: LLVMMetadataRef) -> LLVMMetadataRef; + + ///Get the metadata of the file associated with a given variable. + pub fn LLVMDIVariableGetFile(Var: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Get the metadata of the scope associated with a given variable. + pub fn LLVMDIVariableGetScope(Var: LLVMMetadataRef) -> LLVMMetadataRef; + + /// Get the source line where this \c DIVariable is declared. + pub fn LLVMDIVariableGetLine(Var: LLVMMetadataRef) -> ::libc::c_uint; + + /// Create a new temporary \c MDNode. Suitable for use in constructing cyclic + pub fn LLVMTemporaryMDNode( + Ctx: LLVMContextRef, + Data: *mut LLVMMetadataRef, + NumElements: ::libc::size_t, + ) -> LLVMMetadataRef; + + /// Deallocate a temporary node. + pub fn LLVMDisposeTemporaryMDNode(TempNode: LLVMMetadataRef); + + /// Replace all uses of temporary metadata. + pub fn LLVMMetadataReplaceAllUsesWith( + TempTargetMetadata: LLVMMetadataRef, + Replacement: LLVMMetadataRef, + ); + + /// Create a new descriptor for the specified global variable that is temporary + pub fn LLVMDIBuilderCreateTempGlobalVariableFwdDecl( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + Linkage: *const ::libc::c_char, + LnkLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Ty: LLVMMetadataRef, + LocalToUnit: LLVMBool, + Decl: LLVMMetadataRef, + AlignInBits: u32, + ) -> LLVMMetadataRef; + + /// Insert a new llvm.dbg.declare intrinsic call before the given instruction. + pub fn LLVMDIBuilderInsertDeclareBefore( + Builder: LLVMDIBuilderRef, + Storage: LLVMValueRef, + VarInfo: LLVMMetadataRef, + Expr: LLVMMetadataRef, + DebugLoc: LLVMMetadataRef, + Instr: LLVMValueRef, + ) -> LLVMValueRef; + + /// Insert a new llvm.dbg.declare intrinsic call at the end of the given basic block. If the basic block has a terminator instruction, the intrinsic is inserted before that terminator instruction. + pub fn LLVMDIBuilderInsertDeclareAtEnd( + Builder: LLVMDIBuilderRef, + Storage: LLVMValueRef, + VarInfo: LLVMMetadataRef, + Expr: LLVMMetadataRef, + DebugLoc: LLVMMetadataRef, + Block: LLVMBasicBlockRef, + ) -> LLVMValueRef; + + /// Insert a new llvm.dbg.value intrinsic call before the given instruction. + pub fn LLVMDIBuilderInsertDbgValueBefore( + Builder: LLVMDIBuilderRef, + Val: LLVMValueRef, + VarInfo: LLVMMetadataRef, + Expr: LLVMMetadataRef, + DebugLoc: LLVMMetadataRef, + Instr: LLVMValueRef, + ) -> LLVMValueRef; + + /// Insert a new llvm.dbg.value intrinsic call at the end of the given basic block. If the basic block has a terminator instruction, the intrinsic is inserted before that terminator instruction. + pub fn LLVMDIBuilderInsertDbgValueAtEnd( + Builder: LLVMDIBuilderRef, + Val: LLVMValueRef, + VarInfo: LLVMMetadataRef, + Expr: LLVMMetadataRef, + DebugLoc: LLVMMetadataRef, + Block: LLVMBasicBlockRef, + ) -> LLVMValueRef; + + /// Create a new descriptor for a local auto variable. + pub fn LLVMDIBuilderCreateAutoVariable( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Ty: LLVMMetadataRef, + AlwaysPreserve: LLVMBool, + Flags: LLVMDIFlags, + AlignInBits: u32, + ) -> LLVMMetadataRef; + + /// Create a new descriptor for a function parameter variable. + pub fn LLVMDIBuilderCreateParameterVariable( + Builder: LLVMDIBuilderRef, + Scope: LLVMMetadataRef, + Name: *const ::libc::c_char, + NameLen: ::libc::size_t, + ArgNo: ::libc::c_uint, + File: LLVMMetadataRef, + LineNo: ::libc::c_uint, + Ty: LLVMMetadataRef, + AlwaysPreserve: LLVMBool, + Flags: LLVMDIFlags, + ) -> LLVMMetadataRef; + + /// Get the metadata of the subprogram attached to a function. + pub fn LLVMGetSubprogram(Func: LLVMValueRef) -> LLVMMetadataRef; + + /// Set the subprogram attached to a function. + pub fn LLVMSetSubprogram(Func: LLVMValueRef, SP: LLVMMetadataRef); + + /// Get the line associated with a given subprogram. + pub fn LLVMDISubprogramGetLine(Subprogram: LLVMMetadataRef) -> ::libc::c_uint; + + /// Get the debug location for the given instruction. + pub fn LLVMInstructionGetDebugLoc(Inst: LLVMValueRef) -> LLVMMetadataRef; + + /// Set the debug location for the given instruction. + pub fn LLVMInstructionSetDebugLoc(Inst: LLVMValueRef, Loc: LLVMMetadataRef); + + /// Obtain the enumerated type of a metadata instance. + pub fn LLVMGetMetadataKind(Metadata: LLVMMetadataRef) -> LLVMMetadataKind; +} diff --git a/ext/llvm-sys.rs/src/disassembler.rs b/ext/llvm-sys.rs/src/disassembler.rs new file mode 100644 index 0000000..3eed4a3 --- /dev/null +++ b/ext/llvm-sys.rs/src/disassembler.rs @@ -0,0 +1,147 @@ +//! A disassembler library. + +#![allow(non_upper_case_globals, non_snake_case)] + +#[derive(Debug)] +pub enum LLVMOpaqueDisasmContext {} + +pub type LLVMDisasmContextRef = *mut LLVMOpaqueDisasmContext; + +pub type LLVMOpInfoCallback = Option< + extern "C" fn( + DisInfo: *mut ::libc::c_void, + PC: u64, + Offset: u64, + OpSize: u64, + InstSize: u64, + TagType: ::libc::c_int, + TagBuf: *mut ::libc::c_void, + ) -> ::libc::c_int, +>; + +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOpInfoSymbol1 { + /// 1 if this symbol is present. + pub Present: u64, + /// Symbol name if not NULL. + pub Name: *const ::libc::c_char, + /// Symbol value if name is NULL. + pub Value: u64, +} + +#[repr(C)] +#[derive(Debug)] +pub struct Struct_LLVMOpInfo1 { + pub AddSymbol: LLVMOpInfoSymbol1, + pub SubtractSymbol: LLVMOpInfoSymbol1, + pub Value: u64, + pub VariantKind: u64, +} + +pub const LLVMDisassembler_VariantKind_None: u64 = 0; +pub const LLVMDisassembler_VariantKind_ARM_HI16: u64 = 1; +pub const LLVMDisassembler_VariantKind_ARM_LO16: u64 = 2; +pub const LLVMDisassembler_VariantKind_ARM64_PAGE: u64 = 1; +pub const LLVMDisassembler_VariantKind_ARM64_PAGEOFF: u64 = 2; +pub const LLVMDisassembler_VariantKind_ARM64_GOTPAGE: u64 = 3; +pub const LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF: u64 = 4; +pub const LLVMDisassembler_VariantKind_ARM64_TLVP: u64 = 5; +pub const LLVMDisassembler_VariantKind_ARM64_TLVOFF: u64 = 6; + +/// No input reference type or no output reference type. +pub const LLVMDisassembler_ReferenceType_InOut_None: u64 = 0; + +/// The input reference is from a branch instruction. +pub const LLVMDisassembler_ReferenceType_In_Branch: u64 = 1; +/// The input reference is from a PC relative load instruction. +pub const LLVMDisassembler_ReferenceType_In_PCrel_Load: u64 = 2; + +/// The input reference is from an ARM64::ADRP instruction. +pub const LLVMDisassembler_ReferenceType_In_ARM64_ADRP: u64 = 0x100000001; +/// The input reference is from an ARM64::ADDXri instruction. +pub const LLVMDisassembler_ReferenceType_In_ARM64_ADDXri: u64 = 0x100000002; +/// The input reference is from an ARM64::LDRXui instruction. +pub const LLVMDisassembler_ReferenceType_In_ARM64_LDRXui: u64 = 0x100000003; +/// The input reference is from an ARM64::LDRXl instruction. +pub const LLVMDisassembler_ReferenceType_In_ARM64_LDRXl: u64 = 0x100000004; +/// The input reference is from an ARM64::ADR instruction. +pub const LLVMDisassembler_ReferenceType_In_ARM64_ADR: u64 = 0x100000005; + +/// The output reference is to as symbol stub. +pub const LLVMDisassembler_ReferenceType_Out_SymbolStub: u64 = 1; +/// The output reference is to a symbol address in a literal pool. +pub const LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr: u64 = 2; +/// The output reference is to a cstring address in a literal pool. +pub const LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr: u64 = 3; + +/// The output reference is to a Objective-C CoreFoundation string. +pub const LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref: u64 = 4; +/// The output reference is to a Objective-C message. +pub const LLVMDisassembler_ReferenceType_Out_Objc_Message: u64 = 5; +/// The output reference is to a Objective-C message ref. +pub const LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref: u64 = 6; +/// The output reference is to a Objective-C selector ref. +pub const LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref: u64 = 7; +/// The output reference is to a Objective-C class ref. +pub const LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref: u64 = 8; +/// The output reference is to a C++ symbol name. +pub const LLVMDisassembler_ReferenceType_DeMangled_Name: u64 = 9; + +/// The option to produce marked up assembly. +pub const LLVMDisassembler_Option_UseMarkup: u64 = 1; +/// The option to print immediates as hex. +pub const LLVMDisassembler_Option_PrintImmHex: u64 = 2; +/// The option use the other assembler printer variant +pub const LLVMDisassembler_Option_AsmPrinterVariant: u64 = 4; +/// The option to set comment on instructions +pub const LLVMDisassembler_Option_SetInstrComments: u64 = 8; +/// The option to print latency information alongside instructions +pub const LLVMDisassembler_Option_PrintLatency: u64 = 16; + +pub type LLVMSymbolLookupCallback = Option< + extern "C" fn( + DisInfo: *mut ::libc::c_void, + ReferenceValue: u64, + ReferenceType: *mut u64, + ReferencePC: u64, + ReferenceName: *mut *const ::libc::c_char, + ) -> *const ::libc::c_char, +>; + +extern "C" { + pub fn LLVMCreateDisasm( + TripleName: *const ::libc::c_char, + DisInfo: *mut ::libc::c_void, + TagType: ::libc::c_int, + GetOpInfo: LLVMOpInfoCallback, + SymbolLookUp: LLVMSymbolLookupCallback, + ) -> LLVMDisasmContextRef; + pub fn LLVMCreateDisasmCPU( + Triple: *const ::libc::c_char, + CPU: *const ::libc::c_char, + DisInfo: *mut ::libc::c_void, + TagType: ::libc::c_int, + GetOpInfo: LLVMOpInfoCallback, + SymbolLookUp: LLVMSymbolLookupCallback, + ) -> LLVMDisasmContextRef; + pub fn LLVMCreateDisasmCPUFeatures( + Triple: *const ::libc::c_char, + CPU: *const ::libc::c_char, + Features: *const ::libc::c_char, + DisInfo: *mut ::libc::c_void, + TagType: ::libc::c_int, + GetOpInfo: LLVMOpInfoCallback, + SymbolLookUp: LLVMSymbolLookupCallback, + ) -> LLVMDisasmContextRef; + pub fn LLVMSetDisasmOptions(DC: LLVMDisasmContextRef, Options: u64) -> ::libc::c_int; + pub fn LLVMDisasmDispose(DC: LLVMDisasmContextRef); + pub fn LLVMDisasmInstruction( + DC: LLVMDisasmContextRef, + Bytes: *mut u8, + BytesSize: u64, + PC: u64, + OutString: *mut ::libc::c_char, + OutStringSize: ::libc::size_t, + ) -> ::libc::size_t; +} diff --git a/ext/llvm-sys.rs/src/error.rs b/ext/llvm-sys.rs/src/error.rs new file mode 100644 index 0000000..eddfbfa --- /dev/null +++ b/ext/llvm-sys.rs/src/error.rs @@ -0,0 +1,18 @@ +pub const LLVMErrorSuccess: ::libc::c_int = 0; + +#[derive(Debug)] +pub enum LLVMOpaqueError {} + +pub type LLVMErrorRef = *mut LLVMOpaqueError; + +pub type LLVMErrorTypeId = *const ::libc::c_void; + +extern "C" { + pub fn LLVMGetErrorTypeId(Err: LLVMErrorRef) -> LLVMErrorTypeId; + pub fn LLVMConsumeError(Err: LLVMErrorRef); + pub fn LLVMGetErrorMessage(Err: LLVMErrorRef) -> *mut ::libc::c_char; + pub fn LLVMDisposeErrorMessage(ErrMsg: *mut ::libc::c_char); + pub fn LLVMGetStringErrorTypeId() -> LLVMErrorTypeId; + /// Create a StringError. + pub fn LLVMCreateStringError(ErrMst: *const ::libc::c_char) -> LLVMErrorRef; +} diff --git a/ext/llvm-sys.rs/src/error_handling.rs b/ext/llvm-sys.rs/src/error_handling.rs new file mode 100644 index 0000000..c60a831 --- /dev/null +++ b/ext/llvm-sys.rs/src/error_handling.rs @@ -0,0 +1,17 @@ +pub type LLVMFatalErrorHandler = Option; + +extern "C" { + /// Install a fatal error handler. + /// + /// LLVM will call `exit(1)` if it detects a fatal error. A callback + /// registered with this function will be invoked before the program is + /// exited. + pub fn LLVMInstallFatalErrorHandler(Handler: LLVMFatalErrorHandler); + /// Reset fatal error handling to the default. + pub fn LLVMResetFatalErrorHandler(); + /// Enable LLVM's build-in stack trace code. + /// + /// This intercepts the OS's crash signals and prints which component + /// of LLVM you were in at the time of the crash. + pub fn LLVMEnablePrettyStackTrace(); +} diff --git a/ext/llvm-sys.rs/src/execution_engine.rs b/ext/llvm-sys.rs/src/execution_engine.rs new file mode 100644 index 0000000..8aa440b --- /dev/null +++ b/ext/llvm-sys.rs/src/execution_engine.rs @@ -0,0 +1,212 @@ +//! Runtime code generation and execution. + +use super::prelude::*; +use super::target::LLVMTargetDataRef; +use super::target_machine::{LLVMCodeModel, LLVMTargetMachineRef}; + +#[derive(Debug)] +pub enum LLVMOpaqueGenericValue {} + +#[derive(Debug)] +pub enum LLVMOpaqueExecutionEngine {} + +#[derive(Debug)] +pub enum LLVMOpaqueMCJITMemoryManager {} + +pub type LLVMGenericValueRef = *mut LLVMOpaqueGenericValue; +pub type LLVMExecutionEngineRef = *mut LLVMOpaqueExecutionEngine; +pub type LLVMMCJITMemoryManagerRef = *mut LLVMOpaqueMCJITMemoryManager; + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +#[allow(non_snake_case)] +pub struct LLVMMCJITCompilerOptions { + pub OptLevel: ::libc::c_uint, + pub CodeModel: LLVMCodeModel, + pub NoFramePointerElim: LLVMBool, + pub EnableFastISel: LLVMBool, + pub MCJMM: LLVMMCJITMemoryManagerRef, +} + +pub type LLVMMemoryManagerAllocateCodeSectionCallback = extern "C" fn( + Opaque: *mut ::libc::c_void, + Size: ::libc::uintptr_t, + Alignment: ::libc::c_uint, + SectionID: ::libc::c_uint, + SectionName: *const ::libc::c_char, +) -> *mut u8; +pub type LLVMMemoryManagerAllocateDataSectionCallback = extern "C" fn( + Opaque: *mut ::libc::c_void, + Size: ::libc::uintptr_t, + Alignment: ::libc::c_uint, + SectionID: ::libc::c_uint, + SectionName: *const ::libc::c_char, + IsReadOnly: LLVMBool, +) -> *mut u8; +pub type LLVMMemoryManagerFinalizeMemoryCallback = + extern "C" fn(Opaque: *mut ::libc::c_void, ErrMsg: *mut *mut ::libc::c_char) -> LLVMBool; +pub type LLVMMemoryManagerDestroyCallback = Option; + +extern "C" { + pub fn LLVMLinkInMCJIT(); + pub fn LLVMLinkInInterpreter(); + + // Operations on generic values + pub fn LLVMCreateGenericValueOfInt( + Ty: LLVMTypeRef, + N: ::libc::c_ulonglong, + IsSigned: LLVMBool, + ) -> LLVMGenericValueRef; + pub fn LLVMCreateGenericValueOfPointer(P: *mut ::libc::c_void) -> LLVMGenericValueRef; + pub fn LLVMCreateGenericValueOfFloat( + Ty: LLVMTypeRef, + N: ::libc::c_double, + ) -> LLVMGenericValueRef; + pub fn LLVMGenericValueIntWidth(GenValRef: LLVMGenericValueRef) -> ::libc::c_uint; + pub fn LLVMGenericValueToInt( + GenVal: LLVMGenericValueRef, + IsSigned: LLVMBool, + ) -> ::libc::c_ulonglong; + pub fn LLVMGenericValueToPointer(GenVal: LLVMGenericValueRef) -> *mut ::libc::c_void; + pub fn LLVMGenericValueToFloat( + TyRef: LLVMTypeRef, + GenVal: LLVMGenericValueRef, + ) -> ::libc::c_double; + pub fn LLVMDisposeGenericValue(GenVal: LLVMGenericValueRef); + + // Operations on execution engines + pub fn LLVMCreateExecutionEngineForModule( + OutEE: *mut LLVMExecutionEngineRef, + M: LLVMModuleRef, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMCreateInterpreterForModule( + OutInterp: *mut LLVMExecutionEngineRef, + M: LLVMModuleRef, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMCreateJITCompilerForModule( + OutJIT: *mut LLVMExecutionEngineRef, + M: LLVMModuleRef, + OptLevel: ::libc::c_uint, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMInitializeMCJITCompilerOptions( + Options: *mut LLVMMCJITCompilerOptions, + SizeOfOptions: ::libc::size_t, + ); + + /// Create an MCJIT execution engine for a module, with the given options. + /// + /// It is + /// the responsibility of the caller to ensure that all fields in Options up to + /// the given SizeOfOptions are initialized. It is correct to pass a smaller + /// value of SizeOfOptions that omits some fields. The canonical way of using + /// this is: + /// + /// ```c++ + /// LLVMMCJITCompilerOptions options; + /// LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); + /// // ... fill in those options you care about + /// LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options), + /// &error); + /// ``` + /// + /// Note that this is also correct, though possibly suboptimal: + /// + /// ```c++ + /// LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error); + /// ``` + /// + /// 0 is returned on success, or 1 on failure. + pub fn LLVMCreateMCJITCompilerForModule( + OutJIT: *mut LLVMExecutionEngineRef, + M: LLVMModuleRef, + Options: *mut LLVMMCJITCompilerOptions, + SizeOfOptions: ::libc::size_t, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + + pub fn LLVMDisposeExecutionEngine(EE: LLVMExecutionEngineRef); + pub fn LLVMRunStaticConstructors(EE: LLVMExecutionEngineRef); + pub fn LLVMRunStaticDestructors(EE: LLVMExecutionEngineRef); + pub fn LLVMRunFunctionAsMain( + EE: LLVMExecutionEngineRef, + F: LLVMValueRef, + ArgC: ::libc::c_uint, + ArgV: *const *const ::libc::c_char, + EnvP: *const *const ::libc::c_char, + ) -> ::libc::c_int; + pub fn LLVMRunFunction( + EE: LLVMExecutionEngineRef, + F: LLVMValueRef, + NumArgs: ::libc::c_uint, + Args: *mut LLVMGenericValueRef, + ) -> LLVMGenericValueRef; + pub fn LLVMFreeMachineCodeForFunction(EE: LLVMExecutionEngineRef, F: LLVMValueRef); + pub fn LLVMAddModule(EE: LLVMExecutionEngineRef, M: LLVMModuleRef); + pub fn LLVMRemoveModule( + EE: LLVMExecutionEngineRef, + M: LLVMModuleRef, + OutMod: *mut LLVMModuleRef, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMFindFunction( + EE: LLVMExecutionEngineRef, + Name: *const ::libc::c_char, + OutFn: *mut LLVMValueRef, + ) -> LLVMBool; + pub fn LLVMRecompileAndRelinkFunction( + EE: LLVMExecutionEngineRef, + Fn: LLVMValueRef, + ) -> *mut ::libc::c_void; + pub fn LLVMGetExecutionEngineTargetData(EE: LLVMExecutionEngineRef) -> LLVMTargetDataRef; + pub fn LLVMGetExecutionEngineTargetMachine(EE: LLVMExecutionEngineRef) -> LLVMTargetMachineRef; + pub fn LLVMAddGlobalMapping( + EE: LLVMExecutionEngineRef, + Global: LLVMValueRef, + Addr: *mut ::libc::c_void, + ); + pub fn LLVMGetPointerToGlobal( + EE: LLVMExecutionEngineRef, + Global: LLVMValueRef, + ) -> *mut ::libc::c_void; + pub fn LLVMGetGlobalValueAddress( + EE: LLVMExecutionEngineRef, + Name: *const ::libc::c_char, + ) -> u64; + pub fn LLVMGetFunctionAddress(EE: LLVMExecutionEngineRef, Name: *const ::libc::c_char) -> u64; + + pub fn LLVMExecutionEngineGetErrMsg( + EE: LLVMExecutionEngineRef, + OutError: *mut *mut ::libc::c_char, + ) -> LLVMBool; + + // Operations on memory managers + // Create a simple custom MCJIT memory manager. + // + // This memory manager can intercept allocations in a module-oblivious way. It will + // return NULL if any of the passed functions are NULL. + // + // `AllocateCodeSection` and `AllocateDataSection` are called to allocate blocks + // of memory for executable code and data, respectively. `FinalizeMemory` is called + // to set page permissions and flush caches, returning 0 on success and 1 on error. + // + // `Opaque` will be passed to the callbacks. + pub fn LLVMCreateSimpleMCJITMemoryManager( + Opaque: *mut ::libc::c_void, + AllocateCodeSection: LLVMMemoryManagerAllocateCodeSectionCallback, + AllocateDataSection: LLVMMemoryManagerAllocateDataSectionCallback, + FinalizeMemory: LLVMMemoryManagerFinalizeMemoryCallback, + Destroy: LLVMMemoryManagerDestroyCallback, + ) -> LLVMMCJITMemoryManagerRef; + + pub fn LLVMDisposeMCJITMemoryManager(MM: LLVMMCJITMemoryManagerRef); + + // JIT event listener functions + pub fn LLVMCreateGDBRegistrationListener() -> LLVMJITEventListenerRef; + pub fn LLVMCreateIntelJITEventListener() -> LLVMJITEventListenerRef; + pub fn LLVMCreateOProfileJITEventListener() -> LLVMJITEventListenerRef; + pub fn LLVMCreatePerfJITEventListener() -> LLVMJITEventListenerRef; + +} diff --git a/ext/llvm-sys.rs/src/initialization.rs b/ext/llvm-sys.rs/src/initialization.rs new file mode 100644 index 0000000..9e811b6 --- /dev/null +++ b/ext/llvm-sys.rs/src/initialization.rs @@ -0,0 +1,19 @@ +//! Initialization routines which must be called before using library features. + +use super::prelude::*; + +extern "C" { + pub fn LLVMInitializeCore(R: LLVMPassRegistryRef); + pub fn LLVMInitializeTransformUtils(R: LLVMPassRegistryRef); + pub fn LLVMInitializeScalarOpts(R: LLVMPassRegistryRef); + pub fn LLVMInitializeObjCARCOpts(R: LLVMPassRegistryRef); + pub fn LLVMInitializeVectorization(R: LLVMPassRegistryRef); + pub fn LLVMInitializeInstCombine(R: LLVMPassRegistryRef); + pub fn LLVMInitializeAggressiveInstCombiner(R: LLVMPassRegistryRef); + pub fn LLVMInitializeIPO(R: LLVMPassRegistryRef); + pub fn LLVMInitializeInstrumentation(R: LLVMPassRegistryRef); + pub fn LLVMInitializeAnalysis(R: LLVMPassRegistryRef); + pub fn LLVMInitializeIPA(R: LLVMPassRegistryRef); + pub fn LLVMInitializeCodeGen(R: LLVMPassRegistryRef); + pub fn LLVMInitializeTarget(R: LLVMPassRegistryRef); +} diff --git a/ext/llvm-sys.rs/src/ir_reader.rs b/ext/llvm-sys.rs/src/ir_reader.rs new file mode 100644 index 0000000..e5c9f2b --- /dev/null +++ b/ext/llvm-sys.rs/src/ir_reader.rs @@ -0,0 +1,16 @@ +//! The IR reader + +use super::prelude::*; + +extern "C" { + /// Read LLVM IR from a memory buffer and convert it to an in-memory Module. + /// + /// Returns 0 on success, and an optional human-readable description of any + /// errors that occurred. + pub fn LLVMParseIRInContext( + ContextRef: LLVMContextRef, + MemBuf: LLVMMemoryBufferRef, + OutM: *mut LLVMModuleRef, + OutMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/lib.rs b/ext/llvm-sys.rs/src/lib.rs new file mode 100644 index 0000000..33315d8 --- /dev/null +++ b/ext/llvm-sys.rs/src/lib.rs @@ -0,0 +1,500 @@ +//! Bindings to LLVM's C API. +//! +//! Refer to the [LLVM documentation](http://llvm.org/docs/) for more +//! information. + +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] + +extern crate libc; + +use self::prelude::*; + +#[derive(Debug)] +pub enum LLVMMemoryBuffer {} + +#[derive(Debug)] +pub enum LLVMContext {} + +#[derive(Debug)] +pub enum LLVMModule {} + +#[derive(Debug)] +pub enum LLVMType {} + +#[derive(Debug)] +pub enum LLVMValue {} + +#[derive(Debug)] +pub enum LLVMBasicBlock {} + +#[derive(Debug)] +pub enum LLVMOpaqueMetadata {} + +#[derive(Debug)] +pub enum LLVMOpaqueNamedMDNode {} + +#[derive(Debug)] +pub enum LLVMOpaqueValueMetadataEntry {} + +#[derive(Debug)] +pub enum LLVMBuilder {} + +#[derive(Debug)] +pub enum LLVMOpaqueDIBuilder {} + +#[derive(Debug)] +pub enum LLVMModuleProvider {} + +#[derive(Debug)] +pub enum LLVMPassManager {} + +#[derive(Debug)] +pub enum LLVMPassRegistry {} + +#[derive(Debug)] +pub enum LLVMUse {} + +#[derive(Debug)] +pub enum LLVMDiagnosticInfo {} + +#[derive(Debug)] +pub enum LLVMComdat {} + +#[derive(Debug)] +pub enum LLVMOpaqueModuleFlagEntry {} + +#[derive(Debug)] +pub enum LLVMOpaqueJITEventListener {} + +#[derive(Debug)] +pub enum LLVMOpaqueAttributeRef {} + +/// Core types used throughout LLVM. +/// +/// In most cases you will want to `use llvm::prelude::*`. +pub mod prelude { + pub type LLVMBool = ::libc::c_int; + pub type LLVMMemoryBufferRef = *mut super::LLVMMemoryBuffer; + pub type LLVMContextRef = *mut super::LLVMContext; + pub type LLVMModuleRef = *mut super::LLVMModule; + pub type LLVMTypeRef = *mut super::LLVMType; + pub type LLVMValueRef = *mut super::LLVMValue; + pub type LLVMBasicBlockRef = *mut super::LLVMBasicBlock; + pub type LLVMMetadataRef = *mut super::LLVMOpaqueMetadata; + pub type LLVMNamedMDNodeRef = *mut super::LLVMOpaqueNamedMDNode; + pub type LLVMValueMetadataEntry = *mut super::LLVMOpaqueValueMetadataEntry; + pub type LLVMBuilderRef = *mut super::LLVMBuilder; + pub type LLVMDIBuilderRef = *mut super::LLVMOpaqueDIBuilder; + pub type LLVMModuleProviderRef = *mut super::LLVMModuleProvider; + pub type LLVMPassManagerRef = *mut super::LLVMPassManager; + pub type LLVMPassRegistryRef = *mut super::LLVMPassRegistry; + pub type LLVMUseRef = *mut super::LLVMUse; + pub type LLVMDiagnosticInfoRef = *mut super::LLVMDiagnosticInfo; + pub type LLVMComdatRef = *mut super::LLVMComdat; + pub type LLVMModuleFlagEntry = *mut super::LLVMOpaqueModuleFlagEntry; + pub type LLVMJITEventListenerRef = *mut super::LLVMOpaqueJITEventListener; + pub type LLVMAttributeRef = *mut super::LLVMOpaqueAttributeRef; +} + +pub mod analysis; +pub mod bit_reader; +pub mod bit_writer; +pub mod blake3; +pub mod comdat; +pub mod core; +pub mod debuginfo; +pub mod disassembler; +pub mod error; +pub mod error_handling; +pub mod execution_engine; +pub mod initialization; +pub mod ir_reader; +pub mod linker; +pub mod lto; +pub mod object; +pub mod orc2; +pub mod remarks; +pub mod support; +pub mod target; +pub mod target_machine; + +pub mod transforms { + pub mod aggressive_instcombine; + pub mod instcombine; + pub mod ipo; + pub mod pass_builder; + pub mod pass_manager_builder; + pub mod scalar; + pub mod util; + pub mod vectorize; +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMOpcode { + LLVMRet = 1, + LLVMBr = 2, + LLVMSwitch = 3, + LLVMIndirectBr = 4, + LLVMInvoke = 5, + LLVMUnreachable = 7, + LLVMCallBr = 67, + LLVMFNeg = 66, + LLVMAdd = 8, + LLVMFAdd = 9, + LLVMSub = 10, + LLVMFSub = 11, + LLVMMul = 12, + LLVMFMul = 13, + LLVMUDiv = 14, + LLVMSDiv = 15, + LLVMFDiv = 16, + LLVMURem = 17, + LLVMSRem = 18, + LLVMFRem = 19, + LLVMShl = 20, + LLVMLShr = 21, + LLVMAShr = 22, + LLVMAnd = 23, + LLVMOr = 24, + LLVMXor = 25, + LLVMAlloca = 26, + LLVMLoad = 27, + LLVMStore = 28, + LLVMGetElementPtr = 29, + LLVMTrunc = 30, + LLVMZExt = 31, + LLVMSExt = 32, + LLVMFPToUI = 33, + LLVMFPToSI = 34, + LLVMUIToFP = 35, + LLVMSIToFP = 36, + LLVMFPTrunc = 37, + LLVMFPExt = 38, + LLVMPtrToInt = 39, + LLVMIntToPtr = 40, + LLVMBitCast = 41, + LLVMAddrSpaceCast = 60, + LLVMICmp = 42, + LLVMFCmp = 43, + LLVMPHI = 44, + LLVMCall = 45, + LLVMSelect = 46, + LLVMUserOp1 = 47, + LLVMUserOp2 = 48, + LLVMVAArg = 49, + LLVMExtractElement = 50, + LLVMInsertElement = 51, + LLVMShuffleVector = 52, + LLVMExtractValue = 53, + LLVMInsertValue = 54, + LLVMFreeze = 68, + LLVMFence = 55, + LLVMAtomicCmpXchg = 56, + LLVMAtomicRMW = 57, + LLVMResume = 58, + LLVMLandingPad = 59, + LLVMCleanupRet = 61, + LLVMCatchRet = 62, + LLVMCatchPad = 63, + LLVMCleanupPad = 64, + LLVMCatchSwitch = 65, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMTypeKind { + LLVMVoidTypeKind = 0, + LLVMHalfTypeKind = 1, + LLVMFloatTypeKind = 2, + LLVMDoubleTypeKind = 3, + LLVMX86_FP80TypeKind = 4, + LLVMFP128TypeKind = 5, + LLVMPPC_FP128TypeKind = 6, + LLVMLabelTypeKind = 7, + LLVMIntegerTypeKind = 8, + LLVMFunctionTypeKind = 9, + LLVMStructTypeKind = 10, + LLVMArrayTypeKind = 11, + LLVMPointerTypeKind = 12, + LLVMVectorTypeKind = 13, + LLVMMetadataTypeKind = 14, + LLVMX86_MMXTypeKind = 15, + LLVMTokenTypeKind = 16, + LLVMScalableVectorTypeKind = 17, + LLVMBFloatTypeKind = 18, + LLVMX86_AMXTypeKind = 19, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMLinkage { + LLVMExternalLinkage = 0, + LLVMAvailableExternallyLinkage = 1, + LLVMLinkOnceAnyLinkage = 2, + LLVMLinkOnceODRLinkage = 3, + LLVMLinkOnceODRAutoHideLinkage = 4, + LLVMWeakAnyLinkage = 5, + LLVMWeakODRLinkage = 6, + LLVMAppendingLinkage = 7, + LLVMInternalLinkage = 8, + LLVMPrivateLinkage = 9, + LLVMDLLImportLinkage = 10, + LLVMDLLExportLinkage = 11, + LLVMExternalWeakLinkage = 12, + LLVMGhostLinkage = 13, + LLVMCommonLinkage = 14, + LLVMLinkerPrivateLinkage = 15, + LLVMLinkerPrivateWeakLinkage = 16, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMVisibility { + LLVMDefaultVisibility = 0, + LLVMHiddenVisibility = 1, + LLVMProtectedVisibility = 2, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMUnnamedAddr { + /// Address of the GV is significant. + LLVMNoUnnamedAddr, + /// Address of the GV is locally insignificant. + LLVMLocalUnnamedAddr, + /// Address of the GV is globally insignificant. + LLVMGlobalUnnamedAddr, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMDLLStorageClass { + LLVMDefaultStorageClass = 0, + LLVMDLLImportStorageClass = 1, + LLVMDLLExportStorageClass = 2, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMCallConv { + LLVMCCallConv = 0, + LLVMFastCallConv = 8, + LLVMColdCallConv = 9, + LLVMGHCCallConv = 10, + LLVMHiPECallConv = 11, + LLVMWebKitJSCallConv = 12, + LLVMAnyRegCallConv = 13, + LLVMPreserveMostCallConv = 14, + LLVMPreserveAllCallConv = 15, + LLVMSwiftCallConv = 16, + LLVMCXXFASTTLSCallConv = 17, + LLVMX86StdcallCallConv = 64, + LLVMX86FastcallCallConv = 65, + LLVMARMAPCSCallConv = 66, + LLVMARMAAPCSCallConv = 67, + LLVMARMAAPCSVFPCallConv = 68, + LLVMMSP430INTRCallConv = 69, + LLVMX86ThisCallCallConv = 70, + LLVMPTXKernelCallConv = 71, + LLVMPTXDeviceCallConv = 72, + LLVMSPIRFUNCCallConv = 75, + LLVMSPIRKERNELCallConv = 76, + LLVMIntelOCLBICallConv = 77, + LLVMX8664SysVCallConv = 78, + LLVMWin64CallConv = 79, + LLVMX86VectorCallCallConv = 80, + LLVMHHVMCallConv = 81, + LLVMHHVMCCallConv = 82, + LLVMX86INTRCallConv = 83, + LLVMAVRINTRCallConv = 84, + LLVMAVRSIGNALCallConv = 85, + LLVMAVRBUILTINCallConv = 86, + LLVMAMDGPUVSCallConv = 87, + LLVMAMDGPUGSCallConv = 88, + LLVMAMDGPUPSCallConv = 89, + LLVMAMDGPUCSCallConv = 90, + LLVMAMDGPUKERNELCallConv = 91, + LLVMX86RegCallCallConv = 92, + LLVMAMDGPUHSCallConv = 93, + LLVMMSP430BUILTINCallConv = 94, + LLVMAMDGPULSCallConv = 95, + LLVMAMDGPUESCallConv = 96, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMValueKind { + LLVMArgumentValueKind, + LLVMBasicBlockValueKind, + LLVMMemoryUseValueKind, + LLVMMemoryDefValueKind, + LLVMMemoryPhiValueKind, + + LLVMFunctionValueKind, + LLVMGlobalAliasValueKind, + LLVMGlobalIFuncValueKind, + LLVMGlobalVariableValueKind, + LLVMBlockAddressValueKind, + LLVMConstantExprValueKind, + LLVMConstantArrayValueKind, + LLVMConstantStructValueKind, + LLVMConstantVectorValueKind, + LLVMUndefValueValueKind, + LLVMConstantAggregateZeroValueKind, + LLVMConstantDataArrayValueKind, + LLVMConstantDataVectorValueKind, + LLVMConstantIntValueKind, + LLVMConstantFPValueKind, + LLVMConstantPointerNullValueKind, + LLVMConstantTokenNoneValueKind, + + LLVMMetadataAsValueValueKind, + LLVMInlineAsmValueKind, + + LLVMInstructionValueKind, + LLVMPoisonValueKind, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMIntPredicate { + LLVMIntEQ = 32, + LLVMIntNE = 33, + LLVMIntUGT = 34, + LLVMIntUGE = 35, + LLVMIntULT = 36, + LLVMIntULE = 37, + LLVMIntSGT = 38, + LLVMIntSGE = 39, + LLVMIntSLT = 40, + LLVMIntSLE = 41, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMRealPredicate { + LLVMRealPredicateFalse = 0, + LLVMRealOEQ = 1, + LLVMRealOGT = 2, + LLVMRealOGE = 3, + LLVMRealOLT = 4, + LLVMRealOLE = 5, + LLVMRealONE = 6, + LLVMRealORD = 7, + LLVMRealUNO = 8, + LLVMRealUEQ = 9, + LLVMRealUGT = 10, + LLVMRealUGE = 11, + LLVMRealULT = 12, + LLVMRealULE = 13, + LLVMRealUNE = 14, + LLVMRealPredicateTrue = 15, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMLandingPadClauseTy { + LLVMLandingPadCatch = 0, + LLVMLandingPadFilter = 1, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMThreadLocalMode { + LLVMNotThreadLocal = 0, + LLVMGeneralDynamicTLSModel = 1, + LLVMLocalDynamicTLSModel = 2, + LLVMInitialExecTLSModel = 3, + LLVMLocalExecTLSModel = 4, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMAtomicOrdering { + LLVMAtomicOrderingNotAtomic = 0, + LLVMAtomicOrderingUnordered = 1, + LLVMAtomicOrderingMonotonic = 2, + LLVMAtomicOrderingAcquire = 4, + LLVMAtomicOrderingRelease = 5, + LLVMAtomicOrderingAcquireRelease = 6, + LLVMAtomicOrderingSequentiallyConsistent = 7, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMAtomicRMWBinOp { + LLVMAtomicRMWBinOpXchg = 0, + LLVMAtomicRMWBinOpAdd = 1, + LLVMAtomicRMWBinOpSub = 2, + LLVMAtomicRMWBinOpAnd = 3, + LLVMAtomicRMWBinOpNand = 4, + LLVMAtomicRMWBinOpOr = 5, + LLVMAtomicRMWBinOpXor = 6, + LLVMAtomicRMWBinOpMax = 7, + LLVMAtomicRMWBinOpMin = 8, + LLVMAtomicRMWBinOpUMax = 9, + LLVMAtomicRMWBinOpUMin = 10, + LLVMAtomicRMWBinOpFAdd = 11, + LLVMAtomicRMWBinOpFSub = 12, + LLVMAtomicRMWBinOpFMax = 13, + LLVMAtomicRMWBinOpFMin = 14, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMDiagnosticSeverity { + LLVMDSError = 0, + LLVMDSWarning = 1, + LLVMDSRemark = 2, + LLVMDSNote = 3, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMInlineAsmDialect { + LLVMInlineAsmDialectATT, + LLVMInlineAsmDialectIntel, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMModuleFlagBehavior { + /// Emits an error if two values disagree, otherwise the resulting value is that of the operands. + LLVMModuleFlagBehaviorError, + /// Emits a warning if two values disagree. The result value will be the operand for the flag from the first module being linked. + LLVMModuleFlagBehaviorWarning, + /// Adds a requirement that another module flag be present and have a specified value after linking is performed. The value must be a metadata pair, where the first element of the pair is the ID of the module flag to be restricted, and the second element of the pair is the value the module flag should be restricted to. This behavior can be used to restrict the allowable results (via triggering of an error) of linking IDs with the **Override** behavior. + LLVMModuleFlagBehaviorRequire, + /// Uses the specified value, regardless of the behavior or value of the other module. If both modules specify **Override**, but the values differ, an error will be emitted. + LLVMModuleFlagBehaviorOverride, + /// Appends the two values, which are required to be metadata nodes. + LLVMModuleFlagBehaviorAppend, + /// Appends the two values, which are required to be metadata nodes. However, duplicate entries in the second list are dropped during the append operation. + LLVMModuleFlagBehaviorAppendUnique, +} + +pub const LLVMAttributeReturnIndex: ::libc::c_uint = 0; +pub const LLVMAttributeFunctionIndex: ::libc::c_uint = !0; // -1 +/// Either LLVMAttributeReturnIndex, LLVMAttributeFunctionIndex, or a parameter +/// number from 1 to N. +pub type LLVMAttributeIndex = ::libc::c_uint; + +pub type LLVMDiagnosticHandler = + Option; +pub type LLVMYieldCallback = Option; + +#[cfg(all(not(doc), not(feature = "no-llvm-linking"), LLVM_SYS_NOT_FOUND))] +std::compile_error!(concat!( + "No suitable version of LLVM was found system-wide or pointed + to by LLVM_SYS_", + env!("CARGO_PKG_VERSION_MAJOR"), + "_PREFIX. + + Consider using `llvmenv` to compile an appropriate copy of LLVM, and + refer to the llvm-sys documentation for more information. + + llvm-sys: https://crates.io/crates/llvm-sys + llvmenv: https://crates.io/crates/llvmenv" +)); diff --git a/ext/llvm-sys.rs/src/linker.rs b/ext/llvm-sys.rs/src/linker.rs new file mode 100644 index 0000000..60e79db --- /dev/null +++ b/ext/llvm-sys.rs/src/linker.rs @@ -0,0 +1,19 @@ +//! The module/file/archive linker + +use super::prelude::*; + +#[repr(C)] +#[derive(Debug)] +pub enum LLVMLinkerMode { + LLVMLinkerDestroySource = 0, + #[deprecated(since = "3.7.0", note = "LLVMLinkerPreserveSource has no effect")] + LLVMLinkerPreserveSource_Removed = 1, +} + +extern "C" { + /// Link the source module into the destination module. + /// + /// Destroys the source module, returns true on error. Use the diagnostic + /// handler to get any diagnostic message. + pub fn LLVMLinkModules2(Dest: LLVMModuleRef, Src: LLVMModuleRef) -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/lto.rs b/ext/llvm-sys.rs/src/lto.rs new file mode 100644 index 0000000..7efddd9 --- /dev/null +++ b/ext/llvm-sys.rs/src/lto.rs @@ -0,0 +1,442 @@ +//! Abstract link time optimization. +//! +//! ## ThinLTO +//! +//! ThinLTO is designed to do LTO while requiring fewer resources than regular +//! LTO. It can run much faster and in less memory (comparable to linking +//! without LTO) than regular LTO, with essentially no loss in optimization. + +#![allow(non_camel_case_types)] + +pub type lto_bool_t = u8; + +// This looks kind of like bitflags but I'm not sure. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum lto_symbol_attributes { + LTO_SYMBOL_ALIGNMENT_MASK = 31, + LTO_SYMBOL_PERMISSIONS_MASK = 224, + LTO_SYMBOL_PERMISSIONS_CODE = 160, + LTO_SYMBOL_PERMISSIONS_DATA = 192, + LTO_SYMBOL_PERMISSIONS_RODATA = 128, + LTO_SYMBOL_DEFINITION_MASK = 1792, + LTO_SYMBOL_DEFINITION_REGULAR = 256, + LTO_SYMBOL_DEFINITION_TENTATIVE = 512, + LTO_SYMBOL_DEFINITION_WEAK = 768, + LTO_SYMBOL_DEFINITION_UNDEFINED = 1024, + LTO_SYMBOL_DEFINITION_WEAKUNDEF = 1280, + LTO_SYMBOL_SCOPE_MASK = 14336, + LTO_SYMBOL_SCOPE_INTERNAL = 2048, + LTO_SYMBOL_SCOPE_HIDDEN = 0x1000, + LTO_SYMBOL_SCOPE_PROTECTED = 0x2000, + LTO_SYMBOL_SCOPE_DEFAULT = 0x1800, + LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x2800, + /// Added in LLVM 3.7. + LTO_SYMBOL_COMDAT = 0x4000, + /// Added in LLVM 3.7. + LTO_SYMBOL_ALIAS = 0x8000, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum lto_debug_model { + LTO_DEBUG_MODEL_NONE = 0, + LTO_DEBUG_MODEL_DWARF = 1, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum lto_codegen_model { + LTO_CODEGEN_PIC_MODEL_STATIC = 0, + LTO_CODEGEN_PIC_MODEL_DYNAMIC = 1, + LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC = 2, + LTO_CODEGEN_PIC_MODEL_DEFAULT = 3, +} + +#[derive(Debug)] +pub enum LLVMOpaqueLTOModule {} + +pub type lto_module_t = *mut LLVMOpaqueLTOModule; + +#[derive(Debug)] +pub enum LLVMOpaqueLTOCodeGenerator {} + +pub type lto_code_gen_t = *mut LLVMOpaqueLTOCodeGenerator; + +#[derive(Debug)] +pub enum LLVMOpaqueThinLTOCodeGenerator {} + +pub type thinlto_code_gen_t = *mut LLVMOpaqueThinLTOCodeGenerator; + +#[derive(Debug)] +pub enum LLVMOpaqueLTOInput {} + +pub type lto_input_t = *mut LLVMOpaqueLTOInput; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum lto_codegen_diagnostic_severity_t { + LTO_DS_ERROR = 0, + LTO_DS_WARNING = 1, + LTO_DS_REMARK = 3, + LTO_DS_NOTE = 2, +} + +pub type lto_diagnostic_handler_t = Option< + extern "C" fn( + severity: lto_codegen_diagnostic_severity_t, + diag: *const ::libc::c_char, + ctxt: *mut ::libc::c_void, + ), +>; + +extern "C" { + pub fn lto_get_version() -> *const ::libc::c_char; + pub fn lto_get_error_message() -> *const ::libc::c_char; + pub fn lto_module_is_object_file(path: *const ::libc::c_char) -> lto_bool_t; + pub fn lto_module_is_object_file_for_target( + path: *const ::libc::c_char, + target_triple_prefix: *const ::libc::c_char, + ) -> lto_bool_t; + /// Return true if `Buffer` contains a bitcode file with ObjC code + /// (category or class) in it. + pub fn lto_module_has_objc_category( + mem: *const ::libc::c_void, + length: ::libc::size_t, + ) -> lto_bool_t; + /// Checks if a buffer is a loadable object file. + pub fn lto_module_is_object_file_in_memory( + mem: *const ::libc::c_void, + length: ::libc::size_t, + ) -> lto_bool_t; + pub fn lto_module_is_object_file_in_memory_for_target( + mem: *const ::libc::c_void, + length: ::libc::size_t, + target_triple_prefix: *const ::libc::c_char, + ) -> lto_bool_t; + pub fn lto_module_create(path: *const ::libc::c_char) -> lto_module_t; + pub fn lto_module_create_from_memory( + mem: *const ::libc::c_void, + length: ::libc::size_t, + ) -> lto_module_t; + pub fn lto_module_create_from_memory_with_path( + mem: *const ::libc::c_void, + length: ::libc::size_t, + path: *const ::libc::c_char, + ) -> lto_module_t; + pub fn lto_module_create_in_local_context( + mem: *const ::libc::c_void, + length: ::libc::size_t, + path: *const ::libc::c_char, + ) -> lto_module_t; + pub fn lto_module_create_in_codegen_context( + mem: *const ::libc::c_void, + length: ::libc::size_t, + path: *const ::libc::c_char, + cg: lto_code_gen_t, + ) -> lto_module_t; + pub fn lto_module_create_from_fd( + fd: ::libc::c_int, + path: *const ::libc::c_char, + file_size: ::libc::size_t, + ) -> lto_module_t; + pub fn lto_module_create_from_fd_at_offset( + fd: ::libc::c_int, + path: *const ::libc::c_char, + file_size: ::libc::size_t, + map_size: ::libc::size_t, + offset: ::libc::off_t, + ) -> lto_module_t; + pub fn lto_module_dispose(_mod: lto_module_t); + pub fn lto_module_get_target_triple(_mod: lto_module_t) -> *const ::libc::c_char; + pub fn lto_module_set_target_triple(_mod: lto_module_t, triple: *const ::libc::c_char); + pub fn lto_module_get_num_symbols(_mod: lto_module_t) -> ::libc::c_uint; + pub fn lto_module_get_symbol_name( + _mod: lto_module_t, + index: ::libc::c_uint, + ) -> *const ::libc::c_char; + pub fn lto_module_get_symbol_attribute( + _mod: lto_module_t, + index: ::libc::c_uint, + ) -> lto_symbol_attributes; + /// Returns the module's linker options. + /// + /// The linker options may consist of multiple flags. It is the linker's + /// responsibility to split the flags using a platform-specific mechanism. + /// + /// Added in LLVM 3.7. + pub fn lto_module_get_linkeropts(_mod: lto_module_t) -> *const ::libc::c_char; + pub fn lto_module_get_macho_cputype( + _mod: lto_module_t, + out_cputype: *mut ::libc::c_uint, + out_cpusubtype: *mut ::libc::c_uint, + ) -> lto_bool_t; + /// Return true if the module has either the `@llvm.global_ctors` or the `@llvm.global_dtors` + /// symbol. + /// + /// Added in API version 29 (LLVM 14). + pub fn lto_module_has_ctor_dtor(mod_: lto_module_t) -> lto_bool_t; + pub fn lto_codegen_set_diagnostic_handler( + arg1: lto_code_gen_t, + arg2: lto_diagnostic_handler_t, + arg3: *mut ::libc::c_void, + ); + pub fn lto_codegen_create() -> lto_code_gen_t; + pub fn lto_codegen_create_in_local_context() -> lto_code_gen_t; + pub fn lto_codegen_dispose(arg1: lto_code_gen_t); + pub fn lto_codegen_add_module(cg: lto_code_gen_t, _mod: lto_module_t) -> lto_bool_t; + /// Sets the object module for code gneeration. This will transfer ownership + /// of the module to the code generator. + /// + /// Added in LLVM 3.7. + pub fn lto_codegen_set_module(cg: lto_code_gen_t, _mod: lto_module_t); + pub fn lto_codegen_set_debug_model(cg: lto_code_gen_t, arg1: lto_debug_model) -> lto_bool_t; + pub fn lto_codegen_set_pic_model(cg: lto_code_gen_t, arg1: lto_codegen_model) -> lto_bool_t; + pub fn lto_codegen_set_cpu(cg: lto_code_gen_t, cpu: *const ::libc::c_char); + pub fn lto_codegen_set_assembler_path(cg: lto_code_gen_t, path: *const ::libc::c_char); + pub fn lto_codegen_set_assembler_args( + cg: lto_code_gen_t, + args: *mut *const ::libc::c_char, + nargs: ::libc::c_int, + ); + pub fn lto_codegen_add_must_preserve_symbol(cg: lto_code_gen_t, symbol: *const ::libc::c_char); + pub fn lto_codegen_write_merged_modules( + cg: lto_code_gen_t, + path: *const ::libc::c_char, + ) -> lto_bool_t; + pub fn lto_codegen_compile( + cg: lto_code_gen_t, + length: *mut ::libc::size_t, + ) -> *const ::libc::c_void; + pub fn lto_codegen_compile_to_file( + cg: lto_code_gen_t, + name: *mut *const ::libc::c_char, + ) -> lto_bool_t; + /// Runs optimization for the merged module. + /// + /// Returns true on error. + /// + /// Added in LLVM 3.7. + pub fn lto_codegen_optimize(cg: lto_code_gen_t) -> lto_bool_t; + /// Generates code for the optimized merged module into one native object file. + /// + /// Does not run IR optimizations on the merged module. + /// + /// Returns a pointer to the generated mach-o/ELF buffer with length + /// set to the buffer size. This buffer is owned by `cg` and will be + /// freed when `lto_codegen_dispose` is called or `lto_codegen_compile_optimized` + /// is called again. Returns null on failure. + /// + /// Added in LLVM 3.7. + pub fn lto_codegen_compile_optimized( + cg: lto_code_gen_t, + length: *mut ::libc::size_t, + ) -> *mut ::libc::c_void; + /// Returns the runtime API version. + /// + /// Added in LLVM 3.7. + pub fn lto_api_version() -> ::libc::c_uint; + pub fn lto_set_debug_options(options: *mut *const ::libc::c_char, number: ::libc::c_int); + pub fn lto_codegen_debug_options(cg: lto_code_gen_t, arg1: *const ::libc::c_char); + pub fn lto_codegen_debug_options_array( + cg: lto_code_gen_t, + arg2: *const *const ::libc::c_char, + number: ::libc::c_int, + ); + pub fn lto_initialize_disassembler(); + /// Sets if we should run the internalize pass during optimization and code generation. + /// + /// Added in LLVM 3.7. + pub fn lto_codegen_set_should_internalize(cg: lto_code_gen_t, ShouldInternalize: lto_bool_t); + /// Set whether to embed uselists in bitcode. + /// + /// Sets whether `lto_codegen_write_merged_modules` should embed uselists in + /// output bitcode. This should be turned on for all -save-temps output. + /// + /// Added in LLVM 3.7. + pub fn lto_codegen_set_should_embed_uselists( + cg: lto_code_gen_t, + ShouldEmbedUselists: lto_bool_t, + ); +} + +/// Type to wrap a single object returned by ThinLTO. +#[repr(C)] +#[derive(Debug)] +#[allow(non_snake_case)] +pub struct LTOObjectBuffer { + Buffer: *const ::libc::c_char, + Size: ::libc::size_t, +} + +extern "C" { + /// Instantiates a ThinLTO code generator. + /// + /// Returns null on error (check `lto_get_error_message` for details). + /// + /// The code generator should not be reused. + pub fn thinlto_create_codegen() -> thinlto_code_gen_t; + /// Frees a code generator. + pub fn thinlto_codegen_dispose(cg: thinlto_code_gen_t); + /// Add a module to a code generator. + /// + /// Identifier must be unique among all the modules in the code generator. + /// The data buffer remains owned by the client, and must live at least + /// as long as the code generator. + /// + /// Returns null on failure. + pub fn thinlto_codegen_add_module( + cg: thinlto_code_gen_t, + identifier: *const ::libc::c_char, + data: *const ::libc::c_char, + length: ::libc::c_int, + ); + /// Optimize and codegen all modules attached to the code generator. + /// + /// Resulting objects are accessible with `thinlto_module_get_object`. + pub fn thinlto_codegen_process(cg: thinlto_code_gen_t); + /// Return the number of object files produced by the code generator. + /// + /// This usually matches the number of input files, but is not guaranteed + /// to. + pub fn thinlto_module_get_num_objects(cg: thinlto_code_gen_t) -> ::libc::c_int; + /// Return a reference to the `index`th object file produced by the + /// code generator. + pub fn thinlto_module_get_object( + cg: thinlto_code_gen_t, + index: ::libc::c_uint, + ) -> LTOObjectBuffer; + /// Return the number of object files produced by the code generator. + /// + /// Usually the same as the number of input files, but not guaranteed. + pub fn thinlto_module_get_num_object_files(cg: thinlto_code_gen_t) -> ::libc::c_uint; + /// Return the path to the ith output object file. + /// + /// Use `thinlto_module_get_num_object_files` to get the number of available objects. + pub fn thinlto_module_get_object_file( + cg: thinlto_code_gen_t, + index: ::libc::c_uint, + ) -> *const ::libc::c_char; + /// Set which PIC code model to generate. + /// + /// Returns true on error. + pub fn thinlto_codegen_set_pic_model( + cg: thinlto_code_gen_t, + model: lto_codegen_model, + ) -> lto_bool_t; + + // ThinLTO cache control. + // Set the path to a directory to use as cache for increment build. + // + // Setting this activates caching. + pub fn thinlto_codegen_set_cache_dir(cg: thinlto_code_gen_t, cache_dir: *const ::libc::c_char); + /// Set the cache pruning interval, in seconds. + /// + /// A negative value disables pruning, and 0 will force pruning to occur. + pub fn thinlto_codegen_set_cache_pruning_interval( + cg: thinlto_code_gen_t, + interval: ::libc::c_int, + ); + /// Set the maximum cache size to persist across builds. + /// + /// This is expressed as a percentage of available disk space. 100 means no limit, + /// and 50 means no more than half of the available disk space. 0 is ignored, and + /// values over 100 will be reduced to 100. + pub fn thinlto_codegen_set_final_cache_size_relative_to_available_space( + cg: thinlto_code_gen_t, + percentage: ::libc::c_uint, + ); + /// Set the expiration (in seconds) for cache entries. + pub fn thinlto_codegen_set_cache_entry_expiration( + cg: thinlto_code_gen_t, + expiration: ::libc::c_uint, + ); + /// Set the maximum size of the cache directory (in bytes). A value over the + /// amount of available space on the disk will be reduced to the amount of + /// available space. An unspecified default value will be applied. A value of 0 + /// will be ignored. + pub fn thinlto_codegen_set_cache_size_bytes( + cg: thinlto_code_gen_t, + max_size_bytes: ::libc::c_uint, + ); + /// Same as thinlto_codegen_set_cache_size_bytes, except the maximum size is in + /// megabytes (2^20 bytes). + pub fn thinlto_codegen_set_cache_size_megabytes( + cg: thinlto_code_gen_t, + max_size_megabytes: ::libc::c_uint, + ); + /// Sets the maximum number of files in the cache directory. An unspecified default value will be applied. A value of 0 will be ignored. + pub fn thinlto_codegen_set_cache_size_files( + cg: thinlto_code_gen_t, + max_size_files: ::libc::c_uint, + ); + + /// Create an LTO input file from a buffer. + pub fn lto_input_create( + buffer: *const ::libc::c_void, + buffer_size: ::libc::size_t, + path: *const ::libc::c_char, + ) -> lto_input_t; + /// Free all memory allocated by the input file. + pub fn lto_input_dispose(input: lto_input_t); + /// Get the number of dependent library specifiers for the given input. + pub fn lto_input_get_num_dependent_libraries(input: lto_input_t) -> ::libc::c_uint; + /// Get the `i`th dependent library specifier for the given input file. + /// + /// The returned string is not null-terminated. + pub fn lto_input_get_dependent_library( + input: lto_input_t, + index: ::libc::size_t, + size: *mut ::libc::size_t, + ) -> *const ::libc::c_char; + /// Return the list of libcall symbols that can be generated by LTO + /// that might not be visible from the symbol table of bitcode files. + pub fn lto_runtime_lib_symbols_list(size: *mut usize) -> *const *const ::libc::c_char; + + /// Set the path to a directory to use as temporary bitcode storage. + /// + /// This is meant to make the bitcode files available for debugging. + pub fn thinlto_codegen_set_savetemps_dir( + cg: thinlto_code_gen_t, + save_temps_dir: *const ::libc::c_char, + ); + /// Set the path to a directory to save generated object files. + /// + /// Set this to request on-disk rather than in-memory buffers. When set, use + /// `thinlto_module_get_object_file` instead of `thinlto_module_get_object`. + pub fn thinlto_set_generated_objects_dir( + cg: thinlto_code_gen_t, + save_temps_dir: *const ::libc::c_char, + ); + /// Set the CPU to generate code for. + pub fn thinlto_codegen_set_cpu(cg: thinlto_code_gen_t, cpu: *const ::libc::c_char); + /// Disable code generation (running all stages until codegen). + /// + /// The output with codegen disabled is bitcode. + pub fn thinlto_codegen_disable_codegen(cg: thinlto_code_gen_t, disable: lto_bool_t); + /// Perform codegen only; disable all other stages. + pub fn thinlto_codegen_set_codegen_only(cg: thinlto_code_gen_t, codegen_only: lto_bool_t); + /// Parse -mllvm style debug options. + pub fn thinlto_debug_options(options: *const *const ::libc::c_char, number: ::libc::c_int); + /// Test if a module has ThinLTO linking support. + pub fn lto_module_is_thinlto(module: lto_module_t) -> lto_bool_t; + /// Add a symbol to the list of global symbols that must exist in the + /// final generated code. + /// + /// Functions not listed may be inlined in every usage and optimized away. + pub fn thinlto_codegen_add_must_preserve_symbol( + cg: thinlto_code_gen_t, + name: *const ::libc::c_char, + length: ::libc::c_int, + ); + /// Add a symbol to the list of global symbols that are cross-referenced + /// between ThinLTO files. + /// + /// Symbols listed can be discarded if every reference from a ThinLTO module + /// to a symbol is optimized away, then the symbol can be discarded. + pub fn thinlto_codegen_add_cross_referenced_symbol( + cg: thinlto_code_gen_t, + name: *const ::libc::c_char, + length: ::libc::c_int, + ); +} diff --git a/ext/llvm-sys.rs/src/object.rs b/ext/llvm-sys.rs/src/object.rs new file mode 100644 index 0000000..d8c7c78 --- /dev/null +++ b/ext/llvm-sys.rs/src/object.rs @@ -0,0 +1,164 @@ +//! Object file reading and writing + +use super::prelude::*; + +#[derive(Debug)] +pub enum LLVMOpaqueSectionIterator {} + +pub type LLVMSectionIteratorRef = *mut LLVMOpaqueSectionIterator; + +#[derive(Debug)] +pub enum LLVMOpaqueSymbolIterator {} + +pub type LLVMSymbolIteratorRef = *mut LLVMOpaqueSymbolIterator; + +#[derive(Debug)] +pub enum LLVMOpaqueRelocationIterator {} + +pub type LLVMRelocationIteratorRef = *mut LLVMOpaqueRelocationIterator; + +#[derive(Debug)] +pub enum LLVMOpaqueBinary {} + +pub type LLVMBinaryRef = *mut LLVMOpaqueBinary; + +#[repr(C)] +#[derive(Debug)] +pub enum LLVMBinaryType { + /// Archive file + LLVMBinaryTypeArchive, + /// Mach-O Universal Binary file + LLVMBinaryTypeMachOUniversalBinary, + /// COFF Import file + LLVMBinaryTypeCOFFImportFile, + /// LLVM IR + LLVMBinaryTypeIR, + /// Windows resource (.res) file + LLVMBinaryTypeWinRes, + /// COFF Object file + LLVMBinaryTypeCOFF, + /// ELF 32-bit, little endian + LLVMBinaryTypeELF32L, + /// ELF 32-bit, big endian + LLVMBinaryTypeELF32B, + /// ELF 64-bit, little endian + LLVMBinaryTypeELF64L, + /// ELF 64-bit, big endian + LLVMBinaryTypeELF64B, + /// MachO 32-bit, little endian + LLVMBinaryTypeMachO32L, + /// MachO 32-bit, big endian + LLVMBinaryTypeMachO32B, + /// MachO 64-bit, little endian + LLVMBinaryTypeMachO64L, + /// MachO 64-bit, big endian + LLVMBinaryTypeMachO64B, + /// Web assembly + LLVMBinaryTypeWasm, + /// Offloading fatbinary + LLVMBinaryTypeOffload, +} + +#[deprecated(since = "LLVM 9.0")] +pub enum LLVMOpaqueObjectFile {} + +#[allow(deprecated)] +#[deprecated(since = "LLVM 9.0")] +pub type LLVMObjectFileRef = *mut LLVMOpaqueObjectFile; + +extern "C" { + /// Create a binary file from the given memory buffer. + pub fn LLVMCreateBinary( + MemBuf: LLVMMemoryBufferRef, + Context: LLVMContextRef, + ErrorMessage: *mut *mut ::libc::c_char, + ) -> LLVMBinaryRef; + /// Dispose of a binary file + pub fn LLVMDisposeBinary(BR: LLVMBinaryRef); + + pub fn LLVMBinaryCopyMemoryBuffer(BR: LLVMBinaryRef) -> LLVMMemoryBufferRef; + pub fn LLVMBinaryGetType(BR: LLVMBinaryRef) -> LLVMBinaryType; + pub fn LLVMMachOUniversalBinaryCopyObjectForArch( + BR: LLVMBinaryRef, + Arch: *const ::libc::c_char, + ArchLen: ::libc::size_t, + ErrorMessage: *mut *mut ::libc::c_char, + ) -> LLVMBinaryRef; + + pub fn LLVMObjectFileCopySectionIterator(BR: LLVMBinaryRef) -> LLVMSectionIteratorRef; + pub fn LLVMObjectFileIsSectionIteratorAtEnd( + BR: LLVMBinaryRef, + SI: LLVMSectionIteratorRef, + ) -> LLVMBool; + pub fn LLVMObjectFileCopySymbolIterator(BR: LLVMBinaryRef) -> LLVMSymbolIteratorRef; + pub fn LLVMObjectFileIsSymbolIteratorAtEnd( + BR: LLVMBinaryRef, + SI: LLVMSymbolIteratorRef, + ) -> LLVMBool; + pub fn LLVMDisposeSectionIterator(SI: LLVMSectionIteratorRef); + + pub fn LLVMMoveToNextSection(SI: LLVMSectionIteratorRef); + pub fn LLVMMoveToContainingSection(Sect: LLVMSectionIteratorRef, Sym: LLVMSymbolIteratorRef); + pub fn LLVMDisposeSymbolIterator(SI: LLVMSymbolIteratorRef); + pub fn LLVMMoveToNextSymbol(SI: LLVMSymbolIteratorRef); + pub fn LLVMGetSectionName(SI: LLVMSectionIteratorRef) -> *const ::libc::c_char; + pub fn LLVMGetSectionSize(SI: LLVMSectionIteratorRef) -> u64; + pub fn LLVMGetSectionContents(SI: LLVMSectionIteratorRef) -> *const ::libc::c_char; + pub fn LLVMGetSectionAddress(SI: LLVMSectionIteratorRef) -> u64; + pub fn LLVMGetSectionContainsSymbol( + SI: LLVMSectionIteratorRef, + Sym: LLVMSymbolIteratorRef, + ) -> LLVMBool; + pub fn LLVMGetRelocations(Section: LLVMSectionIteratorRef) -> LLVMRelocationIteratorRef; + pub fn LLVMDisposeRelocationIterator(RI: LLVMRelocationIteratorRef); + pub fn LLVMIsRelocationIteratorAtEnd( + Section: LLVMSectionIteratorRef, + RI: LLVMRelocationIteratorRef, + ) -> LLVMBool; + pub fn LLVMMoveToNextRelocation(RI: LLVMRelocationIteratorRef); + pub fn LLVMGetSymbolName(SI: LLVMSymbolIteratorRef) -> *const ::libc::c_char; + pub fn LLVMGetSymbolAddress(SI: LLVMSymbolIteratorRef) -> u64; + pub fn LLVMGetSymbolSize(SI: LLVMSymbolIteratorRef) -> u64; + pub fn LLVMGetRelocationOffset(RI: LLVMRelocationIteratorRef) -> u64; + pub fn LLVMGetRelocationSymbol(RI: LLVMRelocationIteratorRef) -> LLVMSymbolIteratorRef; + pub fn LLVMGetRelocationType(RI: LLVMRelocationIteratorRef) -> u64; + pub fn LLVMGetRelocationTypeName(RI: LLVMRelocationIteratorRef) -> *const ::libc::c_char; + pub fn LLVMGetRelocationValueString(RI: LLVMRelocationIteratorRef) -> *const ::libc::c_char; + + #[allow(deprecated)] + #[deprecated(since = "LLVM 9.0", note = "Use LLVMCreateBinary instead")] + pub fn LLVMCreateObjectFile(MemBuf: LLVMMemoryBufferRef) -> LLVMObjectFileRef; + #[allow(deprecated)] + #[deprecated(since = "LLVM 9.0", note = "Use LLVMDisposeBinary instead")] + pub fn LLVMDisposeObjectFile(ObjectFile: LLVMObjectFileRef); + #[allow(deprecated)] + #[deprecated( + since = "LLVM 9.0", + note = "Use LLVMObjectFileCopySectionIterator instead" + )] + pub fn LLVMGetSections(ObjectFile: LLVMObjectFileRef) -> LLVMSectionIteratorRef; + #[allow(deprecated)] + #[deprecated( + since = "LLVM 9.0", + note = "Use LLVMObjectFileIsSectionIteratorAtEnd instead" + )] + pub fn LLVMIsSectionIteratorAtEnd( + ObjectFile: LLVMObjectFileRef, + SI: LLVMSectionIteratorRef, + ) -> LLVMBool; + #[allow(deprecated)] + #[deprecated( + since = "LLVM 9.0", + note = "Use LLVMObjectFileCopySymbolIterator instead" + )] + pub fn LLVMGetSymbols(ObjectFile: LLVMObjectFileRef) -> LLVMSymbolIteratorRef; + #[allow(deprecated)] + #[deprecated( + since = "LLVM 9.0", + note = "Use LLVMObjectFileIsSymbolIteratorAtEnd instead" + )] + pub fn LLVMIsSymbolIteratorAtEnd( + ObjectFile: LLVMObjectFileRef, + SI: LLVMSymbolIteratorRef, + ) -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/orc2/ee.rs b/ext/llvm-sys.rs/src/orc2/ee.rs new file mode 100644 index 0000000..45f52d6 --- /dev/null +++ b/ext/llvm-sys.rs/src/orc2/ee.rs @@ -0,0 +1,11 @@ +use super::*; + +extern "C" { + pub fn LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager( + ES: LLVMOrcExecutionSessionRef, + ) -> LLVMOrcObjectLayerRef; + pub fn LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener( + RTDyldObjLinkingLayer: LLVMOrcObjectLayerRef, + Listener: LLVMJITEventListenerRef, + ); +} diff --git a/ext/llvm-sys.rs/src/orc2/lljit.rs b/ext/llvm-sys.rs/src/orc2/lljit.rs new file mode 100644 index 0000000..1b82a13 --- /dev/null +++ b/ext/llvm-sys.rs/src/orc2/lljit.rs @@ -0,0 +1,74 @@ +use super::*; +use error::LLVMErrorRef; +use prelude::*; + +pub type LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction = + extern "C" fn( + Ctx: *mut ::libc::c_void, + ES: LLVMOrcExecutionSessionRef, + Triple: *const ::libc::c_char, + ) -> LLVMOrcObjectLayerRef; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueLLJITBuilder {} +pub type LLVMOrcLLJITBuilderRef = *mut LLVMOrcOpaqueLLJITBuilder; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueLLJIT {} +pub type LLVMOrcLLJITRef = *mut LLVMOrcOpaqueLLJIT; + +extern "C" { + pub fn LLVMOrcCreateLLJITBuilder() -> LLVMOrcLLJITBuilderRef; + pub fn LLVMOrcDisposeLLJITBuilder(Builder: LLVMOrcLLJITBuilderRef); + pub fn LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( + Builder: LLVMOrcLLJITBuilderRef, + JTMB: LLVMOrcJITTargetMachineBuilderRef, + ); + pub fn LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator( + Builder: LLVMOrcLLJITBuilderRef, + F: LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction, + Ctx: *mut ::libc::c_void, + ); + pub fn LLVMOrcCreateLLJIT( + Result: *mut LLVMOrcLLJITRef, + Builder: LLVMOrcLLJITBuilderRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcDisposeLLJIT(J: LLVMOrcLLJITRef) -> LLVMErrorRef; + pub fn LLVMOrcLLJITGetExecutionSession(J: LLVMOrcLLJITRef) -> LLVMOrcExecutionSessionRef; + pub fn LLVMOrcLLJITGetMainJITDylib(J: LLVMOrcLLJITRef) -> LLVMOrcJITDylibRef; + pub fn LLVMOrcLLJITGetTripleString(J: LLVMOrcLLJITRef) -> *const ::libc::c_char; + pub fn LLVMOrcLLJITGetGlobalPrefix(J: LLVMOrcLLJITRef) -> ::libc::c_char; + pub fn LLVMOrcLLJITMangleAndIntern( + J: LLVMOrcLLJITRef, + UnmangledName: *const ::libc::c_char, + ) -> LLVMOrcSymbolStringPoolEntryRef; + pub fn LLVMOrcLLJITAddObjectFile( + J: LLVMOrcLLJITRef, + JD: LLVMOrcJITDylibRef, + ObjBuffer: LLVMMemoryBufferRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcLLJITAddObjectFileWithRT( + J: LLVMOrcLLJITRef, + RT: LLVMOrcResourceTrackerRef, + ObjBuffer: LLVMMemoryBufferRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcLLJITAddLLVMIRModule( + J: LLVMOrcLLJITRef, + JD: LLVMOrcJITDylibRef, + TSM: LLVMOrcThreadSafeModuleRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcLLJITAddLLVMIRModuleWithRT( + J: LLVMOrcLLJITRef, + JD: LLVMOrcResourceTrackerRef, + TSM: LLVMOrcThreadSafeModuleRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcLLJITLookup( + J: LLVMOrcLLJITRef, + Result: *mut LLVMOrcExecutorAddress, + Name: *const ::libc::c_char, + ) -> LLVMErrorRef; + pub fn LLVMOrcLLJITGetObjLinkingLayer(J: LLVMOrcLLJITRef) -> LLVMOrcObjectLayerRef; + pub fn LLVMOrcLLJITGetObjTransformLayer(J: LLVMOrcLLJITRef) -> LLVMOrcObjectTransformLayerRef; + pub fn LLVMOrcLLJITGetIRTransformLayer(J: LLVMOrcLLJITRef) -> LLVMOrcIRTransformLayerRef; + pub fn LLVMOrcLLJITGetDataLayoutStr(J: LLVMOrcLLJITRef) -> *const ::libc::c_char; +} diff --git a/ext/llvm-sys.rs/src/orc2/mod.rs b/ext/llvm-sys.rs/src/orc2/mod.rs new file mode 100644 index 0000000..afca862 --- /dev/null +++ b/ext/llvm-sys.rs/src/orc2/mod.rs @@ -0,0 +1,539 @@ +#![allow(non_snake_case)] +//! OrcV2 + +pub mod ee; +pub mod lljit; + +use error::LLVMErrorRef; +use prelude::*; +use target_machine::LLVMTargetMachineRef; + +/// Represents an address in the executor process. +pub type LLVMOrcJITTargetAddress = u64; + +/// Represents an address in the executor process +pub type LLVMOrcExecutorAddress = u64; + +/// Generic linkage flags for a symbol definition. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMJITSymbolGenericFlags { + LLVMJITSymbolGenericFlagsNone = 0, + LLVMJITSymbolGenericFlagsExported = 1, + LLVMJITSymbolGenericFlagsWeak = 2, + LLVMJITSymbolGenericFlagsCallable = 4, + LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly = 8, +} + +/// Target specific flags for a symbol definition. +pub type LLVMJITSymbolTargetFlags = u8; + +/// Linkage flags for a symbol definition. +#[repr(C)] +#[derive(Debug)] +pub struct LLVMJITSymbolFlags { + pub GenericFlags: u8, + pub TargetFlags: u8, +} + +/// An evaluated symbol address and flags. +#[repr(C)] +#[derive(Debug)] +pub struct LLVMJITEvaluatedSymbol { + pub Address: LLVMOrcExecutorAddress, + pub Flags: LLVMJITSymbolFlags, +} + +#[derive(Debug)] +pub enum LLVMOrcOpaqueExecutionSession {} +pub type LLVMOrcExecutionSessionRef = *mut LLVMOrcOpaqueExecutionSession; + +/// Error reporter function. +pub type LLVMOrcErrorReporterFunction = extern "C" fn(Ctx: *mut ::libc::c_void, Err: LLVMErrorRef); + +#[derive(Debug)] +pub enum LLVMOrcOpaqueSymbolStringPool {} +/// A reference to an orc::SymbolStringPool. +pub type LLVMOrcSymbolStringPoolRef = *mut LLVMOrcOpaqueSymbolStringPool; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueSymbolStringPoolEntry {} +pub type LLVMOrcSymbolStringPoolEntryRef = *mut LLVMOrcOpaqueSymbolStringPoolEntry; + +/// A pair of a symbol name and LLVMJITSymbolFlags. +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCSymbolFlagsMapPair { + pub Name: LLVMOrcSymbolStringPoolEntryRef, + pub Flags: LLVMJITSymbolFlags, +} + +pub type LLVMOrcCSymbolFlagsMapPairs = *mut LLVMOrcCSymbolFlagsMapPair; + +/// A pair of a symbol name and an evaluated symbol. +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCSymbolMapPair { + pub Name: LLVMOrcSymbolStringPoolEntryRef, + pub Sym: LLVMJITEvaluatedSymbol, +} + +/// A list of (SymbolStringPtr, JITEvaluatedSymbol) pairs that can be +/// used to construct a SymbolMap. +pub type LLVMOrcCSymbolMapPairs = *mut LLVMOrcCSymbolMapPair; + +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCSymbolAliasMapEntry { + pub Name: LLVMOrcSymbolStringPoolEntryRef, + pub Flags: LLVMJITSymbolFlags, +} + +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCSymbolAliasMapPair { + pub Name: LLVMOrcSymbolStringPoolEntryRef, + pub Entry: LLVMOrcCSymbolAliasMapEntry, +} + +pub type LLVMOrcCSymbolAliasMapPairs = *mut LLVMOrcCSymbolAliasMapPair; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueJITDylib {} +pub type LLVMOrcJITDylibRef = *mut LLVMOrcOpaqueJITDylib; + +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCSymbolsList { + pub Symbols: *mut LLVMOrcSymbolStringPoolEntryRef, + pub Length: ::libc::size_t, +} + +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCDependenceMapPair { + pub JD: LLVMOrcJITDylibRef, + pub Names: LLVMOrcCSymbolsList, +} + +pub type LLVMOrcCDependenceMapPairs = *mut LLVMOrcCDependenceMapPair; + +/// Lookup kind. This can be used by definition generators when deciding whether +/// to produce a definition for a requested symbol. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMOrcLookupKind { + LLVMOrcLookupKindStatic, + LLVMOrcLookupKindDLSym, +} + +/// JITDylib lookup flags. This can be used by definition generators when +/// deciding whether to produce a definition for a requested symbol. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMOrcJITDylibLookupFlags { + LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly, + LLVMOrcJITDylibLookupFlagsMatchAllSymbols, +} + +/// An element type for a JITDylib search order. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct LLVMOrcCJITDylibSearchOrderElement { + pub JD: LLVMOrcJITDylibRef, + pub JDLookupFlags: LLVMOrcJITDylibLookupFlags, +} + +/// A JITDylib search order. +/// +/// The list is terminated with an element containing a null pointer for the JD +/// field. +pub type LLVMOrcCJITDylibSearchOrder = *mut LLVMOrcCJITDylibSearchOrderElement; + +/// Symbol lookup flags for lookup sets. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMOrcSymbolLookupFlags { + LLVMOrcSymbolLookupFlagsRequiredSymbol, + LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol, +} + +/// An element type for a symbol lookup set. +#[repr(C)] +#[derive(Debug)] +pub struct LLVMOrcCLookupSetElement { + pub Name: LLVMOrcSymbolStringPoolEntryRef, + pub LookupFlags: LLVMOrcSymbolLookupFlags, +} + +/// A set of symbols to look up / generate. +/// +/// The list is terminated with an element containing a null pointer for the +/// Name field. +/// +/// The creator is responsible for freeing the set and ensuring all strings +/// are retained for the set's lifetime. +pub type LLVMOrcCLookupSet = *mut LLVMOrcCLookupSetElement; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueMaterializationUnit {} +pub type LLVMOrcMaterializationUnitRef = *mut LLVMOrcOpaqueMaterializationUnit; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueMaterializationResponsibility {} +pub type LLVMOrcMaterializationResponsibilityRef = *mut LLVMOrcOpaqueMaterializationResponsibility; + +pub type LLVMOrcMaterializationUnitMaterializeFunction = + extern "C" fn(Ctx: *mut ::libc::c_void, MR: LLVMOrcMaterializationResponsibilityRef); + +pub type LLVMOrcMaterializationUnitDiscardFunction = extern "C" fn( + Ctx: *mut ::libc::c_void, + JD: LLVMOrcJITDylibRef, + Symbol: LLVMOrcSymbolStringPoolEntryRef, +); + +pub type LLVMOrcMaterializationUnitDestroyFunction = extern "C" fn(Ctx: *mut ::libc::c_void); + +#[derive(Debug)] +pub enum LLVMOrcOpaqueResourceTracker {} +pub type LLVMOrcResourceTrackerRef = *mut LLVMOrcOpaqueResourceTracker; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueDefinitionGenerator {} +pub type LLVMOrcDefinitionGeneratorRef = *mut LLVMOrcOpaqueDefinitionGenerator; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueLookupState {} +pub type LLVMOrcLookupStateRef = *mut LLVMOrcOpaqueLookupState; + +pub type LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction = extern "C" fn( + GeneratorObj: LLVMOrcDefinitionGeneratorRef, + Ctx: *mut ::libc::c_void, + LookupState: *mut LLVMOrcLookupStateRef, + Kind: LLVMOrcLookupKind, + JD: LLVMOrcJITDylibRef, + JDLookupFlags: LLVMOrcJITDylibLookupFlags, + LookupSet: LLVMOrcCLookupSet, + LookupSetSize: usize, +) -> LLVMErrorRef; + +/// Disposer for a custom generator. +/// +/// Will be called by ORC when the JITDylib that the generator is attached to +/// is destroyed. +pub type LLVMOrcDisposeCAPIDefinitionGeneratorFunction = extern "C" fn(Ctx: *mut ::libc::c_void); + +pub type LLVMOrcSymbolPredicate = Option< + extern "C" fn(Ctx: *mut ::libc::c_void, Sym: LLVMOrcSymbolStringPoolEntryRef) -> ::libc::c_int, +>; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueThreadSafeContext {} +pub type LLVMOrcThreadSafeContextRef = *mut LLVMOrcOpaqueThreadSafeContext; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueThreadSafeModule {} +pub type LLVMOrcThreadSafeModuleRef = *mut LLVMOrcOpaqueThreadSafeModule; + +pub type LLVMOrcGenericIRModuleOperationFunction = + extern "C" fn(Ctx: *mut ::libc::c_void, M: LLVMModuleRef) -> LLVMErrorRef; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueJITTargetMachineBuilder {} +pub type LLVMOrcJITTargetMachineBuilderRef = *mut LLVMOrcOpaqueJITTargetMachineBuilder; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueObjectLayer {} +pub type LLVMOrcObjectLayerRef = *mut LLVMOrcOpaqueObjectLayer; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueObjectLinkingLayer {} +pub type LLVMOrcObjectLinkingLayerRef = *mut LLVMOrcOpaqueObjectLayer; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueIRTransformLayer {} +pub type LLVMOrcIRTransformLayerRef = *mut LLVMOrcOpaqueIRTransformLayer; + +pub type LLVMOrcIRTransformLayerTransformFunction = extern "C" fn( + Ctx: *mut ::libc::c_void, + ModInOut: *mut LLVMOrcThreadSafeModuleRef, + MR: LLVMOrcMaterializationResponsibilityRef, +) -> LLVMErrorRef; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueObjectTransformLayer {} +pub type LLVMOrcObjectTransformLayerRef = *mut LLVMOrcOpaqueObjectTransformLayer; + +pub type LLVMOrcObjectTransformLayerTransformFunction = + extern "C" fn(Ctx: *mut ::libc::c_void, ObjInOut: *mut LLVMMemoryBufferRef) -> LLVMErrorRef; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueIndirectStubsManager {} +pub type LLVMOrcIndirectStubsManagerRef = *mut LLVMOrcOpaqueIndirectStubsManager; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueLazyCallThroughManager {} +pub type LLVMOrcLazyCallThroughManagerRef = *mut LLVMOrcOpaqueLazyCallThroughManager; + +#[derive(Debug)] +pub enum LLVMOrcOpaqueDumpObjects {} +pub type LLVMOrcDumpObjectsRef = *mut LLVMOrcOpaqueDumpObjects; + +extern "C" { + pub fn LLVMOrcExecutionSessionSetErrorReporter( + ES: LLVMOrcExecutionSessionRef, + ReportError: LLVMOrcErrorReporterFunction, + Ctx: *mut ::libc::c_void, + ); + pub fn LLVMOrcExecutionSessionGetSymbolStringPool( + ES: LLVMOrcExecutionSessionRef, + ) -> LLVMOrcSymbolStringPoolRef; + pub fn LLVMOrcSymbolStringPoolClearDeadEntries(SSP: LLVMOrcSymbolStringPoolRef); + pub fn LLVMOrcExecutionSessionIntern( + ES: LLVMOrcExecutionSessionRef, + Name: *const ::libc::c_char, + ) -> LLVMOrcSymbolStringPoolEntryRef; +} + +pub type LLVMOrcExecutionSessionLookupHandleResultFunction = extern "C" fn( + Err: LLVMErrorRef, + Result: LLVMOrcCSymbolMapPairs, + NumPairs: usize, + Ctx: *mut ::libc::c_void, +); + +extern "C" { + pub fn LLVMOrcExecutionSessionLookup( + ES: LLVMOrcExecutionSessionRef, + K: LLVMOrcLookupKind, + SearchOrder: LLVMOrcCJITDylibSearchOrder, + SearchOrderSize: usize, + Symbols: LLVMOrcCLookupSet, + SymbolsSize: usize, + HandleResult: LLVMOrcExecutionSessionLookupHandleResultFunction, + Ctx: *mut ::libc::c_void, + ); + pub fn LLVMOrcRetainSymbolStringPoolEntry(S: LLVMOrcSymbolStringPoolEntryRef); + pub fn LLVMOrcReleaseSymbolStringPoolEntry(S: LLVMOrcSymbolStringPoolEntryRef); + pub fn LLVMOrcSymbolStringPoolEntryStr( + S: LLVMOrcSymbolStringPoolEntryRef, + ) -> *const ::libc::c_char; + pub fn LLVMOrcReleaseResourceTracker(RT: LLVMOrcResourceTrackerRef); + pub fn LLVMOrcResourceTrackerTransferTo( + SrcRT: LLVMOrcResourceTrackerRef, + DstRT: LLVMOrcResourceTrackerRef, + ); + pub fn LLVMOrcResourceTrackerRemove(RT: LLVMOrcResourceTrackerRef) -> LLVMErrorRef; + pub fn LLVMOrcDisposeDefinitionGenerator(DG: LLVMOrcDefinitionGeneratorRef); + pub fn LLVMOrcDisposeMaterializationUnit(MU: LLVMOrcMaterializationUnitRef); + pub fn LLVMOrcCreateCustomMaterializationUnit( + Name: *const ::libc::c_char, + Ctx: *mut ::libc::c_void, + Syms: LLVMOrcCSymbolFlagsMapPairs, + NumSyms: ::libc::size_t, + InitSym: LLVMOrcSymbolStringPoolEntryRef, + Materialize: LLVMOrcMaterializationUnitMaterializeFunction, + Discard: LLVMOrcMaterializationUnitDiscardFunction, + Destroy: LLVMOrcMaterializationUnitDestroyFunction, + ) -> LLVMOrcMaterializationUnitRef; + pub fn LLVMOrcAbsoluteSymbols( + Syms: LLVMOrcCSymbolMapPairs, + NumPairs: usize, + ) -> LLVMOrcMaterializationUnitRef; + pub fn LLVMOrcLazyReexports( + LCTM: LLVMOrcLazyCallThroughManagerRef, + ISM: LLVMOrcIndirectStubsManagerRef, + SourceRef: LLVMOrcJITDylibRef, + CallableAliases: LLVMOrcCSymbolAliasMapPairs, + NumPairs: ::libc::size_t, + ) -> LLVMOrcMaterializationUnitRef; + pub fn LLVMOrcDisposeMaterializationResponsibility(MR: LLVMOrcMaterializationResponsibilityRef); + pub fn LLVMOrcMaterializationResponsibilityGetTargetDylib( + MR: LLVMOrcMaterializationResponsibilityRef, + ) -> LLVMOrcJITDylibRef; + pub fn LLVMOrcMaterializationResponsibilityGetExecutionSession( + MR: LLVMOrcMaterializationResponsibilityRef, + ) -> LLVMOrcExecutionSessionRef; + pub fn LLVMOrcMaterializationResponsibilityGetSymbols( + MR: LLVMOrcMaterializationResponsibilityRef, + NumPairs: *mut ::libc::size_t, + ) -> LLVMOrcCSymbolFlagsMapPairs; + pub fn LLVMOrcDisposeCSymbolFlagsMap(Pairs: LLVMOrcCSymbolFlagsMapPairs); + pub fn LLVMOrcMaterializationResponsibilityGetInitializerSymbol( + MR: LLVMOrcMaterializationResponsibilityRef, + ) -> LLVMOrcSymbolStringPoolEntryRef; + pub fn LLVMOrcMaterializationResponsibilityGetRequestedSymbols( + MR: LLVMOrcMaterializationResponsibilityRef, + NumSymbols: *mut ::libc::size_t, + ) -> *mut LLVMOrcSymbolStringPoolEntryRef; + pub fn LLVMOrcDisposeSymbols(Symbols: *mut LLVMOrcSymbolStringPoolEntryRef); + pub fn LLVMOrcMaterializationResponsibilityNotifyResolved( + MR: LLVMOrcMaterializationResponsibilityRef, + Symbols: LLVMOrcCSymbolMapPairs, + NumPairs: ::libc::size_t, + ) -> LLVMErrorRef; + pub fn LLVMOrcMaterializationResponsibilityNotifyEmitted( + MR: LLVMOrcMaterializationResponsibilityRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcMaterializationResponsibilityDefineMaterializing( + MR: LLVMOrcMaterializationResponsibilityRef, + Pairs: LLVMOrcCSymbolFlagsMapPairs, + NumPairs: ::libc::size_t, + ) -> LLVMErrorRef; + pub fn LLVMOrcMaterializationResponsibilityFailMaterialization( + MR: LLVMOrcMaterializationResponsibilityRef, + ); + pub fn LLVMOrcMaterializationResponsibilityReplace( + MR: LLVMOrcMaterializationResponsibilityRef, + MU: LLVMOrcMaterializationUnitRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcMaterializationResponsibilityDelegate( + MR: LLVMOrcMaterializationResponsibilityRef, + Symbols: *mut LLVMOrcSymbolStringPoolEntryRef, + NumSymbols: ::libc::size_t, + Result: *mut LLVMOrcMaterializationResponsibilityRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcMaterializationResponsibilityAddDependencies( + MR: LLVMOrcMaterializationResponsibilityRef, + Name: LLVMOrcSymbolStringPoolEntryRef, + Dependencies: LLVMOrcCDependenceMapPairs, + NumPairs: ::libc::size_t, + ); + pub fn LLVMOrcMaterializationResponsibilityAddDependenciesForAll( + MR: LLVMOrcMaterializationResponsibilityRef, + Dependencies: LLVMOrcCDependenceMapPairs, + NumPairs: ::libc::size_t, + ); + pub fn LLVMOrcExecutionSessionCreateBareJITDylib( + ES: LLVMOrcExecutionSessionRef, + Name: *const ::libc::c_char, + ) -> LLVMOrcJITDylibRef; + pub fn LLVMOrcExecutionSessionCreateJITDylib( + ES: LLVMOrcExecutionSessionRef, + Result_: *mut LLVMOrcJITDylibRef, + Name: *const ::libc::c_char, + ) -> LLVMErrorRef; + pub fn LLVMOrcExecutionSessionGetJITDylibByName( + ES: LLVMOrcExecutionSessionRef, + Name: *const ::libc::c_char, + ) -> LLVMOrcJITDylibRef; + pub fn LLVMOrcJITDylibCreateResourceTracker( + JD: LLVMOrcJITDylibRef, + ) -> LLVMOrcResourceTrackerRef; + pub fn LLVMOrcJITDylibGetDefaultResourceTracker( + JD: LLVMOrcJITDylibRef, + ) -> LLVMOrcResourceTrackerRef; + pub fn LLVMOrcJITDylibDefine( + JD: LLVMOrcJITDylibRef, + MU: LLVMOrcMaterializationUnitRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcJITDylibClear(JD: LLVMOrcJITDylibRef) -> LLVMErrorRef; + pub fn LLVMOrcJITDylibAddGenerator(JD: LLVMOrcJITDylibRef, DG: LLVMOrcDefinitionGeneratorRef); + pub fn LLVMOrcCreateCustomCAPIDefinitionGenerator( + F: LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction, + Ctx: *mut ::libc::c_void, + Dispose: LLVMOrcDisposeCAPIDefinitionGeneratorFunction, + ) -> LLVMOrcDefinitionGeneratorRef; + pub fn LLVMOrcLookupStateContinueLookup( + S: LLVMOrcLookupStateRef, + Err: LLVMErrorRef, + ); + pub fn LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( + Result: *mut LLVMOrcDefinitionGeneratorRef, + GlobalPrefix: ::libc::c_char, + Filter: LLVMOrcSymbolPredicate, + FilterCtx: *mut ::libc::c_void, + ) -> LLVMErrorRef; + pub fn LLVMOrcCreateDynamicLibrarySearchGeneratorForPath( + Result: *mut LLVMOrcDefinitionGeneratorRef, + FileName: *const ::libc::c_char, + GlobalPrefix: ::libc::c_char, + Filter: LLVMOrcSymbolPredicate, + FilterCtx: *mut ::libc::c_void, + ) -> LLVMErrorRef; + pub fn LLVMOrcCreateStaticLibrarySearchGeneratorForPath( + Result: *mut LLVMOrcDefinitionGeneratorRef, + ObjLayer: LLVMOrcObjectLayerRef, + FileName: *const ::libc::c_char, + TargetTriple: *const ::libc::c_char, + ) -> LLVMErrorRef; + pub fn LLVMOrcCreateNewThreadSafeContext() -> LLVMOrcThreadSafeContextRef; + pub fn LLVMOrcThreadSafeContextGetContext(TSCtx: LLVMOrcThreadSafeContextRef) + -> LLVMContextRef; + pub fn LLVMOrcDisposeThreadSafeContext(TSCtx: LLVMOrcThreadSafeContextRef); + pub fn LLVMOrcCreateNewThreadSafeModule( + M: LLVMModuleRef, + TSCtx: LLVMOrcThreadSafeContextRef, + ) -> LLVMOrcThreadSafeModuleRef; + pub fn LLVMOrcDisposeThreadSafeModule(TSM: LLVMOrcThreadSafeModuleRef); + pub fn LLVMOrcThreadSafeModuleWithModuleDo( + TSM: LLVMOrcThreadSafeModuleRef, + F: LLVMOrcGenericIRModuleOperationFunction, + Ctx: *mut ::libc::c_void, + ) -> LLVMErrorRef; + pub fn LLVMOrcJITTargetMachineBuilderDetectHost( + Result: *mut LLVMOrcJITTargetMachineBuilderRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine( + TM: LLVMTargetMachineRef, + ) -> LLVMOrcJITTargetMachineBuilderRef; + pub fn LLVMOrcDisposeJITTargetMachineBuilder(JTMB: LLVMOrcJITTargetMachineBuilderRef); + pub fn LLVMOrcJITTargetMachineBuilderGetTargetTriple( + JTMB: LLVMOrcJITTargetMachineBuilderRef, + ) -> *mut ::libc::c_char; + pub fn LLVMOrcJITTargetMachineBuilderSetTargetTriple( + JTMB: LLVMOrcJITTargetMachineBuilderRef, + TargetTriple: *const ::libc::c_char, + ); + pub fn LLVMOrcObjectLayerAddObjectFile( + ObjLayer: LLVMOrcObjectLayerRef, + JD: LLVMOrcJITDylibRef, + ObjBuffer: LLVMMemoryBufferRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcObjectLayerAddObjectFileWithRT( + ObjLayer: LLVMOrcObjectLayerRef, + RT: LLVMOrcResourceTrackerRef, + ObjBuffer: LLVMMemoryBufferRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcObjectLayerEmit( + ObjLayer: LLVMOrcObjectLayerRef, + R: LLVMOrcMaterializationResponsibilityRef, + ObjBuffer: LLVMMemoryBufferRef, + ); + pub fn LLVMOrcDisposeObjectLayer(ObjLayer: LLVMOrcObjectLayerRef); + pub fn LLVMOrcIRTransformLayerEmit( + IRTransformLayer: LLVMOrcIRTransformLayerRef, + MR: LLVMOrcMaterializationResponsibilityRef, + TSM: LLVMOrcThreadSafeModuleRef, + ); + pub fn LLVMOrcIRTransformLayerSetTransform( + IRTransformLayer: LLVMOrcIRTransformLayerRef, + TransformFunction: LLVMOrcIRTransformLayerTransformFunction, + Ctx: *mut ::libc::c_void, + ); + pub fn LLVMOrcObjectTransformLayerSetTransform( + ObjTransformLayer: LLVMOrcObjectTransformLayerRef, + TransformFunction: LLVMOrcObjectTransformLayerTransformFunction, + Ctx: *mut ::libc::c_void, + ); + pub fn LLVMOrcCreateLocalIndirectStubsManager( + TargetTriple: *const ::libc::c_char, + ) -> LLVMOrcIndirectStubsManagerRef; + pub fn LLVMOrcDisposeIndirectStubsManager(ISM: LLVMOrcIndirectStubsManagerRef); + pub fn LLVMOrcCreateLocalLazyCallThroughManager( + TargetTriple: *const ::libc::c_char, + ES: LLVMOrcExecutionSessionRef, + ErrorHandlerAddr: LLVMOrcJITTargetAddress, + LCTM: *mut LLVMOrcLazyCallThroughManagerRef, + ) -> LLVMErrorRef; + pub fn LLVMOrcDisposeLazyCallThroughManager(LCTM: LLVMOrcLazyCallThroughManagerRef); + pub fn LLVMOrcCreateDumpObjects( + DumpDir: *const ::libc::c_char, + IdentifierOverride: *const ::libc::c_char, + ) -> LLVMOrcDumpObjectsRef; + pub fn LLVMOrcDisposeDumpObjects(DumpObjects: LLVMOrcDumpObjectsRef); + pub fn LLVMOrcDumpObjects_CallOperator( + DumpObjects: LLVMOrcDumpObjectsRef, + ObjBuffer: *mut LLVMMemoryBufferRef, + ) -> LLVMErrorRef; +} diff --git a/ext/llvm-sys.rs/src/remarks.rs b/ext/llvm-sys.rs/src/remarks.rs new file mode 100644 index 0000000..b8b022c --- /dev/null +++ b/ext/llvm-sys.rs/src/remarks.rs @@ -0,0 +1,134 @@ +//! Remark diagnostics library. +use prelude::LLVMBool; + +#[repr(C)] +pub enum LLVMRemarkType { + LLVMRemarkTypeUnknown, + LLVMRemarkTypePassed, + LLVMRemarkTypeMissed, + LLVMRemarkTypeAnalysis, + LLVMRemarkTypeAnalysisFPCommute, + LLVMRemarkTypeAnalysisAliasing, + LLVMRemarkTypeFailure, +} + +pub enum LLVMRemarkOpaqueString {} + +/// String containing a buffer and a length. The buffer is not guaranteed to be zero-terminated. +pub type LLVMRemarkStringRef = *mut LLVMRemarkOpaqueString; + +extern "C" { + /// Returns the buffer holding the string. + pub fn LLVMRemarkStringGetData(String: LLVMRemarkStringRef) -> *const ::libc::c_char; + + /// Returns the size of the string. + pub fn LLVMRemarkStringGetLen(String: LLVMRemarkStringRef) -> u32; +} + +pub enum LLVMRemarkOpaqueDebugLoc {} + +/// DebugLoc containing File, Line and Column. +pub type LLVMRemarkDebugLocRef = *mut LLVMRemarkOpaqueDebugLoc; + +extern "C" { + /// Return the path to the source file for a debug location. + pub fn LLVMRemarkDebugLocGetSourceFilePath(DL: LLVMRemarkDebugLocRef) -> LLVMRemarkStringRef; + + /// Return the line in the source file for a debug location. + pub fn LLVMRemarkDebugLocGetSourceLine(DL: LLVMRemarkDebugLocRef) -> u32; + + /// Return the column in the source file for a debug location. + pub fn LLVMRemarkDebugLocGetSourceColumn(DL: LLVMRemarkDebugLocRef) -> u32; +} + +pub enum LLVMRemarkOpaqueArg {} + +/// Element of the "Args" list. The key might give more information about what +/// the semantics of the value are, e.g. "Callee" will tell you that the value +/// is a symbol that names a function. +pub type LLVMRemarkArgRef = *mut LLVMRemarkOpaqueArg; + +extern "C" { + /// Returns the key of an argument. The key defines what the value is, and the + /// same key can appear multiple times in the list of arguments. + pub fn LLVMRemarkArgGetKey(Arg: LLVMRemarkArgRef) -> LLVMRemarkStringRef; + + /// Returns the value of an argument. This is a string that can contain newlines. + pub fn LLVMRemarkArgGetValue(Arg: LLVMRemarkArgRef) -> LLVMRemarkStringRef; + + /// Returns the debug location that is attached to the value of this argument. + pub fn LLVMRemarkArgGetDebugLoc(Arg: LLVMRemarkArgRef) -> LLVMRemarkDebugLocRef; +} + +pub enum LLVMRemarkOpaqueEntry {} +/// A remark emitted by the compiler. +pub type LLVMRemarkEntryRef = *mut LLVMRemarkOpaqueEntry; + +extern "C" { + /// Free the resources used by the remark entry. + pub fn LLVMRemarkEntryDispose(Remark: LLVMRemarkEntryRef); + + /// The type of the remark. For example, it can allow users to only keep the + /// missed optimizations from the compiler. + pub fn LLVMRemarkEntryGetType(Remark: LLVMRemarkEntryRef) -> LLVMRemarkType; + + /// Get the name of the pass that emitted this remark. + pub fn LLVMRemarkEntryGetPassName(Remark: LLVMRemarkEntryRef) -> LLVMRemarkStringRef; + + /// Get an identifier of the remark. + pub fn LLVMRemarkEntryGetRemarkName(Remark: LLVMRemarkEntryRef) -> LLVMRemarkStringRef; + + /// Get the name of the function being processed when the remark was emitted. + pub fn LLVMRemarkEntryGetFunctionName(Remark: LLVMRemarkEntryRef) -> LLVMRemarkStringRef; + + /// Returns the debug location that is attached to this remark. + pub fn LLVMRemarkEntryGetDebugLoc(Remark: LLVMRemarkEntryRef) -> LLVMRemarkDebugLocRef; + + /// Return the hotness of the remark. + pub fn LLVMRemarkEntryGetHotness(Remark: LLVMRemarkEntryRef) -> u64; + + /// The number of arguments the remark holds. + pub fn LLVMRemarkEntryGetNumArgs(Remark: LLVMRemarkEntryRef) -> u32; + + /// Get a new iterator to iterate over a remark's argument. + pub fn LLVMRemarkEntryGetFirstArg(Remark: LLVMRemarkEntryRef) -> LLVMRemarkArgRef; + + /// Get the next argument in Remark from the position of It. + pub fn LLVMRemarkEntryGetNextArg( + It: LLVMRemarkArgRef, + Remark: LLVMRemarkEntryRef, + ) -> LLVMRemarkArgRef; +} + +pub enum LLVMRemarkOpaqueParser {} +pub type LLVMRemarkParserRef = *mut LLVMRemarkOpaqueParser; + +extern "C" { + /// Creates a remark parser that can be used to parse the buffer located in + /// Buf of size Size bytes. + pub fn LLVMRemarkParserCreateYAML(Buf: *const ::libc::c_void, Size: u64) + -> LLVMRemarkParserRef; + + pub fn LLVMRemarkParserCreateBitstream( + Buf: *const ::libc::c_void, + Size: u64, + ) -> LLVMRemarkParserRef; + + /// Returns the next remark in the file. + pub fn LLVMRemarkParserGetNext(Parser: LLVMRemarkParserRef) -> LLVMRemarkEntryRef; + + /// Returns `1` if the parser encountered an error while parsing the buffer. + pub fn LLVMRemarkParserHasError(Parser: LLVMRemarkParserRef) -> LLVMBool; + + /// Returns a null-terminated string containing an error message. + pub fn LLVMRemarkParserGetErrorMessage(Parser: LLVMRemarkParserRef) -> *const ::libc::c_char; + + pub fn LLVMRemarkParserDispose(Parser: LLVMRemarkParserRef); +} + +pub const REMARKS_API_VERSION: u32 = 1; + +extern "C" { + /// Returns the version of the remarks library. + pub fn LLVMRemarkVersion() -> u32; +} diff --git a/ext/llvm-sys.rs/src/support.rs b/ext/llvm-sys.rs/src/support.rs new file mode 100644 index 0000000..d22c083 --- /dev/null +++ b/ext/llvm-sys.rs/src/support.rs @@ -0,0 +1,22 @@ +use super::prelude::*; + +extern "C" { + pub fn LLVMLoadLibraryPermanently(Filename: *const ::libc::c_char) -> LLVMBool; + pub fn LLVMParseCommandLineOptions( + argc: ::libc::c_int, + argv: *const *const ::libc::c_char, + Overview: *const ::libc::c_char, + ); + /// Search all previously loaded dynamic libraries for the named symbol. + /// + /// Returns its address if found, otherwise null. + /// + /// Added in LLVM 3.7. + pub fn LLVMSearchForAddressOfSymbol(symbolName: *const ::libc::c_char) -> *mut ::libc::c_void; + /// Permanently add the named symbol with the provided value. + /// + /// Symbols added this way are searched before any libraries. + /// + /// Added in LLVM 3.7. + pub fn LLVMAddSymbol(symbolName: *const ::libc::c_char, symbolValue: *mut ::libc::c_void); +} diff --git a/ext/llvm-sys.rs/src/target.rs b/ext/llvm-sys.rs/src/target.rs new file mode 100644 index 0000000..8620790 --- /dev/null +++ b/ext/llvm-sys.rs/src/target.rs @@ -0,0 +1,195 @@ +//! Target information + +use super::prelude::*; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMByteOrdering { + LLVMBigEndian = 0, + LLVMLittleEndian = 1, +} + +#[derive(Debug)] +pub enum LLVMOpaqueTargetData {} + +pub type LLVMTargetDataRef = *mut LLVMOpaqueTargetData; + +#[derive(Debug)] +pub enum LLVMOpaqueTargetLibraryInfotData {} + +pub type LLVMTargetLibraryInfoRef = *mut LLVMOpaqueTargetLibraryInfotData; + +extern "C" { + pub fn LLVMInitializeAMDGPUTargetInfo(); + pub fn LLVMInitializeAMDGPUTarget(); + pub fn LLVMInitializeAMDGPUTargetMC(); + pub fn LLVMInitializeAMDGPUAsmPrinter(); + pub fn LLVMInitializeAMDGPUAsmParser(); + // Disassembler? + + pub fn LLVMInitializeSystemZTargetInfo(); + pub fn LLVMInitializeSystemZTarget(); + pub fn LLVMInitializeSystemZTargetMC(); + pub fn LLVMInitializeSystemZAsmPrinter(); + pub fn LLVMInitializeSystemZAsmParser(); + pub fn LLVMInitializeSystemZDisassembler(); + + pub fn LLVMInitializeHexagonTargetInfo(); + pub fn LLVMInitializeHexagonTarget(); + pub fn LLVMInitializeHexagonTargetMC(); + pub fn LLVMInitializeHexagonAsmPrinter(); + // AsmParser? + pub fn LLVMInitializeHexagonDisassembler(); + + pub fn LLVMInitializeNVPTXTargetInfo(); + pub fn LLVMInitializeNVPTXTarget(); + pub fn LLVMInitializeNVPTXTargetMC(); + pub fn LLVMInitializeNVPTXAsmPrinter(); + // AsmParser? + + pub fn LLVMInitializeMSP430TargetInfo(); + pub fn LLVMInitializeMSP430Target(); + pub fn LLVMInitializeMSP430TargetMC(); + pub fn LLVMInitializeMSP430AsmPrinter(); + // AsmParser? + + pub fn LLVMInitializeXCoreTargetInfo(); + pub fn LLVMInitializeXCoreTarget(); + pub fn LLVMInitializeXCoreTargetMC(); + pub fn LLVMInitializeXCoreAsmPrinter(); + // AsmParser? + pub fn LLVMInitializeXCoreDisassembler(); + + pub fn LLVMInitializeMipsTargetInfo(); + pub fn LLVMInitializeMipsTarget(); + pub fn LLVMInitializeMipsTargetMC(); + pub fn LLVMInitializeMipsAsmPrinter(); + pub fn LLVMInitializeMipsAsmParser(); + pub fn LLVMInitializeMipsDisassembler(); + + pub fn LLVMInitializeAArch64TargetInfo(); + pub fn LLVMInitializeAArch64Target(); + pub fn LLVMInitializeAArch64TargetMC(); + pub fn LLVMInitializeAArch64AsmPrinter(); + pub fn LLVMInitializeAArch64AsmParser(); + pub fn LLVMInitializeAArch64Disassembler(); + + pub fn LLVMInitializeARMTargetInfo(); + pub fn LLVMInitializeARMTarget(); + pub fn LLVMInitializeARMTargetMC(); + pub fn LLVMInitializeARMAsmPrinter(); + pub fn LLVMInitializeARMAsmParser(); + pub fn LLVMInitializeARMDisassembler(); + + pub fn LLVMInitializePowerPCTargetInfo(); + pub fn LLVMInitializePowerPCTarget(); + pub fn LLVMInitializePowerPCTargetMC(); + pub fn LLVMInitializePowerPCAsmPrinter(); + pub fn LLVMInitializePowerPCAsmParser(); + pub fn LLVMInitializePowerPCDisassembler(); + + pub fn LLVMInitializeSparcTargetInfo(); + pub fn LLVMInitializeSparcTarget(); + pub fn LLVMInitializeSparcTargetMC(); + pub fn LLVMInitializeSparcAsmPrinter(); + pub fn LLVMInitializeSparcAsmParser(); + pub fn LLVMInitializeSparcDisassembler(); + + pub fn LLVMInitializeX86TargetInfo(); + pub fn LLVMInitializeX86Target(); + pub fn LLVMInitializeX86TargetMC(); + pub fn LLVMInitializeX86AsmPrinter(); + pub fn LLVMInitializeX86AsmParser(); + pub fn LLVMInitializeX86Disassembler(); + + pub fn LLVMInitializeBPFTargetInfo(); + pub fn LLVMInitializeBPFTarget(); + pub fn LLVMInitializeBPFTargetMC(); + pub fn LLVMInitializeBPFAsmPrinter(); + // No AsmParser + pub fn LLVMInitializeBPFDisassembler(); + + pub fn LLVMInitializeLanaiTargetInfo(); + pub fn LLVMInitializeLanaiTarget(); + pub fn LLVMInitializeLanaiTargetMC(); + pub fn LLVMInitializeLanaiAsmPrinter(); + pub fn LLVMInitializeLanaiAsmParser(); + pub fn LLVMInitializeLanaiDisassembler(); + + pub fn LLVMInitializeRISCVTargetInfo(); + pub fn LLVMInitializeRISCVTarget(); + pub fn LLVMInitializeRISCVTargetMC(); + pub fn LLVMInitializeRISCVAsmPrinter(); + pub fn LLVMInitializeRISCVAsmParser(); + pub fn LLVMInitializeRISCVDisassembler(); + + pub fn LLVMInitializeWebAssemblyTargetInfo(); + pub fn LLVMInitializeWebAssemblyTarget(); + pub fn LLVMInitializeWebAssemblyTargetMC(); + pub fn LLVMInitializeWebAssemblyAsmPrinter(); + pub fn LLVMInitializeWebAssemblyAsmParser(); + pub fn LLVMInitializeWebAssemblyDisassembler(); +} + +extern "C" { + /// Get the data layout for a module. + pub fn LLVMGetModuleDataLayout(M: LLVMModuleRef) -> LLVMTargetDataRef; + /// Set the data layout for a module. + pub fn LLVMSetModuleDataLayout(M: LLVMModuleRef, R: LLVMTargetDataRef); + /// Create target data from a target layout string. + pub fn LLVMCreateTargetData(StringRep: *const ::libc::c_char) -> LLVMTargetDataRef; + pub fn LLVMAddTargetLibraryInfo(TLI: LLVMTargetLibraryInfoRef, PM: LLVMPassManagerRef); + pub fn LLVMCopyStringRepOfTargetData(TD: LLVMTargetDataRef) -> *mut ::libc::c_char; + pub fn LLVMByteOrder(TD: LLVMTargetDataRef) -> LLVMByteOrdering; + pub fn LLVMPointerSize(TD: LLVMTargetDataRef) -> ::libc::c_uint; + pub fn LLVMPointerSizeForAS(TD: LLVMTargetDataRef, AS: ::libc::c_uint) -> ::libc::c_uint; + //pub fn LLVMIntPtrType(TD: LLVMTargetDataRef) -> LLVMTypeRef; + //pub fn LLVMIntPtrTypeForAS(TD: LLVMTargetDataRef, AS: ::libc::c_uint) -> LLVMTypeRef; + pub fn LLVMIntPtrTypeInContext(C: LLVMContextRef, TD: LLVMTargetDataRef) -> LLVMTypeRef; + pub fn LLVMIntPtrTypeForASInContext( + C: LLVMContextRef, + TD: LLVMTargetDataRef, + AS: ::libc::c_uint, + ) -> LLVMTypeRef; + pub fn LLVMSizeOfTypeInBits(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_ulonglong; + pub fn LLVMStoreSizeOfType(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_ulonglong; + pub fn LLVMABISizeOfType(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_ulonglong; + pub fn LLVMABIAlignmentOfType(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMCallFrameAlignmentOfType(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMPreferredAlignmentOfType(TD: LLVMTargetDataRef, Ty: LLVMTypeRef) -> ::libc::c_uint; + pub fn LLVMPreferredAlignmentOfGlobal( + TD: LLVMTargetDataRef, + GlobalVar: LLVMValueRef, + ) -> ::libc::c_uint; + pub fn LLVMElementAtOffset( + TD: LLVMTargetDataRef, + StructTy: LLVMTypeRef, + Offset: ::libc::c_ulonglong, + ) -> ::libc::c_uint; + pub fn LLVMOffsetOfElement( + TD: LLVMTargetDataRef, + StructTy: LLVMTypeRef, + Element: ::libc::c_uint, + ) -> ::libc::c_ulonglong; + pub fn LLVMDisposeTargetData(TD: LLVMTargetDataRef); +} + +// Functions from our target wrappers, since the C interface defines them with +// macros (wrappers/target.c). +extern "C" { + pub fn LLVM_InitializeAllTargetInfos(); + pub fn LLVM_InitializeAllTargets(); + pub fn LLVM_InitializeAllTargetMCs(); + pub fn LLVM_InitializeAllAsmPrinters(); + pub fn LLVM_InitializeAllAsmParsers(); + pub fn LLVM_InitializeAllDisassemblers(); + + /// Returns 1 on failure. + pub fn LLVM_InitializeNativeTarget() -> LLVMBool; + /// Returns 1 on failure. + pub fn LLVM_InitializeNativeAsmParser() -> LLVMBool; + /// Returns 1 on failure. + pub fn LLVM_InitializeNativeAsmPrinter() -> LLVMBool; + /// Returns 1 on failure. + pub fn LLVM_InitializeNativeDisassembler() -> LLVMBool; +} diff --git a/ext/llvm-sys.rs/src/target_machine.rs b/ext/llvm-sys.rs/src/target_machine.rs new file mode 100644 index 0000000..6189db2 --- /dev/null +++ b/ext/llvm-sys.rs/src/target_machine.rs @@ -0,0 +1,111 @@ +//! Target machine information, to generate assembly or object files. + +use super::prelude::*; +use super::target::LLVMTargetDataRef; + +#[derive(Debug)] +pub enum LLVMOpaqueTargetMachine {} + +pub type LLVMTargetMachineRef = *mut LLVMOpaqueTargetMachine; + +#[derive(Debug)] +pub enum LLVMTarget {} + +pub type LLVMTargetRef = *mut LLVMTarget; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMCodeGenOptLevel { + LLVMCodeGenLevelNone = 0, + LLVMCodeGenLevelLess = 1, + LLVMCodeGenLevelDefault = 2, + LLVMCodeGenLevelAggressive = 3, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMRelocMode { + LLVMRelocDefault = 0, + LLVMRelocStatic = 1, + LLVMRelocPIC = 2, + LLVMRelocDynamicNoPic = 3, + LLVMRelocROPI = 4, + LLVMRelocRWPI = 5, + LLVMRelocROPI_RWPI = 6, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMCodeModel { + LLVMCodeModelDefault = 0, + LLVMCodeModelJITDefault = 1, + LLVMCodeModelTiny = 2, + LLVMCodeModelSmall = 3, + LLVMCodeModelKernel = 4, + LLVMCodeModelMedium = 5, + LLVMCodeModelLarge = 6, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LLVMCodeGenFileType { + LLVMAssemblyFile = 0, + LLVMObjectFile = 1, +} + +extern "C" { + pub fn LLVMGetFirstTarget() -> LLVMTargetRef; + pub fn LLVMGetNextTarget(T: LLVMTargetRef) -> LLVMTargetRef; + pub fn LLVMGetTargetFromName(Name: *const ::libc::c_char) -> LLVMTargetRef; + pub fn LLVMGetTargetFromTriple( + Triple: *const ::libc::c_char, + T: *mut LLVMTargetRef, + ErrorMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMGetTargetName(T: LLVMTargetRef) -> *const ::libc::c_char; + pub fn LLVMGetTargetDescription(T: LLVMTargetRef) -> *const ::libc::c_char; + pub fn LLVMTargetHasJIT(T: LLVMTargetRef) -> LLVMBool; + pub fn LLVMTargetHasTargetMachine(T: LLVMTargetRef) -> LLVMBool; + pub fn LLVMTargetHasAsmBackend(T: LLVMTargetRef) -> LLVMBool; + pub fn LLVMCreateTargetMachine( + T: LLVMTargetRef, + Triple: *const ::libc::c_char, + CPU: *const ::libc::c_char, + Features: *const ::libc::c_char, + Level: LLVMCodeGenOptLevel, + Reloc: LLVMRelocMode, + CodeModel: LLVMCodeModel, + ) -> LLVMTargetMachineRef; + pub fn LLVMDisposeTargetMachine(T: LLVMTargetMachineRef); + pub fn LLVMGetTargetMachineTarget(T: LLVMTargetMachineRef) -> LLVMTargetRef; + pub fn LLVMGetTargetMachineTriple(T: LLVMTargetMachineRef) -> *mut ::libc::c_char; + pub fn LLVMGetTargetMachineCPU(T: LLVMTargetMachineRef) -> *mut ::libc::c_char; + pub fn LLVMGetTargetMachineFeatureString(T: LLVMTargetMachineRef) -> *mut ::libc::c_char; + /// Create a DataLayout based on the target machine. + pub fn LLVMCreateTargetDataLayout(T: LLVMTargetMachineRef) -> LLVMTargetDataRef; + pub fn LLVMSetTargetMachineAsmVerbosity(T: LLVMTargetMachineRef, VerboseAsm: LLVMBool); + pub fn LLVMTargetMachineEmitToFile( + T: LLVMTargetMachineRef, + M: LLVMModuleRef, + Filename: *mut ::libc::c_char, + codegen: LLVMCodeGenFileType, + ErrorMessage: *mut *mut ::libc::c_char, + ) -> LLVMBool; + pub fn LLVMTargetMachineEmitToMemoryBuffer( + T: LLVMTargetMachineRef, + M: LLVMModuleRef, + codegen: LLVMCodeGenFileType, + ErrorMessage: *mut *mut ::libc::c_char, + OutMemBuf: *mut LLVMMemoryBufferRef, + ) -> LLVMBool; + + pub fn LLVMGetDefaultTargetTriple() -> *mut ::libc::c_char; + /// Normalize a target triple. The result needs to be disposed with LLVMDisposeMessage. + pub fn LLVMNormalizeTargetTriple(triple: *const ::libc::c_char) -> *mut ::libc::c_char; + /// Get the host CPU as a string. The result needs to be disposed with LLVMDisposeMessage. + pub fn LLVMGetHostCPUName() -> *mut ::libc::c_char; + /// Get the host CPU's features as a string. The result needs to be disposed with LLVMDisposeMessage. + pub fn LLVMGetHostCPUFeatures() -> *mut ::libc::c_char; + + pub fn LLVMAddAnalysisPasses(T: LLVMTargetMachineRef, PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms.rs b/ext/llvm-sys.rs/src/transforms.rs new file mode 100644 index 0000000..2d8f0b0 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms.rs @@ -0,0 +1,8 @@ +use super::*; + +// Util +extern "C" { + pub fn LLVMAddLowerSwitchPass(PM: LLVMPassManagerRef ); + +pub fn LLVMAddPromoteMemoryToRegisterPass(PM: LLVMPassManagerRef ); +} diff --git a/ext/llvm-sys.rs/src/transforms/aggressive_instcombine.rs b/ext/llvm-sys.rs/src/transforms/aggressive_instcombine.rs new file mode 100644 index 0000000..e3bebde --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/aggressive_instcombine.rs @@ -0,0 +1,5 @@ +use prelude::*; + +extern "C" { + pub fn LLVMAddAggressiveInstCombinerPass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/instcombine.rs b/ext/llvm-sys.rs/src/transforms/instcombine.rs new file mode 100644 index 0000000..afc0269 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/instcombine.rs @@ -0,0 +1,5 @@ +use super::super::prelude::*; + +extern "C" { + pub fn LLVMAddInstructionCombiningPass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/ipo.rs b/ext/llvm-sys.rs/src/transforms/ipo.rs new file mode 100644 index 0000000..17c470b --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/ipo.rs @@ -0,0 +1,25 @@ +//! Interprocedural transformations of LLVM IR. + +use super::super::prelude::*; + +extern "C" { + pub fn LLVMAddConstantMergePass(PM: LLVMPassManagerRef); + pub fn LLVMAddMergeFunctionsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddCalledValuePropagationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddDeadArgEliminationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddFunctionAttrsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddFunctionInliningPass(PM: LLVMPassManagerRef); + pub fn LLVMAddAlwaysInlinerPass(PM: LLVMPassManagerRef); + pub fn LLVMAddGlobalDCEPass(PM: LLVMPassManagerRef); + pub fn LLVMAddGlobalOptimizerPass(PM: LLVMPassManagerRef); + pub fn LLVMAddPruneEHPass(PM: LLVMPassManagerRef); + pub fn LLVMAddIPSCCPPass(PM: LLVMPassManagerRef); + pub fn LLVMAddInternalizePass(arg1: LLVMPassManagerRef, AllButMain: ::libc::c_uint); + pub fn LLVMAddInternalizePassWithMustPreservePredicate( + PM: LLVMPassManagerRef, + Context: *mut ::libc::c_void, + MustPreserve: Option LLVMBool>, + ); + pub fn LLVMAddStripDeadPrototypesPass(PM: LLVMPassManagerRef); + pub fn LLVMAddStripSymbolsPass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/pass_builder.rs b/ext/llvm-sys.rs/src/transforms/pass_builder.rs new file mode 100644 index 0000000..42c4d94 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/pass_builder.rs @@ -0,0 +1,64 @@ +#![allow(non_snake_case)] + +use super::super::prelude::*; +use error::LLVMErrorRef; +use target_machine::LLVMTargetMachineRef; + +#[derive(Debug)] +pub enum LLVMOpaquePassBuilderOptions {} +pub type LLVMPassBuilderOptionsRef = *mut LLVMOpaquePassBuilderOptions; + +extern "C" { + pub fn LLVMRunPasses( + M: LLVMModuleRef, + Passes: *const ::libc::c_char, + TM: LLVMTargetMachineRef, + Options: LLVMPassBuilderOptionsRef, + ) -> LLVMErrorRef; + pub fn LLVMCreatePassBuilderOptions() -> LLVMPassBuilderOptionsRef; + pub fn LLVMPassBuilderOptionsSetVerifyEach( + Options: LLVMPassBuilderOptionsRef, + VerifyEach: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetDebugLogging( + Options: LLVMPassBuilderOptionsRef, + DebugLogging: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetLoopInterleaving( + Options: LLVMPassBuilderOptionsRef, + LoopInterleaving: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetLoopVectorization( + Options: LLVMPassBuilderOptionsRef, + LoopVectorization: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetSLPVectorization( + Options: LLVMPassBuilderOptionsRef, + SLPVectorization: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetLoopUnrolling( + Options: LLVMPassBuilderOptionsRef, + LoopUnrolling: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll( + Options: LLVMPassBuilderOptionsRef, + ForgetAllSCEVInLoopUnroll: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetLicmMssaOptCap( + Options: LLVMPassBuilderOptionsRef, + LicmMssaOptCap: ::libc::c_uint, + ); + pub fn LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap( + Options: LLVMPassBuilderOptionsRef, + LicmMssaNoAccForPromotionCap: ::libc::c_uint, + ); + pub fn LLVMPassBuilderOptionsSetCallGraphProfile( + Options: LLVMPassBuilderOptionsRef, + CallGraphProfile: LLVMBool, + ); + pub fn LLVMPassBuilderOptionsSetMergeFunctions( + Options: LLVMPassBuilderOptionsRef, + MergeFunctions: LLVMBool, + ); + pub fn LLVMDisposePassBuilderOptions(Options: LLVMPassBuilderOptionsRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/pass_manager_builder.rs b/ext/llvm-sys.rs/src/transforms/pass_manager_builder.rs new file mode 100644 index 0000000..61f5404 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/pass_manager_builder.rs @@ -0,0 +1,43 @@ +use super::super::prelude::*; + +#[derive(Debug)] +pub enum LLVMOpaquePassManagerBuilder {} + +pub type LLVMPassManagerBuilderRef = *mut LLVMOpaquePassManagerBuilder; + +extern "C" { + pub fn LLVMPassManagerBuilderCreate() -> LLVMPassManagerBuilderRef; + pub fn LLVMPassManagerBuilderDispose(PMB: LLVMPassManagerBuilderRef); + pub fn LLVMPassManagerBuilderSetOptLevel( + PMB: LLVMPassManagerBuilderRef, + OptLevel: ::libc::c_uint, + ); + pub fn LLVMPassManagerBuilderSetSizeLevel( + PMB: LLVMPassManagerBuilderRef, + SizeLevel: ::libc::c_uint, + ); + pub fn LLVMPassManagerBuilderSetDisableUnitAtATime( + PMB: LLVMPassManagerBuilderRef, + Value: LLVMBool, + ); + pub fn LLVMPassManagerBuilderSetDisableUnrollLoops( + PMB: LLVMPassManagerBuilderRef, + Value: LLVMBool, + ); + pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls( + PMB: LLVMPassManagerBuilderRef, + Value: LLVMBool, + ); + pub fn LLVMPassManagerBuilderUseInlinerWithThreshold( + PMB: LLVMPassManagerBuilderRef, + Threshold: ::libc::c_uint, + ); + pub fn LLVMPassManagerBuilderPopulateFunctionPassManager( + PMB: LLVMPassManagerBuilderRef, + PM: LLVMPassManagerRef, + ); + pub fn LLVMPassManagerBuilderPopulateModulePassManager( + PMB: LLVMPassManagerBuilderRef, + PM: LLVMPassManagerRef, + ); +} diff --git a/ext/llvm-sys.rs/src/transforms/scalar.rs b/ext/llvm-sys.rs/src/transforms/scalar.rs new file mode 100644 index 0000000..d4e1a96 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/scalar.rs @@ -0,0 +1,51 @@ +//! Scalar transformations of LLVM IR. + +use super::super::prelude::*; + +extern "C" { + pub fn LLVMAddAggressiveDCEPass(PM: LLVMPassManagerRef); + pub fn LLVMAddDCEPass(PM: LLVMPassManagerRef); + pub fn LLVMAddBitTrackingDCEPass(PM: LLVMPassManagerRef); + pub fn LLVMAddAlignmentFromAssumptionsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddCFGSimplificationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddDeadStoreEliminationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddScalarizerPass(PM: LLVMPassManagerRef); + pub fn LLVMAddMergedLoadStoreMotionPass(PM: LLVMPassManagerRef); + pub fn LLVMAddGVNPass(PM: LLVMPassManagerRef); + pub fn LLVMAddNewGVNPass(PM: LLVMPassManagerRef); + pub fn LLVMAddIndVarSimplifyPass(PM: LLVMPassManagerRef); + pub fn LLVMAddInstructionCombiningPass(PM: LLVMPassManagerRef); + pub fn LLVMAddInstructionSimplifyPass(PM: LLVMPassManagerRef); + pub fn LLVMAddJumpThreadingPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLICMPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopDeletionPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopIdiomPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopRotatePass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopRerollPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopUnrollPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLoopUnrollAndJamPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLowerAtomicPass(PM: LLVMPassManagerRef); + pub fn LLVMAddMemCpyOptPass(PM: LLVMPassManagerRef); + pub fn LLVMAddPartiallyInlineLibCallsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddReassociatePass(PM: LLVMPassManagerRef); + pub fn LLVMAddSCCPPass(PM: LLVMPassManagerRef); + pub fn LLVMAddScalarReplAggregatesPass(PM: LLVMPassManagerRef); + pub fn LLVMAddScalarReplAggregatesPassSSA(PM: LLVMPassManagerRef); + pub fn LLVMAddScalarReplAggregatesPassWithThreshold( + PM: LLVMPassManagerRef, + Threshold: ::libc::c_int, + ); + pub fn LLVMAddSimplifyLibCallsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddTailCallEliminationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddDemoteMemoryToRegisterPass(PM: LLVMPassManagerRef); + pub fn LLVMAddVerifierPass(PM: LLVMPassManagerRef); + pub fn LLVMAddCorrelatedValuePropagationPass(PM: LLVMPassManagerRef); + pub fn LLVMAddEarlyCSEPass(PM: LLVMPassManagerRef); + pub fn LLVMAddEarlyCSEMemSSAPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLowerExpectIntrinsicPass(PM: LLVMPassManagerRef); + pub fn LLVMAddLowerConstantIntrinsicsPass(PM: LLVMPassManagerRef); + pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: LLVMPassManagerRef); + pub fn LLVMAddScopedNoAliasAAPass(PM: LLVMPassManagerRef); + pub fn LLVMAddBasicAliasAnalysisPass(PM: LLVMPassManagerRef); + pub fn LLVMAddUnifyFunctionExitNodesPass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/util.rs b/ext/llvm-sys.rs/src/transforms/util.rs new file mode 100644 index 0000000..6193902 --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/util.rs @@ -0,0 +1,9 @@ +use super::super::prelude::*; + +extern "C" { + pub fn LLVMAddLowerSwitchPass(PM: LLVMPassManagerRef); + + pub fn LLVMAddPromoteMemoryToRegisterPass(PM: LLVMPassManagerRef); + + pub fn LLVMAddAddDiscriminatorsPass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/src/transforms/vectorize.rs b/ext/llvm-sys.rs/src/transforms/vectorize.rs new file mode 100644 index 0000000..2a4bd9c --- /dev/null +++ b/ext/llvm-sys.rs/src/transforms/vectorize.rs @@ -0,0 +1,8 @@ +//! Vectorization transformations of LLVM IR. + +use super::super::prelude::*; + +extern "C" { + pub fn LLVMAddLoopVectorizePass(PM: LLVMPassManagerRef); + pub fn LLVMAddSLPVectorizePass(PM: LLVMPassManagerRef); +} diff --git a/ext/llvm-sys.rs/wrappers/target.c b/ext/llvm-sys.rs/wrappers/target.c new file mode 100644 index 0000000..66035c1 --- /dev/null +++ b/ext/llvm-sys.rs/wrappers/target.c @@ -0,0 +1,48 @@ +/* llvm-c/Target.h helper functions wrappers. + * + * The LLVMInitializeAll* functions and friends are defined `static inline`, so + * we can't bind directly to them (the function body is generated via macro), + * so here are some wrappers. + */ +#include + +void LLVM_InitializeAllTargetInfos(void) { + LLVMInitializeAllTargetInfos(); +} + +void LLVM_InitializeAllTargets(void) { + LLVMInitializeAllTargets(); +} + +void LLVM_InitializeAllTargetMCs(void) { + LLVMInitializeAllTargetMCs(); +} + +void LLVM_InitializeAllAsmPrinters(void) { + LLVMInitializeAllAsmPrinters(); +} + +void LLVM_InitializeAllAsmParsers(void) { + LLVMInitializeAllAsmParsers(); +} + +void LLVM_InitializeAllDisassemblers(void) { + LLVMInitializeAllDisassemblers(); +} + +/* These functions return true on failure. */ +LLVMBool LLVM_InitializeNativeTarget(void) { + return LLVMInitializeNativeTarget(); +} + +LLVMBool LLVM_InitializeNativeAsmParser(void) { + return LLVMInitializeNativeAsmParser(); +} + +LLVMBool LLVM_InitializeNativeAsmPrinter(void) { + return LLVMInitializeNativeAsmPrinter(); +} + +LLVMBool LLVM_InitializeNativeDisassembler(void) { + return LLVMInitializeNativeDisassembler(); +} diff --git a/ext/optix_ext/README.md b/ext/optix_ext/README.md new file mode 100644 index 0000000..3214139 --- /dev/null +++ b/ext/optix_ext/README.md @@ -0,0 +1,10 @@ +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__compile__no__inline_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__compile__no__inline__function__table__definition_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__compile__no__inline__stubs_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__knobs_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__knobs__function__table__definition_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__knobs__stubs_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__ptx__encryption_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__ptx__encryption__function__table__definition_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__ptx__encryption__stubs_8h_source.html +https://raytracing-docs.nvidia.com/optix6/api_6_5/html/optix__ext__ptx__encryption__utilities_8h_source.html \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_compile_no_inline.h b/ext/optix_ext/optix_ext_compile_no_inline.h new file mode 100644 index 0000000..9d39161 --- /dev/null +++ b/ext/optix_ext/optix_ext_compile_no_inline.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_compile_no_inline_h__ +#define __optix_optix_ext_compile_no_inline_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// This will enable or disable the compilation of non-inlined functions as seen by OptiX in any known modules. +// The property cannot be changed after the compilation of the first module. +OptixResult optixExtCompileNoInlineSetEnabled( OptixDeviceContext contextAPI, bool enabled ); +// Query the current value, i.e., whether or not the compilation of non-inlined functions is enabled. +bool optixExtCompileNoInlineIsEnabled( OptixDeviceContext contextAPI ); + + +#ifdef OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +// When changing the ABI version make sure you know exactly what you are doing. See +// apps/optix/exp/functionTable/functionTable.cpp for instructions. See +// https://confluence.nvidia.com/display/RAV/ABI+Versions+in+the+Wild for released ABI versions. +#endif // OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +#define OPTIX_EXT_COMPILE_NO_INLINE_ABI_VERSION 3001 + +typedef struct OptixExtCompileNoInlineFunctionTable +{ + OptixResult ( *optixExtCompileNoInlineSetEnabled )( OptixDeviceContext contextAPI, bool enabled ); + bool ( *optixExtCompileNoInlineIsEnabled )( OptixDeviceContext contextAPI ); + +} OptixExtCompileNoInlineFunctionTable; + + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_compile_no_inline_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_compile_no_inline_function_table_definition.h b/ext/optix_ext/optix_ext_compile_no_inline_function_table_definition.h new file mode 100644 index 0000000..116cbab --- /dev/null +++ b/ext/optix_ext/optix_ext_compile_no_inline_function_table_definition.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_compile_no_inline_function_table_definition_h__ +#define __optix_optix_ext_compile_no_inline_function_table_definition_h__ + +#include "optix_ext_compile_no_inline.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If the stubs in optix_ext_compile_no_inline_stubs.h are used, then the function table needs to be + defined in exactly one translation unit. This can be achieved by including this header file in + that translation unit. */ +OptixExtCompileNoInlineFunctionTable g_optixExtCompileNoInlineFunctionTable; + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_compile_no_inline_function_table_definition_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_compile_no_inline_stubs.h b/ext/optix_ext/optix_ext_compile_no_inline_stubs.h new file mode 100644 index 0000000..22c8c35 --- /dev/null +++ b/ext/optix_ext/optix_ext_compile_no_inline_stubs.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __optix_optix_ext_compile_no_inline_stubs_h__ +#define __optix_optix_ext_compile_no_inline_stubs_h__ + +#include "optix_ext_compile_no_inline.h" + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The function table needs to be defined in exactly one translation unit. This can be + achieved by including optix_ext_compile_no_inline_function_table_definition.h in that translation unit. + */ +extern OptixExtCompileNoInlineFunctionTable g_optixExtCompileNoInlineFunctionTable; + +// Initializes the function table used by the stubs for the extension API for compile_no_inline. +// +// The function requires a handle to the loaded OptiX library. This handle can be obtained by using +// optixInitWithHandle() instead of optixInit(), for example (error handling ommitted): +// +// void* handle; +// optixInitWithHandle( &handle ); +// optixExtCompileNoInlineInit( handle ); +// +inline OptixResult optixExtCompileNoInlineInit( void* handle ) +{ + if( !handle ) + return OPTIX_ERROR_INVALID_VALUE; + +#ifdef _WIN32 + void* symbol = GetProcAddress( (HMODULE)handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#else + void* symbol = dlsym( handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#endif + + OptixQueryFunctionTable_t* optixQueryFunctionTable = (OptixQueryFunctionTable_t*)symbol; + + return optixQueryFunctionTable( OPTIX_EXT_COMPILE_NO_INLINE_ABI_VERSION, 0, 0, 0, &g_optixExtCompileNoInlineFunctionTable, + sizeof( g_optixExtCompileNoInlineFunctionTable ) ); +} + +/* Stub functions that forward calls to the corresponding function pointer in the function table. */ + +inline OptixResult optixExtCompileNoInlineSetEnabled( OptixDeviceContext contextAPI, bool enabled ) +{ + return g_optixExtCompileNoInlineFunctionTable.optixExtCompileNoInlineSetEnabled( contextAPI, enabled ); +} + +inline bool optixExtCompileNoInlineIsEnabled( OptixDeviceContext contextAPI ) +{ + return g_optixExtCompileNoInlineFunctionTable.optixExtCompileNoInlineIsEnabled( contextAPI ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_compile_no_inline_stubs_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_knobs.h b/ext/optix_ext/optix_ext_knobs.h new file mode 100644 index 0000000..ac86018 --- /dev/null +++ b/ext/optix_ext/optix_ext_knobs.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_knobs_h__ +#define __optix_optix_ext_knobs_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Sets values of multiple knobs based on some configuration file. +// +// Comments start with two slashes and are stripped. Whitespace at the begin and end of each line is also stripped. +// Empty lines are ignored. The first non-whitespace to whitespace transition marks the end of the name of the knob, +// the following whitespace is also stripped. The remainder of the line is the value of the knob, unless it is quoted +// by double apostrophes, which are also stripped. +// +// This method can only be used before the first device context has been created. +OptixResult optixExtKnobsSetKnobsFromFile( const char* filename ); + +// Sets the value of a single knob. +// +// This method can only be used before the first device context has been created. +OptixResult optixExtKnobsSetKnob( const char* name, const char* value ); + + +#ifdef OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +// When changing the ABI version make sure you know exactly what you are doing. See +// apps/optix/exp/functionTable/functionTable.cpp for instructions. See +// https://confluence.nvidia.com/display/RAV/ABI+Versions+in+the+Wild for released ABI versions. +#endif // OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +#define OPTIX_EXT_KNOBS_ABI_VERSION 1001 + +typedef struct OptixExtKnobsFunctionTable +{ + OptixResult ( *optixExtKnobsSetKnobsFromFile )( const char* filename ); + + OptixResult ( *optixExtKnobsSetKnob )( const char* name, const char* value ); + +} OptixExtKnobsFunctionTable; + + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_knobs_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_knobs_function_table_definition.h b/ext/optix_ext/optix_ext_knobs_function_table_definition.h new file mode 100644 index 0000000..30bdde8 --- /dev/null +++ b/ext/optix_ext/optix_ext_knobs_function_table_definition.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_knobs_function_table_definition_h__ +#define __optix_optix_ext_knobs_function_table_definition_h__ + +#include "optix_ext_knobs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If the stubs in optix_ext_knobs_stubs.h are used, then the function table needs to be + defined in exactly one translation unit. This can be achieved by including this header file in + that translation unit. */ +OptixExtKnobsFunctionTable g_optixExtKnobsFunctionTable; + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_knobs_function_table_definition_h__ */ diff --git a/ext/optix_ext/optix_ext_knobs_stubs.h b/ext/optix_ext/optix_ext_knobs_stubs.h new file mode 100644 index 0000000..18e1837 --- /dev/null +++ b/ext/optix_ext/optix_ext_knobs_stubs.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __optix_optix_ext_knobs_stubs_h__ +#define __optix_optix_ext_knobs_stubs_h__ + +#include "optix_ext_knobs.h" + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The function table needs to be defined in exactly one translation unit. This can be + achieved by including optix_ext_knobs_function_table_definition.h in that translation unit. + */ +extern OptixExtKnobsFunctionTable g_optixExtKnobsFunctionTable; + +// Initializes the function table used by the stubs for the extension API for knobs. +// +// The function requires a handle to the loaded OptiX library. This handle can be obtained by using +// optixInitWithHandle() instead of optixInit(), for example (error handling ommitted): +// +// void* handle; +// optixInitWithHandle( &handle ); +// optixExtKnobsInit( handle ); +// +inline OptixResult optixExtKnobsInit( void* handle ) +{ + if( !handle ) + return OPTIX_ERROR_INVALID_VALUE; + +#ifdef _WIN32 + void* symbol = GetProcAddress( (HMODULE)handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#else + void* symbol = dlsym( handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#endif + + OptixQueryFunctionTable_t* optixQueryFunctionTable = (OptixQueryFunctionTable_t*)symbol; + + return optixQueryFunctionTable( OPTIX_EXT_KNOBS_ABI_VERSION, 0, 0, 0, &g_optixExtKnobsFunctionTable, + sizeof( g_optixExtKnobsFunctionTable ) ); +} + +/* Stub functions that forward calls to the corresponding function pointer in the function table. */ + +inline OptixResult optixExtKnobsSetKnobsFromFile( const char* filename ) +{ + return g_optixExtKnobsFunctionTable.optixExtKnobsSetKnobsFromFile( filename ); +} + +inline OptixResult optixExtKnobsSetKnob( const char* name, const char* value ) +{ + return g_optixExtKnobsFunctionTable.optixExtKnobsSetKnob( name, value ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_knobs_stubs_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_ptx_encryption.h b/ext/optix_ext/optix_ext_ptx_encryption.h new file mode 100644 index 0000000..23cc62b --- /dev/null +++ b/ext/optix_ext/optix_ext_ptx_encryption.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_ptx_encryption_h__ +#define __optix_optix_ext_ptx_encryption_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Returns the OptiX salt for PTX encryption. The buffer for the salt value must consist of 32 bytes. +// +// Instead of using this function directly, consider using the C++ interface optix::PtxEncryption. This utility class +// also takes care of computing the session key needed for encryption. +OptixResult optixExtPtxEncryptionGetOptixSalt( OptixDeviceContext context, void* optixSalt, size_t optixSaltSizeInBytes ); + +// Sets the OptiX salt for PTX encryption. The salt value must consist of 32 bytes. +// +// Instead of using this function directly, consider using the C++ interface optix::PtxEncryption. This utility class +// also takes care of computing the session key needed for encryption. +OptixResult optixExtPtxEncryptionSetOptixSalt( OptixDeviceContext context, const void* optixSalt, size_t optixSaltSizeInBytes ); + +// Sets the vendor salt for PTX encryption. The salt value must consist of 32 bytes. +// +// Instead of using this function directly, consider using the C++ interface optix::PtxEncryption. This utility class +// also takes care of computing the session key needed for encryption. +OptixResult optixExtPtxEncryptionSetVendorSalt( OptixDeviceContext context, const void* vendorSalt, size_t vendorSaltSizeInBytes ); + +// Sets the public vendor key for PTX encryption. +// +// Instead of using this function directly, consider using the C++ interface optix::PtxEncryption. This utility class +// also takes care of computing the session key needed for encryption. +OptixResult optixExtPtxEncryptionSetPublicVendorKey( OptixDeviceContext context, const void* publicVendorKey, size_t publicVendorKeySizeInBytes ); + + +#ifdef OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +// When changing the ABI version make sure you know exactly what you are doing. See +// apps/optix/exp/functionTable/functionTable.cpp for instructions. See +// https://confluence.nvidia.com/display/RAV/ABI+Versions+in+the+Wild for released ABI versions. +#endif // OPTIX_OPTIONAL_FEATURE_OPTIX7_INTERNAL_DOCUMENTATION +#define OPTIX_EXT_PTX_ENCRYPTION_ABI_VERSION 2001 + +typedef struct OptixExtPtxEncryptionFunctionTable +{ + OptixResult ( *optixExtPtxEncryptionGetOptixSalt )( OptixDeviceContext context, void* optixSalt, size_t optixSaltSizeInBytes ); + + OptixResult ( *optixExtPtxEncryptionSetOptixSalt )( OptixDeviceContext context, const void* optixSalt, size_t optixSaltSizeInBytes ); + + OptixResult ( *optixExtPtxEncryptionSetVendorSalt )( OptixDeviceContext context, const void* vendorSalt, size_t vendorSaltSizeInBytes ); + + OptixResult ( *optixExtPtxEncryptionSetPublicVendorKey )( OptixDeviceContext context, + const void* publicVendorKey, + size_t publicVendorKeySizeInBytes ); + +} OptixExtPtxEncryptionFunctionTable; + + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_ptx_encryption_h__ */ \ No newline at end of file diff --git a/ext/optix_ext/optix_ext_ptx_encryption_function_table_definition.h b/ext/optix_ext/optix_ext_ptx_encryption_function_table_definition.h new file mode 100644 index 0000000..35415ac --- /dev/null +++ b/ext/optix_ext/optix_ext_ptx_encryption_function_table_definition.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and proprietary + * rights in and to this software, related documentation and any modifications thereto. + * Any use, reproduction, disclosure or distribution of this software and related + * documentation without an express license agreement from NVIDIA Corporation is strictly + * prohibited. + * + * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* + * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT + * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF + * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES + */ + +#ifndef __optix_optix_ext_ptx_encryption_function_table_definition_h__ +#define __optix_optix_ext_ptx_encryption_function_table_definition_h__ + +#include "optix_ext_ptx_encryption.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If the stubs in optix_ext_ptx_encryption_stubs.h are used, then the function table needs to be + defined in exactly one translation unit. This can be achieved by including this header file in + that translation unit. */ +OptixExtPtxEncryptionFunctionTable g_optixExtPtxEncryptionFunctionTable; + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_ptx_encryption_function_table_definition_h__ */ diff --git a/ext/optix_ext/optix_ext_ptx_encryption_stubs.h b/ext/optix_ext/optix_ext_ptx_encryption_stubs.h new file mode 100644 index 0000000..4157d95 --- /dev/null +++ b/ext/optix_ext/optix_ext_ptx_encryption_stubs.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __optix_optix_ext_ptx_encryption_stubs_h__ +#define __optix_optix_ext_ptx_encryption_stubs_h__ + +#include "optix_ext_ptx_encryption.h" + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The function table needs to be defined in exactly one translation unit. This can be + achieved by including optix_ext_ptx_encryption_function_table_definition.h in that translation unit. + */ +extern OptixExtPtxEncryptionFunctionTable g_optixExtPtxEncryptionFunctionTable; + +// Initializes the function table used by the stubs for the extension API for PTX encryption. +// +// The function requires a handle to the loaded OptiX library. This handle can be obtained by using +// optixInitWithHandle() instead of optixInit(), for example (error handling ommitted): +// +// void* handle; +// optixInitWithHandle( &handle ); +// optixExtPtxEncryptionInit( handle ); +// +inline OptixResult optixExtPtxEncryptionInit( void* handle ) +{ + if( !handle ) + return OPTIX_ERROR_INVALID_VALUE; + +#ifdef _WIN32 + void* symbol = GetProcAddress( (HMODULE)handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#else + void* symbol = dlsym( handle, "optixQueryFunctionTable" ); + if( !symbol ) + return OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND; +#endif + + OptixQueryFunctionTable_t* optixQueryFunctionTable = (OptixQueryFunctionTable_t*)symbol; + + return optixQueryFunctionTable( OPTIX_EXT_PTX_ENCRYPTION_ABI_VERSION, 0, 0, 0, &g_optixExtPtxEncryptionFunctionTable, + sizeof( g_optixExtPtxEncryptionFunctionTable ) ); +} + +/* Stub functions that forward calls to the corresponding function pointer in the function table. */ + +inline OptixResult optixExtPtxEncryptionGetOptixSalt( OptixDeviceContext context, void* optixSalt, size_t optixSaltSizeInBytes ) +{ + return g_optixExtPtxEncryptionFunctionTable.optixExtPtxEncryptionGetOptixSalt( context, optixSalt, optixSaltSizeInBytes ); +} + +inline OptixResult optixExtPtxEncryptionSetOptixSalt( OptixDeviceContext context, const void* optixSalt, size_t optixSaltSizeInBytes ) +{ + return g_optixExtPtxEncryptionFunctionTable.optixExtPtxEncryptionSetOptixSalt( context, optixSalt, optixSaltSizeInBytes ); +} + +inline OptixResult optixExtPtxEncryptionSetVendorSalt( OptixDeviceContext context, const void* vendorSalt, size_t vendorSaltSizeInBytes ) +{ + return g_optixExtPtxEncryptionFunctionTable.optixExtPtxEncryptionSetVendorSalt( context, vendorSalt, vendorSaltSizeInBytes ); +} + +inline OptixResult optixExtPtxEncryptionSetPublicVendorKey( OptixDeviceContext context, const void* publicVendorKey, size_t publicVendorKeySizeInBytes ) +{ + return g_optixExtPtxEncryptionFunctionTable.optixExtPtxEncryptionSetPublicVendorKey( context, publicVendorKey, + publicVendorKeySizeInBytes ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __optix_optix_ext_ptx_encryption_stubs_h__ */ diff --git a/ext/optix_ext/optix_ptx_encryption.h b/ext/optix_ext/optix_ptx_encryption.h new file mode 100644 index 0000000..0168723 --- /dev/null +++ b/ext/optix_ext/optix_ptx_encryption.h @@ -0,0 +1,416 @@ +// Copyright (c) 2017, NVIDIA CORPORATION. +// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS +// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES +// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, +// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) +// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS +// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + +#pragma once + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#undef min +#undef max +#undef IGNORE +#else +#include +#include +#include +#endif + +#include +#include +#include +#include + +#ifndef OPTIX_PTX_ENCRYPTION_STANDALONE +#include +#endif // OPTIX_PTX_ENCRYPTION_STANDALONE + +namespace optix { + +#ifndef OPTIX_PTX_ENCRYPTION_STANDALONE + +class PtxEncryption +{ + public: + PtxEncryption( RTcontext context, const char* publicVendorKey, const char* secretVendorKey ); + + PtxEncryption( Context context, const char* publicVendorKey, const char* secretVendorKey ); + + PtxEncryption( RTcontext context, const char* publicVendorKey, const char* secretVendorKey, const char* optixSalt, const char* vendorSalt ); + + PtxEncryption( Context context, const char* publicVendorKey, const char* secretVendorKey, const char* optixSalt, const char* vendorSalt ); + + ::std::string encrypt( const ::std::string& ptx ) const; + + static ::std::string getPrefix() { return "eptx0001"; } + + private: + // Magic number used by the TEA algorithm. + static const uint32_t MAGIC = 0x9e3779b9; + // Uses TEA to encrypt 8 bytes v[0] and v[1] using the key k. + static void encryptTeaBlock( uint32_t* v, const uint32_t k[4] ); + // Uses TEA to encrypt \p sz bytes at \p data using the key \p key. + static void encryptTea( unsigned char* data, size_t sz, const uint32_t key[4] ); + // Encodes the given string to ensure that it does not contain any null bytes. + static ::std::string encode( const ::std::vector& input ); + + // The session key used by #encrypt(). + ::std::vector m_sessionKey; +}; + +#endif // OPTIX_PTX_ENCRYPTION_STANDALONE + +namespace detail { + +// Generates a salt. +// +// \param[out] buffer The buffer for the salt. Needs to be able to hold 32 bytes. +void generateSalt( unsigned char* buffer ); + +// Computes a SHA256 hash value. +// +// \param input The input for which to compute the SHA256 hash value. +// \param input_length The size of the input. +// \param[out] buffer The buffer for the SHA256 hash value. Needs to be able to hold 32 bytes. +void sha256( const unsigned char* input, unsigned int input_length, unsigned char* buffer ); + +} // end namespace detail + +#ifndef OPTIX_PTX_ENCRYPTION_STANDALONE + +// Magic key used to obfuscate the last incomplete block. +const unsigned char KEY[7] = {164, 195, 147, 255, 203, 161, 184}; + +inline PtxEncryption::PtxEncryption( RTcontext context, const char* publicVendorKey, const char* secretVendorKeyHex ) +{ + // Get optix salt + const size_t optixSaltLength = 32; + unsigned char optixSalt[optixSaltLength]; + RTresult result = rtContextGetAttribute( context, RT_CONTEXT_ATTRIBUTE_OPTIX_SALT, 32, &optixSalt[0] ); + assert( result == RT_SUCCESS ); + (void)result; + + // Generate and set vendor salt + const size_t vendorSaltLength = 32; + unsigned char vendorSalt[vendorSaltLength]; + detail::generateSalt( &vendorSalt[0] ); + result = rtContextSetAttribute( context, RT_CONTEXT_ATTRIBUTE_VENDOR_SALT, 32, &vendorSalt[0] ); + assert( result == RT_SUCCESS ); + + // Set vendor public key + const size_t publicVendorKeyLength = strlen( publicVendorKey ); + result = rtContextSetAttribute( context, RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY, publicVendorKeyLength, &publicVendorKey[0] ); + assert( result == RT_SUCCESS ); + + // Generate sessionKey = hash(optixSalt, secretVendorKeyHex, vendorSalt). + const size_t secretVendorKeyHexLength = strlen( secretVendorKeyHex ); + const size_t sessionKeyInputLength = optixSaltLength + secretVendorKeyHexLength + vendorSaltLength; + ::std::vector sessionKeyInput( sessionKeyInputLength ); + memcpy( &sessionKeyInput[0], &optixSalt[0], optixSaltLength ); + memcpy( &sessionKeyInput[optixSaltLength], secretVendorKeyHex, secretVendorKeyHexLength ); + memcpy( &sessionKeyInput[optixSaltLength + secretVendorKeyHexLength], vendorSalt, vendorSaltLength ); + + m_sessionKey.resize( 32 ); + detail::sha256( &sessionKeyInput[0], static_cast( sessionKeyInputLength ), &m_sessionKey[0] ); + + for( size_t i = 0; i < 16; ++i ) + m_sessionKey[i] += m_sessionKey[i + 16]; + m_sessionKey.resize( 16 ); +} + +inline PtxEncryption::PtxEncryption( Context context, const char* publicVendorKey, const char* secretVendorKeyHex ) + : PtxEncryption( context->get(), publicVendorKey, secretVendorKeyHex ) +{ +} + +inline PtxEncryption::PtxEncryption( RTcontext context, + const char* publicVendorKey, + const char* secretVendorKeyHex, + const char* optixSalt, + const char* vendorSalt ) +{ + // Set optix salt + const size_t optixSaltLength = strlen( optixSalt ); + RTresult result = rtContextSetAttribute( context, RT_CONTEXT_ATTRIBUTE_OPTIX_SALT, optixSaltLength, optixSalt ); + assert( result == RT_SUCCESS ); + (void)result; + + // Set vendor salt + const size_t vendorSaltLength = strlen( vendorSalt ); + result = rtContextSetAttribute( context, RT_CONTEXT_ATTRIBUTE_VENDOR_SALT, vendorSaltLength, vendorSalt ); + assert( result == RT_SUCCESS ); + + // Set vendor public key + const size_t publicVendorKeyLength = strlen( publicVendorKey ); + result = rtContextSetAttribute( context, RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY, publicVendorKeyLength, &publicVendorKey[0] ); + assert( result == RT_SUCCESS ); + + // Generate sessionKey = hash(optixSalt, secretVendorKeyHex, vendorSalt). + const size_t secretVendorKeyHexLength = strlen( secretVendorKeyHex ); + const size_t sessionKeyInputLength = optixSaltLength + secretVendorKeyHexLength + vendorSaltLength; + ::std::vector sessionKeyInput( sessionKeyInputLength ); + memcpy( &sessionKeyInput[0], &optixSalt[0], optixSaltLength ); + memcpy( &sessionKeyInput[optixSaltLength], secretVendorKeyHex, secretVendorKeyHexLength ); + memcpy( &sessionKeyInput[optixSaltLength + secretVendorKeyHexLength], vendorSalt, vendorSaltLength ); + + m_sessionKey.resize( 32 ); + detail::sha256( &sessionKeyInput[0], static_cast( sessionKeyInputLength ), &m_sessionKey[0] ); + + for( size_t i = 0; i < 16; ++i ) + m_sessionKey[i] += m_sessionKey[i + 16]; + m_sessionKey.resize( 16 ); +} + +inline PtxEncryption::PtxEncryption( Context context, + const char* publicVendorKey, + const char* secretVendorKeyHex, + const char* optixSalt, + const char* vendorSalt ) + : PtxEncryption( context->get(), publicVendorKey, secretVendorKeyHex, optixSalt, vendorSalt ) +{ +} + +inline ::std::string PtxEncryption::encrypt( const ::std::string& ptx ) const +{ + uint32_t teaKey[4]; + assert( m_sessionKey.size() == sizeof( teaKey ) ); + memcpy( &teaKey[0], &m_sessionKey[0], sizeof( teaKey ) ); + + ::std::vector result( ptx.size() ); + memcpy( &result[0], &ptx[0], ptx.size() ); + encryptTea( &result[0], result.size(), teaKey ); + + return getPrefix() + encode( result ); +} + +inline ::std::string PtxEncryption::encode( const ::std::vector& input ) +{ + ::std::string output; + + // Replace '\0' by '\1\1' and '\1' by '\1\2'. + for( size_t i = 0; i < input.size(); ++i ) + { + char c = input[i]; + if( c == '\0' || c == '\1' ) + { + output.push_back( '\1' ); + output.push_back( c + 1 ); + } + else + output.push_back( c ); + } + + return output; +} + +inline void PtxEncryption::encryptTeaBlock( uint32_t* v, const uint32_t k[4] ) +{ + uint32_t v0 = v[0]; + uint32_t v1 = v[1]; + uint32_t s0 = 0; + + for( uint32_t n = 0; n < 16; n++ ) + { + s0 += MAGIC; + v0 += ( ( v1 << 4 ) + k[0] ) ^ ( v1 + s0 ) ^ ( ( v1 >> 5 ) + k[1] ); + v1 += ( ( v0 << 4 ) + k[2] ) ^ ( v0 + s0 ) ^ ( ( v0 >> 5 ) + k[3] ); + } + + v[0] = v0; + v[1] = v1; +} + +inline void PtxEncryption::encryptTea( unsigned char* data, size_t sz, const uint32_t key[4] ) +{ + // Encrypt 8 byte blocks with TEA + const size_t n = sz / static_cast( 8 ); + uint32_t* v = reinterpret_cast( data ); + for( size_t i = 0; i < n; ++i ) + encryptTeaBlock( &v[2 * i], key ); + + // Slightly obfuscate leftover bytes (at most 7) with simple xor. + for( size_t i = 8 * n, k = 0; i < sz; ++i, ++k ) + data[i] = data[i] ^ KEY[k]; +} + +#endif // OPTIX_PTX_ENCRYPTION_STANDALONE + +namespace detail { + +inline void generateSalt( unsigned char* buffer ) +{ + if( buffer == 0 ) + return; + + uint64_t number = 0; +#ifdef _WIN32 + srand( GetTickCount() ); + LARGE_INTEGER tmp; + QueryPerformanceCounter( &tmp ); + number += tmp.QuadPart + GetCurrentProcessId() + GetTickCount(); +#else + srand( static_cast( time( 0 ) ) ); + struct timeval tv; + gettimeofday( &tv, 0 ); + number += static_cast( tv.tv_sec + tv.tv_usec ); +#endif + + unsigned char buf[sizeof( uint32_t ) + 3 * sizeof( uint64_t )] = {0}; + int r = rand(); + memcpy( buf, &r, sizeof( uint32_t ) ); + memcpy( buf + sizeof( uint32_t ), &number, sizeof( uint64_t ) ); + memcpy( buf + sizeof( uint32_t ) + sizeof( uint64_t ), &number, sizeof( uint64_t ) ); + number += static_cast( rand() ); + memcpy( buf + sizeof( uint32_t ) + 2 * sizeof( uint64_t ), &number, sizeof( uint64_t ) ); + sha256( buf, static_cast( sizeof( buf ) ), buffer ); +} + +namespace { + +// Table of round constants. +// First 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311 +const uint32_t sha256_constants[] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, + 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, + 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, + 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, + 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, + 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, + 0xc67178f2}; + +// Reverses the byte order of the bytes of \p x +uint32_t flip32( uint32_t x ) +{ + return ( ( ( (x)&0xff000000 ) >> 24 ) | ( ( (x)&0x00ff0000 ) >> 8 ) | ( ( (x)&0x0000ff00 ) << 8 ) + | ( ( (x)&0x000000ff ) << 24 ) ); +} + +// Rotates the bits of \p x to the right by \p y bits +uint32_t rightrotate( uint32_t x, uint32_t y ) +{ + return ( ( x >> y ) | ( x << ( 32 - y ) ) ); +} + +} // end namespace + +inline void sha256( const unsigned char* input, unsigned int input_length, unsigned char* buffer ) +{ + if( ( input_length <= 0 ) || ( input == 0 ) || ( buffer == 0 ) ) + return; + + // First 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 + uint32_t state[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + + // k is the number of '0' bits >= 0 such that the resulting message length is 448 (mod 512) + unsigned int r = ( input_length * 8 + 1 ) % 512; + unsigned int k = r > 448 ? 960 - r : 448 - r; + + unsigned int pos = 0; + for( unsigned int chunk = 0; k != 0; ++chunk ) + { + uint32_t W[64] = {0}; + uint8_t* ptr = reinterpret_cast( W ); + unsigned int to_copy = input_length - pos; + to_copy = to_copy > 64 ? 64 : to_copy; + if( to_copy > 0 ) + { + memcpy( ptr, input + pos, to_copy ); + pos += to_copy; + } + + // If we are at the end of input message + if( pos == input_length ) + { + // If we still have not padded and have space to add a 1, add it + if( ( k > 0 ) && ( pos / 64 == chunk ) ) + ptr[pos % 64] |= static_cast( 0x80 ); + // If we can pad and still have space to add the length, add it + if( ( pos * 8 + 1 + k ) - ( chunk * 512 ) <= 448 ) + { + uint64_t value = input_length * 8; + ptr = reinterpret_cast( &W[14] ); + ptr[0] = static_cast( ( value >> 56 ) & 0xff ); + ptr[1] = static_cast( ( value >> 48 ) & 0xff ); + ptr[2] = static_cast( ( value >> 40 ) & 0xff ); + ptr[3] = static_cast( ( value >> 32 ) & 0xff ); + ptr[4] = static_cast( ( value >> 24 ) & 0xff ); + ptr[5] = static_cast( ( value >> 16 ) & 0xff ); + ptr[6] = static_cast( ( value >> 8 ) & 0xff ); + ptr[7] = static_cast( value & 0xff ); + k = 0; + } + } + + // Flip to big endian + for( int i = 0; i < 16; ++i ) + W[i] = flip32( W[i] ); + + // Extend the sixteen 32-bit words into 64 32-bit words + for( uint32_t i = 16; i < 64; ++i ) + { + uint32_t s0 = rightrotate( W[i - 15], 7 ) ^ rightrotate( W[i - 15], 18 ) ^ ( W[i - 15] >> 3 ); + uint32_t s1 = rightrotate( W[i - 2], 17 ) ^ rightrotate( W[i - 2], 19 ) ^ ( W[i - 2] >> 10 ); + W[i] = W[i - 16] + s0 + W[i - 7] + s1; + } + + // Initialize hash value for this chunk + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + uint32_t e = state[4]; + uint32_t f = state[5]; + uint32_t g = state[6]; + uint32_t h = state[7]; + + for( uint32_t j = 0; j < 64; ++j ) + { + uint32_t s0 = rightrotate( a, 2 ) ^ rightrotate( a, 13 ) ^ rightrotate( a, 22 ); + uint32_t maj = ( a & b ) ^ ( a & c ) ^ ( b & c ); + uint32_t t2 = s0 + maj; + uint32_t s1 = rightrotate( e, 6 ) ^ rightrotate( e, 11 ) ^ rightrotate( e, 25 ); + uint32_t ch = ( e & f ) ^ ( ( ~e ) & g ); + uint32_t t1 = h + s1 + ch + sha256_constants[j] + W[j]; + + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + // Add this chunk's hash value to result so far + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } + + // Flip to little endian + for( int i = 0; i < 8; ++i ) + state[i] = flip32( state[i] ); + + memcpy( buffer, reinterpret_cast( state ), 32 ); +} + +} // end namespace detail + +} // end namespace optix \ No newline at end of file diff --git a/ext/spirv-headers b/ext/spirv-headers deleted file mode 160000 index 308bd07..0000000 --- a/ext/spirv-headers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 308bd07424350a6000f35a77b5f85cd4f3da319e diff --git a/ext/spirv-tools b/ext/spirv-tools deleted file mode 160000 index e128ab0..0000000 --- a/ext/spirv-tools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e128ab0d624ce7beb08eb9656bb260c597a46d0a diff --git a/geekbench.svg b/geekbench.svg new file mode 100644 index 0000000..262f70c --- /dev/null +++ b/geekbench.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hip_common/Cargo.toml b/hip_common/Cargo.toml new file mode 100644 index 0000000..0f2accb --- /dev/null +++ b/hip_common/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "hip_common" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] + +[dependencies] +const_format = "0.2.30" +hip_runtime-sys = { path = "../hip_runtime-sys" } +cuda_types = { path = "../cuda_types" } +rusqlite = { version = "0.28.0", features = ["bundled", "serde_json"] } +sha2 = "0.10.2" +itertools = "0.10.5" +capnp = "0.17.2" +rustc-hash = "1.1" +goblin = { version = "0.5.1", default-features = false, features = ["elf64", "elf32", "endian_fd"] } +memchr = "2.5.0" +libloading = "0.8" + +[build-dependencies] +capnpc = "0.17.2" diff --git a/hip_common/src/cache.rs b/hip_common/src/cache.rs new file mode 100644 index 0000000..d241259 --- /dev/null +++ b/hip_common/src/cache.rs @@ -0,0 +1,257 @@ +use itertools::Itertools; +use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef}; +use rusqlite::Connection; +use std::ffi::{CStr, CString}; +use std::fmt::Display; +use std::marker::PhantomData; +use std::path::PathBuf; +use std::time::{self, SystemTime}; + +pub trait KernelExtendedData { + const INPUT_COLUMNS: &'static [[&'static str; 2]]; +} + +pub struct KernelRepository { + cache_file: Option, + insert_kernel: String, + update_last_used: String, + select_kernel: String, + _marker: PhantomData, +} + +// We do all that string concatenation during run time, because there is no +// good alternative. const_format crate implements const-time format!(), +// but it does not work with generic types. Maybe it works with &'static str +// const generics, but &'static str const generics are currently illegal +impl KernelRepository { + pub fn new(cache_file: Option) -> rusqlite::Result { + let create_tables = { + let input_columns = Self::columns_comma(T::INPUT_COLUMNS); + let input_columns_with_type = Self::columns_comma_type(T::INPUT_COLUMNS); + format!(" + CREATE TABLE IF NOT EXISTS kernels ( + id INTEGER PRIMARY KEY NOT NULL, + hash TEXT NOT NULL, + compiler_version TEXT NOT NULL, + git_hash TEXT NOT NULL, + device TEXT NOT NULL, + is_debug INTEGER NOT NULL, + is_windows BOOLEAN NOT NULL, + binary BLOB NOT NULL, + last_used INTEGER NOT NULL + {input_columns_with_type} + ); + CREATE UNIQUE INDEX IF NOT EXISTS kernels_index ON kernels (hash, compiler_version, git_hash, device, is_windows, is_debug {input_columns}); + CREATE TABLE IF NOT EXISTS globals ( + key TEXT PRIMARY KEY, + value INTEGER NOT NULL + ) WITHOUT ROWID; + CREATE TRIGGER IF NOT EXISTS update_size_on_delete + AFTER + DELETE ON kernels FOR EACH ROW BEGIN + UPDATE + globals + SET + value = value - length(OLD.binary) + WHERE + key = 'total_binary_size'; + END; + CREATE TRIGGER IF NOT EXISTS update_size_on_insert + AFTER + INSERT ON kernels FOR EACH ROW BEGIN + UPDATE + globals + SET + value = value + length(NEW.binary) + WHERE + key = 'total_binary_size'; + END; + INSERT OR IGNORE INTO globals (key, value) VALUES ('total_binary_size', 0);") + }; + let insert_kernel = { + let input_columns = Self::columns_comma(T::INPUT_COLUMNS); + let arg_markers = (0..T::INPUT_COLUMNS.len()) + .into_iter() + .format_with("", |_, f| f(&", ?")); + format!(" + INSERT INTO + kernels (last_used, hash, compiler_version, git_hash, device, is_windows, is_debug, binary {input_columns}) + VALUES + (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8 {arg_markers}) ON CONFLICT DO + UPDATE + SET + last_used = ?1;") + }; + let update_last_used = { + let input_columns = Self::columns_and(T::INPUT_COLUMNS); + format!(" + UPDATE + kernels + SET + last_used = ?1 + WHERE + hash = ?2 AND compiler_version = ?3 AND git_hash = ?4 AND device = ?5 AND is_windows = ?6 AND is_debug = ?7 {input_columns};") + }; + let select_kernel = { + let input_columns = Self::columns_and(T::INPUT_COLUMNS); + format!(" + SELECT + id, binary + FROM + kernels + WHERE + hash = ?1 AND compiler_version = ?2 AND git_hash = ?3 AND device = ?4 AND is_windows = ?5 AND is_debug = ?6 {input_columns};") + }; + let result = Self { + cache_file, + insert_kernel, + update_last_used, + select_kernel, + _marker: PhantomData, + }; + let mut connection = result.connect()?; + connection.pragma_update(None, "journal_mode", "WAL")?; + connection.pragma_update(None, "synchronous", "normal")?; + // Deferred transaction here can lead to SQLITE_BUSY errors + let tx = connection.transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)?; + { + tx.set_db_config( + rusqlite::config::DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY, + true, + )?; + tx.set_db_config( + rusqlite::config::DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER, + true, + )?; + tx.execute_batch(&create_tables)?; + } + tx.commit()?; + Ok(result) + } + + pub fn connect(&self) -> rusqlite::Result { + match self.cache_file { + Some(ref file) => rusqlite::Connection::open(file), + None => rusqlite::Connection::open_in_memory(), + } + } + + pub fn save_program( + &self, + now: i64, + hash: &str, + compiler_version: &str, + git_hash: &str, + device: &CStr, + binary: &[u8], + input_values: &[&dyn rusqlite::ToSql], + ) -> rusqlite::Result<()> { + let connection = self.connect()?; + let tx = connection.unchecked_transaction()?; + { + let mut insert_kernel = tx.prepare(&self.insert_kernel)?; + let common_values = rusqlite::params![ + now, + hash, + compiler_version, + git_hash, + SqlCStrRef(device), + cfg!(windows), + cfg!(debug_assertions), + binary + ]; + insert_kernel.execute(rusqlite::params_from_iter( + IntoIterator::into_iter([common_values, input_values]).flatten(), + ))?; + } + tx.commit() + } + + pub fn try_load_program( + &self, + now: i64, + hash: &str, + compiler_version: &str, + git_hash: &str, + device: &CStr, + input_values: &[&dyn rusqlite::ToSql], + ) -> rusqlite::Result>> { + let connection = self.connect()?; + let tx = connection.unchecked_transaction()?; + let result; + { + let common_params = rusqlite::params![ + now, + hash, + compiler_version, + git_hash, + SqlCStrRef(device), + cfg!(windows), + cfg!(debug_assertions) + ]; + let mut statement = tx.prepare(&self.update_last_used)?; + let rows_affected = statement.execute(rusqlite::params_from_iter( + IntoIterator::into_iter([common_params, input_values]).flatten(), + ))?; + if rows_affected == 0 { + return Ok(None); + } + let mut select_kernel = tx.prepare(&self.select_kernel)?; + let mut kernel_rows = select_kernel.query(rusqlite::params_from_iter( + IntoIterator::into_iter([&common_params[1..], input_values]).flatten(), + ))?; + if let Some(row) = kernel_rows.next()? { + let binary = row.get::<_, Vec>(1)?; + result = Some(binary); + } else { + result = None; + } + } + tx.commit()?; + Ok(result) + } + + fn columns_comma(columns: &'static [[&'static str; 2]]) -> impl Display { + columns + .iter() + .format_with("", |[name, _], f| f(&format_args!(", {name}"))) + } + + fn columns_comma_type(columns: &'static [[&'static str; 2]]) -> impl Display { + columns + .iter() + .format_with("", |[name, type_], f| f(&format_args!(", {name} {type_}"))) + } + + fn columns_and(columns: &'static [[&'static str; 2]]) -> impl Display { + columns + .iter() + .format_with("", |[name, _], f| f(&format_args!(" AND {name} = ?"))) + } + + pub fn now() -> Result { + let now = SystemTime::now().duration_since(time::UNIX_EPOCH)?; + Ok(now.as_millis() as i64) + } +} + +pub struct SqlCStrRef<'a>(pub &'a CStr); + +impl<'a> rusqlite::ToSql for SqlCStrRef<'a> { + fn to_sql(&self) -> rusqlite::Result> { + Ok(rusqlite::types::ToSqlOutput::Borrowed( + rusqlite::types::ValueRef::Text(self.0.to_bytes()), + )) + } +} + +pub struct SqlCString(pub CString); + +impl FromSql for SqlCString { + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + let str = value.as_str()?; + Ok(SqlCString( + CString::new(str.to_string()).map_err(|err| FromSqlError::Other(Box::new(err)))?, + )) + } +} diff --git a/hip_common/src/kernel_metadata.rs b/hip_common/src/kernel_metadata.rs new file mode 100644 index 0000000..754bc6e --- /dev/null +++ b/hip_common/src/kernel_metadata.rs @@ -0,0 +1,214 @@ +// TODO: instead of writing metadata to a temporary buffer. +// write it directly into a section string + +use crate::unwrap_or_return; +use goblin::elf::{Elf, SectionHeader}; +use std::ops::Range; + +pub fn get_section<'a>(section_name: &str, module: &'a [u8]) -> Option<&'a [u8]> { + let header = Elf::parse_header(module).ok()?; + if header.e_shoff == 0 { + return None; + } + let ctx = goblin::container::Ctx::new(header.container().ok()?, header.endianness().ok()?); + let section_headers = SectionHeader::parse( + module, + header.e_shoff as usize, + header.e_shnum as usize, + ctx, + ) + .ok()?; + let string_table_section_header = match section_headers.get(header.e_shstrndx as usize) { + Some(h) => h, + None => return None, + }; + let string_section = &module[section_range(string_table_section_header)]; + let zluda_rt_section_header = unwrap_or_return!( + section_headers.iter().find(|header| { + if let Some(nul_pos) = memchr::memchr(0, &string_section[header.sh_name..]) { + let name = &string_section[header.sh_name..header.sh_name + nul_pos]; + return name == section_name.as_bytes(); + } + false + }), + None + ); + Some(&module[section_range(zluda_rt_section_header)]) +} + +fn section_range(section: &SectionHeader) -> Range { + section.sh_offset as usize + ..(section.sh_offset as usize).saturating_add(section.sh_size as usize) +} + +pub mod zluda { + use crate::unwrap_or_continue; + use capnp::message::{ReaderOptions, TypedBuilder, TypedReader}; + use std::num::NonZeroU32; + + pub const SECTION_STR: &'static str = "zluda_meta"; + + pub fn write<'a>( + sm_version: u32, + kernels: impl ExactSizeIterator, Option)>, + ) -> Vec { + let mut builder = TypedBuilder::::new_default(); + let result = builder.init_root(); + let mut version1 = result.init_version1(); + version1.set_sm_version(sm_version); + let mut kernels_emitter = version1.init_kernels(kernels.len() as u32); + for (i, (name, min, max)) in kernels.enumerate() { + let mut kernel_emitter = kernels_emitter.reborrow().get(i as u32); + kernel_emitter.set_name(name); + let min = min.map(NonZeroU32::get).unwrap_or_default(); + kernel_emitter.set_min_goup_size(min); + let max = max.map(NonZeroU32::get).unwrap_or_default(); + kernel_emitter.set_max_group_size(max); + } + capnp::serialize::write_message_to_words(builder.borrow_inner()) + } + + pub fn read<'a>( + mut message: &'a [u8], + mut on_kernel: impl FnMut(&'a str, u32, u32), + ) -> Result { + let reader = + capnp::serialize::read_message_from_flat_slice(&mut message, ReaderOptions::new())?; + let typed_reader = TypedReader::<_, crate::zluda_capnp::metadata::Owned>::new(reader); + let root = typed_reader.get()?; + let version1 = root.get_version1()?; + let kernels = version1.get_kernels()?; + for kernel in kernels.iter() { + on_kernel( + // This just transmutes the lifetime + // The string slice points to the underlying `message` byte array, so it is safe + unsafe { std::mem::transmute(unwrap_or_continue!(kernel.get_name())) }, + kernel.get_min_goup_size(), + kernel.get_max_group_size(), + ); + } + Ok(version1.get_sm_version()) + } +} + +pub mod zluda_rt6 { + use crate::raytracing::{Variable, VariablesBlock}; + use capnp::message::{ReaderOptions, TypedBuilder, TypedReader}; + use rustc_hash::FxHashMap; + use std::{alloc::Layout, ffi::CString}; + + pub const SECTION_STR: &'static str = "zluda_rt6_meta"; + + pub fn write( + attributes: &VariablesBlock, + variables: &VariablesBlock, + is_callable: bool, + ) -> Vec { + let mut builder = TypedBuilder::::new_default(); + let result = builder.init_root(); + let mut version1 = result.init_version1(); + version1.set_attributes_align(attributes.layout.align() as u32); + version1.set_attributes_size(attributes.layout.size() as u32); + let mut attributes_builder = version1 + .reborrow() + .init_attributes(attributes.variables.len() as u32); + for (idx, (name, var)) in attributes.variables.iter().enumerate() { + let mut attribute_builder = attributes_builder.reborrow().get(idx as u32); + attribute_builder.set_name(&name.as_c_str().to_string_lossy()); + attribute_builder.set_offset(var.offset); + attribute_builder.set_size(var.size); + } + version1.set_variables_align(variables.layout.align() as u32); + version1.set_variables_size(variables.layout.size() as u32); + let mut variables_builder = version1 + .reborrow() + .init_variables(variables.variables.len() as u32); + for (idx, (name, var)) in variables.variables.iter().enumerate() { + let mut variables_builder = variables_builder.reborrow().get(idx as u32); + variables_builder.set_name(&name.as_c_str().to_string_lossy()); + variables_builder.set_offset(var.offset); + variables_builder.set_size(var.size); + variables_builder.set_default_value(&var.default_value); + } + version1.set_is_callable(is_callable); + capnp::serialize::write_message_to_words(builder.borrow_inner()) + } + + pub fn read(mut message: &[u8]) -> Result { + let reader = + capnp::serialize::read_message_from_flat_slice(&mut message, ReaderOptions::new())?; + let typed_reader = TypedReader::<_, crate::zluda_rt6_capnp::metadata::Owned>::new(reader); + let root = typed_reader.get()?; + let version1 = root.get_version1()?; + let mut attribute_variables = FxHashMap::default(); + let attribute_size = version1.get_attributes_size(); + let attribute_align = version1.get_attributes_align(); + for attribute in version1.get_attributes()? { + let name = attribute.get_name()?; + let offset = attribute.get_offset(); + let size = attribute.get_size(); + attribute_variables.insert( + CString::new(name).map_err(|err| capnp::Error { + kind: capnp::ErrorKind::Failed, + description: err.to_string(), + })?, + Variable { + offset, + size, + default_value: Vec::new(), + }, + ); + } + let attribute_variables = new_block(attribute_variables, attribute_size, attribute_align)?; + let variables_size = version1.get_variables_size(); + let variables_align = version1.get_variables_align(); + let mut variables = FxHashMap::default(); + for variable in version1.get_variables()? { + let name = variable.get_name()?; + let offset = variable.get_offset(); + let size = variable.get_size(); + let default_value = variable.get_default_value()?.to_vec(); + variables.insert( + CString::new(name).map_err(|err| capnp::Error { + kind: capnp::ErrorKind::Failed, + description: err.to_string(), + })?, + Variable { + offset, + size, + default_value, + }, + ); + } + let variables = new_block(variables, variables_size, variables_align)?; + let is_callable = version1.get_is_callable(); + Ok(Metadata { + attribute_variables, + variables, + is_callable, + }) + } + + fn new_block( + variables: FxHashMap, + size: u32, + align: u32, + ) -> Result { + let attribute_variables = VariablesBlock { + variables, + layout: Layout::from_size_align(size as usize, align as usize).map_err(|err| { + capnp::Error { + kind: capnp::ErrorKind::Failed, + description: err.to_string(), + } + })?, + }; + Ok(attribute_variables) + } + + pub struct Metadata { + pub attribute_variables: VariablesBlock, + pub variables: VariablesBlock, + pub is_callable: bool, + } +} diff --git a/hip_common/src/lib.rs b/hip_common/src/lib.rs new file mode 100644 index 0000000..356bdf9 --- /dev/null +++ b/hip_common/src/lib.rs @@ -0,0 +1,117 @@ +use hip_runtime_sys::*; +use std::{ + ffi::{CStr, CString}, + mem, +}; + +pub mod cache; +pub mod kernel_metadata; +pub mod raytracing; +#[allow(dead_code)] +mod zluda_capnp; +pub mod zluda_ext; +#[allow(dead_code)] +mod zluda_rt6_capnp; + +#[macro_export] +macro_rules! hip { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(err); + } + } + }; +} + +#[macro_export] +macro_rules! cuda { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != cuda_types::CUresult::CUDA_SUCCESS { + return Result::Err(err); + } + } + }; +} + +#[macro_export] +macro_rules! unwrap_or_return { + ( $e:expr ) => { + match $e { + Ok(x) => x, + Err(_) => return, + } + }; + ( $e:expr, $err:expr ) => { + match $e { + Some(x) => x, + None => return $err, + } + }; +} + +#[macro_export] +macro_rules! unwrap_or_continue { + ( $e:expr ) => { + match $e { + Ok(x) => x, + Err(_) => continue, + } + }; +} + +#[repr(u8)] +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum CompilationMode { + Wave32 = 1, + Wave32OnWave64 = 2, + DoubleWave32OnWave64 = 3, +} + +impl CompilationMode { + pub unsafe fn from_device(device: i32) -> Result { + let mut device_props = mem::zeroed(); + hip! { hipGetDeviceProperties(&mut device_props, device) }; + if device_props.warpSize == 32 { + Ok(CompilationMode::Wave32) + } else { + Ok(CompilationMode::Wave32OnWave64) + } + } + + pub fn from_u8(value: u8) -> Option { + Some(match value { + 1 => CompilationMode::Wave32, + 2 => CompilationMode::Wave32OnWave64, + 3 => CompilationMode::DoubleWave32OnWave64, + _ => return None, + }) + } +} + +pub unsafe fn comgr_isa(device: i32) -> Result { + let mut device_props = mem::zeroed(); + hip! { hipGetDeviceProperties(&mut device_props, device) }; + let gcn_arch = CStr::from_ptr(device_props.gcnArchName.as_ptr() as _); + let mut arch_name = b"amdgcn-amd-amdhsa--".to_vec(); + arch_name.extend_from_slice(gcn_arch.to_bytes_with_nul()); + Ok(CString::from_vec_with_nul_unchecked(arch_name)) +} + +pub mod elf { + use goblin::elf::header::header64::Header; + + pub unsafe fn as_slice(ptr: *const u8) -> &'static [u8] { + let header = Header::from_bytes(&*(ptr as *mut [u8; 64])); + let size = + header.e_shoff as usize + (header.e_shnum as usize * header.e_shentsize as usize); + // TODO: enumerate sections to check if there's a section beyond + // sections header table + std::slice::from_raw_parts(ptr as _, size) + } +} diff --git a/hip_common/src/raytracing.rs b/hip_common/src/raytracing.rs new file mode 100644 index 0000000..7772af2 --- /dev/null +++ b/hip_common/src/raytracing.rs @@ -0,0 +1,24 @@ +use rustc_hash::FxHashMap; +use std::{alloc::Layout, ffi::CString}; + +#[derive(Clone)] +pub struct VariablesBlock { + pub variables: FxHashMap, + pub layout: Layout, +} + +impl VariablesBlock { + pub fn empty() -> Self { + Self { + variables: FxHashMap::default(), + layout: Layout::new::<()>(), + } + } +} + +#[derive(Clone, PartialEq, Eq)] +pub struct Variable { + pub size: u32, + pub offset: u32, + pub default_value: Vec, +} diff --git a/hip_common/src/zluda.capnp b/hip_common/src/zluda.capnp new file mode 100644 index 0000000..89c1d7d --- /dev/null +++ b/hip_common/src/zluda.capnp @@ -0,0 +1,18 @@ +@0xbefb36a5417c8ae1; + +struct Metadata { + # We can turn it into an union later: "a field can be replaced with a group + # or union containing an equivalent field and some new fields" + version1 @0 :Version1; +} + +struct Version1 { + kernels @0 :List(Kernel); + smVersion @1 :UInt32; +} + +struct Kernel { + name @0 :Text; + minGoupSize @1 :UInt32; + maxGroupSize @2 :UInt32; +} diff --git a/hip_common/src/zluda_capnp.rs b/hip_common/src/zluda_capnp.rs new file mode 100644 index 0000000..dcc8b0d --- /dev/null +++ b/hip_common/src/zluda_capnp.rs @@ -0,0 +1,713 @@ +// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler. +// DO NOT EDIT. +// source: src/zluda.capnp + + +pub mod metadata { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_version1(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_version1(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 0, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_version1(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_version1(&mut self, value: crate::zluda_capnp::version1::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) + } + #[inline] + pub fn init_version1(self, ) -> crate::zluda_capnp::version1::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0) + } + #[inline] + pub fn has_version1(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + pub fn get_version1(&self) -> crate::zluda_capnp::version1::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) + } + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 34] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(249, 253, 193, 247, 84, 253, 97, 238), + ::capnp::word(16, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(225, 138, 124, 65, 165, 54, 251, 190), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 202, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 63, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 46, 99, 97, 112, 110, 112, 58), + ::capnp::word(77, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 74, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(24, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(118, 101, 114, 115, 105, 111, 110, 49), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(135, 155, 30, 175, 171, 91, 219, 138), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xee61_fd54_f7c1_fdf9; + } +} + +pub mod version1 { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_kernels(self) -> ::capnp::Result<::capnp::struct_list::Reader<'a,crate::zluda_capnp::kernel::Owned>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_kernels(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_sm_version(self) -> u32 { + self.reader.get_data_field::(0) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_kernels(self) -> ::capnp::Result<::capnp::struct_list::Builder<'a,crate::zluda_capnp::kernel::Owned>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_kernels(&mut self, value: ::capnp::struct_list::Reader<'a,crate::zluda_capnp::kernel::Owned>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) + } + #[inline] + pub fn init_kernels(self, size: u32) -> ::capnp::struct_list::Builder<'a,crate::zluda_capnp::kernel::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), size) + } + #[inline] + pub fn has_kernels(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_sm_version(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_sm_version(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 53] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(135, 155, 30, 175, 171, 91, 219, 138), + ::capnp::word(16, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(225, 138, 124, 65, 165, 54, 251, 190), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 202, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 46, 99, 97, 112, 110, 112, 58), + ::capnp::word(86, 101, 114, 115, 105, 111, 110, 49), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 66, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(64, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(61, 0, 0, 0, 82, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(60, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(72, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(107, 101, 114, 110, 101, 108, 115, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(66, 232, 92, 140, 116, 139, 41, 203), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 109, 86, 101, 114, 115, 105, 111), + ::capnp::word(110, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0x8adb_5bab_af1e_9b87; + } +} + +pub mod kernel { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_min_goup_size(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_max_group_size(self) -> u32 { + self.reader.get_data_field::(1) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_name(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_text(value); + } + #[inline] + pub fn init_name(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(0).init_text(size) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_min_goup_size(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_min_goup_size(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_max_group_size(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_max_group_size(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 64] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(66, 232, 92, 140, 116, 139, 41, 203), + ::capnp::word(16, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(225, 138, 124, 65, 165, 54, 251, 190), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 186, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 175, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 46, 99, 97, 112, 110, 112, 58), + ::capnp::word(75, 101, 114, 110, 101, 108, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(69, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(64, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(76, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(73, 0, 0, 0, 98, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(72, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(84, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(81, 0, 0, 0, 106, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(80, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(92, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(110, 97, 109, 101, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 105, 110, 71, 111, 117, 112, 83), + ::capnp::word(105, 122, 101, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 97, 120, 71, 114, 111, 117, 112), + ::capnp::word(83, 105, 122, 101, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::text::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + 2 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1,2]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xcb29_8b74_8c5c_e842; + } +} diff --git a/hip_common/src/zluda_ext.rs b/hip_common/src/zluda_ext.rs new file mode 100644 index 0000000..5b639b4 --- /dev/null +++ b/hip_common/src/zluda_ext.rs @@ -0,0 +1,77 @@ +use cuda_types::CUresult; +use std::ptr; + +#[repr(C)] +pub enum CudaObjectKind { + Context, + Stream, +} + +#[repr(C)] +pub struct CudaResult { + pub return_code: CUresult, + pub value: T, +} + +impl From> for CudaResult<*const T> { + fn from(result: Result<*const T, CUresult>) -> Self { + match result { + Ok(value) => Self { + return_code: CUresult::CUDA_SUCCESS, + value, + }, + Err(return_code) => Self { + return_code, + value: ptr::null(), + }, + } + } +} + +impl From> for Result<*const T, CUresult> { + fn from(result: CudaResult<*const T>) -> Self { + if result.return_code == CUresult::CUDA_SUCCESS { + Ok(result.value) + } else { + Err(result.return_code) + } + } +} + +#[cfg(windows)] +type Library = libloading::os::windows::Library; +#[cfg(windows)] +type Symbol = libloading::os::windows::Symbol; + +#[cfg(unix)] +type Library = libloading::os::unix::Library; +#[cfg(unix)] +type Symbol = libloading::os::unix::Symbol; + +#[cfg(windows)] +pub unsafe fn get_cuda_library() -> Result { + libloading::os::windows::Library::open_already_loaded("nvcuda") +} + +#[cfg(unix)] +pub unsafe fn get_cuda_library() -> Result { + const RTLD_NOLOAD: i32 = 0x4; + libloading::os::unix::Library::open( + Some("libcuda.so"), + libloading::os::unix::RTLD_LAZY | RTLD_NOLOAD, + ) +} + +pub unsafe fn zluda_get_hip_object( + lib: &Library, +) -> Result< + Symbol< + unsafe extern "C" fn( + cuda_object: *mut std::os::raw::c_void, + kind: CudaObjectKind, + ) -> CudaResult<*const std::os::raw::c_void>, + >, + libloading::Error, +> { + lib.get(b"zluda_get_hip_object\0") +} diff --git a/hip_common/src/zluda_rt6.capnp b/hip_common/src/zluda_rt6.capnp new file mode 100644 index 0000000..5db5a07 --- /dev/null +++ b/hip_common/src/zluda_rt6.capnp @@ -0,0 +1,30 @@ +@0xb631f7be1b968e02; + +struct Metadata { + # We can turn it into an union later: "a field can be replaced with a group + # or union containing an equivalent field and some new fields" + version1 @0 :Version1; +} + +struct Version1 { + attributesSize @0 :UInt32; + attributesAlign @1 :UInt32; + attributes @2 :List(Attribute); + variablesSize @3 :UInt32; + variablesAlign @4 :UInt32; + variables @5 :List(GlobalVariable); + isCallable @6 :Bool; +} + +struct Attribute { + name @0 :Text; + offset @1 :UInt32; + size @2 :UInt32; +} + +struct GlobalVariable { + name @0 :Text; + offset @1 :UInt32; + size @2 :UInt32; + defaultValue @3 :Data; +} diff --git a/hip_common/src/zluda_rt6_capnp.rs b/hip_common/src/zluda_rt6_capnp.rs new file mode 100644 index 0000000..641b8d1 --- /dev/null +++ b/hip_common/src/zluda_rt6_capnp.rs @@ -0,0 +1,1177 @@ +// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler. +// DO NOT EDIT. +// source: src/zluda_rt6.capnp + + +pub mod metadata { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_version1(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_version1(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 0, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_version1(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_version1(&mut self, value: crate::zluda_rt6_capnp::version1::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) + } + #[inline] + pub fn init_version1(self, ) -> crate::zluda_rt6_capnp::version1::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0) + } + #[inline] + pub fn has_version1(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + pub fn get_version1(&self) -> crate::zluda_rt6_capnp::version1::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) + } + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 34] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(0, 219, 214, 72, 128, 66, 27, 177), + ::capnp::word(20, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(2, 142, 150, 27, 190, 247, 49, 182), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 234, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 63, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 95, 114, 116, 54, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 77, 101, 116, 97), + ::capnp::word(100, 97, 116, 97, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 74, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(24, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(118, 101, 114, 115, 105, 111, 110, 49), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(162, 180, 209, 177, 231, 68, 125, 179), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xb11b_4280_48d6_db00; + } +} + +pub mod version1 { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_attributes_size(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_attributes_align(self) -> u32 { + self.reader.get_data_field::(1) + } + #[inline] + pub fn get_attributes(self) -> ::capnp::Result<::capnp::struct_list::Reader<'a,crate::zluda_rt6_capnp::attribute::Owned>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_attributes(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_variables_size(self) -> u32 { + self.reader.get_data_field::(2) + } + #[inline] + pub fn get_variables_align(self) -> u32 { + self.reader.get_data_field::(3) + } + #[inline] + pub fn get_variables(self) -> ::capnp::Result<::capnp::struct_list::Reader<'a,crate::zluda_rt6_capnp::global_variable::Owned>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn has_variables(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + #[inline] + pub fn get_is_callable(self) -> bool { + self.reader.get_bool_field(128) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 3, pointers: 2 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_attributes_size(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_attributes_size(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_attributes_align(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_attributes_align(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + #[inline] + pub fn get_attributes(self) -> ::capnp::Result<::capnp::struct_list::Builder<'a,crate::zluda_rt6_capnp::attribute::Owned>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_attributes(&mut self, value: ::capnp::struct_list::Reader<'a,crate::zluda_rt6_capnp::attribute::Owned>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) + } + #[inline] + pub fn init_attributes(self, size: u32) -> ::capnp::struct_list::Builder<'a,crate::zluda_rt6_capnp::attribute::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), size) + } + #[inline] + pub fn has_attributes(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_variables_size(self) -> u32 { + self.builder.get_data_field::(2) + } + #[inline] + pub fn set_variables_size(&mut self, value: u32) { + self.builder.set_data_field::(2, value); + } + #[inline] + pub fn get_variables_align(self) -> u32 { + self.builder.get_data_field::(3) + } + #[inline] + pub fn set_variables_align(&mut self, value: u32) { + self.builder.set_data_field::(3, value); + } + #[inline] + pub fn get_variables(self) -> ::capnp::Result<::capnp::struct_list::Builder<'a,crate::zluda_rt6_capnp::global_variable::Owned>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn set_variables(&mut self, value: ::capnp::struct_list::Reader<'a,crate::zluda_rt6_capnp::global_variable::Owned>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) + } + #[inline] + pub fn init_variables(self, size: u32) -> ::capnp::struct_list::Builder<'a,crate::zluda_rt6_capnp::global_variable::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(1), size) + } + #[inline] + pub fn has_variables(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + #[inline] + pub fn get_is_callable(self) -> bool { + self.builder.get_bool_field(128) + } + #[inline] + pub fn set_is_callable(&mut self, value: bool) { + self.builder.set_bool_field(128, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 138] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(162, 180, 209, 177, 231, 68, 125, 179), + ::capnp::word(20, 0, 0, 0, 1, 0, 3, 0), + ::capnp::word(2, 142, 150, 27, 190, 247, 49, 182), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 234, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 143, 1, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 95, 114, 116, 54, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 86, 101, 114, 115), + ::capnp::word(105, 111, 110, 49, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(28, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(181, 0, 0, 0, 122, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(180, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(192, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(189, 0, 0, 0, 130, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(188, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(200, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(197, 0, 0, 0, 90, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(196, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(224, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(3, 0, 0, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 3, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(221, 0, 0, 0, 114, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(220, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(232, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 3, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 4, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(229, 0, 0, 0, 122, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(228, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(240, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(5, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 5, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(237, 0, 0, 0, 82, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(236, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(8, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(6, 0, 0, 0, 128, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 6, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(5, 1, 0, 0, 90, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(4, 1, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(97, 116, 116, 114, 105, 98, 117, 116), + ::capnp::word(101, 115, 83, 105, 122, 101, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(97, 116, 116, 114, 105, 98, 117, 116), + ::capnp::word(101, 115, 65, 108, 105, 103, 110, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(97, 116, 116, 114, 105, 98, 117, 116), + ::capnp::word(101, 115, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(23, 101, 167, 213, 168, 105, 53, 178), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 97, 114, 105, 97, 98, 108, 101), + ::capnp::word(115, 83, 105, 122, 101, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 97, 114, 105, 97, 98, 108, 101), + ::capnp::word(115, 65, 108, 105, 103, 110, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 97, 114, 105, 97, 98, 108, 101), + ::capnp::word(115, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(70, 171, 233, 170, 211, 40, 31, 251), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(105, 115, 67, 97, 108, 108, 97, 98), + ::capnp::word(108, 101, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + 2 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 3 => ::introspect(), + 4 => ::introspect(), + 5 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 6 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1,2,3,4,5,6]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xb37d_44e7_b1d1_b4a2; + } +} + +pub mod attribute { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_offset(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_size(self) -> u32 { + self.reader.get_data_field::(1) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_name(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_text(value); + } + #[inline] + pub fn init_name(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(0).init_text(size) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_offset(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_offset(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_size(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_size(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 63] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(23, 101, 167, 213, 168, 105, 53, 178), + ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(2, 142, 150, 27, 190, 247, 49, 182), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 242, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 175, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 95, 114, 116, 54, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 65, 116, 116, 114), + ::capnp::word(105, 98, 117, 116, 101, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(69, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(64, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(76, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(73, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(68, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(80, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(77, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(72, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(84, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(110, 97, 109, 101, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(111, 102, 102, 115, 101, 116, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 105, 122, 101, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::text::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + 2 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1,2]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xb235_69a8_d5a7_6517; + } +} + +pub mod global_variable { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_offset(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_size(self) -> u32 { + self.reader.get_data_field::(1) + } + #[inline] + pub fn get_default_value(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn has_default_value(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 2 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_name(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_text(value); + } + #[inline] + pub fn init_name(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(0).init_text(size) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_offset(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_offset(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_size(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_size(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + #[inline] + pub fn get_default_value(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn set_default_value(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(1).set_data(value); + } + #[inline] + pub fn init_default_value(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(1).init_data(size) + } + #[inline] + pub fn has_default_value(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 80] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(70, 171, 233, 170, 211, 40, 31, 251), + ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(2, 142, 150, 27, 190, 247, 49, 182), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 26, 1, 0, 0), + ::capnp::word(37, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 231, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 114, 99, 47, 122, 108, 117, 100), + ::capnp::word(97, 95, 114, 116, 54, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 71, 108, 111, 98), + ::capnp::word(97, 108, 86, 97, 114, 105, 97, 98), + ::capnp::word(108, 101, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(97, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(92, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(104, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(101, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(96, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(108, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(105, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(100, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(112, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(3, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 3, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 0, 0, 0, 106, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(108, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(120, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(110, 97, 109, 101, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(12, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(111, 102, 102, 115, 101, 116, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 105, 122, 101, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(100, 101, 102, 97, 117, 108, 116, 86), + ::capnp::word(97, 108, 117, 101, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::text::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + 2 => ::introspect(), + 3 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1,2,3]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xfb1f_28d3_aae9_ab46; + } +} diff --git a/hip_runtime-sys/Cargo.toml b/hip_runtime-sys/Cargo.toml new file mode 100644 index 0000000..98f7daf --- /dev/null +++ b/hip_runtime-sys/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "hip_runtime-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "amdhip" + +[lib] + +[dependencies] +rustc-hash = "1.1" \ No newline at end of file diff --git a/hip_runtime-sys/Makefile.toml b/hip_runtime-sys/Makefile.toml new file mode 100644 index 0000000..1a1a04d --- /dev/null +++ b/hip_runtime-sys/Makefile.toml @@ -0,0 +1,17 @@ +[tasks.bindgen] +command = "bindgen" +args = [ + "include/hip_runtime_api.h", + "-o", "src/hip_runtime_api.rs", + "--rust-target", "1.64", + "--no-layout-tests", + "--no-derive-debug", + "--default-enum-style=newtype", + "--must-use-type", "hipError_t", + "--allowlist-function", "hip.*", + "--allowlist-type", "hip.*", + "--allowlist-var", "^hip.*$", + "--new-type-alias", "hipDeviceptr_t", + "--", "-I/opt/rocm/include", "-D__HIP_PLATFORM_AMD__", + "-IZ:/opt/rocm-5.7.2/include" +] \ No newline at end of file diff --git a/hip_runtime-sys/README b/hip_runtime-sys/README new file mode 100644 index 0000000..5fe5c6d --- /dev/null +++ b/hip_runtime-sys/README @@ -0,0 +1 @@ +bindgen include/hip_runtime_api.h -o src/hip_runtime_api.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --whitelist-function "hip.*" --whitelist-type "hip.*" --no-derive-debug --must-use-type hipError_t --new-type-alias "^hipDeviceptr_t$" --whitelist-var "^hip.*$" -- -I/opt/rocm/include -D__HIP_PLATFORM_AMD__ diff --git a/level_zero-sys/build.rs b/hip_runtime-sys/build.rs similarity index 69% rename from level_zero-sys/build.rs rename to hip_runtime-sys/build.rs index 0d2488c..b6d842e 100644 --- a/level_zero-sys/build.rs +++ b/hip_runtime-sys/build.rs @@ -1,8 +1,8 @@ -use env::VarError; +use std::env::VarError; use std::{env, path::PathBuf}; -fn main() -> Result<(), VarError> { - println!("cargo:rustc-link-lib=dylib=ze_loader"); +fn main() -> Result<(), VarError> { + println!("cargo:rustc-link-lib=dylib=amdhip64"); if cfg!(windows) { let env = env::var("CARGO_CFG_TARGET_ENV")?; if env == "msvc" { @@ -12,6 +12,8 @@ fn main() -> Result<(), VarError> { } else { println!("cargo:rustc-link-search=native=C:\\Windows\\System32"); }; + } else { + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); } Ok(()) } diff --git a/hip_runtime-sys/include/hip_runtime_api.h b/hip_runtime-sys/include/hip_runtime_api.h new file mode 100644 index 0000000..173daee --- /dev/null +++ b/hip_runtime-sys/include/hip_runtime_api.h @@ -0,0 +1,2 @@ +#define __HIP_PLATFORM_HCC__ +#include \ No newline at end of file diff --git a/hip_runtime-sys/lib/amdhip64.def b/hip_runtime-sys/lib/amdhip64.def new file mode 100644 index 0000000..8dda3d7 --- /dev/null +++ b/hip_runtime-sys/lib/amdhip64.def @@ -0,0 +1,561 @@ +; +; Definition file of amdhip64.dll +; Automatic generated by gendef +; written by Kai Tietz 2008 +; +LIBRARY "amdhip64.dll" +EXPORTS +hipCreateSurfaceObject +hipDestroySurfaceObject +hipExtModuleLaunchKernel +hipHccModuleLaunchKernel +hipModuleLaunchKernelExt +hipTexRefGetArray +hipTexRefGetBorderColor +hipTexRefGetMipmappedArray +AMD_CPU_AFFINITY DATA +AMD_DIRECT_DISPATCH DATA +AMD_GPU_FORCE_SINGLE_FP_DENORM DATA +AMD_LOG_LEVEL DATA +AMD_LOG_LEVEL_FILE DATA +AMD_LOG_MASK DATA +AMD_OCL_BUILD_OPTIONS DATA +AMD_OCL_BUILD_OPTIONS_APPEND DATA +AMD_OCL_LINK_OPTIONS DATA +AMD_OCL_LINK_OPTIONS_APPEND DATA +AMD_OCL_SC_LIB DATA +AMD_OCL_WAIT_COMMAND DATA +AMD_OPT_FLUSH DATA +AMD_SERIALIZE_COPY DATA +AMD_SERIALIZE_KERNEL DATA +AMD_THREAD_TRACE_ENABLE DATA +CL_KHR_FP64 DATA +CQ_THREAD_STACK_SIZE DATA +CUDA_VISIBLE_DEVICES DATA +DISABLE_DEFERRED_ALLOC DATA +GPU_ADD_HBCC_SIZE DATA +GPU_ANALYZE_HANG DATA +GPU_BLIT_ENGINE_TYPE DATA +GPU_CP_DMA_COPY_SIZE DATA +GPU_DEVICE_ORDINAL DATA +GPU_DUMP_BLIT_KERNELS DATA +GPU_DUMP_CODE_OBJECT DATA +GPU_ENABLE_COOP_GROUPS DATA +GPU_ENABLE_HW_P2P DATA +GPU_ENABLE_LARGE_ALLOCATION DATA +GPU_ENABLE_LC DATA +GPU_ENABLE_PAL DATA +GPU_ENABLE_WAVE32_MODE DATA +GPU_ENABLE_WGP_MODE DATA +GPU_FLUSH_ON_EXECUTION DATA +GPU_FORCE_64BIT_PTR DATA +GPU_FORCE_BLIT_COPY_SIZE DATA +GPU_FORCE_OCL20_32BIT DATA +GPU_FORCE_QUEUE_PROFILING DATA +GPU_IFH_MODE DATA +GPU_IMAGE_BUFFER_WAR DATA +GPU_IMAGE_DMA DATA +GPU_MAX_COMMAND_BUFFERS DATA +GPU_MAX_COMMAND_QUEUES DATA +GPU_MAX_HEAP_SIZE DATA +GPU_MAX_HW_QUEUES DATA +GPU_MAX_REMOTE_MEM_SIZE DATA +GPU_MAX_SUBALLOC_SIZE DATA +GPU_MAX_USWC_ALLOC_SIZE DATA +GPU_MAX_WORKGROUP_SIZE DATA +GPU_MAX_WORKGROUP_SIZE_2D_X DATA +GPU_MAX_WORKGROUP_SIZE_2D_Y DATA +GPU_MAX_WORKGROUP_SIZE_3D_X DATA +GPU_MAX_WORKGROUP_SIZE_3D_Y DATA +GPU_MAX_WORKGROUP_SIZE_3D_Z DATA +GPU_MIPMAP DATA +GPU_NUM_COMPUTE_RINGS DATA +GPU_NUM_MEM_DEPENDENCY DATA +GPU_PINNED_MIN_XFER_SIZE DATA +GPU_PINNED_XFER_SIZE DATA +GPU_PRINT_CHILD_KERNEL DATA +GPU_RAW_TIMESTAMP DATA +GPU_RESOURCE_CACHE_SIZE DATA +GPU_SELECT_COMPUTE_RINGS_ID DATA +GPU_SINGLE_ALLOC_PERCENT DATA +GPU_STAGING_BUFFER_SIZE DATA +GPU_STREAMOPS_CP_WAIT DATA +GPU_USE_DEVICE_QUEUE DATA +GPU_USE_SINGLE_SCRATCH DATA +GPU_USE_SYNC_OBJECTS DATA +GPU_WAVES_PER_SIMD DATA +GPU_WAVE_LIMIT_ENABLE DATA +GPU_WORKLOAD_SPLIT DATA +GPU_XFER_BUFFER_SIZE DATA +HIPRTC_USE_RUNTIME_UNBUNDLER DATA +HIP_FORCE_DEV_KERNARG DATA +HIP_HIDDEN_FREE_MEM DATA +HIP_HOST_COHERENT DATA +HIP_INITIAL_DM_SIZE DATA +HIP_MEM_POOL_SUPPORT DATA +HIP_MEM_POOL_USE_VM DATA +HIP_USE_RUNTIME_UNBUNDLER DATA +HIP_VISIBLE_DEVICES DATA +HSA_ENABLE_COARSE_GRAIN_SVM DATA +HSA_KERNARG_POOL_SIZE DATA +HSA_LOCAL_MEMORY_ENABLE DATA +OCL_CODE_CACHE_ENABLE DATA +OCL_CODE_CACHE_RESET DATA +OCL_SET_SVM_SIZE DATA +OCL_STUB_PROGRAMS DATA +OPENCL_VERSION DATA +PAL_ALWAYS_RESIDENT DATA +PAL_DISABLE_SDMA DATA +PAL_EMBED_KERNEL_MD DATA +PAL_FORCE_ASIC_REVISION DATA +PAL_MALL_POLICY DATA +PAL_PREPINNED_MEMORY_SIZE DATA +PAL_RGP_DISP_COUNT DATA +REMOTE_ALLOC DATA +ROC_ACTIVE_WAIT_TIMEOUT DATA +ROC_AQL_QUEUE_SIZE DATA +ROC_CPU_WAIT_FOR_SIGNAL DATA +ROC_ENABLE_LARGE_BAR DATA +ROC_ENABLE_PRE_VEGA DATA +ROC_GLOBAL_CU_MASK DATA +ROC_HMM_FLAGS DATA +ROC_P2P_SDMA_SIZE DATA +ROC_SIGNAL_POOL_SIZE DATA +ROC_SKIP_COPY_SYNC DATA +ROC_SKIP_KERNEL_ARG_COPY DATA +ROC_SYSTEM_SCOPE_SIGNAL DATA +ROC_USE_FGS_KERNARG DATA +__gnu_f2h_ieee +__gnu_h2f_ieee +__hipPopCallConfiguration +__hipPushCallConfiguration +__hipRegisterFatBinary +__hipRegisterFunction +__hipRegisterManagedVar +__hipRegisterSurface +__hipRegisterTexture +__hipRegisterVar +__hipUnregisterFatBinary +amd_dbgapi_get_build_id +amd_dbgapi_get_build_name +amd_dbgapi_get_git_hash +hipApiName +hipArray3DCreate +hipArray3DGetDescriptor +hipArrayCreate +hipArrayDestroy +hipArrayGetDescriptor +hipArrayGetInfo +hipBindTexture +hipBindTexture2D +hipBindTextureToArray +hipBindTextureToMipmappedArray +hipChooseDevice +hipConfigureCall +hipCreateChannelDesc +hipCreateTextureObject +hipCtxCreate +hipCtxDestroy +hipCtxDisablePeerAccess +hipCtxEnablePeerAccess +hipCtxGetApiVersion +hipCtxGetCacheConfig +hipCtxGetCurrent +hipCtxGetDevice +hipCtxGetFlags +hipCtxGetSharedMemConfig +hipCtxPopCurrent +hipCtxPushCurrent +hipCtxSetCacheConfig +hipCtxSetCurrent +hipCtxSetSharedMemConfig +hipCtxSynchronize +hipDestroyExternalMemory +hipDestroyExternalSemaphore +hipDestroyTextureObject +hipDeviceCanAccessPeer +hipDeviceComputeCapability +hipDeviceDisablePeerAccess +hipDeviceEnablePeerAccess +hipDeviceGet +hipDeviceGetAttribute +hipDeviceGetByPCIBusId +hipDeviceGetCacheConfig +hipDeviceGetDefaultMemPool +hipDeviceGetGraphMemAttribute +hipDeviceGetLimit +hipDeviceGetMemPool +hipDeviceGetName +hipDeviceGetP2PAttribute +hipDeviceGetPCIBusId +hipDeviceGetSharedMemConfig +hipDeviceGetStreamPriorityRange +hipDeviceGetUuid +hipDeviceGraphMemTrim +hipDevicePrimaryCtxGetState +hipDevicePrimaryCtxRelease +hipDevicePrimaryCtxReset +hipDevicePrimaryCtxRetain +hipDevicePrimaryCtxSetFlags +hipDeviceReset +hipDeviceSetCacheConfig +hipDeviceSetGraphMemAttribute +hipDeviceSetLimit +hipDeviceSetMemPool +hipDeviceSetSharedMemConfig +hipDeviceSynchronize +hipDeviceTotalMem +hipDriverGetVersion +hipDrvGetErrorName +hipDrvGetErrorString +hipDrvMemcpy2DUnaligned +hipDrvMemcpy3D +hipDrvMemcpy3DAsync +hipDrvPointerGetAttributes +hipEventCreate +hipEventCreateWithFlags +hipEventDestroy +hipEventElapsedTime +hipEventQuery +hipEventRecord +hipEventRecord_spt +hipEventSynchronize +hipExtGetLinkTypeAndHopCount +hipExtLaunchKernel +hipExtLaunchMultiKernelMultiDevice +hipExtMallocWithFlags +hipExtStreamCreateWithCUMask +hipExtStreamGetCUMask +hipExternalMemoryGetMappedBuffer +hipFree +hipFreeArray +hipFreeAsync +hipFreeHost +hipFreeMipmappedArray +hipFuncGetAttribute +hipFuncGetAttributes +hipFuncSetAttribute +hipFuncSetCacheConfig +hipFuncSetSharedMemConfig +hipGLGetDevices +hipGetChannelDesc +hipGetCmdName +hipGetDevice +hipGetDeviceCount +hipGetDeviceFlags +hipGetDeviceProperties +hipGetErrorName +hipGetErrorString +hipGetLastError +hipGetMipmappedArrayLevel +hipGetStreamDeviceId +hipGetSymbolAddress +hipGetSymbolSize +hipGetTextureAlignmentOffset +hipGetTextureObjectResourceDesc +hipGetTextureObjectResourceViewDesc +hipGetTextureObjectTextureDesc +hipGetTextureReference +hipGraphAddChildGraphNode +hipGraphAddDependencies +hipGraphAddEmptyNode +hipGraphAddEventRecordNode +hipGraphAddEventWaitNode +hipGraphAddHostNode +hipGraphAddKernelNode +hipGraphAddMemAllocNode +hipGraphAddMemFreeNode +hipGraphAddMemcpyNode +hipGraphAddMemcpyNode1D +hipGraphAddMemcpyNodeFromSymbol +hipGraphAddMemcpyNodeToSymbol +hipGraphAddMemsetNode +hipGraphChildGraphNodeGetGraph +hipGraphClone +hipGraphCreate +hipGraphDebugDotPrint +hipGraphDestroy +hipGraphDestroyNode +hipGraphEventRecordNodeGetEvent +hipGraphEventRecordNodeSetEvent +hipGraphEventWaitNodeGetEvent +hipGraphEventWaitNodeSetEvent +hipGraphExecChildGraphNodeSetParams +hipGraphExecDestroy +hipGraphExecEventRecordNodeSetEvent +hipGraphExecEventWaitNodeSetEvent +hipGraphExecHostNodeSetParams +hipGraphExecKernelNodeSetParams +hipGraphExecMemcpyNodeSetParams +hipGraphExecMemcpyNodeSetParams1D +hipGraphExecMemcpyNodeSetParamsFromSymbol +hipGraphExecMemcpyNodeSetParamsToSymbol +hipGraphExecMemsetNodeSetParams +hipGraphExecUpdate +hipGraphGetEdges +hipGraphGetNodes +hipGraphGetRootNodes +hipGraphHostNodeGetParams +hipGraphHostNodeSetParams +hipGraphInstantiate +hipGraphInstantiateWithFlags +hipGraphKernelNodeCopyAttributes +hipGraphKernelNodeGetAttribute +hipGraphKernelNodeGetParams +hipGraphKernelNodeSetAttribute +hipGraphKernelNodeSetParams +hipGraphLaunch +hipGraphLaunch_spt +hipGraphMemAllocNodeGetParams +hipGraphMemFreeNodeGetParams +hipGraphMemcpyNodeGetParams +hipGraphMemcpyNodeSetParams +hipGraphMemcpyNodeSetParams1D +hipGraphMemcpyNodeSetParamsFromSymbol +hipGraphMemcpyNodeSetParamsToSymbol +hipGraphMemsetNodeGetParams +hipGraphMemsetNodeSetParams +hipGraphNodeFindInClone +hipGraphNodeGetDependencies +hipGraphNodeGetDependentNodes +hipGraphNodeGetEnabled +hipGraphNodeGetType +hipGraphNodeSetEnabled +hipGraphReleaseUserObject +hipGraphRemoveDependencies +hipGraphRetainUserObject +hipGraphUpload +hipGraphicsGLRegisterBuffer +hipGraphicsGLRegisterImage +hipGraphicsMapResources +hipGraphicsResourceGetMappedPointer +hipGraphicsSubResourceGetMappedArray +hipGraphicsUnmapResources +hipGraphicsUnregisterResource +hipHostAlloc +hipHostFree +hipHostGetDevicePointer +hipHostGetFlags +hipHostMalloc +hipHostRegister +hipHostUnregister +hipImportExternalMemory +hipImportExternalSemaphore +hipInit +hipIpcCloseMemHandle +hipIpcGetEventHandle +hipIpcGetMemHandle +hipIpcOpenEventHandle +hipIpcOpenMemHandle +hipKernelNameRef +hipLaunchByPtr +hipLaunchCooperativeKernel +hipLaunchCooperativeKernelMultiDevice +hipLaunchCooperativeKernel_spt +hipLaunchHostFunc +hipLaunchHostFunc_spt +hipLaunchKernel +hipLaunchKernel_spt +hipMalloc +hipMalloc3D +hipMalloc3DArray +hipMallocArray +hipMallocAsync +hipMallocFromPoolAsync +hipMallocHost +hipMallocManaged +hipMallocMipmappedArray +hipMallocPitch +hipMemAddressFree +hipMemAddressReserve +hipMemAdvise +hipMemAllocHost +hipMemAllocPitch +hipMemCreate +hipMemExportToShareableHandle +hipMemGetAccess +hipMemGetAddressRange +hipMemGetAllocationGranularity +hipMemGetAllocationPropertiesFromHandle +hipMemGetInfo +hipMemImportFromShareableHandle +hipMemMap +hipMemMapArrayAsync +hipMemPoolCreate +hipMemPoolDestroy +hipMemPoolExportPointer +hipMemPoolExportToShareableHandle +hipMemPoolGetAccess +hipMemPoolGetAttribute +hipMemPoolImportFromShareableHandle +hipMemPoolImportPointer +hipMemPoolSetAccess +hipMemPoolSetAttribute +hipMemPoolTrimTo +hipMemPrefetchAsync +hipMemPtrGetInfo +hipMemRangeGetAttribute +hipMemRangeGetAttributes +hipMemRelease +hipMemRetainAllocationHandle +hipMemSetAccess +hipMemUnmap +hipMemcpy +hipMemcpy2D +hipMemcpy2DAsync +hipMemcpy2DAsync_spt +hipMemcpy2DFromArray +hipMemcpy2DFromArrayAsync +hipMemcpy2DFromArrayAsync_spt +hipMemcpy2DFromArray_spt +hipMemcpy2DToArray +hipMemcpy2DToArrayAsync +hipMemcpy2DToArrayAsync_spt +hipMemcpy2DToArray_spt +hipMemcpy2D_spt +hipMemcpy3D +hipMemcpy3DAsync +hipMemcpy3DAsync_spt +hipMemcpy3D_spt +hipMemcpyAsync +hipMemcpyAsync_spt +hipMemcpyAtoH +hipMemcpyDtoD +hipMemcpyDtoDAsync +hipMemcpyDtoH +hipMemcpyDtoHAsync +hipMemcpyFromArray +hipMemcpyFromArray_spt +hipMemcpyFromSymbol +hipMemcpyFromSymbolAsync +hipMemcpyFromSymbolAsync_spt +hipMemcpyFromSymbol_spt +hipMemcpyHtoA +hipMemcpyHtoD +hipMemcpyHtoDAsync +hipMemcpyParam2D +hipMemcpyParam2DAsync +hipMemcpyPeer +hipMemcpyPeerAsync +hipMemcpyToArray +hipMemcpyToSymbol +hipMemcpyToSymbolAsync +hipMemcpyToSymbolAsync_spt +hipMemcpyToSymbol_spt +hipMemcpyWithStream +hipMemcpy_spt +hipMemset +hipMemset2D +hipMemset2DAsync +hipMemset2DAsync_spt +hipMemset2D_spt +hipMemset3D +hipMemset3DAsync +hipMemset3DAsync_spt +hipMemset3D_spt +hipMemsetAsync +hipMemsetAsync_spt +hipMemsetD16 +hipMemsetD16Async +hipMemsetD32 +hipMemsetD32Async +hipMemsetD8 +hipMemsetD8Async +hipMemset_spt +hipMipmappedArrayCreate +hipMipmappedArrayDestroy +hipMipmappedArrayGetLevel +hipModuleGetFunction +hipModuleGetGlobal +hipModuleGetTexRef +hipModuleLaunchCooperativeKernel +hipModuleLaunchCooperativeKernelMultiDevice +hipModuleLaunchKernel +hipModuleLoad +hipModuleLoadData +hipModuleLoadDataEx +hipModuleOccupancyMaxActiveBlocksPerMultiprocessor +hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags +hipModuleOccupancyMaxPotentialBlockSize +hipModuleOccupancyMaxPotentialBlockSizeWithFlags +hipModuleUnload +hipOccupancyMaxActiveBlocksPerMultiprocessor +hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags +hipOccupancyMaxPotentialBlockSize +hipPeekAtLastError +hipPointerGetAttribute +hipPointerGetAttributes +hipProfilerStart +hipProfilerStop +hipRegisterTracerCallback +hipRuntimeGetVersion +hipSetDevice +hipSetDeviceFlags +hipSetupArgument +hipSignalExternalSemaphoresAsync +hipStreamAddCallback +hipStreamAddCallback_spt +hipStreamAttachMemAsync +hipStreamBeginCapture +hipStreamBeginCapture_spt +hipStreamCreate +hipStreamCreateWithFlags +hipStreamCreateWithPriority +hipStreamDestroy +hipStreamEndCapture +hipStreamEndCapture_spt +hipStreamGetCaptureInfo +hipStreamGetCaptureInfo_spt +hipStreamGetCaptureInfo_v2 +hipStreamGetCaptureInfo_v2_spt +hipStreamGetDevice +hipStreamGetFlags +hipStreamGetFlags_spt +hipStreamGetPriority +hipStreamGetPriority_spt +hipStreamIsCapturing +hipStreamIsCapturing_spt +hipStreamQuery +hipStreamQuery_spt +hipStreamSynchronize +hipStreamSynchronize_spt +hipStreamUpdateCaptureDependencies +hipStreamWaitEvent +hipStreamWaitEvent_spt +hipStreamWaitValue32 +hipStreamWaitValue64 +hipStreamWriteValue32 +hipStreamWriteValue64 +hipTexObjectCreate +hipTexObjectDestroy +hipTexObjectGetResourceDesc +hipTexObjectGetResourceViewDesc +hipTexObjectGetTextureDesc +hipTexRefGetAddress +hipTexRefGetAddressMode +hipTexRefGetFilterMode +hipTexRefGetFlags +hipTexRefGetFormat +hipTexRefGetMaxAnisotropy +hipTexRefGetMipmapFilterMode +hipTexRefGetMipmapLevelBias +hipTexRefGetMipmapLevelClamp +hipTexRefSetAddress +hipTexRefSetAddress2D +hipTexRefSetAddressMode +hipTexRefSetArray +hipTexRefSetBorderColor +hipTexRefSetFilterMode +hipTexRefSetFlags +hipTexRefSetFormat +hipTexRefSetMaxAnisotropy +hipTexRefSetMipmapFilterMode +hipTexRefSetMipmapLevelBias +hipTexRefSetMipmapLevelClamp +hipTexRefSetMipmappedArray +hipThreadExchangeStreamCaptureMode +hipUnbindTexture +hipUserObjectCreate +hipUserObjectRelease +hipUserObjectRetain +hipWaitExternalSemaphoresAsync diff --git a/hip_runtime-sys/lib/amdhip64.lib b/hip_runtime-sys/lib/amdhip64.lib new file mode 100644 index 0000000000000000000000000000000000000000..f7c559162058a1770d32cd26368d73652243a098 GIT binary patch literal 124886 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 literal 0 HcmV?d00001 diff --git a/hip_runtime-sys/src/hip_runtime_api.rs b/hip_runtime-sys/src/hip_runtime_api.rs new file mode 100644 index 0000000..78a4774 --- /dev/null +++ b/hip_runtime-sys/src/hip_runtime_api.rs @@ -0,0 +1,7135 @@ +/* automatically generated by rust-bindgen 0.69.1 */ + +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +pub const hipTextureType1D: u32 = 1; +pub const hipTextureType2D: u32 = 2; +pub const hipTextureType3D: u32 = 3; +pub const hipTextureTypeCubemap: u32 = 12; +pub const hipTextureType1DLayered: u32 = 241; +pub const hipTextureType2DLayered: u32 = 242; +pub const hipTextureTypeCubemapLayered: u32 = 252; +pub const hipIpcMemLazyEnablePeerAccess: u32 = 0; +pub const hipStreamDefault: u32 = 0; +pub const hipStreamNonBlocking: u32 = 1; +pub const hipEventDefault: u32 = 0; +pub const hipEventBlockingSync: u32 = 1; +pub const hipEventDisableTiming: u32 = 2; +pub const hipEventInterprocess: u32 = 4; +pub const hipEventDisableSystemFence: u32 = 536870912; +pub const hipEventReleaseToDevice: u32 = 1073741824; +pub const hipEventReleaseToSystem: u32 = 2147483648; +pub const hipHostMallocDefault: u32 = 0; +pub const hipHostMallocPortable: u32 = 1; +pub const hipHostMallocMapped: u32 = 2; +pub const hipHostMallocWriteCombined: u32 = 4; +pub const hipHostMallocNumaUser: u32 = 536870912; +pub const hipHostMallocCoherent: u32 = 1073741824; +pub const hipHostMallocNonCoherent: u32 = 2147483648; +pub const hipMemAttachGlobal: u32 = 1; +pub const hipMemAttachHost: u32 = 2; +pub const hipMemAttachSingle: u32 = 4; +pub const hipDeviceMallocDefault: u32 = 0; +pub const hipDeviceMallocFinegrained: u32 = 1; +pub const hipMallocSignalMemory: u32 = 2; +pub const hipDeviceMallocUncached: u32 = 3; +pub const hipHostRegisterDefault: u32 = 0; +pub const hipHostRegisterPortable: u32 = 1; +pub const hipHostRegisterMapped: u32 = 2; +pub const hipHostRegisterIoMemory: u32 = 4; +pub const hipHostRegisterReadOnly: u32 = 8; +pub const hipExtHostRegisterCoarseGrained: u32 = 8; +pub const hipDeviceScheduleAuto: u32 = 0; +pub const hipDeviceScheduleSpin: u32 = 1; +pub const hipDeviceScheduleYield: u32 = 2; +pub const hipDeviceScheduleBlockingSync: u32 = 4; +pub const hipDeviceScheduleMask: u32 = 7; +pub const hipDeviceMapHost: u32 = 8; +pub const hipDeviceLmemResizeToMax: u32 = 16; +pub const hipArrayDefault: u32 = 0; +pub const hipArrayLayered: u32 = 1; +pub const hipArraySurfaceLoadStore: u32 = 2; +pub const hipArrayCubemap: u32 = 4; +pub const hipArrayTextureGather: u32 = 8; +pub const hipOccupancyDefault: u32 = 0; +pub const hipOccupancyDisableCachingOverride: u32 = 1; +pub const hipCooperativeLaunchMultiDeviceNoPreSync: u32 = 1; +pub const hipCooperativeLaunchMultiDeviceNoPostSync: u32 = 2; +pub const hipExtAnyOrderLaunch: u32 = 1; +pub const hipStreamWaitValueGte: u32 = 0; +pub const hipStreamWaitValueEq: u32 = 1; +pub const hipStreamWaitValueAnd: u32 = 2; +pub const hipStreamWaitValueNor: u32 = 3; +pub const hipExternalMemoryDedicated: u32 = 1; +#[doc = " @defgroup GlobalDefs Global enum and defines\n @{\n\n/\n/**\n hipDeviceArch_t\n"] +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct hipDeviceArch_t { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub __bindgen_padding_0: u8, +} +impl hipDeviceArch_t { + #[inline] + pub fn hasGlobalInt32Atomics(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasGlobalInt32Atomics(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasGlobalFloatAtomicExch(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasGlobalFloatAtomicExch(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasSharedInt32Atomics(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasSharedInt32Atomics(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasSharedFloatAtomicExch(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasSharedFloatAtomicExch(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasFloatAtomicAdd(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasFloatAtomicAdd(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasGlobalInt64Atomics(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasGlobalInt64Atomics(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasSharedInt64Atomics(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasSharedInt64Atomics(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasDoubles(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasDoubles(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasWarpVote(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasWarpVote(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasWarpBallot(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasWarpBallot(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasWarpShuffle(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasWarpShuffle(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasFunnelShift(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasFunnelShift(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasThreadFenceSystem(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasThreadFenceSystem(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasSyncThreadsExt(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasSyncThreadsExt(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasSurfaceFuncs(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasSurfaceFuncs(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn has3dGrid(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u32) } + } + #[inline] + pub fn set_has3dGrid(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasDynamicParallelism(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u32) } + } + #[inline] + pub fn set_hasDynamicParallelism(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + hasGlobalInt32Atomics: ::std::os::raw::c_uint, + hasGlobalFloatAtomicExch: ::std::os::raw::c_uint, + hasSharedInt32Atomics: ::std::os::raw::c_uint, + hasSharedFloatAtomicExch: ::std::os::raw::c_uint, + hasFloatAtomicAdd: ::std::os::raw::c_uint, + hasGlobalInt64Atomics: ::std::os::raw::c_uint, + hasSharedInt64Atomics: ::std::os::raw::c_uint, + hasDoubles: ::std::os::raw::c_uint, + hasWarpVote: ::std::os::raw::c_uint, + hasWarpBallot: ::std::os::raw::c_uint, + hasWarpShuffle: ::std::os::raw::c_uint, + hasFunnelShift: ::std::os::raw::c_uint, + hasThreadFenceSystem: ::std::os::raw::c_uint, + hasSyncThreadsExt: ::std::os::raw::c_uint, + hasSurfaceFuncs: ::std::os::raw::c_uint, + has3dGrid: ::std::os::raw::c_uint, + hasDynamicParallelism: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let hasGlobalInt32Atomics: u32 = + unsafe { ::std::mem::transmute(hasGlobalInt32Atomics) }; + hasGlobalInt32Atomics as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let hasGlobalFloatAtomicExch: u32 = + unsafe { ::std::mem::transmute(hasGlobalFloatAtomicExch) }; + hasGlobalFloatAtomicExch as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let hasSharedInt32Atomics: u32 = + unsafe { ::std::mem::transmute(hasSharedInt32Atomics) }; + hasSharedInt32Atomics as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let hasSharedFloatAtomicExch: u32 = + unsafe { ::std::mem::transmute(hasSharedFloatAtomicExch) }; + hasSharedFloatAtomicExch as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let hasFloatAtomicAdd: u32 = unsafe { ::std::mem::transmute(hasFloatAtomicAdd) }; + hasFloatAtomicAdd as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let hasGlobalInt64Atomics: u32 = + unsafe { ::std::mem::transmute(hasGlobalInt64Atomics) }; + hasGlobalInt64Atomics as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let hasSharedInt64Atomics: u32 = + unsafe { ::std::mem::transmute(hasSharedInt64Atomics) }; + hasSharedInt64Atomics as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let hasDoubles: u32 = unsafe { ::std::mem::transmute(hasDoubles) }; + hasDoubles as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let hasWarpVote: u32 = unsafe { ::std::mem::transmute(hasWarpVote) }; + hasWarpVote as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let hasWarpBallot: u32 = unsafe { ::std::mem::transmute(hasWarpBallot) }; + hasWarpBallot as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let hasWarpShuffle: u32 = unsafe { ::std::mem::transmute(hasWarpShuffle) }; + hasWarpShuffle as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let hasFunnelShift: u32 = unsafe { ::std::mem::transmute(hasFunnelShift) }; + hasFunnelShift as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let hasThreadFenceSystem: u32 = unsafe { ::std::mem::transmute(hasThreadFenceSystem) }; + hasThreadFenceSystem as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let hasSyncThreadsExt: u32 = unsafe { ::std::mem::transmute(hasSyncThreadsExt) }; + hasSyncThreadsExt as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let hasSurfaceFuncs: u32 = unsafe { ::std::mem::transmute(hasSurfaceFuncs) }; + hasSurfaceFuncs as u64 + }); + __bindgen_bitfield_unit.set(15usize, 1u8, { + let has3dGrid: u32 = unsafe { ::std::mem::transmute(has3dGrid) }; + has3dGrid as u64 + }); + __bindgen_bitfield_unit.set(16usize, 1u8, { + let hasDynamicParallelism: u32 = + unsafe { ::std::mem::transmute(hasDynamicParallelism) }; + hasDynamicParallelism as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipUUID_t { + pub bytes: [::std::os::raw::c_char; 16usize], +} +pub type hipUUID = hipUUID_t; +#[doc = " hipDeviceProp\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipDeviceProp_t { + #[doc = "< Device name."] + pub name: [::std::os::raw::c_char; 256usize], + #[doc = "< Size of global memory region (in bytes)."] + pub totalGlobalMem: usize, + #[doc = "< Size of shared memory region (in bytes)."] + pub sharedMemPerBlock: usize, + #[doc = "< Registers per block."] + pub regsPerBlock: ::std::os::raw::c_int, + #[doc = "< Warp size."] + pub warpSize: ::std::os::raw::c_int, + #[doc = "< Max work items per work group or workgroup max size."] + pub maxThreadsPerBlock: ::std::os::raw::c_int, + #[doc = "< Max number of threads in each dimension (XYZ) of a block."] + pub maxThreadsDim: [::std::os::raw::c_int; 3usize], + #[doc = "< Max grid dimensions (XYZ)."] + pub maxGridSize: [::std::os::raw::c_int; 3usize], + #[doc = "< Max clock frequency of the multiProcessors in khz."] + pub clockRate: ::std::os::raw::c_int, + #[doc = "< Max global memory clock frequency in khz."] + pub memoryClockRate: ::std::os::raw::c_int, + #[doc = "< Global memory bus width in bits."] + pub memoryBusWidth: ::std::os::raw::c_int, + #[doc = "< Size of shared memory region (in bytes)."] + pub totalConstMem: usize, + #[doc = "< Major compute capability. On HCC, this is an approximation and features may\n< differ from CUDA CC. See the arch feature flags for portable ways to query\n< feature caps."] + pub major: ::std::os::raw::c_int, + #[doc = "< Minor compute capability. On HCC, this is an approximation and features may\n< differ from CUDA CC. See the arch feature flags for portable ways to query\n< feature caps."] + pub minor: ::std::os::raw::c_int, + #[doc = "< Number of multi-processors (compute units)."] + pub multiProcessorCount: ::std::os::raw::c_int, + #[doc = "< L2 cache size."] + pub l2CacheSize: ::std::os::raw::c_int, + #[doc = "< Maximum resident threads per multi-processor."] + pub maxThreadsPerMultiProcessor: ::std::os::raw::c_int, + #[doc = "< Compute mode."] + pub computeMode: ::std::os::raw::c_int, + #[doc = "< Frequency in khz of the timer used by the device-side \"clock*\"\n< instructions. New for HIP."] + pub clockInstructionRate: ::std::os::raw::c_int, + #[doc = "< Architectural feature flags. New for HIP."] + pub arch: hipDeviceArch_t, + #[doc = "< Device can possibly execute multiple kernels concurrently."] + pub concurrentKernels: ::std::os::raw::c_int, + #[doc = "< PCI Domain ID"] + pub pciDomainID: ::std::os::raw::c_int, + #[doc = "< PCI Bus ID."] + pub pciBusID: ::std::os::raw::c_int, + #[doc = "< PCI Device ID."] + pub pciDeviceID: ::std::os::raw::c_int, + #[doc = "< Maximum Shared Memory Per Multiprocessor."] + pub maxSharedMemoryPerMultiProcessor: usize, + #[doc = "< 1 if device is on a multi-GPU board, 0 if not."] + pub isMultiGpuBoard: ::std::os::raw::c_int, + #[doc = "< Check whether HIP can map host memory"] + pub canMapHostMemory: ::std::os::raw::c_int, + #[doc = "< DEPRECATED: use gcnArchName instead"] + pub gcnArch: ::std::os::raw::c_int, + #[doc = "< AMD GCN Arch Name."] + pub gcnArchName: [::std::os::raw::c_char; 256usize], + #[doc = "< APU vs dGPU"] + pub integrated: ::std::os::raw::c_int, + #[doc = "< HIP device supports cooperative launch"] + pub cooperativeLaunch: ::std::os::raw::c_int, + #[doc = "< HIP device supports cooperative launch on multiple devices"] + pub cooperativeMultiDeviceLaunch: ::std::os::raw::c_int, + #[doc = "< Maximum size for 1D textures bound to linear memory"] + pub maxTexture1DLinear: ::std::os::raw::c_int, + #[doc = "< Maximum number of elements in 1D images"] + pub maxTexture1D: ::std::os::raw::c_int, + #[doc = "< Maximum dimensions (width, height) of 2D images, in image elements"] + pub maxTexture2D: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum dimensions (width, height, depth) of 3D images, in image elements"] + pub maxTexture3D: [::std::os::raw::c_int; 3usize], + #[doc = "< Addres of HDP_MEM_COHERENCY_FLUSH_CNTL register"] + pub hdpMemFlushCntl: *mut ::std::os::raw::c_uint, + #[doc = "< Addres of HDP_REG_COHERENCY_FLUSH_CNTL register"] + pub hdpRegFlushCntl: *mut ::std::os::raw::c_uint, + #[doc = " hipChannelFormatDesc; +} +#[doc = " An opaque value that represents a hip texture object"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __hip_texture { + _unused: [u8; 0], +} +pub type hipTextureObject_t = *mut __hip_texture; +impl hipTextureAddressMode { + pub const hipAddressModeWrap: hipTextureAddressMode = hipTextureAddressMode(0); +} +impl hipTextureAddressMode { + pub const hipAddressModeClamp: hipTextureAddressMode = hipTextureAddressMode(1); +} +impl hipTextureAddressMode { + pub const hipAddressModeMirror: hipTextureAddressMode = hipTextureAddressMode(2); +} +impl hipTextureAddressMode { + pub const hipAddressModeBorder: hipTextureAddressMode = hipTextureAddressMode(3); +} +#[repr(transparent)] +#[doc = " hip texture address modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipTextureAddressMode(pub ::std::os::raw::c_int); +impl hipTextureFilterMode { + pub const hipFilterModePoint: hipTextureFilterMode = hipTextureFilterMode(0); +} +impl hipTextureFilterMode { + pub const hipFilterModeLinear: hipTextureFilterMode = hipTextureFilterMode(1); +} +#[repr(transparent)] +#[doc = " hip texture filter modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipTextureFilterMode(pub ::std::os::raw::c_int); +impl hipTextureReadMode { + pub const hipReadModeElementType: hipTextureReadMode = hipTextureReadMode(0); +} +impl hipTextureReadMode { + pub const hipReadModeNormalizedFloat: hipTextureReadMode = hipTextureReadMode(1); +} +#[repr(transparent)] +#[doc = " hip texture read modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipTextureReadMode(pub ::std::os::raw::c_int); +#[doc = " hip texture reference"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct textureReference { + pub normalized: ::std::os::raw::c_int, + pub readMode: hipTextureReadMode, + pub filterMode: hipTextureFilterMode, + pub addressMode: [hipTextureAddressMode; 3usize], + pub channelDesc: hipChannelFormatDesc, + pub sRGB: ::std::os::raw::c_int, + pub maxAnisotropy: ::std::os::raw::c_uint, + pub mipmapFilterMode: hipTextureFilterMode, + pub mipmapLevelBias: f32, + pub minMipmapLevelClamp: f32, + pub maxMipmapLevelClamp: f32, + pub textureObject: hipTextureObject_t, + pub numChannels: ::std::os::raw::c_int, + pub format: hipArray_Format, +} +#[doc = " hip texture descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipTextureDesc { + pub addressMode: [hipTextureAddressMode; 3usize], + pub filterMode: hipTextureFilterMode, + pub readMode: hipTextureReadMode, + pub sRGB: ::std::os::raw::c_int, + pub borderColor: [f32; 4usize], + pub normalizedCoords: ::std::os::raw::c_int, + pub maxAnisotropy: ::std::os::raw::c_uint, + pub mipmapFilterMode: hipTextureFilterMode, + pub mipmapLevelBias: f32, + pub minMipmapLevelClamp: f32, + pub maxMipmapLevelClamp: f32, +} +#[doc = " An opaque value that represents a hip surface object"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __hip_surface { + _unused: [u8; 0], +} +pub type hipSurfaceObject_t = *mut __hip_surface; +impl hipSurfaceBoundaryMode { + pub const hipBoundaryModeZero: hipSurfaceBoundaryMode = hipSurfaceBoundaryMode(0); +} +impl hipSurfaceBoundaryMode { + pub const hipBoundaryModeTrap: hipSurfaceBoundaryMode = hipSurfaceBoundaryMode(1); +} +impl hipSurfaceBoundaryMode { + pub const hipBoundaryModeClamp: hipSurfaceBoundaryMode = hipSurfaceBoundaryMode(2); +} +#[repr(transparent)] +#[doc = " hip surface boundary modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipSurfaceBoundaryMode(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipCtx_t { + _unused: [u8; 0], +} +pub type hipCtx_t = *mut ihipCtx_t; +pub type hipDevice_t = ::std::os::raw::c_int; +impl hipDeviceP2PAttr { + pub const hipDevP2PAttrPerformanceRank: hipDeviceP2PAttr = hipDeviceP2PAttr(0); +} +impl hipDeviceP2PAttr { + pub const hipDevP2PAttrAccessSupported: hipDeviceP2PAttr = hipDeviceP2PAttr(1); +} +impl hipDeviceP2PAttr { + pub const hipDevP2PAttrNativeAtomicSupported: hipDeviceP2PAttr = hipDeviceP2PAttr(2); +} +impl hipDeviceP2PAttr { + pub const hipDevP2PAttrHipArrayAccessSupported: hipDeviceP2PAttr = hipDeviceP2PAttr(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipDeviceP2PAttr(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +pub type hipStream_t = *mut ihipStream_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipIpcMemHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +pub type hipIpcMemHandle_t = hipIpcMemHandle_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipIpcEventHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +pub type hipIpcEventHandle_t = hipIpcEventHandle_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipModule_t { + _unused: [u8; 0], +} +pub type hipModule_t = *mut ihipModule_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipModuleSymbol_t { + _unused: [u8; 0], +} +pub type hipFunction_t = *mut ihipModuleSymbol_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipMemPoolHandle_t { + _unused: [u8; 0], +} +#[doc = " HIP memory pool"] +pub type hipMemPool_t = *mut ihipMemPoolHandle_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipFuncAttributes { + pub binaryVersion: ::std::os::raw::c_int, + pub cacheModeCA: ::std::os::raw::c_int, + pub constSizeBytes: usize, + pub localSizeBytes: usize, + pub maxDynamicSharedSizeBytes: ::std::os::raw::c_int, + pub maxThreadsPerBlock: ::std::os::raw::c_int, + pub numRegs: ::std::os::raw::c_int, + pub preferredShmemCarveout: ::std::os::raw::c_int, + pub ptxVersion: ::std::os::raw::c_int, + pub sharedSizeBytes: usize, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipEvent_t { + _unused: [u8; 0], +} +pub type hipEvent_t = *mut ihipEvent_t; +impl hipLimit_t { + #[doc = "< limit of stack size in bytes on the current device"] + pub const hipLimitStackSize: hipLimit_t = hipLimit_t(0); +} +impl hipLimit_t { + #[doc = "< size limit in bytes of fifo used by printf call on the device"] + pub const hipLimitPrintfFifoSize: hipLimit_t = hipLimit_t(1); +} +impl hipLimit_t { + #[doc = "< limit of heap size in bytes on the current device"] + pub const hipLimitMallocHeapSize: hipLimit_t = hipLimit_t(2); +} +impl hipLimit_t { + #[doc = "< supported limit range"] + pub const hipLimitRange: hipLimit_t = hipLimit_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipLimit_t(pub ::std::os::raw::c_int); +impl hipMemoryAdvise { + #[doc = "< Data will mostly be read and only occassionally\n< be written to"] + pub const hipMemAdviseSetReadMostly: hipMemoryAdvise = hipMemoryAdvise(1); +} +impl hipMemoryAdvise { + #[doc = "< Undo the effect of hipMemAdviseSetReadMostly"] + pub const hipMemAdviseUnsetReadMostly: hipMemoryAdvise = hipMemoryAdvise(2); +} +impl hipMemoryAdvise { + #[doc = "< Set the preferred location for the data as\n< the specified device"] + pub const hipMemAdviseSetPreferredLocation: hipMemoryAdvise = hipMemoryAdvise(3); +} +impl hipMemoryAdvise { + #[doc = "< Clear the preferred location for the data"] + pub const hipMemAdviseUnsetPreferredLocation: hipMemoryAdvise = hipMemoryAdvise(4); +} +impl hipMemoryAdvise { + #[doc = "< Data will be accessed by the specified device\n< so prevent page faults as much as possible"] + pub const hipMemAdviseSetAccessedBy: hipMemoryAdvise = hipMemoryAdvise(5); +} +impl hipMemoryAdvise { + #[doc = "< Let HIP to decide on the page faulting policy\n< for the specified device"] + pub const hipMemAdviseUnsetAccessedBy: hipMemoryAdvise = hipMemoryAdvise(6); +} +impl hipMemoryAdvise { + #[doc = "< The default memory model is fine-grain. That allows\n< coherent operations between host and device, while\n< executing kernels. The coarse-grain can be used\n< for data that only needs to be coherent at dispatch\n< boundaries for better performance"] + pub const hipMemAdviseSetCoarseGrain: hipMemoryAdvise = hipMemoryAdvise(100); +} +impl hipMemoryAdvise { + #[doc = "< Restores cache coherency policy back to fine-grain"] + pub const hipMemAdviseUnsetCoarseGrain: hipMemoryAdvise = hipMemoryAdvise(101); +} +#[repr(transparent)] +#[doc = " HIP Memory Advise values\n\n @note This memory advise enumeration is used on Linux, not Windows."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemoryAdvise(pub ::std::os::raw::c_int); +impl hipMemRangeCoherencyMode { + #[doc = "< Updates to memory with this attribute can be\n< done coherently from all devices"] + pub const hipMemRangeCoherencyModeFineGrain: hipMemRangeCoherencyMode = + hipMemRangeCoherencyMode(0); +} +impl hipMemRangeCoherencyMode { + #[doc = "< Writes to memory with this attribute can be\n< performed by a single device at a time"] + pub const hipMemRangeCoherencyModeCoarseGrain: hipMemRangeCoherencyMode = + hipMemRangeCoherencyMode(1); +} +impl hipMemRangeCoherencyMode { + #[doc = "< Memory region queried contains subregions with\n< both hipMemRangeCoherencyModeFineGrain and\n< hipMemRangeCoherencyModeCoarseGrain attributes"] + pub const hipMemRangeCoherencyModeIndeterminate: hipMemRangeCoherencyMode = + hipMemRangeCoherencyMode(2); +} +#[repr(transparent)] +#[doc = " HIP Coherency Mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemRangeCoherencyMode(pub ::std::os::raw::c_int); +impl hipMemRangeAttribute { + #[doc = "< Whether the range will mostly be read and\n< only occassionally be written to"] + pub const hipMemRangeAttributeReadMostly: hipMemRangeAttribute = hipMemRangeAttribute(1); +} +impl hipMemRangeAttribute { + #[doc = "< The preferred location of the range"] + pub const hipMemRangeAttributePreferredLocation: hipMemRangeAttribute = hipMemRangeAttribute(2); +} +impl hipMemRangeAttribute { + #[doc = "< Memory range has hipMemAdviseSetAccessedBy\n< set for the specified device"] + pub const hipMemRangeAttributeAccessedBy: hipMemRangeAttribute = hipMemRangeAttribute(3); +} +impl hipMemRangeAttribute { + #[doc = "< The last location to where the range was\n< prefetched"] + pub const hipMemRangeAttributeLastPrefetchLocation: hipMemRangeAttribute = + hipMemRangeAttribute(4); +} +impl hipMemRangeAttribute { + #[doc = "< Returns coherency mode\n< @ref hipMemRangeCoherencyMode for the range"] + pub const hipMemRangeAttributeCoherencyMode: hipMemRangeAttribute = hipMemRangeAttribute(100); +} +#[repr(transparent)] +#[doc = " HIP range attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemRangeAttribute(pub ::std::os::raw::c_int); +impl hipMemPoolAttr { + #[doc = " (value type = int)\n Allow @p hipMemAllocAsync to use memory asynchronously freed\n in another streams as long as a stream ordering dependency\n of the allocating stream on the free action exists.\n hip events and null stream interactions can create the required\n stream ordered dependencies. (default enabled)"] + pub const hipMemPoolReuseFollowEventDependencies: hipMemPoolAttr = hipMemPoolAttr(1); +} +impl hipMemPoolAttr { + #[doc = " (value type = int)\n Allow reuse of already completed frees when there is no dependency\n between the free and allocation. (default enabled)"] + pub const hipMemPoolReuseAllowOpportunistic: hipMemPoolAttr = hipMemPoolAttr(2); +} +impl hipMemPoolAttr { + #[doc = " (value type = int)\n Allow @p hipMemAllocAsync to insert new stream dependencies\n in order to establish the stream ordering required to reuse\n a piece of memory released by cuFreeAsync (default enabled)."] + pub const hipMemPoolReuseAllowInternalDependencies: hipMemPoolAttr = hipMemPoolAttr(3); +} +impl hipMemPoolAttr { + #[doc = " (value type = uint64_t)\n Amount of reserved memory in bytes to hold onto before trying\n to release memory back to the OS. When more than the release\n threshold bytes of memory are held by the memory pool, the\n allocator will try to release memory back to the OS on the\n next call to stream, event or context synchronize. (default 0)"] + pub const hipMemPoolAttrReleaseThreshold: hipMemPoolAttr = hipMemPoolAttr(4); +} +impl hipMemPoolAttr { + #[doc = " (value type = uint64_t)\n Amount of backing memory currently allocated for the mempool."] + pub const hipMemPoolAttrReservedMemCurrent: hipMemPoolAttr = hipMemPoolAttr(5); +} +impl hipMemPoolAttr { + #[doc = " (value type = uint64_t)\n High watermark of backing memory allocated for the mempool since the\n last time it was reset. High watermark can only be reset to zero."] + pub const hipMemPoolAttrReservedMemHigh: hipMemPoolAttr = hipMemPoolAttr(6); +} +impl hipMemPoolAttr { + #[doc = " (value type = uint64_t)\n Amount of memory from the pool that is currently in use by the application."] + pub const hipMemPoolAttrUsedMemCurrent: hipMemPoolAttr = hipMemPoolAttr(7); +} +impl hipMemPoolAttr { + #[doc = " (value type = uint64_t)\n High watermark of the amount of memory from the pool that was in use by the application since\n the last time it was reset. High watermark can only be reset to zero."] + pub const hipMemPoolAttrUsedMemHigh: hipMemPoolAttr = hipMemPoolAttr(8); +} +#[repr(transparent)] +#[doc = " HIP memory pool attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemPoolAttr(pub ::std::os::raw::c_int); +impl hipMemLocationType { + pub const hipMemLocationTypeInvalid: hipMemLocationType = hipMemLocationType(0); +} +impl hipMemLocationType { + #[doc = "< Device location, thus it's HIP device ID"] + pub const hipMemLocationTypeDevice: hipMemLocationType = hipMemLocationType(1); +} +#[repr(transparent)] +#[doc = " Specifies the type of location"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemLocationType(pub ::std::os::raw::c_int); +#[doc = " Specifies a memory location.\n\n To specify a gpu, set type = @p hipMemLocationTypeDevice and set id = the gpu's device ID"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemLocation { + #[doc = "< Specifies the location type, which describes the meaning of id"] + pub type_: hipMemLocationType, + #[doc = "< Identifier for the provided location type @p hipMemLocationType"] + pub id: ::std::os::raw::c_int, +} +impl hipMemAccessFlags { + #[doc = "< Default, make the address range not accessible"] + pub const hipMemAccessFlagsProtNone: hipMemAccessFlags = hipMemAccessFlags(0); +} +impl hipMemAccessFlags { + #[doc = "< Set the address range read accessible"] + pub const hipMemAccessFlagsProtRead: hipMemAccessFlags = hipMemAccessFlags(1); +} +impl hipMemAccessFlags { + #[doc = "< Set the address range read-write accessible"] + pub const hipMemAccessFlagsProtReadWrite: hipMemAccessFlags = hipMemAccessFlags(3); +} +#[repr(transparent)] +#[doc = " Specifies the memory protection flags for mapping\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemAccessFlags(pub ::std::os::raw::c_int); +#[doc = " Memory access descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemAccessDesc { + #[doc = "< Location on which the accessibility has to change"] + pub location: hipMemLocation, + #[doc = "< Accessibility flags to set"] + pub flags: hipMemAccessFlags, +} +impl hipMemAllocationType { + pub const hipMemAllocationTypeInvalid: hipMemAllocationType = hipMemAllocationType(0); +} +impl hipMemAllocationType { + #[doc = " This allocation type is 'pinned', i.e. cannot migrate from its current\n location while the application is actively using it"] + pub const hipMemAllocationTypePinned: hipMemAllocationType = hipMemAllocationType(1); +} +impl hipMemAllocationType { + #[doc = " This allocation type is 'pinned', i.e. cannot migrate from its current\n location while the application is actively using it"] + pub const hipMemAllocationTypeMax: hipMemAllocationType = hipMemAllocationType(2147483647); +} +#[repr(transparent)] +#[doc = " Defines the allocation types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemAllocationType(pub ::std::os::raw::c_int); +impl hipMemAllocationHandleType { + #[doc = "< Does not allow any export mechanism"] + pub const hipMemHandleTypeNone: hipMemAllocationHandleType = hipMemAllocationHandleType(0); +} +impl hipMemAllocationHandleType { + #[doc = "< Allows a file descriptor for exporting. Permitted only on POSIX systems"] + pub const hipMemHandleTypePosixFileDescriptor: hipMemAllocationHandleType = + hipMemAllocationHandleType(1); +} +impl hipMemAllocationHandleType { + #[doc = "< Allows a Win32 NT handle for exporting. (HANDLE)"] + pub const hipMemHandleTypeWin32: hipMemAllocationHandleType = hipMemAllocationHandleType(2); +} +impl hipMemAllocationHandleType { + #[doc = "< Allows a Win32 KMT handle for exporting. (D3DKMT_HANDLE)"] + pub const hipMemHandleTypeWin32Kmt: hipMemAllocationHandleType = hipMemAllocationHandleType(4); +} +#[repr(transparent)] +#[doc = " Flags for specifying handle types for memory pool allocations\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemAllocationHandleType(pub ::std::os::raw::c_int); +#[doc = " Specifies the properties of allocations made from the pool."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemPoolProps { + #[doc = "< Allocation type. Currently must be specified as @p hipMemAllocationTypePinned"] + pub allocType: hipMemAllocationType, + #[doc = "< Handle types that will be supported by allocations from the pool"] + pub handleTypes: hipMemAllocationHandleType, + #[doc = "< Location where allocations should reside"] + pub location: hipMemLocation, + #[doc = " Windows-specific LPSECURITYATTRIBUTES required when @p hipMemHandleTypeWin32 is specified"] + pub win32SecurityAttributes: *mut ::std::os::raw::c_void, + #[doc = "< Reserved for future use, must be 0"] + pub reserved: [::std::os::raw::c_uchar; 64usize], +} +#[doc = " Opaque data structure for exporting a pool allocation"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemPoolPtrExportData { + pub reserved: [::std::os::raw::c_uchar; 64usize], +} +impl hipJitOption { + pub const hipJitOptionMaxRegisters: hipJitOption = hipJitOption(0); +} +impl hipJitOption { + pub const hipJitOptionThreadsPerBlock: hipJitOption = hipJitOption(1); +} +impl hipJitOption { + pub const hipJitOptionWallTime: hipJitOption = hipJitOption(2); +} +impl hipJitOption { + pub const hipJitOptionInfoLogBuffer: hipJitOption = hipJitOption(3); +} +impl hipJitOption { + pub const hipJitOptionInfoLogBufferSizeBytes: hipJitOption = hipJitOption(4); +} +impl hipJitOption { + pub const hipJitOptionErrorLogBuffer: hipJitOption = hipJitOption(5); +} +impl hipJitOption { + pub const hipJitOptionErrorLogBufferSizeBytes: hipJitOption = hipJitOption(6); +} +impl hipJitOption { + pub const hipJitOptionOptimizationLevel: hipJitOption = hipJitOption(7); +} +impl hipJitOption { + pub const hipJitOptionTargetFromContext: hipJitOption = hipJitOption(8); +} +impl hipJitOption { + pub const hipJitOptionTarget: hipJitOption = hipJitOption(9); +} +impl hipJitOption { + pub const hipJitOptionFallbackStrategy: hipJitOption = hipJitOption(10); +} +impl hipJitOption { + pub const hipJitOptionGenerateDebugInfo: hipJitOption = hipJitOption(11); +} +impl hipJitOption { + pub const hipJitOptionLogVerbose: hipJitOption = hipJitOption(12); +} +impl hipJitOption { + pub const hipJitOptionGenerateLineInfo: hipJitOption = hipJitOption(13); +} +impl hipJitOption { + pub const hipJitOptionCacheMode: hipJitOption = hipJitOption(14); +} +impl hipJitOption { + pub const hipJitOptionSm3xOpt: hipJitOption = hipJitOption(15); +} +impl hipJitOption { + pub const hipJitOptionFastCompile: hipJitOption = hipJitOption(16); +} +impl hipJitOption { + pub const hipJitOptionNumOptions: hipJitOption = hipJitOption(17); +} +#[repr(transparent)] +#[doc = " hipJitOption"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipJitOption(pub ::std::os::raw::c_int); +impl hipFuncAttribute { + pub const hipFuncAttributeMaxDynamicSharedMemorySize: hipFuncAttribute = hipFuncAttribute(8); +} +impl hipFuncAttribute { + pub const hipFuncAttributePreferredSharedMemoryCarveout: hipFuncAttribute = hipFuncAttribute(9); +} +impl hipFuncAttribute { + pub const hipFuncAttributeMax: hipFuncAttribute = hipFuncAttribute(10); +} +#[repr(transparent)] +#[doc = " @warning On AMD devices and some Nvidia devices, these hints and controls are ignored."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipFuncAttribute(pub ::std::os::raw::c_int); +impl hipFuncCache_t { + #[doc = "< no preference for shared memory or L1 (default)"] + pub const hipFuncCachePreferNone: hipFuncCache_t = hipFuncCache_t(0); +} +impl hipFuncCache_t { + #[doc = "< prefer larger shared memory and smaller L1 cache"] + pub const hipFuncCachePreferShared: hipFuncCache_t = hipFuncCache_t(1); +} +impl hipFuncCache_t { + #[doc = "< prefer larger L1 cache and smaller shared memory"] + pub const hipFuncCachePreferL1: hipFuncCache_t = hipFuncCache_t(2); +} +impl hipFuncCache_t { + #[doc = "< prefer equal size L1 cache and shared memory"] + pub const hipFuncCachePreferEqual: hipFuncCache_t = hipFuncCache_t(3); +} +#[repr(transparent)] +#[doc = " @warning On AMD devices and some Nvidia devices, these hints and controls are ignored."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipFuncCache_t(pub ::std::os::raw::c_int); +impl hipSharedMemConfig { + #[doc = "< The compiler selects a device-specific value for the banking."] + pub const hipSharedMemBankSizeDefault: hipSharedMemConfig = hipSharedMemConfig(0); +} +impl hipSharedMemConfig { + #[doc = "< Shared mem is banked at 4-bytes intervals and performs best\n< when adjacent threads access data 4 bytes apart."] + pub const hipSharedMemBankSizeFourByte: hipSharedMemConfig = hipSharedMemConfig(1); +} +impl hipSharedMemConfig { + #[doc = "< Shared mem is banked at 8-byte intervals and performs best\n< when adjacent threads access data 4 bytes apart."] + pub const hipSharedMemBankSizeEightByte: hipSharedMemConfig = hipSharedMemConfig(2); +} +#[repr(transparent)] +#[doc = " @warning On AMD devices and some Nvidia devices, these hints and controls are ignored."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipSharedMemConfig(pub ::std::os::raw::c_int); +#[doc = " Struct for data in 3D"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct dim3 { + #[doc = "< x"] + pub x: u32, + #[doc = "< y"] + pub y: u32, + #[doc = "< z"] + pub z: u32, +} +#[doc = " struct hipLaunchParams_t"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipLaunchParams_t { + #[doc = "< Device function symbol"] + pub func: *mut ::std::os::raw::c_void, + #[doc = "< Grid dimentions"] + pub gridDim: dim3, + #[doc = "< Block dimentions"] + pub blockDim: dim3, + #[doc = "< Arguments"] + pub args: *mut *mut ::std::os::raw::c_void, + #[doc = "< Shared memory"] + pub sharedMem: usize, + #[doc = "< Stream identifier"] + pub stream: hipStream_t, +} +#[doc = " struct hipLaunchParams_t"] +pub type hipLaunchParams = hipLaunchParams_t; +#[doc = " struct hipFunctionLaunchParams_t"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipFunctionLaunchParams_t { + #[doc = "< Kernel to launch"] + pub function: hipFunction_t, + #[doc = "< Width(X) of grid in blocks"] + pub gridDimX: ::std::os::raw::c_uint, + #[doc = "< Height(Y) of grid in blocks"] + pub gridDimY: ::std::os::raw::c_uint, + #[doc = "< Depth(Z) of grid in blocks"] + pub gridDimZ: ::std::os::raw::c_uint, + #[doc = "< X dimension of each thread block"] + pub blockDimX: ::std::os::raw::c_uint, + #[doc = "< Y dimension of each thread block"] + pub blockDimY: ::std::os::raw::c_uint, + #[doc = "< Z dimension of each thread block"] + pub blockDimZ: ::std::os::raw::c_uint, + #[doc = "< Shared memory"] + pub sharedMemBytes: ::std::os::raw::c_uint, + #[doc = "< Stream identifier"] + pub hStream: hipStream_t, + #[doc = "< Kernel parameters"] + pub kernelParams: *mut *mut ::std::os::raw::c_void, +} +#[doc = " struct hipFunctionLaunchParams_t"] +pub type hipFunctionLaunchParams = hipFunctionLaunchParams_t; +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeOpaqueFd: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(1); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeOpaqueWin32: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(2); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeOpaqueWin32Kmt: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(3); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeD3D12Heap: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(4); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeD3D12Resource: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(5); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeD3D11Resource: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(6); +} +impl hipExternalMemoryHandleType_enum { + pub const hipExternalMemoryHandleTypeD3D11ResourceKmt: hipExternalMemoryHandleType_enum = + hipExternalMemoryHandleType_enum(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipExternalMemoryHandleType_enum(pub ::std::os::raw::c_int); +pub use self::hipExternalMemoryHandleType_enum as hipExternalMemoryHandleType; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalMemoryHandleDesc_st { + pub type_: hipExternalMemoryHandleType, + pub handle: hipExternalMemoryHandleDesc_st__bindgen_ty_1, + pub size: ::std::os::raw::c_ulonglong, + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipExternalMemoryHandleDesc_st__bindgen_ty_1 { + pub fd: ::std::os::raw::c_int, + pub win32: hipExternalMemoryHandleDesc_st__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalMemoryHandleDesc_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 hipExternalMemoryHandleDesc = hipExternalMemoryHandleDesc_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalMemoryBufferDesc_st { + pub offset: ::std::os::raw::c_ulonglong, + pub size: ::std::os::raw::c_ulonglong, + pub flags: ::std::os::raw::c_uint, +} +pub type hipExternalMemoryBufferDesc = hipExternalMemoryBufferDesc_st; +pub type hipExternalMemory_t = *mut ::std::os::raw::c_void; +impl hipExternalSemaphoreHandleType_enum { + pub const hipExternalSemaphoreHandleTypeOpaqueFd: hipExternalSemaphoreHandleType_enum = + hipExternalSemaphoreHandleType_enum(1); +} +impl hipExternalSemaphoreHandleType_enum { + pub const hipExternalSemaphoreHandleTypeOpaqueWin32: hipExternalSemaphoreHandleType_enum = + hipExternalSemaphoreHandleType_enum(2); +} +impl hipExternalSemaphoreHandleType_enum { + pub const hipExternalSemaphoreHandleTypeOpaqueWin32Kmt: hipExternalSemaphoreHandleType_enum = + hipExternalSemaphoreHandleType_enum(3); +} +impl hipExternalSemaphoreHandleType_enum { + pub const hipExternalSemaphoreHandleTypeD3D12Fence: hipExternalSemaphoreHandleType_enum = + hipExternalSemaphoreHandleType_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipExternalSemaphoreHandleType_enum(pub ::std::os::raw::c_int); +pub use self::hipExternalSemaphoreHandleType_enum as hipExternalSemaphoreHandleType; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreHandleDesc_st { + pub type_: hipExternalSemaphoreHandleType, + pub handle: hipExternalSemaphoreHandleDesc_st__bindgen_ty_1, + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipExternalSemaphoreHandleDesc_st__bindgen_ty_1 { + pub fd: ::std::os::raw::c_int, + pub win32: hipExternalSemaphoreHandleDesc_st__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreHandleDesc_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 hipExternalSemaphoreHandleDesc = hipExternalSemaphoreHandleDesc_st; +pub type hipExternalSemaphore_t = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreSignalParams_st { + pub params: hipExternalSemaphoreSignalParams_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 hipExternalSemaphoreSignalParams_st__bindgen_ty_1 { + pub fence: hipExternalSemaphoreSignalParams_st__bindgen_ty_1__bindgen_ty_1, + pub keyedMutex: hipExternalSemaphoreSignalParams_st__bindgen_ty_1__bindgen_ty_2, + pub reserved: [::std::os::raw::c_uint; 12usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreSignalParams_st__bindgen_ty_1__bindgen_ty_1 { + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreSignalParams_st__bindgen_ty_1__bindgen_ty_2 { + pub key: ::std::os::raw::c_ulonglong, +} +pub type hipExternalSemaphoreSignalParams = hipExternalSemaphoreSignalParams_st; +#[doc = " External semaphore wait parameters, compatible with driver type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreWaitParams_st { + pub params: hipExternalSemaphoreWaitParams_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 hipExternalSemaphoreWaitParams_st__bindgen_ty_1 { + pub fence: hipExternalSemaphoreWaitParams_st__bindgen_ty_1__bindgen_ty_1, + pub keyedMutex: hipExternalSemaphoreWaitParams_st__bindgen_ty_1__bindgen_ty_2, + pub reserved: [::std::os::raw::c_uint; 10usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreWaitParams_st__bindgen_ty_1__bindgen_ty_1 { + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreWaitParams_st__bindgen_ty_1__bindgen_ty_2 { + pub key: ::std::os::raw::c_ulonglong, + pub timeoutMs: ::std::os::raw::c_uint, +} +#[doc = " External semaphore wait parameters, compatible with driver type"] +pub type hipExternalSemaphoreWaitParams = hipExternalSemaphoreWaitParams_st; +impl hipGLDeviceList { + #[doc = "< All hip devices used by current OpenGL context."] + pub const hipGLDeviceListAll: hipGLDeviceList = hipGLDeviceList(1); +} +impl hipGLDeviceList { + #[doc = "< Hip devices used by current OpenGL context in current\n< frame"] + pub const hipGLDeviceListCurrentFrame: hipGLDeviceList = hipGLDeviceList(2); +} +impl hipGLDeviceList { + #[doc = "< Hip devices used by current OpenGL context in next\n< frame."] + pub const hipGLDeviceListNextFrame: hipGLDeviceList = hipGLDeviceList(3); +} +#[repr(transparent)] +#[doc = " HIP Devices used by current OpenGL Context."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGLDeviceList(pub ::std::os::raw::c_int); +impl hipGraphicsRegisterFlags { + pub const hipGraphicsRegisterFlagsNone: hipGraphicsRegisterFlags = hipGraphicsRegisterFlags(0); +} +impl hipGraphicsRegisterFlags { + #[doc = "< HIP will not write to this registered resource"] + pub const hipGraphicsRegisterFlagsReadOnly: hipGraphicsRegisterFlags = + hipGraphicsRegisterFlags(1); +} +impl hipGraphicsRegisterFlags { + pub const hipGraphicsRegisterFlagsWriteDiscard: hipGraphicsRegisterFlags = + hipGraphicsRegisterFlags(2); +} +impl hipGraphicsRegisterFlags { + #[doc = "< HIP will bind this resource to a surface"] + pub const hipGraphicsRegisterFlagsSurfaceLoadStore: hipGraphicsRegisterFlags = + hipGraphicsRegisterFlags(4); +} +impl hipGraphicsRegisterFlags { + pub const hipGraphicsRegisterFlagsTextureGather: hipGraphicsRegisterFlags = + hipGraphicsRegisterFlags(8); +} +#[repr(transparent)] +#[doc = " HIP Access falgs for Interop resources."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphicsRegisterFlags(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _hipGraphicsResource { + _unused: [u8; 0], +} +pub type hipGraphicsResource = _hipGraphicsResource; +pub type hipGraphicsResource_t = *mut hipGraphicsResource; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipGraph { + _unused: [u8; 0], +} +#[doc = " An opaque value that represents a hip graph"] +pub type hipGraph_t = *mut ihipGraph; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipGraphNode { + _unused: [u8; 0], +} +#[doc = " An opaque value that represents a hip graph node"] +pub type hipGraphNode_t = *mut hipGraphNode; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipGraphExec { + _unused: [u8; 0], +} +#[doc = " An opaque value that represents a hip graph Exec"] +pub type hipGraphExec_t = *mut hipGraphExec; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipUserObject { + _unused: [u8; 0], +} +#[doc = " An opaque value that represents a user obj"] +pub type hipUserObject_t = *mut hipUserObject; +impl hipGraphNodeType { + #[doc = "< GPU kernel node"] + pub const hipGraphNodeTypeKernel: hipGraphNodeType = hipGraphNodeType(0); +} +impl hipGraphNodeType { + #[doc = "< Memcpy node"] + pub const hipGraphNodeTypeMemcpy: hipGraphNodeType = hipGraphNodeType(1); +} +impl hipGraphNodeType { + #[doc = "< Memset node"] + pub const hipGraphNodeTypeMemset: hipGraphNodeType = hipGraphNodeType(2); +} +impl hipGraphNodeType { + #[doc = "< Host (executable) node"] + pub const hipGraphNodeTypeHost: hipGraphNodeType = hipGraphNodeType(3); +} +impl hipGraphNodeType { + #[doc = "< Node which executes an embedded graph"] + pub const hipGraphNodeTypeGraph: hipGraphNodeType = hipGraphNodeType(4); +} +impl hipGraphNodeType { + #[doc = "< Empty (no-op) node"] + pub const hipGraphNodeTypeEmpty: hipGraphNodeType = hipGraphNodeType(5); +} +impl hipGraphNodeType { + #[doc = "< External event wait node"] + pub const hipGraphNodeTypeWaitEvent: hipGraphNodeType = hipGraphNodeType(6); +} +impl hipGraphNodeType { + #[doc = "< External event record node"] + pub const hipGraphNodeTypeEventRecord: hipGraphNodeType = hipGraphNodeType(7); +} +impl hipGraphNodeType { + #[doc = "< External Semaphore signal node"] + pub const hipGraphNodeTypeExtSemaphoreSignal: hipGraphNodeType = hipGraphNodeType(8); +} +impl hipGraphNodeType { + #[doc = "< External Semaphore wait node"] + pub const hipGraphNodeTypeExtSemaphoreWait: hipGraphNodeType = hipGraphNodeType(9); +} +impl hipGraphNodeType { + #[doc = "< Memory alloc node"] + pub const hipGraphNodeTypeMemAlloc: hipGraphNodeType = hipGraphNodeType(10); +} +impl hipGraphNodeType { + #[doc = "< Memory free node"] + pub const hipGraphNodeTypeMemFree: hipGraphNodeType = hipGraphNodeType(11); +} +impl hipGraphNodeType { + #[doc = "< MemcpyFromSymbol node"] + pub const hipGraphNodeTypeMemcpyFromSymbol: hipGraphNodeType = hipGraphNodeType(12); +} +impl hipGraphNodeType { + #[doc = "< MemcpyToSymbol node"] + pub const hipGraphNodeTypeMemcpyToSymbol: hipGraphNodeType = hipGraphNodeType(13); +} +impl hipGraphNodeType { + pub const hipGraphNodeTypeCount: hipGraphNodeType = hipGraphNodeType(14); +} +#[repr(transparent)] +#[doc = " hipGraphNodeType"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphNodeType(pub ::std::os::raw::c_int); +pub type hipHostFn_t = + ::std::option::Option; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipHostNodeParams { + pub fn_: hipHostFn_t, + pub userData: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipKernelNodeParams { + pub blockDim: dim3, + pub extra: *mut *mut ::std::os::raw::c_void, + pub func: *mut ::std::os::raw::c_void, + pub gridDim: dim3, + pub kernelParams: *mut *mut ::std::os::raw::c_void, + pub sharedMemBytes: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemsetParams { + pub dst: *mut ::std::os::raw::c_void, + pub elementSize: ::std::os::raw::c_uint, + pub height: usize, + pub pitch: usize, + pub value: ::std::os::raw::c_uint, + pub width: usize, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemAllocNodeParams { + #[doc = "< Pool properties, which contain where\n< the location should reside"] + pub poolProps: hipMemPoolProps, + #[doc = "< The number of memory access descriptors.\n< Must not be bigger than the number of GPUs"] + pub accessDescs: *const hipMemAccessDesc, + #[doc = "< The number of access descriptors"] + pub accessDescCount: usize, + #[doc = "< The size of the requested allocation in bytes"] + pub bytesize: usize, + #[doc = "< Returned device address of the allocation"] + pub dptr: *mut ::std::os::raw::c_void, +} +impl hipKernelNodeAttrID { + pub const hipKernelNodeAttributeAccessPolicyWindow: hipKernelNodeAttrID = + hipKernelNodeAttrID(1); +} +impl hipKernelNodeAttrID { + pub const hipKernelNodeAttributeCooperative: hipKernelNodeAttrID = hipKernelNodeAttrID(2); +} +#[repr(transparent)] +#[doc = " Kernel node attributeID"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipKernelNodeAttrID(pub ::std::os::raw::c_int); +impl hipAccessProperty { + pub const hipAccessPropertyNormal: hipAccessProperty = hipAccessProperty(0); +} +impl hipAccessProperty { + pub const hipAccessPropertyStreaming: hipAccessProperty = hipAccessProperty(1); +} +impl hipAccessProperty { + pub const hipAccessPropertyPersisting: hipAccessProperty = hipAccessProperty(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipAccessProperty(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipAccessPolicyWindow { + pub base_ptr: *mut ::std::os::raw::c_void, + pub hitProp: hipAccessProperty, + pub hitRatio: f32, + pub missProp: hipAccessProperty, + pub num_bytes: usize, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipKernelNodeAttrValue { + pub accessPolicyWindow: hipAccessPolicyWindow, + pub cooperative: ::std::os::raw::c_int, +} +impl hipGraphExecUpdateResult { + #[doc = "< The update succeeded"] + pub const hipGraphExecUpdateSuccess: hipGraphExecUpdateResult = hipGraphExecUpdateResult(0); +} +impl hipGraphExecUpdateResult { + #[doc = "< The update failed for an unexpected reason which is described\n< in the return value of the function"] + pub const hipGraphExecUpdateError: hipGraphExecUpdateResult = hipGraphExecUpdateResult(1); +} +impl hipGraphExecUpdateResult { + #[doc = "< The update failed because the topology changed"] + pub const hipGraphExecUpdateErrorTopologyChanged: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(2); +} +impl hipGraphExecUpdateResult { + #[doc = "< The update failed because a node type changed"] + pub const hipGraphExecUpdateErrorNodeTypeChanged: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(3); +} +impl hipGraphExecUpdateResult { + pub const hipGraphExecUpdateErrorFunctionChanged: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(4); +} +impl hipGraphExecUpdateResult { + pub const hipGraphExecUpdateErrorParametersChanged: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(5); +} +impl hipGraphExecUpdateResult { + pub const hipGraphExecUpdateErrorNotSupported: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(6); +} +impl hipGraphExecUpdateResult { + pub const hipGraphExecUpdateErrorUnsupportedFunctionChange: hipGraphExecUpdateResult = + hipGraphExecUpdateResult(7); +} +#[repr(transparent)] +#[doc = " Graph execution update result"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphExecUpdateResult(pub ::std::os::raw::c_int); +impl hipStreamCaptureMode { + pub const hipStreamCaptureModeGlobal: hipStreamCaptureMode = hipStreamCaptureMode(0); +} +impl hipStreamCaptureMode { + pub const hipStreamCaptureModeThreadLocal: hipStreamCaptureMode = hipStreamCaptureMode(1); +} +impl hipStreamCaptureMode { + pub const hipStreamCaptureModeRelaxed: hipStreamCaptureMode = hipStreamCaptureMode(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipStreamCaptureMode(pub ::std::os::raw::c_int); +impl hipStreamCaptureStatus { + #[doc = "< Stream is not capturing"] + pub const hipStreamCaptureStatusNone: hipStreamCaptureStatus = hipStreamCaptureStatus(0); +} +impl hipStreamCaptureStatus { + #[doc = "< Stream is actively capturing"] + pub const hipStreamCaptureStatusActive: hipStreamCaptureStatus = hipStreamCaptureStatus(1); +} +impl hipStreamCaptureStatus { + #[doc = "< Stream is part of a capture sequence that has been\n< invalidated, but not terminated"] + pub const hipStreamCaptureStatusInvalidated: hipStreamCaptureStatus = hipStreamCaptureStatus(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipStreamCaptureStatus(pub ::std::os::raw::c_int); +impl hipStreamUpdateCaptureDependenciesFlags { + #[doc = "< Add new nodes to the dependency set"] + pub const hipStreamAddCaptureDependencies: hipStreamUpdateCaptureDependenciesFlags = + hipStreamUpdateCaptureDependenciesFlags(0); +} +impl hipStreamUpdateCaptureDependenciesFlags { + #[doc = "< Replace the dependency set with the new nodes"] + pub const hipStreamSetCaptureDependencies: hipStreamUpdateCaptureDependenciesFlags = + hipStreamUpdateCaptureDependenciesFlags(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipStreamUpdateCaptureDependenciesFlags(pub ::std::os::raw::c_int); +impl hipGraphMemAttributeType { + #[doc = "< Amount of memory, in bytes, currently associated with graphs"] + pub const hipGraphMemAttrUsedMemCurrent: hipGraphMemAttributeType = hipGraphMemAttributeType(0); +} +impl hipGraphMemAttributeType { + #[doc = "< High watermark of memory, in bytes, associated with graphs since the last time."] + pub const hipGraphMemAttrUsedMemHigh: hipGraphMemAttributeType = hipGraphMemAttributeType(1); +} +impl hipGraphMemAttributeType { + #[doc = "< Amount of memory, in bytes, currently allocated for graphs."] + pub const hipGraphMemAttrReservedMemCurrent: hipGraphMemAttributeType = + hipGraphMemAttributeType(2); +} +impl hipGraphMemAttributeType { + #[doc = "< High watermark of memory, in bytes, currently allocated for graphs"] + pub const hipGraphMemAttrReservedMemHigh: hipGraphMemAttributeType = + hipGraphMemAttributeType(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphMemAttributeType(pub ::std::os::raw::c_int); +impl hipUserObjectFlags { + #[doc = "< Destructor execution is not synchronized."] + pub const hipUserObjectNoDestructorSync: hipUserObjectFlags = hipUserObjectFlags(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipUserObjectFlags(pub ::std::os::raw::c_int); +impl hipUserObjectRetainFlags { + #[doc = "< Add new reference or retain."] + pub const hipGraphUserObjectMove: hipUserObjectRetainFlags = hipUserObjectRetainFlags(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipUserObjectRetainFlags(pub ::std::os::raw::c_int); +impl hipGraphInstantiateFlags { + pub const hipGraphInstantiateFlagAutoFreeOnLaunch: hipGraphInstantiateFlags = + hipGraphInstantiateFlags(1); +} +impl hipGraphInstantiateFlags { + pub const hipGraphInstantiateFlagUpload: hipGraphInstantiateFlags = hipGraphInstantiateFlags(2); +} +impl hipGraphInstantiateFlags { + pub const hipGraphInstantiateFlagDeviceLaunch: hipGraphInstantiateFlags = + hipGraphInstantiateFlags(4); +} +impl hipGraphInstantiateFlags { + pub const hipGraphInstantiateFlagUseNodePriority: hipGraphInstantiateFlags = + hipGraphInstantiateFlags(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphInstantiateFlags(pub ::std::os::raw::c_int); +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsVerbose: hipGraphDebugDotFlags = hipGraphDebugDotFlags(1); +} +impl hipGraphDebugDotFlags { + #[doc = "< Adds hipKernelNodeParams to output"] + pub const hipGraphDebugDotFlagsKernelNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(4); +} +impl hipGraphDebugDotFlags { + #[doc = "< Adds hipMemcpy3DParms to output"] + pub const hipGraphDebugDotFlagsMemcpyNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(8); +} +impl hipGraphDebugDotFlags { + #[doc = "< Adds hipMemsetParams to output"] + pub const hipGraphDebugDotFlagsMemsetNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(16); +} +impl hipGraphDebugDotFlags { + #[doc = "< Adds hipHostNodeParams to output"] + pub const hipGraphDebugDotFlagsHostNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(32); +} +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsEventNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(64); +} +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsExtSemasSignalNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(128); +} +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsExtSemasWaitNodeParams: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(256); +} +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsKernelNodeAttributes: hipGraphDebugDotFlags = + hipGraphDebugDotFlags(512); +} +impl hipGraphDebugDotFlags { + pub const hipGraphDebugDotFlagsHandles: hipGraphDebugDotFlags = hipGraphDebugDotFlags(1024); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipGraphDebugDotFlags(pub ::std::os::raw::c_int); +#[doc = " Memory allocation properties"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemAllocationProp { + #[doc = "< Memory allocation type"] + pub type_: hipMemAllocationType, + #[doc = "< Requested handle type"] + pub requestedHandleType: hipMemAllocationHandleType, + #[doc = "< Memory location"] + pub location: hipMemLocation, + #[doc = "< Metadata for Win32 handles"] + pub win32HandleMetaData: *mut ::std::os::raw::c_void, + pub allocFlags: hipMemAllocationProp__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipMemAllocationProp__bindgen_ty_1 { + #[doc = "< Compression type"] + pub compressionType: ::std::os::raw::c_uchar, + #[doc = "< RDMA capable"] + pub gpuDirectRDMACapable: ::std::os::raw::c_uchar, + #[doc = "< Usage"] + pub usage: ::std::os::raw::c_ushort, +} +#[doc = " External semaphore signal node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreSignalNodeParams { + pub extSemArray: *mut hipExternalSemaphore_t, + pub paramsArray: *const hipExternalSemaphoreSignalParams, + pub numExtSems: ::std::os::raw::c_uint, +} +#[doc = " External semaphore wait node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipExternalSemaphoreWaitNodeParams { + pub extSemArray: *mut hipExternalSemaphore_t, + pub paramsArray: *const hipExternalSemaphoreWaitParams, + pub numExtSems: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipMemGenericAllocationHandle { + _unused: [u8; 0], +} +#[doc = " Generic handle for memory allocation"] +pub type hipMemGenericAllocationHandle_t = *mut ihipMemGenericAllocationHandle; +impl hipMemAllocationGranularity_flags { + #[doc = "< Minimum granularity"] + pub const hipMemAllocationGranularityMinimum: hipMemAllocationGranularity_flags = + hipMemAllocationGranularity_flags(0); +} +impl hipMemAllocationGranularity_flags { + #[doc = "< Recommended granularity for performance"] + pub const hipMemAllocationGranularityRecommended: hipMemAllocationGranularity_flags = + hipMemAllocationGranularity_flags(1); +} +#[repr(transparent)] +#[doc = " Flags for granularity"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemAllocationGranularity_flags(pub ::std::os::raw::c_int); +impl hipMemHandleType { + #[doc = "< Generic handle type"] + pub const hipMemHandleTypeGeneric: hipMemHandleType = hipMemHandleType(0); +} +#[repr(transparent)] +#[doc = " Memory handle type"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemHandleType(pub ::std::os::raw::c_int); +impl hipMemOperationType { + #[doc = "< Map operation"] + pub const hipMemOperationTypeMap: hipMemOperationType = hipMemOperationType(1); +} +impl hipMemOperationType { + #[doc = "< Unmap operation"] + pub const hipMemOperationTypeUnmap: hipMemOperationType = hipMemOperationType(2); +} +#[repr(transparent)] +#[doc = " Memory operation types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipMemOperationType(pub ::std::os::raw::c_int); +impl hipArraySparseSubresourceType { + #[doc = "< Sparse level"] + pub const hipArraySparseSubresourceTypeSparseLevel: hipArraySparseSubresourceType = + hipArraySparseSubresourceType(0); +} +impl hipArraySparseSubresourceType { + #[doc = "< Miptail"] + pub const hipArraySparseSubresourceTypeMiptail: hipArraySparseSubresourceType = + hipArraySparseSubresourceType(1); +} +#[repr(transparent)] +#[doc = " Subresource types for sparse arrays"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipArraySparseSubresourceType(pub ::std::os::raw::c_int); +#[doc = " Map info for arrays"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipArrayMapInfo { + #[doc = "< Resource type"] + pub resourceType: hipResourceType, + pub resource: hipArrayMapInfo__bindgen_ty_1, + #[doc = "< Sparse subresource type"] + pub subresourceType: hipArraySparseSubresourceType, + pub subresource: hipArrayMapInfo__bindgen_ty_2, + #[doc = "< Memory operation type"] + pub memOperationType: hipMemOperationType, + #[doc = "< Memory handle type"] + pub memHandleType: hipMemHandleType, + pub memHandle: hipArrayMapInfo__bindgen_ty_3, + #[doc = "< Offset within the memory"] + pub offset: ::std::os::raw::c_ulonglong, + #[doc = "< Device ordinal bit mask"] + pub deviceBitMask: ::std::os::raw::c_uint, + #[doc = "< flags for future use, must be zero now."] + pub flags: ::std::os::raw::c_uint, + #[doc = "< Reserved for future use, must be zero now."] + pub reserved: [::std::os::raw::c_uint; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipArrayMapInfo__bindgen_ty_1 { + pub mipmap: hipMipmappedArray, + pub array: hipArray_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipArrayMapInfo__bindgen_ty_2 { + pub sparseLevel: hipArrayMapInfo__bindgen_ty_2__bindgen_ty_1, + pub miptail: hipArrayMapInfo__bindgen_ty_2__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipArrayMapInfo__bindgen_ty_2__bindgen_ty_1 { + #[doc = "< For mipmapped arrays must be a valid mipmap level. For arrays must be zero"] + pub level: ::std::os::raw::c_uint, + #[doc = "< For layered arrays must be a valid layer index. Otherwise, must be zero"] + pub layer: ::std::os::raw::c_uint, + #[doc = "< X offset in elements"] + pub offsetX: ::std::os::raw::c_uint, + #[doc = "< Y offset in elements"] + pub offsetY: ::std::os::raw::c_uint, + #[doc = "< Z offset in elements"] + pub offsetZ: ::std::os::raw::c_uint, + #[doc = "< Width in elements"] + pub extentWidth: ::std::os::raw::c_uint, + #[doc = "< Height in elements"] + pub extentHeight: ::std::os::raw::c_uint, + #[doc = "< Depth in elements"] + pub extentDepth: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipArrayMapInfo__bindgen_ty_2__bindgen_ty_2 { + #[doc = "< For layered arrays must be a valid layer index. Otherwise, must be zero"] + pub layer: ::std::os::raw::c_uint, + #[doc = "< Offset within mip tail"] + pub offset: ::std::os::raw::c_ulonglong, + #[doc = "< Extent in bytes"] + pub size: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hipArrayMapInfo__bindgen_ty_3 { + pub memHandle: hipMemGenericAllocationHandle_t, +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n @defgroup API HIP API\n @{\n\n Defines the HIP API. See the individual sections for more information.\n/\n/**\n @defgroup Driver Initialization and Version\n @{\n This section describes the initializtion and version functions of HIP runtime API.\n\n/\n/**\n @brief Explicitly initializes the HIP runtime.\n\n Most HIP APIs implicitly initialize the HIP runtime.\n This API provides control over the timing of the initialization."] + pub fn hipInit(flags: ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the approximate HIP driver version.\n\n @param [out] driverVersion driver version\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning The HIP feature set does not correspond to an exact CUDA SDK driver revision.\n This function always set *driverVersion to 4 as an approximation though HIP supports\n some features which were introduced in later CUDA SDK revisions.\n HIP apps code should not rely on the driver revision number here and should\n use arch feature flags to test device capabilities or conditional compilation.\n\n @see hipRuntimeGetVersion"] + pub fn hipDriverGetVersion(driverVersion: *mut ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the approximate HIP Runtime version.\n\n @param [out] runtimeVersion HIP runtime version\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning The version definition of HIP runtime is different from CUDA.\n On AMD platform, the function returns HIP runtime version,\n while on NVIDIA platform, it returns CUDA runtime version.\n And there is no mapping/correlation between HIP version and CUDA version.\n\n @see hipDriverGetVersion"] + pub fn hipRuntimeGetVersion(runtimeVersion: *mut ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a handle to a compute device\n @param [out] device Handle of device\n @param [in] ordinal Device ordinal\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceGet(device: *mut hipDevice_t, ordinal: ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the compute capability of the device\n @param [out] major Major compute capability version number\n @param [out] minor Minor compute capability version number\n @param [in] device Device ordinal\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceComputeCapability( + major: *mut ::std::os::raw::c_int, + minor: *mut ::std::os::raw::c_int, + device: hipDevice_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns an identifer string for the device.\n @param [out] name String of the device name\n @param [in] len Maximum length of string to store in device name\n @param [in] device Device ordinal\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceGetName( + name: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + device: hipDevice_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns an UUID for the device.[BETA]\n @param [out] uuid UUID for the device\n @param [in] device device ordinal\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue, #hipErrorNotInitialized,\n #hipErrorDeinitialized"] + pub fn hipDeviceGetUuid(uuid: *mut hipUUID, device: hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a value for attribute of link between two devices\n @param [out] value Pointer of the value for the attrubute\n @param [in] attr enum of hipDeviceP2PAttr to query\n @param [in] srcDevice The source device of the link\n @param [in] dstDevice The destination device of the link\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceGetP2PAttribute( + value: *mut ::std::os::raw::c_int, + attr: hipDeviceP2PAttr, + srcDevice: ::std::os::raw::c_int, + dstDevice: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a PCI Bus Id string for the device, overloaded to take int device ID.\n @param [out] pciBusId The string of PCI Bus Id format for the device\n @param [in] len Maximum length of string\n @param [in] device The device ordinal\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceGetPCIBusId( + pciBusId: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + device: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a handle to a compute device.\n @param [out] device The handle of the device\n @param [in] pciBusId The string of PCI Bus Id for the device\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue"] + pub fn hipDeviceGetByPCIBusId( + device: *mut ::std::os::raw::c_int, + pciBusId: *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the total amount of memory on the device.\n @param [out] bytes The size of memory in bytes, on the device\n @param [in] device The ordinal of the device\n\n @returns #hipSuccess, #hipErrorInvalidDevice"] + pub fn hipDeviceTotalMem(bytes: *mut usize, device: hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n @defgroup Device Device Management\n @{\n This section describes the device management functions of HIP runtime API.\n/\n/**\n @brief Waits on all active streams on current device\n\n When this command is invoked, the host thread gets blocked until all the commands associated\n with streams associated with the device. HIP does not support multiple blocking modes (yet!).\n\n @returns #hipSuccess\n\n @see hipSetDevice, hipDeviceReset"] + pub fn hipDeviceSynchronize() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief The state of current device is discarded and updated to a fresh state.\n\n Calling this function deletes all streams created, memory allocated, kernels running, events\n created. Make sure that no other thread is using the device or streams, memory, kernels, events\n associated with the current device.\n\n @returns #hipSuccess\n\n @see hipDeviceSynchronize"] + pub fn hipDeviceReset() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set default device to be used for subsequent hip API calls from this thread.\n\n @param[in] deviceId Valid device in range 0...hipGetDeviceCount().\n\n Sets @p device as the default device for the calling host thread. Valid device id's are 0...\n (hipGetDeviceCount()-1).\n\n Many HIP APIs implicitly use the \"default device\" :\n\n - Any device memory subsequently allocated from this host thread (using hipMalloc) will be\n allocated on device.\n - Any streams or events created from this host thread will be associated with device.\n - Any kernels launched from this host thread (using hipLaunchKernel) will be executed on device\n (unless a specific stream is specified, in which case the device associated with that stream will\n be used).\n\n This function may be called from any host thread. Multiple host threads may use the same device.\n This function does no synchronization with the previous or new device, and has very little\n runtime overhead. Applications can use hipSetDevice to quickly switch the default device before\n making a HIP runtime call which uses the default device.\n\n The default device is stored in thread-local-storage for each thread.\n Thread-pool implementations may inherit the default device of the previous thread. A good\n practice is to always call hipSetDevice at the start of HIP coding sequency to establish a known\n standard device.\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorDeviceAlreadyInUse\n\n @see hipGetDevice, hipGetDeviceCount"] + pub fn hipSetDevice(deviceId: ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return the default device id for the calling host thread.\n\n @param [out] deviceId *device is written with the default device\n\n HIP maintains an default device for each thread using thread-local-storage.\n This device is used implicitly for HIP runtime APIs called by this thread.\n hipGetDevice returns in * @p device the default device for the calling host thread.\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see hipSetDevice, hipGetDevicesizeBytes"] + pub fn hipGetDevice(deviceId: *mut ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return number of compute-capable devices.\n\n @param [out] count Returns number of compute-capable devices.\n\n @returns #hipSuccess, #hipErrorNoDevice\n\n\n Returns in @p *count the number of devices that have ability to run compute commands. If there\n are no such devices, then @ref hipGetDeviceCount will return #hipErrorNoDevice. If 1 or more\n devices can be found, then hipGetDeviceCount returns #hipSuccess."] + pub fn hipGetDeviceCount(count: *mut ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query for a specific device attribute.\n\n @param [out] pi pointer to value to return\n @param [in] attr attribute to query\n @param [in] deviceId which device to query for information\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue"] + pub fn hipDeviceGetAttribute( + pi: *mut ::std::os::raw::c_int, + attr: hipDeviceAttribute_t, + deviceId: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the default memory pool of the specified device\n\n @param [out] mem_pool Default memory pool to return\n @param [in] device Device index for query the default memory pool\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipDeviceGetDefaultMemPool, hipMallocAsync, hipMemPoolTrimTo, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceGetDefaultMemPool( + mem_pool: *mut hipMemPool_t, + device: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the current memory pool of a device\n\n The memory pool must be local to the specified device.\n @p hipMallocAsync allocates from the current mempool of the provided stream's device.\n By default, a device's current memory pool is its default memory pool.\n\n @note Use @p hipMallocFromPoolAsync for asynchronous memory allocations from a device\n different than the one the stream runs on.\n\n @param [in] device Device index for the update\n @param [in] mem_pool Memory pool for update as the current on the specified device\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDevice, #hipErrorNotSupported\n\n @see hipDeviceGetDefaultMemPool, hipMallocAsync, hipMemPoolTrimTo, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceSetMemPool(device: ::std::os::raw::c_int, mem_pool: hipMemPool_t) + -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the current memory pool for the specified device\n\n Returns the last pool provided to @p hipDeviceSetMemPool for this device\n or the device's default memory pool if @p hipDeviceSetMemPool has never been called.\n By default the current mempool is the default mempool for a device,\n otherwise the returned pool must have been set with @p hipDeviceSetMemPool.\n\n @param [out] mem_pool Current memory pool on the specified device\n @param [in] device Device index to query the current memory pool\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipDeviceGetDefaultMemPool, hipMallocAsync, hipMemPoolTrimTo, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceGetMemPool( + mem_pool: *mut hipMemPool_t, + device: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns device properties.\n\n @param [out] prop written with device properties\n @param [in] deviceId which device to query for information\n\n @return #hipSuccess, #hipErrorInvalidDevice\n @bug HCC always returns 0 for maxThreadsPerMultiProcessor\n @bug HCC always returns 0 for regsPerBlock\n @bug HCC always returns 0 for l2CacheSize\n\n Populates hipGetDeviceProperties with information for the specified device."] + pub fn hipGetDeviceProperties( + prop: *mut hipDeviceProp_t, + deviceId: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set L1/Shared cache partition.\n\n @param [in] cacheConfig Cache configuration\n\n @returns #hipSuccess, #hipErrorNotInitialized, #hipErrorNotSupported\n\n Note: AMD devices do not support reconfigurable cache. This API is not implemented\n on AMD platform. If the function is called, it will return hipErrorNotSupported.\n"] + pub fn hipDeviceSetCacheConfig(cacheConfig: hipFuncCache_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get Cache configuration for a specific Device\n\n @param [out] cacheConfig Pointer of cache configuration\n\n @returns #hipSuccess, #hipErrorNotInitialized\n Note: AMD devices do not support reconfigurable cache. This hint is ignored\n on these architectures.\n"] + pub fn hipDeviceGetCacheConfig(cacheConfig: *mut hipFuncCache_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets resource limits of current device\n The funtion querys the size of limit value, as required input enum hipLimit_t, can be either\n hipLimitStackSize, or hipLimitMallocHeapSize.\n\n @param [out] pValue returns the size of the limit in bytes\n @param [in] limit the limit to query\n\n @returns #hipSuccess, #hipErrorUnsupportedLimit, #hipErrorInvalidValue\n"] + pub fn hipDeviceGetLimit(pValue: *mut usize, limit: hipLimit_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets resource limits of current device\n As the input enum limit, hipLimitStackSize sets the limit value of the stack size on current\n GPU devie, hipLimitMallocHeapSize sets the limit value of the heap used by the malloc()/free()\n calls.\n\n @param [in] limit enum of hipLimit_t to set\n @param [in] value the size of limit value in bytes\n\n @returns #hipSuccess, #hipErrorUnsupportedLimit, #hipErrorInvalidValue\n"] + pub fn hipDeviceSetLimit(limit: hipLimit_t, value: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns bank width of shared memory for current device\n\n @param [out] pConfig The pointer of the bank width for shared memory\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized\n\n Note: AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n"] + pub fn hipDeviceGetSharedMemConfig(pConfig: *mut hipSharedMemConfig) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the flags set for current device\n\n @param [out] flags Pointer of the flags\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue"] + pub fn hipGetDeviceFlags(flags: *mut ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief The bank width of shared memory on current device is set\n\n @param [in] config Configuration for the bank width of shared memory\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized\n\n Note: AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n"] + pub fn hipDeviceSetSharedMemConfig(config: hipSharedMemConfig) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief The current device behavior is changed according the flags passed.\n\n @param [in] flags Flag to set on the current device\n\n The schedule flags impact how HIP waits for the completion of a command running on a device.\n hipDeviceScheduleSpin : HIP runtime will actively spin in the thread which submitted the\n work until the command completes. This offers the lowest latency, but will consume a CPU core\n and may increase power. hipDeviceScheduleYield : The HIP runtime will yield the CPU to\n system so that other tasks can use it. This may increase latency to detect the completion but\n will consume less power and is friendlier to other tasks in the system.\n hipDeviceScheduleBlockingSync : On ROCm platform, this is a synonym for hipDeviceScheduleYield.\n hipDeviceScheduleAuto : Use a hueristic to select between Spin and Yield modes. If the\n number of HIP contexts is greater than the number of logical processors in the system, use Spin\n scheduling. Else use Yield scheduling.\n\n\n hipDeviceMapHost : Allow mapping host memory. On ROCM, this is always allowed and\n the flag is ignored. hipDeviceLmemResizeToMax : @warning ROCm silently ignores this flag.\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorSetOnActiveProcess\n\n"] + pub fn hipSetDeviceFlags(flags: ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Device which matches hipDeviceProp_t is returned\n\n @param [out] device Pointer of the device\n @param [in] prop Pointer of the properties\n\n @returns #hipSuccess, #hipErrorInvalidValue"] + pub fn hipChooseDevice( + device: *mut ::std::os::raw::c_int, + prop: *const hipDeviceProp_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the link type and hop count between two devices\n\n @param [in] device1 Ordinal for device1\n @param [in] device2 Ordinal for device2\n @param [out] linktype Returns the link type (See hsa_amd_link_info_type_t) between the two devices\n @param [out] hopcount Returns the hop count between the two devices\n\n Queries and returns the HSA link type and the hop count between the two specified devices.\n\n @returns #hipSuccess, #hipInvalidDevice, #hipErrorRuntimeOther"] + pub fn hipExtGetLinkTypeAndHopCount( + device1: ::std::os::raw::c_int, + device2: ::std::os::raw::c_int, + linktype: *mut u32, + hopcount: *mut u32, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets an interprocess memory handle for an existing device memory\n allocation\n\n Takes a pointer to the base of an existing device memory allocation created\n with hipMalloc and exports it for use in another process. This is a\n lightweight operation and may be called multiple times on an allocation\n without adverse effects.\n\n If a region of memory is freed with hipFree and a subsequent call\n to hipMalloc returns memory with the same device address,\n hipIpcGetMemHandle will return a unique handle for the\n new memory.\n\n @param handle - Pointer to user allocated hipIpcMemHandle to return\n the handle in.\n @param devPtr - Base pointer to previously allocated device memory\n\n @returns\n #hipSuccess\n #hipErrorInvalidHandle\n #hipErrorOutOfMemory\n #hipErrorMapFailed\n\n @note This IPC memory related feature API on Windows may behave differently from Linux.\n"] + pub fn hipIpcGetMemHandle( + handle: *mut hipIpcMemHandle_t, + devPtr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Opens an interprocess memory handle exported from another process\n and returns a device pointer usable in the local process.\n\n Maps memory exported from another process with hipIpcGetMemHandle into\n the current device address space. For contexts on different devices\n hipIpcOpenMemHandle can attempt to enable peer access between the\n devices as if the user called hipDeviceEnablePeerAccess. This behavior is\n controlled by the hipIpcMemLazyEnablePeerAccess flag.\n hipDeviceCanAccessPeer can determine if a mapping is possible.\n\n Contexts that may open hipIpcMemHandles are restricted in the following way.\n hipIpcMemHandles from each device in a given process may only be opened\n by one context per device per other process.\n\n Memory returned from hipIpcOpenMemHandle must be freed with\n hipIpcCloseMemHandle.\n\n Calling hipFree on an exported memory region before calling\n hipIpcCloseMemHandle in the importing context will result in undefined\n behavior.\n\n @param devPtr - Returned device pointer\n @param handle - hipIpcMemHandle to open\n @param flags - Flags for this operation. Must be specified as hipIpcMemLazyEnablePeerAccess\n\n @returns\n #hipSuccess,\n #hipErrorMapFailed,\n #hipErrorInvalidHandle,\n #hipErrorTooManyPeers\n\n @note During multiple processes, using the same memory handle opened by the current context,\n there is no guarantee that the same device poiter will be returned in @p *devPtr.\n This is diffrent from CUDA.\n @note This IPC memory related feature API on Windows may behave differently from Linux.\n"] + pub fn hipIpcOpenMemHandle( + devPtr: *mut *mut ::std::os::raw::c_void, + handle: hipIpcMemHandle_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Close memory mapped with hipIpcOpenMemHandle\n\n Unmaps memory returnd by hipIpcOpenMemHandle. The original allocation\n in the exporting process as well as imported mappings in other processes\n will be unaffected.\n\n Any resources used to enable peer access will be freed if this is the\n last mapping using them.\n\n @param devPtr - Device pointer returned by hipIpcOpenMemHandle\n\n @returns\n #hipSuccess,\n #hipErrorMapFailed,\n #hipErrorInvalidHandle\n\n @note This IPC memory related feature API on Windows may behave differently from Linux.\n"] + pub fn hipIpcCloseMemHandle(devPtr: *mut ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets an opaque interprocess handle for an event.\n\n This opaque handle may be copied into other processes and opened with hipIpcOpenEventHandle.\n Then hipEventRecord, hipEventSynchronize, hipStreamWaitEvent and hipEventQuery may be used in\n either process. Operations on the imported event after the exported event has been freed with hipEventDestroy\n will result in undefined behavior.\n\n @param[out] handle Pointer to hipIpcEventHandle to return the opaque event handle\n @param[in] event Event allocated with hipEventInterprocess and hipEventDisableTiming flags\n\n @returns #hipSuccess, #hipErrorInvalidConfiguration, #hipErrorInvalidValue\n\n @note This IPC event related feature API is currently applicable on Linux.\n"] + pub fn hipIpcGetEventHandle(handle: *mut hipIpcEventHandle_t, event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Opens an interprocess event handles.\n\n Opens an interprocess event handle exported from another process with cudaIpcGetEventHandle. The returned\n hipEvent_t behaves like a locally created event with the hipEventDisableTiming flag specified. This event\n need be freed with hipEventDestroy. Operations on the imported event after the exported event has been freed\n with hipEventDestroy will result in undefined behavior. If the function is called within the same process where\n handle is returned by hipIpcGetEventHandle, it will return hipErrorInvalidContext.\n\n @param[out] event Pointer to hipEvent_t to return the event\n @param[in] handle The opaque interprocess handle to open\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidContext\n\n @note This IPC event related feature API is currently applicable on Linux.\n"] + pub fn hipIpcOpenEventHandle(event: *mut hipEvent_t, handle: hipIpcEventHandle_t) + -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n\n @defgroup Execution Execution Control\n @{\n This section describes the execution control functions of HIP runtime API.\n\n/\n/**\n @brief Set attribute for a specific function\n\n @param [in] func Pointer of the function\n @param [in] attr Attribute to set\n @param [in] value Value to set\n\n @returns #hipSuccess, #hipErrorInvalidDeviceFunction, #hipErrorInvalidValue\n\n Note: AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n"] + pub fn hipFuncSetAttribute( + func: *const ::std::os::raw::c_void, + attr: hipFuncAttribute, + value: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set Cache configuration for a specific function\n\n @param [in] func Pointer of the function.\n @param [in] config Configuration to set.\n\n @returns #hipSuccess, #hipErrorNotInitialized\n Note: AMD devices and some Nvidia GPUS do not support reconfigurable cache. This hint is ignored\n on those architectures.\n"] + pub fn hipFuncSetCacheConfig( + func: *const ::std::os::raw::c_void, + config: hipFuncCache_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shared memory configuation for a specific function\n\n @param [in] func Pointer of the function\n @param [in] config Configuration\n\n @returns #hipSuccess, #hipErrorInvalidDeviceFunction, #hipErrorInvalidValue\n\n Note: AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n"] + pub fn hipFuncSetSharedMemConfig( + func: *const ::std::os::raw::c_void, + config: hipSharedMemConfig, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup Error Error Handling\n @{\n This section describes the error handling functions of HIP runtime API.\n/\n/**\n @brief Return last error returned by any HIP runtime API call and resets the stored error code to\n #hipSuccess\n\n @returns return code from last HIP called from the active host thread\n\n Returns the last error that has been returned by any of the runtime calls in the same host\n thread, and then resets the saved error to #hipSuccess.\n\n @see hipGetErrorString, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipGetLastError() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return last error returned by any HIP runtime API call.\n\n @return #hipSuccess\n\n Returns the last error that has been returned by any of the runtime calls in the same host\n thread. Unlike hipGetLastError, this function does not reset the saved error code.\n\n @see hipGetErrorString, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipPeekAtLastError() -> hipError_t; +} +extern "C" { + #[doc = " @brief Return hip error as text string form.\n\n @param hip_error Error code to convert to name.\n @return const char pointer to the NULL-terminated error name\n\n @see hipGetErrorString, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipGetErrorName(hip_error: hipError_t) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Return handy text string message to explain the error which occurred\n\n @param hipError Error code to convert to string.\n @return const char pointer to the NULL-terminated error string\n\n @see hipGetErrorName, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipGetErrorString(hipError: hipError_t) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[must_use] + #[doc = " @brief Return hip error as text string form.\n\n @param [in] hipError Error code to convert to string.\n @param [out] errorString char pointer to the NULL-terminated error string\n @return #hipSuccess, #hipErrorInvalidValue\n\n @see hipGetErrorName, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipDrvGetErrorName( + hipError: hipError_t, + errorString: *mut *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return handy text string message to explain the error which occurred\n\n @param [in] hipError Error code to convert to string.\n @param [out] errorString char pointer to the NULL-terminated error string\n @return #hipSuccess, #hipErrorInvalidValue\n\n @see hipGetErrorName, hipGetLastError, hipPeakAtLastError, hipError_t"] + pub fn hipDrvGetErrorString( + hipError: hipError_t, + errorString: *mut *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an asynchronous stream.\n\n @param[in, out] stream Valid pointer to hipStream_t. This function writes the memory with the\n newly created stream.\n @return #hipSuccess, #hipErrorInvalidValue\n\n Create a new asynchronous stream. @p stream returns an opaque handle that can be used to\n reference the newly created stream in subsequent hipStream* commands. The stream is allocated on\n the heap and will remain allocated even if the handle goes out-of-scope. To release the memory\n used by the stream, applicaiton must call hipStreamDestroy.\n\n @return #hipSuccess, #hipErrorInvalidValue\n\n @see hipStreamCreateWithFlags, hipStreamCreateWithPriority, hipStreamSynchronize, hipStreamWaitEvent, hipStreamDestroy"] + pub fn hipStreamCreate(stream: *mut hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an asynchronous stream.\n\n @param[in, out] stream Pointer to new stream\n @param[in ] flags to control stream creation.\n @return #hipSuccess, #hipErrorInvalidValue\n\n Create a new asynchronous stream. @p stream returns an opaque handle that can be used to\n reference the newly created stream in subsequent hipStream* commands. The stream is allocated on\n the heap and will remain allocated even if the handle goes out-of-scope. To release the memory\n used by the stream, applicaiton must call hipStreamDestroy. Flags controls behavior of the\n stream. See #hipStreamDefault, #hipStreamNonBlocking.\n\n\n @see hipStreamCreate, hipStreamCreateWithPriority, hipStreamSynchronize, hipStreamWaitEvent, hipStreamDestroy"] + pub fn hipStreamCreateWithFlags( + stream: *mut hipStream_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an asynchronous stream with the specified priority.\n\n @param[in, out] stream Pointer to new stream\n @param[in ] flags to control stream creation.\n @param[in ] priority of the stream. Lower numbers represent higher priorities.\n @return #hipSuccess, #hipErrorInvalidValue\n\n Create a new asynchronous stream with the specified priority. @p stream returns an opaque handle\n that can be used to reference the newly created stream in subsequent hipStream* commands. The\n stream is allocated on the heap and will remain allocated even if the handle goes out-of-scope.\n To release the memory used by the stream, applicaiton must call hipStreamDestroy. Flags controls\n behavior of the stream. See #hipStreamDefault, #hipStreamNonBlocking.\n\n\n @see hipStreamCreate, hipStreamSynchronize, hipStreamWaitEvent, hipStreamDestroy"] + pub fn hipStreamCreateWithPriority( + stream: *mut hipStream_t, + flags: ::std::os::raw::c_uint, + priority: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns numerical values that correspond to the least and greatest stream priority.\n\n @param[in, out] leastPriority pointer in which value corresponding to least priority is returned.\n @param[in, out] greatestPriority pointer in which value corresponding to greatest priority is returned.\n\n Returns in *leastPriority and *greatestPriority the numerical values that correspond to the least\n and greatest stream priority respectively. Stream priorities follow a convention where lower numbers\n imply greater priorities. The range of meaningful stream priorities is given by\n [*greatestPriority, *leastPriority]. If the user attempts to create a stream with a priority value\n that is outside the the meaningful range as specified by this API, the priority is automatically\n clamped to within the valid range."] + pub fn hipDeviceGetStreamPriorityRange( + leastPriority: *mut ::std::os::raw::c_int, + greatestPriority: *mut ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the specified stream.\n\n @param[in] stream stream identifier.\n @return #hipSuccess #hipErrorInvalidHandle\n\n Destroys the specified stream.\n\n If commands are still executing on the specified stream, some may complete execution before the\n queue is deleted.\n\n The queue may be destroyed while some commands are still inflight, or may wait for all commands\n queued to the stream before destroying it.\n\n @see hipStreamCreate, hipStreamCreateWithFlags, hipStreamCreateWithPriority, hipStreamQuery, hipStreamWaitEvent,\n hipStreamSynchronize"] + pub fn hipStreamDestroy(stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return #hipSuccess if all of the operations in the specified @p stream have completed, or\n #hipErrorNotReady if not.\n\n @param[in] stream stream to query\n\n @return #hipSuccess, #hipErrorNotReady, #hipErrorInvalidHandle\n\n This is thread-safe and returns a snapshot of the current state of the queue. However, if other\n host threads are sending work to the stream, the status may change immediately after the function\n is called. It is typically used for debug.\n\n @see hipStreamCreate, hipStreamCreateWithFlags, hipStreamCreateWithPriority, hipStreamWaitEvent, hipStreamSynchronize,\n hipStreamDestroy"] + pub fn hipStreamQuery(stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Wait for all commands in stream to complete.\n\n @param[in] stream stream identifier.\n\n @return #hipSuccess, #hipErrorInvalidHandle\n\n This command is host-synchronous : the host will block until the specified stream is empty.\n\n This command follows standard null-stream semantics. Specifically, specifying the null stream\n will cause the command to wait for other streams on the same device to complete all pending\n operations.\n\n This command honors the hipDeviceLaunchBlocking flag, which controls whether the wait is active\n or blocking.\n\n @see hipStreamCreate, hipStreamCreateWithFlags, hipStreamCreateWithPriority, hipStreamWaitEvent, hipStreamDestroy\n"] + pub fn hipStreamSynchronize(stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Make the specified compute stream wait for an event\n\n @param[in] stream stream to make wait.\n @param[in] event event to wait on\n @param[in] flags control operation [must be 0]\n\n @return #hipSuccess, #hipErrorInvalidHandle\n\n This function inserts a wait operation into the specified stream.\n All future work submitted to @p stream will wait until @p event reports completion before\n beginning execution.\n\n This function only waits for commands in the current stream to complete. Notably,, this function\n does not impliciy wait for commands in the default stream to complete, even if the specified\n stream is created with hipStreamNonBlocking = 0.\n\n @see hipStreamCreate, hipStreamCreateWithFlags, hipStreamCreateWithPriority, hipStreamSynchronize, hipStreamDestroy"] + pub fn hipStreamWaitEvent( + stream: hipStream_t, + event: hipEvent_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return flags associated with this stream.\n\n @param[in] stream stream to be queried\n @param[in,out] flags Pointer to an unsigned integer in which the stream's flags are returned\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidHandle\n\n @returns #hipSuccess #hipErrorInvalidValue #hipErrorInvalidHandle\n\n Return flags associated with this stream in *@p flags.\n\n @see hipStreamCreateWithFlags"] + pub fn hipStreamGetFlags(stream: hipStream_t, flags: *mut ::std::os::raw::c_uint) + -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the priority of a stream.\n\n @param[in] stream stream to be queried\n @param[in,out] priority Pointer to an unsigned integer in which the stream's priority is returned\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidHandle\n\n @returns #hipSuccess #hipErrorInvalidValue #hipErrorInvalidHandle\n\n Query the priority of a stream. The priority is returned in in priority.\n\n @see hipStreamCreateWithFlags"] + pub fn hipStreamGetPriority( + stream: hipStream_t, + priority: *mut ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the device assocaited with the stream\n\n @param[in] stream stream to be queried\n @param[out] device device associated with the stream\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorContextIsDestroyed, #hipErrorInvalidHandle,\n #hipErrorNotInitialized, #hipErrorDeinitialized, #hipErrorInvalidContext\n\n @see hipStreamCreate, hipStreamDestroy, hipDeviceGetStreamPriorityRange"] + pub fn hipStreamGetDevice(stream: hipStream_t, device: *mut hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an asynchronous stream with the specified CU mask.\n\n @param[in, out] stream Pointer to new stream\n @param[in ] cuMaskSize Size of CU mask bit array passed in.\n @param[in ] cuMask Bit-vector representing the CU mask. Each active bit represents using one CU.\n The first 32 bits represent the first 32 CUs, and so on. If its size is greater than physical\n CU number (i.e., multiProcessorCount member of hipDeviceProp_t), the extra elements are ignored.\n It is user's responsibility to make sure the input is meaningful.\n @return #hipSuccess, #hipErrorInvalidHandle, #hipErrorInvalidValue\n\n Create a new asynchronous stream with the specified CU mask. @p stream returns an opaque handle\n that can be used to reference the newly created stream in subsequent hipStream* commands. The\n stream is allocated on the heap and will remain allocated even if the handle goes out-of-scope.\n To release the memory used by the stream, application must call hipStreamDestroy.\n\n\n @see hipStreamCreate, hipStreamSynchronize, hipStreamWaitEvent, hipStreamDestroy"] + pub fn hipExtStreamCreateWithCUMask( + stream: *mut hipStream_t, + cuMaskSize: u32, + cuMask: *const u32, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get CU mask associated with an asynchronous stream\n\n @param[in] stream stream to be queried\n @param[in] cuMaskSize number of the block of memories (uint32_t *) allocated by user\n @param[out] cuMask Pointer to a pre-allocated block of memories (uint32_t *) in which\n the stream's CU mask is returned. The CU mask is returned in a chunck of 32 bits where\n each active bit represents one active CU\n @return #hipSuccess, #hipErrorInvalidHandle, #hipErrorInvalidValue\n\n @see hipStreamCreate, hipStreamSynchronize, hipStreamWaitEvent, hipStreamDestroy"] + pub fn hipExtStreamGetCUMask( + stream: hipStream_t, + cuMaskSize: u32, + cuMask: *mut u32, + ) -> hipError_t; +} +#[doc = " Stream CallBack struct"] +pub type hipStreamCallback_t = ::std::option::Option< + unsafe extern "C" fn( + stream: hipStream_t, + status: hipError_t, + userData: *mut ::std::os::raw::c_void, + ), +>; +extern "C" { + #[must_use] + #[doc = " @brief Adds a callback to be called on the host after all currently enqueued\n items in the stream have completed. For each\n hipStreamAddCallback call, a callback will be executed exactly once.\n The callback will block later work in the stream until it is finished.\n @param[in] stream - Stream to add callback to\n @param[in] callback - The function to call once preceding stream operations are complete\n @param[in] userData - User specified data to be passed to the callback function\n @param[in] flags - Reserved for future use, must be 0\n @return #hipSuccess, #hipErrorInvalidHandle, #hipErrorNotSupported\n\n @see hipStreamCreate, hipStreamCreateWithFlags, hipStreamQuery, hipStreamSynchronize,\n hipStreamWaitEvent, hipStreamDestroy, hipStreamCreateWithPriority\n"] + pub fn hipStreamAddCallback( + stream: hipStream_t, + callback: hipStreamCallback_t, + userData: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup StreamM Stream Memory Operations\n @{\n This section describes Stream Memory Wait and Write functions of HIP runtime API.\n/\n/**\n @brief Enqueues a wait command to the stream.[BETA]\n\n @param [in] stream - Stream identifier\n @param [in] ptr - Pointer to memory object allocated using 'hipMallocSignalMemory' flag\n @param [in] value - Value to be used in compare operation\n @param [in] flags - Defines the compare operation, supported values are hipStreamWaitValueGte\n hipStreamWaitValueEq, hipStreamWaitValueAnd and hipStreamWaitValueNor\n @param [in] mask - Mask to be applied on value at memory before it is compared with value,\n default value is set to enable every bit\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n Enqueues a wait command to the stream, all operations enqueued on this stream after this, will\n not execute until the defined wait condition is true.\n\n hipStreamWaitValueGte: waits until *ptr&mask >= value\n hipStreamWaitValueEq : waits until *ptr&mask == value\n hipStreamWaitValueAnd: waits until ((*ptr&mask) & value) != 0\n hipStreamWaitValueNor: waits until ~((*ptr&mask) | (value&mask)) != 0\n\n @note when using 'hipStreamWaitValueNor', mask is applied on both 'value' and '*ptr'.\n\n @note Support for hipStreamWaitValue32 can be queried using 'hipDeviceGetAttribute()' and\n 'hipDeviceAttributeCanUseStreamWaitValue' flag.\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipExtMallocWithFlags, hipFree, hipStreamWaitValue64, hipStreamWriteValue64,\n hipStreamWriteValue32, hipDeviceGetAttribute"] + pub fn hipStreamWaitValue32( + stream: hipStream_t, + ptr: *mut ::std::os::raw::c_void, + value: u32, + flags: ::std::os::raw::c_uint, + mask: u32, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enqueues a wait command to the stream.[BETA]\n\n @param [in] stream - Stream identifier\n @param [in] ptr - Pointer to memory object allocated using 'hipMallocSignalMemory' flag\n @param [in] value - Value to be used in compare operation\n @param [in] flags - Defines the compare operation, supported values are hipStreamWaitValueGte\n hipStreamWaitValueEq, hipStreamWaitValueAnd and hipStreamWaitValueNor.\n @param [in] mask - Mask to be applied on value at memory before it is compared with value\n default value is set to enable every bit\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n Enqueues a wait command to the stream, all operations enqueued on this stream after this, will\n not execute until the defined wait condition is true.\n\n hipStreamWaitValueGte: waits until *ptr&mask >= value\n hipStreamWaitValueEq : waits until *ptr&mask == value\n hipStreamWaitValueAnd: waits until ((*ptr&mask) & value) != 0\n hipStreamWaitValueNor: waits until ~((*ptr&mask) | (value&mask)) != 0\n\n @note when using 'hipStreamWaitValueNor', mask is applied on both 'value' and '*ptr'.\n\n @note Support for hipStreamWaitValue64 can be queried using 'hipDeviceGetAttribute()' and\n 'hipDeviceAttributeCanUseStreamWaitValue' flag.\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipExtMallocWithFlags, hipFree, hipStreamWaitValue32, hipStreamWriteValue64,\n hipStreamWriteValue32, hipDeviceGetAttribute"] + pub fn hipStreamWaitValue64( + stream: hipStream_t, + ptr: *mut ::std::os::raw::c_void, + value: u64, + flags: ::std::os::raw::c_uint, + mask: u64, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enqueues a write command to the stream.[BETA]\n\n @param [in] stream - Stream identifier\n @param [in] ptr - Pointer to a GPU accessible memory object\n @param [in] value - Value to be written\n @param [in] flags - reserved, ignored for now, will be used in future releases\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n Enqueues a write command to the stream, write operation is performed after all earlier commands\n on this stream have completed the execution.\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipExtMallocWithFlags, hipFree, hipStreamWriteValue32, hipStreamWaitValue32,\n hipStreamWaitValue64"] + pub fn hipStreamWriteValue32( + stream: hipStream_t, + ptr: *mut ::std::os::raw::c_void, + value: u32, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enqueues a write command to the stream.[BETA]\n\n @param [in] stream - Stream identifier\n @param [in] ptr - Pointer to a GPU accessible memory object\n @param [in] value - Value to be written\n @param [in] flags - reserved, ignored for now, will be used in future releases\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n Enqueues a write command to the stream, write operation is performed after all earlier commands\n on this stream have completed the execution.\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipExtMallocWithFlags, hipFree, hipStreamWriteValue32, hipStreamWaitValue32,\n hipStreamWaitValue64"] + pub fn hipStreamWriteValue64( + stream: hipStream_t, + ptr: *mut ::std::os::raw::c_void, + value: u64, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup Event Event Management\n @{\n This section describes the event management functions of HIP runtime API.\n/\n/**\n @brief Create an event with the specified flags\n\n @param[in,out] event Returns the newly created event.\n @param[in] flags Flags to control event behavior. Valid values are #hipEventDefault,\n#hipEventBlockingSync, #hipEventDisableTiming, #hipEventInterprocess\n #hipEventDefault : Default flag. The event will use active synchronization and will support\ntiming. Blocking synchronization provides lowest possible latency at the expense of dedicating a\nCPU to poll on the event.\n #hipEventBlockingSync : The event will use blocking synchronization : if hipEventSynchronize is\ncalled on this event, the thread will block until the event completes. This can increase latency\nfor the synchroniation but can result in lower power and more resources for other CPU threads.\n #hipEventDisableTiming : Disable recording of timing information. Events created with this flag\nwould not record profiling data and provide best performance if used for synchronization.\n #hipEventInterprocess : The event can be used as an interprocess event. hipEventDisableTiming\nflag also must be set when hipEventInterprocess flag is set.\n #hipEventDisableSystemFence : Disable acquire and release system scope fence. This may\nimprove performance but device memory may not be visible to the host and other devices\nif this flag is set.\n\n @returns #hipSuccess, #hipErrorNotInitialized, #hipErrorInvalidValue,\n#hipErrorLaunchFailure, #hipErrorOutOfMemory\n\n @see hipEventCreate, hipEventSynchronize, hipEventDestroy, hipEventElapsedTime"] + pub fn hipEventCreateWithFlags( + event: *mut hipEvent_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " Create an event\n\n @param[in,out] event Returns the newly created event.\n\n @returns #hipSuccess, #hipErrorNotInitialized, #hipErrorInvalidValue,\n #hipErrorLaunchFailure, #hipErrorOutOfMemory\n\n @see hipEventCreateWithFlags, hipEventRecord, hipEventQuery, hipEventSynchronize,\n hipEventDestroy, hipEventElapsedTime"] + pub fn hipEventCreate(event: *mut hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipEventRecord(event: hipEvent_t, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy the specified event.\n\n @param[in] event Event to destroy.\n @returns #hipSuccess, #hipErrorNotInitialized, #hipErrorInvalidValue,\n #hipErrorLaunchFailure\n\n Releases memory associated with the event. If the event is recording but has not completed\n recording when hipEventDestroy() is called, the function will return immediately and the\n completion_future resources will be released later, when the hipDevice is synchronized.\n\n @see hipEventCreate, hipEventCreateWithFlags, hipEventQuery, hipEventSynchronize, hipEventRecord,\n hipEventElapsedTime\n\n @returns #hipSuccess"] + pub fn hipEventDestroy(event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Wait for an event to complete.\n\n This function will block until the event is ready, waiting for all previous work in the stream\n specified when event was recorded with hipEventRecord().\n\n If hipEventRecord() has not been called on @p event, this function returns immediately.\n\n TODO-hip- This function needs to support hipEventBlockingSync parameter.\n\n @param[in] event Event on which to wait.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized,\n #hipErrorInvalidHandle, #hipErrorLaunchFailure\n\n @see hipEventCreate, hipEventCreateWithFlags, hipEventQuery, hipEventDestroy, hipEventRecord,\n hipEventElapsedTime"] + pub fn hipEventSynchronize(event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return the elapsed time between two events.\n\n @param[out] ms : Return time between start and stop in ms.\n @param[in] start : Start event.\n @param[in] stop : Stop event.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotReady, #hipErrorInvalidHandle,\n #hipErrorNotInitialized, #hipErrorLaunchFailure\n\n Computes the elapsed time between two events. Time is computed in ms, with\n a resolution of approximately 1 us.\n\n Events which are recorded in a NULL stream will block until all commands\n on all other streams complete execution, and then record the timestamp.\n\n Events which are recorded in a non-NULL stream will record their timestamp\n when they reach the head of the specified stream, after all previous\n commands in that stream have completed executing. Thus the time that\n the event recorded may be significantly after the host calls hipEventRecord().\n\n If hipEventRecord() has not been called on either event, then #hipErrorInvalidHandle is\n returned. If hipEventRecord() has been called on both events, but the timestamp has not yet been\n recorded on one or both events (that is, hipEventQuery() would return #hipErrorNotReady on at\n least one of the events), then #hipErrorNotReady is returned.\n\n @see hipEventCreate, hipEventCreateWithFlags, hipEventQuery, hipEventDestroy, hipEventRecord,\n hipEventSynchronize"] + pub fn hipEventElapsedTime(ms: *mut f32, start: hipEvent_t, stop: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query event status\n\n @param[in] event Event to query.\n @returns #hipSuccess, #hipErrorNotReady, #hipErrorInvalidHandle, #hipErrorInvalidValue,\n #hipErrorNotInitialized, #hipErrorLaunchFailure\n\n Query the status of the specified event. This function will return #hipSuccess if all\n commands in the appropriate stream (specified to hipEventRecord()) have completed. If that work\n has not completed, or if hipEventRecord() was not called on the event, then #hipErrorNotReady is\n returned.\n\n @see hipEventCreate, hipEventCreateWithFlags, hipEventRecord, hipEventDestroy,\n hipEventSynchronize, hipEventElapsedTime"] + pub fn hipEventQuery(event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets information on the specified pointer.[BETA]\n\n @param [in] value sets pointer attribute value\n @param [in] atribute attribute to set\n @param [in] ptr pointer to set attributes for\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipPointerSetAttribute( + value: *const ::std::os::raw::c_void, + attribute: hipPointer_attribute, + ptr: hipDeviceptr_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return attributes for the specified pointer\n\n @param [out] attributes attributes for the specified pointer\n @param [in] ptr pointer to get attributes for\n\n @note To get pointer's memory type, the parameter attributes has 'type' as member variable.\n The 'type' indicates input pointer is allocated on device or host. That means the input\n pointer must be returned or passed through an HIP API such as hipHostMalloc, hipMallocManaged,\n hipHostRegister, etc. Otherwise, the pointer couldn't be handled by this API and attributes\n returned hipErrorInvalidValue, due to the hipMemoryType enums values, unrecognized memory type\n is currently not supported due to HIP functionality backward compatibility.\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see hipPointerGetAttribute\n"] + pub fn hipPointerGetAttributes( + attributes: *mut hipPointerAttribute_t, + ptr: *const ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns information about the specified pointer.[BETA]\n\n @param [in, out] data returned pointer attribute value\n @param [in] atribute attribute to query for\n @param [in] ptr pointer to get attributes for\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipPointerGetAttributes"] + pub fn hipPointerGetAttribute( + data: *mut ::std::os::raw::c_void, + attribute: hipPointer_attribute, + ptr: hipDeviceptr_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns information about the specified pointer.[BETA]\n\n @param [in] numAttributes number of attributes to query for\n @param [in] attributes attributes to query for\n @param [in, out] data a two-dimensional containing pointers to memory locations\n where the result of each attribute query will be written to\n @param [in] ptr pointer to get attributes for\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @beta This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @see hipPointerGetAttribute"] + pub fn hipDrvPointerGetAttributes( + numAttributes: ::std::os::raw::c_uint, + attributes: *mut hipPointer_attribute, + data: *mut *mut ::std::os::raw::c_void, + ptr: hipDeviceptr_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = "-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup External External Resource Interoperability\n @{\n @ingroup API\n\n This section describes the external resource interoperability functions of HIP runtime API.\n\n/\n/**\n @brief Imports an external semaphore.\n\n @param[out] extSem_out External semaphores to be waited on\n @param[in] semHandleDesc Semaphore import handle descriptor\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipImportExternalSemaphore( + extSem_out: *mut hipExternalSemaphore_t, + semHandleDesc: *const hipExternalSemaphoreHandleDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Signals a set of external semaphore objects.\n\n @param[in] extSem_out External semaphores to be waited on\n @param[in] paramsArray Array of semaphore parameters\n @param[in] numExtSems Number of semaphores to wait on\n @param[in] stream Stream to enqueue the wait operations in\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipSignalExternalSemaphoresAsync( + extSemArray: *const hipExternalSemaphore_t, + paramsArray: *const hipExternalSemaphoreSignalParams, + numExtSems: ::std::os::raw::c_uint, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Waits on a set of external semaphore objects\n\n @param[in] extSem_out External semaphores to be waited on\n @param[in] paramsArray Array of semaphore parameters\n @param[in] numExtSems Number of semaphores to wait on\n @param[in] stream Stream to enqueue the wait operations in\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipWaitExternalSemaphoresAsync( + extSemArray: *const hipExternalSemaphore_t, + paramsArray: *const hipExternalSemaphoreWaitParams, + numExtSems: ::std::os::raw::c_uint, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys an external semaphore object and releases any references to the underlying resource. Any outstanding signals or waits must have completed before the semaphore is destroyed.\n\n @param[in] extSem handle to an external memory object\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipDestroyExternalSemaphore(extSem: hipExternalSemaphore_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Imports an external memory object.\n\n @param[out] extMem_out Returned handle to an external memory object\n @param[in] memHandleDesc Memory import handle descriptor\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipImportExternalMemory( + extMem_out: *mut hipExternalMemory_t, + memHandleDesc: *const hipExternalMemoryHandleDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Maps a buffer onto an imported memory object.\n\n @param[out] devPtr Returned device pointer to buffer\n @param[in] extMem Handle to external memory object\n @param[in] bufferDesc Buffer descriptor\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipExternalMemoryGetMappedBuffer( + devPtr: *mut *mut ::std::os::raw::c_void, + extMem: hipExternalMemory_t, + bufferDesc: *const hipExternalMemoryBufferDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys an external memory object.\n\n @param[in] extMem External memory object to be destroyed\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n\n @see"] + pub fn hipDestroyExternalMemory(extMem: hipExternalMemory_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}"] + pub fn hipMalloc(ptr: *mut *mut ::std::os::raw::c_void, size: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate memory on the default accelerator\n\n @param[out] ptr Pointer to the allocated memory\n @param[in] size Requested memory size\n @param[in] flags Type of memory allocation\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n\n @return #hipSuccess, #hipErrorOutOfMemory, #hipErrorInvalidValue (bad context, null *ptr)\n\n @see hipMallocPitch, hipFree, hipMallocArray, hipFreeArray, hipMalloc3D, hipMalloc3DArray,\n hipHostFree, hipHostMalloc"] + pub fn hipExtMallocWithFlags( + ptr: *mut *mut ::std::os::raw::c_void, + sizeBytes: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate pinned host memory [Deprecated]\n\n @param[out] ptr Pointer to the allocated host pinned memory\n @param[in] size Requested memory size\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @warning This API is deprecated use hipHostMalloc() instead"] + pub fn hipMallocHost(ptr: *mut *mut ::std::os::raw::c_void, size: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate pinned host memory [Deprecated]\n\n @param[out] ptr Pointer to the allocated host pinned memory\n @param[in] size Requested memory size\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @warning This API is deprecated, use hipHostMalloc() instead"] + pub fn hipMemAllocHost(ptr: *mut *mut ::std::os::raw::c_void, size: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocates device accessible page locked (pinned) host memory\n\n This API allocates pinned host memory which is mapped into the address space of all GPUs\n in the system, the memory can be accessed directly by the GPU device, and can be read or\n written with much higher bandwidth than pageable memory obtained with functions such as\n malloc().\n\n Using the pinned host memory, applications can implement faster data transfers for HostToDevice\n and DeviceToHost. The runtime tracks the hipHostMalloc allocations and can avoid some of the\n setup required for regular unpinned memory.\n\n When the memory accesses are infrequent, zero-copy memory can be a good choice, for coherent\n allocation. GPU can directly access the host memory over the CPU/GPU interconnect, without need\n to copy the data.\n\n Currently the allocation granularity is 4KB for the API.\n\n Developers need to choose proper allocation flag with consideration of synchronization.\n\n @param[out] ptr Pointer to the allocated host pinned memory\n @param[in] size Requested memory size in bytes\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n @param[in] flags Type of host memory allocation\n\n If no input for flags, it will be the default pinned memory allocation on the host.\n\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @see hipSetDeviceFlags, hipHostFree"] + pub fn hipHostMalloc( + ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = "-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup MemoryM Managed Memory\n\n @ingroup Memory\n @{\n This section describes the managed memory management functions of HIP runtime API.\n\n @note The managed memory management APIs are implemented on Linux, under developement\n on Windows.\n\n/\n/**\n @brief Allocates memory that will be automatically managed by HIP.\n\n This API is used for managed memory, allows data be shared and accessible to both CPU and\n GPU using a single pointer.\n\n The API returns the allocation pointer, managed by HMM, can be used further to execute kernels\n on device and fetch data between the host and device as needed.\n\n @note It is recommend to do the capability check before call this API.\n\n @param [out] dev_ptr - pointer to allocated device memory\n @param [in] size - requested allocation size in bytes, it should be granularity of 4KB\n @param [in] flags - must be either hipMemAttachGlobal or hipMemAttachHost\n (defaults to hipMemAttachGlobal)\n\n @returns #hipSuccess, #hipErrorMemoryAllocation, #hipErrorNotSupported, #hipErrorInvalidValue\n"] + pub fn hipMallocManaged( + dev_ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Prefetches memory to the specified destination device using HIP.\n\n @param [in] dev_ptr pointer to be prefetched\n @param [in] count size in bytes for prefetching\n @param [in] device destination device to prefetch to\n @param [in] stream stream to enqueue prefetch operation\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPrefetchAsync( + dev_ptr: *const ::std::os::raw::c_void, + count: usize, + device: ::std::os::raw::c_int, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Advise about the usage of a given memory range to HIP.\n\n @param [in] dev_ptr pointer to memory to set the advice for\n @param [in] count size in bytes of the memory range, it should be CPU page size alligned.\n @param [in] advice advice to be applied for the specified memory range\n @param [in] device device to apply the advice for\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n This HIP API advises about the usage to be applied on unified memory allocation in the\n range starting from the pointer address devPtr, with the size of count bytes. The memory range\n must refer to managed memory allocated via the API hipMallocManaged, and the range will be\n handled with proper round down and round up respectively in the driver to be aligned to\n CPU page size.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemAdvise( + dev_ptr: *const ::std::os::raw::c_void, + count: usize, + advice: hipMemoryAdvise, + device: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query an attribute of a given memory range in HIP.\n\n @param [in,out] data a pointer to a memory location where the result of each\n attribute query will be written to\n @param [in] data_size the size of data\n @param [in] attribute the attribute to query\n @param [in] dev_ptr start of the range to query\n @param [in] count size of the range to query\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemRangeGetAttribute( + data: *mut ::std::os::raw::c_void, + data_size: usize, + attribute: hipMemRangeAttribute, + dev_ptr: *const ::std::os::raw::c_void, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query attributes of a given memory range in HIP.\n\n @param [in,out] data a two-dimensional array containing pointers to memory locations\n where the result of each attribute query will be written to\n @param [in] data_sizes an array, containing the sizes of each result\n @param [in] attributes the attribute to query\n @param [in] num_attributes an array of attributes to query (numAttributes and the number\n of attributes in this array should match)\n @param [in] dev_ptr start of the range to query\n @param [in] count size of the range to query\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemRangeGetAttributes( + data: *mut *mut ::std::os::raw::c_void, + data_sizes: *mut usize, + attributes: *mut hipMemRangeAttribute, + num_attributes: usize, + dev_ptr: *const ::std::os::raw::c_void, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Attach memory to a stream asynchronously in HIP.\n\n @param [in] stream - stream in which to enqueue the attach operation\n @param [in] dev_ptr - pointer to memory (must be a pointer to managed memory or\n to a valid host-accessible region of system-allocated memory)\n @param [in] length - length of memory (defaults to zero)\n @param [in] flags - must be one of hipMemAttachGlobal, hipMemAttachHost or\n hipMemAttachSingle (defaults to hipMemAttachSingle)\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipStreamAttachMemAsync( + stream: hipStream_t, + dev_ptr: *mut ::std::os::raw::c_void, + length: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocates memory with stream ordered semantics\n\n Inserts a memory allocation operation into @p stream.\n A pointer to the allocated memory is returned immediately in *dptr.\n The allocation must not be accessed until the the allocation operation completes.\n The allocation comes from the memory pool associated with the stream's device.\n\n @note The default memory pool of a device contains device memory from that device.\n @note Basic stream ordering allows future work submitted into the same stream to use the\n allocation. Stream query, stream synchronize, and HIP events can be used to guarantee that\n the allocation operation completes before work submitted in a separate stream runs.\n @note During stream capture, this function results in the creation of an allocation node.\n In this case, the allocation is owned by the graph instead of the memory pool. The memory\n pool's properties are used to set the node's creation parameters.\n\n @param [out] dev_ptr Returned device pointer of memory allocation\n @param [in] size Number of bytes to allocate\n @param [in] stream The stream establishing the stream ordering contract and\n the memory pool to allocate from\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported, #hipErrorOutOfMemory\n\n @see hipMallocFromPoolAsync, hipFreeAsync, hipMemPoolTrimTo, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMallocAsync( + dev_ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Frees memory with stream ordered semantics\n\n Inserts a free operation into @p stream.\n The allocation must not be used after stream execution reaches the free.\n After this API returns, accessing the memory from any subsequent work launched on the GPU\n or querying its pointer attributes results in undefined behavior.\n\n @note During stream capture, this function results in the creation of a free node and\n must therefore be passed the address of a graph allocation.\n\n @param [in] dev_ptr Pointer to device memory to free\n @param [in] stream The stream, where the destruciton will occur according to the execution order\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipMemPoolTrimTo, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipFreeAsync(dev_ptr: *mut ::std::os::raw::c_void, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Releases freed memory back to the OS\n\n Releases memory back to the OS until the pool contains fewer than @p min_bytes_to_keep\n reserved bytes, or there is no more memory that the allocator can safely release.\n The allocator cannot release OS allocations that back outstanding asynchronous allocations.\n The OS allocations may happen at different granularity from the user allocations.\n\n @note: Allocations that have not been freed count as outstanding.\n @note: Allocations that have been asynchronously freed but whose completion has\n not been observed on the host (eg. by a synchronize) can count as outstanding.\n\n @param[in] mem_pool The memory pool to trim allocations\n @param[in] min_bytes_to_hold If the pool has less than min_bytes_to_hold reserved,\n then the TrimTo operation is a no-op. Otherwise the memory pool will contain\n at least min_bytes_to_hold bytes reserved after the operation.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute,\n hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolTrimTo(mem_pool: hipMemPool_t, min_bytes_to_hold: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets attributes of a memory pool\n\n Supported attributes are:\n - @p hipMemPoolAttrReleaseThreshold: (value type = cuuint64_t)\n Amount of reserved memory in bytes to hold onto before trying\n to release memory back to the OS. When more than the release\n threshold bytes of memory are held by the memory pool, the\n allocator will try to release memory back to the OS on the\n next call to stream, event or context synchronize. (default 0)\n - @p hipMemPoolReuseFollowEventDependencies: (value type = int)\n Allow @p hipMallocAsync to use memory asynchronously freed\n in another stream as long as a stream ordering dependency\n of the allocating stream on the free action exists.\n HIP events and null stream interactions can create the required\n stream ordered dependencies. (default enabled)\n - @p hipMemPoolReuseAllowOpportunistic: (value type = int)\n Allow reuse of already completed frees when there is no dependency\n between the free and allocation. (default enabled)\n - @p hipMemPoolReuseAllowInternalDependencies: (value type = int)\n Allow @p hipMallocAsync to insert new stream dependencies\n in order to establish the stream ordering required to reuse\n a piece of memory released by @p hipFreeAsync (default enabled).\n\n @param [in] mem_pool The memory pool to modify\n @param [in] attr The attribute to modify\n @param [in] value Pointer to the value to assign\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute,\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolSetAttribute( + mem_pool: hipMemPool_t, + attr: hipMemPoolAttr, + value: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets attributes of a memory pool\n\n Supported attributes are:\n - @p hipMemPoolAttrReleaseThreshold: (value type = cuuint64_t)\n Amount of reserved memory in bytes to hold onto before trying\n to release memory back to the OS. When more than the release\n threshold bytes of memory are held by the memory pool, the\n allocator will try to release memory back to the OS on the\n next call to stream, event or context synchronize. (default 0)\n - @p hipMemPoolReuseFollowEventDependencies: (value type = int)\n Allow @p hipMallocAsync to use memory asynchronously freed\n in another stream as long as a stream ordering dependency\n of the allocating stream on the free action exists.\n HIP events and null stream interactions can create the required\n stream ordered dependencies. (default enabled)\n - @p hipMemPoolReuseAllowOpportunistic: (value type = int)\n Allow reuse of already completed frees when there is no dependency\n between the free and allocation. (default enabled)\n - @p hipMemPoolReuseAllowInternalDependencies: (value type = int)\n Allow @p hipMallocAsync to insert new stream dependencies\n in order to establish the stream ordering required to reuse\n a piece of memory released by @p hipFreeAsync (default enabled).\n\n @param [in] mem_pool The memory pool to get attributes of\n @param [in] attr The attribute to get\n @param [in] value Retrieved value\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync,\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolGetAttribute( + mem_pool: hipMemPool_t, + attr: hipMemPoolAttr, + value: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Controls visibility of the specified pool between devices\n\n @param [in] mem_pool Memory pool for acccess change\n @param [in] desc_list Array of access descriptors. Each descriptor instructs the access to enable for a single gpu\n @param [in] count Number of descriptors in the map array.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute,\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolSetAccess( + mem_pool: hipMemPool_t, + desc_list: *const hipMemAccessDesc, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the accessibility of a pool from a device\n\n Returns the accessibility of the pool's memory from the specified location.\n\n @param [out] flags Accessibility of the memory pool from the specified location/device\n @param [in] mem_pool Memory pool being queried\n @param [in] location Location/device for memory pool access\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute,\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolGetAccess( + flags: *mut hipMemAccessFlags, + mem_pool: hipMemPool_t, + location: *mut hipMemLocation, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memory pool\n\n Creates a HIP memory pool and returns the handle in @p mem_pool. The @p pool_props determines\n the properties of the pool such as the backing device and IPC capabilities.\n\n By default, the memory pool will be accessible from the device it is allocated on.\n\n @param [out] mem_pool Contains createed memory pool\n @param [in] pool_props Memory pool properties\n\n @note Specifying hipMemHandleTypeNone creates a memory pool that will not support IPC.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute, hipMemPoolDestroy,\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolCreate( + mem_pool: *mut hipMemPool_t, + pool_props: *const hipMemPoolProps, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the specified memory pool\n\n If any pointers obtained from this pool haven't been freed or\n the pool has free operations that haven't completed\n when @p hipMemPoolDestroy is invoked, the function will return immediately and the\n resources associated with the pool will be released automatically\n once there are no more outstanding allocations.\n\n Destroying the current mempool of a device sets the default mempool of\n that device as the current mempool for that device.\n\n @param [in] mem_pool Memory pool for destruction\n\n @note A device's default memory pool cannot be destroyed.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipMallocFromPoolAsync, hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute, hipMemPoolCreate\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolDestroy(mem_pool: hipMemPool_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocates memory from a specified pool with stream ordered semantics.\n\n Inserts an allocation operation into @p stream.\n A pointer to the allocated memory is returned immediately in @p dev_ptr.\n The allocation must not be accessed until the the allocation operation completes.\n The allocation comes from the specified memory pool.\n\n @note The specified memory pool may be from a device different than that of the specified @p stream.\n\n Basic stream ordering allows future work submitted into the same stream to use the allocation.\n Stream query, stream synchronize, and HIP events can be used to guarantee that the allocation\n operation completes before work submitted in a separate stream runs.\n\n @note During stream capture, this function results in the creation of an allocation node. In this case,\n the allocation is owned by the graph instead of the memory pool. The memory pool's properties\n are used to set the node's creation parameters.\n\n @param [out] dev_ptr Returned device pointer\n @param [in] size Number of bytes to allocate\n @param [in] mem_pool The pool to allocate from\n @param [in] stream The stream establishing the stream ordering semantic\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported, #hipErrorOutOfMemory\n\n @see hipMallocAsync, hipFreeAsync, hipMemPoolGetAttribute, hipMemPoolCreate\n hipMemPoolTrimTo, hipDeviceSetMemPool, hipMemPoolSetAttribute, hipMemPoolSetAccess, hipMemPoolGetAccess,\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMallocFromPoolAsync( + dev_ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + mem_pool: hipMemPool_t, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Exports a memory pool to the requested handle type.\n\n Given an IPC capable mempool, create an OS handle to share the pool with another process.\n A recipient process can convert the shareable handle into a mempool with @p hipMemPoolImportFromShareableHandle.\n Individual pointers can then be shared with the @p hipMemPoolExportPointer and @p hipMemPoolImportPointer APIs.\n The implementation of what the shareable handle is and how it can be transferred is defined by the requested\n handle type.\n\n @note: To create an IPC capable mempool, create a mempool with a @p hipMemAllocationHandleType other\n than @p hipMemHandleTypeNone.\n\n @param [out] shared_handle Pointer to the location in which to store the requested handle\n @param [in] mem_pool Pool to export\n @param [in] handle_type The type of handle to create\n @param [in] flags Must be 0\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorOutOfMemory\n\n @see hipMemPoolImportFromShareableHandle\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolExportToShareableHandle( + shared_handle: *mut ::std::os::raw::c_void, + mem_pool: hipMemPool_t, + handle_type: hipMemAllocationHandleType, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Imports a memory pool from a shared handle.\n\n Specific allocations can be imported from the imported pool with @p hipMemPoolImportPointer.\n\n @note Imported memory pools do not support creating new allocations.\n As such imported memory pools may not be used in @p hipDeviceSetMemPool\n or @p hipMallocFromPoolAsync calls.\n\n @param [out] mem_pool Returned memory pool\n @param [in] shared_handle OS handle of the pool to open\n @param [in] handle_type The type of handle being imported\n @param [in] flags Must be 0\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorOutOfMemory\n\n @see hipMemPoolExportToShareableHandle\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolImportFromShareableHandle( + mem_pool: *mut hipMemPool_t, + shared_handle: *mut ::std::os::raw::c_void, + handle_type: hipMemAllocationHandleType, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Export data to share a memory pool allocation between processes.\n\n Constructs @p export_data for sharing a specific allocation from an already shared memory pool.\n The recipient process can import the allocation with the @p hipMemPoolImportPointer api.\n The data is not a handle and may be shared through any IPC mechanism.\n\n @param[out] export_data Returned export data\n @param[in] dev_ptr Pointer to memory being exported\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorOutOfMemory\n\n @see hipMemPoolImportPointer\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolExportPointer( + export_data: *mut hipMemPoolPtrExportData, + dev_ptr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Import a memory pool allocation from another process.\n\n Returns in @p dev_ptr a pointer to the imported memory.\n The imported memory must not be accessed before the allocation operation completes\n in the exporting process. The imported memory must be freed from all importing processes before\n being freed in the exporting process. The pointer may be freed with @p hipFree\n or @p hipFreeAsync. If @p hipFreeAsync is used, the free must be completed\n on the importing process before the free operation on the exporting process.\n\n @note The @p hipFreeAsync api may be used in the exporting process before\n the @p hipFreeAsync operation completes in its stream as long as the\n @p hipFreeAsync in the exporting process specifies a stream with\n a stream dependency on the importing process's @p hipFreeAsync.\n\n @param [out] dev_ptr Pointer to imported memory\n @param [in] mem_pool Memory pool from which to import a pointer\n @param [in] export_data Data specifying the memory to import\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized, #hipErrorOutOfMemory\n\n @see hipMemPoolExportPointer\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemPoolImportPointer( + dev_ptr: *mut *mut ::std::os::raw::c_void, + mem_pool: hipMemPool_t, + export_data: *mut hipMemPoolPtrExportData, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate device accessible page locked host memory [Deprecated]\n\n @param[out] ptr Pointer to the allocated host pinned memory\n @param[in] size Requested memory size in bytes\n @param[in] flags Type of host memory allocation\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @warning This API is deprecated, use hipHostMalloc() instead"] + pub fn hipHostAlloc( + ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get Device pointer from Host Pointer allocated through hipHostMalloc\n\n @param[out] dstPtr Device Pointer mapped to passed host pointer\n @param[in] hstPtr Host Pointer allocated through hipHostMalloc\n @param[in] flags Flags to be passed for extension\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorOutOfMemory\n\n @see hipSetDeviceFlags, hipHostMalloc"] + pub fn hipHostGetDevicePointer( + devPtr: *mut *mut ::std::os::raw::c_void, + hstPtr: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return flags associated with host pointer\n\n @param[out] flagsPtr Memory location to store flags\n @param[in] hostPtr Host Pointer allocated through hipHostMalloc\n @return #hipSuccess, #hipErrorInvalidValue\n\n @see hipHostMalloc"] + pub fn hipHostGetFlags( + flagsPtr: *mut ::std::os::raw::c_uint, + hostPtr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Register host memory so it can be accessed from the current device.\n\n @param[out] hostPtr Pointer to host memory to be registered.\n @param[in] sizeBytes size of the host memory\n @param[in] flags. See below.\n\n Flags:\n - #hipHostRegisterDefault Memory is Mapped and Portable\n - #hipHostRegisterPortable Memory is considered registered by all contexts. HIP only supports\n one context so this is always assumed true.\n - #hipHostRegisterMapped Map the allocation into the address space for the current device.\n The device pointer can be obtained with #hipHostGetDevicePointer.\n\n\n After registering the memory, use #hipHostGetDevicePointer to obtain the mapped device pointer.\n On many systems, the mapped device pointer will have a different value than the mapped host\n pointer. Applications must use the device pointer in device code, and the host pointer in device\n code.\n\n On some systems, registered memory is pinned. On some systems, registered memory may not be\n actually be pinned but uses OS or hardware facilities to all GPU access to the host memory.\n\n Developers are strongly encouraged to register memory blocks which are aligned to the host\n cache-line size. (typically 64-bytes but can be obtains from the CPUID instruction).\n\n If registering non-aligned pointers, the application must take care when register pointers from\n the same cache line on different devices. HIP's coarse-grained synchronization model does not\n guarantee correct results if different devices write to different parts of the same cache block -\n typically one of the writes will \"win\" and overwrite data from the other registered memory\n region.\n\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @see hipHostUnregister, hipHostGetFlags, hipHostGetDevicePointer"] + pub fn hipHostRegister( + hostPtr: *mut ::std::os::raw::c_void, + sizeBytes: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Un-register host pointer\n\n @param[in] hostPtr Host pointer previously registered with #hipHostRegister\n @return Error code\n\n @see hipHostRegister"] + pub fn hipHostUnregister(hostPtr: *mut ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " Allocates at least width (in bytes) * height bytes of linear memory\n Padding may occur to ensure alighnment requirements are met for the given row\n The change in width size due to padding will be returned in *pitch.\n Currently the alignment is set to 128 bytes\n\n @param[out] ptr Pointer to the allocated device memory\n @param[out] pitch Pitch for allocation (in bytes)\n @param[in] width Requested pitched allocation width (in bytes)\n @param[in] height Requested pitched allocation height\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n\n @return Error code\n\n @see hipMalloc, hipFree, hipMallocArray, hipFreeArray, hipHostFree, hipMalloc3D,\n hipMalloc3DArray, hipHostMalloc"] + pub fn hipMallocPitch( + ptr: *mut *mut ::std::os::raw::c_void, + pitch: *mut usize, + width: usize, + height: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " Allocates at least width (in bytes) * height bytes of linear memory\n Padding may occur to ensure alighnment requirements are met for the given row\n The change in width size due to padding will be returned in *pitch.\n Currently the alignment is set to 128 bytes\n\n @param[out] dptr Pointer to the allocated device memory\n @param[out] pitch Pitch for allocation (in bytes)\n @param[in] width Requested pitched allocation width (in bytes)\n @param[in] height Requested pitched allocation height\n\n If size is 0, no memory is allocated, *ptr returns nullptr, and hipSuccess is returned.\n The intended usage of pitch is as a separate parameter of the allocation, used to compute addresses within the 2D array.\n Given the row and column of an array element of type T, the address is computed as:\n T* pElement = (T*)((char*)BaseAddress + Row * Pitch) + Column;\n\n @return Error code\n\n @see hipMalloc, hipFree, hipMallocArray, hipFreeArray, hipHostFree, hipMalloc3D,\n hipMalloc3DArray, hipHostMalloc"] + pub fn hipMemAllocPitch( + dptr: *mut hipDeviceptr_t, + pitch: *mut usize, + widthInBytes: usize, + height: usize, + elementSizeBytes: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Free memory allocated by the hcc hip memory allocation API.\n This API performs an implicit hipDeviceSynchronize() call.\n If pointer is NULL, the hip runtime is initialized and hipSuccess is returned.\n\n @param[in] ptr Pointer to memory to be freed\n @return #hipSuccess\n @return #hipErrorInvalidDevicePointer (if pointer is invalid, including host pointers allocated\n with hipHostMalloc)\n\n @see hipMalloc, hipMallocPitch, hipMallocArray, hipFreeArray, hipHostFree, hipMalloc3D,\n hipMalloc3DArray, hipHostMalloc"] + pub fn hipFree(ptr: *mut ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Free memory allocated by the hcc hip host memory allocation API [Deprecated]\n\n @param[in] ptr Pointer to memory to be freed\n @return #hipSuccess, #hipErrorInvalidValue (if pointer is invalid, including device pointers\n allocated with hipMalloc)\n\n @warning This API is deprecated, use hipHostFree() instead"] + pub fn hipFreeHost(ptr: *mut ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Free memory allocated by the hcc hip host memory allocation API\n This API performs an implicit hipDeviceSynchronize() call.\n If pointer is NULL, the hip runtime is initialized and hipSuccess is returned.\n\n @param[in] ptr Pointer to memory to be freed\n @return #hipSuccess,\n #hipErrorInvalidValue (if pointer is invalid, including device pointers allocated with\n hipMalloc)\n\n @see hipMalloc, hipMallocPitch, hipFree, hipMallocArray, hipFreeArray, hipMalloc3D,\n hipMalloc3DArray, hipHostMalloc"] + pub fn hipHostFree(ptr: *mut ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from src to dst.\n\n It supports memory from host to device,\n device to host, device to device and host to host\n The src and dst must not overlap.\n\n For hipMemcpy, the copy is always performed by the current device (set by hipSetDevice).\n For multi-gpu or peer-to-peer configurations, it is recommended to set the current device to the\n device where the src data is physically located. For optimal peer-to-peer copies, the copy device\n must be able to access the src and dst pointers (by calling hipDeviceEnablePeerAccess with copy\n agent as the current device and src/dest as the peerDevice argument. if this is not done, the\n hipMemcpy will still work, but will perform the copy using a staging buffer on the host.\n Calling hipMemcpy with dst and src pointers that do not match the hipMemcpyKind results in\n undefined behavior.\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n @param[in] copyType Memory copy type\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree, #hipErrorUnknown\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpy( + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Memory copy on the stream.\n It allows single or multiple devices to do memory copy on single or multiple streams.\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n @param[in] copyType Memory copy type\n @param[in] stream Valid stream\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree, #hipErrorUnknown, #hipErrorContextIsDestroyed\n\n @see hipMemcpy, hipStreamCreate, hipStreamSynchronize, hipStreamDestroy, hipSetDevice, hipLaunchKernelGGL\n"] + pub fn hipMemcpyWithStream( + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Host to Device\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyHtoD( + dst: hipDeviceptr_t, + src: *mut ::std::os::raw::c_void, + sizeBytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Device to Host\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyDtoH( + dst: *mut ::std::os::raw::c_void, + src: hipDeviceptr_t, + sizeBytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Device to Device\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyDtoD(dst: hipDeviceptr_t, src: hipDeviceptr_t, sizeBytes: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Host to Device asynchronously\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyHtoDAsync( + dst: hipDeviceptr_t, + src: *mut ::std::os::raw::c_void, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Device to Host asynchronously\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyDtoHAsync( + dst: *mut ::std::os::raw::c_void, + src: hipDeviceptr_t, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from Device to Device asynchronously\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n\n @return #hipSuccess, #hipErrorDeinitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc, hipMemAllocHost,\n hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned, hipMemcpyAtoA,\n hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync, hipMemcpyDtoA, hipMemcpyDtoD,\n hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync, hipMemcpyHtoA, hipMemcpyHtoAAsync,\n hipMemcpyHtoDAsync, hipMemFree, hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo,\n hipMemHostAlloc, hipMemHostGetDevicePointer"] + pub fn hipMemcpyDtoDAsync( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a global pointer from a module.\n Returns in *dptr and *bytes the pointer and size of the global of name name located in module hmod.\n If no variable of that name exists, it returns hipErrorNotFound. Both parameters dptr and bytes are optional.\n If one of them is NULL, it is ignored and hipSuccess is returned.\n\n @param[out] dptr Returns global device pointer\n @param[out] bytes Returns global size in bytes\n @param[in] hmod Module to retrieve global from\n @param[in] name Name of global to retrieve\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotFound, #hipErrorInvalidContext\n"] + pub fn hipModuleGetGlobal( + dptr: *mut hipDeviceptr_t, + bytes: *mut usize, + hmod: hipModule_t, + name: *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets device pointer associated with symbol on the device.\n\n @param[out] devPtr pointer to the device associated the symbole\n @param[in] symbol pointer to the symbole of the device\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetSymbolAddress( + devPtr: *mut *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the size of the given symbol on the device.\n\n @param[in] symbol pointer to the device symbole\n @param[out] size pointer to the size\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetSymbolSize(size: *mut usize, symbol: *const ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data to the given symbol on the device.\n Symbol HIP APIs allow a kernel to define a device-side data symbol which can be accessed on\n the host side. The symbol can be in __constant or device space.\n Note that the symbol name needs to be encased in the HIP_SYMBOL macro.\n This also applies to hipMemcpyFromSymbol, hipGetSymbolAddress, and hipGetSymbolSize.\n For detail usage, see the example at\n https://github.com/ROCm-Developer-Tools/HIP/blob/rocm-5.0.x/docs/markdown/hip_porting_guide.md\n\n @param[out] symbol pointer to the device symbole\n @param[in] src pointer to the source address\n @param[in] sizeBytes size in bytes to copy\n @param[in] offset offset in bytes from start of symbole\n @param[in] kind type of memory transfer\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipMemcpyToSymbol( + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data to the given symbol on the device asynchronously.\n\n @param[out] symbol pointer to the device symbole\n @param[in] src pointer to the source address\n @param[in] sizeBytes size in bytes to copy\n @param[in] offset offset in bytes from start of symbole\n @param[in] kind type of memory transfer\n @param[in] stream stream identifier\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipMemcpyToSymbolAsync( + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data from the given symbol on the device.\n\n @param[out] dptr Returns pointer to destinition memory address\n @param[in] symbol pointer to the symbole address on the device\n @param[in] sizeBytes size in bytes to copy\n @param[in] offset offset in bytes from the start of symbole\n @param[in] kind type of memory transfer\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipMemcpyFromSymbol( + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data from the given symbol on the device asynchronously.\n\n @param[out] dptr Returns pointer to destinition memory address\n @param[in] symbol pointer to the symbole address on the device\n @param[in] sizeBytes size in bytes to copy\n @param[in] offset offset in bytes from the start of symbole\n @param[in] kind type of memory transfer\n @param[in] stream stream identifier\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipMemcpyFromSymbolAsync( + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copy data from src to dst asynchronously.\n\n @warning If host or dest are not pinned, the memory copy will be performed synchronously. For\n best performance, use hipHostMalloc to allocate host memory that is transferred asynchronously.\n\n @warning on HCC hipMemcpyAsync does not support overlapped H2D and D2H copies.\n For hipMemcpy, the copy is always performed by the device associated with the specified stream.\n\n For multi-gpu or peer-to-peer configurations, it is recommended to use a stream which is a\n attached to the device where the src data is physically located. For optimal peer-to-peer copies,\n the copy device must be able to access the src and dst pointers (by calling\n hipDeviceEnablePeerAccess with copy agent as the current device and src/dest as the peerDevice\n argument. if this is not done, the hipMemcpy will still work, but will perform the copy using a\n staging buffer on the host.\n\n @param[out] dst Data being copy to\n @param[in] src Data being copy from\n @param[in] sizeBytes Data size in bytes\n @param[in] accelerator_view Accelerator view which the copy is being enqueued\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree, #hipErrorUnknown\n\n @see hipMemcpy, hipMemcpy2D, hipMemcpyToArray, hipMemcpy2DToArray, hipMemcpyFromArray,\n hipMemcpy2DFromArray, hipMemcpyArrayToArray, hipMemcpy2DArrayToArray, hipMemcpyToSymbol,\n hipMemcpyFromSymbol, hipMemcpy2DAsync, hipMemcpyToArrayAsync, hipMemcpy2DToArrayAsync,\n hipMemcpyFromArrayAsync, hipMemcpy2DFromArrayAsync, hipMemcpyToSymbolAsync,\n hipMemcpyFromSymbolAsync"] + pub fn hipMemcpyAsync( + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant\n byte value value.\n\n @param[out] dst Data being filled\n @param[in] constant value to be set\n @param[in] sizeBytes Data size in bytes\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemset( + dst: *mut ::std::os::raw::c_void, + value: ::std::os::raw::c_int, + sizeBytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant\n byte value value.\n\n @param[out] dst Data ptr to be filled\n @param[in] constant value to be set\n @param[in] number of values to be set\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemsetD8( + dest: hipDeviceptr_t, + value: ::std::os::raw::c_uchar, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant\n byte value value.\n\n hipMemsetD8Async() is asynchronous with respect to the host, so the call may return before the\n memset is complete. The operation can optionally be associated to a stream by passing a non-zero\n stream argument. If stream is non-zero, the operation may overlap with operations in other\n streams.\n\n @param[out] dst Data ptr to be filled\n @param[in] constant value to be set\n @param[in] number of values to be set\n @param[in] stream - Stream identifier\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemsetD8Async( + dest: hipDeviceptr_t, + value: ::std::os::raw::c_uchar, + count: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant\n short value value.\n\n @param[out] dst Data ptr to be filled\n @param[in] constant value to be set\n @param[in] number of values to be set\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemsetD16( + dest: hipDeviceptr_t, + value: ::std::os::raw::c_ushort, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant\n short value value.\n\n hipMemsetD16Async() is asynchronous with respect to the host, so the call may return before the\n memset is complete. The operation can optionally be associated to a stream by passing a non-zero\n stream argument. If stream is non-zero, the operation may overlap with operations in other\n streams.\n\n @param[out] dst Data ptr to be filled\n @param[in] constant value to be set\n @param[in] number of values to be set\n @param[in] stream - Stream identifier\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemsetD16Async( + dest: hipDeviceptr_t, + value: ::std::os::raw::c_ushort, + count: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the memory area pointed to by dest with the constant integer\n value for specified number of times.\n\n @param[out] dst Data being filled\n @param[in] constant value to be set\n @param[in] number of values to be set\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized"] + pub fn hipMemsetD32( + dest: hipDeviceptr_t, + value: ::std::os::raw::c_int, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the first sizeBytes bytes of the memory area pointed to by dev with the constant\n byte value value.\n\n hipMemsetAsync() is asynchronous with respect to the host, so the call may return before the\n memset is complete. The operation can optionally be associated to a stream by passing a non-zero\n stream argument. If stream is non-zero, the operation may overlap with operations in other\n streams.\n\n @param[out] dst Pointer to device memory\n @param[in] value - Value to set for each byte of specified memory\n @param[in] sizeBytes - Size in bytes to set\n @param[in] stream - Stream identifier\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemsetAsync( + dst: *mut ::std::os::raw::c_void, + value: ::std::os::raw::c_int, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the memory area pointed to by dev with the constant integer\n value for specified number of times.\n\n hipMemsetD32Async() is asynchronous with respect to the host, so the call may return before the\n memset is complete. The operation can optionally be associated to a stream by passing a non-zero\n stream argument. If stream is non-zero, the operation may overlap with operations in other\n streams.\n\n @param[out] dst Pointer to device memory\n @param[in] value - Value to set for each byte of specified memory\n @param[in] count - number of values to be set\n @param[in] stream - Stream identifier\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemsetD32Async( + dst: hipDeviceptr_t, + value: ::std::os::raw::c_int, + count: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills the memory area pointed to by dst with the constant value.\n\n @param[out] dst Pointer to device memory\n @param[in] pitch - data size in bytes\n @param[in] value - constant value to be set\n @param[in] width\n @param[in] height\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemset2D( + dst: *mut ::std::os::raw::c_void, + pitch: usize, + value: ::std::os::raw::c_int, + width: usize, + height: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills asynchronously the memory area pointed to by dst with the constant value.\n\n @param[in] dst Pointer to device memory\n @param[in] pitch - data size in bytes\n @param[in] value - constant value to be set\n @param[in] width\n @param[in] height\n @param[in] stream\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemset2DAsync( + dst: *mut ::std::os::raw::c_void, + pitch: usize, + value: ::std::os::raw::c_int, + width: usize, + height: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills synchronously the memory area pointed to by pitchedDevPtr with the constant value.\n\n @param[in] pitchedDevPtr\n @param[in] value - constant value to be set\n @param[in] extent\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemset3D( + pitchedDevPtr: hipPitchedPtr, + value: ::std::os::raw::c_int, + extent: hipExtent, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills asynchronously the memory area pointed to by pitchedDevPtr with the constant value.\n\n @param[in] pitchedDevPtr\n @param[in] value - constant value to be set\n @param[in] extent\n @param[in] stream\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryFree"] + pub fn hipMemset3DAsync( + pitchedDevPtr: hipPitchedPtr, + value: ::std::os::raw::c_int, + extent: hipExtent, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query memory info.\n\n On ROCM, this function gets the actual free memory left on the current device, so supports\n the cases while running multi-workload (such as multiple processes, multiple threads, and\n multiple GPUs).\n\n @warning On Windows, the free memory only accounts for memory allocated by this process and may\n be optimistic.\n\n @param[out] free Returns free memory on the current device in bytes\n @param[out] total Returns total allocatable memory on the current device in bytes\n\n @return #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue\n"] + pub fn hipMemGetInfo(free: *mut usize, total: *mut usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get allocated memory size via memory pointer.\n\n This function gets the allocated shared virtual memory size from memory pointer.\n\n @param[in] ptr Pointer to allocated memory\n @param[out] size Returns the allocated memory size in bytes\n\n @return #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipMemPtrGetInfo(ptr: *mut ::std::os::raw::c_void, size: *mut usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate an array on the device.\n\n @param[out] array Pointer to allocated array in device memory\n @param[in] desc Requested channel format\n @param[in] width Requested array allocation width\n @param[in] height Requested array allocation height\n @param[in] flags Requested properties of allocated array\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @see hipMalloc, hipMallocPitch, hipFree, hipFreeArray, hipHostMalloc, hipHostFree"] + pub fn hipMallocArray( + array: *mut *mut hipArray, + desc: *const hipChannelFormatDesc, + width: usize, + height: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an array memory pointer on the device.\n\n @param[out] pHandle Pointer to the array memory\n @param[in] pAllocateArray Requested array desciptor\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipMallocArray, hipArrayDestroy, hipFreeArray"] + pub fn hipArrayCreate( + pHandle: *mut *mut hipArray, + pAllocateArray: *const HIP_ARRAY_DESCRIPTOR, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy an array memory pointer on the device.\n\n @param[in] array Pointer to the array memory\n\n @return #hipSuccess, #hipErrorInvalidValue\n\n @see hipArrayCreate, hipArrayDestroy, hipFreeArray"] + pub fn hipArrayDestroy(array: *mut hipArray) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a 3D array memory pointer on the device.\n\n @param[out] array Pointer to the 3D array memory\n @param[in] pAllocateArray Requested array desciptor\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipMallocArray, hipArrayDestroy, hipFreeArray"] + pub fn hipArray3DCreate( + array: *mut *mut hipArray, + pAllocateArray: *const HIP_ARRAY3D_DESCRIPTOR, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a 3D memory pointer on the device.\n\n @param[out] pitchedDevPtr Pointer to the 3D memory\n @param[in] extent Requested extent\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n\n @see hipMallocPitch, hipMemGetInfo, hipFree"] + pub fn hipMalloc3D(pitchedDevPtr: *mut hipPitchedPtr, extent: hipExtent) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Frees an array on the device.\n\n @param[in] array Pointer to array to free\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorNotInitialized\n\n @see hipMalloc, hipMallocPitch, hipFree, hipMallocArray, hipHostMalloc, hipHostFree"] + pub fn hipFreeArray(array: *mut hipArray) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate an array on the device.\n\n @param[out] array Pointer to allocated array in device memory\n @param[in] desc Requested channel format\n @param[in] extent Requested array allocation width, height and depth\n @param[in] flags Requested properties of allocated array\n @return #hipSuccess, #hipErrorOutOfMemory\n\n @see hipMalloc, hipMallocPitch, hipFree, hipFreeArray, hipHostMalloc, hipHostFree"] + pub fn hipMalloc3DArray( + array: *mut *mut hipArray, + desc: *const hipChannelFormatDesc, + extent: hipExtent, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets info about the specified array\n\n @param[out] desc - Returned array type\n @param[out] extent - Returned array shape. 2D arrays will have depth of zero\n @param[out] flags - Returned array flags\n @param[in] array - The HIP array to get info for\n\n @return #hipSuccess, #hipErrorInvalidValue #hipErrorInvalidHandle\n\n @see hipArrayGetDescriptor, hipArray3DGetDescriptor"] + pub fn hipArrayGetInfo( + desc: *mut hipChannelFormatDesc, + extent: *mut hipExtent, + flags: *mut ::std::os::raw::c_uint, + array: *mut hipArray, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a 1D or 2D array descriptor\n\n @param[out] pArrayDescriptor - Returned array descriptor\n @param[in] array - Array to get descriptor of\n\n @return #hipSuccess, #hipErrorDeInitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue #hipErrorInvalidHandle\n\n @see hipArray3DCreate, hipArray3DGetDescriptor, hipArrayCreate, hipArrayDestroy, hipMemAlloc,\n hipMemAllocHost, hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned,\n hipMemcpy3D, hipMemcpy3DAsync, hipMemcpyAtoA, hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync,\n hipMemcpyDtoA, hipMemcpyDtoD, hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync,\n hipMemcpyHtoA, hipMemcpyHtoAAsync, hipMemcpyHtoD, hipMemcpyHtoDAsync, hipMemFree,\n hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo, hipMemHostAlloc,\n hipMemHostGetDevicePointer, hipMemsetD8, hipMemsetD16, hipMemsetD32, hipArrayGetInfo"] + pub fn hipArrayGetDescriptor( + pArrayDescriptor: *mut HIP_ARRAY_DESCRIPTOR, + array: *mut hipArray, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a 3D array descriptor\n\n @param[out] pArrayDescriptor - Returned 3D array descriptor\n @param[in] array - 3D array to get descriptor of\n\n @return #hipSuccess, #hipErrorDeInitialized, #hipErrorNotInitialized, #hipErrorInvalidContext,\n #hipErrorInvalidValue #hipErrorInvalidHandle, #hipErrorContextIsDestroyed\n\n @see hipArray3DCreate, hipArrayCreate, hipArrayDestroy, hipArrayGetDescriptor, hipMemAlloc,\n hipMemAllocHost, hipMemAllocPitch, hipMemcpy2D, hipMemcpy2DAsync, hipMemcpy2DUnaligned,\n hipMemcpy3D, hipMemcpy3DAsync, hipMemcpyAtoA, hipMemcpyAtoD, hipMemcpyAtoH, hipMemcpyAtoHAsync,\n hipMemcpyDtoA, hipMemcpyDtoD, hipMemcpyDtoDAsync, hipMemcpyDtoH, hipMemcpyDtoHAsync,\n hipMemcpyHtoA, hipMemcpyHtoAAsync, hipMemcpyHtoD, hipMemcpyHtoDAsync, hipMemFree,\n hipMemFreeHost, hipMemGetAddressRange, hipMemGetInfo, hipMemHostAlloc,\n hipMemHostGetDevicePointer, hipMemsetD8, hipMemsetD16, hipMemsetD32, hipArrayGetInfo"] + pub fn hipArray3DGetDescriptor( + pArrayDescriptor: *mut HIP_ARRAY3D_DESCRIPTOR, + array: *mut hipArray, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] dpitch Pitch of destination memory\n @param[in] src Source memory address\n @param[in] spitch Pitch of source memory\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpyToArray, hipMemcpy2DToArray, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2D( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies memory for 2D arrays.\n @param[in] pCopy Parameters for the memory copy\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2D, hipMemcpyToArray, hipMemcpy2DToArray, hipMemcpyFromArray,\n hipMemcpyToSymbol, hipMemcpyAsync"] + pub fn hipMemcpyParam2D(pCopy: *const hip_Memcpy2D) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies memory for 2D arrays.\n @param[in] pCopy Parameters for the memory copy\n @param[in] stream Stream to use\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2D, hipMemcpyToArray, hipMemcpy2DToArray, hipMemcpyFromArray,\n hipMemcpyToSymbol, hipMemcpyAsync"] + pub fn hipMemcpyParam2DAsync(pCopy: *const hip_Memcpy2D, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] dpitch Pitch of destination memory\n @param[in] src Source memory address\n @param[in] spitch Pitch of source memory\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @param[in] stream Stream to use\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpyToArray, hipMemcpy2DToArray, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2DAsync( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] wOffset Destination starting X offset\n @param[in] hOffset Destination starting Y offset\n @param[in] src Source memory address\n @param[in] spitch Pitch of source memory\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpyToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2DToArray( + dst: *mut hipArray, + wOffset: usize, + hOffset: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] wOffset Destination starting X offset\n @param[in] hOffset Destination starting Y offset\n @param[in] src Source memory address\n @param[in] spitch Pitch of source memory\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @param[in] stream Accelerator view which the copy is being enqueued\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpyToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2DToArrayAsync( + dst: *mut hipArray, + wOffset: usize, + hOffset: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] wOffset Destination starting X offset\n @param[in] hOffset Destination starting Y offset\n @param[in] src Source memory address\n @param[in] count size in bytes to copy\n @param[in] kind Type of transfer\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync\n\n @warning This API is deprecated."] + pub fn hipMemcpyToArray( + dst: *mut hipArray, + wOffset: usize, + hOffset: usize, + src: *const ::std::os::raw::c_void, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] srcArray Source memory address\n @param[in] wOffset Source starting X offset\n @param[in] hOffset Source starting Y offset\n @param[in] count Size in bytes to copy\n @param[in] kind Type of transfer\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync\n\n @warning This API is deprecated."] + pub fn hipMemcpyFromArray( + dst: *mut ::std::os::raw::c_void, + srcArray: hipArray_const_t, + wOffset: usize, + hOffset: usize, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] dpitch Pitch of destination memory\n @param[in] src Source memory address\n @param[in] wOffset Source starting X offset\n @param[in] hOffset Source starting Y offset\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2DFromArray( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: hipArray_const_t, + wOffset: usize, + hOffset: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device asynchronously.\n\n @param[in] dst Destination memory address\n @param[in] dpitch Pitch of destination memory\n @param[in] src Source memory address\n @param[in] wOffset Source starting X offset\n @param[in] hOffset Source starting Y offset\n @param[in] width Width of matrix transfer (columns in bytes)\n @param[in] height Height of matrix transfer (rows)\n @param[in] kind Type of transfer\n @param[in] stream Accelerator view which the copy is being enqueued\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy2DFromArrayAsync( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: hipArray_const_t, + wOffset: usize, + hOffset: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dst Destination memory address\n @param[in] srcArray Source array\n @param[in] srcoffset Offset in bytes of source array\n @param[in] count Size of memory copy in bytes\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpyAtoH( + dst: *mut ::std::os::raw::c_void, + srcArray: *mut hipArray, + srcOffset: usize, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] dstArray Destination memory address\n @param[in] dstOffset Offset in bytes of destination array\n @param[in] srcHost Source host pointer\n @param[in] count Size of memory copy in bytes\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpyHtoA( + dstArray: *mut hipArray, + dstOffset: usize, + srcHost: *const ::std::os::raw::c_void, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] p 3D memory copy parameters\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy3D(p: *const hipMemcpy3DParms) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device asynchronously.\n\n @param[in] p 3D memory copy parameters\n @param[in] stream Stream to use\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipMemcpy3DAsync(p: *const hipMemcpy3DParms, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device.\n\n @param[in] pCopy 3D memory copy parameters\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipDrvMemcpy3D(pCopy: *const HIP_MEMCPY3D) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies data between host and device asynchronously.\n\n @param[in] pCopy 3D memory copy parameters\n @param[in] stream Stream to use\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidPitchValue,\n #hipErrorInvalidDevicePointer, #hipErrorInvalidMemcpyDirection\n\n @see hipMemcpy, hipMemcpy2DToArray, hipMemcpy2D, hipMemcpyFromArray, hipMemcpyToSymbol,\n hipMemcpyAsync"] + pub fn hipDrvMemcpy3DAsync(pCopy: *const HIP_MEMCPY3D, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup PeerToPeer PeerToPeer Device Memory Access\n @{\n @warning PeerToPeer support is experimental.\n This section describes the PeerToPeer device memory access functions of HIP runtime API.\n/\n/**\n @brief Determine if a device can access a peer's memory.\n\n @param [out] canAccessPeer Returns the peer access capability (0 or 1)\n @param [in] device - device from where memory may be accessed.\n @param [in] peerDevice - device where memory is physically located\n\n Returns \"1\" in @p canAccessPeer if the specified @p device is capable\n of directly accessing memory physically located on peerDevice , or \"0\" if not.\n\n Returns \"0\" in @p canAccessPeer if deviceId == peerDeviceId, and both are valid devices : a\n device is not a peer of itself.\n\n @returns #hipSuccess,\n @returns #hipErrorInvalidDevice if deviceId or peerDeviceId are not valid devices"] + pub fn hipDeviceCanAccessPeer( + canAccessPeer: *mut ::std::os::raw::c_int, + deviceId: ::std::os::raw::c_int, + peerDeviceId: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enable direct access from current device's virtual address space to memory allocations\n physically located on a peer device.\n\n Memory which already allocated on peer device will be mapped into the address space of the\n current device. In addition, all future memory allocations on peerDeviceId will be mapped into\n the address space of the current device when the memory is allocated. The peer memory remains\n accessible from the current device until a call to hipDeviceDisablePeerAccess or hipDeviceReset.\n\n\n @param [in] peerDeviceId\n @param [in] flags\n\n Returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue,\n @returns #hipErrorPeerAccessAlreadyEnabled if peer access is already enabled for this device."] + pub fn hipDeviceEnablePeerAccess( + peerDeviceId: ::std::os::raw::c_int, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Disable direct access from current device's virtual address space to memory allocations\n physically located on a peer device.\n\n Returns hipErrorPeerAccessNotEnabled if direct access to memory on peerDevice has not yet been\n enabled from the current device.\n\n @param [in] peerDeviceId\n\n @returns #hipSuccess, #hipErrorPeerAccessNotEnabled"] + pub fn hipDeviceDisablePeerAccess(peerDeviceId: ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get information on memory allocations.\n\n @param [out] pbase - BAse pointer address\n @param [out] psize - Size of allocation\n @param [in] dptr- Device Pointer\n\n @returns #hipSuccess, #hipErrorInvalidDevicePointer\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice"] + pub fn hipMemGetAddressRange( + pbase: *mut hipDeviceptr_t, + psize: *mut usize, + dptr: hipDeviceptr_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies memory from one device to memory on another device.\n\n @param [out] dst - Destination device pointer.\n @param [in] dstDeviceId - Destination device\n @param [in] src - Source device pointer\n @param [in] srcDeviceId - Source device\n @param [in] sizeBytes - Size of memory copy in bytes\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDevice"] + pub fn hipMemcpyPeer( + dst: *mut ::std::os::raw::c_void, + dstDeviceId: ::std::os::raw::c_int, + src: *const ::std::os::raw::c_void, + srcDeviceId: ::std::os::raw::c_int, + sizeBytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies memory from one device to memory on another device.\n\n @param [out] dst - Destination device pointer.\n @param [in] dstDevice - Destination device\n @param [in] src - Source device pointer\n @param [in] srcDevice - Source device\n @param [in] sizeBytes - Size of memory copy in bytes\n @param [in] stream - Stream identifier\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDevice"] + pub fn hipMemcpyPeerAsync( + dst: *mut ::std::os::raw::c_void, + dstDeviceId: ::std::os::raw::c_int, + src: *const ::std::os::raw::c_void, + srcDevice: ::std::os::raw::c_int, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup Context Context Management\n @{\n This section describes the context management functions of HIP runtime API.\n/\n/**\n\n @addtogroup ContextD Context Management [Deprecated]\n @{\n @ingroup Context\n This section describes the deprecated context management functions of HIP runtime API.\n/\n/**\n @brief Create a context and set it as current/default context.\n\n @param [out] ctx Context to create\n @param [in] flags Context creation flags\n @param [in] device device handle\n\n @return #hipSuccess\n\n @see hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent, hipCtxPushCurrent,\n hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxCreate( + ctx: *mut hipCtx_t, + flags: ::std::os::raw::c_uint, + device: hipDevice_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy a HIP context.\n\n @param [in] ctx Context to destroy\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @see hipCtxCreate, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,hipCtxSetCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize , hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxDestroy(ctx: hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Pop the current/default context and return the popped context.\n\n @param [out] ctx\n\n @returns #hipSuccess, #hipErrorInvalidContext\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxSetCurrent, hipCtxGetCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxPopCurrent(ctx: *mut hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Push the context to be set as current/ default context.\n\n @param [in] ctx\n\n @returns #hipSuccess, #hipErrorInvalidContext\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize , hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxPushCurrent(ctx: hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the passed context as current/default.\n\n @param [in] ctx\n\n @returns #hipSuccess, #hipErrorInvalidContext\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize , hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxSetCurrent(ctx: hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the handle of the current/ default context.\n\n @param [out] ctx\n\n @returns #hipSuccess, #hipErrorInvalidContext\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetDevice, hipCtxGetFlags, hipCtxPopCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetCurrent(ctx: *mut hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the handle of the device associated with current/default context.\n\n @param [out] device\n\n @returns #hipSuccess, #hipErrorInvalidContext\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetDevice(device: *mut hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the approximate HIP api version.\n\n @param [in] ctx Context to check\n @param [out] apiVersion\n\n @return #hipSuccess\n\n @warning The HIP feature set does not correspond to an exact CUDA SDK api revision.\n This function always set *apiVersion to 4 as an approximation though HIP supports\n some features which were introduced in later CUDA SDK revisions.\n HIP apps code should not rely on the api revision number here and should\n use arch feature flags to test device capabilities or conditional compilation.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetDevice, hipCtxGetFlags, hipCtxPopCurrent,\n hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetApiVersion(ctx: hipCtx_t, apiVersion: *mut ::std::os::raw::c_int) + -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get Cache configuration for a specific function.\n\n @param [out] cacheConfig Cache configuration\n\n @return #hipSuccess\n\n @warning AMD devices and some Nvidia GPUS do not support reconfigurable cache. This hint is\n ignored on those architectures.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetCacheConfig(cacheConfig: *mut hipFuncCache_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set L1/Shared cache partition.\n\n @param [in] cacheConfig Cache configuration to set\n\n @return #hipSuccess\n\n @warning AMD devices and some Nvidia GPUS do not support reconfigurable cache. This hint is\n ignored on those architectures.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxSetCacheConfig(cacheConfig: hipFuncCache_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set Shared memory bank configuration.\n\n @param [in] config Shared memory configuration to set\n\n @return #hipSuccess\n\n @warning AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxSetSharedMemConfig(config: hipSharedMemConfig) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get Shared memory bank configuration.\n\n @param [out] pConfig Pointer of shared memory configuration\n\n @return #hipSuccess\n\n @warning AMD devices and some Nvidia GPUS do not support shared cache banking, and the hint is\n ignored on those architectures.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetSharedMemConfig(pConfig: *mut hipSharedMemConfig) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Blocks until the default context has completed all preceding requested tasks.\n\n @return #hipSuccess\n\n @warning This function waits for all streams on the default context to complete execution, and\n then returns.\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxSynchronize() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return flags used for creating default context.\n\n @param [out] flags Pointer of flags\n\n @returns #hipSuccess\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxPopCurrent, hipCtxGetCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxGetFlags(flags: *mut ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enables direct access to memory allocations in a peer context.\n\n Memory which already allocated on peer device will be mapped into the address space of the\n current device. In addition, all future memory allocations on peerDeviceId will be mapped into\n the address space of the current device when the memory is allocated. The peer memory remains\n accessible from the current device until a call to hipDeviceDisablePeerAccess or hipDeviceReset.\n\n\n @param [in] peerCtx Peer context\n @param [in] flags flags, need to set as 0\n\n @returns #hipSuccess, #hipErrorInvalidDevice, #hipErrorInvalidValue,\n #hipErrorPeerAccessAlreadyEnabled\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n @warning PeerToPeer support is experimental.\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxEnablePeerAccess(peerCtx: hipCtx_t, flags: ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Disable direct access from current context's virtual address space to memory allocations\n physically located on a peer context.Disables direct access to memory allocations in a peer\n context and unregisters any registered allocations.\n\n Returns #hipErrorPeerAccessNotEnabled if direct access to memory on peerDevice has not yet been\n enabled from the current device.\n\n @param [in] peerCtx Peer context to be disabled\n\n @returns #hipSuccess, #hipErrorPeerAccessNotEnabled\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n @warning PeerToPeer support is experimental.\n\n @warning : This HIP API is deprecated."] + pub fn hipCtxDisablePeerAccess(peerCtx: hipCtx_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n @brief Get the state of the primary context.\n\n @param [in] dev Device to get primary context flags for\n @param [out] flags Pointer to store flags\n @param [out] active Pointer to store context state; 0 = inactive, 1 = active\n\n @returns #hipSuccess\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice"] + pub fn hipDevicePrimaryCtxGetState( + dev: hipDevice_t, + flags: *mut ::std::os::raw::c_uint, + active: *mut ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Release the primary context on the GPU.\n\n @param [in] dev Device which primary context is released\n\n @returns #hipSuccess\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice\n @warning This function return #hipSuccess though doesn't release the primaryCtx by design on\n HIP/HCC path."] + pub fn hipDevicePrimaryCtxRelease(dev: hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retain the primary context on the GPU.\n\nhipError_t hipDevicePrimaryCtxRetain(hipCtx_t* pctx, hipDevice_t dev);\n @param [out] pctx Returned context handle of the new context\n @param [in] dev Device which primary context is released\n\n @returns #hipSuccess\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice"] + pub fn hipDevicePrimaryCtxRetain(pctx: *mut hipCtx_t, dev: hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Resets the primary context on the GPU.\n\n @param [in] dev Device which primary context is reset\n\n @returns #hipSuccess\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice"] + pub fn hipDevicePrimaryCtxReset(dev: hipDevice_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set flags for the primary context.\n\n @param [in] dev Device for which the primary context flags are set\n @param [in] flags New flags for the device\n\n @returns #hipSuccess, #hipErrorContextAlreadyInUse\n\n @see hipCtxCreate, hipCtxDestroy, hipCtxGetFlags, hipCtxPopCurrent, hipCtxGetCurrent,\n hipCtxSetCurrent, hipCtxPushCurrent, hipCtxSetCacheConfig, hipCtxSynchronize, hipCtxGetDevice"] + pub fn hipDevicePrimaryCtxSetFlags( + dev: hipDevice_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n\n @defgroup Module Module Management\n @{\n @ingroup API\n This section describes the module management functions of HIP runtime API.\n\n/\n/**\n @brief Loads code object from file into a module the currrent context.\n\n @param [in] fname Filename of code object to load\n\n @param [out] module Module\n\n @warning File/memory resources allocated in this function are released only in hipModuleUnload.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidContext, #hipErrorFileNotFound,\n #hipErrorOutOfMemory, #hipErrorSharedObjectInitFailed, #hipErrorNotInitialized\n"] + pub fn hipModuleLoad( + module: *mut hipModule_t, + fname: *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Frees the module\n\n @param [in] module Module to free\n\n @returns #hipSuccess, #hipErrorInvalidResourceHandle\n\n The module is freed, and the code objects associated with it are destroyed."] + pub fn hipModuleUnload(module: hipModule_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Function with kname will be extracted if present in module\n\n @param [in] module Module to get function from\n @param [in] kname Pointer to the name of function\n @param [out] function Pointer to function handle\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidContext, #hipErrorNotInitialized,\n #hipErrorNotFound,"] + pub fn hipModuleGetFunction( + function: *mut hipFunction_t, + module: hipModule_t, + kname: *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Find out attributes for a given function.\n\n @param [out] attr Attributes of funtion\n @param [in] func Pointer to the function handle\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDeviceFunction"] + pub fn hipFuncGetAttributes( + attr: *mut hipFuncAttributes, + func: *const ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Find out a specific attribute for a given function.\n\n @param [out] value Pointer to the value\n @param [in] attrib Attributes of the given funtion\n @param [in] hfunc Function to get attributes from\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDeviceFunction"] + pub fn hipFuncGetAttribute( + value: *mut ::std::os::raw::c_int, + attrib: hipFunction_attribute, + hfunc: hipFunction_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief returns the handle of the texture reference with the name from the module.\n\n @param [in] hmod Module\n @param [in] name Pointer of name of texture reference\n @param [out] texRef Pointer of texture reference\n\n @returns #hipSuccess, #hipErrorNotInitialized, #hipErrorNotFound, #hipErrorInvalidValue"] + pub fn hipModuleGetTexRef( + texRef: *mut *mut textureReference, + hmod: hipModule_t, + name: *const ::std::os::raw::c_char, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief builds module from code object which resides in host memory. Image is pointer to that\n location.\n\n @param [in] image\n @param [out] module\n\n @returns hipSuccess, hipErrorNotInitialized, hipErrorOutOfMemory, hipErrorNotInitialized"] + pub fn hipModuleLoadData( + module: *mut hipModule_t, + image: *const ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief builds module from code object which resides in host memory. Image is pointer to that\n location. Options are not used. hipModuleLoadData is called.\n\n @param [in] image\n @param [out] module\n @param [in] number of options\n @param [in] options for JIT\n @param [in] option values for JIT\n\n @returns hipSuccess, hipErrorNotInitialized, hipErrorOutOfMemory, hipErrorNotInitialized"] + pub fn hipModuleLoadDataEx( + module: *mut hipModule_t, + image: *const ::std::os::raw::c_void, + numOptions: ::std::os::raw::c_uint, + options: *mut hipJitOption, + optionValues: *mut *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief launches kernel f with launch parameters and shared memory on stream with arguments passed\n to kernelparams or extra\n\n @param [in] f Kernel to launch.\n @param [in] gridDimX X grid dimension specified as multiple of blockDimX.\n @param [in] gridDimY Y grid dimension specified as multiple of blockDimY.\n @param [in] gridDimZ Z grid dimension specified as multiple of blockDimZ.\n @param [in] blockDimX X block dimensions specified in work-items\n @param [in] blockDimY Y grid dimension specified in work-items\n @param [in] blockDimZ Z grid dimension specified in work-items\n @param [in] sharedMemBytes Amount of dynamic shared memory to allocate for this kernel. The\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream Stream where the kernel should be dispatched. May be 0, in which case th\n default stream is used with associated synchronization rules.\n @param [in] kernelParams\n @param [in] extra Pointer to kernel arguments. These are passed directly to the kernel and\n must be in the memory layout and alignment expected by the kernel.\n All passed arguments must be naturally aligned according to their type. The memory address of each\n argument should be a multiple of its size in bytes. Please refer to hip_porting_driver_api.md\n for sample usage.\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32. So gridDim.x * blockDim.x, gridDim.y * blockDim.y\n and gridDim.z * blockDim.z are always less than 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue"] + pub fn hipModuleLaunchKernel( + f: hipFunction_t, + 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, + stream: hipStream_t, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief launches kernel f with launch parameters and shared memory on stream with arguments passed\n to kernelParams, where thread blocks can cooperate and synchronize as they execute\n\n @param [in] f Kernel to launch.\n @param [in] gridDimX X grid dimension specified as multiple of blockDimX.\n @param [in] gridDimY Y grid dimension specified as multiple of blockDimY.\n @param [in] gridDimZ Z grid dimension specified as multiple of blockDimZ.\n @param [in] blockDimX X block dimension specified in work-items.\n @param [in] blockDimY Y block dimension specified in work-items.\n @param [in] blockDimZ Z block dimension specified in work-items.\n @param [in] sharedMemBytes Amount of dynamic shared memory to allocate for this kernel. The\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream Stream where the kernel should be dispatched. May be 0,\n in which case the default stream is used with associated synchronization rules.\n @param [in] kernelParams A list of kernel arguments.\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipErrorDeinitialized, hipErrorNotInitialized, hipErrorInvalidContext,\n hipErrorInvalidHandle, hipErrorInvalidImage, hipErrorInvalidValue, hipInvalidDevice,\n hipErrorInvalidConfiguration, hipErrorLaunchFailure, hipErrorLaunchOutOfResources,\n hipErrorLaunchTimeOut, hipErrorCooperativeLaunchTooLarge, hipErrorSharedObjectInitFailed"] + pub fn hipModuleLaunchCooperativeKernel( + f: hipFunction_t, + 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, + stream: hipStream_t, + kernelParams: *mut *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Launches kernels on multiple devices where thread blocks can cooperate and\n synchronize as they execute.\n\n @param [in] launchParamsList List of launch parameters, one per device.\n @param [in] numDevices Size of the launchParamsList array.\n @param [in] flags Flags to control launch behavior.\n\n @returns hipSuccess, hipErrorDeinitialized, hipErrorNotInitialized, hipErrorInvalidContext,\n hipErrorInvalidHandle, hipErrorInvalidImage, hipErrorInvalidValue, hipInvalidDevice,\n hipErrorInvalidConfiguration, hipErrorInvalidResourceHandle, hipErrorLaunchFailure,\n hipErrorLaunchOutOfResources, hipErrorLaunchTimeOut, hipErrorCooperativeLaunchTooLarge,\n hipErrorSharedObjectInitFailed"] + pub fn hipModuleLaunchCooperativeKernelMultiDevice( + launchParamsList: *mut hipFunctionLaunchParams, + numDevices: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief launches kernel f with launch parameters and shared memory on stream with arguments passed\n to kernelparams or extra, where thread blocks can cooperate and synchronize as they execute\n\n @param [in] f Kernel to launch.\n @param [in] gridDim Grid dimensions specified as multiple of blockDim.\n @param [in] blockDim Block dimensions specified in work-items\n @param [in] kernelParams A list of kernel arguments\n @param [in] sharedMemBytes Amount of dynamic shared memory to allocate for this kernel. The\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream Stream where the kernel should be dispatched. May be 0, in which case th\n default stream is used with associated synchronization rules.\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue, hipErrorCooperativeLaunchTooLarge"] + pub fn hipLaunchCooperativeKernel( + f: *const ::std::os::raw::c_void, + gridDim: dim3, + blockDimX: dim3, + kernelParams: *mut *mut ::std::os::raw::c_void, + sharedMemBytes: ::std::os::raw::c_uint, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Launches kernels on multiple devices where thread blocks can cooperate and\n synchronize as they execute.\n\n @param [in] launchParamsList List of launch parameters, one per device.\n @param [in] numDevices Size of the launchParamsList array.\n @param [in] flags Flags to control launch behavior.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue, hipErrorCooperativeLaunchTooLarge"] + pub fn hipLaunchCooperativeKernelMultiDevice( + launchParamsList: *mut hipLaunchParams, + numDevices: ::std::os::raw::c_int, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Launches kernels on multiple devices and guarantees all specified kernels are dispatched\n on respective streams before enqueuing any other work on the specified streams from any other threads\n\n\n @param [in] hipLaunchParams List of launch parameters, one per device.\n @param [in] numDevices Size of the launchParamsList array.\n @param [in] flags Flags to control launch behavior.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue"] + pub fn hipExtLaunchMultiKernelMultiDevice( + launchParamsList: *mut hipLaunchParams, + numDevices: ::std::os::raw::c_int, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = "-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup Occupancy Occupancy\n @{\n This section describes the occupancy functions of HIP runtime API.\n\n/\n/**\n @brief determine the grid and block sizes to achieves maximum occupancy for a kernel\n\n @param [out] gridSize minimum grid size for maximum potential occupancy\n @param [out] blockSize block size for maximum potential occupancy\n @param [in] f kernel function for which occupancy is calulated\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block\n @param [in] blockSizeLimit the maximum block size for the kernel, use 0 for no limit\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorInvalidValue"] + pub fn hipModuleOccupancyMaxPotentialBlockSize( + gridSize: *mut ::std::os::raw::c_int, + blockSize: *mut ::std::os::raw::c_int, + f: hipFunction_t, + dynSharedMemPerBlk: usize, + blockSizeLimit: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief determine the grid and block sizes to achieves maximum occupancy for a kernel\n\n @param [out] gridSize minimum grid size for maximum potential occupancy\n @param [out] blockSize block size for maximum potential occupancy\n @param [in] f kernel function for which occupancy is calulated\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block\n @param [in] blockSizeLimit the maximum block size for the kernel, use 0 for no limit\n @param [in] flags Extra flags for occupancy calculation (only default supported)\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorInvalidValue"] + pub fn hipModuleOccupancyMaxPotentialBlockSizeWithFlags( + gridSize: *mut ::std::os::raw::c_int, + blockSize: *mut ::std::os::raw::c_int, + f: hipFunction_t, + dynSharedMemPerBlk: usize, + blockSizeLimit: ::std::os::raw::c_int, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns occupancy for a device function.\n\n @param [out] numBlocks Returned occupancy\n @param [in] func Kernel function (hipFunction) for which occupancy is calulated\n @param [in] blockSize Block size the kernel is intended to be launched with\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block"] + pub fn hipModuleOccupancyMaxActiveBlocksPerMultiprocessor( + numBlocks: *mut ::std::os::raw::c_int, + f: hipFunction_t, + blockSize: ::std::os::raw::c_int, + dynSharedMemPerBlk: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns occupancy for a device function.\n\n @param [out] numBlocks Returned occupancy\n @param [in] f Kernel function(hipFunction_t) for which occupancy is calulated\n @param [in] blockSize Block size the kernel is intended to be launched with\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block\n @param [in] flags Extra flags for occupancy calculation (only default supported)"] + pub fn hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( + numBlocks: *mut ::std::os::raw::c_int, + f: hipFunction_t, + blockSize: ::std::os::raw::c_int, + dynSharedMemPerBlk: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns occupancy for a device function.\n\n @param [out] numBlocks Returned occupancy\n @param [in] func Kernel function for which occupancy is calulated\n @param [in] blockSize Block size the kernel is intended to be launched with\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block"] + pub fn hipOccupancyMaxActiveBlocksPerMultiprocessor( + numBlocks: *mut ::std::os::raw::c_int, + f: *const ::std::os::raw::c_void, + blockSize: ::std::os::raw::c_int, + dynSharedMemPerBlk: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns occupancy for a device function.\n\n @param [out] numBlocks Returned occupancy\n @param [in] f Kernel function for which occupancy is calulated\n @param [in] blockSize Block size the kernel is intended to be launched with\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block\n @param [in] flags Extra flags for occupancy calculation (currently ignored)"] + pub fn hipOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( + numBlocks: *mut ::std::os::raw::c_int, + f: *const ::std::os::raw::c_void, + blockSize: ::std::os::raw::c_int, + dynSharedMemPerBlk: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief determine the grid and block sizes to achieves maximum occupancy for a kernel\n\n @param [out] gridSize minimum grid size for maximum potential occupancy\n @param [out] blockSize block size for maximum potential occupancy\n @param [in] f kernel function for which occupancy is calulated\n @param [in] dynSharedMemPerBlk dynamic shared memory usage (in bytes) intended for each block\n @param [in] blockSizeLimit the maximum block size for the kernel, use 0 for no limit\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorInvalidValue"] + pub fn hipOccupancyMaxPotentialBlockSize( + gridSize: *mut ::std::os::raw::c_int, + blockSize: *mut ::std::os::raw::c_int, + f: *const ::std::os::raw::c_void, + dynSharedMemPerBlk: usize, + blockSizeLimit: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Start recording of profiling information.\n When using this API, start the profiler with profiling disabled. (--startdisabled)\n @warning hipProfilerStart API is deprecated, use roctracer/rocTX instead."] + pub fn hipProfilerStart() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Stop recording of profiling information.\n When using this API, start the profiler with profiling disabled. (--startdisabled)\n @warning hipProfilerStop API is deprecated, use roctracer/rocTX instead."] + pub fn hipProfilerStop() -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @}\n/\n/**\n-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup Clang Launch API to support the triple-chevron syntax\n @{\n This section describes the API to support the triple-chevron syntax.\n/\n/**\n @brief Configure a kernel launch.\n\n @param [in] gridDim grid dimension specified as multiple of blockDim.\n @param [in] blockDim block dimensions specified in work-items\n @param [in] sharedMem Amount of dynamic shared memory to allocate for this kernel. The\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream Stream where the kernel should be dispatched. May be 0, in which case the\n default stream is used with associated synchronization rules.\n\n Please note, HIP does not support kernel launch with total work items defined in dimension with\n size gridDim x blockDim >= 2^32.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue\n"] + pub fn hipConfigureCall( + gridDim: dim3, + blockDim: dim3, + sharedMem: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set a kernel argument.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue\n\n @param [in] arg Pointer the argument in host memory.\n @param [in] size Size of the argument.\n @param [in] offset Offset of the argument on the argument stack.\n"] + pub fn hipSetupArgument( + arg: *const ::std::os::raw::c_void, + size: usize, + offset: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Launch a kernel.\n\n @param [in] func Kernel to launch.\n\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue\n"] + pub fn hipLaunchByPtr(func: *const ::std::os::raw::c_void) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief C compliant kernel launch API\n\n @param [in] function_address - kernel stub function pointer.\n @param [in] numBlocks - number of blocks\n @param [in] dimBlocks - dimension of a block\n @param [in] args - kernel arguments\n @param [in] sharedMemBytes - Amount of dynamic shared memory to allocate for this kernel. The\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream - Stream where the kernel should be dispatched. May be 0, in which case th\n default stream is used with associated synchronization rules.\n\n @returns #hipSuccess, #hipErrorInvalidValue, hipInvalidDevice\n"] + pub fn hipLaunchKernel( + function_address: *const ::std::os::raw::c_void, + numBlocks: dim3, + dimBlocks: dim3, + args: *mut *mut ::std::os::raw::c_void, + sharedMemBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enqueues a host function call in a stream.\n\n @param [in] stream - stream to enqueue work to.\n @param [in] fn - function to call once operations enqueued preceeding are complete.\n @param [in] userData - User-specified data to be passed to the function.\n @returns #hipSuccess, #hipErrorInvalidResourceHandle, #hipErrorInvalidValue,\n #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipLaunchHostFunc( + stream: hipStream_t, + fn_: hipHostFn_t, + userData: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " Copies memory for 2D arrays.\n\n @param pCopy - Parameters for the memory copy\n\n @returns #hipSuccess, #hipErrorInvalidValue"] + pub fn hipDrvMemcpy2DUnaligned(pCopy: *const hip_Memcpy2D) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Launches kernel from the pointer address, with arguments and shared memory on stream.\n\n @param [in] function_address pointer to the Kernel to launch.\n @param [in] numBlocks number of blocks.\n @param [in] dimBlocks dimension of a block.\n @param [in] args pointer to kernel arguments.\n @param [in] sharedMemBytes Amount of dynamic shared memory to allocate for this kernel.\n HIP-Clang compiler provides support for extern shared declarations.\n @param [in] stream Stream where the kernel should be dispatched.\n May be 0, in which case the default stream is used with associated synchronization rules.\n @param [in] startEvent If non-null, specified event will be updated to track the start time of\n the kernel launch. The event must be created before calling this API.\n @param [in] stopEvent If non-null, specified event will be updated to track the stop time of\n the kernel launch. The event must be created before calling this API.\n @param [in] flags. The value of hipExtAnyOrderLaunch, signifies if kernel can be\n launched in any order.\n @returns hipSuccess, hipInvalidDevice, hipErrorNotInitialized, hipErrorInvalidValue.\n"] + pub fn hipExtLaunchKernel( + function_address: *const ::std::os::raw::c_void, + numBlocks: dim3, + dimBlocks: dim3, + args: *mut *mut ::std::os::raw::c_void, + sharedMemBytes: usize, + stream: hipStream_t, + startEvent: hipEvent_t, + stopEvent: hipEvent_t, + flags: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a texture object.\n\n @param [out] pTexObject pointer to the texture object to create\n @param [in] pResDesc pointer to resource descriptor\n @param [in] pTexDesc pointer to texture descriptor\n @param [in] pResViewDesc pointer to resource view descriptor\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported, #hipErrorOutOfMemory\n\n @note 3D liner filter isn't supported on GFX90A boards, on which the API @p hipCreateTextureObject will\n return hipErrorNotSupported.\n"] + pub fn hipCreateTextureObject( + pTexObject: *mut hipTextureObject_t, + pResDesc: *const hipResourceDesc, + pTexDesc: *const hipTextureDesc, + pResViewDesc: *const hipResourceViewDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys a texture object.\n\n @param [in] textureObject texture object to destroy\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipDestroyTextureObject(textureObject: hipTextureObject_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the channel descriptor in an array.\n\n @param [in] desc pointer to channel format descriptor\n @param [out] array memory array on the device\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetChannelDesc( + desc: *mut hipChannelFormatDesc, + array: hipArray_const_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets resource descriptor for the texture object.\n\n @param [out] pResDesc pointer to resource descriptor\n @param [in] textureObject texture object\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetTextureObjectResourceDesc( + pResDesc: *mut hipResourceDesc, + textureObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets resource view descriptor for the texture object.\n\n @param [out] pResViewDesc pointer to resource view descriptor\n @param [in] textureObject texture object\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetTextureObjectResourceViewDesc( + pResViewDesc: *mut hipResourceViewDesc, + textureObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets texture descriptor for the texture object.\n\n @param [out] pTexDesc pointer to texture descriptor\n @param [in] textureObject texture object\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGetTextureObjectTextureDesc( + pTexDesc: *mut hipTextureDesc, + textureObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a texture object.\n\n @param [out] pTexObject pointer to texture object to create\n @param [in] pResDesc pointer to resource descriptor\n @param [in] pTexDesc pointer to texture descriptor\n @param [in] pResViewDesc pointer to resource view descriptor\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipTexObjectCreate( + pTexObject: *mut hipTextureObject_t, + pResDesc: *const HIP_RESOURCE_DESC, + pTexDesc: *const HIP_TEXTURE_DESC, + pResViewDesc: *const HIP_RESOURCE_VIEW_DESC, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys a texture object.\n\n @param [in] texObject texture object to destroy\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipTexObjectDestroy(texObject: hipTextureObject_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets resource descriptor of a texture object.\n\n @param [out] pResDesc pointer to resource descriptor\n @param [in] texObject texture object\n\n @returns #hipSuccess, #hipErrorNotSupported, #hipErrorInvalidValue\n"] + pub fn hipTexObjectGetResourceDesc( + pResDesc: *mut HIP_RESOURCE_DESC, + texObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets resource view descriptor of a texture object.\n\n @param [out] pResViewDesc pointer to resource view descriptor\n @param [in] texObject texture object\n\n @returns #hipSuccess, #hipErrorNotSupported, #hipErrorInvalidValue\n"] + pub fn hipTexObjectGetResourceViewDesc( + pResViewDesc: *mut HIP_RESOURCE_VIEW_DESC, + texObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets texture descriptor of a texture object.\n\n @param [out] pTexDesc pointer to texture descriptor\n @param [in] texObject texture object\n\n @returns #hipSuccess, #hipErrorNotSupported, #hipErrorInvalidValue\n"] + pub fn hipTexObjectGetTextureDesc( + pTexDesc: *mut HIP_TEXTURE_DESC, + texObject: hipTextureObject_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allocate a mipmapped array on the device.\n\n @param[out] mipmappedArray - Pointer to allocated mipmapped array in device memory\n @param[in] desc - Requested channel format\n @param[in] extent - Requested allocation size (width field in elements)\n @param[in] numLevels - Number of mipmap levels to allocate\n @param[in] flags - Flags for extensions\n\n @return #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryAllocation\n\n @note This API is implemented on Windows, under development on Linux.\n"] + pub fn hipMallocMipmappedArray( + mipmappedArray: *mut hipMipmappedArray_t, + desc: *const hipChannelFormatDesc, + extent: hipExtent, + numLevels: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Frees a mipmapped array on the device.\n\n @param[in] mipmappedArray - Pointer to mipmapped array to free\n\n @return #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Windows, under development on Linux.\n"] + pub fn hipFreeMipmappedArray(mipmappedArray: hipMipmappedArray_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a mipmap level of a HIP mipmapped array.\n\n @param[out] levelArray - Returned mipmap level HIP array\n @param[in] mipmappedArray - HIP mipmapped array\n @param[in] level - Mipmap level\n\n @return #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Windows, under development on Linux.\n"] + pub fn hipGetMipmappedArrayLevel( + levelArray: *mut hipArray_t, + mipmappedArray: hipMipmappedArray_const_t, + level: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a mipmapped array.\n\n @param [out] pHandle pointer to mipmapped array\n @param [in] pMipmappedArrayDesc mipmapped array descriptor\n @param [in] numMipmapLevels mipmap level\n\n @returns #hipSuccess, #hipErrorNotSupported, #hipErrorInvalidValue\n\n @note This API is implemented on Windows, under development on Linux."] + pub fn hipMipmappedArrayCreate( + pHandle: *mut hipMipmappedArray_t, + pMipmappedArrayDesc: *mut HIP_ARRAY3D_DESCRIPTOR, + numMipmapLevels: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy a mipmapped array.\n\n @param [out] hMipmappedArray pointer to mipmapped array to destroy\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Windows, under development on Linux.\n"] + pub fn hipMipmappedArrayDestroy(hMipmappedArray: hipMipmappedArray_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get a mipmapped array on a mipmapped level.\n\n @param [in] pLevelArray Pointer of array\n @param [out] hMipMappedArray Pointer of mipmapped array on the requested mipmap level\n @param [out] level Mipmap level\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note This API is implemented on Windows, under development on Linux.\n"] + pub fn hipMipmappedArrayGetLevel( + pLevelArray: *mut hipArray_t, + hMipMappedArray: hipMipmappedArray_t, + level: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds a mipmapped array to a texture.\n\n @param [in] tex pointer to the texture reference to bind\n @param [in] mipmappedArray memory mipmapped array on the device\n @param [in] desc opointer to the channel format\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipBindTextureToMipmappedArray( + tex: *const textureReference, + mipmappedArray: hipMipmappedArray_const_t, + desc: *const hipChannelFormatDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the texture reference related with the symbol.\n\n @param [out] texref texture reference\n @param [in] symbol pointer to the symbol related with the texture for the reference\n\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning This API is deprecated.\n"] + pub fn hipGetTextureReference( + texref: *mut *const textureReference, + symbol: *const ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets address mode for a texture reference.\n\n @param [in] texRef texture reference.\n @param [in] dim Dimension of the texture.\n @param [in] am Value of the texture address mode.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetAddressMode( + texRef: *mut textureReference, + dim: ::std::os::raw::c_int, + am: hipTextureAddressMode, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds an array as a texture reference.\n\n @param [in] tex Pointer texture reference.\n @param [in] array Array to bind.\n @param [in] flags Flags should be set as HIP_TRSA_OVERRIDE_FORMAT, as a valid value.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetArray( + tex: *mut textureReference, + array: hipArray_const_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set filter mode for a texture reference.\n\n @param [in] texRef Pointer texture reference.\n @param [in] fm Value of texture filter mode.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetFilterMode( + texRef: *mut textureReference, + fm: hipTextureFilterMode, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set flags for a texture reference.\n\n @param [in] texRef Pointer texture reference.\n @param [in] Flags Value of flags.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetFlags( + texRef: *mut textureReference, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set format for a texture reference.\n\n @param [in] texRef Pointer texture reference.\n @param [in] fmt Value of format.\n @param [in] NumPackedComponents Number of components per array.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetFormat( + texRef: *mut textureReference, + fmt: hipArray_Format, + NumPackedComponents: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds a memory area to a texture.\n\n @param [in] offset Offset in bytes.\n @param [in] tex Texture to bind.\n @param [in] devPtr Pointer of memory on the device.\n @param [in] desc Pointer of channel format descriptor.\n @param [in] size Size of memory in bites.\n\n @warning This API is deprecated.\n"] + pub fn hipBindTexture( + offset: *mut usize, + tex: *const textureReference, + devPtr: *const ::std::os::raw::c_void, + desc: *const hipChannelFormatDesc, + size: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds a 2D memory area to a texture.\n\n @param [in] offset Offset in bytes.\n @param [in] tex Texture to bind.\n @param [in] devPtr Pointer of 2D memory area on the device.\n @param [in] desc Pointer of channel format descriptor.\n @param [in] width Width in texel units.\n @param [in] height Height in texel units.\n @param [in] pitch Pitch in bytes.\n\n @warning This API is deprecated.\n"] + pub fn hipBindTexture2D( + offset: *mut usize, + tex: *const textureReference, + devPtr: *const ::std::os::raw::c_void, + desc: *const hipChannelFormatDesc, + width: usize, + height: usize, + pitch: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds a memory area to a texture.\n\n @param [in] tex Pointer of texture reference.\n @param [in] array Array to bind.\n @param [in] desc Pointer of channel format descriptor.\n\n @warning This API is deprecated.\n"] + pub fn hipBindTextureToArray( + tex: *const textureReference, + array: hipArray_const_t, + desc: *const hipChannelFormatDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the offset of the alignment in a texture.\n\n @param [in] offset Offset in bytes.\n @param [in] texref Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipGetTextureAlignmentOffset( + offset: *mut usize, + texref: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Unbinds a texture.\n\n @param [in] tex Texture to unbind.\n\n @warning This API is deprecated.\n"] + pub fn hipUnbindTexture(tex: *const textureReference) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the the address for a texture reference.\n\n @param [out] dev_ptr Pointer of device address.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetAddress( + dev_ptr: *mut hipDeviceptr_t, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the address mode for a texture reference.\n\n @param [out] pam Pointer of address mode.\n @param [in] texRef Pointer of texture reference.\n @param [in] dim Dimension.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetAddressMode( + pam: *mut hipTextureAddressMode, + texRef: *const textureReference, + dim: ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets filter mode for a texture reference.\n\n @param [out] pfm Pointer of filter mode.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetFilterMode( + pfm: *mut hipTextureFilterMode, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets flags for a texture reference.\n\n @param [out] pFlags Pointer of flags.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetFlags( + pFlags: *mut ::std::os::raw::c_uint, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets texture format for a texture reference.\n\n @param [out] pFormat Pointer of the format.\n @param [out] pNumChannels Pointer of number of channels.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetFormat( + pFormat: *mut hipArray_Format, + pNumChannels: *mut ::std::os::raw::c_int, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the maximum anisotropy for a texture reference.\n\n @param [out] pmaxAnsio Pointer of the maximum anisotropy.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetMaxAnisotropy( + pmaxAnsio: *mut ::std::os::raw::c_int, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the mipmap filter mode for a texture reference.\n\n @param [out] pfm Pointer of the mipmap filter mode.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetMipmapFilterMode( + pfm: *mut hipTextureFilterMode, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the mipmap level bias for a texture reference.\n\n @param [out] pbias Pointer of the mipmap level bias.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetMipmapLevelBias( + pbias: *mut f32, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the minimum and maximum mipmap level clamps for a texture reference.\n\n @param [out] pminMipmapLevelClamp Pointer of the minimum mipmap level clamp.\n @param [out] pmaxMipmapLevelClamp Pointer of the maximum mipmap level clamp.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetMipmapLevelClamp( + pminMipmapLevelClamp: *mut f32, + pmaxMipmapLevelClamp: *mut f32, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the mipmapped array bound to a texture reference.\n\n @param [out] pArray Pointer of the mipmapped array.\n @param [in] texRef Pointer of texture reference.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefGetMipMappedArray( + pArray: *mut hipMipmappedArray_t, + texRef: *const textureReference, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets an bound address for a texture reference.\n\n @param [out] ByteOffset Pointer of the offset in bytes.\n @param [in] texRef Pointer of texture reference.\n @param [in] dptr Pointer of device address to bind.\n @param [in] bytes Size in bytes.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetAddress( + ByteOffset: *mut usize, + texRef: *mut textureReference, + dptr: hipDeviceptr_t, + bytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set a bind an address as a 2D texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [in] desc Pointer of array descriptor.\n @param [in] dptr Pointer of device address to bind.\n @param [in] Pitch Pitch in bytes.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetAddress2D( + texRef: *mut textureReference, + desc: *const HIP_ARRAY_DESCRIPTOR, + dptr: hipDeviceptr_t, + Pitch: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the maximum anisotropy for a texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [out] maxAniso Value of the maximum anisotropy.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetMaxAnisotropy( + texRef: *mut textureReference, + maxAniso: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets border color for a texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [in] pBorderColor Pointer of border color.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetBorderColor( + texRef: *mut textureReference, + pBorderColor: *mut f32, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets mipmap filter mode for a texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [in] fm Value of filter mode.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetMipmapFilterMode( + texRef: *mut textureReference, + fm: hipTextureFilterMode, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets mipmap level bias for a texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [in] bias Value of mipmap bias.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetMipmapLevelBias(texRef: *mut textureReference, bias: f32) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets mipmap level clamp for a texture reference.\n\n @param [in] texRef Pointer of texture reference.\n @param [in] minMipMapLevelClamp Value of minimum mipmap level clamp.\n @param [in] maxMipMapLevelClamp Value of maximum mipmap level clamp.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetMipmapLevelClamp( + texRef: *mut textureReference, + minMipMapLevelClamp: f32, + maxMipMapLevelClamp: f32, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Binds mipmapped array to a texture reference.\n\n @param [in] texRef Pointer of texture reference to bind.\n @param [in] mipmappedArray Pointer of mipmapped array to bind.\n @param [in] Flags Flags should be set as HIP_TRSA_OVERRIDE_FORMAT, as a valid value.\n\n @warning This API is deprecated.\n"] + pub fn hipTexRefSetMipmappedArray( + texRef: *mut textureReference, + mipmappedArray: *mut hipMipmappedArray, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[doc = " @defgroup Callback Callback Activity APIs\n @{\n This section describes the callback/Activity of HIP runtime API.\n/\n/**\n @brief Returns HIP API name by ID.\n\n @param [in] id ID of HIP API\n\n @returns hipSuccess, hipErrorInvalidValue\n"] + pub fn hipApiName(id: u32) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Returns kernel name reference by function name.\n\n @param [in] f name of function\n\n @returns hipSuccess, hipErrorInvalidValue\n"] + pub fn hipKernelNameRef(f: hipFunction_t) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Retrives kernel for a given host pointer, unless stated otherwise.\n\n @param [in] hostFunction Pointer of host function.\n @param [in] stream stream the kernel is executed on.\n\n @returns hipSuccess, hipErrorInvalidValue\n"] + pub fn hipKernelNameRefByPtr( + hostFunction: *const ::std::os::raw::c_void, + stream: hipStream_t, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " @brief Returns device ID on the stream.\n\n @param [in] stream stream of device executed on.\n\n @returns hipSuccess, hipErrorInvalidValue\n"] + pub fn hipGetStreamDeviceId(stream: hipStream_t) -> ::std::os::raw::c_int; +} +extern "C" { + #[must_use] + #[doc = " @brief Begins graph capture on a stream.\n\n @param [in] stream - Stream to initiate capture.\n @param [in] mode - Controls the interaction of this capture sequence with other API calls that\n are not safe.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamBeginCapture(stream: hipStream_t, mode: hipStreamCaptureMode) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Ends capture on a stream, returning the captured graph.\n\n @param [in] stream - Stream to end capture.\n @param [out] pGraph - returns the graph captured.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamEndCapture(stream: hipStream_t, pGraph: *mut hipGraph_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get capture status of a stream.\n\n @param [in] stream - Stream under capture.\n @param [out] pCaptureStatus - returns current status of the capture.\n @param [out] pId - unique ID of the capture.\n\n @returns #hipSuccess, #hipErrorStreamCaptureImplicit\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamGetCaptureInfo( + stream: hipStream_t, + pCaptureStatus: *mut hipStreamCaptureStatus, + pId: *mut ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get stream's capture state\n\n @param [in] stream - Stream under capture.\n @param [out] captureStatus_out - returns current status of the capture.\n @param [out] id_out - unique ID of the capture.\n @param [in] graph_out - returns the graph being captured into.\n @param [out] dependencies_out - returns pointer to an array of nodes.\n @param [out] numDependencies_out - returns size of the array returned in dependencies_out.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorStreamCaptureImplicit\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamGetCaptureInfo_v2( + stream: hipStream_t, + captureStatus_out: *mut hipStreamCaptureStatus, + id_out: *mut ::std::os::raw::c_ulonglong, + graph_out: *mut hipGraph_t, + dependencies_out: *mut *const hipGraphNode_t, + numDependencies_out: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get stream's capture state\n\n @param [in] stream - Stream under capture.\n @param [out] pCaptureStatus - returns current status of the capture.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorStreamCaptureImplicit\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamIsCapturing( + stream: hipStream_t, + pCaptureStatus: *mut hipStreamCaptureStatus, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Update the set of dependencies in a capturing stream\n\n @param [in] stream - Stream under capture.\n @param [in] dependencies - pointer to an array of nodes to Add/Replace.\n @param [in] numDependencies - size of the array in dependencies.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorIllegalState\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipStreamUpdateCaptureDependencies( + stream: hipStream_t, + dependencies: *mut hipGraphNode_t, + numDependencies: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Swaps the stream capture mode of a thread.\n\n @param [in] mode - Pointer to mode value to swap with the current mode\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipThreadExchangeStreamCaptureMode(mode: *mut hipStreamCaptureMode) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a graph\n\n @param [out] pGraph - pointer to graph to create.\n @param [in] flags - flags for graph creation, must be 0.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryAllocation\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphCreate(pGraph: *mut hipGraph_t, flags: ::std::os::raw::c_uint) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys a graph\n\n @param [in] graph - instance of graph to destroy.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphDestroy(graph: hipGraph_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Adds dependency edges to a graph.\n\n @param [in] graph - instance of the graph to add dependencies.\n @param [in] from - pointer to the graph nodes with dependenties to add from.\n @param [in] to - pointer to the graph nodes to add dependenties to.\n @param [in] numDependencies - the number of dependencies to add.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphAddDependencies( + graph: hipGraph_t, + from: *const hipGraphNode_t, + to: *const hipGraphNode_t, + numDependencies: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Removes dependency edges from a graph.\n\n @param [in] graph - instance of the graph to remove dependencies.\n @param [in] from - Array of nodes that provide the dependencies.\n @param [in] to - Array of dependent nodes.\n @param [in] numDependencies - the number of dependencies to remove.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphRemoveDependencies( + graph: hipGraph_t, + from: *const hipGraphNode_t, + to: *const hipGraphNode_t, + numDependencies: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a graph's dependency edges.\n\n @param [in] graph - instance of the graph to get the edges from.\n @param [out] from - pointer to the graph nodes to return edge endpoints.\n @param [out] to - pointer to the graph nodes to return edge endpoints.\n @param [out] numEdges - returns number of edges.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n from and to may both be NULL, in which case this function only returns the number of edges in\n numEdges. Otherwise, numEdges entries will be filled in. If numEdges is higher than the actual\n number of edges, the remaining entries in from and to will be set to NULL, and the number of\n edges actually returned will be written to numEdges\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphGetEdges( + graph: hipGraph_t, + from: *mut hipGraphNode_t, + to: *mut hipGraphNode_t, + numEdges: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns graph nodes.\n\n @param [in] graph - instance of graph to get the nodes.\n @param [out] nodes - pointer to return the graph nodes.\n @param [out] numNodes - returns number of graph nodes.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n nodes may be NULL, in which case this function will return the number of nodes in numNodes.\n Otherwise, numNodes entries will be filled in. If numNodes is higher than the actual number of\n nodes, the remaining entries in nodes will be set to NULL, and the number of nodes actually\n obtained will be returned in numNodes.\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphGetNodes( + graph: hipGraph_t, + nodes: *mut hipGraphNode_t, + numNodes: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns graph's root nodes.\n\n @param [in] graph - instance of the graph to get the nodes.\n @param [out] pRootNodes - pointer to return the graph's root nodes.\n @param [out] pNumRootNodes - returns the number of graph's root nodes.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n pRootNodes may be NULL, in which case this function will return the number of root nodes in\n pNumRootNodes. Otherwise, pNumRootNodes entries will be filled in. If pNumRootNodes is higher\n than the actual number of root nodes, the remaining entries in pRootNodes will be set to NULL,\n and the number of nodes actually obtained will be returned in pNumRootNodes.\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphGetRootNodes( + graph: hipGraph_t, + pRootNodes: *mut hipGraphNode_t, + pNumRootNodes: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a node's dependencies.\n\n @param [in] node - graph node to get the dependencies from.\n @param [out] pDependencies - pointer to to return the dependencies.\n @param [out] pNumDependencies - returns the number of graph node dependencies.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n pDependencies may be NULL, in which case this function will return the number of dependencies in\n pNumDependencies. Otherwise, pNumDependencies entries will be filled in. If pNumDependencies is\n higher than the actual number of dependencies, the remaining entries in pDependencies will be set\n to NULL, and the number of nodes actually obtained will be returned in pNumDependencies.\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphNodeGetDependencies( + node: hipGraphNode_t, + pDependencies: *mut hipGraphNode_t, + pNumDependencies: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a node's dependent nodes.\n\n @param [in] node - graph node to get the Dependent nodes from.\n @param [out] pDependentNodes - pointer to return the graph dependent nodes.\n @param [out] pNumDependentNodes - returns the number of graph node dependent nodes.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n DependentNodes may be NULL, in which case this function will return the number of dependent nodes\n in pNumDependentNodes. Otherwise, pNumDependentNodes entries will be filled in. If\n pNumDependentNodes is higher than the actual number of dependent nodes, the remaining entries in\n pDependentNodes will be set to NULL, and the number of nodes actually obtained will be returned\n in pNumDependentNodes.\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphNodeGetDependentNodes( + node: hipGraphNode_t, + pDependentNodes: *mut hipGraphNode_t, + pNumDependentNodes: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a node's type.\n\n @param [in] node - instance of the graph to add dependencies.\n @param [out] pType - pointer to the return the type\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphNodeGetType(node: hipGraphNode_t, pType: *mut hipGraphNodeType) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Remove a node from the graph.\n\n @param [in] node - graph node to remove\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphDestroyNode(node: hipGraphNode_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Clones a graph.\n\n @param [out] pGraphClone - Returns newly created cloned graph.\n @param [in] originalGraph - original graph to clone from.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorMemoryAllocation\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphClone(pGraphClone: *mut hipGraph_t, originalGraph: hipGraph_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Finds a cloned version of a node.\n\n @param [out] pNode - Returns the cloned node.\n @param [in] originalNode - original node handle.\n @param [in] clonedGraph - Cloned graph to query.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphNodeFindInClone( + pNode: *mut hipGraphNode_t, + originalNode: hipGraphNode_t, + clonedGraph: hipGraph_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an executable graph from a graph\n\n @param [out] pGraphExec - pointer to instantiated executable graph that is created.\n @param [in] graph - instance of graph to instantiate.\n @param [out] pErrorNode - pointer to error node in case error occured in graph instantiation,\n it could modify the correponding node.\n @param [out] pLogBuffer - pointer to log buffer.\n @param [out] bufferSize - the size of log buffer.\n\n @returns #hipSuccess, #hipErrorOutOfMemory\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n"] + pub fn hipGraphInstantiate( + pGraphExec: *mut hipGraphExec_t, + graph: hipGraph_t, + pErrorNode: *mut hipGraphNode_t, + pLogBuffer: *mut ::std::os::raw::c_char, + bufferSize: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an executable graph from a graph.\n\n @param [out] pGraphExec - pointer to instantiated executable graph that is created.\n @param [in] graph - instance of graph to instantiate.\n @param [in] flags - Flags to control instantiation.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.It does not support\n any of flag and is behaving as hipGraphInstantiate."] + pub fn hipGraphInstantiateWithFlags( + pGraphExec: *mut hipGraphExec_t, + graph: hipGraph_t, + flags: ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief launches an executable graph in a stream\n\n @param [in] graphExec - instance of executable graph to launch.\n @param [in] stream - instance of stream in which to launch executable graph.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphLaunch(graphExec: hipGraphExec_t, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief uploads an executable graph in a stream\n\n @param [in] graphExec - instance of executable graph to launch.\n @param [in] stream - instance of stream in which to launch executable graph.\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphUpload(graphExec: hipGraphExec_t, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys an executable graph\n\n @param [in] graphExec - instance of executable graph to destry.\n\n @returns #hipSuccess.\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecDestroy(graphExec: hipGraphExec_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Check whether an executable graph can be updated with a graph and perform the update if *\n possible.\n\n @param [in] hGraphExec - instance of executable graph to update.\n @param [in] hGraph - graph that contains the updated parameters.\n @param [in] hErrorNode_out - node which caused the permissibility check to forbid the update.\n @param [in] updateResult_out - Whether the graph update was permitted.\n @returns #hipSuccess, #hipErrorGraphExecUpdateFailure\n\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecUpdate( + hGraphExec: hipGraphExec_t, + hGraph: hipGraph_t, + hErrorNode_out: *mut hipGraphNode_t, + updateResult_out: *mut hipGraphExecUpdateResult, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a kernel execution node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to graph node to create.\n @param [in] graph - instance of graph to add the created node.\n @param [in] pDependencies - pointer to the dependencies on the kernel execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] pNodeParams - pointer to the parameters to the kernel execution node on the GPU.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorInvalidDeviceFunction\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddKernelNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + pNodeParams: *const hipKernelNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets kernel node's parameters.\n\n @param [in] node - instance of the node to get parameters from.\n @param [out] pNodeParams - pointer to the parameters\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphKernelNodeGetParams( + node: hipGraphNode_t, + pNodeParams: *mut hipKernelNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a kernel node's parameters.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - const pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphKernelNodeSetParams( + node: hipGraphNode_t, + pNodeParams: *const hipKernelNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a kernel node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - const pointer to the kernel node parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecKernelNodeSetParams( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + pNodeParams: *const hipKernelNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memcpy node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to graph node to create.\n @param [in] graph - instance of graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memcpy execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] pCopyParams - const pointer to the parameters for the memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemcpyNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + pCopyParams: *const hipMemcpy3DParms, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a memcpy node's parameters.\n\n @param [in] node - instance of the node to get parameters from.\n @param [out] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemcpyNodeGetParams( + node: hipGraphNode_t, + pNodeParams: *mut hipMemcpy3DParms, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a memcpy node's parameters.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - const pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemcpyNodeSetParams( + node: hipGraphNode_t, + pNodeParams: *const hipMemcpy3DParms, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a node attribute.\n\n @param [in] hNode - instance of the node to set parameters to.\n @param [in] attr - the attribute node is set to.\n @param [in] value - const pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphKernelNodeSetAttribute( + hNode: hipGraphNode_t, + attr: hipKernelNodeAttrID, + value: *const hipKernelNodeAttrValue, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a node attribute.\n\n @param [in] hNode - instance of the node to set parameters to.\n @param [in] attr - the attribute node is set to.\n @param [in] value - const pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphKernelNodeGetAttribute( + hNode: hipGraphNode_t, + attr: hipKernelNodeAttrID, + value: *mut hipKernelNodeAttrValue, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a memcpy node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - const pointer to the kernel node parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecMemcpyNodeSetParams( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + pNodeParams: *mut hipMemcpy3DParms, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a 1D memcpy node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to graph node to create.\n @param [in] graph - instance of graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memcpy execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] src - pointer to memory address to the source.\n @param [in] count - the size of the memory to copy.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemcpyNode1D( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a memcpy node's parameters to perform a 1-dimensional copy.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] src - pointer to memory address to the source.\n @param [in] count - the size of the memory to copy.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemcpyNodeSetParams1D( + node: hipGraphNode_t, + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a memcpy node in the given graphExec to perform a 1-dimensional\n copy.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] src - pointer to memory address to the source.\n @param [in] count - the size of the memory to copy.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecMemcpyNodeSetParams1D( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memcpy node to copy from a symbol on the device and adds it to a graph.\n\n @param [out] pGraphNode - pointer to graph node to create.\n @param [in] graph - instance of graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memcpy execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] symbol - Device symbol address.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemcpyNodeFromSymbol( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a memcpy node's parameters to copy from a symbol on the device.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] symbol - Device symbol address.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemcpyNodeSetParamsFromSymbol( + node: hipGraphNode_t, + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a memcpy node in the given graphExec to copy from a symbol on the\n * device.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] dst - pointer to memory address to the destination.\n @param [in] symbol - Device symbol address.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecMemcpyNodeSetParamsFromSymbol( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memcpy node to copy to a symbol on the device and adds it to a graph.\n\n @param [out] pGraphNode - pointer to graph node to create.\n @param [in] graph - instance of graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memcpy execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] symbol - Device symbol address.\n @param [in] src - pointer to memory address of the src.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemcpyNodeToSymbol( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a memcpy node's parameters to copy to a symbol on the device.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] symbol - Device symbol address.\n @param [in] src - pointer to memory address of the src.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemcpyNodeSetParamsToSymbol( + node: hipGraphNode_t, + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a memcpy node in the given graphExec to copy to a symbol on the\n device.\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] symbol - Device symbol address.\n @param [in] src - pointer to memory address of the src.\n @param [in] count - the size of the memory to copy.\n @param [in] offset - Offset from start of symbol in bytes.\n @param [in] kind - the type of memory copy.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecMemcpyNodeSetParamsToSymbol( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + count: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memset node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create.\n @param [in] graph - instance of the graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memset execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] pMemsetParams - const pointer to the parameters for the memory set.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemsetNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + pMemsetParams: *const hipMemsetParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a memset node's parameters.\n\n @param [in] node - instane of the node to get parameters from.\n @param [out] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemsetNodeGetParams( + node: hipGraphNode_t, + pNodeParams: *mut hipMemsetParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a memset node's parameters.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemsetNodeSetParams( + node: hipGraphNode_t, + pNodeParams: *const hipMemsetParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a memset node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecMemsetNodeSetParams( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + pNodeParams: *const hipMemsetParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a host execution node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create.\n @param [in] graph - instance of the graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memset execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] pNodeParams -pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddHostNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + pNodeParams: *const hipHostNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns a host node's parameters.\n\n @param [in] node - instane of the node to get parameters from.\n @param [out] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphHostNodeGetParams( + node: hipGraphNode_t, + pNodeParams: *mut hipHostNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a host node's parameters.\n\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphHostNodeSetParams( + node: hipGraphNode_t, + pNodeParams: *const hipHostNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the parameters for a host node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - instance of the node to set parameters to.\n @param [in] pNodeParams - pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecHostNodeSetParams( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + pNodeParams: *const hipHostNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a child graph node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create.\n @param [in] graph - instance of the graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memset execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] childGraph - the graph to clone into this node\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddChildGraphNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + childGraph: hipGraph_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a handle to the embedded graph of a child graph node.\n\n @param [in] node - instane of the node to get child graph.\n @param [out] pGraph - pointer to get the graph.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphChildGraphNodeGetGraph( + node: hipGraphNode_t, + pGraph: *mut hipGraph_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Updates node parameters in the child graph node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] node - node from the graph which was used to instantiate graphExec.\n @param [in] childGraph - child graph with updated parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecChildGraphNodeSetParams( + hGraphExec: hipGraphExec_t, + node: hipGraphNode_t, + childGraph: hipGraph_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an empty node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create and add to the graph.\n @param [in] graph - instane of the graph the node is add to.\n @param [in] pDependencies - const pointer to the node dependenties.\n @param [in] numDependencies - the number of dependencies.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddEmptyNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an event record node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create and add to the graph.\n @param [in] graph - instane of the graph the node to be added.\n @param [in] pDependencies - const pointer to the node dependenties.\n @param [in] numDependencies - the number of dependencies.\n @param [in] event - Event for the node.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddEventRecordNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + event: hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the event associated with an event record node.\n\n @param [in] node - instane of the node to get event from.\n @param [out] event_out - Pointer to return the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphEventRecordNodeGetEvent( + node: hipGraphNode_t, + event_out: *mut hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets an event record node's event.\n\n @param [in] node - instane of the node to set event to.\n @param [in] event - pointer to the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphEventRecordNodeSetEvent(node: hipGraphNode_t, event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the event for an event record node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] hNode - node from the graph which was used to instantiate graphExec.\n @param [in] event - pointer to the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecEventRecordNodeSetEvent( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + event: hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an event wait node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create and add to the graph.\n @param [in] graph - instane of the graph the node to be added.\n @param [in] pDependencies - const pointer to the node dependenties.\n @param [in] numDependencies - the number of dependencies.\n @param [in] event - Event for the node.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddEventWaitNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + event: hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the event associated with an event wait node.\n\n @param [in] node - instane of the node to get event from.\n @param [out] event_out - Pointer to return the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphEventWaitNodeGetEvent( + node: hipGraphNode_t, + event_out: *mut hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets an event wait node's event.\n\n @param [in] node - instane of the node to set event to.\n @param [in] event - pointer to the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphEventWaitNodeSetEvent(node: hipGraphNode_t, event: hipEvent_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the event for an event record node in the given graphExec.\n\n @param [in] hGraphExec - instance of the executable graph with the node.\n @param [in] hNode - node from the graph which was used to instantiate graphExec.\n @param [in] event - pointer to the event.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecEventWaitNodeSetEvent( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + event: hipEvent_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memory allocation node and adds it to a graph\n\n @param [out] pGraphNode - Pointer to the graph node to create and add to the graph\n @param [in] graph - Instane of the graph the node to be added\n @param [in] pDependencies - Const pointer to the node dependenties\n @param [in] numDependencies - The number of dependencies\n @param [in] pNodeParams - Node parameters for memory allocation\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemAllocNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + pNodeParams: *mut hipMemAllocNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns parameters for memory allocation node\n\n @param [in] node - Memory allocation node for a query\n @param [out] pNodeParams - Parameters for the specified memory allocation node\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemAllocNodeGetParams( + node: hipGraphNode_t, + pNodeParams: *mut hipMemAllocNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memory free node and adds it to a graph\n\n @param [out] pGraphNode - Pointer to the graph node to create and add to the graph\n @param [in] graph - Instane of the graph the node to be added\n @param [in] pDependencies - Const pointer to the node dependenties\n @param [in] numDependencies - The number of dependencies\n @param [in] dev_ptr - Pointer to the memory to be freed\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddMemFreeNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + dev_ptr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns parameters for memory free node\n\n @param [in] node - Memory free node for a query\n @param [out] dev_ptr - Device pointer for the specified memory free node\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphMemFreeNodeGetParams( + node: hipGraphNode_t, + dev_ptr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the mem attribute for graphs.\n\n @param [in] device - device the attr is get for.\n @param [in] attr - attr to get.\n @param [out] value - value for specific attr.\n @returns #hipSuccess, #hipErrorInvalidDevice\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceGetGraphMemAttribute( + device: ::std::os::raw::c_int, + attr: hipGraphMemAttributeType, + value: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the mem attribute for graphs.\n\n @param [in] device - device the attr is set for.\n @param [in] attr - attr to set.\n @param [in] value - value for specific attr.\n @returns #hipSuccess, #hipErrorInvalidDevice\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceSetGraphMemAttribute( + device: ::std::os::raw::c_int, + attr: hipGraphMemAttributeType, + value: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Free unused memory on specific device used for graph back to OS.\n\n @param [in] device - device the memory is used for graphs\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipDeviceGraphMemTrim(device: ::std::os::raw::c_int) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create an instance of userObject to manage lifetime of a resource.\n\n @param [out] object_out - pointer to instace of userobj.\n @param [in] ptr - pointer to pass to destroy function.\n @param [in] destroy - destroy callback to remove resource.\n @param [in] initialRefcount - reference to resource.\n @param [in] flags - flags passed to API.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipUserObjectCreate( + object_out: *mut hipUserObject_t, + ptr: *mut ::std::os::raw::c_void, + destroy: hipHostFn_t, + initialRefcount: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Release number of references to resource.\n\n @param [in] object - pointer to instace of userobj.\n @param [in] count - reference to resource to be retained.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipUserObjectRelease( + object: hipUserObject_t, + count: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retain number of references to resource.\n\n @param [in] object - pointer to instace of userobj.\n @param [in] count - reference to resource to be retained.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipUserObjectRetain( + object: hipUserObject_t, + count: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retain user object for graphs.\n\n @param [in] graph - pointer to graph to retain the user object for.\n @param [in] object - pointer to instace of userobj.\n @param [in] count - reference to resource to be retained.\n @param [in] flags - flags passed to API.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphRetainUserObject( + graph: hipGraph_t, + object: hipUserObject_t, + count: ::std::os::raw::c_uint, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Release user object from graphs.\n\n @param [in] graph - pointer to graph to retain the user object for.\n @param [in] object - pointer to instace of userobj.\n @param [in] count - reference to resource to be retained.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphReleaseUserObject( + graph: hipGraph_t, + object: hipUserObject_t, + count: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Write a DOT file describing graph structure.\n\n @param [in] graph - graph object for which DOT file has to be generated.\n @param [in] path - path to write the DOT file.\n @param [in] flags - Flags from hipGraphDebugDotFlags to get additional node information.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorOperatingSystem\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphDebugDotPrint( + graph: hipGraph_t, + path: *const ::std::os::raw::c_char, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies attributes from source node to destination node.\n\n Copies attributes from source node to destination node.\n Both node must have the same context.\n\n @param [out] hDst - Destination node.\n @param [in] hSrc - Source node.\n For list of attributes see ::hipKernelNodeAttrID.\n\n @returns #hipSuccess, #hipErrorInvalidContext\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphKernelNodeCopyAttributes( + hSrc: hipGraphNode_t, + hDst: hipGraphNode_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enables or disables the specified node in the given graphExec\n\n Sets hNode to be either enabled or disabled. Disabled nodes are functionally equivalent\n to empty nodes until they are reenabled. Existing node parameters are not affected by\n disabling/enabling the node.\n\n The node is identified by the corresponding hNode in the non-executable graph, from which the\n executable graph was instantiated.\n\n hNode must not have been removed from the original graph.\n\n @note Currently only kernel, memset and memcpy nodes are supported.\n\n @param [in] hGraphExec - The executable graph in which to set the specified node.\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [in] isEnabled - Node is enabled if != 0, otherwise the node is disabled.\n\n @returns #hipSuccess, #hipErrorInvalidValue,\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphNodeSetEnabled( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + isEnabled: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query whether a node in the given graphExec is enabled\n\n Sets isEnabled to 1 if hNode is enabled, or 0 if it is disabled.\n\n The node is identified by the corresponding node in the non-executable graph, from which the\n executable graph was instantiated.\n\n hNode must not have been removed from the original graph.\n\n @note Currently only kernel, memset and memcpy nodes are supported.\n\n @param [in] hGraphExec - The executable graph in which to set the specified node.\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [out] isEnabled - Location to return the enabled status of the node.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphNodeGetEnabled( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + isEnabled: *mut ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a external semaphor wait node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create.\n @param [in] graph - instance of the graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memset execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] nodeParams -pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddExternalSemaphoresWaitNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + nodeParams: *const hipExternalSemaphoreWaitNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a external semaphor signal node and adds it to a graph.\n\n @param [out] pGraphNode - pointer to the graph node to create.\n @param [in] graph - instance of the graph to add the created node.\n @param [in] pDependencies - const pointer to the dependencies on the memset execution node.\n @param [in] numDependencies - the number of the dependencies.\n @param [in] nodeParams -pointer to the parameters.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphAddExternalSemaphoresSignalNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + nodeParams: *const hipExternalSemaphoreSignalNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Updates node parameters in the external semaphore signal node.\n\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [in] nodeParams - Pointer to the params to be set.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExternalSemaphoresSignalNodeSetParams( + hNode: hipGraphNode_t, + nodeParams: *const hipExternalSemaphoreSignalNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Updates node parameters in the external semaphore wait node.\n\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [in] nodeParams - Pointer to the params to be set.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExternalSemaphoresWaitNodeSetParams( + hNode: hipGraphNode_t, + nodeParams: *const hipExternalSemaphoreWaitNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns external semaphore signal node params.\n\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [out] params_out - Pointer to params.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExternalSemaphoresSignalNodeGetParams( + hNode: hipGraphNode_t, + params_out: *const hipExternalSemaphoreSignalNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns external semaphore wait node params.\n\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [out] params_out - Pointer to params.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExternalSemaphoresWaitNodeGetParams( + hNode: hipGraphNode_t, + params_out: *const hipExternalSemaphoreWaitNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Updates node parameters in the external semaphore signal node in the given graphExec.\n\n @param [in] hGraphExec - The executable graph in which to set the specified node.\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [in] nodeParams - Pointer to the params to be set.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecExternalSemaphoresSignalNodeSetParams( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + nodeParams: *const hipExternalSemaphoreSignalNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Updates node parameters in the external semaphore wait node in the given graphExec.\n\n @param [in] hGraphExec - The executable graph in which to set the specified node.\n @param [in] hNode - Node from the graph from which graphExec was instantiated.\n @param [in] nodeParams - Pointer to the params to be set.\n @returns #hipSuccess, #hipErrorInvalidValue\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues."] + pub fn hipGraphExecExternalSemaphoresWaitNodeSetParams( + hGraphExec: hipGraphExec_t, + hNode: hipGraphNode_t, + nodeParams: *const hipExternalSemaphoreWaitNodeParams, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Frees an address range reservation made via hipMemAddressReserve\n\n @param [in] devPtr - starting address of the range.\n @param [in] size - size of the range.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemAddressFree(devPtr: *mut ::std::os::raw::c_void, size: usize) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reserves an address range\n\n @param [out] ptr - starting address of the reserved range.\n @param [in] size - size of the reservation.\n @param [in] alignment - alignment of the address.\n @param [in] addr - requested starting address of the range.\n @param [in] flags - currently unused, must be zero.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemAddressReserve( + ptr: *mut *mut ::std::os::raw::c_void, + size: usize, + alignment: usize, + addr: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a memory allocation described by the properties and size\n\n @param [out] handle - value of the returned handle.\n @param [in] size - size of the allocation.\n @param [in] prop - properties of the allocation.\n @param [in] flags - currently unused, must be zero.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemCreate( + handle: *mut hipMemGenericAllocationHandle_t, + size: usize, + prop: *const hipMemAllocationProp, + flags: ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Exports an allocation to a requested shareable handle type.\n\n @param [out] shareableHandle - value of the returned handle.\n @param [in] handle - handle to share.\n @param [in] handleType - type of the shareable handle.\n @param [in] flags - currently unused, must be zero.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemExportToShareableHandle( + shareableHandle: *mut ::std::os::raw::c_void, + handle: hipMemGenericAllocationHandle_t, + handleType: hipMemAllocationHandleType, + flags: ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the access flags set for the given location and ptr.\n\n @param [out] flags - flags for this location.\n @param [in] location - target location.\n @param [in] ptr - address to check the access flags.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemGetAccess( + flags: *mut ::std::os::raw::c_ulonglong, + location: *const hipMemLocation, + ptr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Calculates either the minimal or recommended granularity.\n\n @param [out] granularity - returned granularity.\n @param [in] prop - location properties.\n @param [in] option - determines which granularity to return.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows.\n"] + pub fn hipMemGetAllocationGranularity( + granularity: *mut usize, + prop: *const hipMemAllocationProp, + option: hipMemAllocationGranularity_flags, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the property structure of the given handle.\n\n @param [out] prop - properties of the given handle.\n @param [in] handle - handle to perform the query on.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux under development on Windows."] + pub fn hipMemGetAllocationPropertiesFromHandle( + prop: *mut hipMemAllocationProp, + handle: hipMemGenericAllocationHandle_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Imports an allocation from a requested shareable handle type.\n\n @param [out] handle - returned value.\n @param [in] osHandle - shareable handle representing the memory allocation.\n @param [in] shHandleType - handle type.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemImportFromShareableHandle( + handle: *mut hipMemGenericAllocationHandle_t, + osHandle: *mut ::std::os::raw::c_void, + shHandleType: hipMemAllocationHandleType, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Maps an allocation handle to a reserved virtual address range.\n\n @param [in] ptr - address where the memory will be mapped.\n @param [in] size - size of the mapping.\n @param [in] offset - offset into the memory, currently must be zero.\n @param [in] handle - memory allocation to be mapped.\n @param [in] flags - currently unused, must be zero.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemMap( + ptr: *mut ::std::os::raw::c_void, + size: usize, + offset: usize, + handle: hipMemGenericAllocationHandle_t, + flags: ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Maps or unmaps subregions of sparse HIP arrays and sparse HIP mipmapped arrays.\n\n @param [in] mapInfoList - list of hipArrayMapInfo.\n @param [in] count - number of hipArrayMapInfo in mapInfoList.\n @param [in] stream - stream identifier for the stream to use for map or unmap operations.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemMapArrayAsync( + mapInfoList: *mut hipArrayMapInfo, + count: ::std::os::raw::c_uint, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Release a memory handle representing a memory allocation which was previously allocated through hipMemCreate.\n\n @param [in] handle - handle of the memory allocation.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemRelease(handle: hipMemGenericAllocationHandle_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the allocation handle of the backing memory allocation given the address.\n\n @param [out] handle - handle representing addr.\n @param [in] addr - address to look up.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemRetainAllocationHandle( + handle: *mut hipMemGenericAllocationHandle_t, + addr: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the access flags for each location specified in desc for the given virtual address range.\n\n @param [in] ptr - starting address of the virtual address range.\n @param [in] size - size of the range.\n @param [in] desc - array of hipMemAccessDesc.\n @param [in] count - number of hipMemAccessDesc in desc.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemSetAccess( + ptr: *mut ::std::os::raw::c_void, + size: usize, + desc: *const hipMemAccessDesc, + count: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Unmap memory allocation of a given address range.\n\n @param [in] ptr - starting address of the range to unmap.\n @param [in] size - size of the virtual address range.\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n @warning : This API is marked as beta, meaning, while this is feature complete,\n it is still open to changes and may have outstanding issues.\n\n @note This API is implemented on Linux, under development on Windows."] + pub fn hipMemUnmap(ptr: *mut ::std::os::raw::c_void, size: usize) -> hipError_t; +} +#[doc = "-------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------\n @defgroup GL OpenGL Interop\n @{\n This section describes the OpenGL and graphics interoperability functions of HIP runtime API.\n/\n/** GLuint as uint."] +pub type GLuint = ::std::os::raw::c_uint; +#[doc = " GLenum as uint."] +pub type GLenum = ::std::os::raw::c_uint; +extern "C" { + #[must_use] + #[doc = " @brief Queries devices associated with the current OpenGL context.\n\n @param [out] pHipDeviceCount - Pointer of number of devices on the current GL context.\n @param [out] pHipDevices - Pointer of devices on the current OpenGL context.\n @param [in] hipDeviceCount - Size of device.\n @param [in] deviceList - The setting of devices. It could be either hipGLDeviceListCurrentFrame\n for the devices used to render the current frame, or hipGLDeviceListAll for all devices.\n The default setting is Invalid deviceList value.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorNotSupported\n"] + pub fn hipGLGetDevices( + pHipDeviceCount: *mut ::std::os::raw::c_uint, + pHipDevices: *mut ::std::os::raw::c_int, + hipDeviceCount: ::std::os::raw::c_uint, + deviceList: hipGLDeviceList, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Registers a GL Buffer for interop and returns corresponding graphics resource.\n\n @param [out] resource - Returns pointer of graphics resource.\n @param [in] buffer - Buffer to be registered.\n @param [in] flags - Register flags.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorUnknown, #hipErrorInvalidResourceHandle\n"] + pub fn hipGraphicsGLRegisterBuffer( + resource: *mut *mut hipGraphicsResource, + buffer: GLuint, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Register a GL Image for interop and returns the corresponding graphic resource.\n\n @param [out] resource - Returns pointer of graphics resource.\n @param [in] image - Image to be registered.\n @param [in] target - Valid target value Id.\n @param [in] flags - Register flags.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorUnknown, #hipErrorInvalidResourceHandle\n"] + pub fn hipGraphicsGLRegisterImage( + resource: *mut *mut hipGraphicsResource, + image: GLuint, + target: GLenum, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Maps a graphics resource for access.\n\n @param [in] count - Number of resources to map.\n @param [in] resources - Pointer of resources to map.\n @param [in] stream - Stream for synchronization.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorUnknown, #hipErrorInvalidResourceHandle\n"] + pub fn hipGraphicsMapResources( + count: ::std::os::raw::c_int, + resources: *mut hipGraphicsResource_t, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get an array through which to access a subresource of a mapped graphics resource.\n\n @param [out] array - Pointer of array through which a subresource of resource may be accessed.\n @param [in] resource - Mapped resource to access.\n @param [in] arrayIndex - Array index for the subresource to access.\n @param [in] mipLevel - Mipmap level for the subresource to access.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n\n @note In this API, the value of arrayIndex higher than zero is currently not supported.\n"] + pub fn hipGraphicsSubResourceGetMappedArray( + array: *mut hipArray_t, + resource: hipGraphicsResource_t, + arrayIndex: ::std::os::raw::c_uint, + mipLevel: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets device accessible address of a graphics resource.\n\n @param [out] devPtr - Pointer of device through which graphic resource may be accessed.\n @param [out] size - Size of the buffer accessible from devPtr.\n @param [in] resource - Mapped resource to access.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipGraphicsResourceGetMappedPointer( + devPtr: *mut *mut ::std::os::raw::c_void, + size: *mut usize, + resource: hipGraphicsResource_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Unmaps graphics resources.\n\n @param [in] count - Number of resources to unmap.\n @param [in] resources - Pointer of resources to unmap.\n @param [in] stream - Stream for synchronization.\n\n @returns #hipSuccess, #hipErrorInvalidValue, #hipErrorUnknown, #hipErrorContextIsDestroyed\n"] + pub fn hipGraphicsUnmapResources( + count: ::std::os::raw::c_int, + resources: *mut hipGraphicsResource_t, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Unregisters a graphics resource.\n\n @param [in] resource - Graphics resources to unregister.\n\n @returns #hipSuccess\n"] + pub fn hipGraphicsUnregisterResource(resource: hipGraphicsResource_t) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a surface object.\n\n @param [out] pSurfObject Pointer of surface object to be created.\n @param [in] pResDesc Pointer of suface object descriptor.\n\n @returns #hipSuccess, #hipErrorInvalidValue\n"] + pub fn hipCreateSurfaceObject( + pSurfObject: *mut hipSurfaceObject_t, + pResDesc: *const hipResourceDesc, + ) -> hipError_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy a surface object.\n\n @param [in] surfaceObject Surface object to be destroyed.\n\n @returns #hipSuccess, #hipErrorInvalidValue"] + pub fn hipDestroySurfaceObject(surfaceObject: hipSurfaceObject_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy_spt( + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyToSymbol_spt( + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyFromSymbol_spt( + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2D_spt( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2DFromArray_spt( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: hipArray_const_t, + wOffset: usize, + hOffset: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy3D_spt(p: *const hipMemcpy3DParms) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemset_spt( + dst: *mut ::std::os::raw::c_void, + value: ::std::os::raw::c_int, + sizeBytes: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemsetAsync_spt( + dst: *mut ::std::os::raw::c_void, + value: ::std::os::raw::c_int, + sizeBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemset2D_spt( + dst: *mut ::std::os::raw::c_void, + pitch: usize, + value: ::std::os::raw::c_int, + width: usize, + height: usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemset2DAsync_spt( + dst: *mut ::std::os::raw::c_void, + pitch: usize, + value: ::std::os::raw::c_int, + width: usize, + height: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemset3DAsync_spt( + pitchedDevPtr: hipPitchedPtr, + value: ::std::os::raw::c_int, + extent: hipExtent, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemset3D_spt( + pitchedDevPtr: hipPitchedPtr, + value: ::std::os::raw::c_int, + extent: hipExtent, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyAsync_spt( + dst: *mut ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy3DAsync_spt(p: *const hipMemcpy3DParms, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2DAsync_spt( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyFromSymbolAsync_spt( + dst: *mut ::std::os::raw::c_void, + symbol: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyToSymbolAsync_spt( + symbol: *const ::std::os::raw::c_void, + src: *const ::std::os::raw::c_void, + sizeBytes: usize, + offset: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpyFromArray_spt( + dst: *mut ::std::os::raw::c_void, + src: hipArray_const_t, + wOffsetSrc: usize, + hOffset: usize, + count: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2DToArray_spt( + dst: *mut hipArray, + wOffset: usize, + hOffset: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2DFromArrayAsync_spt( + dst: *mut ::std::os::raw::c_void, + dpitch: usize, + src: hipArray_const_t, + wOffsetSrc: usize, + hOffsetSrc: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipMemcpy2DToArrayAsync_spt( + dst: *mut hipArray, + wOffset: usize, + hOffset: usize, + src: *const ::std::os::raw::c_void, + spitch: usize, + width: usize, + height: usize, + kind: hipMemcpyKind, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamQuery_spt(stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamSynchronize_spt(stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamGetPriority_spt( + stream: hipStream_t, + priority: *mut ::std::os::raw::c_int, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamWaitEvent_spt( + stream: hipStream_t, + event: hipEvent_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamGetFlags_spt( + stream: hipStream_t, + flags: *mut ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamAddCallback_spt( + stream: hipStream_t, + callback: hipStreamCallback_t, + userData: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipEventRecord_spt(event: hipEvent_t, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipLaunchCooperativeKernel_spt( + f: *const ::std::os::raw::c_void, + gridDim: dim3, + blockDim: dim3, + kernelParams: *mut *mut ::std::os::raw::c_void, + sharedMemBytes: u32, + hStream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipLaunchKernel_spt( + function_address: *const ::std::os::raw::c_void, + numBlocks: dim3, + dimBlocks: dim3, + args: *mut *mut ::std::os::raw::c_void, + sharedMemBytes: usize, + stream: hipStream_t, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipGraphLaunch_spt(graphExec: hipGraphExec_t, stream: hipStream_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamBeginCapture_spt(stream: hipStream_t, mode: hipStreamCaptureMode) + -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamEndCapture_spt(stream: hipStream_t, pGraph: *mut hipGraph_t) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamIsCapturing_spt( + stream: hipStream_t, + pCaptureStatus: *mut hipStreamCaptureStatus, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamGetCaptureInfo_spt( + stream: hipStream_t, + pCaptureStatus: *mut hipStreamCaptureStatus, + pId: *mut ::std::os::raw::c_ulonglong, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipStreamGetCaptureInfo_v2_spt( + stream: hipStream_t, + captureStatus_out: *mut hipStreamCaptureStatus, + id_out: *mut ::std::os::raw::c_ulonglong, + graph_out: *mut hipGraph_t, + dependencies_out: *mut *const hipGraphNode_t, + numDependencies_out: *mut usize, + ) -> hipError_t; +} +extern "C" { + #[must_use] + pub fn hipLaunchHostFunc_spt( + stream: hipStream_t, + fn_: hipHostFn_t, + userData: *mut ::std::os::raw::c_void, + ) -> hipError_t; +} diff --git a/hip_runtime-sys/src/lib.rs b/hip_runtime-sys/src/lib.rs new file mode 100644 index 0000000..d86bfe5 --- /dev/null +++ b/hip_runtime-sys/src/lib.rs @@ -0,0 +1,11 @@ +#![allow(warnings)] +pub mod hip_runtime_api; +pub mod hip_runtime_api_ext { + use crate::hipStream_t; + + pub const hipStreamNull: hipStream_t = 0 as _; + pub const hipStreamPerThread: hipStream_t = 2 as _; + pub const HIP_TRSA_OVERRIDE_FORMAT: u32 = 1; +} +pub use hip_runtime_api::*; +pub use hip_runtime_api_ext::*; diff --git a/level_zero-sys/Cargo.toml b/hipblaslt-sys/Cargo.toml similarity index 55% rename from level_zero-sys/Cargo.toml rename to hipblaslt-sys/Cargo.toml index 7f8b497..96dd807 100644 --- a/level_zero-sys/Cargo.toml +++ b/hipblaslt-sys/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "level_zero-sys" -version = "1.0.4" +name = "hipblaslt-sys" +version = "0.0.0" authors = ["Andrzej Janik "] edition = "2018" -links = "ze_loader" +links = "hipblaslt" [lib] \ No newline at end of file diff --git a/hipblaslt-sys/README b/hipblaslt-sys/README new file mode 100644 index 0000000..0d7cc98 --- /dev/null +++ b/hipblaslt-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/hipblaslt/hipblaslt.h -o src/hipblaslt.rs --no-layout-tests --default-enum-style=newtype --allowlist-function "^hipblasLt.*" --allowlist-type "^hipblasLt.*" --no-derive-debug --must-use-type hiprtError -- -I /opt/rocm/include -D__HIP_PLATFORM_AMD__ -D__HIP_PLATFORM_HCC__ -x c++ diff --git a/hipblaslt-sys/build.rs b/hipblaslt-sys/build.rs new file mode 100644 index 0000000..6045f68 --- /dev/null +++ b/hipblaslt-sys/build.rs @@ -0,0 +1,7 @@ +use std::env::VarError; + +fn main() -> Result<(), VarError> { + println!("cargo:rustc-link-lib=dylib=hipblaslt"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); + Ok(()) +} diff --git a/hipblaslt-sys/src/hipblaslt.rs b/hipblaslt-sys/src/hipblaslt.rs new file mode 100644 index 0000000..3401b35 --- /dev/null +++ b/hipblaslt-sys/src/hipblaslt.rs @@ -0,0 +1,513 @@ +type _hipblasLtGroupedGemmOpaque_t = (); + +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +pub type hipStream_t = *mut ihipStream_t; +impl hipblasStatus_t { + #[doc = "< Function succeeds"] + pub const HIPBLAS_STATUS_SUCCESS: hipblasStatus_t = hipblasStatus_t(0); +} +impl hipblasStatus_t { + #[doc = "< HIPBLAS library not initialized"] + pub const HIPBLAS_STATUS_NOT_INITIALIZED: hipblasStatus_t = hipblasStatus_t(1); +} +impl hipblasStatus_t { + #[doc = "< resource allocation failed"] + pub const HIPBLAS_STATUS_ALLOC_FAILED: hipblasStatus_t = hipblasStatus_t(2); +} +impl hipblasStatus_t { + #[doc = "< unsupported numerical value was passed to function"] + pub const HIPBLAS_STATUS_INVALID_VALUE: hipblasStatus_t = hipblasStatus_t(3); +} +impl hipblasStatus_t { + #[doc = "< access to GPU memory space failed"] + pub const HIPBLAS_STATUS_MAPPING_ERROR: hipblasStatus_t = hipblasStatus_t(4); +} +impl hipblasStatus_t { + #[doc = "< GPU program failed to execute"] + pub const HIPBLAS_STATUS_EXECUTION_FAILED: hipblasStatus_t = hipblasStatus_t(5); +} +impl hipblasStatus_t { + #[doc = "< an internal HIPBLAS operation failed"] + pub const HIPBLAS_STATUS_INTERNAL_ERROR: hipblasStatus_t = hipblasStatus_t(6); +} +impl hipblasStatus_t { + #[doc = "< function not implemented"] + pub const HIPBLAS_STATUS_NOT_SUPPORTED: hipblasStatus_t = hipblasStatus_t(7); +} +impl hipblasStatus_t { + #[doc = "< architecture mismatch"] + pub const HIPBLAS_STATUS_ARCH_MISMATCH: hipblasStatus_t = hipblasStatus_t(8); +} +impl hipblasStatus_t { + #[doc = "< hipBLAS handle is null pointer"] + pub const HIPBLAS_STATUS_HANDLE_IS_NULLPTR: hipblasStatus_t = hipblasStatus_t(9); +} +impl hipblasStatus_t { + #[doc = "< unsupported enum value was passed to function"] + pub const HIPBLAS_STATUS_INVALID_ENUM: hipblasStatus_t = hipblasStatus_t(10); +} +impl hipblasStatus_t { + #[doc = "< back-end returned an unsupported status code"] + pub const HIPBLAS_STATUS_UNKNOWN: hipblasStatus_t = hipblasStatus_t(11); +} +#[repr(transparent)] +#[doc = " \\brief hipblas status codes definition"] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipblasStatus_t(pub ::std::os::raw::c_uint); +impl hipblasDatatype_t { + #[doc = "< 16 bit floating point, real"] + pub const HIPBLAS_R_16F: hipblasDatatype_t = hipblasDatatype_t(150); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit floating point, real"] + pub const HIPBLAS_R_32F: hipblasDatatype_t = hipblasDatatype_t(151); +} +impl hipblasDatatype_t { + #[doc = "< 64 bit floating point, real"] + pub const HIPBLAS_R_64F: hipblasDatatype_t = hipblasDatatype_t(152); +} +impl hipblasDatatype_t { + #[doc = "< 16 bit floating point, complex"] + pub const HIPBLAS_C_16F: hipblasDatatype_t = hipblasDatatype_t(153); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit floating point, complex"] + pub const HIPBLAS_C_32F: hipblasDatatype_t = hipblasDatatype_t(154); +} +impl hipblasDatatype_t { + #[doc = "< 64 bit floating point, complex"] + pub const HIPBLAS_C_64F: hipblasDatatype_t = hipblasDatatype_t(155); +} +impl hipblasDatatype_t { + #[doc = "< 8 bit signed integer, real"] + pub const HIPBLAS_R_8I: hipblasDatatype_t = hipblasDatatype_t(160); +} +impl hipblasDatatype_t { + #[doc = "< 8 bit unsigned integer, real"] + pub const HIPBLAS_R_8U: hipblasDatatype_t = hipblasDatatype_t(161); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit signed integer, real"] + pub const HIPBLAS_R_32I: hipblasDatatype_t = hipblasDatatype_t(162); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit unsigned integer, real"] + pub const HIPBLAS_R_32U: hipblasDatatype_t = hipblasDatatype_t(163); +} +impl hipblasDatatype_t { + #[doc = "< 8 bit signed integer, complex"] + pub const HIPBLAS_C_8I: hipblasDatatype_t = hipblasDatatype_t(164); +} +impl hipblasDatatype_t { + #[doc = "< 8 bit unsigned integer, complex"] + pub const HIPBLAS_C_8U: hipblasDatatype_t = hipblasDatatype_t(165); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit signed integer, complex"] + pub const HIPBLAS_C_32I: hipblasDatatype_t = hipblasDatatype_t(166); +} +impl hipblasDatatype_t { + #[doc = "< 32 bit unsigned integer, complex"] + pub const HIPBLAS_C_32U: hipblasDatatype_t = hipblasDatatype_t(167); +} +impl hipblasDatatype_t { + #[doc = "< 16 bit bfloat, real"] + pub const HIPBLAS_R_16B: hipblasDatatype_t = hipblasDatatype_t(168); +} +impl hipblasDatatype_t { + #[doc = "< 16 bit bfloat, complex"] + pub const HIPBLAS_C_16B: hipblasDatatype_t = hipblasDatatype_t(169); +} +impl hipblasDatatype_t { + #[doc = "< Invalid datatype value, do not use"] + pub const HIPBLAS_DATATYPE_INVALID: hipblasDatatype_t = hipblasDatatype_t(255); +} +#[repr(transparent)] +#[doc = " \\brief Indicates the precision width of data stored in a blas type."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipblasDatatype_t(pub ::std::os::raw::c_uint); +#[doc = " \\brief Struct to represent a 16 bit brain floating point number."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hip_bfloat16 { + pub data: u16, +} +#[doc = " \\brief Single precision floating point type"] +pub type hipblasLtFloat = f32; +#[doc = " \\brief Structure definition for hipblasLtHalf"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _hipblasLtHalf { + pub data: u16, +} +#[doc = " \\brief Structure definition for hipblasLtHalf"] +pub type hipblasLtHalf = _hipblasLtHalf; +#[doc = " \\brief Struct to represent a 16 bit brain floating point number."] +pub type hipblasLtBfloat16 = hip_bfloat16; +impl hipblasLtEpilogue_t { + #[doc = " hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtGetGitRevision( + handle: hipblasLtHandle_t, + rev: *mut ::std::os::raw::c_char, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtGetArchName(archName: *mut *mut ::std::os::raw::c_char) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Create a hipblaslt handle\n\n \\details\n This function initializes the hipBLASLt library and creates a handle to an\n opaque structure holding the hipBLASLt library context. It allocates light\n hardware resources on the host and device, and must be called prior to making\n any other hipBLASLt library calls. The hipBLASLt library context is tied to\n the current CUDA device. To use the library on multiple devices, one\n hipBLASLt handle should be created for each device.\n\n @param[out]\n handle Pointer to the allocated hipBLASLt handle for the created hipBLASLt\n context.\n\n \\retval HIPBLAS_STATUS_SUCCESS The allocation completed successfully.\n \\retval HIPBLAS_STATUS_INVALID_VALUE \\p handle == NULL."] + pub fn hipblasLtCreate(handle: *mut hipblasLtHandle_t) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Destory a hipblaslt handle\n\n \\details\n This function releases hardware resources used by the hipBLASLt library.\n This function is usually the last call with a particular handle to the\n hipBLASLt library. Because hipblasLtCreate() allocates some internal\n resources and the release of those resources by calling hipblasLtDestroy()\n will implicitly call hipDeviceSynchronize(), it is recommended to minimize\n the number of hipblasLtCreate()/hipblasLtDestroy() occurrences.\n\n @param[in]\n handle Pointer to the hipBLASLt handle to be destroyed.\n\n \\retval HIPBLAS_STATUS_SUCCESS The hipBLASLt context was successfully\n destroyed. \\retval HIPBLAS_STATUS_NOT_INITIALIZED The hipBLASLt library was\n not initialized. \\retval HIPBLAS_STATUS_INVALID_VALUE \\p handle == NULL."] + pub fn hipblasLtDestroy(handle: hipblasLtHandle_t) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Create a matrix layout descriptor\n\n \\details\n This function creates a matrix layout descriptor by allocating the memory\n needed to hold its opaque structure.\n\n @param[out]\n matLayout Pointer to the structure holding the matrix layout descriptor\n created by this function. see \\ref hipblasLtMatrixLayout_t .\n @param[in]\n type Enumerant that specifies the data precision for the matrix layout\n descriptor this function creates. See hipblasDataType_t.\n @param[in]\n rows Number of rows of the matrix.\n @param[in]\n cols Number of columns of the matrix.\n @param[in]\n ld The leading dimension of the matrix. In column major layout, this is the\n number of elements to jump to reach the next column. Thus ld >= m (number of\n rows).\n\n \\retval HIPBLAS_STATUS_SUCCESS If the descriptor was created successfully.\n \\retval HIPBLAS_STATUS_ALLOC_FAILED If the memory could not be allocated."] + pub fn hipblasLtMatrixLayoutCreate( + matLayout: *mut hipblasLtMatrixLayout_t, + type_: hipblasDatatype_t, + rows: u64, + cols: u64, + ld: i64, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Destory a matrix layout descriptor\n\n \\details\n This function destroys a previously created matrix layout descriptor object.\n\n @param[in]\n matLayout Pointer to the structure holding the matrix layout descriptor that\n should be destroyed by this function. see \\ref hipblasLtMatrixLayout_t .\n\n \\retval HIPBLAS_STATUS_SUCCESS If the operation was successful."] + pub fn hipblasLtMatrixLayoutDestroy(matLayout: hipblasLtMatrixLayout_t) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Set attribute to a matrix descriptor\n\n \\details\n This function sets the value of the specified attribute belonging to a\n previously created matrix descriptor.\n\n @param[in]\n matLayout Pointer to the previously created structure holding the matrix\n mdescriptor queried by this function. See \\ref hipblasLtMatrixLayout_t\n .\n @param[in]\n attr \tThe attribute that will be set by this function. See \\ref\n hipblasLtMatrixLayoutAttribute_t.\n @param[in]\n buf The value to which the specified attribute should be set.\n @param[in]\n sizeInBytes Size of buf buffer (in bytes) for verification.\n\n \\retval HIPBLAS_STATUS_SUCCESS If the attribute was set successfully..\n \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p buf is NULL or \\p sizeInBytes\n doesn't match the size of the internal storage for the selected attribute."] + pub fn hipblasLtMatrixLayoutSetAttribute( + matLayout: hipblasLtMatrixLayout_t, + attr: hipblasLtMatrixLayoutAttribute_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Query attribute from a matrix descriptor\n\n \\details\n This function returns the value of the queried attribute belonging to a\n previously created matrix descriptor.\n\n @param[in]\n matLayout Pointer to the previously created structure holding the matrix\n descriptor queried by this function. See \\ref hipblasLtMatrixLayout_t\n .\n @param[in]\n attr \t The attribute that will be retrieved by this function. See\n \\ref hipblasLtMatrixLayoutAttribute_t.\n @param[out]\n buf Memory address containing the attribute value retrieved by this\n function.\n @param[in]\n sizeInBytes Size of \\p buf buffer (in bytes) for verification.\n @param[out]\n sizeWritten Valid only when the return value is HIPBLAS_STATUS_SUCCESS. If\n sizeInBytes is non-zero: then sizeWritten is the number of bytes actually\n written; if sizeInBytes is 0: then sizeWritten is the number of bytes needed\n to write full contents.\n\n \\retval HIPBLAS_STATUS_SUCCESS If attribute's value was successfully\n written to user memory. \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p\n sizeInBytes is 0 and \\p sizeWritten is NULL, or if \\p sizeInBytes is non-zero\n and \\p buf is NULL, or \\p sizeInBytes doesn't match size of internal storage\n for the selected attribute."] + pub fn hipblasLtMatrixLayoutGetAttribute( + matLayout: hipblasLtMatrixLayout_t, + attr: hipblasLtMatrixLayoutAttribute_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Create a matrix multiply descriptor\n\n \\details\n This function creates a matrix multiply descriptor by allocating the memory\n needed to hold its opaque structure.\n\n @param[out]\n matmulDesc Pointer to the structure holding the matrix multiply descriptor\n created by this function. See \\ref hipblasLtMatmulDesc_t .\n @param[in]\n computeType Enumerant that specifies the data precision for the matrix\n multiply descriptor this function creates. See \\ref hipblasLtComputeType_t .\n @param[in]\n scaleType Enumerant that specifies the data precision for the matrix\n transform descriptor this function creates. See hipblasDataType_t.\n\n \\retval HIPBLAS_STATUS_SUCCESS If the descriptor was created successfully.\n \\retval HIPBLAS_STATUS_ALLOC_FAILED If the memory could not be allocated."] + pub fn hipblasLtMatmulDescCreate( + matmulDesc: *mut hipblasLtMatmulDesc_t, + computeType: hipblasLtComputeType_t, + scaleType: hipblasDatatype_t, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Destory a matrix multiply descriptor\n\n \\details\n This function destroys a previously created matrix multiply descriptor\n object.\n\n @param[in]\n matmulDesc Pointer to the structure holding the matrix multiply descriptor\n that should be destroyed by this function. See \\ref hipblasLtMatmulDesc_t .\n\n \\retval HIPBLAS_STATUS_SUCCESS If operation was successful."] + pub fn hipblasLtMatmulDescDestroy(matmulDesc: hipblasLtMatmulDesc_t) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Set attribute to a matrix multiply descriptor\n\n \\details\n This function sets the value of the specified attribute belonging to a\n previously created matrix multiply descriptor.\n\n @param[in]\n matmulDesc Pointer to the previously created structure holding the matrix\n multiply descriptor queried by this function. See \\ref hipblasLtMatmulDesc_t\n .\n @param[in]\n attr \tThe attribute that will be set by this function. See \\ref\n hipblasLtMatmulDescAttributes_t.\n @param[in]\n buf The value to which the specified attribute should be set.\n @param[in]\n sizeInBytes Size of buf buffer (in bytes) for verification.\n\n \\retval HIPBLAS_STATUS_SUCCESS If the attribute was set successfully..\n \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p buf is NULL or \\p sizeInBytes\n doesn't match the size of the internal storage for the selected attribute."] + pub fn hipblasLtMatmulDescSetAttribute( + matmulDesc: hipblasLtMatmulDesc_t, + attr: hipblasLtMatmulDescAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Query attribute from a matrix multiply descriptor\n\n \\details\n This function returns the value of the queried attribute belonging to a\n previously created matrix multiply descriptor.\n\n @param[in]\n matmulDesc Pointer to the previously created structure holding the matrix\n multiply descriptor queried by this function. See \\ref hipblasLtMatmulDesc_t\n .\n @param[in]\n attr \t The attribute that will be retrieved by this function. See\n \\ref hipblasLtMatmulDescAttributes_t.\n @param[out]\n buf Memory address containing the attribute value retrieved by this\n function.\n @param[in]\n sizeInBytes Size of \\p buf buffer (in bytes) for verification.\n @param[out]\n sizeWritten Valid only when the return value is HIPBLAS_STATUS_SUCCESS. If\n sizeInBytes is non-zero: then sizeWritten is the number of bytes actually\n written; if sizeInBytes is 0: then sizeWritten is the number of bytes needed\n to write full contents.\n\n \\retval HIPBLAS_STATUS_SUCCESS If attribute's value was successfully\n written to user memory. \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p\n sizeInBytes is 0 and \\p sizeWritten is NULL, or if \\p sizeInBytes is non-zero\n and \\p buf is NULL, or \\p sizeInBytes doesn't match size of internal storage\n for the selected attribute."] + pub fn hipblasLtMatmulDescGetAttribute( + matmulDesc: hipblasLtMatmulDesc_t, + attr: hipblasLtMatmulDescAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Create a preference descriptor\n\n \\details\n This function creates a matrix multiply heuristic search preferences\n descriptor by allocating the memory needed to hold its opaque structure.\n\n @param[out]\n pref Pointer to the structure holding the matrix multiply preferences\n descriptor created by this function. see \\ref hipblasLtMatmulPreference_t .\n\n \\retval HIPBLAS_STATUS_SUCCESS If the descriptor was created\n successfully. \\retval HIPBLAS_STATUS_ALLOC_FAILED If memory could not be\n allocated."] + pub fn hipblasLtMatmulPreferenceCreate( + pref: *mut hipblasLtMatmulPreference_t, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Destory a preferences descriptor\n\n \\details\n This function destroys a previously created matrix multiply preferences\n descriptor object.\n\n @param[in]\n pref Pointer to the structure holding the matrix multiply preferences\n descriptor that should be destroyed by this function. See \\ref\n hipblasLtMatmulPreference_t .\n\n \\retval HIPBLAS_STATUS_SUCCESS If operation was successful."] + pub fn hipblasLtMatmulPreferenceDestroy(pref: hipblasLtMatmulPreference_t) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Set attribute to a preference descriptor\n\n \\details\n This function sets the value of the specified attribute belonging to a\n previously created matrix multiply preferences descriptor.\n\n @param[in]\n pref Pointer to the previously created structure holding the matrix\n multiply preferences descriptor queried by this function. See \\ref\n hipblasLtMatmulPreference_t\n @param[in]\n attr \t The attribute that will be set by this function. See \\ref\n hipblasLtMatmulPreferenceAttributes_t.\n @param[in]\n buf The value to which the specified attribute should be set.\n @param[in]\n sizeInBytes Size of \\p buf buffer (in bytes) for verification.\n\n \\retval HIPBLAS_STATUS_SUCCESS If the attribute was set successfully..\n \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p buf is NULL or \\p sizeInBytes\n doesn't match the size of the internal storage for the selected attribute."] + pub fn hipblasLtMatmulPreferenceSetAttribute( + pref: hipblasLtMatmulPreference_t, + attr: hipblasLtMatmulPreferenceAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Query attribute from a preference descriptor\n\n \\details\n This function returns the value of the queried attribute belonging to a\n previously created matrix multiply heuristic search preferences descriptor.\n\n @param[in]\n pref Pointer to the previously created structure holding the matrix\n multiply heuristic search preferences descriptor queried by this function.\n See \\ref hipblasLtMatmulPreference_t.\n @param[in]\n attr \t The attribute that will be retrieved by this function. See\n \\ref hipblasLtMatmulPreferenceAttributes_t.\n @param[out]\n buf Memory address containing the attribute value retrieved by this\n function.\n @param[in]\n sizeInBytes Size of \\p buf buffer (in bytes) for verification.\n @param[out]\n sizeWritten Valid only when the return value is HIPBLAS_STATUS_SUCCESS. If\n sizeInBytes is non-zero: then sizeWritten is the number of bytes actually\n written; if sizeInBytes is 0: then sizeWritten is the number of bytes needed\n to write full contents.\n\n \\retval HIPBLAS_STATUS_SUCCESS If attribute's value was successfully\n written to user memory. \\retval HIPBLAS_STATUS_INVALID_VALUE If \\p\n sizeInBytes is 0 and \\p sizeWritten is NULL, or if \\p sizeInBytes is non-zero\n and \\p buf is NULL, or \\p sizeInBytes doesn't match size of internal storage\n for the selected attribute."] + pub fn hipblasLtMatmulPreferenceGetAttribute( + pref: hipblasLtMatmulPreference_t, + attr: hipblasLtMatmulPreferenceAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Retrieve the possible algorithms\n\n \\details\n This function retrieves the possible algorithms for the matrix multiply\n operation hipblasLtMatmul() function with the given input matrices A, B and\n C, and the output matrix D. The output is placed in heuristicResultsArray[]\n in the order of increasing estimated compute time.\n\n @param[in]\n handle Pointer to the allocated hipBLASLt handle for the\n hipBLASLt context. See \\ref hipblasLtHandle_t .\n @param[in]\n matmulDesc Handle to a previously created matrix multiplication\n descriptor of type \\ref hipblasLtMatmulDesc_t .\n @param[in]\n Adesc,Bdesc,Cdesc,Ddesc Handles to the previously created matrix layout\n descriptors of the type \\ref hipblasLtMatrixLayout_t .\n @param[in]\n pref Pointer to the structure holding the heuristic\n search preferences descriptor. See \\ref hipblasLtMatmulPreference_t .\n @param[in]\n requestedAlgoCount Size of the \\p heuristicResultsArray (in elements).\n This is the requested maximum number of algorithms to return.\n @param[out]\n heuristicResultsArray[] Array containing the algorithm heuristics and\n associated runtime characteristics, returned by this function, in the order\n of increasing estimated compute time.\n @param[out]\n returnAlgoCount Number of algorithms returned by this function. This\n is the number of \\p heuristicResultsArray elements written.\n\n \\retval HIPBLAS_STATUS_SUCCESS If query was successful. Inspect\n heuristicResultsArray[0 to (returnAlgoCount -1)].state for the status of the\n results. \\retval HIPBLAS_STATUS_NOT_SUPPORTED If no heuristic function\n available for current configuration. \\retval HIPBLAS_STATUS_INVALID_VALUE If\n \\p requestedAlgoCount is less or equal to zero."] + pub fn hipblasLtMatmulAlgoGetHeuristic( + handle: hipblasLtHandle_t, + matmulDesc: hipblasLtMatmulDesc_t, + Adesc: hipblasLtMatrixLayout_t, + Bdesc: hipblasLtMatrixLayout_t, + Cdesc: hipblasLtMatrixLayout_t, + Ddesc: hipblasLtMatrixLayout_t, + pref: hipblasLtMatmulPreference_t, + requestedAlgoCount: ::std::os::raw::c_int, + heuristicResultsArray: *mut hipblasLtMatmulHeuristicResult_t, + returnAlgoCount: *mut ::std::os::raw::c_int, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtExtGroupedGemmAlgoGetHeuristic( + groupedgemm: hipblasLtExtGroupedGemm_t, + pref: hipblasLtMatmulPreference_t, + requestedAlgoCount: ::std::os::raw::c_int, + heuristicResultsArray: *mut hipblasLtMatmulHeuristicResult_t, + returnAlgoCount: *mut ::std::os::raw::c_int, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup library_module\n \\brief Retrieve the possible algorithms\n\n \\details\n This function computes the matrix multiplication of matrices A and B to\n produce the output matrix D, according to the following operation: \\p D = \\p\n alpha*( \\p A *\\p B) + \\p beta*( \\p C ), where \\p A, \\p B, and \\p C are input\n matrices, and \\p alpha and \\p beta are input scalars. Note: This function\n supports both in-place matrix multiplication (C == D and Cdesc == Ddesc) and\n out-of-place matrix multiplication (C != D, both matrices must have the same\n data type, number of rows, number of columns, batch size, and memory order).\n In the out-of-place case, the leading dimension of C can be different from\n the leading dimension of D. Specifically the leading dimension of C can be 0\n to achieve row or column broadcast. If Cdesc is omitted, this function\n assumes it to be equal to Ddesc.\n\n @param[in]\n handle Pointer to the allocated hipBLASLt handle for the\n hipBLASLt context. See \\ref hipblasLtHandle_t .\n @param[in]\n matmulDesc Handle to a previously created matrix multiplication\n descriptor of type \\ref hipblasLtMatmulDesc_t .\n @param[in]\n alpha,beta Pointers to the scalars used in the multiplication.\n @param[in]\n Adesc,Bdesc,Cdesc,Ddesc Handles to the previously created matrix layout\n descriptors of the type \\ref hipblasLtMatrixLayout_t .\n @param[in]\n A,B,C Pointers to the GPU memory associated with the\n corresponding descriptors \\p Adesc, \\p Bdesc and \\p Cdesc .\n @param[out]\n D Pointer to the GPU memory associated with the\n descriptor \\p Ddesc .\n @param[in]\n algo Handle for matrix multiplication algorithm to be\n used. See \\ref hipblasLtMatmulAlgo_t. When NULL, an implicit heuritics query\n with default search preferences will be performed to determine actual\n algorithm to use.\n @param[in]\n workspace Pointer to the workspace buffer allocated in the GPU\n memory. Pointer must be 16B aligned (that is, lowest 4 bits of address must\n be 0).\n @param[in]\n workspaceSizeInBytes Size of the workspace.\n @param[in]\n stream The HIP stream where all the GPU work will be\n submitted.\n\n \\retval HIPBLAS_STATUS_SUCCESS If the operation completed\n successfully. \\retval HIPBLAS_STATUS_EXECUTION_FAILED If HIP reported an\n execution error from the device. \\retval HIPBLAS_STATUS_ARCH_MISMATCH If\n the configured operation cannot be run using the selected device. \\retval\n HIPBLAS_STATUS_NOT_SUPPORTED If the current implementation on the\n selected device doesn't support the configured operation. \\retval\n HIPBLAS_STATUS_INVALID_VALUE If the parameters are unexpectedly NULL, in\n conflict or in an impossible configuration. For example, when\n workspaceSizeInBytes is less than workspace required by the configured algo.\n \\retval HIBLAS_STATUS_NOT_INITIALIZED If hipBLASLt handle has not been\n initialized."] + pub fn hipblasLtMatmul( + handle: hipblasLtHandle_t, + matmulDesc: hipblasLtMatmulDesc_t, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + Adesc: hipblasLtMatrixLayout_t, + B: *const ::std::os::raw::c_void, + Bdesc: hipblasLtMatrixLayout_t, + beta: *const ::std::os::raw::c_void, + C: *const ::std::os::raw::c_void, + Cdesc: hipblasLtMatrixLayout_t, + D: *mut ::std::os::raw::c_void, + Ddesc: hipblasLtMatrixLayout_t, + algo: *const hipblasLtMatmulAlgo_t, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, + stream: hipStream_t, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtExtGroupedGemmDestroy( + groupedgemm: hipblasLtExtGroupedGemm_t, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtExtGroupedGemmMakeArgument( + groupedgemm: hipblasLtExtGroupedGemm_t, + algo: *const hipblasLtMatmulAlgo_t, + workspace: *mut ::std::os::raw::c_void, + stream: hipStream_t, + ) -> hipblasStatus_t; +} +extern "C" { + #[must_use] + pub fn hipblasLtExtGroupedGemmRun( + groupedgemm: hipblasLtExtGroupedGemm_t, + stream: hipStream_t, + ) -> hipblasStatus_t; +} diff --git a/hipblaslt-sys/src/lib.rs b/hipblaslt-sys/src/lib.rs new file mode 100644 index 0000000..8449ff8 --- /dev/null +++ b/hipblaslt-sys/src/lib.rs @@ -0,0 +1,3 @@ +#[allow(warnings)] +mod hipblaslt; +pub use hipblaslt::*; \ No newline at end of file diff --git a/hipfft-sys/Cargo.toml b/hipfft-sys/Cargo.toml new file mode 100644 index 0000000..f79e007 --- /dev/null +++ b/hipfft-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hipfft-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "hipfft" + +[lib] \ No newline at end of file diff --git a/hipfft-sys/README b/hipfft-sys/README new file mode 100644 index 0000000..7326df4 --- /dev/null +++ b/hipfft-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/hipfft/hipfft.h -o src/hipfft.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --allowlist-function "hipfft.*" --must-use-type hipfftResult_t -- -I/opt/rocm/include -D__HIP_PLATFORM_AMD__ \ No newline at end of file diff --git a/hipfft-sys/build.rs b/hipfft-sys/build.rs new file mode 100644 index 0000000..61a5e9b --- /dev/null +++ b/hipfft-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=hipfft"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/hipfft-sys/src/hipfft.rs b/hipfft-sys/src/hipfft.rs new file mode 100644 index 0000000..bac893e --- /dev/null +++ b/hipfft-sys/src/hipfft.rs @@ -0,0 +1,458 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct float2 { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct double2 { + pub x: f64, + pub y: f64, +} +pub type hipFloatComplex = float2; +pub type hipDoubleComplex = double2; +pub type hipComplex = hipFloatComplex; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +pub type hipStream_t = *mut ihipStream_t; +impl hipfftResult_t { + #[doc = " hipFFT operation was successful"] + pub const HIPFFT_SUCCESS: hipfftResult_t = hipfftResult_t(0); +} +impl hipfftResult_t { + #[doc = " hipFFT was passed an invalid plan handle"] + pub const HIPFFT_INVALID_PLAN: hipfftResult_t = hipfftResult_t(1); +} +impl hipfftResult_t { + #[doc = " hipFFT failed to allocate GPU or CPU memory"] + pub const HIPFFT_ALLOC_FAILED: hipfftResult_t = hipfftResult_t(2); +} +impl hipfftResult_t { + #[doc = " No longer used"] + pub const HIPFFT_INVALID_TYPE: hipfftResult_t = hipfftResult_t(3); +} +impl hipfftResult_t { + #[doc = " User specified an invalid pointer or parameter"] + pub const HIPFFT_INVALID_VALUE: hipfftResult_t = hipfftResult_t(4); +} +impl hipfftResult_t { + #[doc = " Driver or internal hipFFT library error"] + pub const HIPFFT_INTERNAL_ERROR: hipfftResult_t = hipfftResult_t(5); +} +impl hipfftResult_t { + #[doc = " Failed to execute an FFT on the GPU"] + pub const HIPFFT_EXEC_FAILED: hipfftResult_t = hipfftResult_t(6); +} +impl hipfftResult_t { + #[doc = " hipFFT failed to initialize"] + pub const HIPFFT_SETUP_FAILED: hipfftResult_t = hipfftResult_t(7); +} +impl hipfftResult_t { + #[doc = " User specified an invalid transform size"] + pub const HIPFFT_INVALID_SIZE: hipfftResult_t = hipfftResult_t(8); +} +impl hipfftResult_t { + #[doc = " No longer used"] + pub const HIPFFT_UNALIGNED_DATA: hipfftResult_t = hipfftResult_t(9); +} +impl hipfftResult_t { + #[doc = " Missing parameters in call"] + pub const HIPFFT_INCOMPLETE_PARAMETER_LIST: hipfftResult_t = hipfftResult_t(10); +} +impl hipfftResult_t { + #[doc = " Execution of a plan was on different GPU than plan creation"] + pub const HIPFFT_INVALID_DEVICE: hipfftResult_t = hipfftResult_t(11); +} +impl hipfftResult_t { + #[doc = " Internal plan database error"] + pub const HIPFFT_PARSE_ERROR: hipfftResult_t = hipfftResult_t(12); +} +impl hipfftResult_t { + #[doc = " No workspace has been provided prior to plan execution"] + pub const HIPFFT_NO_WORKSPACE: hipfftResult_t = hipfftResult_t(13); +} +impl hipfftResult_t { + #[doc = " Function does not implement functionality for parameters given."] + pub const HIPFFT_NOT_IMPLEMENTED: hipfftResult_t = hipfftResult_t(14); +} +impl hipfftResult_t { + #[doc = " Operation is not supported for parameters given."] + pub const HIPFFT_NOT_SUPPORTED: hipfftResult_t = hipfftResult_t(16); +} +#[repr(transparent)] +#[doc = " @brief Result/status/error codes"] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipfftResult_t(pub ::std::os::raw::c_uint); +#[doc = " @brief Result/status/error codes"] +pub use self::hipfftResult_t as hipfftResult; +impl hipfftType_t { + #[doc = " Real to complex (interleaved)"] + pub const HIPFFT_R2C: hipfftType_t = hipfftType_t(42); +} +impl hipfftType_t { + #[doc = " Complex (interleaved) to real"] + pub const HIPFFT_C2R: hipfftType_t = hipfftType_t(44); +} +impl hipfftType_t { + #[doc = " Complex to complex (interleaved)"] + pub const HIPFFT_C2C: hipfftType_t = hipfftType_t(41); +} +impl hipfftType_t { + #[doc = " Double to double-complex (interleaved)"] + pub const HIPFFT_D2Z: hipfftType_t = hipfftType_t(106); +} +impl hipfftType_t { + #[doc = " Double-complex (interleaved) to double"] + pub const HIPFFT_Z2D: hipfftType_t = hipfftType_t(108); +} +impl hipfftType_t { + #[doc = " Double-complex to double-complex (interleaved)"] + pub const HIPFFT_Z2Z: hipfftType_t = hipfftType_t(105); +} +#[repr(transparent)] +#[doc = " @brief Transform type\n @details This type is used to declare the Fourier transform type that will be executed."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipfftType_t(pub ::std::os::raw::c_uint); +#[doc = " @brief Transform type\n @details This type is used to declare the Fourier transform type that will be executed."] +pub use self::hipfftType_t as hipfftType; +impl hipfftLibraryPropertyType_t { + pub const HIPFFT_MAJOR_VERSION: hipfftLibraryPropertyType_t = hipfftLibraryPropertyType_t(0); +} +impl hipfftLibraryPropertyType_t { + pub const HIPFFT_MINOR_VERSION: hipfftLibraryPropertyType_t = hipfftLibraryPropertyType_t(1); +} +impl hipfftLibraryPropertyType_t { + pub const HIPFFT_PATCH_LEVEL: hipfftLibraryPropertyType_t = hipfftLibraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hipfftLibraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::hipfftLibraryPropertyType_t as hipfftLibraryPropertyType; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hipfftHandle_t { + _unused: [u8; 0], +} +pub type hipfftHandle = *mut hipfftHandle_t; +pub type hipfftComplex = hipComplex; +pub type hipfftDoubleComplex = hipDoubleComplex; +pub type hipfftReal = f32; +pub type hipfftDoubleReal = f64; +extern "C" { + #[doc = " @brief Create a new one-dimensional FFT plan.\n\n @details Allocate and initialize a new one-dimensional FFT plan.\n\n @param[out] plan Pointer to the FFT plan handle.\n @param[in] nx FFT length.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to compute."] + pub fn hipfftPlan1d( + plan: *mut hipfftHandle, + nx: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Create a new two-dimensional FFT plan.\n\n @details Allocate and initialize a new two-dimensional FFT plan.\n Two-dimensional data should be stored in C ordering (row-major\n format), so that indexes in y-direction (j index) vary the\n fastest.\n\n @param[out] plan Pointer to the FFT plan handle.\n @param[in] nx Number of elements in the x-direction (slow index).\n @param[in] ny Number of elements in the y-direction (fast index).\n @param[in] type FFT type."] + pub fn hipfftPlan2d( + plan: *mut hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: hipfftType, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Create a new three-dimensional FFT plan.\n\n @details Allocate and initialize a new three-dimensional FFT plan.\n Three-dimensional data should be stored in C ordering (row-major\n format), so that indexes in z-direction (k index) vary the\n fastest.\n\n @param[out] plan Pointer to the FFT plan handle.\n @param[in] nx Number of elements in the x-direction (slowest index).\n @param[in] ny Number of elements in the y-direction.\n @param[in] nz Number of elements in the z-direction (fastest index).\n @param[in] type FFT type."] + pub fn hipfftPlan3d( + plan: *mut hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: hipfftType, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Create a new batched rank-dimensional FFT plan with advanced data layout.\n\n @details Allocate and initialize a new batched rank-dimensional\n FFT plan. The number of elements to transform in each direction of\n the input data is specified in n.\n\n The batch parameter tells hipFFT how many transforms to perform.\n The distance between the first elements of two consecutive batches\n of the input and output data are specified with the idist and odist\n parameters.\n\n The inembed and onembed parameters define the input and output data\n layouts. The number of elements in the data is assumed to be larger\n than the number of elements in the transform. Strided data layouts\n are also supported. Strides along the fastest direction in the input\n and output data are specified via the istride and ostride parameters.\n\n If both inembed and onembed parameters are set to NULL, all the\n advanced data layout parameters are ignored and reverted to default\n values, i.e., the batched transform is performed with non-strided data\n access and the number of data/transform elements are assumed to be\n equivalent.\n\n @param[out] plan Pointer to the FFT plan handle.\n @param[in] rank Dimension of transform (1, 2, or 3).\n @param[in] n Number of elements to transform in the x/y/z directions.\n @param[in] inembed Number of elements in the input data in the x/y/z directions.\n @param[in] istride Distance between two successive elements in the input data.\n @param[in] idist Distance between input batches.\n @param[in] onembed Number of elements in the output data in the x/y/z directions.\n @param[in] ostride Distance between two successive elements in the output data.\n @param[in] odist Distance between output batches.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to perform."] + pub fn hipfftPlanMany( + plan: *mut hipfftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Allocate a new plan."] + pub fn hipfftCreate(plan: *mut hipfftHandle) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Set scaling factor.\n\n @details hipFFT multiplies each element of the result by the given factor at the end of the transform.\n\n The supplied factor must be a finite number. That is, it must neither be infinity nor NaN.\n\n This function must be called after the plan is allocated using\n ::hipfftCreate, but before the plan is initialized by any of the\n \"MakePlan\" functions. Therefore, API functions that combine\n creation and initialization (::hipfftPlan1d, ::hipfftPlan2d,\n ::hipfftPlan3d, and ::hipfftPlanMany) cannot set a scale factor.\n\n Note that the scale factor applies to both forward and\n backward transforms executed with the specified plan handle."] + pub fn hipfftExtPlanScaleFactor(plan: hipfftHandle, scalefactor: f64) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Initialize a new one-dimensional FFT plan.\n\n @details Assumes that the plan has been created already, and\n modifies the plan associated with the plan handle.\n\n @param[in] plan Handle of the FFT plan.\n @param[in] nx FFT length.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to compute."] + pub fn hipfftMakePlan1d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Initialize a new two-dimensional FFT plan.\n\n @details Assumes that the plan has been created already, and\n modifies the plan associated with the plan handle.\n Two-dimensional data should be stored in C ordering (row-major\n format), so that indexes in y-direction (j index) vary the\n fastest.\n\n @param[in] plan Handle of the FFT plan.\n @param[in] nx Number of elements in the x-direction (slow index).\n @param[in] ny Number of elements in the y-direction (fast index).\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftMakePlan2d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Initialize a new two-dimensional FFT plan.\n\n @details Assumes that the plan has been created already, and\n modifies the plan associated with the plan handle.\n Three-dimensional data should be stored in C ordering (row-major\n format), so that indexes in z-direction (k index) vary the\n fastest.\n\n @param[in] plan Handle of the FFT plan.\n @param[in] nx Number of elements in the x-direction (slowest index).\n @param[in] ny Number of elements in the y-direction.\n @param[in] nz Number of elements in the z-direction (fastest index).\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftMakePlan3d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Initialize a new batched rank-dimensional FFT plan with advanced data layout.\n\n @details Assumes that the plan has been created already, and\n modifies the plan associated with the plan handle. The number\n of elements to transform in each direction of the input data\n in the FFT plan is specified in n.\n\n The batch parameter tells hipFFT how many transforms to perform.\n The distance between the first elements of two consecutive batches\n of the input and output data are specified with the idist and odist\n parameters.\n\n The inembed and onembed parameters define the input and output data\n layouts. The number of elements in the data is assumed to be larger\n than the number of elements in the transform. Strided data layouts\n are also supported. Strides along the fastest direction in the input\n and output data are specified via the istride and ostride parameters.\n\n If both inembed and onembed parameters are set to NULL, all the\n advanced data layout parameters are ignored and reverted to default\n values, i.e., the batched transform is performed with non-strided data\n access and the number of data/transform elements are assumed to be\n equivalent.\n\n @param[out] plan Pointer to the FFT plan handle.\n @param[in] rank Dimension of transform (1, 2, or 3).\n @param[in] n Number of elements to transform in the x/y/z directions.\n @param[in] inembed Number of elements in the input data in the x/y/z directions.\n @param[in] istride Distance between two successive elements in the input data.\n @param[in] idist Distance between input batches.\n @param[in] onembed Number of elements in the output data in the x/y/z directions.\n @param[in] ostride Distance between two successive elements in the output data.\n @param[in] odist Distance between output batches.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to perform.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftMakePlanMany( + plan: hipfftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + pub fn hipfftMakePlanMany64( + plan: hipfftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + type_: hipfftType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return an estimate of the work area size required for a 1D plan.\n\n @param[in] nx Number of elements in the x-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftEstimate1d( + nx: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return an estimate of the work area size required for a 2D plan.\n\n @param[in] nx Number of elements in the x-direction.\n @param[in] ny Number of elements in the y-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftEstimate2d( + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return an estimate of the work area size required for a 3D plan.\n\n @param[in] nx Number of elements in the x-direction.\n @param[in] ny Number of elements in the y-direction.\n @param[in] nz Number of elements in the z-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftEstimate3d( + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return an estimate of the work area size required for a rank-dimensional plan.\n\n @param[in] rank Dimension of FFT transform (1, 2, or 3).\n @param[in] n Number of elements in the x/y/z directions.\n @param[in] inembed\n @param[in] istride\n @param[in] idist Distance between input batches.\n @param[in] onembed\n @param[in] ostride\n @param[in] odist Distance between output batches.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to perform.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftEstimateMany( + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return size of the work area size required for a 1D plan.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] nx Number of elements in the x-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftGetSize1d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return size of the work area size required for a 2D plan.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] nx Number of elements in the x-direction.\n @param[in] ny Number of elements in the y-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftGetSize2d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return size of the work area size required for a 3D plan.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] nx Number of elements in the x-direction.\n @param[in] ny Number of elements in the y-direction.\n @param[in] nz Number of elements in the z-direction.\n @param[in] type FFT type.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftGetSize3d( + plan: hipfftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: hipfftType, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return size of the work area size required for a rank-dimensional plan.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] rank Dimension of FFT transform (1, 2, or 3).\n @param[in] n Number of elements in the x/y/z directions.\n @param[in] inembed\n @param[in] istride\n @param[in] idist Distance between input batches.\n @param[in] onembed\n @param[in] ostride\n @param[in] odist Distance between output batches.\n @param[in] type FFT type.\n @param[in] batch Number of batched transforms to perform.\n @param[out] workSize Pointer to work area size (returned value)."] + pub fn hipfftGetSizeMany( + plan: hipfftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: hipfftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + pub fn hipfftGetSizeMany64( + plan: hipfftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + type_: hipfftType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Return size of the work area size required for a rank-dimensional plan.\n\n @param[in] plan Pointer to the FFT plan."] + pub fn hipfftGetSize(plan: hipfftHandle, workSize: *mut usize) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Set the plan's auto-allocation flag. The plan will allocate its own workarea.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] autoAllocate 0 to disable auto-allocation, non-zero to enable."] + pub fn hipfftSetAutoAllocation( + plan: hipfftHandle, + autoAllocate: ::std::os::raw::c_int, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Set the plan's work area.\n\n @param[in] plan Pointer to the FFT plan.\n @param[in] workArea Pointer to the work area (on device)."] + pub fn hipfftSetWorkArea( + plan: hipfftHandle, + workArea: *mut ::std::os::raw::c_void, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (float) complex-to-complex FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device).\n @param direction Either `HIPFFT_FORWARD` or `HIPFFT_BACKWARD`."] + pub fn hipfftExecC2C( + plan: hipfftHandle, + idata: *mut hipfftComplex, + odata: *mut hipfftComplex, + direction: ::std::os::raw::c_int, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (float) real-to-complex FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device)."] + pub fn hipfftExecR2C( + plan: hipfftHandle, + idata: *mut hipfftReal, + odata: *mut hipfftComplex, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (float) complex-to-real FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device)."] + pub fn hipfftExecC2R( + plan: hipfftHandle, + idata: *mut hipfftComplex, + odata: *mut hipfftReal, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (double) complex-to-complex FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device).\n @param direction Either `HIPFFT_FORWARD` or `HIPFFT_BACKWARD`."] + pub fn hipfftExecZ2Z( + plan: hipfftHandle, + idata: *mut hipfftDoubleComplex, + odata: *mut hipfftDoubleComplex, + direction: ::std::os::raw::c_int, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (double) real-to-complex FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device)."] + pub fn hipfftExecD2Z( + plan: hipfftHandle, + idata: *mut hipfftDoubleReal, + odata: *mut hipfftDoubleComplex, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Execute a (double) complex-to-real FFT.\n\n @details If the input and output buffers are equal, an in-place\n transform is performed.\n\n @param plan The FFT plan.\n @param idata Input data (on device).\n @param odata Output data (on device)."] + pub fn hipfftExecZ2D( + plan: hipfftHandle, + idata: *mut hipfftDoubleComplex, + odata: *mut hipfftDoubleReal, + ) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Set HIP stream to execute plan on.\n\n @details Associates a HIP stream with a hipFFT plan. All kernels\n launched by this plan are associated with the provided stream.\n\n @param plan The FFT plan.\n @param stream The HIP stream."] + pub fn hipfftSetStream(plan: hipfftHandle, stream: hipStream_t) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Destroy and deallocate an existing plan."] + pub fn hipfftDestroy(plan: hipfftHandle) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Get rocFFT/cuFFT version.\n\n @param[out] version cuFFT/rocFFT version (returned value)."] + pub fn hipfftGetVersion(version: *mut ::std::os::raw::c_int) -> hipfftResult; +} +extern "C" { + #[doc = " @brief Get library property.\n\n @param[in] type Property type.\n @param[out] value Returned value."] + pub fn hipfftGetProperty( + type_: hipfftLibraryPropertyType, + value: *mut ::std::os::raw::c_int, + ) -> hipfftResult; +} diff --git a/hipfft-sys/src/lib.rs b/hipfft-sys/src/lib.rs new file mode 100644 index 0000000..eb0f281 --- /dev/null +++ b/hipfft-sys/src/lib.rs @@ -0,0 +1,3 @@ +#[allow(warnings)] +mod hipfft; +pub use hipfft::*; \ No newline at end of file diff --git a/hiprt-sys/Cargo.toml b/hiprt-sys/Cargo.toml new file mode 100644 index 0000000..621b5d7 --- /dev/null +++ b/hiprt-sys/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "hiprt-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] + +[dependencies] +libloading = "0.8" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi", "std"] } +widestring = "1.0" diff --git a/hiprt-sys/Makefile.toml b/hiprt-sys/Makefile.toml new file mode 100644 index 0000000..f21834a --- /dev/null +++ b/hiprt-sys/Makefile.toml @@ -0,0 +1,16 @@ +[tasks.bindgen] +command = "bindgen" +args = [ + "include/hiprt.h", + "-o", "src/hiprt.rs", + "--rust-target", "1.64", + "--no-layout-tests", + "--no-derive-debug", + "--default-enum-style=newtype", + "--dynamic-loading", "HipRt", + "--must-use-type", "hiprtError", + "--allowlist-function", "hiprt.*", + "--allowlist-type", "hiprt.*", + "--allowlist-var", "^HIPRT.*$", + "--", "-I", "include", "-x", "c++", +] \ No newline at end of file diff --git a/hiprt-sys/include/hiprt.h b/hiprt-sys/include/hiprt.h new file mode 100644 index 0000000..af756bc --- /dev/null +++ b/hiprt-sys/include/hiprt.h @@ -0,0 +1,714 @@ +#ifndef HIPRT_H +#define HIPRT_H + +#define HIPRT_API_MAJOR_VERSION 0x000001 +#define HIPRT_API_MINOR_VERSION 0x000002 +#define HIPRT_API_PATCH_VERSION 0x000000 +#define HIPRT_API_VERSION HIPRT_API_MAJOR_VERSION * 1000000 + HIPRT_API_MINOR_VERSION * 1000 + HIPRT_API_PATCH_VERSION + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined( _MSC_VER ) +#ifdef HIPRT_EXPORTS +#define HIPRT_API __declspec( dllexport ) +#else +#define HIPRT_API __declspec( dllimport ) +#endif +#elif defined( __GNUC__ ) +#ifdef HIPRT_EXPORTS +#define HIPRT_API __attribute__( ( visibility( "default" ) ) ) +#else +#define HIPRT_API +#endif +#else +#define HIPRT_API +#pragma warning Unknown dynamic link import / export semantics. +#endif + +struct _hiprtGeometry; +struct _hiprtGeometryCustom; +struct _hiprtScene; +struct _hiprtContext; +struct _hiprtCustomFuncTable; + +typedef void* hiprtDevicePtr; +typedef hiprtDevicePtr hiprtGeometry; +typedef hiprtDevicePtr hiprtScene; +typedef uint32_t hiprtBuildFlags; +typedef uint32_t hiprtRayMask; +typedef uint32_t hiprtCustomType; +typedef _hiprtContext* hiprtContext; +typedef _hiprtCustomFuncTable* hiprtCustomFuncTable; + +typedef int hiprtApiDevice; // hipDevice, cuDevice +typedef void* hiprtApiCtx; // hipCtx, cuCtx +typedef void* hiprtApiStream; // hipStream, cuStream +typedef void* hiprtApiFunction; // hipFunction, cuFunction + +/** \brief Various constants. + * + */ +enum : uint32_t +{ + hiprtInvalidValue = ~0u, + hiprtMaxCustomFunctions = 65536, +}; + +/** \brief Error codes. + * + */ +typedef enum +{ + hiprtSuccess = 0, + hiprtErrorNotImplemented = 1, + hiprtErrorInternal = 2, + hiprtErrorOutOfHostMemory = 3, + hiprtErrorOutOfDeviceMemory = 4, + hiprtErrorInvalidApiVersion = 5, + hiprtErrorInvalidParameter = 6 +} hiprtError; + +/** \brief Type of geometry/scene build operation. + * + * hiprtBuildGeometry/hiprtBuildScene can either build or update + * an underlying acceleration structure. + */ +typedef enum +{ + hiprtBuildOperationBuild = 1, + hiprtBuildOperationUpdate = 2 +} hiprtBuildOperation; + +/** \brief Hint flags for geometry/scene build functions. + * + * hiprtBuildGeometry/hiprtBuildScene use these flags to choose + * an appropriate build format/algorithm. + */ +typedef enum +{ + hiprtBuildFlagBitPreferFastBuild = 0, + hiprtBuildFlagBitPreferBalancedBuild = 1, + hiprtBuildFlagBitPreferHighQualityBuild = 2, + hiprtBuildFlagBitCustomBvhImport = 3, + hiprtBuildFlagBitDisableSpatialSplits = 1 << 2 +} hiprtBuildFlagBits; + +/** \brief Geometric primitive type. + * + * hiprtGeometry can be built from multiple primitive types, + * such as triangle meshes, AABB lists, line lists, etc. This enum + * defines primitive type for hiprtBuildGeometry function. + */ +typedef enum +{ + hiprtPrimitiveTypeTriangleMesh, + hiprtPrimitiveTypeAABBList, +} hiprtPrimitiveType; + +/** \brief Traversal state. + * + * On-device traversal can be in either hit state (and can be continued using + * hiprtNextHit) or finished state. + */ +typedef enum +{ + hiprtTraversalStateInit, + hiprtTraversalStateFinished, + hiprtTraversalStateHit, + hiprtTraversalStateStackOverflow +} hiprtTraversalState; + +/** \brief Ray traversal type. + * + */ +enum hiprtTraversalType +{ + /*!< 0 or 1 element iterator with any hit along the ray */ + hiprtTraversalTerminateAtAnyHit = 1, + /*!< 0 or 1 element iterator with a closest hit along the ray */ + hiprtTraversalTerminateAtClosestHit = 2, +}; + +/** \brief Bvh node type. + * + */ +enum hiprtBvhNodeType +{ + /*!< Leaf node */ + hiprtBvhNodeTypeInternal = 0, + /*!< Internal node */ + hiprtBvhNodeTypeLeaf = 1, +}; + +/** \brief Ray data structure. + * + */ +struct hiprtRay +{ + /*!< Ray origin */ + hiprtFloat3 origin; + /*!< Ray time for motion blur */ + float time; + /*!< Ray direction */ + hiprtFloat3 direction; + /*!< Ray maximum distance */ + float maxT; +}; + +/** \brief Ray hit data structure. + * + */ +struct hiprtHit +{ + /*!< Instance ID */ + uint32_t instanceID; + /*!< Primitive ID */ + uint32_t primID; + /*!< Texture coordinates */ + hiprtFloat2 uv; + /*!< Geeometric normal (not normalized) */ + hiprtFloat3 normal; + /*!< Distance */ + float t; +}; + +/** \brief Insersection function for custom primitives. + * + * \param ray Ray. + * \param primID Primtive ID. + * \param data User data. + * \param payload Payload for additional outputs. + * \param uv Output texture coordinates. + * \param normal Output normal. + * \param t Output distance. + * \return A flag indicating hit. + */ +typedef bool ( *hiprtIntersectFunc )( + const hiprtRay& ray, + uint32_t primID, + const void* data, + void* payload, + hiprtFloat2& uv, + hiprtFloat3& normal, + float& t ); + +/** \brief Set of functions for custom primitives. + * + */ +typedef struct +{ + hiprtIntersectFunc intersectFunc; + const void* intersectFuncData; +} hiprtCustomFuncSet; + +/** \brief Device type. + * + */ +enum hiprtDeviceType +{ + /*!< AMD device */ + hiprtDeviceAMD, + /*!< Nvidia device */ + hiprtDeviceNVIDIA, +}; + +/** \brief Context creation input. + * + */ +typedef struct +{ + /*!< HIPRT API context */ + hiprtApiCtx ctxt; + /*!< HIPRT API device */ + hiprtApiDevice device; + /*!< HIPRT API device type */ + hiprtDeviceType deviceType; +} hiprtContextCreationInput; + +/** \brief Various flags controlling scene/geometry build process. + * + */ +typedef struct +{ + /*!< Build flags */ + hiprtBuildFlags buildFlags; +} hiprtBuildOptions; + +/** \brief Triangle mesh primitive. + * + * Triangle mesh primitive is represented as an indexed vertex array. + * Vertex and index arrays are defined using device pointers and strides. + * Each vertex has to have 3 components: (x, y, z) coordinates. + * Indices are organized into triples (i0, i1, i2) - one for each triangle. + */ +typedef struct +{ + /*!< Device pointer to vertex data */ + hiprtDevicePtr vertices; + /*!< Number of vertices in vertex array */ + uint32_t vertexCount; + /*!< Stride in bytes between two vertices */ + uint32_t vertexStride; + + /*!< Device pointer to index data */ + hiprtDevicePtr triangleIndices; + /*!< Number of trinagles in index array */ + uint32_t triangleCount; + /*!< Stride in bytes between two triangles */ + uint32_t triangleStride; +} hiprtTriangleMeshPrimitive; + +/** \brief AABB list primitive. + * + * AABB list is an array of axis aligned bounding boxes, represented + * by device memory pointer and stride between two consequetive boxes. + * Each AABB is a pair of float4 values (xmin, ymin, zmin, unused), (xmax, ymax, + * zmax, unused). + */ +typedef struct +{ + /*!< Device pointer to AABB data */ + hiprtDevicePtr aabbs; + /*!< Number of AABBs in the array */ + uint32_t aabbCount; + /*!< Stride in bytes between two AABBs */ + uint32_t aabbStride; +} hiprtAABBListPrimitive; + +/** \brief Bvh node for custom import Bvh. + * + */ +typedef struct +{ + /*!< Child indices (empty slot needs to be marked by hiprtInvalidValue) */ + uint32_t childIndices[4]; + /*!< Child node types */ + hiprtBvhNodeType childNodeTypes[4]; + /*!< Node bounding box min */ + hiprtFloat3 boundingBoxMin; + /*!< Node bounding box max */ + hiprtFloat3 boundingBoxMax; + + int pad[2]; +} hiprtBvhNode; + +/** \brief Bvh node list. + * + */ +typedef struct +{ + /*!< Array of hiprtBvhNode's */ + hiprtDevicePtr nodes; + /*!< Number of nodes */ + uint32_t nodeCount; +} hiprtBvhNodeList; + +/** \brief Input for geometry build/update operation. + * + * Build input defines concrete primitive type and a pointer to an actual + * primitive description. + */ +typedef struct +{ + /*!< Primitive type */ + hiprtPrimitiveType type; + /*!< Defines the following union */ + union + { + struct + { + /*!< Triangle mesh */ + hiprtTriangleMeshPrimitive* primitive; + } triangleMesh; + struct + { + /*!< Bounding boxes of custom primitives */ + hiprtAABBListPrimitive* primitive; + /*!< Type of custom primitives */ + hiprtCustomType customType; + } aabbList; + }; + /*!< Custom Bvh nodes (optional) */ + hiprtBvhNodeList* nodes; +} hiprtGeometryBuildInput; + +/** \brief Build input for the scene. + * + * Scene consists of a set of instances. Each of the instances is defined by: + * - Root pointer of the corresponding geometry + * - Transformation header + * - Mask + * + * Instances can refer to the same geometry but with different transformations + * (essentially implementing instancing). Mask is used to implement ray + * masking: ray mask is bitwise &ded with an instance mask, and no intersections + * are evaluated with the primitive of corresponding instance if the result is + * 0. The transformation header defines the offset and the number of consecutive + * transformation frames in the frame array for each instance. More than one frame + * is interpreted as motion blur. If the transformation headers is NULL, it + * assumes one frame per instance. Optionally, it is possible to import a custom + * BVH by setting nodes and the corresponding build flag. + */ +typedef struct +{ + /*!< Array of instanceCount pointers to geometries */ + hiprtDevicePtr instanceGeometries; + /*!< Array of instanceCount transform headers (optional: per object frame assumed if NULL) */ + hiprtDevicePtr instanceTransformHeaders; + /*!< Array of frameCount frames (supposed to be ordered according to time) */ + hiprtDevicePtr instanceFrames; + /*!< Per object bit masks for instance masking (optional: if NULL masks treated as 0xFFFFFFFF) */ + hiprtDevicePtr instanceMasks; + /*!< Custom Bvh nodes (optional) */ + hiprtBvhNodeList* nodes; + /*!< Number of instances */ + uint32_t instanceCount; + /*!< Number of frames (such that instanceCount <= frameCount) */ + uint32_t frameCount; +} hiprtSceneBuildInput; + +/** \brief Transformation frame. + * + * Defines scale, translation, rotation, and time. + */ +typedef struct +{ + /*!< Rotation (axis and angle) */ + hiprtFloat4 rotation; + /*!< Scale */ + hiprtFloat3 scale; + /*!< Translation */ + hiprtFloat3 translation; + /*!< Time */ + float time; + + int pad; +} hiprtFrame; + +/** \brief Transformation header. + * + * Defines defines the index to the array of frames and the number of frames. + */ +typedef struct +{ + /*!< Frame index */ + uint32_t frameIndex; + /*!< Number of frames */ + uint32_t frameCount; +} hiprtTransformHeader; + +/** \brief Create HIPRT API context. + * + * All HIPRT functions expect context as their first argument. Context + * keeps global data required by HIPRT session. Calls made from different + * threads with different HIPRT contexts are safe. Calls with the same context + * should be externally synchronized by the client. + * + * \param hiprtApiVersion API version. + * \param outContext Created context. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtCreateContext( uint32_t hiprtApiVersion, hiprtContextCreationInput& input, hiprtContext* outContext ); + +/** \brief Destory HIPRT API context. + * + * Destroys all the global resources used by HIPRT session. Further calls + * with this context are prohibited. + * + * \param context API context. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtDestroyContext( hiprtContext context ); + +/** \brief Create a geometry. + * + * This function creates + * hiprtGeometry representing acceleration structure topology. + * + * \param context HIPRT API context. + * \param buildInput Describes input primitive to build geometry from. + * \param buildOptions Various flags controlling build process. + * \param outGeometry Resulting geometry. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtCreateGeometry( + hiprtContext context, + const hiprtGeometryBuildInput* buildInput, + const hiprtBuildOptions* buildOptions, + hiprtGeometry* outGeometry ); + +/** \brief Destroy a geometry. + * + * This function destroys + * hiprtGeometry representing acceleration structure topology. + * + * \param context HIPRT API context. + * \param outGeometry Resulting geometry. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtDestroyGeometry( hiprtContext context, hiprtGeometry outGeometry ); + +/** \brief Build or update a geometry. + * + * Given geometry description from the client, this function builds + * hiprtGeometry representing acceleration structure topology (in case of a + * build) or updates acceleration structure keeping topology intact (update). + * + * \param context HIPRT API context. + * \param buildOperation Type of build operation. + * \param buildInput Describes input primitive to build geometry from. + * \param buildOptions Various flags controlling build process. + * \param attributeOutputs Describes additional values written into vidmem. + * \param attributeOutputCount Number of additional attributes, can be 0. + * \param temporaryBuffer Temporary buffer for build operation. + * \param stream to run acceleration structure build command. + * \param outGeometry Resulting geometry. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtBuildGeometry( + hiprtContext context, + hiprtBuildOperation buildOperation, + const hiprtGeometryBuildInput* buildInput, + const hiprtBuildOptions* buildOptions, + hiprtDevicePtr temporaryBuffer, + hiprtApiStream stream, + hiprtGeometry outGeometry ); + +/** \brief Get temporary storage requirements for geometry build. + * + * \param context HIPRT API context. + * \param buildInput Describes input primitive to build geometry from. + * \param buildOptions Various flags controlling build process. + * \param outSize Pointer to write result to. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtGetGeometryBuildTemporaryBufferSize( + hiprtContext context, const hiprtGeometryBuildInput* buildInput, const hiprtBuildOptions* buildOptions, size_t* outSize ); + +/** \brief Get temporary storage requirements for scene trace. + * + * \param context HIPRT API context. + * \param scene Built scene for trace. + * \param numRays Rays to be issued. + * \param outSize Pointer to write result to. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError +hiprtGetGeometryTraceTemporaryBufferSize( hiprtContext context, hiprtGeometry scene, uint32_t numRays, size_t* outSize ); + +/** \brief Create a scene. + * + * This function creates + * hiprtScene representing acceleration structure topology. + * + * \param context HIPRT API context. + * \param buildInput Decribes input geometires to build scene for. + * \param buildOptions Various flags controlling build process. + * \param outScene Resulting scene. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtCreateScene( + hiprtContext context, const hiprtSceneBuildInput* buildInput, const hiprtBuildOptions* buildOptions, hiprtScene* outScene ); + +/** \brief Destroy a scene. + * + * This function destroys + * hiprtScene representing acceleration structure topology. + * + * \param context HIPRT API context. + * \param outScene Resulting scene. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtDestroyScene( hiprtContext context, hiprtScene outScene ); + +/** \brief Build or update a scene. + * + * Given a number of hiprtGeometries from the client, this function builds + * hiprtScene representing top level acceleration structure topology (in case of + * a build) or updates acceleration structure keeping topology intact (update). + * + * \param context HIPRT API context. + * \param buildOperation Type of build operation. + * \param buildInput Decribes input geometires to build scene for. + * \param buildOptions Various flags controlling build process. + * \param temporaryBuffer Temporary buffer for build operation. + * \param stream to run acceleration structure build command. + * \param outScene Resulting scene. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtBuildScene( + hiprtContext context, + hiprtBuildOperation buildOperation, + const hiprtSceneBuildInput* buildInput, + const hiprtBuildOptions* buildOptions, + hiprtDevicePtr temporaryBuffer, + hiprtApiStream stream, + hiprtScene outScene ); + +/** \brief Get temporary storage requirements for scene build. + * + * \param context HIPRT API context. + * \param buildInput Decribes input geometires to build scene for. + * \param buildOptions Various flags controlling build process. + * \param outSize Pointer to write result to. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtGetSceneBuildTemporaryBufferSize( + hiprtContext context, const hiprtSceneBuildInput* buildInput, const hiprtBuildOptions* buildOptions, size_t* outSize ); + +/** \brief Get temporary storage requirements for scene trace. + * + * \param context HIPRT API context. + * \param scene Built scene for trace. + * \param numRays Rays to be issued. + * \param outSize Pointer to write result to. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError +hiprtGetSceneTraceTemporaryBufferSize( hiprtContext context, hiprtScene scene, uint32_t numRays, size_t* outSize ); + +/** \brief Creates a custom function table (for custom geometry). + * + * \param context HIPRT API context. + * \param outFuncTable Resulting table. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtCreateCustomFuncTable( hiprtContext context, hiprtCustomFuncTable* outFuncTable ); + +/** \brief Sets a custom function table. + * + * \param context HIPRT API context. + * \param outFuncTable Resulting table. + * \param index Index of the set in the table. + * \param set Function set to be set. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError +hiprtSetCustomFuncTable( hiprtContext context, hiprtCustomFuncTable outFuncTable, uint32_t index, hiprtCustomFuncSet set ); + +/** \brief Destroys a custom function table. + * + * \param context HIPRT API context. + * \param outFuncTable Resulting table. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtDestroyCustomFuncTable( hiprtContext context, hiprtCustomFuncTable outFuncTable ); + +/** \brief Saves hiprtGeometry to a binary file. + * + * \param context HIPRT API context. + * \param inGeometry Geometry to be saved. + * \param filename File name with full path. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtSaveGeometry( hiprtContext context, hiprtGeometry inGeometry, const char* filename ); + +/** \brief Loads hiprtGeometry to a binary file. + * + * \param context HIPRT API context. + * \param outGeometry Geometry to be loaded. + * \param filename File name with full path. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtLoadGeometry( hiprtContext context, hiprtGeometry* outGeometry, const char* filename ); + +/** \brief Saves hiprtScene to a binary file. + * + * \param context HIPRT API context. + * \param inScene Scene to be saved. + * \param filename File name with full path. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtSaveScene( hiprtContext context, hiprtScene inScene, const char* filename ); + +/** \brief Loads hiprtScene to a binary file. + * + * \param context HIPRT API context. + * \param outScene Scene to be loaded. + * \param filename File name with full path. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtLoadScene( hiprtContext context, hiprtScene* outScene, const char* filename ); + +/** \brief Output scene's AABB. + * + * \param context HIPRT API context. + * \param inGeometry Geometry to be queried. + * \param outAabbMin The bounding box min. bound. + * \param outAabbMax The bounding box max. bound. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtExportGeometryAabb( hiprtContext context, hiprtGeometry inGeometry, hiprtFloat3& outAabbMin, hiprtFloat3& outAabbMax ); + +/** \brief Output scene's AABB. + * + * \param context HIPRT API context. + * \param inScene Scene to be queried. + * \param outAabbMin The bounding box min. bound. + * \param outAabbMax The bounding box max. bound. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtExportSceneAabb( hiprtContext context, hiprtScene inScene, hiprtFloat3& outAabbMin, hiprtFloat3& outAabbMax ); + +/** \brief Get Program instance with HIPRT routines. + * \param functionName function to which handle will be returned, cannot be NULL. + * \param context HIPRT API context. + * \param src HIP program source. + * \param name Program source filename. + * \param numHeaders Number of headers, numHeaders must be greater than or equal to 0. + * \param headers Sources of the headers, headers can be NULL when numHeaders is 0. + * \param includeNames Name of each header by which they can be included in the HIP program source, includeNames can be NULL + * when numHeaders is 0. + * \param options Compiler options, can be NULL. + * \param progOut Output build program instance. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtBuildTraceProgram( + hiprtContext context, + const char* functionName, + const char* src, + const char* name, + int numHeaders, + const char** headers, + const char** includeNames, + const char** options, + int nOptions, + void* progOut ); + +/** \brief Get binary with HIPRT routines. + * + * \param prog program instance. + * \param size Output size of binary . + * \param binary Output if NULL function returns size of parameter else returned binary(application should allocate for binary).. + * \return HIPRT error in case of a failure, hiprtSuccess otherwise. + */ +HIPRT_API hiprtError hiprtBuildTraceGetBinary( + void* prog, + size_t* size, + void* binary); + +/** \brief Setting log level. + * + * \param path user defined path to cache kernels. + */ +HIPRT_API void hiprtSetCacheDirPath( + const char* path ); + + +/** \brief Setting log level. + * + * \param level Desired log level. + */ +HIPRT_API void hiprtSetLogLevel( int level = 0 ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hiprt-sys/include/hiprt/hiprt_vec.h b/hiprt-sys/include/hiprt/hiprt_vec.h new file mode 100644 index 0000000..11eb531 --- /dev/null +++ b/hiprt-sys/include/hiprt/hiprt_vec.h @@ -0,0 +1,79 @@ +#pragma once +#if !defined( __KERNELCC__ ) + +#if !defined( HIPRT_EXPORTS ) +#define HIPRT_HOST_DEVICE +#define HIPRT_INLINE inline +#else +#include +#endif + +struct hiprtInt2 +{ + int x, y; +}; + +struct hiprtFloat2 +{ + float x, y; +}; + +struct hiprtInt3 +{ + int x, y, z; +}; + +struct hiprtFloat3 +{ + float x, y, z; +}; + +struct hiprtInt4 +{ + int x, y, z, w; +}; + +struct hiprtFloat4 +{ + float x, y, z, w; +}; + +struct hiprtUint2 +{ + unsigned int x, y; +}; + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtInt2 make_hiprtInt2( int x, int y ) { return { x, y }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtFloat2 make_hiprtFloat2( float x, float y ) { return { x, y }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtInt3 make_hiprtInt3( int x, int y, int z ) { return { x, y, z }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtFloat3 make_hiprtFloat3( float x, float y, float z ) { return { x, y, z }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtInt4 make_hiprtInt4( int x, int y, int z, int w ) { return { x, y, z, w }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtFloat4 make_hiprtFloat4( float x, float y, float z, float w ) { return { x, y, z, w }; } + +HIPRT_HOST_DEVICE HIPRT_INLINE hiprtUint2 make_hiprtUint2( unsigned int x, unsigned int y ) { return { x, y }; } + +#if defined( HIPRT_EXPORTS ) +#define int2 hiprtInt2 +#define int3 hiprtInt3 +#define int4 hiprtInt4 +#define uint2 hiprtUint2 + +#define float2 hiprtFloat2 +#define float3 hiprtFloat3 +#define float4 hiprtFloat4 + +#define make_int2 make_hiprtInt2 +#define make_int3 make_hiprtInt3 +#define make_int4 make_hiprtInt4 +#define make_uint2 make_hiprtUint2 + +#define make_float2 make_hiprtFloat2 +#define make_float3 make_hiprtFloat3 +#define make_float4 make_hiprtFloat4 +#endif +#endif diff --git a/hiprt-sys/lib/hiprt64.dll b/hiprt-sys/lib/hiprt64.dll new file mode 100644 index 0000000000000000000000000000000000000000..6008127217fa20f2ff272377bfc6ecd3130c3bb3 GIT binary patch literal 580608 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

y}g^VQ8w!RN2N2kzXFClJ=}iJJq*e0#q^{XT`; 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 literal 0 HcmV?d00001 diff --git a/hiprt-sys/lib/libhiprt64.so b/hiprt-sys/lib/libhiprt64.so new file mode 100644 index 0000000000000000000000000000000000000000..b5b6393fc05ac9f75d02b282fb4e9853c8140841 GIT binary patch literal 586056 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

bWL;kOLTHYm3DmYC|@&6OC*zLv>n-{w> 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 oodIDg{Wv2)VX>m`;}gz#<)0aiwDl+Y|3?*lM bool, +>; +#[doc = " \\brief Set of functions for custom primitives.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtCustomFuncSet { + pub intersectFunc: hiprtIntersectFunc, + pub intersectFuncData: *const ::std::os::raw::c_void, +} +impl hiprtDeviceType { + pub const hiprtDeviceAMD: hiprtDeviceType = hiprtDeviceType(0); +} +impl hiprtDeviceType { + pub const hiprtDeviceNVIDIA: hiprtDeviceType = hiprtDeviceType(1); +} +#[repr(transparent)] +#[doc = " \\brief Device type.\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct hiprtDeviceType(pub ::std::os::raw::c_uint); +#[doc = " \\brief Context creation input.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtContextCreationInput { + pub ctxt: hiprtApiCtx, + pub device: hiprtApiDevice, + pub deviceType: hiprtDeviceType, +} +#[doc = " \\brief Various flags controlling scene/geometry build process.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtBuildOptions { + pub buildFlags: hiprtBuildFlags, +} +#[doc = " \\brief Triangle mesh primitive.\n\n Triangle mesh primitive is represented as an indexed vertex array.\n Vertex and index arrays are defined using device pointers and strides.\n Each vertex has to have 3 components: (x, y, z) coordinates.\n Indices are organized into triples (i0, i1, i2) - one for each triangle."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtTriangleMeshPrimitive { + pub vertices: hiprtDevicePtr, + pub vertexCount: u32, + pub vertexStride: u32, + pub triangleIndices: hiprtDevicePtr, + pub triangleCount: u32, + pub triangleStride: u32, +} +#[doc = " \\brief AABB list primitive.\n\n AABB list is an array of axis aligned bounding boxes, represented\n by device memory pointer and stride between two consequetive boxes.\n Each AABB is a pair of float4 values (xmin, ymin, zmin, unused), (xmax, ymax,\n zmax, unused)."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtAABBListPrimitive { + pub aabbs: hiprtDevicePtr, + pub aabbCount: u32, + pub aabbStride: u32, +} +#[doc = " \\brief Bvh node for custom import Bvh.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtBvhNode { + pub childIndices: [u32; 4usize], + pub childNodeTypes: [hiprtBvhNodeType; 4usize], + pub boundingBoxMin: hiprtFloat3, + pub boundingBoxMax: hiprtFloat3, + pub pad: [::std::os::raw::c_int; 2usize], +} +#[doc = " \\brief Bvh node list.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtBvhNodeList { + pub nodes: hiprtDevicePtr, + pub nodeCount: u32, +} +#[doc = " \\brief Input for geometry build/update operation.\n\n Build input defines concrete primitive type and a pointer to an actual\n primitive description."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtGeometryBuildInput { + pub type_: hiprtPrimitiveType, + pub __bindgen_anon_1: hiprtGeometryBuildInput__bindgen_ty_1, + pub nodes: *mut hiprtBvhNodeList, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union hiprtGeometryBuildInput__bindgen_ty_1 { + pub triangleMesh: hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_1, + pub aabbList: hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_1 { + pub primitive: *mut hiprtTriangleMeshPrimitive, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_2 { + pub primitive: *mut hiprtAABBListPrimitive, + pub customType: hiprtCustomType, +} +#[doc = " \\brief Build input for the scene.\n\n Scene consists of a set of instances. Each of the instances is defined by:\n - Root pointer of the corresponding geometry\n - Transformation header\n - Mask\n\n Instances can refer to the same geometry but with different transformations\n (essentially implementing instancing). Mask is used to implement ray\n masking: ray mask is bitwise &ded with an instance mask, and no intersections\n are evaluated with the primitive of corresponding instance if the result is\n 0. The transformation header defines the offset and the number of consecutive\n transformation frames in the frame array for each instance. More than one frame\n is interpreted as motion blur. If the transformation headers is NULL, it\n assumes one frame per instance. Optionally, it is possible to import a custom\n BVH by setting nodes and the corresponding build flag."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtSceneBuildInput { + pub instanceGeometries: hiprtDevicePtr, + pub instanceTransformHeaders: hiprtDevicePtr, + pub instanceFrames: hiprtDevicePtr, + pub instanceMasks: hiprtDevicePtr, + pub nodes: *mut hiprtBvhNodeList, + pub instanceCount: u32, + pub frameCount: u32, +} +#[doc = " \\brief Transformation frame.\n\n Defines scale, translation, rotation, and time."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtFrame { + pub rotation: hiprtFloat4, + pub scale: hiprtFloat3, + pub translation: hiprtFloat3, + pub time: f32, + pub pad: ::std::os::raw::c_int, +} +#[doc = " \\brief Transformation header.\n\n Defines defines the index to the array of frames and the number of frames."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct hiprtTransformHeader { + pub frameIndex: u32, + pub frameCount: u32, +} +extern crate libloading; +pub struct HipRt { + __library: ::libloading::Library, + pub hiprtCreateContext: Result< + unsafe extern "C" fn( + hiprtApiVersion: u32, + input: *mut hiprtContextCreationInput, + outContext: *mut hiprtContext, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtDestroyContext: + Result hiprtError, ::libloading::Error>, + pub hiprtCreateGeometry: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + outGeometry: *mut hiprtGeometry, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtDestroyGeometry: Result< + unsafe extern "C" fn(context: hiprtContext, outGeometry: hiprtGeometry) -> hiprtError, + ::libloading::Error, + >, + pub hiprtBuildGeometry: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildOperation: hiprtBuildOperation, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + temporaryBuffer: hiprtDevicePtr, + stream: hiprtApiStream, + outGeometry: hiprtGeometry, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtGetGeometryBuildTemporaryBufferSize: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + outSize: *mut usize, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtGetGeometryTraceTemporaryBufferSize: Result< + unsafe extern "C" fn( + context: hiprtContext, + scene: hiprtGeometry, + numRays: u32, + outSize: *mut usize, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtCreateScene: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + outScene: *mut hiprtScene, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtDestroyScene: Result< + unsafe extern "C" fn(context: hiprtContext, outScene: hiprtScene) -> hiprtError, + ::libloading::Error, + >, + pub hiprtBuildScene: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildOperation: hiprtBuildOperation, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + temporaryBuffer: hiprtDevicePtr, + stream: hiprtApiStream, + outScene: hiprtScene, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtGetSceneBuildTemporaryBufferSize: Result< + unsafe extern "C" fn( + context: hiprtContext, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + outSize: *mut usize, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtGetSceneTraceTemporaryBufferSize: Result< + unsafe extern "C" fn( + context: hiprtContext, + scene: hiprtScene, + numRays: u32, + outSize: *mut usize, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtCreateCustomFuncTable: Result< + unsafe extern "C" fn( + context: hiprtContext, + outFuncTable: *mut hiprtCustomFuncTable, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtSetCustomFuncTable: Result< + unsafe extern "C" fn( + context: hiprtContext, + outFuncTable: hiprtCustomFuncTable, + index: u32, + set: hiprtCustomFuncSet, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtDestroyCustomFuncTable: Result< + unsafe extern "C" fn( + context: hiprtContext, + outFuncTable: hiprtCustomFuncTable, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtSaveGeometry: Result< + unsafe extern "C" fn( + context: hiprtContext, + inGeometry: hiprtGeometry, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtLoadGeometry: Result< + unsafe extern "C" fn( + context: hiprtContext, + outGeometry: *mut hiprtGeometry, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtSaveScene: Result< + unsafe extern "C" fn( + context: hiprtContext, + inScene: hiprtScene, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtLoadScene: Result< + unsafe extern "C" fn( + context: hiprtContext, + outScene: *mut hiprtScene, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtExportGeometryAabb: Result< + unsafe extern "C" fn( + context: hiprtContext, + inGeometry: hiprtGeometry, + outAabbMin: *mut hiprtFloat3, + outAabbMax: *mut hiprtFloat3, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtExportSceneAabb: Result< + unsafe extern "C" fn( + context: hiprtContext, + inScene: hiprtScene, + outAabbMin: *mut hiprtFloat3, + outAabbMax: *mut hiprtFloat3, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtBuildTraceProgram: Result< + unsafe extern "C" fn( + context: hiprtContext, + functionName: *const ::std::os::raw::c_char, + src: *const ::std::os::raw::c_char, + name: *const ::std::os::raw::c_char, + numHeaders: ::std::os::raw::c_int, + headers: *mut *const ::std::os::raw::c_char, + includeNames: *mut *const ::std::os::raw::c_char, + options: *mut *const ::std::os::raw::c_char, + nOptions: ::std::os::raw::c_int, + progOut: *mut ::std::os::raw::c_void, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtBuildTraceGetBinary: Result< + unsafe extern "C" fn( + prog: *mut ::std::os::raw::c_void, + size: *mut usize, + binary: *mut ::std::os::raw::c_void, + ) -> hiprtError, + ::libloading::Error, + >, + pub hiprtSetCacheDirPath: + Result, + pub hiprtSetLogLevel: + Result, +} +impl HipRt { + pub unsafe fn new

(path: P) -> Result + where + P: AsRef<::std::ffi::OsStr>, + { + let library = ::libloading::Library::new(path)?; + Self::from_library(library) + } + pub unsafe fn from_library(library: L) -> Result + where + L: Into<::libloading::Library>, + { + let __library = library.into(); + let hiprtCreateContext = __library.get(b"hiprtCreateContext\0").map(|sym| *sym); + let hiprtDestroyContext = __library.get(b"hiprtDestroyContext\0").map(|sym| *sym); + let hiprtCreateGeometry = __library.get(b"hiprtCreateGeometry\0").map(|sym| *sym); + let hiprtDestroyGeometry = __library.get(b"hiprtDestroyGeometry\0").map(|sym| *sym); + let hiprtBuildGeometry = __library.get(b"hiprtBuildGeometry\0").map(|sym| *sym); + let hiprtGetGeometryBuildTemporaryBufferSize = __library + .get(b"hiprtGetGeometryBuildTemporaryBufferSize\0") + .map(|sym| *sym); + let hiprtGetGeometryTraceTemporaryBufferSize = __library + .get(b"hiprtGetGeometryTraceTemporaryBufferSize\0") + .map(|sym| *sym); + let hiprtCreateScene = __library.get(b"hiprtCreateScene\0").map(|sym| *sym); + let hiprtDestroyScene = __library.get(b"hiprtDestroyScene\0").map(|sym| *sym); + let hiprtBuildScene = __library.get(b"hiprtBuildScene\0").map(|sym| *sym); + let hiprtGetSceneBuildTemporaryBufferSize = __library + .get(b"hiprtGetSceneBuildTemporaryBufferSize\0") + .map(|sym| *sym); + let hiprtGetSceneTraceTemporaryBufferSize = __library + .get(b"hiprtGetSceneTraceTemporaryBufferSize\0") + .map(|sym| *sym); + let hiprtCreateCustomFuncTable = __library + .get(b"hiprtCreateCustomFuncTable\0") + .map(|sym| *sym); + let hiprtSetCustomFuncTable = __library.get(b"hiprtSetCustomFuncTable\0").map(|sym| *sym); + let hiprtDestroyCustomFuncTable = __library + .get(b"hiprtDestroyCustomFuncTable\0") + .map(|sym| *sym); + let hiprtSaveGeometry = __library.get(b"hiprtSaveGeometry\0").map(|sym| *sym); + let hiprtLoadGeometry = __library.get(b"hiprtLoadGeometry\0").map(|sym| *sym); + let hiprtSaveScene = __library.get(b"hiprtSaveScene\0").map(|sym| *sym); + let hiprtLoadScene = __library.get(b"hiprtLoadScene\0").map(|sym| *sym); + let hiprtExportGeometryAabb = __library.get(b"hiprtExportGeometryAabb\0").map(|sym| *sym); + let hiprtExportSceneAabb = __library.get(b"hiprtExportSceneAabb\0").map(|sym| *sym); + let hiprtBuildTraceProgram = __library.get(b"hiprtBuildTraceProgram\0").map(|sym| *sym); + let hiprtBuildTraceGetBinary = __library.get(b"hiprtBuildTraceGetBinary\0").map(|sym| *sym); + let hiprtSetCacheDirPath = __library.get(b"hiprtSetCacheDirPath\0").map(|sym| *sym); + let hiprtSetLogLevel = __library.get(b"hiprtSetLogLevel\0").map(|sym| *sym); + Ok(HipRt { + __library, + hiprtCreateContext, + hiprtDestroyContext, + hiprtCreateGeometry, + hiprtDestroyGeometry, + hiprtBuildGeometry, + hiprtGetGeometryBuildTemporaryBufferSize, + hiprtGetGeometryTraceTemporaryBufferSize, + hiprtCreateScene, + hiprtDestroyScene, + hiprtBuildScene, + hiprtGetSceneBuildTemporaryBufferSize, + hiprtGetSceneTraceTemporaryBufferSize, + hiprtCreateCustomFuncTable, + hiprtSetCustomFuncTable, + hiprtDestroyCustomFuncTable, + hiprtSaveGeometry, + hiprtLoadGeometry, + hiprtSaveScene, + hiprtLoadScene, + hiprtExportGeometryAabb, + hiprtExportSceneAabb, + hiprtBuildTraceProgram, + hiprtBuildTraceGetBinary, + hiprtSetCacheDirPath, + hiprtSetLogLevel, + }) + } + #[must_use] + #[doc = " \\brief Create HIPRT API context.\n\n All HIPRT functions expect context as their first argument. Context\n keeps global data required by HIPRT session. Calls made from different\n threads with different HIPRT contexts are safe. Calls with the same context\n should be externally synchronized by the client.\n\n \\param hiprtApiVersion API version.\n \\param outContext Created context.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtCreateContext( + &self, + hiprtApiVersion: u32, + input: *mut hiprtContextCreationInput, + outContext: *mut hiprtContext, + ) -> hiprtError { + (self + .hiprtCreateContext + .as_ref() + .expect("Expected function, got error."))(hiprtApiVersion, input, outContext) + } + #[must_use] + #[doc = " \\brief Destory HIPRT API context.\n\n Destroys all the global resources used by HIPRT session. Further calls\n with this context are prohibited.\n\n \\param context API context.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtDestroyContext(&self, context: hiprtContext) -> hiprtError { + (self + .hiprtDestroyContext + .as_ref() + .expect("Expected function, got error."))(context) + } + #[must_use] + #[doc = " \\brief Create a geometry.\n\n This function creates\n hiprtGeometry representing acceleration structure topology.\n\n \\param context HIPRT API context.\n \\param buildInput Describes input primitive to build geometry from.\n \\param buildOptions Various flags controlling build process.\n \\param outGeometry Resulting geometry.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtCreateGeometry( + &self, + context: hiprtContext, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + outGeometry: *mut hiprtGeometry, + ) -> hiprtError { + (self + .hiprtCreateGeometry + .as_ref() + .expect("Expected function, got error."))( + context, + buildInput, + buildOptions, + outGeometry, + ) + } + #[must_use] + #[doc = " \\brief Destroy a geometry.\n\n This function destroys\n hiprtGeometry representing acceleration structure topology.\n\n \\param context HIPRT API context.\n \\param outGeometry Resulting geometry.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtDestroyGeometry( + &self, + context: hiprtContext, + outGeometry: hiprtGeometry, + ) -> hiprtError { + (self + .hiprtDestroyGeometry + .as_ref() + .expect("Expected function, got error."))(context, outGeometry) + } + #[must_use] + #[doc = " \\brief Build or update a geometry.\n\n Given geometry description from the client, this function builds\n hiprtGeometry representing acceleration structure topology (in case of a\n build) or updates acceleration structure keeping topology intact (update).\n\n \\param context HIPRT API context.\n \\param buildOperation Type of build operation.\n \\param buildInput Describes input primitive to build geometry from.\n \\param buildOptions Various flags controlling build process.\n \\param attributeOutputs Describes additional values written into vidmem.\n \\param attributeOutputCount Number of additional attributes, can be 0.\n \\param temporaryBuffer Temporary buffer for build operation.\n \\param stream to run acceleration structure build command.\n \\param outGeometry Resulting geometry.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtBuildGeometry( + &self, + context: hiprtContext, + buildOperation: hiprtBuildOperation, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + temporaryBuffer: hiprtDevicePtr, + stream: hiprtApiStream, + outGeometry: hiprtGeometry, + ) -> hiprtError { + (self + .hiprtBuildGeometry + .as_ref() + .expect("Expected function, got error."))( + context, + buildOperation, + buildInput, + buildOptions, + temporaryBuffer, + stream, + outGeometry, + ) + } + #[must_use] + #[doc = " \\brief Get temporary storage requirements for geometry build.\n\n \\param context HIPRT API context.\n \\param buildInput Describes input primitive to build geometry from.\n \\param buildOptions Various flags controlling build process.\n \\param outSize Pointer to write result to.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtGetGeometryBuildTemporaryBufferSize( + &self, + context: hiprtContext, + buildInput: *const hiprtGeometryBuildInput, + buildOptions: *const hiprtBuildOptions, + outSize: *mut usize, + ) -> hiprtError { + (self + .hiprtGetGeometryBuildTemporaryBufferSize + .as_ref() + .expect("Expected function, got error."))( + context, buildInput, buildOptions, outSize + ) + } + #[must_use] + #[doc = " \\brief Get temporary storage requirements for scene trace.\n\n \\param context HIPRT API context.\n \\param scene Built scene for trace.\n \\param numRays Rays to be issued.\n \\param outSize Pointer to write result to.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtGetGeometryTraceTemporaryBufferSize( + &self, + context: hiprtContext, + scene: hiprtGeometry, + numRays: u32, + outSize: *mut usize, + ) -> hiprtError { + (self + .hiprtGetGeometryTraceTemporaryBufferSize + .as_ref() + .expect("Expected function, got error."))(context, scene, numRays, outSize) + } + #[must_use] + #[doc = " \\brief Create a scene.\n\n This function creates\n hiprtScene representing acceleration structure topology.\n\n \\param context HIPRT API context.\n \\param buildInput Decribes input geometires to build scene for.\n \\param buildOptions Various flags controlling build process.\n \\param outScene Resulting scene.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtCreateScene( + &self, + context: hiprtContext, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + outScene: *mut hiprtScene, + ) -> hiprtError { + (self + .hiprtCreateScene + .as_ref() + .expect("Expected function, got error."))( + context, buildInput, buildOptions, outScene + ) + } + #[must_use] + #[doc = " \\brief Destroy a scene.\n\n This function destroys\n hiprtScene representing acceleration structure topology.\n\n \\param context HIPRT API context.\n \\param outScene Resulting scene.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtDestroyScene( + &self, + context: hiprtContext, + outScene: hiprtScene, + ) -> hiprtError { + (self + .hiprtDestroyScene + .as_ref() + .expect("Expected function, got error."))(context, outScene) + } + #[must_use] + #[doc = " \\brief Build or update a scene.\n\n Given a number of hiprtGeometries from the client, this function builds\n hiprtScene representing top level acceleration structure topology (in case of\n a build) or updates acceleration structure keeping topology intact (update).\n\n \\param context HIPRT API context.\n \\param buildOperation Type of build operation.\n \\param buildInput Decribes input geometires to build scene for.\n \\param buildOptions Various flags controlling build process.\n \\param temporaryBuffer Temporary buffer for build operation.\n \\param stream to run acceleration structure build command.\n \\param outScene Resulting scene.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtBuildScene( + &self, + context: hiprtContext, + buildOperation: hiprtBuildOperation, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + temporaryBuffer: hiprtDevicePtr, + stream: hiprtApiStream, + outScene: hiprtScene, + ) -> hiprtError { + (self + .hiprtBuildScene + .as_ref() + .expect("Expected function, got error."))( + context, + buildOperation, + buildInput, + buildOptions, + temporaryBuffer, + stream, + outScene, + ) + } + #[must_use] + #[doc = " \\brief Get temporary storage requirements for scene build.\n\n \\param context HIPRT API context.\n \\param buildInput Decribes input geometires to build scene for.\n \\param buildOptions Various flags controlling build process.\n \\param outSize Pointer to write result to.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtGetSceneBuildTemporaryBufferSize( + &self, + context: hiprtContext, + buildInput: *const hiprtSceneBuildInput, + buildOptions: *const hiprtBuildOptions, + outSize: *mut usize, + ) -> hiprtError { + (self + .hiprtGetSceneBuildTemporaryBufferSize + .as_ref() + .expect("Expected function, got error."))( + context, buildInput, buildOptions, outSize + ) + } + #[must_use] + #[doc = " \\brief Get temporary storage requirements for scene trace.\n\n \\param context HIPRT API context.\n \\param scene Built scene for trace.\n \\param numRays Rays to be issued.\n \\param outSize Pointer to write result to.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtGetSceneTraceTemporaryBufferSize( + &self, + context: hiprtContext, + scene: hiprtScene, + numRays: u32, + outSize: *mut usize, + ) -> hiprtError { + (self + .hiprtGetSceneTraceTemporaryBufferSize + .as_ref() + .expect("Expected function, got error."))(context, scene, numRays, outSize) + } + #[must_use] + #[doc = " \\brief Creates a custom function table (for custom geometry).\n\n \\param context HIPRT API context.\n \\param outFuncTable Resulting table.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtCreateCustomFuncTable( + &self, + context: hiprtContext, + outFuncTable: *mut hiprtCustomFuncTable, + ) -> hiprtError { + (self + .hiprtCreateCustomFuncTable + .as_ref() + .expect("Expected function, got error."))(context, outFuncTable) + } + #[must_use] + #[doc = " \\brief Sets a custom function table.\n\n \\param context HIPRT API context.\n \\param outFuncTable Resulting table.\n \\param index Index of the set in the table.\n \\param set Function set to be set.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtSetCustomFuncTable( + &self, + context: hiprtContext, + outFuncTable: hiprtCustomFuncTable, + index: u32, + set: hiprtCustomFuncSet, + ) -> hiprtError { + (self + .hiprtSetCustomFuncTable + .as_ref() + .expect("Expected function, got error."))(context, outFuncTable, index, set) + } + #[must_use] + #[doc = " \\brief Destroys a custom function table.\n\n \\param context HIPRT API context.\n \\param outFuncTable Resulting table.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtDestroyCustomFuncTable( + &self, + context: hiprtContext, + outFuncTable: hiprtCustomFuncTable, + ) -> hiprtError { + (self + .hiprtDestroyCustomFuncTable + .as_ref() + .expect("Expected function, got error."))(context, outFuncTable) + } + #[must_use] + #[doc = " \\brief Saves hiprtGeometry to a binary file.\n\n \\param context HIPRT API context.\n \\param inGeometry Geometry to be saved.\n \\param filename File name with full path.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtSaveGeometry( + &self, + context: hiprtContext, + inGeometry: hiprtGeometry, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError { + (self + .hiprtSaveGeometry + .as_ref() + .expect("Expected function, got error."))(context, inGeometry, filename) + } + #[must_use] + #[doc = " \\brief Loads hiprtGeometry to a binary file.\n\n \\param context HIPRT API context.\n \\param outGeometry Geometry to be loaded.\n \\param filename File name with full path.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtLoadGeometry( + &self, + context: hiprtContext, + outGeometry: *mut hiprtGeometry, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError { + (self + .hiprtLoadGeometry + .as_ref() + .expect("Expected function, got error."))(context, outGeometry, filename) + } + #[must_use] + #[doc = " \\brief Saves hiprtScene to a binary file.\n\n \\param context HIPRT API context.\n \\param inScene Scene to be saved.\n \\param filename File name with full path.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtSaveScene( + &self, + context: hiprtContext, + inScene: hiprtScene, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError { + (self + .hiprtSaveScene + .as_ref() + .expect("Expected function, got error."))(context, inScene, filename) + } + #[must_use] + #[doc = " \\brief Loads hiprtScene to a binary file.\n\n \\param context HIPRT API context.\n \\param outScene Scene to be loaded.\n \\param filename File name with full path.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtLoadScene( + &self, + context: hiprtContext, + outScene: *mut hiprtScene, + filename: *const ::std::os::raw::c_char, + ) -> hiprtError { + (self + .hiprtLoadScene + .as_ref() + .expect("Expected function, got error."))(context, outScene, filename) + } + #[must_use] + #[doc = " \\brief Output scene's AABB.\n\n \\param context HIPRT API context.\n \\param inGeometry Geometry to be queried.\n \\param outAabbMin The bounding box min. bound.\n \\param outAabbMax The bounding box max. bound.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtExportGeometryAabb( + &self, + context: hiprtContext, + inGeometry: hiprtGeometry, + outAabbMin: *mut hiprtFloat3, + outAabbMax: *mut hiprtFloat3, + ) -> hiprtError { + (self + .hiprtExportGeometryAabb + .as_ref() + .expect("Expected function, got error."))( + context, inGeometry, outAabbMin, outAabbMax + ) + } + #[must_use] + #[doc = " \\brief Output scene's AABB.\n\n \\param context HIPRT API context.\n \\param inScene Scene to be queried.\n \\param outAabbMin The bounding box min. bound.\n \\param outAabbMax The bounding box max. bound.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtExportSceneAabb( + &self, + context: hiprtContext, + inScene: hiprtScene, + outAabbMin: *mut hiprtFloat3, + outAabbMax: *mut hiprtFloat3, + ) -> hiprtError { + (self + .hiprtExportSceneAabb + .as_ref() + .expect("Expected function, got error."))( + context, inScene, outAabbMin, outAabbMax + ) + } + #[must_use] + #[doc = " \\brief Get Program instance with HIPRT routines.\n \\param functionName function to which handle will be returned, cannot be NULL.\n \\param context HIPRT API context.\n \\param src HIP program source.\n \\param name Program source filename.\n \\param numHeaders Number of headers, numHeaders must be greater than or equal to 0.\n \\param headers Sources of the headers, headers can be NULL when numHeaders is 0.\n \\param includeNames Name of each header by which they can be included in the HIP program source, includeNames can be NULL\n when numHeaders is 0.\n \\param options Compiler options, can be NULL.\n \\param progOut Output build program instance.\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtBuildTraceProgram( + &self, + context: hiprtContext, + functionName: *const ::std::os::raw::c_char, + src: *const ::std::os::raw::c_char, + name: *const ::std::os::raw::c_char, + numHeaders: ::std::os::raw::c_int, + headers: *mut *const ::std::os::raw::c_char, + includeNames: *mut *const ::std::os::raw::c_char, + options: *mut *const ::std::os::raw::c_char, + nOptions: ::std::os::raw::c_int, + progOut: *mut ::std::os::raw::c_void, + ) -> hiprtError { + (self + .hiprtBuildTraceProgram + .as_ref() + .expect("Expected function, got error."))( + context, + functionName, + src, + name, + numHeaders, + headers, + includeNames, + options, + nOptions, + progOut, + ) + } + #[must_use] + #[doc = " \\brief Get binary with HIPRT routines.\n\n \\param prog program instance.\n \\param size Output size of binary .\n \\param binary Output if NULL function returns size of parameter else returned binary(application should allocate for binary)..\n \\return HIPRT error in case of a failure, hiprtSuccess otherwise."] + pub unsafe fn hiprtBuildTraceGetBinary( + &self, + prog: *mut ::std::os::raw::c_void, + size: *mut usize, + binary: *mut ::std::os::raw::c_void, + ) -> hiprtError { + (self + .hiprtBuildTraceGetBinary + .as_ref() + .expect("Expected function, got error."))(prog, size, binary) + } + #[doc = " \\brief Setting log level.\n\n \\param path user defined path to cache kernels."] + pub unsafe fn hiprtSetCacheDirPath(&self, path: *const ::std::os::raw::c_char) { + (self + .hiprtSetCacheDirPath + .as_ref() + .expect("Expected function, got error."))(path) + } + #[doc = " \\brief Setting log level.\n\n \\param level Desired log level."] + pub unsafe fn hiprtSetLogLevel(&self, level: ::std::os::raw::c_int) { + (self + .hiprtSetLogLevel + .as_ref() + .expect("Expected function, got error."))(level) + } +} diff --git a/hiprt-sys/src/lib.rs b/hiprt-sys/src/lib.rs new file mode 100644 index 0000000..a931426 --- /dev/null +++ b/hiprt-sys/src/lib.rs @@ -0,0 +1,84 @@ +#![allow(warnings)] +pub mod hiprt; +pub use hiprt::*; + +use std::ffi::OsString; +use std::mem; +use std::path::PathBuf; + +impl hiprt::HipRt { + pub unsafe fn load() -> Result { + Self::new(os::HIPRT_NAME).or_else(|_| { + let module_path = os::currently_executing().ok_or(os::UNKNOWN_ERROR)?; + let mut path = PathBuf::from(module_path); + if !path.pop() { + return Err(os::UNKNOWN_ERROR); + } + path.push(os::HIPRT_NAME); + Self::new(path) + }) + } +} + +#[cfg(not(target_os = "windows"))] +mod os { + use std::ffi::CStr; + use std::os::unix::ffi::OsStringExt; + use std::{ + ffi::{c_char, c_int, c_void, CString, OsString}, + mem, + }; + + pub(crate) const HIPRT_NAME: &'static str = "libhiprt64.so"; + pub(crate) const UNKNOWN_ERROR: libloading::Error = libloading::Error::DlOpenUnknown; + + #[link(name = "dl")] + extern "C" { + fn dladdr(addr: *mut c_void, info: *mut DlInfo) -> c_int; + } + + pub(crate) unsafe fn currently_executing() -> Option { + let mut dlinfo = mem::zeroed(); + if 0 == dladdr(currently_executing as _, &mut dlinfo) { + return None; + } + Some(OsString::from_vec( + CStr::from_ptr(dlinfo.dli_fname.cast_mut()) + .to_bytes() + .to_vec(), + )) + } + + #[repr(C)] + struct DlInfo { + dli_fname: *const c_char, + dli_fbase: *mut c_void, + dli_sname: *const c_char, + dli_saddr: *mut c_void, + } +} + +#[cfg(target_os = "windows")] +mod os { + use std::ffi::OsString; + use std::mem; + use widestring::U16CStr; + use winapi::shared::minwindef::HMODULE; + use winapi::um::libloaderapi::*; + + pub(crate) const HIPRT_NAME: &'static str = "hiprt64.dll"; + pub(crate) const UNKNOWN_ERROR: libloading::Error = + libloading::Error::GetModuleHandleExWUnknown; + + pub(crate) unsafe fn currently_executing() -> Option { + let mut module = mem::zeroed(); + if 0 == GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + currently_executing as _, + &mut module, + ) { + return None; + } + Some(U16CStr::from_ptr_str(module.cast()).to_os_string()) + } +} diff --git a/level_zero-sys/README b/level_zero-sys/README deleted file mode 100644 index ff5978a..0000000 --- a/level_zero-sys/README +++ /dev/null @@ -1,4 +0,0 @@ -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/lib/ze_loader.def b/level_zero-sys/lib/ze_loader.def deleted file mode 100644 index 71bc4df4bb6534e42585f407e4fb5f256b561449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15760 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 IjNg&?55;PF1poj5 diff --git a/level_zero-sys/lib/ze_loader.lib b/level_zero-sys/lib/ze_loader.lib deleted file mode 100644 index dfb3f84a4b9e74af7c267ba8b3a658794dd5aaf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77220 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, - 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/Cargo.toml b/level_zero/Cargo.toml deleted file mode 100644 index 851159d..0000000 --- a/level_zero/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "level_zero" -version = "0.1.0" -authors = ["Andrzej Janik "] -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 deleted file mode 100644 index b9785bf..0000000 --- a/level_zero/README +++ /dev/null @@ -1 +0,0 @@ -More ergonomic bindings for oneAPI Level Zero diff --git a/level_zero/src/lib.rs b/level_zero/src/lib.rs deleted file mode 100644 index bdc25a8..0000000 --- a/level_zero/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index ce675eb..0000000 --- a/level_zero/src/ze.rs +++ /dev/null @@ -1,947 +0,0 @@ -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 = std::result::Result; - -#[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> { - 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::>(); - check!(sys::zeDriverGet(&mut len, result.as_mut_ptr() as *mut _)); - Ok(result) - } - - pub fn devices(&self) -> Result> { - 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::>(); - 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> { - let mut props = Box::new(unsafe { mem::zeroed::() }); - check! { sys::zeDeviceGetProperties(self.0, props.as_mut()) }; - Ok(props) - } - - pub fn get_image_properties(&self) -> Result> { - let mut props = Box::new(unsafe { mem::zeroed::() }); - check! { sys::zeDeviceGetImageProperties(self.0, props.as_mut()) }; - Ok(props) - } - - pub fn get_memory_properties(&self) -> Result> { - 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::() }; count as usize]; - check! { sys::zeDeviceGetMemoryProperties(self.0, &mut count, props.as_mut_ptr()) }; - Ok(props) - } - - pub fn get_compute_properties(&self) -> Result> { - let mut props = Box::new(unsafe { mem::zeroed::() }); - 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 { - 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 { - 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> { - 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, Option) { - 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_logged(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 { - 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::( - 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_ctx, - Some(&[device]), - &options, - &programs.iter().collect::>(), - None, - None, - None, - ) - } - - pub fn build_spirv( - ctx: &mut Context, - d: &Device, - bin: &[u8], - opts: Option<&CStr>, - ) -> Result { - Module::new(ctx, true, d, bin, opts) - } - - pub fn build_spirv_logged( - ctx: &mut Context, - d: &Device, - bin: &[u8], - opts: Option<&CStr>, - ) -> (Result, BuildLog) { - Module::new_logged(ctx, true, d, bin, opts) - } - - pub fn build_native_logged(ctx: &mut Context, d: &Device, bin: &[u8]) -> (Result, BuildLog) { - Module::new_logged(ctx, false, d, bin, None) - } - - fn new( - ctx: &mut Context, - spirv: bool, - d: &Device, - bin: &[u8], - opts: Option<&CStr>, - ) -> Result { - 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 err = unsafe { sys::zeModuleCreate(ctx.0, d.0, &desc, &mut result, ptr::null_mut()) }; - if err != crate::sys::ze_result_t::ZE_RESULT_SUCCESS { - Result::Err(err) - } else { - Ok(Module(result)) - } - } - - fn new_logged( - ctx: &mut Context, - spirv: bool, - d: &Device, - bin: &[u8], - opts: Option<&CStr>, - ) -> (Result, 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 { - 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 { - ptr: *mut c_void, - ctx: sys::ze_context_handle_t, - len: usize, - marker: PhantomData, -} - -impl DeviceBuffer { - 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::; - Self { - ptr, - ctx, - len, - marker, - } - } - - pub fn new(ctx: &mut Context, dev: &Device, len: usize) -> Result { - 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::(), - mem::align_of::(), - dev.0, - &mut result - )); - Ok(unsafe { Self::from_ffi(ctx.0, result, len) }) - } - - pub fn len(&self) -> usize { - self.len - } -} - -impl Drop for DeviceBuffer { - #[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 { - 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>, - Src: Into>, - >( - &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::(); - 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( - &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::(); - check!(sys::zeCommandListAppendMemoryFill( - self.0, - dst.get(), - raw_pattern, - mem::size_of::(), - byte_len, - signal_event, - wait_len, - wait_ptr - )); - Ok(()) - } - - pub unsafe fn append_memory_fill_unsafe( - &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::(), - 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 { - 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> for BufferPtr<'a, T> { - fn from(b: &'a DeviceBuffer) -> 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> for BufferPtrMut<'a, T> { - fn from(b: &'a mut DeviceBuffer) -> Self { - BufferPtrMut { - ptr: b.ptr as *mut _, - marker: PhantomData, - elems: b.len(), - } - } -} - -impl<'a, T: SafeRepr> From> 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 { - 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::>()); - 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 { - 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 { - 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>>( - &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(&self, index: u32, value: &T) -> Result<()> { - check!(sys::zeKernelSetArgumentValue( - self.0, - index, - mem::size_of::(), - 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> { - let mut props = Box::new(unsafe { mem::zeroed::() }); - 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::(), - mem::size_of::() - ); - } -} diff --git a/spirv_tools-sys/Cargo.toml b/miopen-sys/Cargo.toml similarity index 58% rename from spirv_tools-sys/Cargo.toml rename to miopen-sys/Cargo.toml index a5cadc1..a2d90da 100644 --- a/spirv_tools-sys/Cargo.toml +++ b/miopen-sys/Cargo.toml @@ -1,10 +1,8 @@ -[package] -name = "spirv_tools-sys" -version = "0.0.0" -authors = ["Andrzej Janik "] -edition = "2018" - -[lib] - -[build-dependencies] -cmake = "0.1" \ No newline at end of file +[package] +name = "miopen-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "MIOpen" + +[lib] diff --git a/miopen-sys/README b/miopen-sys/README new file mode 100644 index 0000000..980e9e8 --- /dev/null +++ b/miopen-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/miopen/miopen.h -o src/miopen.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --allowlist-function "miopen.*" --allowlist-var "MIOPEN_*" --must-use-type miopenStatus_t -- -D__HIP_PLATFORM_AMD__ -DMIOPEN_BACKEND_HIP=1 -I/opt/rocm/include -x c++ \ No newline at end of file diff --git a/miopen-sys/build.rs b/miopen-sys/build.rs new file mode 100644 index 0000000..f6c0300 --- /dev/null +++ b/miopen-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=MIOpen"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/miopen-sys/src/lib.rs b/miopen-sys/src/lib.rs new file mode 100644 index 0000000..67d5e40 --- /dev/null +++ b/miopen-sys/src/lib.rs @@ -0,0 +1,3 @@ +#![allow(warnings)] +mod miopen; +pub use miopen::*; \ No newline at end of file diff --git a/miopen-sys/src/miopen.rs b/miopen-sys/src/miopen.rs new file mode 100644 index 0000000..4240400 --- /dev/null +++ b/miopen-sys/src/miopen.rs @@ -0,0 +1,2991 @@ +/* automatically generated by rust-bindgen 0.64.0 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +pub type hipStream_t = *mut ihipStream_t; +pub type miopenAcceleratorQueue_t = hipStream_t; +#[doc = " @ingroup handle\n @brief Creates the miopenHandle_t type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenHandle { + pub _address: u8, +} +pub type miopenHandle_t = *mut miopenHandle; +impl miopenStatus_t { + #[doc = "< No errors"] + pub const miopenStatusSuccess: miopenStatus_t = miopenStatus_t(0); +} +impl miopenStatus_t { + #[doc = "< Data not initialized."] + pub const miopenStatusNotInitialized: miopenStatus_t = miopenStatus_t(1); +} +impl miopenStatus_t { + #[doc = "< Incorrect variable value."] + pub const miopenStatusInvalidValue: miopenStatus_t = miopenStatus_t(2); +} +impl miopenStatus_t { + #[doc = "< Incorrect parameter detected."] + pub const miopenStatusBadParm: miopenStatus_t = miopenStatus_t(3); +} +impl miopenStatus_t { + #[doc = "< Memory allocation error."] + pub const miopenStatusAllocFailed: miopenStatus_t = miopenStatus_t(4); +} +impl miopenStatus_t { + #[doc = "< MIOpen failure."] + pub const miopenStatusInternalError: miopenStatus_t = miopenStatus_t(5); +} +impl miopenStatus_t { + #[doc = "< Use of unimplemented feature."] + pub const miopenStatusNotImplemented: miopenStatus_t = miopenStatus_t(6); +} +impl miopenStatus_t { + #[doc = "< Unknown error occurred."] + pub const miopenStatusUnknownError: miopenStatus_t = miopenStatus_t(7); +} +impl miopenStatus_t { + #[doc = "< Unsupported operator for fusion."] + pub const miopenStatusUnsupportedOp: miopenStatus_t = miopenStatus_t(8); +} +impl miopenStatus_t { + #[doc = "< This is not an error."] + pub const miopenStatusGpuOperationsSkipped: miopenStatus_t = miopenStatus_t(9); +} +impl miopenStatus_t { + #[doc = "< Version mismatch of the supplied binary data argment."] + pub const miopenStatusVersionMismatch: miopenStatus_t = miopenStatus_t(10); +} +#[repr(transparent)] +#[doc = " @enum miopenStatus_t\n Error codes that are returned by all MIOpen API calls."] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenStatus_t(pub ::std::os::raw::c_uint); +extern "C" { + #[doc = " @brief Get character string for an error code.\n\n A function which returns a NULL terminated character string of the error code.\n\n @param error miopenStatus_t type error status (input)\n @return errorString"] + pub fn miopenGetErrorString(error: miopenStatus_t) -> *const ::std::os::raw::c_char; +} +#[doc = " @brief Custom allocator function\n\n This function allow for user-defined custom allocator\n\n @param context A pointer a context (input)\n @param sizeBytes Number of bytes to allocate (input)\n"] +pub type miopenAllocatorFunction = ::std::option::Option< + unsafe extern "C" fn( + context: *mut ::std::os::raw::c_void, + sizeBytes: usize, + ) -> *mut ::std::os::raw::c_void, +>; +#[doc = " @brief Custom deallocator function\n\n This function allow for user-defined custom deallocation function\n\n @param context A pointer context (input)\n @param memory A pointer allocated memory (input)\n"] +pub type miopenDeallocatorFunction = ::std::option::Option< + unsafe extern "C" fn(context: *mut ::std::os::raw::c_void, memory: *mut ::std::os::raw::c_void), +>; +extern "C" { + #[must_use] + #[doc = " @brief Method to return version of MIOpen\n\n The output values of this call follow from the versioning\n format major.minor.patch\n\n Pointers that are NULL will be ignored.\n\n @param major Major version number (output)\n @param minor Minor version number (output)\n @param patch Patch version number (output)\n\n @return miopenStatus_t"] + pub fn miopenGetVersion( + major: *mut usize, + minor: *mut usize, + patch: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Method to create the MIOpen handle object.\n\n This function creates a MIOpen handle. This is called at the very start to initialize the MIOpen\n environment.\n @param handle A pointer to a MIOpen handle type (output)\n\n @return miopenStatus_t"] + pub fn miopenCreate(handle: *mut miopenHandle_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a MIOpen handle with an accelerator stream.\n\n The HIP side uses a hipStream_t type for the stream, while OpenCL will use a\n cl_command_queue.\n\n Create a handle with a previously created accelerator command queue.\n @param handle A pointer to a MIOpen handle type (output)\n @param stream An accelerator queue type (input)\n\n @return miopenStatus_t"] + pub fn miopenCreateWithStream( + handle: *mut miopenHandle_t, + stream: miopenAcceleratorQueue_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the MIOpen handle.\n\n This is called when breaking down the MIOpen environment.\n @param handle MIOpen handle (input)\n @return miopenStatus_t"] + pub fn miopenDestroy(handle: miopenHandle_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set accelerator command queue previously created\n\n Set a command queue for an accelerator device\n @param handle MIOpen handle (input)\n @param streamID An accelerator queue type (input)\n @return miopenStatus_t"] + pub fn miopenSetStream( + handle: miopenHandle_t, + streamID: miopenAcceleratorQueue_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the previously created accelerator command queue\n\n Creates a command queue for an accelerator device\n @param handle MIOpen handle (input)\n @param streamID Pointer to a accelerator queue type (output)\n @return miopenStatus_t"] + pub fn miopenGetStream( + handle: miopenHandle_t, + streamID: *mut miopenAcceleratorQueue_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set allocator for previously created miopenHandle\n\n Set a command queue for an accelerator device\n @param handle MIOpen handle\n @param allocator A callback function MIOpen will use for internal memory allocations.\n The provided callback function should allocate device memory with requested size\n and return a pointer to this memory.\n Passing 0 will restore the default MIOpen allocator and deallocator.\n @param deallocator A callback function MIOpen will use to for internal memory deallocation.\n The provided callback function should free the specified memory pointer\n @param allocatorContext User-specified pointer which is passed to \\p allocator and \\p\n deallocator\n This allows the callback function to access state set by the caller to this function,\n for example a stateful heap allocator or a c++ class.\n @return miopenStatus_t"] + pub fn miopenSetAllocator( + handle: miopenHandle_t, + allocator: miopenAllocatorFunction, + deallocator: miopenDeallocatorFunction, + allocatorContext: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get time for last kernel launched\n\n This function is used only when profiling mode has been enabled.\n Kernel timings are based on the MIOpen handle and is not thread-safe.\n In order to use multi-threaded profiling, create an MIOpen handle for each\n concurrent thread.\n\n @param handle MIOpen handle (input)\n @param time Pointer to a float type to contain kernel time in milliseconds (output)\n @return miopenStatus_t"] + pub fn miopenGetKernelTime(handle: miopenHandle_t, time: *mut f32) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enable profiling to retrieve kernel time\n\n Enable or disable kernel profiling. This profiling is only for kernel time.\n @param handle MIOpen handle (input)\n @param enable Boolean to toggle profiling (input)\n @return miopenStatus_t"] + pub fn miopenEnableProfiling(handle: miopenHandle_t, enable: bool) -> miopenStatus_t; +} +#[doc = " @ingroup fusion\n @brief Creates the miopenFusionOpDescriptor_t type\n\n Fusion Operator Descriptor contains the meta-data associated with an operator\n to be fused in a compute graph\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenFusionOpDescriptor { + pub _address: u8, +} +pub type miopenFusionOpDescriptor_t = *mut miopenFusionOpDescriptor; +#[doc = " @ingroup tensor\n @brief Creates the miopenTensorDescriptor_t type\n\n Tensor descriptor is an object that allows the user to specify a layer's size for each\n dimension and dimension strides. Currently only 4-D fully packed tensors are supported.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenTensorDescriptor { + pub _address: u8, +} +pub type miopenTensorDescriptor_t = *mut miopenTensorDescriptor; +#[doc = " @ingroup convolutions\n @brief Creates the miopenConvolutionDescriptor_t type\n\n Convolution descriptor is an object that allows the user to specify a layer's padding, stride,\n and dilation of the convolutional filter. Parameters must all be non-negative.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenConvolutionDescriptor { + pub _address: u8, +} +pub type miopenConvolutionDescriptor_t = *mut miopenConvolutionDescriptor; +#[doc = " @ingroup pooling\n @brief Creates the miopenPoolingDescriptor_t type\n\n Pooling descriptor is an object that allows the user to specify the dimension sizes of the\n pooling windows, paddings, strides, and pooling mode.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenPoolingDescriptor { + pub _address: u8, +} +pub type miopenPoolingDescriptor_t = *mut miopenPoolingDescriptor; +#[doc = " @ingroup LRN\n @brief Creates the miopenLRNDescriptor_t type\n\n LRN descriptor is an object that allows the user to specify the LRN mode, the number of elements\n in the normalization window, and the LRN k-parameter.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenLRNDescriptor { + pub _address: u8, +} +pub type miopenLRNDescriptor_t = *mut miopenLRNDescriptor; +#[doc = " @ingroup activation\n @brief Creates the miopenActivationDescriptor_t type\n\n Activation descriptor is an object that allows the user to specify the activation mode.\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenActivationDescriptor { + pub _address: u8, +} +pub type miopenActivationDescriptor_t = *mut miopenActivationDescriptor; +#[doc = " @ingroup RNN\n @brief Creates the miopenRNNDescriptor_t type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenRNNDescriptor { + pub _address: u8, +} +pub type miopenRNNDescriptor_t = *mut miopenRNNDescriptor; +#[doc = " @ingroup LossFunction\n @brief Creates the miopenCTCLossDescriptor_t type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenCTCLossDescriptor { + pub _address: u8, +} +pub type miopenCTCLossDescriptor_t = *mut miopenCTCLossDescriptor; +#[doc = " @ingroup Dropout\n @brief Creates the miopenDropoutDescriptor_t type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenDropoutDescriptor { + pub _address: u8, +} +pub type miopenDropoutDescriptor_t = *mut miopenDropoutDescriptor; +#[doc = " @ingroup TensorReduce\n @brief Creates the miopenReduceTensorDescriptor_t type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenReduceTensorDescriptor { + pub _address: u8, +} +pub type miopenReduceTensorDescriptor_t = *mut miopenReduceTensorDescriptor; +impl miopenDataType_t { + #[doc = "< 16-bit floating point (Fully supported)"] + pub const miopenHalf: miopenDataType_t = miopenDataType_t(0); +} +impl miopenDataType_t { + #[doc = "< 32-bit floating point (Fully supported)"] + pub const miopenFloat: miopenDataType_t = miopenDataType_t(1); +} +impl miopenDataType_t { + #[doc = "< 32-bit int point (Partially supported)"] + pub const miopenInt32: miopenDataType_t = miopenDataType_t(2); +} +impl miopenDataType_t { + #[doc = "< 8-bit int point (Partially supported)"] + pub const miopenInt8: miopenDataType_t = miopenDataType_t(3); +} +impl miopenDataType_t { + pub const miopenInt8x4: miopenDataType_t = miopenDataType_t(4); +} +impl miopenDataType_t { + #[doc = "< 16-bit binary floating point (8-bit exponent, 7-bit fraction)\n(Partially supported)"] + pub const miopenBFloat16: miopenDataType_t = miopenDataType_t(5); +} +impl miopenDataType_t { + #[doc = "< 64-bit floating point (Partially supported)"] + pub const miopenDouble: miopenDataType_t = miopenDataType_t(6); +} +#[repr(transparent)] +#[doc = " @ingroup tensor\n @enum miopenDataType_t\n MIOpen floating point datatypes. Both 32-bit and 16-bit floats are supported in MIOpen."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenDataType_t(pub ::std::os::raw::c_uint); +impl miopenTensorLayout_t { + #[doc = "< NCHW memory layout (Fully supported)"] + pub const miopenTensorNCHW: miopenTensorLayout_t = miopenTensorLayout_t(0); +} +impl miopenTensorLayout_t { + #[doc = "< NHWC memory layout (Fully supported)"] + pub const miopenTensorNHWC: miopenTensorLayout_t = miopenTensorLayout_t(1); +} +impl miopenTensorLayout_t { + #[doc = "< CHWN memory layout (Not supported)"] + pub const miopenTensorCHWN: miopenTensorLayout_t = miopenTensorLayout_t(2); +} +impl miopenTensorLayout_t { + #[doc = "< NCHWc4 memory layout (Partially supported)"] + pub const miopenTensorNCHWc4: miopenTensorLayout_t = miopenTensorLayout_t(3); +} +impl miopenTensorLayout_t { + #[doc = "< NCHWc8 memory layout (Partially supported)"] + pub const miopenTensorNCHWc8: miopenTensorLayout_t = miopenTensorLayout_t(4); +} +impl miopenTensorLayout_t { + #[doc = "< CHWNc4 memory layout (Partially supported)"] + pub const miopenTensorCHWNc4: miopenTensorLayout_t = miopenTensorLayout_t(5); +} +impl miopenTensorLayout_t { + #[doc = "< CHWNc8 memory layout (Partially supported)"] + pub const miopenTensorCHWNc8: miopenTensorLayout_t = miopenTensorLayout_t(6); +} +impl miopenTensorLayout_t { + #[doc = "< NCDHW memory layout (Fully supported)"] + pub const miopenTensorNCDHW: miopenTensorLayout_t = miopenTensorLayout_t(7); +} +impl miopenTensorLayout_t { + #[doc = "< NCDHW memory layout (Fully supported)"] + pub const miopenTensorNDHWC: miopenTensorLayout_t = miopenTensorLayout_t(8); +} +#[repr(transparent)] +#[doc = " @ingroup tensor\n @enum miopenTensorLayout_t\n Tensor layouts supported by MIOpen.\n miopenTensorCHWNc4 and miopenTensorCHWNc8 layout only support weight tensor."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenTensorLayout_t(pub ::std::os::raw::c_uint); +impl miopenIndexType_t { + #[doc = "< 8-bit unsigned"] + pub const miopenIndexUint8: miopenIndexType_t = miopenIndexType_t(0); +} +impl miopenIndexType_t { + #[doc = "< 16-bit unsigned"] + pub const miopenIndexUint16: miopenIndexType_t = miopenIndexType_t(1); +} +impl miopenIndexType_t { + #[doc = "< 32-bit unsigned"] + pub const miopenIndexUint32: miopenIndexType_t = miopenIndexType_t(2); +} +impl miopenIndexType_t { + #[doc = "< 64-bit unsigned"] + pub const miopenIndexUint64: miopenIndexType_t = miopenIndexType_t(3); +} +#[repr(transparent)] +#[doc = " @ingroup pooling\n @enum miopenIndexType_t\n MIOpen index datatypes."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenIndexType_t(pub ::std::os::raw::c_uint); +impl miopenTensorOp_t { + #[doc = "< Add tensors element-wise"] + pub const miopenTensorOpAdd: miopenTensorOp_t = miopenTensorOp_t(0); +} +impl miopenTensorOp_t { + #[doc = "< Multiply two tensors element-wise"] + pub const miopenTensorOpMul: miopenTensorOp_t = miopenTensorOp_t(1); +} +impl miopenTensorOp_t { + #[doc = "< Minimum of tensor element pairs"] + pub const miopenTensorOpMin: miopenTensorOp_t = miopenTensorOp_t(2); +} +impl miopenTensorOp_t { + #[doc = "< Maximum of tensor element pairs"] + pub const miopenTensorOpMax: miopenTensorOp_t = miopenTensorOp_t(3); +} +#[repr(transparent)] +#[doc = " @ingroup tensor\n @enum miopenTensorOp_t\n Element-wise tensor operation modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenTensorOp_t(pub ::std::os::raw::c_uint); +impl miopenConvolutionMode_t { + #[doc = "< Cross-Correlation convolution"] + pub const miopenConvolution: miopenConvolutionMode_t = miopenConvolutionMode_t(0); +} +impl miopenConvolutionMode_t { + #[doc = "< Transpose convolutions -- deconvolution"] + pub const miopenTranspose: miopenConvolutionMode_t = miopenConvolutionMode_t(1); +} +impl miopenConvolutionMode_t { + #[doc = "< Deprecated Group convolution legacy, ToBe Removed"] + pub const miopenGroupConv: miopenConvolutionMode_t = miopenConvolutionMode_t(2); +} +impl miopenConvolutionMode_t { + #[doc = "< Deprecated Depthwise convolution legacy, ToBe Removed"] + pub const miopenDepthwise: miopenConvolutionMode_t = miopenConvolutionMode_t(3); +} +#[repr(transparent)] +#[doc = " @ingroup convolutions\n @enum miopenConvolutionMode_t\n Convolution mode selection for convolution layer preference."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvolutionMode_t(pub ::std::os::raw::c_uint); +impl miopenPoolingMode_t { + #[doc = "< Maximum pooling"] + pub const miopenPoolingMax: miopenPoolingMode_t = miopenPoolingMode_t(0); +} +impl miopenPoolingMode_t { + #[doc = "< Average pooling"] + pub const miopenPoolingAverage: miopenPoolingMode_t = miopenPoolingMode_t(1); +} +impl miopenPoolingMode_t { + #[doc = "< Inclusive Average pooling"] + pub const miopenPoolingAverageInclusive: miopenPoolingMode_t = miopenPoolingMode_t(2); +} +#[repr(transparent)] +#[doc = " @ingroup pooling\n @enum miopenPoolingMode_t\n Pooling layer mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenPoolingMode_t(pub ::std::os::raw::c_uint); +impl miopenPoolingWorkspaceIndexMode_t { + #[doc = "< Use mask indices, 2D pooling only"] + pub const miopenPoolingWorkspaceIndexMask: miopenPoolingWorkspaceIndexMode_t = + miopenPoolingWorkspaceIndexMode_t(0); +} +impl miopenPoolingWorkspaceIndexMode_t { + #[doc = "< Use image indices"] + pub const miopenPoolingWorkspaceIndexImage: miopenPoolingWorkspaceIndexMode_t = + miopenPoolingWorkspaceIndexMode_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup pooling\n @enum miopenPoolingWorkspaceIndexMode_t\n Pooling layer workspace index mode. miopenPoolingWorkspaceIndexMask mode records indices\n indicating the max values' positions in the filter/mask. miopenPoolingWorkspaceIndexImage mode\n records indices indicating the max values' positions in the image."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenPoolingWorkspaceIndexMode_t(pub ::std::os::raw::c_uint); +impl miopenLRNMode_t { + #[doc = "< Channel independent"] + pub const miopenLRNWithinChannel: miopenLRNMode_t = miopenLRNMode_t(0); +} +impl miopenLRNMode_t { + #[doc = "< Cross Channel"] + pub const miopenLRNCrossChannel: miopenLRNMode_t = miopenLRNMode_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup LRN\n @enum miopenLRNMode_t\n Local Response Normalization layer mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenLRNMode_t(pub ::std::os::raw::c_uint); +impl miopenBatchNormMode_t { + #[doc = "< Element-wise normalization for fully connected layer"] + pub const miopenBNPerActivation: miopenBatchNormMode_t = miopenBatchNormMode_t(0); +} +impl miopenBatchNormMode_t { + #[doc = "< Mini-batch spatial normalization for convolutional layers"] + pub const miopenBNSpatial: miopenBatchNormMode_t = miopenBatchNormMode_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup batchnorm\n @enum miopenBatchNormMode_t\n Batch Normalization layer mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenBatchNormMode_t(pub ::std::os::raw::c_uint); +impl miopenActivationMode_t { + #[doc = "< No activation, pass through the data"] + pub const miopenActivationPASTHRU: miopenActivationMode_t = miopenActivationMode_t(0); +} +impl miopenActivationMode_t { + #[doc = "< Sigmoid function: \\f$1 / (1 + e^{-x})\\f$"] + pub const miopenActivationLOGISTIC: miopenActivationMode_t = miopenActivationMode_t(1); +} +impl miopenActivationMode_t { + #[doc = "< Tanh activation \\f$ \\beta * tanh( \\alpha * x) \\f$"] + pub const miopenActivationTANH: miopenActivationMode_t = miopenActivationMode_t(2); +} +impl miopenActivationMode_t { + #[doc = "< Rectified Linear Unit \\f$ max(0, x) \\f$"] + pub const miopenActivationRELU: miopenActivationMode_t = miopenActivationMode_t(3); +} +impl miopenActivationMode_t { + #[doc = "< \\f$log(1 + e^x)\\f$"] + pub const miopenActivationSOFTRELU: miopenActivationMode_t = miopenActivationMode_t(4); +} +impl miopenActivationMode_t { + #[doc = "< Absolute value \\f$abs(x)\\f$"] + pub const miopenActivationABS: miopenActivationMode_t = miopenActivationMode_t(5); +} +impl miopenActivationMode_t { + #[doc = "< Scaled and shifted power \\f$(\\alpha + \\beta * x)^{gamma}\\f$"] + pub const miopenActivationPOWER: miopenActivationMode_t = miopenActivationMode_t(6); +} +impl miopenActivationMode_t { + pub const miopenActivationCLIPPEDRELU: miopenActivationMode_t = miopenActivationMode_t(7); +} +impl miopenActivationMode_t { + pub const miopenActivationLEAKYRELU: miopenActivationMode_t = miopenActivationMode_t(8); +} +impl miopenActivationMode_t { + pub const miopenActivationELU: miopenActivationMode_t = miopenActivationMode_t(9); +} +#[repr(transparent)] +#[doc = " @ingroup activation\n @enum miopenActivationMode_t\n Activation layer modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenActivationMode_t(pub ::std::os::raw::c_uint); +impl miopenSoftmaxAlgorithm_t { + #[doc = "< straightforward softmax"] + pub const MIOPEN_SOFTMAX_FAST: miopenSoftmaxAlgorithm_t = miopenSoftmaxAlgorithm_t(0); +} +impl miopenSoftmaxAlgorithm_t { + #[doc = "< scaled softmax by maximum value in input domain"] + pub const MIOPEN_SOFTMAX_ACCURATE: miopenSoftmaxAlgorithm_t = miopenSoftmaxAlgorithm_t(1); +} +impl miopenSoftmaxAlgorithm_t { + #[doc = "< log softmax"] + pub const MIOPEN_SOFTMAX_LOG: miopenSoftmaxAlgorithm_t = miopenSoftmaxAlgorithm_t(2); +} +#[repr(transparent)] +#[doc = " @ingroup softmax\n @enum miopenSoftmaxAlgorithm_t\n Softmax implementation algorithms"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenSoftmaxAlgorithm_t(pub ::std::os::raw::c_uint); +impl miopenSoftmaxMode_t { + #[doc = "< compute per image (N) across C, H, W"] + pub const MIOPEN_SOFTMAX_MODE_INSTANCE: miopenSoftmaxMode_t = miopenSoftmaxMode_t(0); +} +impl miopenSoftmaxMode_t { + pub const MIOPEN_SOFTMAX_MODE_CHANNEL: miopenSoftmaxMode_t = miopenSoftmaxMode_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup softmax\n @enum miopenSoftmaxMode_t\n Softmax modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenSoftmaxMode_t(pub ::std::os::raw::c_uint); +impl miopenReduceTensorOp_t { + #[doc = "< the operation is adding the values of the reduced elements"] + pub const MIOPEN_REDUCE_TENSOR_ADD: miopenReduceTensorOp_t = miopenReduceTensorOp_t(0); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_MUL: miopenReduceTensorOp_t = miopenReduceTensorOp_t(1); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_MIN: miopenReduceTensorOp_t = miopenReduceTensorOp_t(2); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_MAX: miopenReduceTensorOp_t = miopenReduceTensorOp_t(3); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_AMAX: miopenReduceTensorOp_t = miopenReduceTensorOp_t(4); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_AVG: miopenReduceTensorOp_t = miopenReduceTensorOp_t(5); +} +impl miopenReduceTensorOp_t { + pub const MIOPEN_REDUCE_TENSOR_NORM1: miopenReduceTensorOp_t = miopenReduceTensorOp_t(6); +} +impl miopenReduceTensorOp_t { + #[doc = "< the operation is getting the square root of the sum of\nsquares of the reduced elements"] + pub const MIOPEN_REDUCE_TENSOR_NORM2: miopenReduceTensorOp_t = miopenReduceTensorOp_t(7); +} +#[repr(transparent)] +#[doc = " @ingroup TensorReduce\n @enum miopenReduceTensorOp_t\n Tensor Reduction operation types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenReduceTensorOp_t(pub ::std::os::raw::c_uint); +impl miopenNanPropagation_t { + #[doc = "< does not propagate Nan number"] + pub const MIOPEN_NOT_PROPAGATE_NAN: miopenNanPropagation_t = miopenNanPropagation_t(0); +} +impl miopenNanPropagation_t { + #[doc = "< propagate the Nan number by the Reduction operation"] + pub const MIOPEN_PROPAGATE_NAN: miopenNanPropagation_t = miopenNanPropagation_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup TensorReduce\n @enum miopenReduceTensorOp_t\n Nan numbers propagation modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenNanPropagation_t(pub ::std::os::raw::c_uint); +impl miopenReduceTensorIndices_t { + #[doc = "< Does not compuate indices"] + pub const MIOPEN_REDUCE_TENSOR_NO_INDICES: miopenReduceTensorIndices_t = + miopenReduceTensorIndices_t(0); +} +impl miopenReduceTensorIndices_t { + #[doc = "< Compute the relative, flatted indices"] + pub const MIOPEN_REDUCE_TENSOR_FLATTENED_INDICES: miopenReduceTensorIndices_t = + miopenReduceTensorIndices_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup TensorReduce\n @enum miopenReduceTensorIndices_t\n Reduction Indices computation modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenReduceTensorIndices_t(pub ::std::os::raw::c_uint); +impl miopenIndicesType_t { + #[doc = "< unsigned integer indices"] + pub const MIOPEN_32BIT_INDICES: miopenIndicesType_t = miopenIndicesType_t(0); +} +impl miopenIndicesType_t { + #[doc = "< unsigned long indices"] + pub const MIOPEN_64BIT_INDICES: miopenIndicesType_t = miopenIndicesType_t(1); +} +impl miopenIndicesType_t { + #[doc = "< unsigned short indices"] + pub const MIOPEN_16BIT_INDICES: miopenIndicesType_t = miopenIndicesType_t(2); +} +impl miopenIndicesType_t { + #[doc = "< unsigned char indices"] + pub const MIOPEN_8BIT_INDICES: miopenIndicesType_t = miopenIndicesType_t(3); +} +#[repr(transparent)] +#[doc = " @ingroup TensorReduce\n @enum miopenIndicesType_t\n Reduction Indices types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenIndicesType_t(pub ::std::os::raw::c_uint); +impl miopenConvolutionAttrib_t { + pub const MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL: miopenConvolutionAttrib_t = + miopenConvolutionAttrib_t(0); +} +impl miopenConvolutionAttrib_t { + pub const MIOPEN_CONVOLUTION_ATTRIB_DETERMINISTIC: miopenConvolutionAttrib_t = + miopenConvolutionAttrib_t(1); +} +#[repr(transparent)] +#[doc = " @ingroup convolutions\n @enum miopenConvolutionAttrib_t\n Attribute for convolution descriptor, used for alternating the convolution behavior"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvolutionAttrib_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Create a Tensor Descriptor\n\n API for creating an uninitialized tensor descriptor.\n @param tensorDesc Pointer to a tensor descriptor type (output)\n @return miopenStatus_t"] + pub fn miopenCreateTensorDescriptor( + tensorDesc: *mut miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shape of 4D tensor\n\n Interface for setting 4-D tensor shape. MIOpen currently only implements NCHW layout.\n\n @param tensorDesc Tensor descriptor type (output)\n @param dataType MIOpen datatype (input)\n @param n Mini-batch size (input)\n @param c Number of channels (input)\n @param h Data height dimension size (input)\n @param w Data width dimension size (input)\n @return miopenStatus_t"] + pub fn miopenSet4dTensorDescriptor( + tensorDesc: miopenTensorDescriptor_t, + dataType: miopenDataType_t, + n: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + h: ::std::os::raw::c_int, + w: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shape of ND tensor with specific layout\n\n Interface for setting N-D tensor shape. This interface support NHWC, NCHW, NCHWc*, CHWNc*\n @param tensorDesc Tensor descriptor type (output)\n @param dataType MIOpen datatype (input)\n @param tensorLayout Tensor layout (input)\n @param lens Tensor dimensions (input)\n @param num_lens Tensor dimension size (input)\n @return miopenStatus_t"] + pub fn miopenSetNdTensorDescriptorWithLayout( + tensorDesc: miopenTensorDescriptor_t, + dataType: miopenDataType_t, + tensorLayout: miopenTensorLayout_t, + lens: *mut ::std::os::raw::c_int, + num_lens: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shape and stride of 4D tensor\n\n Interface for setting 4-D tensor shape and stride.\n\n @param tensorDesc Tensor descriptor type (output)\n @param dataType MIOpen datatype (input)\n @param n Mini-batch size (input)\n @param c Number of channels (input)\n @param h Data height dimension size (input)\n @param w Data width dimension size (input)\n @param nStride Mini-batch dimension stride (input)\n @param cStride Channel dimension stride (input)\n @param hStride Height dimension stride (input)\n @param wStride Width dimension stride (input)\n @return miopenStatus_t"] + pub fn miopenSet4dTensorDescriptorEx( + tensorDesc: miopenTensorDescriptor_t, + dataType: miopenDataType_t, + n: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + h: ::std::os::raw::c_int, + w: ::std::os::raw::c_int, + nStride: ::std::os::raw::c_int, + cStride: ::std::os::raw::c_int, + hStride: ::std::os::raw::c_int, + wStride: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the details of the tensor descriptor\n\n Interface to query the 4-D tensor shape.\n\n @param tensorDesc Tensor descriptor type (input)\n @param dataType MIOpen datatype (input)\n @param n Mini-batch size (output)\n @param c Number of channels (output)\n @param h Data height dimension size (output)\n @param w Data width dimension size (output)\n @param nStride Mini-batch dimension stride (output)\n @param cStride Channel dimension stride (output)\n @param hStride Height dimension stride (output)\n @param wStride Width dimension stride (output)\n @return miopenStatus_t"] + pub fn miopenGet4dTensorDescriptor( + tensorDesc: miopenTensorDescriptor_t, + dataType: *mut miopenDataType_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, + nStride: *mut ::std::os::raw::c_int, + cStride: *mut ::std::os::raw::c_int, + hStride: *mut ::std::os::raw::c_int, + wStride: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shape of N-dimensional tensor\n\n Interface for setting tensor shape. MIOpen has support for 1, 2, 3, 4, 5 dimensional tensor of\n layout.\n @param tensorDesc Tensor descriptor type (input)\n @param dataType MIOpen datatype (input)\n @param nbDims Number of dimensions in the dimsA array (input)\n @param dimsA Array containing the size of dimensions (input)\n @param stridesA Array containing the size of stride (input)\n @return miopenStatus_t"] + pub fn miopenSetTensorDescriptor( + tensorDesc: miopenTensorDescriptor_t, + dataType: miopenDataType_t, + nbDims: ::std::os::raw::c_int, + dimsA: *mut ::std::os::raw::c_int, + stridesA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set shape of N-dimensional tensor\n\n Interface for querying tensor size. MIOpen has support for 1, 2, 3, 4, 5 dimensional tensor of\n layout.\n @param tensorDesc Tensor descriptor type (input)\n @param size number of elements in tensor described by the descriptor (output)\n @return miopenStatus_t"] + pub fn miopenGetTensorDescriptorSize( + tensorDesc: miopenTensorDescriptor_t, + size: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the details of the N-dimensional tensor descriptor.\n\n @param tensorDesc Tensor descriptor type (input)\n @param dataType MIOpen datatype (input)\n @param dimsA Array containing the size of dimensions (output)\n @param stridesA Array containing the size of stride (output)\n @return miopenStatus_t"] + pub fn miopenGetTensorDescriptor( + tensorDesc: miopenTensorDescriptor_t, + dataType: *mut miopenDataType_t, + dimsA: *mut ::std::os::raw::c_int, + stridesA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the tensor descriptor\n\n @param tensorDesc Tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyTensorDescriptor(tensorDesc: miopenTensorDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute element-wise tensor operations\n\n This function implements: \\f$ C = op ( alpha1[0] * A, alpha2[0] * B ) + beta[0] * C \\f$\n\n For Forward Bias one can also use, miopenConvolutionForwardBias()\n\n @param handle MIOpen handle (input)\n @param tensorOp Operation from miopenTensorOp_t (input)\n @param alpha1 Tensor A's floating point scaling factor, allocated on the host (input)\n @param aDesc Tensor descriptor for tensor A (input)\n @param A Tensor A (input)\n @param alpha2 Tensor B's floating point scaling factor, allocated on the host (input)\n @param bDesc Tensor descriptor for tensor B (input)\n @param B Tensor B (input)\n @param beta Tensor C's floating point scaling factor, allocated on the host (input)\n @param cDesc Tensor descriptor for tensor C (input)\n @param C Tensor C (input and output)\n @return miopenStatus_t"] + pub fn miopenOpTensor( + handle: miopenHandle_t, + tensorOp: miopenTensorOp_t, + alpha1: *const ::std::os::raw::c_void, + aDesc: miopenTensorDescriptor_t, + A: *const ::std::os::raw::c_void, + alpha2: *const ::std::os::raw::c_void, + bDesc: miopenTensorDescriptor_t, + B: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + cDesc: miopenTensorDescriptor_t, + C: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Fills a tensor with a single value.\n\n Supported datatypes are fp32, fp16, and bfp16\n\n @param handle MIOpen handle (input)\n @param yDesc Tensor descriptor for tensor y (input)\n @param y Tensor y (input)\n @param alpha Pointer to fill value (input)\n @return miopenStatus_t"] + pub fn miopenSetTensor( + handle: miopenHandle_t, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + alpha: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Scales all elements in a tensor by a single value.\n\n Supported datatypes are fp32 and fp16\n\n @param handle MIOpen handle (input)\n @param yDesc Tensor descriptor for tensor y (input)\n @param y Tensor y (input and output)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @return miopenStatus_t"] + pub fn miopenScaleTensor( + handle: miopenHandle_t, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + alpha: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns number of bytes associated with tensor descriptor\n\n @param tensorDesc Tensor descriptor (input)\n @param numBytes Number of bytes associated with tensor descriptor (output)\n @return miopenStatus_t"] + pub fn miopenGetTensorNumBytes( + tensorDesc: miopenTensorDescriptor_t, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Copies one tensor to another tensor with a different layout/scale.\n\n This function implements:\n 1. \\f$ Y = alpha * X + beta * Y \\f$ for fp32 and fp16 datatype\n 2. Vectorize/de-vectorize along channel dimension C for int8 datatype\n\n Currently this is used for transforming from int8 to int8x4 vector datatypes\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Source Tensor descriptor for tensor x (input)\n @param x Source Tensor x (input)\n @param beta Floating point scaling factor, allocated on the host (input)\n @param yDesc Destination Tensor descriptor for tensor y (input)\n @param y Destination Tensor y (output)\n @return miopenStatus_t"] + pub fn miopenTransformTensor( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a convolution layer descriptor\n\n @param convDesc Convolution layer descriptor\n @return miopenStatus_t"] + pub fn miopenCreateConvolutionDescriptor( + convDesc: *mut miopenConvolutionDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a 2-D convolution layer descriptor\n\n For group/depthwise convolution dilation height and width, only a dilation value of 1 is\n supported.\n\n @param convDesc Convolution layer descriptor (output)\n @param c_mode Convolutional mode (input)\n @param pad_h Height input data padding (input)\n @param pad_w Width input data padding (input)\n @param stride_h Stride for the height of input data (input)\n @param stride_w Stride for the width of input data (input)\n @param dilation_h Dilation height (input)\n @param dilation_w Dilation width (input)\n @return miopenStatus_t"] + pub fn miopenInitConvolutionDescriptor( + convDesc: miopenConvolutionDescriptor_t, + c_mode: miopenConvolutionMode_t, + pad_h: ::std::os::raw::c_int, + pad_w: ::std::os::raw::c_int, + stride_h: ::std::os::raw::c_int, + stride_w: ::std::os::raw::c_int, + dilation_h: ::std::os::raw::c_int, + dilation_w: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a N-dimensional convolution layer descriptor\n\n @param convDesc Convolution layer descriptor (output)\n @param spatialDim Convolutional spatial dimension (input)\n @param padA Array of input data padding (input)\n @param strideA Array of convolution stride (input)\n @param dilationA Array of convolution dilation (input)\n @param c_mode Convolutional mode (input)\n @return miopenStatus_t"] + pub fn miopenInitConvolutionNdDescriptor( + convDesc: miopenConvolutionDescriptor_t, + spatialDim: ::std::os::raw::c_int, + padA: *mut ::std::os::raw::c_int, + strideA: *mut ::std::os::raw::c_int, + dilationA: *mut ::std::os::raw::c_int, + c_mode: miopenConvolutionMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieves a 2-D convolution layer descriptor's details\n\n For group/depthwise convolution dilation height and width, only a dilation value of 1 is\n supported.\n\n @param convDesc Convolution layer descriptor (input)\n @param c_mode Convolutional mode (output)\n @param pad_h Height input data padding (output)\n @param pad_w Width input data padding (output)\n @param stride_h Stride for the height of input data (output)\n @param stride_w Stride for the width of input data (output)\n @param dilation_h Dilation height (output)\n @param dilation_w Dilation width (output)\n @return miopenStatus_t"] + pub fn miopenGetConvolutionDescriptor( + convDesc: miopenConvolutionDescriptor_t, + c_mode: *mut miopenConvolutionMode_t, + pad_h: *mut ::std::os::raw::c_int, + pad_w: *mut ::std::os::raw::c_int, + stride_h: *mut ::std::os::raw::c_int, + stride_w: *mut ::std::os::raw::c_int, + dilation_h: *mut ::std::os::raw::c_int, + dilation_w: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieves a N-dimensional convolution layer descriptor's details\n\n @param convDesc Convolution layer descriptor (input)\n @param requestedSpatialDim Expected convolution spatial dimension (intput)\n @param spatialDim Convolutional spatial dimension (output)\n @param padA Array of input data padding (output)\n @param strideA Array of convolution stride (output)\n @param dilationA Array of convolution dilation (output)\n @param c_mode Convolutional mode (output)\n @return miopenStatus_t"] + pub fn miopenGetConvolutionNdDescriptor( + convDesc: miopenConvolutionDescriptor_t, + requestedSpatialDim: ::std::os::raw::c_int, + spatialDim: *mut ::std::os::raw::c_int, + padA: *mut ::std::os::raw::c_int, + strideA: *mut ::std::os::raw::c_int, + dilationA: *mut ::std::os::raw::c_int, + c_mode: *mut miopenConvolutionMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the number of groups to be used in Group/Depthwise convolution\n\n Must be called before all computational APIs of group/depthwise convolution, it is preferable to\n call miopenInitConvolutionDescriptor() first, then miopenSetConvolutionGroupCount() to fully\n initialize group convolutions. Both Convolution Mode and Transpose Convolution Mode support\n group/depthwise convolution. To run depthwise convolution, set groupCount value equal to number\n of channels.\n\n @param convDesc Convolution layer descriptor (output)\n @param groupCount number of groups, in depthwise conv using filter_number/channel_multiplier\n (input)\n @return miopenStatus_t"] + pub fn miopenSetConvolutionGroupCount( + convDesc: miopenConvolutionDescriptor_t, + groupCount: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the output padding to be used in 2-D Transpose convolution\n\n This function is optional for initialization of Transpose convolution. If applicable, it must be\n called before all computational APIs of Transpose convolution. It is preferable to call\n miopenInitConvolutionDescriptor() first, then miopenSetTransposeConvOutputPadding() to fully\n initialize transpose convolutions.\n\n @param convDesc Convolution layer descriptor (output)\n @param adj_h output padding for the height of output data (input)\n @param adj_w output padding for the width of output data (input)\n @return miopenStatus_t"] + pub fn miopenSetTransposeConvOutputPadding( + convDesc: miopenConvolutionDescriptor_t, + adj_h: ::std::os::raw::c_int, + adj_w: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the output padding to be used in N-dimensional Transpose convolution\n\n This function is optional for initialization of Transpose convolution. If applicable, it must be\n called before all computational APIs of Transpose convolution. It is preferable to call\n miopenInitConvolutionNdDescriptor() first, then miopenSetTransposeConvNdOutputPadding() to fully\n initialize transpose convolutions. Currently, 2-D and 3-D convolutions are supported.\n\n @param convDesc Convolution layer descriptor (output)\n @param spatialDim Convolutional spatial dimension (input)\n @param adjA array of output padding for output data (input)\n @return miopenStatus_t"] + pub fn miopenSetTransposeConvNdOutputPadding( + convDesc: miopenConvolutionDescriptor_t, + spatialDim: ::std::os::raw::c_int, + adjA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the shape of a resulting 4-D tensor from a 2-D convolution\n\n This function returns the dimensions of the resulting 4D tensor of a 2D\n convolution, given the convolution descriptor, the input tensor descriptor\n and the filter descriptor. This function can help to setup the output tensor\n and allocate the proper amount of memory prior to launch the actual\n convolution.\n\n @param convDesc Convolution layer descriptor (input)\n @param inputTensorDesc Input data tensor descriptor (input)\n @param filterDesc Weight descriptor (input)\n @param n Mini-batch size (output)\n @param c Number of channels (output)\n @param h Data height dimension size (output)\n @param w Data width dimension size (output)\n @return miopenStatus_t"] + pub fn miopenGetConvolutionForwardOutputDim( + convDesc: miopenConvolutionDescriptor_t, + inputTensorDesc: miopenTensorDescriptor_t, + filterDesc: miopenTensorDescriptor_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the shape of a resulting N-dimensional tensor from a (N-2)-dimensional convolution\n\n This function returns the dimensions of the resulting N-dimensional tensor of a (N-2)-dimensional\n convolution, given the convolution descriptor, the input tensor descriptor\n and the filter descriptor. It is used to setup the output tensor descriptor prior to executing\n the convolution layer.\n\n @param convDesc Convolution layer descriptor (input)\n @param inputTensorDesc Input data tensor descriptor (input)\n @param filterDesc Weight descriptor (input)\n @param nDim Pointer to Output data tensor dimension (output)\n @param outputTensorDimA Array of Output data tensor length (output)"] + pub fn miopenGetConvolutionNdForwardOutputDim( + convDesc: miopenConvolutionDescriptor_t, + inputTensorDesc: miopenTensorDescriptor_t, + filterDesc: miopenTensorDescriptor_t, + nDim: *mut ::std::os::raw::c_int, + outputTensorDimA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the tensor descriptor object\n\n @param convDesc Convolution tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyConvolutionDescriptor( + convDesc: miopenConvolutionDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the attribute of the convolution descriptor\n\n @param convDesc Convolution layer descriptor (input)\n @param attr Attribute of this convolution to set (input)\n @param value Value of this attribute (input)"] + pub fn miopenSetConvolutionAttribute( + convDesc: miopenConvolutionDescriptor_t, + attr: miopenConvolutionAttrib_t, + value: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the attribute of the convolution descriptor\n\n @param convDesc Convolution layer descriptor (input)\n @param attr Attribute of this convolution to get (input)\n @param value Value of this attribute (output)"] + pub fn miopenGetConvolutionAttribute( + convDesc: miopenConvolutionDescriptor_t, + attr: miopenConvolutionAttrib_t, + value: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +impl miopenConvFwdAlgorithm_t { + #[doc = "< GEMM variant"] + pub const miopenConvolutionFwdAlgoGEMM: miopenConvFwdAlgorithm_t = miopenConvFwdAlgorithm_t(0); +} +impl miopenConvFwdAlgorithm_t { + #[doc = "< Direct convolutions"] + pub const miopenConvolutionFwdAlgoDirect: miopenConvFwdAlgorithm_t = + miopenConvFwdAlgorithm_t(1); +} +impl miopenConvFwdAlgorithm_t { + #[doc = "< Fast Fourier Transform indirect convolutions"] + pub const miopenConvolutionFwdAlgoFFT: miopenConvFwdAlgorithm_t = miopenConvFwdAlgorithm_t(2); +} +impl miopenConvFwdAlgorithm_t { + #[doc = "< Winograd indirect convolutions"] + pub const miopenConvolutionFwdAlgoWinograd: miopenConvFwdAlgorithm_t = + miopenConvFwdAlgorithm_t(3); +} +impl miopenConvFwdAlgorithm_t { + #[doc = "< Implicit GEMM convolutions, fp32 only"] + pub const miopenConvolutionFwdAlgoImplicitGEMM: miopenConvFwdAlgorithm_t = + miopenConvFwdAlgorithm_t(5); +} +#[repr(transparent)] +#[doc = " @enum miopenConvFwdAlgorithm_t\n Convolutional algorithm mode for forward propagation. MIOpen use cross-correlation for its\n convolution implementation."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvFwdAlgorithm_t(pub ::std::os::raw::c_uint); +impl miopenConvBwdWeightsAlgorithm_t { + #[doc = "< GEMM variant"] + pub const miopenConvolutionBwdWeightsAlgoGEMM: miopenConvBwdWeightsAlgorithm_t = + miopenConvBwdWeightsAlgorithm_t(0); +} +impl miopenConvBwdWeightsAlgorithm_t { + #[doc = "< Direct convolution algorithm"] + pub const miopenConvolutionBwdWeightsAlgoDirect: miopenConvBwdWeightsAlgorithm_t = + miopenConvBwdWeightsAlgorithm_t(1); +} +impl miopenConvBwdWeightsAlgorithm_t { + #[doc = "< Winograd convolutions"] + pub const miopenConvolutionBwdWeightsAlgoWinograd: miopenConvBwdWeightsAlgorithm_t = + miopenConvBwdWeightsAlgorithm_t(3); +} +impl miopenConvBwdWeightsAlgorithm_t { + #[doc = "< Implicit GEMM convolutions"] + pub const miopenConvolutionBwdWeightsAlgoImplicitGEMM: miopenConvBwdWeightsAlgorithm_t = + miopenConvBwdWeightsAlgorithm_t(5); +} +#[repr(transparent)] +#[doc = " @enum miopenConvBwdWeightsAlgorithm_t\n Convolutional algorithm mode for back propagation on weights."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvBwdWeightsAlgorithm_t(pub ::std::os::raw::c_uint); +impl miopenConvBwdDataAlgorithm_t { + #[doc = "< GEMM variant"] + pub const miopenConvolutionBwdDataAlgoGEMM: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(0); +} +impl miopenConvBwdDataAlgorithm_t { + #[doc = "< Direct convolutions"] + pub const miopenConvolutionBwdDataAlgoDirect: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(1); +} +impl miopenConvBwdDataAlgorithm_t { + #[doc = "< Fast Fourier Transform indirect convolutions"] + pub const miopenConvolutionBwdDataAlgoFFT: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(2); +} +impl miopenConvBwdDataAlgorithm_t { + #[doc = "< Winograd indirect convolutions"] + pub const miopenConvolutionBwdDataAlgoWinograd: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(3); +} +impl miopenConvBwdDataAlgorithm_t { + pub const miopenTransposeBwdDataAlgoGEMM: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(4); +} +impl miopenConvBwdDataAlgorithm_t { + #[doc = "< Implicit GEMM convolutions, fp32 only"] + pub const miopenConvolutionBwdDataAlgoImplicitGEMM: miopenConvBwdDataAlgorithm_t = + miopenConvBwdDataAlgorithm_t(5); +} +#[repr(transparent)] +#[doc = " @enum miopenConvBwdDataAlgorithm_t\n Convolutional algorithm mode for back propagation on data."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvBwdDataAlgorithm_t(pub ::std::os::raw::c_uint); +impl miopenConvAlgorithm_t { + #[doc = "< GEMM variant"] + pub const miopenConvolutionAlgoGEMM: miopenConvAlgorithm_t = miopenConvAlgorithm_t(0); +} +impl miopenConvAlgorithm_t { + #[doc = "< Direct convolutions"] + pub const miopenConvolutionAlgoDirect: miopenConvAlgorithm_t = miopenConvAlgorithm_t(1); +} +impl miopenConvAlgorithm_t { + #[doc = "< Fast Fourier Transform indirect convolutions"] + pub const miopenConvolutionAlgoFFT: miopenConvAlgorithm_t = miopenConvAlgorithm_t(2); +} +impl miopenConvAlgorithm_t { + #[doc = "< Winograd indirect convolutions"] + pub const miopenConvolutionAlgoWinograd: miopenConvAlgorithm_t = miopenConvAlgorithm_t(3); +} +impl miopenConvAlgorithm_t { + #[doc = "< Implicit GEMM convolutions, fp32 only"] + pub const miopenConvolutionAlgoImplicitGEMM: miopenConvAlgorithm_t = miopenConvAlgorithm_t(5); +} +#[repr(transparent)] +#[doc = " @enum miopenConvAlgorithm_t\n Top-level convolutional algorithm mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenConvAlgorithm_t(pub ::std::os::raw::c_uint); +#[doc = " @brief Perf struct for forward, backward filter, or backward data algorithms\n\n Contains the union to hold the selected convolution algorithm for forward, or backwards layers,\n and also contains the time it took to run the algorithm and the workspace required to run the\n algorithm. The workspace in this structure can be used when executing the convolution layer."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenConvAlgoPerf_t { + pub __bindgen_anon_1: miopenConvAlgoPerf_t__bindgen_ty_1, + #[doc = "< Time to exectued the selected algorithm represented in the union"] + pub time: f32, + #[doc = "< Workspace required to run the selected algorithm represented in the union"] + pub memory: usize, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union miopenConvAlgoPerf_t__bindgen_ty_1 { + #[doc = "< Forward convolution algorithm enum selection"] + pub fwd_algo: miopenConvFwdAlgorithm_t, + #[doc = "< Back propagation on weights\nconvolution algorithm enum selection"] + pub bwd_weights_algo: miopenConvBwdWeightsAlgorithm_t, + #[doc = "< Back propagation on data convolution algorithm enum selection"] + pub bwd_data_algo: miopenConvBwdDataAlgorithm_t, +} +#[doc = " @brief Performance struct for forward, backward filter, or backward data algorithms in\n immediate mode\n\n Contains a 64-bit integer identifying the solution and the algorithm for the solution,\n as well as the runtime, workspace size and a boolean flag indicating whether the returned\n solution is a heuristic or resulting from an actual run\n"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenConvSolution_t { + #[doc = "< Represents the approximate time required to execute this solution on the GPU,\nin milliseconds. This value may either be based on an acutal kernel run or an\nestimate based on a heuristic."] + pub time: f32, + #[doc = "< Workspace required to run the selected algorithm represented in the\nunion"] + pub workspace_size: usize, + #[doc = "< Identifier for the returned solution"] + pub solution_id: u64, + #[doc = "< The algorithm used to compute the solution"] + pub algorithm: miopenConvAlgorithm_t, +} +extern "C" { + #[must_use] + #[doc = " @brief Query the maximum number of solutions applicable for the given input/output and weights\n tensor descriptor for Convolution in the Forward direction.\n\n This call returns the maximum number of applicable solutions for a forward convolution problem.\n The \\c solutionCount returned may be used to allocate the memory required for the\n \\c miopenConvAlgoPerf_t which is required by miopenConvolutionGetSolution API calls.\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param solutionCount Pointer to memory to return number of applicable solutions (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardGetSolutionCount( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + solutionCount: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the applicable solutions for a convolution configuration described by\n input, output and convolution descriptors.\n\n The returned solutions array is sorted in the order of decreasing performance. The returned\n solutions\n might be based\n on heuristics and for more consistent performance results the user the advised to run the Find\n step.\n The maximum length of the solutions array may be queried using\n miopenConvolutionForwardGetSolutionCount\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param maxSolutionCount The size of the solutions array passed in below (input)\n @param solutionCount The size of the solutions array returned (output)\n @param solutions A pointer to an array of type miopenConvSolution_t allocated by the user,\n filled in by MIOpen with applicable solutions. (output)\n @return miopenStatus_t\n"] + pub fn miopenConvolutionForwardGetSolution( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + maxSolutionCount: usize, + solutionCount: *mut usize, + solutions: *mut miopenConvSolution_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the workspace size required for a particular solution id.\n\n This is an optional call for users who may have serialized the solution id and just need the\n workspace\n size for it. The same information is returned by the miopenConvolutionForwardGetSolution as part\n of the\n miopenConvSolution_t struct.\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param solution_id ID of the solution for which workspace size is required (input)\n @param workSpaceSize The size of the workspace (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardGetSolutionWorkspaceSize( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + solution_id: u64, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Compiles the solution provided by the user, this solution may be acquired by the\n miopenConvolutionForwardGetSolution API call above.\n Compiling the solution ensures that the first API call to miopenConvolutionForwardImmediate\n does\n not cause a compile.\n\n This is an optional step and may be skipped if a slow first miopenConvolutionForwardImmediate\n invocation is acceptable.\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardCompileSolution( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Executes the Forward convolution operation based on the provided solution ID.\n\n Supported datatypes are fp32, fp16, bfp16, and int8\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param x Data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param workSpace Workspace tensor (input)\n @param workSpaceSize Size of the memory in bytes pointed to by workSpace above\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardImmediate( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the maximum number of solutions applicable for the given input/output and weights\n tensor descriptor for backward Convolution w-r-t Data.\n\n This call returns the maximum number of applicable solutions for a the convolution problem, the\n number\n returned may be used to allocate the memory required for the miopenConvAlgoPert2_t which is\n required\n by miopenConvolutionBackwardDataGetSolution API calls.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param solutionCount Pointer to memory to return number of applicable solutions (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardDataGetSolutionCount( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + solutionCount: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the applicable solutions for a backward convolution w-r-t data as described by\n input, output and convolution descriptors.\n\n The returned solutions array is sorted in the order of decreasing performance. The returned\n solutions\n ns\n might be based\n on heuristics and for more consistent performance results the user the advised to run the Find\n step.\n The maximum length of the solutions array may be queried using\n miopenConvolutionBackwardDataGetSolutionCount\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param maxSolutionCount The size of the solutions array passed in below (input)\n @param solutionCount The size of the solutions array returned (output)\n @param solutions A pointer to an array of type miopenConvSolution_t allocated by the user,\n filled in by MIOpen with applicable solutions. (output)\n @return miopenStatus_t\n"] + pub fn miopenConvolutionBackwardDataGetSolution( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + maxSolutionCount: usize, + solutionCount: *mut usize, + solutions: *mut miopenConvSolution_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the workspace size required for a particular solution id.\n\n This is an optional call for users who may have serialized the solution id and just need the\n workspace\n size for it. The same information is returned by the miopenConvolutionBackwardDataGetSolution as\n part of the\n miopenConvSolution_t struct.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param solution_id ID of the solution for which workspace size is required (input)\n @param workSpaceSize The size of the workspace (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardDataGetSolutionWorkspaceSize( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + solution_id: u64, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Compiles the solution provided by the user, this solution may be acquired by the\n miopenConvolutionBackwardDataGetSolution API call above.\n Compiling the solution ensures that the first API call to\n miopenConvolutionBackwardDataImmediate\n does not cause a compile.\n\n This is an optional step and may be skipped if a slow first\n miopenConvolutionBackwardDataImmediate\n invocation is acceptable.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardDataCompileSolution( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Executes the Backward convolution w-r-t data operation based on the provided solution\n ID.\n\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param dx Data delta tensor dx (output)\n @param workSpace Workspace tensor (input)\n @param workSpaceSize Size in bytes of the workspace memory pointed to by workSpace\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardDataImmediate( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the maximum number of solutions applicable for the given input/output and weights\n tensor descriptor for backward Convolution w-r-t Weights.\n\n This call returns the maximum number of applicable solutions for a the convolution problem, the\n number\n returned may be used to allocate the memory required for the miopenConvAlgoPert2_t which is\n required\n by miopenConvolutionBackwardWeightsGetSolution API calls.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param solutionCount Pointer to memory to return number of applicable solutions (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeightsGetSolutionCount( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + solutionCount: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the applicable solutions for a backward convolution w-r-t weights as described by\n input, output and convolution descriptors.\n\n The returned solutions array is sorted in the order of decreasing performance. The returned\n solutions\n might be based\n on heuristics and for more consistent performance results the user the advised to run the Find\n step.\n The maximum length of the solutions array may be queried using\n miopenConvolutionBackwardWeightsGetSolutionCount\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param maxSolutionCount The size of the solutions array passed in below (input)\n @param solutionCount The size of the solutions array returned (output)\n @param solutions A pointer to an array of type miopenConvSolution_t allocated by the user,\n filled in by MIOpen with applicable solutions. (output)\n @return miopenStatus_t\n"] + pub fn miopenConvolutionBackwardWeightsGetSolution( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + maxSolutionCount: usize, + solutionCount: *mut usize, + solutions: *mut miopenConvSolution_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the workspace size required for a particular solution id.\n\n This is an optional call for users who may have serialized the solution id and just need the\n workspace\n size for it. The same information is returned by the miopenConvolutionBackwardWeightsGetSolution\n as part of the\n miopenConvSolution_t struct.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param solution_id ID of the solution for which workspace size is required (input)\n @param workSpaceSize The size of the workspace (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeightsGetSolutionWorkspaceSize( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + solution_id: u64, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Compiles the solution provided by the user, this solution may be acquired by the\n miopenConvolutionBackwardWeightsGetSolution API call above.\n Compiling the solution ensures that the first API call to\n miopenConvolutionBackwardWeightsImmediate\n does not cause a compile.\n\n This is an optional step and may be skipped if a slow first\n miopenConvolutionBackwardWeightsImmediate invocation is acceptable.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeightsCompileSolution( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Executes the Backward convolution w-r-t weights operation based on the provided solution\n ID.\n\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param x Data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param dw Weights delta tensor dw (output)\n @param workSpace Workspace tensor (input)\n @param workSpaceSize Size in bytes of the memory passed in, pointed to by workSpace pointer\n above\n @param solution_id ID of the solution to be compiled, as chosen by the user\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeightsImmediate( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + dw: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + solution_id: u64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the workspace size required for a forward convolution layer\n\n This call is required and must be executed once before running\n miopenFindConvolutionForwardAlgorithm()\n in order to determine the largest required allocation for the algorithm search; i.e., the maximum\n size\n of the memory needed from the set of potential forward convolution algorithm is returned.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param workSpaceSize Pointer to memory to return size in bytes (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardGetWorkSpaceSize( + handle: miopenHandle_t, + wDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Search and run the forward convolutional algorithms and return a list of kernel times.\n\n This function attempts all MIOpen forward convolution algorithms based on\n the input configuration, and outputs performance metrics to a\n user-allocated array of type miopenConvAlgoPerf_t. These metrics are written\n in a sorted fashion where the first element has the lowest compute time.\n Users can chose the top-most algorithm if they only care about the fastest\n algorithm.\n\n This function is mandatory before using miopenConvolutionForward(). In order\n to execute this function, miopenConvolutionForwardGetWorkSpaceSize() must be\n run to determine the required memory for this search.\n\n * If exhaustiveSearch == 0, MIOpen will look for the first kernel with a configuration match. If\n a configuration match is not found, a default configuration will be returned.\n\n * If exhaustiveSearch == 1, MIOpen will look for the best kernel for the provided configuration.\n If a match is not found, an exhaustive search is performed by running individual algorithms.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param requestAlgoCount Number of algorithms to return kernel times (input)\n @param returnedAlgoCount Pointer to number of algorithms returned (output)\n @param perfResults Pointer to union of best algorithm for forward and backwards (input)\n @param workSpace Pointer to workspace required for the search (output)\n @param workSpaceSize Size in bytes of the memory needed for find (output)\n @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations\n (input)\n @return miopenStatus_t"] + pub fn miopenFindConvolutionForwardAlgorithm( + handle: miopenHandle_t, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + requestAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut miopenConvAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + exhaustiveSearch: bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a forward convolution layer\n\n Runs the forward convolution layer based on the selected algorithm. The function\n miopenFindConvolutionForwardAlgorithm() must have been executed previously to\n determine the required memory needed for the workspace and the best convolutional algorithm.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (inputs)\n @param convDesc Convolution layer descriptor (inputs)\n @param algo Algorithm selected (inputs)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param workSpace Pointer to workspace required (input)\n @param workSpaceSize Size in bytes of the memory determined by the find step (input)\n @return miopenStatus_t"] + pub fn miopenConvolutionForward( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + algo: miopenConvFwdAlgorithm_t, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Calculate element-wise scale and shift of a tensor via a bias tensor\n\n This function applies an element-wise bias to a data tensor from an input bias tensor.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param bDesc Tensor descriptor for bias tensor b (input)\n @param b Bias tensor b (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for data tensor y (input)\n @param y Data tensor y (input and output)\n @return miopenStatus_t"] + pub fn miopenConvolutionForwardBias( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + bDesc: miopenTensorDescriptor_t, + b: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the GPU memory required for the backward data convolution algorithm.\n\n For a provided tensor descriptors and algorithm selection, this function calculates and returns\n the workspace size required for back propagation on data. This call is required and must be\n executed once before running miopenFindConvolutionBackwardDataAlgorithm() in order to determine\n the largest required allocation for the algorithm search; i.e., the maximum size of the memory\n needed from the set of potential backward convolution algorithm is returned.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param workSpaceSize Size in bytes of the memory required (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardDataGetWorkSpaceSize( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Search and run the backwards data convolution algorithms and return a list of kernel\n times.\n\n This function attempts all MIOpen backward data convolution algorithms, and outputs the\n performance metrics to a user-allocated array of type miopenConvAlgoPerf_t.\n These metrics are written in sorted fashion where the first element has the lowest compute time.\n This function is mandatory before using backwards convolutions. Users can chose the top-most\n algorithm if they only care about the fastest algorithm.\n\n This function is mandatory before using miopenConvolutionBackwardData(). In order to\n execute this function, miopenConvolutionBackwardsDataGetWorkSpaceSize() must be run to determine\n the required memory for this search.\n\n * If exhaustiveSearch == 0, MIOpen will look for the first kernel with a configuration match. If\n a configuration match is not found, a default configuration will be returned.\n\n * If exhaustiveSearch == 1, MIOpen will look for the best kernel for the provided configuration.\n If a match is not found, an exhaustive search is performed by running individual algorithms.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param dx Data delta tensor dx (input)\n @param requestAlgoCount Number of algorithms to return kernel times (input)\n @param returnedAlgoCount Pointer to number of algorithms returned (output)\n @param perfResults Pointer to union of best algorithm for forward and backwards (output)\n @param workSpace Pointer to workspace required for the search (output)\n @param workSpaceSize Size in bytes of the memory needed for find (output)\n @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations\n (input)\n @return miopenStatus_t"] + pub fn miopenFindConvolutionBackwardDataAlgorithm( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + requestAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut miopenConvAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + exhaustiveSearch: bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a backward data convolution layer\n\n Runs the backward data convolution layer based on the selected algorithm. The function\n miopenFindConvolutionBackwardDataAlgorithm() must have been executed previously to\n determine the required memory needed for the workspace and the best convolutional\n algorithm.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param wDesc Tensor descriptor for weight tensor w (input)\n @param w Weights tensor w (input)\n @param convDesc Convolution layer descriptor (input)\n @param algo Algorithm selected (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param dx Data delta tensor dx (output)\n @param workSpace Pointer to workspace required for the search (input)\n @param workSpaceSize Size in bytes of the memory needed for find (input)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardData( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + algo: miopenConvBwdDataAlgorithm_t, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the GPU memory required for the backward weights convolution algorithm.\n\n\n For a provided tensor descriptors and algorithm selection, this function calculates and returns\n the workspace size required for back propagation on data. This call is required and must be\n executed once before running miopenFindConvolutionBackwardWeightsAlgorithm() in order to\n determine\n the largest required allocation for the algorithm search; i.e., the maximum size of the memory\n needed from the set of potential backward weights convolution algorithm is returned.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for output weights tensor dw (input)\n @param workSpaceSize Size in bytes of the memory required (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeightsGetWorkSpaceSize( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Search and run the backwards weights convolutional algorithms and return a list of kernel\n times.\n\n This function attempts all MIOpen backward weights convolution algorithms, and outputs\n the performance metrics to a user-allocated array of type miopenConvAlgoPerf_t. These metrics are\n written in sorted fashion where the first element has the lowest compute time.\n This function is mandatory before using backwards weight convolutions. Users can chose the\n top-most algorithm if they only care about the fastest algorithm.\n\n This function is mandatory before using miopenConvolutionBackwardWeights(). In order to\n execute this function, miopenConvolutionBackwardsWeightsGetWorkSpaceSize() must be run to\n determine the required memory for this search.\n\n * If exhaustiveSearch == 0, MIOpen will look for the first kernel with a configuration match. If\n a configuration match is not found, a default configuration will be returned.\n\n * If exhaustiveSearch == 1, MIOpen will look for the best kernel for the provided configuration.\n If a match is not found, an exhaustive search is performed by running individual algorithms.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for output data tensor x (input)\n @param x Data delta tensor dx (input)\n @param convDesc Convolution layer descriptor (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param dw Weights delta tensor dw (input)\n @param requestAlgoCount Number of algorithms to return kernel times (input)\n @param returnedAlgoCount Pointer to number of algorithms returned (output)\n @param perfResults Pointer to union of best algorithm for forward and backwards (output)\n @param workSpace Pointer to workspace required for the search (output)\n @param workSpaceSize Size in bytes of the memory needed for find (output)\n @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations\n (input)\n @return miopenStatus_t"] + pub fn miopenFindConvolutionBackwardWeightsAlgorithm( + handle: miopenHandle_t, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + dwDesc: miopenTensorDescriptor_t, + dw: *mut ::std::os::raw::c_void, + requestAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut miopenConvAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + exhaustiveSearch: bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a backward weights convolution layer\n\n Runs the backward weights convolution layer based on the selected algorithm. The function\n miopenFindConvolutionBackwardWeightsAlgorithm() must have\n been executed previously to determine the required memory needed for the workspace and the\n best convolutional algorithm.\n\n If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running\n this.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param dyDesc Tensor descriptor for data tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param x Data tensor x (input)\n @param convDesc Convolution layer descriptor (input)\n @param algo Algorithm selected (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dwDesc Tensor descriptor for weight tensor dw (input)\n @param dw Weights delta tensor dw (output)\n @param workSpace Pointer to workspace required for the search (input)\n @param workSpaceSize Size in bytes of the memory needed for find (input)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardWeights( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + algo: miopenConvBwdWeightsAlgorithm_t, + beta: *const ::std::os::raw::c_void, + dwDesc: miopenTensorDescriptor_t, + dw: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Calculates the gradient with respect to the bias.\n\n Compute the convolution backwards gradient with respect to the bias tensor.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dbDesc Tensor descriptor for input bias tensor db (input)\n @param db Bias delta tensor db (output)\n @return miopenStatus_t"] + pub fn miopenConvolutionBackwardBias( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dbDesc: miopenTensorDescriptor_t, + db: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a pooling layer descriptor\n\n @param poolDesc Pointer to a pooling layer descriptor (output)\n @return miopenStatus_t"] + pub fn miopenCreatePoolingDescriptor( + poolDesc: *mut miopenPoolingDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set index data type for pooling layer. The default indexing type is uint8_t.\n Users can set the index type to any of the miopenIndexType_t sizes; 8, 16, 32, or 64 bit\n unsigned integers.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param index_type Index type (input)\n @return miopenStatus_t"] + pub fn miopenSetPoolingIndexType( + poolDesc: miopenPoolingDescriptor_t, + index_type: miopenIndexType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the index data type for pooling layer. The index type to any of the\n miopenIndexType_t sizes; 8, 16, 32, or 64 bit unsigned integers.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param index_type Index type (output)\n @return miopenStatus_t"] + pub fn miopenGetPoolingIndexType( + poolDesc: miopenPoolingDescriptor_t, + index_type: *mut miopenIndexType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set workspace index mode for pooling layer. The default mode is\n miopenPoolingWorkSpaceIndexMask.\n\n @param poolDesc Pointer to a pooling layer descriptor (input/output)\n @param workspace_index Workspace index mode (input)\n @return miopenStatus_t"] + pub fn miopenSetPoolingWorkSpaceIndexMode( + poolDesc: miopenPoolingDescriptor_t, + workspace_index: miopenPoolingWorkspaceIndexMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get workspace index mode for pooling layer.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param workspace_index Workspace index mode (output)\n @return miopenStatus_t"] + pub fn miopenGetPoolingWorkSpaceIndexMode( + poolDesc: miopenPoolingDescriptor_t, + workspace_index: *mut miopenPoolingWorkspaceIndexMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a 2-D pooling layer descriptor details.\n\n Sets the window shape, padding, and stride for a previously created 2-D pooling descriptor.\n\n @param poolDesc Pointer to a pooling layer descriptor (output)\n @param mode Pooling mode enum (input)\n @param windowHeight Input window height dimension (input)\n @param windowWidth Input window width dimension (input)\n @param pad_h Number of elements to pad height (input)\n @param pad_w Number of elements to pad width (input)\n @param stride_h Vertical stride (input)\n @param stride_w Horizontal stride (input)\n @return miopenStatus_t"] + pub fn miopenSet2dPoolingDescriptor( + poolDesc: miopenPoolingDescriptor_t, + mode: miopenPoolingMode_t, + windowHeight: ::std::os::raw::c_int, + windowWidth: ::std::os::raw::c_int, + pad_h: ::std::os::raw::c_int, + pad_w: ::std::os::raw::c_int, + stride_h: ::std::os::raw::c_int, + stride_w: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a 2-D pooling layer descriptor details\n\n Gets the window shape, padding, and stride for a previously created 2-D pooling descriptor.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param mode Pooling mode enum (output)\n @param windowHeight Input window height dimension (output)\n @param windowWidth Input window width dimension (output)\n @param pad_h Number of elements to pad height (output)\n @param pad_w Number of elements to pad width (output)\n @param stride_h Vertical stride (output)\n @param stride_w Horizontal stride (output)\n @return miopenStatus_t"] + pub fn miopenGet2dPoolingDescriptor( + poolDesc: miopenPoolingDescriptor_t, + mode: *mut miopenPoolingMode_t, + windowHeight: *mut ::std::os::raw::c_int, + windowWidth: *mut ::std::os::raw::c_int, + pad_h: *mut ::std::os::raw::c_int, + pad_w: *mut ::std::os::raw::c_int, + stride_h: *mut ::std::os::raw::c_int, + stride_w: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the shape of the output tensor for 2-D pooling\n\n Retrieve the tensor dimensions for the forward 2-D pooling. This call is required for\n the forward if the output dimensions are different than the input tensor\n dimensions.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param tensorDesc Input tensor descriptor (input)\n @param n\t Mini-batch dim (output)\n @param c\t Number of channels (output)\n @param h Heights of input map (output)\n @param w Width of input map (output)\n @return miopenStatus_t"] + pub fn miopenGetPoolingForwardOutputDim( + poolDesc: miopenPoolingDescriptor_t, + tensorDesc: miopenTensorDescriptor_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set details of a N-D pooling layer descriptor\n\n Set the window shape, padding, and stride for a previously created N-D pooling descriptor.\n\n @param poolDesc Pointer to a pooling layer descriptor (input/output)\n @param mode Pooling mode enum (input)\n @param nbDims Dimension of the pooling (input)\n @param windowDimA Array of input window dimensions with length equal to or larger than\n dimsRequested (input)\n @param padA Array of number of elements to padding with length equal to or larger than\n dimsRequested (input)\n @param stridesA Array of stride parameter with length equal to or larger than dimsRequested\n (input)\n @return miopenStatus_t"] + pub fn miopenSetNdPoolingDescriptor( + poolDesc: miopenPoolingDescriptor_t, + mode: miopenPoolingMode_t, + nbDims: ::std::os::raw::c_int, + windowDimA: *mut ::std::os::raw::c_int, + padA: *mut ::std::os::raw::c_int, + stridesA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get details of a N-D pooling layer descriptor\n\n Get the window shape, padding, and stride for a previously created N-D pooling descriptor.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param nbDimsRequested Dimension of the expected pooling descriptor (input)\n @param mode Pooling mode enum (output)\n @param nbDims Actual dimension of the pooling descriptor (output)\n @param windowDimA Array of input window dimensions with length equal to or larger than\n dimsRequested (output)\n @param padA Array of number of elements to padding with length equal to or larger\n than dimsRequested (output)\n @param stridesA Array of stride parameter with length equal to or larger than\n dimsRequested (output)\n @return miopenStatus_t"] + pub fn miopenGetNdPoolingDescriptor( + poolDesc: miopenPoolingDescriptor_t, + nbDimsRequested: ::std::os::raw::c_int, + mode: *mut miopenPoolingMode_t, + nbDims: *mut ::std::os::raw::c_int, + windowDimA: *mut ::std::os::raw::c_int, + padA: *mut ::std::os::raw::c_int, + stridesA: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the shape of the output tensor for N-D pooling\n\n Retrieve the tensor dimensions for the forward N-D pooling. This call is required for\n the forward if the output dimensions are different than the input tensor\n dimensions.\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param tensorDesc Input tensor descriptor (input)\n @param dims Dimension of the pooling (input)\n @param tensorDimArr Array of tensor dimension (output)\n @return miopenStatus_t"] + pub fn miopenGetPoolingNdForwardOutputDim( + poolDesc: miopenPoolingDescriptor_t, + tensorDesc: miopenTensorDescriptor_t, + dims: ::std::os::raw::c_int, + tensorDimArr: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the amount of GPU memory required for pooling\n\n Retrieves the amount of workspace in bytes require for pooling. This call is required to\n determine the amount of GPU memory needed for the backwards pooling algorithms. For max-\n pooling, an assumption is that index data type is uint8_t, therefore the returned\n workspace size will be based on this assumption even if the user sets the index type with\n miopenSetPoolingIndexType().\n\n @param yDesc Descriptor for pooling layer (input)\n @param workSpaceSize Pointer to workSpaceSize (output)\n @return miopenStatus_t"] + pub fn miopenPoolingGetWorkSpaceSize( + yDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the amount of GPU memory required for pooling\n\n Retrieves the amount of workspace in bytes require for pooling. This call is required to\n determine the amount of GPU memory needed for the backwards pooling algorithms. For max-\n pooling, there is no assumption on index data type. As the user can set the index datatype\n size using miopenSetPoolingIndexType().\n\n @param poolDesc Pointer to a pooling layer descriptor (input)\n @param yDesc Descriptor for pooling layer (input)\n @param workSpaceSize Pointer to workSpaceSize (output)\n @return miopenStatus_t"] + pub fn miopenPoolingGetWorkSpaceSizeV2( + poolDesc: miopenPoolingDescriptor_t, + yDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a forward pooling layer\n\n Runs forward pooling. miopenGetPoolingForwardOutputDim() should be called before\n miopenPoolingForward().\n If the parameter do_backward == 0, then set workSpace = nullptr and workSpaceSize = 0. However,\n for back-propagation do_backwards must be set to 1 in miopenPoolingForward().\n\n @param handle MIOpen handle (input)\n @param poolDesc Descriptor for pooling layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param do_backward Boolean to toggle save data in workspace for backwards pass (input)\n @param workSpace Pointer user allocated memory (input)\n @param workSpaceSize Size in bytes of the memory needed (input)\n @return miopenStatus_t"] + pub fn miopenPoolingForward( + handle: miopenHandle_t, + poolDesc: miopenPoolingDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + do_backward: bool, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a backward pooling layer\n\n Runs backward pooling. miopenPoolingGetWorkSpaceSize() must be called before\n miopenPoolingBackward() to determine the amount of workSpace to be allocated.\n\n @param handle MIOpen handle (input)\n @param poolDesc Descriptor for pooling layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for output data tensor x (input)\n @param x Data tensor x (output)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for tensor dx (input)\n @param dx Weights delta tensor dx (output)\n @param workSpace Pointer to user allocated workspace (input)\n @return miopenStatus_t"] + pub fn miopenPoolingBackward( + handle: miopenHandle_t, + poolDesc: miopenPoolingDescriptor_t, + alpha: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the pooling descriptor object\n\n @param poolDesc Pooling tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyPoolingDescriptor(poolDesc: miopenPoolingDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @addtogroup LRN\n\n @{\n/\n/*! @brief Creates a local response normalization (LRN) layer descriptor\n\n @param lrnDesc Pointer to a local response normalization layer descriptor type\n @return miopenStatus_t"] + pub fn miopenCreateLRNDescriptor(lrnDesc: *mut miopenLRNDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a LRN layer descriptor details\n\n Sets all of the descriptor details for the LRN layer. The number of window elements lrnN is\n a diameter and always odd.\n\n @param lrnDesc Pointer to a LRN layer descriptor (output)\n @param mode LRN mode enum (input)\n @param lrnN Number of normalization window elements (input)\n @param lrnAlpha Scaling factor (input)\n @param lrnBeta Shift factor (input)\n @param lrnK K factor (input)\n @return miopenStatus_t"] + pub fn miopenSetLRNDescriptor( + lrnDesc: miopenLRNDescriptor_t, + mode: miopenLRNMode_t, + lrnN: ::std::os::raw::c_uint, + lrnAlpha: f64, + lrnBeta: f64, + lrnK: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a LRN layer descriptor details\n\n Retrieve the LRN descriptor details.\n\n @param lrnDesc Pointer to a LRN layer descriptor (input)\n @param mode LRN mode enum (output)\n @param lrnN Number of normalization window elements (output)\n @param lrnAlpha Scaling factor (output)\n @param lrnBeta Shift factor (output)\n @param lrnK K factor (output)\n @return miopenStatus_t"] + pub fn miopenGetLRNDescriptor( + lrnDesc: miopenLRNDescriptor_t, + mode: *mut miopenLRNMode_t, + lrnN: *mut ::std::os::raw::c_uint, + lrnAlpha: *mut f64, + lrnBeta: *mut f64, + lrnK: *mut f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Determine the workspace requirements.\n\n This function determines the GPU memory allocation required to execute the LRN layer based on the\n LRN descriptor.\n\n @param yDesc Pointer to a LRN layer descriptor (input)\n @param workSpaceSize Output variable for workspace size (output)\n @return miopenStatus_t"] + pub fn miopenLRNGetWorkSpaceSize( + yDesc: miopenTensorDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a LRN forward layer\n\n Runs the forward layer normalization in the forward direction. If do_backward == 0, then\n set workSpace = nullptr and workSpaceSize = 0. However, if the user wishes to execute backwards,\n then they must set do_backwards = 1 in miopenLRNForward().\n\n @param handle MIOpen handle (input)\n @param lrnDesc Descriptor for LRN layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param do_backward Boolean to toggle save data in workspace for backwards pass (input)\n @param workSpace Pointer user allocated memory (input)\n @return miopenStatus_t"] + pub fn miopenLRNForward( + handle: miopenHandle_t, + lrnDesc: miopenLRNDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + do_backward: bool, + workSpace: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a LRN backward layer\n\n @param handle MIOpen handle (input)\n @param lrnDesc Descriptor for LRN layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param yDesc Tensor descriptor for data input tensor y (input)\n @param y Data tensor y (input)\n @param dyDesc Tensor descriptor for data input tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for input data tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for output data tensor dx(input)\n @param dx Data delta tensor x (output)\n @param workSpace Pointer user allocated memory (input)\n @return miopenStatus_t"] + pub fn miopenLRNBackward( + handle: miopenHandle_t, + lrnDesc: miopenLRNDescriptor_t, + alpha: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + workSpace: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the LRN descriptor object\n\n @param lrnDesc LRN tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyLRNDescriptor(lrnDesc: miopenLRNDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Derive tensor for gamma and beta from input tensor descriptor\n\n This function takes the input tensor descriptor and outputs a derived tensor for the\n normalization scale (gamma) and shift (beta) tensors.\n\n For an input tensor NCHW and spatial mode, the output derived tensor is 1C11, while for\n per-activation the derived tensor is 1CHW.\n\n For an input tensor NCDHW and spatial mode, the output derived tensor is 1C111, while for\n per-activation the derived tensor is 1CDHW.\n\n @param derivedBnDesc Output derived tensor descriptor (output)\n @param xDesc Input tensor descriptor (input)\n @param bn_mode Batch Normalization mode (input)\n @return miopenStatus_t"] + pub fn miopenDeriveBNTensorDescriptor( + derivedBnDesc: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + bn_mode: miopenBatchNormMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward training layer for batch normalization\n\n Batch normalization pass for forward training pass.\n Takes in batch normalization mode bn_mode and input tensor x, output tensor y, bnBias and bnScale\n with their descriptor.\n\n If either resultSaveMean, or resultSaveInvVariance are null pointers then the values for the mean\n and inverse variance will not be used.\n\n Likewise, if either resultRunningMean, or resultRunningVariance are null pointers then the values\n for the running mean and variance will not be saved.\n Running averages and variances are scaled using an exponential averaging factor: \\f[\n \\mu_{old} = \\mu_{new}*factor + \\mu_{old}*(1-factor)\n \\f]\n where \\f[\n factor=1/(1+iteration)\n \\f]\n\n @param handle MIOpen handle (input)\n @param bn_mode Batch normalization mode (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param bnScaleBiasMeanVarDesc Tensor descriptor for BN scaling, shifting, saved variance and\n mean (input)\n @param bnScale Batch norm scaling, gamma, tensor (input)\n @param bnBias Batch norm bias, beta, tensor (input)\n @param expAvgFactor Exponential averaging factor (input)\n @param resultRunningMean Running average saved for inference (output)\n @param resultRunningVariance Running variance saved for inference (output)\n @param epsilon Value to stablize inverse variance calculation (input)\n @param resultSaveMean Saved mini-batch mean for backwards pass (output)\n @param resultSaveInvVariance Saved mini-batch inverse variance for backwards pass (output)\n @return miopenStatus_t"] + pub fn miopenBatchNormalizationForwardTraining( + handle: miopenHandle_t, + bn_mode: miopenBatchNormMode_t, + alpha: *mut ::std::os::raw::c_void, + beta: *mut ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + bnScaleBiasMeanVarDesc: miopenTensorDescriptor_t, + bnScale: *mut ::std::os::raw::c_void, + bnBias: *mut ::std::os::raw::c_void, + expAvgFactor: f64, + resultRunningMean: *mut ::std::os::raw::c_void, + resultRunningVariance: *mut ::std::os::raw::c_void, + epsilon: f64, + resultSaveMean: *mut ::std::os::raw::c_void, + resultSaveInvVariance: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward inference layer for batch normalization\n\n Batch normalization pass for forward inference pass.\n Takes in batch normalization mode bn_mode and input tensor x, output tensor y, bnBias and bnScale\n with their descriptor.\n\n If either estimatedMean, or estimatedVariance are null pointers then the values for the mean and\n variance will be calculated from input data and this calculated mean and variance will be used\n to update input values.\n If variance is zero and epsilon is also zero, this function outputs NAN values. Input espilon\n value should always be non zero positive value.\n\n @param handle MIOpen handle (input)\n @param bn_mode Batch normalization mode (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param bnScaleBiasMeanVarDesc Tensor descriptor for BN scaling, shifting, saved variance and\n mean (input)\n @param bnScale Batch norm scaling, gamma, tensor (input)\n @param bnBias Batch norm bias, beta, tensor (input)\n @param estimatedMean Running average saved during forward training (input)\n @param estimatedVariance Running variance saved during forward training (input)\n @param epsilon Value to stabilize inverse variance calculation (input)\n @return miopenStatus_t"] + pub fn miopenBatchNormalizationForwardInference( + handle: miopenHandle_t, + bn_mode: miopenBatchNormMode_t, + alpha: *mut ::std::os::raw::c_void, + beta: *mut ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + bnScaleBiasMeanVarDesc: miopenTensorDescriptor_t, + bnScale: *mut ::std::os::raw::c_void, + bnBias: *mut ::std::os::raw::c_void, + estimatedMean: *mut ::std::os::raw::c_void, + estimatedVariance: *mut ::std::os::raw::c_void, + epsilon: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute backwards propagation layer for batch normalization\n\n Batch normalization pass for backwards propagation training pass.\n The method for backwards propagation batch normalization.\n\n Takes in batch normalization mode bn_mode and input tensor data x, input activation tensor dy,\n output tensor dx, the learned tensors resultBNBiasDiff and resultBNScaleDiff with their\n descriptor.\n\n If BOTH savedMean, and savedVariance are not null pointers then the method will use the saved\n mean and variance calculated by the forward training phase.\n\n @param handle MIOpen handle (input)\n @param bn_mode Batch normalization mode (input)\n @param alphaDataDiff Floating point scaling factor, allocated on the host (input)\n @param betaDataDiff Floating point shift factor, allocated on the host (input)\n @param alphaParamDiff Floating point scaling factor, allocated on the host (input)\n @param betaParamDiff Floating point shift factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param dyDesc Tensor descriptor for output data tensor y (input)\n @param dy Data tensor y (input)\n @param dxDesc Tensor descriptor for output data tensor dx (input)\n @param dx Data delta tensor dx (output)\n @param bnScaleBiasDiffDesc Tensor descriptor for BN scaling, shifting, saved variance and\n mean (input)\n @param bnScale Batch norm scaling, gamma, tensor (input)\n @param resultBnScaleDiff Tensor for dscale (output)\n @param resultBnBiasDiff Tensor for dbias (output)\n @param epsilon Value to stabilize inverse variance calculation (input)\n @param savedMean Saved mini-batch mean for backwards pass (input)\n @param savedInvVariance Saved mini-bathc inverse variance for backwards pass (input)\n @return miopenStatus_t"] + pub fn miopenBatchNormalizationBackward( + handle: miopenHandle_t, + bn_mode: miopenBatchNormMode_t, + alphaDataDiff: *const ::std::os::raw::c_void, + betaDataDiff: *const ::std::os::raw::c_void, + alphaParamDiff: *const ::std::os::raw::c_void, + betaParamDiff: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + bnScaleBiasDiffDesc: miopenTensorDescriptor_t, + bnScale: *const ::std::os::raw::c_void, + resultBnScaleDiff: *mut ::std::os::raw::c_void, + resultBnBiasDiff: *mut ::std::os::raw::c_void, + epsilon: f64, + savedMean: *const ::std::os::raw::c_void, + savedInvVariance: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @addtogroup activation\n\n @{\n/\n/*! @brief Creates the Activation descriptor object\n\n @param activDesc Pointer to an activation tensor descriptor type\n @return miopenStatus_t"] + pub fn miopenCreateActivationDescriptor( + activDesc: *mut miopenActivationDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the activation layer descriptor details\n\n Sets all of the descriptor details for the activation layer\n\n @param activDesc Pointer to a activation layer descriptor (output)\n @param mode Activation mode enum (input)\n @param activAlpha Alpha value for some activation modes (input)\n @param activBeta Beta value for some activation modes (input)\n @param activGamma Gamma value for some activation modes (input)\n @return miopenStatus_t"] + pub fn miopenSetActivationDescriptor( + activDesc: miopenActivationDescriptor_t, + mode: miopenActivationMode_t, + activAlpha: f64, + activBeta: f64, + activGamma: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the activation layer descriptor details\n\n Retrieves all of the descriptor details for the activation layer.\n\n @param activDesc Pointer to a activation layer descriptor (input)\n @param mode Activation mode enum (output)\n @param activAlpha Alpha value for some activation modes (output)\n @param activBeta Beta value for some activation modes (output)\n @param activGamma Gamma value for some activation modes (output)\n @return miopenStatus_t"] + pub fn miopenGetActivationDescriptor( + activDesc: miopenActivationDescriptor_t, + mode: *mut miopenActivationMode_t, + activAlpha: *mut f64, + activBeta: *mut f64, + activGamma: *mut f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute an activation forward layer\n\n @param handle MIOpen handle (input)\n @param activDesc Descriptor for activation layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @return miopenStatus_t"] + pub fn miopenActivationForward( + handle: miopenHandle_t, + activDesc: miopenActivationDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a activation backwards layer\n\n @param handle MIOpen handle (input)\n @param activDesc Descriptor for activation layer (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param yDesc Tensor descriptor for input data tensor y (input)\n @param y Data tensor y (input)\n @param dyDesc Tensor descriptor for input data tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for data output tensor dx (input)\n @param dx Output data delta tensor dx (output)\n @return miopenStatus_t"] + pub fn miopenActivationBackward( + handle: miopenHandle_t, + activDesc: miopenActivationDescriptor_t, + alpha: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the activation descriptor object\n\n @param activDesc Activation tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyActivationDescriptor( + activDesc: miopenActivationDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @addtogroup softmax\n\n @{\n/\n/*! @brief Execute a softmax forward layer\n\n This API only implements the SOFTMAX_MODE_CHANNEL in SOFTMAX_ACCURATE path.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @return miopenStatus_t"] + pub fn miopenSoftmaxForward( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a softmax backwards layer\n\n This API only implements the SOFTMAX_MODE_CHANNEL in SOFTMAX_ACCURATE path.\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param yDesc Tensor descriptor for input data tensor y (input)\n @param y Data tensor y (input)\n @param dyDesc Tensor descriptor for input data tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for data output tensor dx (input)\n @param dx Output data delta tensor dx (output)\n @return miopenStatus_t"] + pub fn miopenSoftmaxBackward( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a softmax forward layer with expanded modes and algorithms\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param xDesc Tensor descriptor for data input tensor x (input)\n @param x Data tensor x (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param yDesc Tensor descriptor for output data tensor y (input)\n @param y Data tensor y (output)\n @param algorithm Softmax implementation algorithm (input)\n @param mode Softmax mode (input)\n @return miopenStatus_t"] + pub fn miopenSoftmaxForward_V2( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + algorithm: miopenSoftmaxAlgorithm_t, + mode: miopenSoftmaxMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute a softmax backwards layer with expanded modes and algorithms\n\n @param handle MIOpen handle (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param yDesc Tensor descriptor for input data tensor y (input)\n @param y Data tensor y (input)\n @param dyDesc Tensor descriptor for input data tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param dxDesc Tensor descriptor for data output tensor dx (input)\n @param dx Output data delta tensor dx (output)\n @param algorithm Softmax implementation algorithm (input)\n @param mode Softmax mode (input)\n @return miopenStatus_t"] + pub fn miopenSoftmaxBackward_V2( + handle: miopenHandle_t, + alpha: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + algorithm: miopenSoftmaxAlgorithm_t, + mode: miopenSoftmaxMode_t, + ) -> miopenStatus_t; +} +#[doc = " @ingroup FUSION\n @brief MIOpen fusion interface"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenFusionPlanDescriptor { + pub _address: u8, +} +pub type miopenFusionPlanDescriptor_t = *mut miopenFusionPlanDescriptor; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenOperatorArgs { + pub _address: u8, +} +pub type miopenOperatorArgs_t = *mut miopenOperatorArgs; +impl miopenFusionDirection_t { + #[doc = "< fuses layers vertically, current the only supported mode"] + pub const miopenVerticalFusion: miopenFusionDirection_t = miopenFusionDirection_t(0); +} +impl miopenFusionDirection_t { + #[doc = "< fuses layers horizontally, this is unimplemented"] + pub const miopenHorizontalFusion: miopenFusionDirection_t = miopenFusionDirection_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenFusionDirection_t\n @brief Kernel fusion direction in the network"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenFusionDirection_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Creates the kenrel fusion plan descriptor object\n\n @param fusePlanDesc Pointer to a fusion plan (output)\n @param fuseDirection Horizontal or Vertical fusion (input)\n @param inputDesc Descriptor to tensor for the input (input)\n @return miopenStatus_t"] + pub fn miopenCreateFusionPlan( + fusePlanDesc: *mut miopenFusionPlanDescriptor_t, + fuseDirection: miopenFusionDirection_t, + inputDesc: miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy the fusion plan descriptor object\n\n @param fusePlanDesc A fusion plan descriptor type\n @return miopenStatus_t"] + pub fn miopenDestroyFusionPlan(fusePlanDesc: miopenFusionPlanDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Compiles the fusion plan\n\n @param handle MIOpen handle (input)\n @param fusePlanDesc A fusion plan descriptor (input)\n @return miopenStatus_t"] + pub fn miopenCompileFusionPlan( + handle: miopenHandle_t, + fusePlanDesc: miopenFusionPlanDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Allows access to the operators in a fusion plan\n @details This api call does bounds checking on the supplied op_idx and would\n return miopenStatusError if the index is out of bounds\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param op_idx Index of the required operator in the fusion plan, in the order of insertion\n @param op returned pointer to the operator\n @return miopenStatus_t"] + pub fn miopenFusionPlanGetOp( + fusePlanDesc: miopenFusionPlanDescriptor_t, + op_idx: ::std::os::raw::c_int, + op: *mut miopenFusionOpDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the workspace size required for the fusion plan\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param workSpaceSize Pointer to memory to return size in bytes (output)\n @return miopenStatus_t"] + pub fn miopenFusionPlanGetWorkSpaceSize( + handle: miopenHandle_t, + fusePlanDesc: miopenFusionPlanDescriptor_t, + workSpaceSize: *mut usize, + algo: miopenConvFwdAlgorithm_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Returns the supported algorithms for the convolution operator in the Fusion Plan\n\n @details A Convolution operator in a fusion plan may be implemented by different algorithms\n representing different tradeoffs of memory and performance. The returned list of algorithms\n is sorted in decreasing order of priority. Therefore, if the user does not request an\n algorithm to be set using the miopenFusionPlanConvolutionSetAlgo call, the first algorithm\n in the list would be used to execute the convolution in the fusion plan. Moreover this call\n must be immediately preceded by the miopenCreateOpConvForward call for the op in question.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param requestAlgoCount Number of algorithms to return (input)\n @param returnedAlgoCount The actual number of returned algorithms; always be less than\n equal to requestAlgoCount (output)\n @param returnedAlgos Pointer to the list of supported algorithms\n @return miopenStatus_t"] + pub fn miopenFusionPlanConvolutionGetAlgo( + fusePlanDesc: miopenFusionPlanDescriptor_t, + requestAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + returnedAlgos: *mut miopenConvFwdAlgorithm_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Requests the fusion runtime to choose a particular algorithm for the added convolution\n operation\n\n @details Please see the description for miopenFusionPlanConvolutionGetAlgo\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param algo Requested algorithm for the convolution operator (input)\n @return miopenStatus_t"] + pub fn miopenFusionPlanConvolutionSetAlgo( + fusePlanDesc: miopenFusionPlanDescriptor_t, + algo: miopenConvFwdAlgorithm_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates forward convolution operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param convOp Pointer to an operator type (output)\n @param convDesc Convolution layer descriptor (input)\n @param wDesc Descriptor for the weights tensor (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpConvForward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + convOp: *mut miopenFusionOpDescriptor_t, + convDesc: miopenConvolutionDescriptor_t, + wDesc: miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a forward activation operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param activFwdOp Pointer to an operator type (output)\n @param mode Activation version (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpActivationForward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + activFwdOp: *mut miopenFusionOpDescriptor_t, + mode: miopenActivationMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a backward activation operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param activBwdOp Pointer to an operator type (output)\n @param mode Activation version (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpActivationBackward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + activBwdOp: *mut miopenFusionOpDescriptor_t, + mode: miopenActivationMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a forward bias operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param biasOp Pointer to an operator type (output)\n @param bDesc bias tensor descriptor (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpBiasForward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + biasOp: *mut miopenFusionOpDescriptor_t, + bDesc: miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a forward inference batch normalization operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param bnOp Pointer to an operator type (output)\n @param bn_mode Batch normalization layer mode (input)\n @param bnScaleBiasMeanVarDesc Gamma, beta, mean, variance tensor descriptor (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpBatchNormInference( + fusePlanDesc: miopenFusionPlanDescriptor_t, + bnOp: *mut miopenFusionOpDescriptor_t, + bn_mode: miopenBatchNormMode_t, + bnScaleBiasMeanVarDesc: miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a forward training batch normalization operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param bnFwdOp Pointer to an operator type (output)\n @param bn_mode Batch normalization layer mode (input)\n @param runningMeanVariance Toggles whether or not to save population statistics for inference;\n batch statistic are required (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpBatchNormForward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + bnFwdOp: *mut miopenFusionOpDescriptor_t, + bn_mode: miopenBatchNormMode_t, + runningMeanVariance: bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates a back propagation batch normalization operator.\n\n @param fusePlanDesc A fusion plan descriptor (input)\n @param bnBwdOp Pointer to an operator type (output)\n @param bn_mode Batch normalization layer mode (input)\n @return miopenStatus_t"] + pub fn miopenCreateOpBatchNormBackward( + fusePlanDesc: miopenFusionPlanDescriptor_t, + bnBwdOp: *mut miopenFusionOpDescriptor_t, + bn_mode: miopenBatchNormMode_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates an operator argument object\n\n @param args Pointer to an operator argument type (output)\n @return miopenStatus_t"] + pub fn miopenCreateOperatorArgs(args: *mut miopenOperatorArgs_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys an operator argument object\n\n @param args An operator argument type (output)\n @return miopenStatus_t"] + pub fn miopenDestroyOperatorArgs(args: miopenOperatorArgs_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for forward convolution op\n\n @param args An arguments object type (output)\n @param convOp Forward convolution operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param w Pointer to tensor memory (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsConvForward( + args: miopenOperatorArgs_t, + convOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + w: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for forward activation op\n\n @param args An arguments object type (output)\n @param activFwdOp Activation backwards operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param activAlpha Double precision activation parameter which depends on activation mode (input)\n @param activBeta Double precision activation parameter which depends on activation mode (input)\n @param activGamma Double precision activation parameter which depends on activation mode (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsActivForward( + args: miopenOperatorArgs_t, + activFwdOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + activAlpha: f64, + activBeta: f64, + activGamma: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for backward activation op\n\n @param args An arguments object type (output)\n @param activBwdOp Activation backwards operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param y Data tensor y, output of activations in the forward direction (input)\n @param reserved Data tensor reserved memory space; currently should be nullptr (input)\n @param activAlpha Double precision activation parameter which depends on activation mode (input)\n @param activBeta Double precision activation parameter which depends on activation mode (input)\n @param activGamma Double precision activation parameter which depends on activation mode (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsActivBackward( + args: miopenOperatorArgs_t, + activBwdOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + y: *const ::std::os::raw::c_void, + reserved: *const ::std::os::raw::c_void, + activAlpha: f64, + activBeta: f64, + activGamma: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for inference batch normalization op\n\n @param args An arguments object type (output)\n @param bnOp Batch normalization inference operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param bnScale Pointer to the gamma tensor memory (input)\n @param bnBias Pointer to the beta tensor memory (input)\n @param estimatedMean Pointer to population mean memory (input)\n @param estimatedVariance Pointer to population variance memory (input)\n @param epsilon Scalar value for numerical stability (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsBatchNormInference( + args: miopenOperatorArgs_t, + bnOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + estimatedMean: *const ::std::os::raw::c_void, + estimatedVariance: *const ::std::os::raw::c_void, + epsilon: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for forward batch normalization op\n\n @param args An arguments object type (output)\n @param bnOp Batch normalization forward operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param bnScale Pointer to the gamma tensor memory (input)\n @param bnBias Pointer to the beta tensor memory (input)\n @param savedMean Pointer to batch mean memory (input)\n @param savedInvVariance Pointer to batch inverse variance memory (input)\n @param runningMean Pointer to population mean memory (input)\n @param runningVariance Pointer to population variance memory (input)\n @param expAvgFactor Scalar value for control of population statistics (input)\n @param epsilon Scalar value for numerical stability (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsBatchNormForward( + args: miopenOperatorArgs_t, + bnOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + savedMean: *mut ::std::os::raw::c_void, + savedInvVariance: *mut ::std::os::raw::c_void, + runningMean: *mut ::std::os::raw::c_void, + runningVariance: *mut ::std::os::raw::c_void, + expAvgFactor: f64, + epsilon: f64, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for backward batch normalization op\n\n @param args An arguments object type (output)\n @param bnOp Batch normalization forward operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param x Pointer to the forward input tensor memory (input)\n @param bnScale Pointer to the gamma tensor memory (input)\n @param bnBias Pointer to the beta tensor memory (input)\n @param resultBnScaleDiff Pointer to the gamma gradient tensor memory (output)\n @param resultBnBiasDiff Pointer to the beta gradient tensor memory (output)\n @param savedMean Pointer to batch mean memory (input)\n @param savedInvVariance Pointer to batch inverse variance memory (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsBatchNormBackward( + args: miopenOperatorArgs_t, + bnOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + x: *const ::std::os::raw::c_void, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + resultBnScaleDiff: *mut ::std::os::raw::c_void, + resultBnBiasDiff: *mut ::std::os::raw::c_void, + savedMean: *const ::std::os::raw::c_void, + savedInvVariance: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the arguments for forward bias op\n\n @param args An arguments object type (output)\n @param biasOp Forward bias operator (input)\n @param alpha Floating point scaling factor, allocated on the host (input)\n @param beta Floating point shift factor, allocated on the host (input)\n @param bias Pointer to the forward bias input tensor memory (input)\n @return miopenStatus_t"] + pub fn miopenSetOpArgsBiasForward( + args: miopenOperatorArgs_t, + biasOp: miopenFusionOpDescriptor_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + bias: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Executes the fusion plan\n\n\n @param handle MIOpen handle (input)\n @param fusePlanDesc fused plan descriptor (input)\n @param inputDesc Descriptor of the input tensor (input)\n @param input Source data tensor (input)\n @param outputDesc Decriptor of the output tensor (input)\n @param output Destination data tensor (output)\n @param args An argument object of the fused kernel (input)\n @return miopenStatus_t"] + pub fn miopenExecuteFusionPlan( + handle: miopenHandle_t, + fusePlanDesc: miopenFusionPlanDescriptor_t, + inputDesc: miopenTensorDescriptor_t, + input: *const ::std::os::raw::c_void, + outputDesc: miopenTensorDescriptor_t, + output: *mut ::std::os::raw::c_void, + args: miopenOperatorArgs_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Prepares and executes the Convlution+Bias+Activation Fusion\n\n\n @param handle MIOpen handle (input)\n @return miopenStatus_t"] + pub fn miopenConvolutionBiasActivationForward( + handle: miopenHandle_t, + alpha1: *const ::std::os::raw::c_void, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: miopenConvolutionDescriptor_t, + algo: miopenConvFwdAlgorithm_t, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, + alpha2: *const ::std::os::raw::c_void, + zDesc: miopenTensorDescriptor_t, + z: *const ::std::os::raw::c_void, + biasDesc: miopenTensorDescriptor_t, + bias: *const ::std::os::raw::c_void, + activationDesc: miopenActivationDescriptor_t, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +impl miopenRNNMode_t { + #[doc = "< RNN with ReLU activation"] + pub const miopenRNNRELU: miopenRNNMode_t = miopenRNNMode_t(0); +} +impl miopenRNNMode_t { + #[doc = "< RNN with tanh activation"] + pub const miopenRNNTANH: miopenRNNMode_t = miopenRNNMode_t(1); +} +impl miopenRNNMode_t { + #[doc = "< LSTM"] + pub const miopenLSTM: miopenRNNMode_t = miopenRNNMode_t(2); +} +impl miopenRNNMode_t { + #[doc = "< GRU"] + pub const miopenGRU: miopenRNNMode_t = miopenRNNMode_t(3); +} +#[repr(transparent)] +#[doc = " @enum miopenRNNMode_t\n RNN mode selection for rnn layer preference"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNNMode_t(pub ::std::os::raw::c_uint); +impl miopenRNNInputMode_t { + #[doc = "< Matrix multiplication at the input of the first layer"] + pub const miopenRNNlinear: miopenRNNInputMode_t = miopenRNNInputMode_t(0); +} +impl miopenRNNInputMode_t { + #[doc = "< No operation is performed at the input of the first layer."] + pub const miopenRNNskip: miopenRNNInputMode_t = miopenRNNInputMode_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenRNNInputMode_t\n Recurrent Neural Network layer initial input mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNNInputMode_t(pub ::std::os::raw::c_uint); +impl miopenRNNAlgo_t { + #[doc = "< Use dedicated gate-operation kernel for LSTM and fundamental\nalgorithm for vanilla RNN & GRU"] + pub const miopenRNNdefault: miopenRNNAlgo_t = miopenRNNAlgo_t(0); +} +impl miopenRNNAlgo_t { + pub const miopenRNNfundamental: miopenRNNAlgo_t = miopenRNNAlgo_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenRNNAlgo_t\n Recurrent Neural Network algorithm mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNNAlgo_t(pub ::std::os::raw::c_uint); +impl miopenRNNDirectionMode_t { + #[doc = "< Forward in time only."] + pub const miopenRNNunidirection: miopenRNNDirectionMode_t = miopenRNNDirectionMode_t(0); +} +impl miopenRNNDirectionMode_t { + #[doc = "< Forward and backwards in time."] + pub const miopenRNNbidirection: miopenRNNDirectionMode_t = miopenRNNDirectionMode_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenRNNDirectionMode_t\n Recurrent Neural Network bi-directional behavior"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNNDirectionMode_t(pub ::std::os::raw::c_uint); +impl miopenRNNBiasMode_t { + #[doc = "< No Biases will be applied to GEMM operations"] + pub const miopenRNNNoBias: miopenRNNBiasMode_t = miopenRNNBiasMode_t(0); +} +impl miopenRNNBiasMode_t { + #[doc = "< Biases will be applied to GEMM operations"] + pub const miopenRNNwithBias: miopenRNNBiasMode_t = miopenRNNBiasMode_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenRNNBiasMode_t\n Recurrent Neural Network add on bias"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNNBiasMode_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Create a RNN layer Descriptor\n\n API for creating an uninitialized RNN layer descriptor.\n @param rnnDesc Pointer to a tensor descriptor type\n @return miopenStatus_t"] + pub fn miopenCreateRNNDescriptor(rnnDesc: *mut miopenRNNDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieves a RNN layer descriptor's details\n\n @param rnnDesc RNN layer descriptor (input)\n @param rnnMode RNN mode (output)\n @param algoMode RNN algorithm mode (output)\n @param inputMode RNN data input mode (output)\n @param dirMode Uni or bi direction mode (output)\n @param biasMode Bias used (output)\n @param hiddenSize Size of hidden state (output)\n @param layer Number of stacked layers (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNDescriptor( + rnnDesc: miopenRNNDescriptor_t, + rnnMode: *mut miopenRNNMode_t, + algoMode: *mut miopenRNNAlgo_t, + inputMode: *mut miopenRNNInputMode_t, + dirMode: *mut miopenRNNDirectionMode_t, + biasMode: *mut miopenRNNBiasMode_t, + hiddenSize: *mut ::std::os::raw::c_int, + layer: *mut ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieves a RNN layer descriptor's details version 2. This version enables retrieving\n information of the dropout descriptor of the rnn descriptor.\n\n @param rnnDesc RNN layer descriptor (input)\n @param hiddenSize Size of hidden state (output)\n @param layer Number of stacked layers (output)\n @param dropoutDesc Pre-configured dropout descriptor for dropout layer in between RNN layers\n (output)\n @param inputMode RNN data input mode (output)\n @param dirMode Uni or bi direction mode (output)\n @param rnnMode RNN mode (output)\n @param biasMode Bias used (output)\n @param algoMode RNN algorithm mode (output)\n @param dataType Data type of RNN (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNDescriptor_V2( + rnnDesc: miopenRNNDescriptor_t, + hiddenSize: *mut ::std::os::raw::c_int, + layer: *mut ::std::os::raw::c_int, + dropoutDesc: *mut miopenDropoutDescriptor_t, + inputMode: *mut miopenRNNInputMode_t, + dirMode: *mut miopenRNNDirectionMode_t, + rnnMode: *mut miopenRNNMode_t, + biasMode: *mut miopenRNNBiasMode_t, + algoMode: *mut miopenRNNAlgo_t, + dataType: *mut miopenDataType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the tensor descriptor object\n\n @param rnnDesc RNN tensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyRNNDescriptor(rnnDesc: miopenRNNDescriptor_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the details of the RNN descriptor\n\n Interface for setting the values of the RNN descriptor object. This function requires specific\n algorithm selection.\n @param rnnDesc RNN layer descriptor type (input)\n @param hsize Hidden layer size (input)\n @param nlayers Number of layers (input)\n @param inMode RNN first layer input mode (input)\n @param direction RNN direction (input)\n @param rnnMode RNN model type (input)\n @param biasMode RNN bias included (input)\n @param algo RNN algorithm selected (input)\n @param dataType Only fp32 currently supported for RNNs (input)\n @return miopenStatus_t"] + pub fn miopenSetRNNDescriptor( + rnnDesc: miopenRNNDescriptor_t, + hsize: ::std::os::raw::c_int, + nlayers: ::std::os::raw::c_int, + inMode: miopenRNNInputMode_t, + direction: miopenRNNDirectionMode_t, + rnnMode: miopenRNNMode_t, + biasMode: miopenRNNBiasMode_t, + algo: miopenRNNAlgo_t, + dataType: miopenDataType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the details of the RNN descriptor version 2. This version enables the use of dropout\n in rnn.\n\n Interface for setting the values of the RNN descriptor object. This function requires specific\n algorithm selection.\n @param rnnDesc RNN layer descriptor type (input/output)\n @param hsize Hidden layer size (input)\n @param nlayers Number of layers (input)\n @param dropoutDesc Pre-initialized dropout descriptor for dropout layer in between RNN layers\n (input)\n @param inMode RNN first layer input mode (input)\n @param direction RNN direction (input)\n @param rnnMode RNN model type (input)\n @param biasMode RNN bias included (input)\n @param algo RNN algorithm selected (input)\n @param dataType Only fp32 currently supported for RNNs (input)\n @return miopenStatus_t"] + pub fn miopenSetRNNDescriptor_V2( + rnnDesc: miopenRNNDescriptor_t, + hsize: ::std::os::raw::c_int, + nlayers: ::std::os::raw::c_int, + dropoutDesc: miopenDropoutDescriptor_t, + inMode: miopenRNNInputMode_t, + direction: miopenRNNDirectionMode_t, + rnnMode: miopenRNNMode_t, + biasMode: miopenRNNBiasMode_t, + algo: miopenRNNAlgo_t, + dataType: miopenDataType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of memory required to execute the RNN layer\n\n This function calculates the amount of memory required to run the RNN layer given an RNN\n descriptor and a tensor descriptor.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Number of iteration unrolls (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param numBytes Number of bytes required for RNN layer execution (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNWorkspaceSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + xDesc: *const miopenTensorDescriptor_t, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of memory required for RNN training\n\n This function calculates the amount of memory required to train the RNN layer given an\n RNN descriptor and a tensor descriptor.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Number of iteration unrolls (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param numBytes Number of bytes required for RNN layer execution (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNTrainingReserveSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + xDesc: *const miopenTensorDescriptor_t, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of parameter memory required for RNN training\n\n This function calculates the amount of parameter memory required to train the RNN layer given an\n RNN descriptor and a tensor descriptor.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param xDesc A tensor descriptor (input)\n @param numBytes Number of bytes required for RNN layer execution (output)\n @param dtype MIOpen data type enum (input)\n @return miopenStatus_t"] + pub fn miopenGetRNNParamsSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + xDesc: miopenTensorDescriptor_t, + numBytes: *mut usize, + dtype: miopenDataType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Obtain a weight tensor descriptor for RNNs\n\n This function populates a weight descriptor that describes the memory layout of the\n weight matrix.\n\n @param handle MIOpen handle (input)\n @param rnnDesc Fully populated RNN layer descriptor type (input)\n @param xDesc A previously populated tensor descriptor (input)\n @param wDesc A previously allocated tensor descriptor (output)\n @param dtype MIOpen data type enum, currently only fp32 is supported (input)\n @return miopenStatus_t"] + pub fn miopenGetRNNParamsDescriptor( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + xDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + dtype: miopenDataType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Obtain a the size in bytes of the RNN input tensor\n\n This function determines the size in bytes of the allocation needed for the input data\n tensor for an RNN layer. The number of bytes is derived from the array of\n tensor descriptors.\n\n @param handle MIOpen handle (input)\n @param rnnDesc Fully populated RNN layer descriptor (input)\n @param seqLen Number of iteration unrolls (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param numBytes Number of bytes required for input tensor (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNInputTensorSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + seqLen: ::std::os::raw::c_int, + xDesc: *mut miopenTensorDescriptor_t, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Obtain a the size in bytes of the RNN hidden tensor\n\n This function determines the size in bytes of the allocation needed for the\n hidden tensor over all layers\n\n @param handle MIOpen handle (input)\n @param rnnDesc Fully populated RNN layer descriptor type (input)\n @param seqLen Number of iteration unrolls (input)\n @param xDesc An array of previously populated tensor descriptors (input)\n @param numBytes Number of bytes required for input tensor (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNHiddenTensorSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + seqLen: ::std::os::raw::c_int, + xDesc: *mut miopenTensorDescriptor_t, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the number of bytes of a parameter matrix\n\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, paramID == 0 retrieves the\n weight matrix associated with the in input GEMM, while paramID == 1 retrieves\n the weight matrix associated with the hidden state GEMM.\n\n For miopenLSTM paramID 0 to 3 refer to the weight matrices associated\n with the input GEMM, 4-7 are associated with matrices associated with the\n hidden state GEMM.\n\n * paramID 0 and 4 are for the input gate.\n\n * paramID 1 and 5 are for the forget gate.\n\n * paramID 2 and 6 are for the output gate.\n\n * paramID 3 and 7 are for the new memory gate.\n\n For miopenGRU paramID 0 to 2 refer to the weight matrix offset associated\n with the input GEMM, while 3 through 5 are associated with the hidden state\n GEMM.\n\n * paramID 0 and 3 are for the update gate.\n\n * paramID 1 and 4 are for the reset gate.\n\n * paramID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param paramID ID of the internal parameter tensor (input)\n @param numBytes The number of bytes of the layer's parameter matrix (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerParamSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + paramID: ::std::os::raw::c_int, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets the number of bytes of a bias\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, biasID == 0 retrieves the\n weight matrix associated with the in input GEMM, while biasID == 1 retrieves\n the bias associated with the hidden state GEMM.\n\n For miopenLSTM biasID 0 to 3 refer to the biases associated\n with the input GEMM, 4-7 are associated with biases associated with the\n hidden state GEMM.\n\n * biasID 0 and 4 are for the input gate.\n\n * biasID 1 and 5 are for the forget gate.\n\n * biasID 2 and 6 are for the output gate.\n\n * biasID 3 and 7 are for the new memory gate.\n\n For miopenGRU biasID 0 to 2 refer to the biases associated with the input GEMM,\n while 3 through 5 are associated with the hidden state GEMM.\n\n * biasID 0 and 3 are for the update gate.\n\n * biasID 1 and 4 are for the reset gate.\n\n * biasID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param biasID ID of the internal parameter tensor (input)\n @param numBytes The number of bytes of the layer's bias (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerBiasSize( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + biasID: ::std::os::raw::c_int, + numBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a weight matrix for a specific layer in an RNN stack\n\n This function retrieves the weight matrix data for a specific layer and parameter ID\n and copies the data into previously allocated device memory.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, paramID == 0 retrieves the\n weight matrix associated with the in input GEMM, while paramID == 1 retrieves\n the weight matrix associated with the hidden state GEMM.\n\n For miopenLSTM paramID 0 to 3 refer to the weight matrices associated\n with the input GEMM, 4-7 are associated with matrices associated with the\n hidden state GEMM.\n\n * paramID 0 and 4 are for the input gate.\n\n * paramID 1 and 5 are for the forget gate.\n\n * paramID 2 and 6 are for the output gate.\n\n * paramID 3 and 7 are for the new memory gate.\n\n For miopenGRU paramID 0 to 2 refer to the weight matrix offset associated\n with the input GEMM, while 3 through 5 are associated with the hidden state\n GEMM.\n\n * paramID 0 and 3 are for the update gate.\n\n * paramID 1 and 4 are for the reset gate.\n\n * paramID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The output argument paramDesc is a previously created tensor descriptor that is populated\n to describe the memory layout of the parameter matrix. It is full packed and is used when\n calling to miopenSetRNNLayerParam()\n\n The argument layerParam should either be nullptr, or have device memory allocated\n to allow copying of the entire layer parameter matrix into it. If layerParam is\n nullptr then only the paramDesc is populated and returned. The size in bytes of the\n layer parameter matrix can be determined by using miopenGetRNNLayerParamSize().\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenGetRNNLayerParam() will return\n a error status miopenStatusBadParm for input paramID associated with the input GEMM.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param wDesc A tensor descriptor to the parameter tensor (input)\n @param w Pointer to memory containing parameter tensor (input)\n @param paramID ID of the internal parameter tensor (input)\n @param paramDesc Tensor descriptor for the fully packed output parameter tensor (output)\n @param layerParam Pointer to the memory location of the parameter tensor (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerParam( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + paramID: ::std::os::raw::c_int, + paramDesc: miopenTensorDescriptor_t, + layerParam: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a bias for a specific layer in an RNN stack\n\n This function retrieves the bias data for a specific layer and bias ID and copies\n the data into previously allocated device memory.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, biasID == 0 retrieves the\n bias associated with the in input GEMM, while biasID == 1 retrieves\n the bias associated with the hidden state GEMM.\n\n For miopenLSTM biasID 0 to 3 refer to the biases associated\n with the input GEMM, 4-7 are associated with biases associated with the\n hidden state GEMM.\n\n * biasID 0 and 4 are for the input gate.\n\n * biasID 1 and 5 are for the forget gate.\n\n * biasID 2 and 6 are for the output gate.\n\n * biasID 3 and 7 are for the new memory gate.\n\n For miopenGRU biasID 0 to 2 refer to the biases associated with the input GEMM,\n while 3 through 5 are associated with the hidden state GEMM.\n\n * biasID 0 and 3 are for the update gate.\n\n * biasID 1 and 4 are for the reset gate.\n\n * biasID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The output argument biasDesc is a previously created tensor descriptor that is populated\n to describe the memory layout of the bias. It is full packed and is used when\n calling to miopenSetRNNLayerBias()\n\n The argument layerBias should either be nullptr, or have device memory allocated\n to allow copying of the entire layer bias into it. If layerBias is\n nullptr then only the biasDesc is populated and returned. The size in bytes of the\n layer bias can be determined by using miopenGetRNNLayerBiasSize().\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenGetRNNLayerBias() will return\n a error status miopenStatusBadParm for input biasID associated with the input GEMM.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param wDesc A tensor descriptor to the parameter tensor (input)\n @param w Pointer to memory containing parameter tensor (input)\n @param biasID ID of the internal parameter tensor (input)\n @param biasDesc Descriptor of the parameter tensor (output)\n @param layerBias Pointer to the memory location of the bias tensor (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerBias( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + biasID: ::std::os::raw::c_int, + biasDesc: miopenTensorDescriptor_t, + layerBias: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets an index offset for a specific weight matrix for a layer in the\n RNN stack\n\n This function retrieves the index offset for a weight matrix in a layer.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, paramID == 0 retrieves the\n weight matrix offset associated with the in input GEMM, while paramID == 1\n retrieves the weight matrix offset associated with the hidden state GEMM.\n\n For miopenLSTM paramID 0 to 3 refer to the weight matrix offsets associated\n with the input GEMM, 4-7 are associated with matrix offset associated with the\n hidden state GEMM.\n\n * paramID 0 and 4 are for the input gate.\n\n * paramID 1 and 5 are for the forget gate.\n\n * paramID 2 and 6 are for the output gate.\n\n * paramID 3 and 7 are for the new memory gate.\n\n For miopenGRU paramID 0 to 2 refer to the weight matrix offset associated\n with the input GEMM, while 3 through 5 are associated with the hidden state\n GEMM.\n\n * paramID 0 and 3 are for the update gate.\n\n * paramID 1 and 4 are for the reset gate.\n\n * paramID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The output argument paramDesc is a previously created tensor descriptor that is populated\n to describe the memory layout of the parameter matrix. It is full packed and is used when\n calling to miopenSetRNNLayerParam().\n\n The argument layerParamOffset should either be nullptr, or an address to place the\n offset. If layerParamOffset is nullptr then only the paramDesc is populated and returned.\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenGetRNNLayerParamOffset() will return\n a error status miopenStatusBadParm for input paramID associated with the input GEMM.\n\n\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param paramID ID of the internal parameter tensor (input)\n @param paramDesc Tensor descriptor for the fully packed output parameter tensor (output)\n @param layerParamOffset Location for the parameter offset (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerParamOffset( + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + paramID: ::std::os::raw::c_int, + paramDesc: miopenTensorDescriptor_t, + layerParamOffset: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Gets a bias index offset for a specific layer in an RNN stack\n\n This function retrieves the bias index offset for a specific layer and bias ID.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, biasID == 0 retrieves the\n bias associated with the in input GEMM, while biasID == 1 retrieves\n the weight matrix associated with the hidden state GEMM.\n\n For miopenLSTM biasID 0 to 3 refer to the bias offset associated\n with the input GEMM, 4-7 are the bias offsets associated with the hidden state GEMM.\n\n * biasID 0 and 4 are for the input gate.\n\n * biasID 1 and 5 are for the forget gate.\n\n * biasID 2 and 6 are for the output gate.\n\n * biasID 3 and 7 are for the new memory gate.\n\n For miopenGRU biasID 0 to 2 refer to the biases associated with the input GEMM,\n while 3 through 5 are associated with the hidden state GEMM.\n\n * biasID 0 and 3 are for the update gate.\n\n * biasID 1 and 4 are for the reset gate.\n\n * biasID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The output argument biasDesc is a previously created tensor descriptor that is populated\n to describe the memory layout of the bias. It is full packed and is used when\n calling to miopenSetRNNLayerBias()\n\n The argument layerBiasOffset should either be nullptr, or point to an output address.\n If layerBias is nullptr then only the biasDesc is populated and returned.\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenGetRNNLayerBiasOffset() will return\n a error status miopenStatusBadParm for input biasID associated with the input GEMM.\n\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param biasID ID of the internal parameter tensor (input)\n @param biasDesc Descriptor of the parameter tensor (output)\n @param layerBiasOffset Pointer to the memory location of the bias tensor (output)\n @return miopenStatus_t"] + pub fn miopenGetRNNLayerBiasOffset( + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + biasID: ::std::os::raw::c_int, + biasDesc: miopenTensorDescriptor_t, + layerBiasOffset: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a weight matrix for a specific layer in an RNN stack\n\n This function sets the weight matrix data for a specific layer and parameter ID.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, paramID == 0 sets the\n weight matrix associated with the in input GEMM, while paramID == 1 sets\n the weight matrix associated with the hidden state GEMM.\n\n\n For miopenLSTM paramID 0 to 3 refer to the weight matrices associated\n with the input GEMM, 4-7 are associated with matrices associated with the\n hidden state GEMM.\n\n * paramID 0 and 4 are for the input gate.\n\n * paramID 1 and 5 are for the forget gate.\n\n * paramID 2 and 6 are for the output gate.\n\n * paramID 3 and 7 are for the new memory gate.\n\n For miopenGRU paramID 0 to 2 refer to the weight matrix offset associated\n with the input GEMM, while 3 through 5 are associated with the hidden state\n GEMM.\n\n * paramID 0 and 3 are for the update gate.\n\n * paramID 1 and 4 are for the reset gate.\n\n * paramID 2 and 5 are for the new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The input argument paramDesc is a previously populated tensor descriptor typically\n by first calling miopenGetRNNLayerParam().\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenSetRNNLayerParam() will return\n a error status miopenStatusBadParm for input paramID associated with the input GEMM.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param wDesc A tensor descriptor to the parameter tensor (input)\n @param w Pointer to memory containing parameter tensor (input)\n @param paramID ID of the internal parameter tensor (input)\n @param paramDesc Descriptor of the parameter tensor (input)\n @param layerParam Pointer to the memory location of the parameter tensor (input)\n @return miopenStatus_t"] + pub fn miopenSetRNNLayerParam( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + w: *mut ::std::os::raw::c_void, + paramID: ::std::os::raw::c_int, + paramDesc: miopenTensorDescriptor_t, + layerParam: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a bias for a specific layer in an RNN stack\n\n This function sets the bias data for a specific layer and bias ID.\n\n For RNN vanilla miopenRNNRELU and miopenRNNTANH, biasID == 0 retrieves the\n weight matrix associated with the in input GEMM, while biasID == 1 retrieves\n the bias associated with the hidden state GEMM.\n\n For miopenLSTM biasID 0 to 3 refer to the biases associated\n with the input GEMM, 4-7 are associated with the biases associated with the\n hidden state GEMM.\n\n * biasID 0 and 4 are for the input gate.\n\n * biasID 1 and 5 are for the forget gate.\n\n * biasID 2 and 6 are for the output gate.\n\n * biasID 3 and 7 are for the new memory gate.\n\n For miopenGRU biasID 0 to 2 refer to the biases associated with the input GEMM,\n while 3 through 5 are associated with the hidden state GEMM.\n\n * biasID 0 and 3 are for the update gate.\n\n * biasID 1 and 4 are for the reset gate.\n\n * biasID 2 and 5 are for the new new memory gate.\n\n For bi-directional RNNs the backwards in time direction is numbered as the layer\n directly after the forward in time direction.\n\n The input argument biasDesc is a previously populated tensor descriptor typically\n by first calling miopenGetRNNLayeBias().\n\n Note: When inputSkip mode is selected there is no input layer matrix operation,\n and therefore no associated memory. In this case miopenSetRNNLayerBias will return\n a error status miopenStatusBadParm for input biasID associated with the input GEMM.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param layer The layer number in the RNN stack (input)\n @param xDesc A tensor descriptor to input (input)\n @param wDesc A tensor descriptor to the bias tensor (input)\n @param w Pointer to memory containing bias tensor (input)\n @param biasID ID of the internal bias tensor (input)\n @param biasDesc Descriptor of the bias tensor (output)\n @param layerBias Pointer to the memory location of the bias tensor (output)\n @return miopenStatus_t"] + pub fn miopenSetRNNLayerBias( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + layer: ::std::os::raw::c_int, + xDesc: miopenTensorDescriptor_t, + wDesc: miopenTensorDescriptor_t, + w: *mut ::std::os::raw::c_void, + biasID: ::std::os::raw::c_int, + biasDesc: miopenTensorDescriptor_t, + layerBias: *const ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward training for recurrent layer\n\n Interface for executing the forward training pass on a RNN.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Temporal iterations to unroll (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param x Pointer to input tensor (input)\n @param hxDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hx Pointer to the hidden layer input tensor. If hx is NULL,\n then the initial hidden state will be zero initialized. (input)\n @param cxDesc A cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param cx Pointer to the cell layer input tensor. If cx is NULL,\n then the initial cell state will be zero initialized. (input)\n @param wDesc A weights tensor descriptor (input)\n @param w Pointer to input weights tensor (input)\n @param yDesc An array of fully packed tensor descriptors associated\n with the output from each time step. The first dimension of the tensor descriptors\n must equal the first dimension of the first descriptor (batch size) in the xDesc\n tensor array. The second dimension of the element of the descriptor array\n depends on the direction mode selected. If the direction mode is unidirectional,\n the second dimension is the hiddenSize. If direction mode is bidirectional\n the second dimension is twice the hiddenSize. (input)\n @param y Pointer to output tensor (output)\n @param hyDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hy Pointer to the hidden layer output tensor. If hy is NULL,\n then the final hidden state will not be saved. (output)\n @param cyDesc A cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param cy Pointer to the cell layer output tensor. If hy is NULL,\n then the final cell state will not be saved. (output)\n @param workSpace Pointer to memory allocated for forward training (input)\n @param workSpaceNumBytes Number of allocated bytes in memory for the workspace (input)\n @param reserveSpace Pointer to memory allocated for random states (input / output)\n @param reserveSpaceNumBytes Number of allocated bytes in memory for use in the forward (input)\n @return miopenStatus_t"] + pub fn miopenRNNForwardTraining( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + xDesc: *const miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: miopenTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: miopenTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: miopenTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: miopenTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceNumBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceNumBytes: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute backward data for recurrent layer\n\n Interface for executing the backward data pass on a RNN.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Temporal iterations to unroll (input)\n @param yDesc An array of tensor descriptors (input)\n @param y Pointer to input tensor (input)\n @param dyDesc An array of fully packed tensor descriptors associated\n with the output from each time step. The first dimension of the tensor descriptors\n must equal the first dimension of the first descriptor (batch size) in the xDesc\n tensor array. The second dimension of the element of the descriptor array\n depends on the direction mode selected. If the direction mode is unidirectional,\n the second dimension is the hiddenSize. If direction mode is bidirectional\n the second dimension is twice the hiddenSize. (input)\n @param dy Pointer to the hidden layer input tensor (input)\n @param dhyDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param dhy Pointer to the cell layer input tensor (input)\n @param dcyDesc A cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param dcy Pointer to the cell layer input tensor. If dcy is NULL,\n then the initial delta cell state will be zero initialized. (input)\n @param wDesc A weights tensor descriptor (input)\n @param w Pointer to input weights tensor (input)\n @param hxDesc An input hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hx Pointer to the hidden layer input tensor. If hx is NULL,\n then the initial hidden state will be zero initialized. (input)\n @param cxDesc A input cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param cx Pointer to the hidden layer input tensor. If cx is NULL,\n then the initial cell state will be zero initialized. (input)\n @param dxDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param dx Pointer to the cell layer output tensor (output)\n @param dhxDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param dhx Pointer to the delta hidden layer output tensor. If dhx is NULL\n the hidden gradient will not ouput. (output)\n @param dcxDesc A tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param dcx Pointer to the cell layer output tensor. If dcx is NULL\n the cell gradient will not ouput. (output)\n @param workSpace Pointer to memory allocated for forward training (input)\n @param workSpaceNumBytes Number of allocated bytes in memory for the workspace (input)\n @param reserveSpace Pointer to memory allocated for random states (input / output)\n @param reserveSpaceNumBytes Number of allocated bytes in memory for use in the forward (input)\n @return miopenStatus_t"] + pub fn miopenRNNBackwardData( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + yDesc: *const miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: *const miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dhyDesc: miopenTensorDescriptor_t, + dhy: *const ::std::os::raw::c_void, + dcyDesc: miopenTensorDescriptor_t, + dcy: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + hxDesc: miopenTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: miopenTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + dxDesc: *const miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dhxDesc: miopenTensorDescriptor_t, + dhx: *mut ::std::os::raw::c_void, + dcxDesc: miopenTensorDescriptor_t, + dcx: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceNumBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceNumBytes: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute backward weights for recurrent layer\n\n Interface for executing the backward weights pass on a RNN.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Temporal iterations to unroll (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param x Pointer to input tensor (input)\n @param hxDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hx Pointer to the hidden layer input tensor. If hx is NULL,\n then the initial hidden state will be zero initialized. (input)\n @param yDesc An array of fully packed tensor descriptors associated\n with the output from each time step. The first dimension of the tensor descriptors\n must equal the first dimension of the first descriptor (batch size) in the xDesc\n tensor array. The second dimension of the element of the descriptor array\n depends on the direction mode selected. If the direction mode is unidirectional,\n the second dimension is the hiddenSize. If direction mode is bidirectional\n the second dimension is twice the hiddenSize. (input)\n @param y Pointer to the output tensor (input)\n @param dwDesc A weights tensor descriptor (input)\n @param dw Pointer to input weights tensor (input / output)\n @param workSpace Pointer to memory allocated for forward training (input)\n @param workSpaceNumBytes Number of allocated bytes in memory for the workspace (input)\n @param reserveSpace Pointer to memory allocated for random states (input)\n @param reserveSpaceNumBytes Number of allocated bytes in memory for use in the forward (input)\n @return miopenStatus_t"] + pub fn miopenRNNBackwardWeights( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + xDesc: *const miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: miopenTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + yDesc: *const miopenTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dwDesc: miopenTensorDescriptor_t, + dw: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceNumBytes: usize, + reserveSpace: *const ::std::os::raw::c_void, + reserveSpaceNumBytes: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward inference for RNN layer\n\n Interface for executing the forward inference pass on a RNN.\n\n @param handle MIOpen handle (input)\n @param rnnDesc RNN layer descriptor type (input)\n @param sequenceLen Temporal iterations to unroll (input)\n @param xDesc An array of tensor descriptors. These are the\n input descriptors to each time step. The first dimension of each descriptor is the\n batch size and may decrease from element n to element n+1 and not increase in size.\n The second dimension is the same for all descriptors in the array and is the input\n vector length. (input)\n @param x Pointer to input tensor (input)\n @param hxDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hx Pointer to the hidden layer input tensor. If hx is NULL,\n then the initial hidden state will be zero initialized. (input)\n @param cxDesc A cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param cx Pointer to the cell layer input tensor. If cx is NULL,\n then the initial cell state will be zero initialized. (input)\n @param wDesc A weights tensor descriptor (input)\n @param w Pointer to input weights tensor (input)\n @param yDesc An array of fully packed tensor descriptors associated\n with the output from each time step. The first dimension of the tensor descriptors\n must equal the first dimension of the first descriptor (batch size) in the xDesc\n tensor array. The second dimension of the element of the descriptor array\n depends on the direction mode selected. If the direction mode is unidirectional,\n the second dimension is the hiddenSize. If direction mode is bidirectional\n the second dimension is twice the hiddenSize. (input)\n @param y Pointer to output tensor (output)\n @param hyDesc A hidden tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param hy Pointer to the hidden layer output tensor. If hy is NULL,\n then the final hidden state will not be saved. (output)\n @param cyDesc A output cell tensor descriptor that has as its first dimension\n of the number of layers if the direction mode is unidirectional and twice the\n number of layers if the direction mode is bidirectional. The second dimension of\n the descriptor must equal the largest first dimension of the xDesc tensor descriptor\n array. The third dimension equals the hiddenSize. (input)\n @param cy Pointer to the cell layer output tensor. If cy is NULL,\n then the final cell state will not be saved. (output)\n @param workSpace Pointer to memory allocated for forward training (input)\n @param workSpaceNumBytes Number of allocated bytes in memory for the workspace (input)\n @return miopenStatus_t"] + pub fn miopenRNNForwardInference( + handle: miopenHandle_t, + rnnDesc: miopenRNNDescriptor_t, + sequenceLen: ::std::os::raw::c_int, + xDesc: *const miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: miopenTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: miopenTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: miopenTensorDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: miopenTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: miopenTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceNumBytes: usize, + ) -> miopenStatus_t; +} +impl miopenCTCLossAlgo_t { + #[doc = "< Results are guaranteed to be reproducible"] + pub const MIOPEN_CTC_LOSS_ALGO_DETERMINISTIC: miopenCTCLossAlgo_t = miopenCTCLossAlgo_t(0); +} +#[repr(transparent)] +#[doc = " @enum miopenCTCLossAlgo_t\n Algorithms available to execute the CTC loss operation"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenCTCLossAlgo_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Create a CTC loss function Descriptor\n\n API for creating an uninitialized CTC loss function descriptor.\n @param ctcLossDesc Pointer to the CTC loss function descriptor type (output)\n @return miopenStatus_t"] + pub fn miopenCreateCTCLossDescriptor( + ctcLossDesc: *mut miopenCTCLossDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieves a CTC loss function descriptor's details\n\n @param ctcLossDesc CTC loss function descriptor (input)\n @param dataType Data type used in this CTC loss operation, only fp32 currently\n supported (output)\n @param blank_label_id User defined index for blank label (output)\n @param apply_softmax_layer Boolean to toggle input layer property (output)\n @return miopenStatus_t"] + pub fn miopenGetCTCLossDescriptor( + ctcLossDesc: miopenCTCLossDescriptor_t, + dataType: *mut miopenDataType_t, + blank_label_id: *mut ::std::os::raw::c_int, + apply_softmax_layer: *mut bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys a CTC loss function descriptor object\n\n @param ctcLossDesc CTC loss function descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyCTCLossDescriptor(ctcLossDesc: miopenCTCLossDescriptor_t) + -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the details of a CTC loss function descriptor\n\n @param ctcLossDesc CTC loss function descriptor type (input)\n @param dataType Data type used in this CTC loss operation, only fp32 currently\n supported (input)\n @param blank_label_id User defined index for blank label, default 0 (input)\n @param apply_softmax_layer Boolean to toggle input layer property (input)\n @return miopenStatus_t"] + pub fn miopenSetCTCLossDescriptor( + ctcLossDesc: miopenCTCLossDescriptor_t, + dataType: miopenDataType_t, + blank_label_id: ::std::os::raw::c_int, + apply_softmax_layer: bool, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of memory required to execute miopenCTCLoss\n\n This function calculates the amount of memory required to run the CTC loss function given a CTC\n loss function descriptor with the specified algorithm.\n @param handle MIOpen handle (input)\n @param probsDesc Tensor descriptor for probabilities (input)\n @param gradientsDesc Tensor descriptor for gradients (input)\n @param labels Pointer to the flattened labels list (input)\n @param labelLengths Pointer to the lengths list for \"labels\" (input)\n @param inputLengths Pointer to the list of the time steps in each batch (input)\n @param algo CTC loss algorithm selected (input)\n @param ctcLossDesc CTC loss function descriptor type (input)\n @param workSpaceSize Number of bytes of workspace required for CTC loss operation with selected\n algorithm (output)\n @return miopenStatus_t"] + pub fn miopenGetCTCLossWorkspaceSize( + handle: miopenHandle_t, + probsDesc: miopenTensorDescriptor_t, + gradientsDesc: miopenTensorDescriptor_t, + labels: *const ::std::os::raw::c_int, + labelLengths: *const ::std::os::raw::c_int, + inputLengths: *const ::std::os::raw::c_int, + algo: miopenCTCLossAlgo_t, + ctcLossDesc: miopenCTCLossDescriptor_t, + workSpaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward inference for CTCLoss layer\n\n Interface for executing the forward inference pass on a CTCLoss.\n @param handle MIOpen handle (input)\n @param probsDesc Tensor descriptor for probabilities (input)\n @param probs Pointer to the probabilities tensor (input)\n @param labels Pointer to the flattened labels list (input)\n @param labelLengths Pointer to the lengths list for \"labels\" (input)\n @param inputLengths Pointer to the list of the time steps in each batch (input)\n @param losses Pointer to the computed losses of CTC (Output)\n @param gradientsDesc Tensor descriptor for gradients (input)\n @param gradients Pointer to the computed gradients of CTC (Output)\n @param algo CTC loss algorithm selected (input)\n @param ctcLossDesc CTC loss function descriptor type (input)\n @param workSpace Pointer to memory allocated for execute CTC loss operation (input)\n @param workSpaceSize Number of bytes of workspace required for CTC loss operation with selected\n algorithm (input)\n @return miopenStatus_t"] + pub fn miopenCTCLoss( + handle: miopenHandle_t, + probsDesc: miopenTensorDescriptor_t, + probs: *const ::std::os::raw::c_void, + labels: *const ::std::os::raw::c_int, + labelLengths: *const ::std::os::raw::c_int, + inputLengths: *const ::std::os::raw::c_int, + losses: *mut ::std::os::raw::c_void, + gradientsDesc: miopenTensorDescriptor_t, + gradients: *mut ::std::os::raw::c_void, + algo: miopenCTCLossAlgo_t, + ctcLossDesc: miopenCTCLossDescriptor_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + ) -> miopenStatus_t; +} +impl miopenRNGType_t { + #[doc = "< XORWOW pseudorandom generator"] + pub const MIOPEN_RNG_PSEUDO_XORWOW: miopenRNGType_t = miopenRNGType_t(0); +} +#[repr(transparent)] +#[doc = " @enum miopenRNGType_t\n random number generator type"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenRNGType_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Creates the dropout descriptor object\n\n @param dropoutDesc Pointer to a dropout descriptor type\n @return miopenStatus_t"] + pub fn miopenCreateDropoutDescriptor( + dropoutDesc: *mut miopenDropoutDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys the dropout descriptor object\n\n @param dropoutDesc Dropout descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyDropoutDescriptor(dropoutDesc: miopenDropoutDescriptor_t) + -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of memory required to run dropout\n\n This function calculates the amount of memory required to run dropout.\n @param xDesc Tensor descriptor for data tensor x (input)\n @param reserveSpaceSizeInBytes Number of bytes of reservespace required for executing dropout\n (Output)\n @return miopenStatus_t"] + pub fn miopenDropoutGetReserveSpaceSize( + xDesc: miopenTensorDescriptor_t, + reserveSpaceSizeInBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query the amount of memory required to store the states of the random number generators\n\n This function calculates the amount of memory required to store the states of the random number\n generators used by miopenDropoutForward.\n @param handle MIOpen handle (input)\n @param stateSizeInBytes Number of bytes required to store random generator states (Output)\n @return miopenStatus_t"] + pub fn miopenDropoutGetStatesSize( + handle: miopenHandle_t, + stateSizeInBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the details of the dropout descriptor\n\n Interface for querying the dropout descriptor\n @param dropoutDesc Dropout layer descriptor (input)\n @param handle MIOpen handle (input)\n @param dropout The probability by which the input is set to 0 in the dropout layer (Output)\n @param states Pointer to memory that holds random number generator states (Output)\n @param seed Seed used to initialize random number generator states (Output)\n @param use_mask Boolean flag indicating whether to use a saved mask (an existing or\n user-defined dropout layout) in reserveSpace (Output)\n @param state_evo Boolean flag indicating whether to adopt state evolution strategy to update\n the PRNG states by the end of each implementation (Output placeholder, currently not enabled)\n @param rng_mode Random number generator used to generate parallel random number sequences\n (Output)\n @return miopenStatus_t"] + pub fn miopenGetDropoutDescriptor( + dropoutDesc: miopenDropoutDescriptor_t, + handle: miopenHandle_t, + dropout: *mut f32, + states: *mut *mut ::std::os::raw::c_void, + seed: *mut ::std::os::raw::c_ulonglong, + use_mask: *mut bool, + state_evo: *mut bool, + rng_mode: *mut miopenRNGType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Restore the dropout descriptor to a saved state\n\n This function restores the state of dropout descriptor using the address of a state buffer with\n previously saved PRNG state pattern, without launching the expensive PRNG initialization process.\n\n Interface for restoring the dropout descriptor\n @param dropoutDesc Dropout layer descriptor (input/Output)\n @param handle MIOpen handle (input)\n @param dropout The probability by which the input is set to 0 in the dropout layer\n (input)\n @param states Pointer to memory that holds random number generator states (input)\n @param stateSizeInBytes Number of bytes holding random generator states (input)\n @param seed Seed used to initialize random number generator states (input)\n @param use_mask Boolean flag indicating whether to use a saved mask (an existing or\n user-defined dropout layout) in reserveSpace (input)\n @param state_evo Boolean flag indicating whether to adopt state evolution strategy to\n update the PRNG states by the end of each implementation (input placeholder, currently not\n enabled)\n @param rng_mode Random number generator used to generate parallel random number\n sequences (input)\n @return miopenStatus_t"] + pub fn miopenRestoreDropoutDescriptor( + dropoutDesc: miopenDropoutDescriptor_t, + handle: miopenHandle_t, + dropout: f32, + states: *mut ::std::os::raw::c_void, + stateSizeInBytes: usize, + seed: ::std::os::raw::c_ulonglong, + use_mask: bool, + state_evo: bool, + rng_mode: miopenRNGType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Initialize the dropout descriptor\n\n Interface for setting up the dropout descriptor\n @param dropoutDesc Dropout layer descriptor (input/Output)\n @param handle MIOpen handle (input)\n @param dropout The probability by which the input is set to 0 in the dropout layer\n (input)\n @param states Pointer to memory that holds random number generator states (input)\n @param stateSizeInBytes Number of bytes provided for random generator states (input)\n @param seed Seed used to initialize random number generator states (input)\n @param use_mask Boolean flag indicating whether to use a saved mask (an existing or\n user-defined dropout layout) in reserveSpace (input)\n @param state_evo Boolean flag indicating whether to adopt state evolution strategy to\n update the PRNG states by the end of each implementation (input placeholder, currently not\n enabled)\n @param rng_mode Random number generator used to generate parallel random number\n sequences (input)\n @return miopenStatus_t"] + pub fn miopenSetDropoutDescriptor( + dropoutDesc: miopenDropoutDescriptor_t, + handle: miopenHandle_t, + dropout: f32, + states: *mut ::std::os::raw::c_void, + stateSizeInBytes: usize, + seed: ::std::os::raw::c_ulonglong, + use_mask: bool, + state_evo: bool, + rng_mode: miopenRNGType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute forward dropout operation\n\n Interface for executing the forward pass on a Dropout.\n @param handle MIOpen handle (input)\n @param dropoutDesc Dropout layer descriptor (input)\n @param noise_shape Tensor descriptor for noise shape (input placeholder, currently\n not enabled)\n @param xDesc Tensor descriptor for data tensor x (input)\n @param x Data tensor x (input)\n @param yDesc Tensor descriptor for data tensor y (input)\n @param y Data tensor y (Output)\n @param reserveSpace Pointer to memory allocated for executing forward dropout,\n expecting reserveSpace unchanged before next call of miopenDropoutBackward (Output)\n @param reserveSpaceSizeInBytes Number of bytes of reservespace required for executing forward\n dropout (input)\n @return miopenStatus_t"] + pub fn miopenDropoutForward( + handle: miopenHandle_t, + dropoutDesc: miopenDropoutDescriptor_t, + noise_shape: miopenTensorDescriptor_t, + xDesc: miopenTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: miopenTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Execute backward dropout operation\n\n Interface for executing the backward pass on a Dropout.\n @param handle MIOpen handle (input)\n @param dropoutDesc Dropout layer descriptor (input)\n @param noise_shape Tensor descriptor for noise shape (input placeholder, currently\n not enabled)\n @param dyDesc Tensor descriptor for data delta tensor dy (input)\n @param dy Data delta tensor dy (input)\n @param dxDesc Tensor descriptor for data delta tensor dx (input)\n @param dx Data delta tensor dx (Output)\n @param reserveSpace Pointer to memory allocated for executing backward dropout,\n expecting reserveSpace unchanged after previous call of miopenDropoutForward (input)\n @param reserveSpaceSizeInBytes Number of bytes of reservespace required for executing backward\n dropout (input)\n @return miopenStatus_t"] + pub fn miopenDropoutBackward( + handle: miopenHandle_t, + dropoutDesc: miopenDropoutDescriptor_t, + noise_shape: miopenTensorDescriptor_t, + dyDesc: miopenTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dxDesc: miopenTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Creates the ReduceTensor descriptor object\n\n @param reduceTensorDesc Pointer to a ReduceTensor descriptor type\n @return miopenStatus_t"] + pub fn miopenCreateReduceTensorDescriptor( + reduceTensorDesc: *mut miopenReduceTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroy the ReduceTensor descriptor object\n\n @param reduceTensorDesc ReduceTensor descriptor type (input)\n @return miopenStatus_t"] + pub fn miopenDestroyReduceTensorDescriptor( + reduceTensorDesc: miopenReduceTensorDescriptor_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Initialize a ReduceTensor descriptor object\n\n @param reduceTensorDesc Pointer to the ReduceTensor descriptor object (output)\n @param reduceTensorOp Enumerant specifying the operation used by ReduceTensor (input)\n @param reduceTensorCompType Enumerant specifying the data type used with ReduceTensor\n operation (input)\n @param reduceTensorNanOpt Enumerant specifying the Nan number propagation mode (input)\n @param reduceTensorIndices Enumerant specifying the indices modes used by ReduceTensor\n (input)\n @param reduceTensorIndicesType Enumerant specifying the data type of the indices (input)\n @return miopenStatus_t"] + pub fn miopenSetReduceTensorDescriptor( + reduceTensorDesc: miopenReduceTensorDescriptor_t, + reduceTensorOp: miopenReduceTensorOp_t, + reduceTensorCompType: miopenDataType_t, + reduceTensorNanOpt: miopenNanPropagation_t, + reduceTensorIndices: miopenReduceTensorIndices_t, + reduceTensorIndicesType: miopenIndicesType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Query a ReduceTensor descriptor object\n\n @param reduceTensorDesc Pointer to the ReduceTensor descriptor object (input)\n @param reduceTensorOp Pointer to enumerant specifying the operation used by\n ReduceTensor (output)\n @param reduceTensorCompType Pointer to enumerant specifying the data type used with\n ReduceTensor operation (output)\n @param reduceTensorNanOpt Pointer to enumerant specifying the Nan number propagation mode\n (output)\n @param reduceTensorIndices Pointer to enumerant specifying the indices modes used by\n ReduceTensor (output)\n @param reduceTensorIndicesType Pointer to enumerant specifying the data type of the indices\n (output)\n @return miopenStatus_t"] + pub fn miopenGetReduceTensorDescriptor( + reduceTensorDesc: miopenReduceTensorDescriptor_t, + reduceTensorOp: *mut miopenReduceTensorOp_t, + reduceTensorCompType: *mut miopenDataType_t, + reduceTensorNanOpt: *mut miopenNanPropagation_t, + reduceTensorIndices: *mut miopenReduceTensorIndices_t, + reduceTensorIndicesType: *mut miopenIndicesType_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Helper function to query the minimum index space size required by the ReduceTensor call\n\n @param handle MIOpen Handle (input)\n @param reduceTensorDesc Pointer to the ReduceTensor descriptor object (input)\n @param aDesc Pointer to the input tensor descriptor (input)\n @param cDesc Pointer to the output tensor descriptor (input)\n @param sizeInBytes Pointer to data to return the minimum index space size\n @return miopenStatus_t"] + pub fn miopenGetReductionIndicesSize( + handle: miopenHandle_t, + reduceTensorDesc: miopenReduceTensorDescriptor_t, + aDesc: miopenTensorDescriptor_t, + cDesc: miopenTensorDescriptor_t, + sizeInBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Helper function to query the minimum workspace size required by the ReduceTensor call\n\n @param handle MIOpen Handle (input)\n @param reduceTensorDesc Pointer to the ReduceTensor descriptor object (input)\n @param aDesc Pointer to the input tensor descriptor (input)\n @param cDesc Pointer to the output tensor descriptor (input)\n @param sizeInBytes Pointer to data to return the minimum workspace size\n @return miopenStatus_t"] + pub fn miopenGetReductionWorkspaceSize( + handle: miopenHandle_t, + reduceTensorDesc: miopenReduceTensorDescriptor_t, + aDesc: miopenTensorDescriptor_t, + cDesc: miopenTensorDescriptor_t, + sizeInBytes: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief TensorReduce function doing reduction on tensor A by implementing C = alpha * reduceOp(A)\n + beta * C\n\n The length of each dimension of output tensor C must match the length of the corresponding\n dimension of\n input tensor A or must be equal to 1. The dimensions with length equal to 1 indicate the\n dimensions\n of A to be reduced.\n\n @param handle MIOpen Handle (input)\n @param reduceTensorDesc Pointer to the ReduceTensor descriptor object (input)\n @param indices Address of the allocated indices data space (output)\n @param indicesSizeInBytes Size in bytes of the allocated indices data space (input)\n @param workspace Address of the allocated workspace data (input)\n @param workspaceSizeInBytes Size in bytes of the allocated workspace data (input)\n @param alpha Pointer to scale factor for data in input tensor A (input)\n @param aDesc Pointer to the tensor descriptor for input tensor A (input)\n @param A Pointer to the data of input tensor A (input)\n @param beta Pointer to scale factor for data in output tensor C (input)\n @param cDesc Pointer to the tensor descriptor for output tensor C (input)\n @param C Pointer to the data of output tensor C (output)\n @return miopenStatus_t"] + pub fn miopenReduceTensor( + handle: miopenHandle_t, + reduceTensorDesc: miopenReduceTensorDescriptor_t, + indices: *mut ::std::os::raw::c_void, + indicesSizeInBytes: usize, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, + alpha: *const ::std::os::raw::c_void, + aDesc: miopenTensorDescriptor_t, + A: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + cDesc: miopenTensorDescriptor_t, + C: *mut ::std::os::raw::c_void, + ) -> miopenStatus_t; +} +#[doc = " @brief Describes a problem for different miopen operations.\n\n For now, this is only used for convolution, but could be used for other\n operators in the future(such as GEMM, Pooling, etc)"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenProblem { + pub _address: u8, +} +pub type miopenProblem_t = *mut miopenProblem; +impl miopenProblemDirection_t { + pub const miopenProblemDirectionForward: miopenProblemDirection_t = miopenProblemDirection_t(0); +} +impl miopenProblemDirection_t { + pub const miopenProblemDirectionBackward: miopenProblemDirection_t = + miopenProblemDirection_t(1); +} +impl miopenProblemDirection_t { + pub const miopenProblemDirectionBackwardWeights: miopenProblemDirection_t = + miopenProblemDirection_t(2); +} +#[repr(transparent)] +#[doc = " @enum miopenProblemDirection_t\n Directions of miopen operation."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenProblemDirection_t(pub ::std::os::raw::c_uint); +impl miopenTensorArgumentId_t { + pub const miopenTensorArgumentIdInvalid: miopenTensorArgumentId_t = miopenTensorArgumentId_t(0); +} +impl miopenTensorArgumentId_t { + pub const miopenTensorConvolutionX: miopenTensorArgumentId_t = miopenTensorArgumentId_t(1); +} +impl miopenTensorArgumentId_t { + pub const miopenTensorConvolutionW: miopenTensorArgumentId_t = miopenTensorArgumentId_t(2); +} +impl miopenTensorArgumentId_t { + pub const miopenTensorConvolutionY: miopenTensorArgumentId_t = miopenTensorArgumentId_t(3); +} +#[repr(transparent)] +#[doc = " @enum miopenTensorArgumentId_t\n Identifiers for tensor arguments of problems and operations."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenTensorArgumentId_t(pub ::std::os::raw::c_uint); +impl miopenFindResultsOrder_t { + pub const miopenFindResultsOrderByTime: miopenFindResultsOrder_t = miopenFindResultsOrder_t(0); +} +impl miopenFindResultsOrder_t { + pub const miopenFindResultsOrderByWorkspaceSize: miopenFindResultsOrder_t = + miopenFindResultsOrder_t(1); +} +#[repr(transparent)] +#[doc = " @enum miopenTensorArgumentId_t\n Different ways to sort results of the find call."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct miopenFindResultsOrder_t(pub ::std::os::raw::c_uint); +extern "C" { + #[must_use] + #[doc = " @brief Initializes a problem object describing a convolution operation.\n\n @param problem Pointer to the problem to initialize\n @param operatorDesc Descriptor of the operator to be used\n @param direction Direction of the operation\n @return miopenStatus_t"] + pub fn miopenCreateConvProblem( + problem: *mut miopenProblem_t, + operatorDesc: miopenConvolutionDescriptor_t, + direction: miopenProblemDirection_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys a problem object.\n\n @param problem Problem to destroy\n @return miopenStatus_t"] + pub fn miopenDestroyProblem(problem: miopenProblem_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets a tensor descriptor for the specified argument.\n\n @param problem Problem to update\n @param id Id of the argument for the descriptor\n @param descriptor Tensor descriptor to set\n @return miopenStatus_t"] + pub fn miopenSetProblemTensorDescriptor( + problem: miopenProblem_t, + id: miopenTensorArgumentId_t, + descriptor: miopenTensorDescriptor_t, + ) -> miopenStatus_t; +} +#[doc = " @brief The miopenFindOptions allows the user to configure how find will be used."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenFindOptions { + pub _address: u8, +} +pub type miopenFindOptions_t = *mut miopenFindOptions; +extern "C" { + #[must_use] + #[doc = " @brief Initializes miopenFindOptions object.\n\n @param options Pointer to options object to initialze\n @return miopenStatus_t"] + pub fn miopenCreateFindOptions(options: *mut miopenFindOptions_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys miopenFindOptions object.\n\n @param options Options object to destroy\n @return miopenStatus_t"] + pub fn miopenDestroyFindOptions(options: miopenFindOptions_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the tuning find option. Default value is zero.\n\n @param options Options object to upfate\n @param value Value of zero means no tuning, value of one means tuning enabled\n @return miopenStatus_t"] + pub fn miopenSetFindOptionTuning( + options: miopenFindOptions_t, + value: ::std::os::raw::c_int, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the results order find option. Default value is miopenFindResultsOrderByTime.\n\n @param options Options object to upfate\n @param value Specifies what order should find results have\n @return miopenStatus_t"] + pub fn miopenSetFindOptionResultsOrder( + options: miopenFindOptions_t, + value: miopenFindResultsOrder_t, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Sets the workspace limit find option. Default value is maximum of size_t\n\n @param options Options object to upfate\n @param value Specifies the workspace limit for find call. All solvers exceeding the limit\n would be ignored.\n @return miopenStatus_t"] + pub fn miopenSetFindOptionWorkspaceLimit( + options: miopenFindOptions_t, + value: usize, + ) -> miopenStatus_t; +} +#[doc = " @brief The miopenSolution object describes a prepared solution."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenSolution { + pub _address: u8, +} +pub type miopenSolution_t = *mut miopenSolution; +extern "C" { + #[must_use] + #[doc = " @brief Finds solutions to a problem by running different applicable solutions. Memory is\n automatically allocated.\n\n @param handle Handle to execute the kernels\n @param problem Problem to solve\n @param options Find options. When null default values would be used\n @param solutions Pointer to the first result. Must not be null\n @param numSolutions Pointer to the amount of results. Ignored if null\n @param maxSolutions Limits the amount of results\n @return miopenStatus_t"] + pub fn miopenFindSolutions( + handle: miopenHandle_t, + problem: miopenProblem_t, + options: miopenFindOptions_t, + solutions: *mut miopenSolution_t, + numSolutions: *mut usize, + maxSolutions: usize, + ) -> miopenStatus_t; +} +#[doc = " @brief Values of a tensor argument for the miopenRunSolution function."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct miopenTensorArgument_t { + pub id: miopenTensorArgumentId_t, + pub descriptor: *mut miopenTensorDescriptor_t, + pub buffer: *mut ::std::os::raw::c_void, +} +extern "C" { + #[must_use] + #[doc = " @brief Runs the solution using the passed in buffers.\n\n @param handle Handle to execute the kernels\n @param solution Solution to execute\n @param nInputs Amount to inputs for the solution\n @param tensors Tensor arguments described by miopenTensorArgument_t\n @param workspace Pointer to device buffer used as workspace. May be null when not required.\n Should not be less than expected\n @param workspaceSize Size of the workspace buffer\n @return miopenStatus_t"] + pub fn miopenRunSolution( + handle: miopenHandle_t, + solution: miopenSolution_t, + nInputs: usize, + tensors: *const miopenTensorArgument_t, + workspace: *mut ::std::os::raw::c_void, + workspaceSize: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Destroys solution object.\n\n @param solution Solution to destroy\n @return miopenStatus_t"] + pub fn miopenDestroySolution(solution: miopenSolution_t) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Loads solution object from binary data.\n\n @param solution Pointer to the solution to load\n @param data Data to load the solution from\n @param size Size of the solution blob\n @return miopenStatus_t"] + pub fn miopenLoadSolution( + solution: *mut miopenSolution_t, + data: *const ::std::os::raw::c_char, + size: usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Saves a solution object as binary data.\n\n @param solution Solution to save\n @param data Pointer to a buffer to save soltuion to\n @return miopenStatus_t"] + pub fn miopenSaveSolution( + solution: miopenSolution_t, + data: *mut ::std::os::raw::c_char, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reads the expected size of a solution.\n\n @param solution Solution to get size\n @param size Pointer to a location where to write the size of the solution blob\n @return miopenStatus_t"] + pub fn miopenGetSolutionSize(solution: miopenSolution_t, size: *mut usize) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reads the amount of workspace required to exectute the solution.\n\n @param solution Solution to get required workspace size\n @param workspaceSize Pointer to a location where to write the workspace size\n @return miopenStatus_t"] + pub fn miopenGetSolutionWorkspaceSize( + solution: miopenSolution_t, + workspaceSize: *mut usize, + ) -> miopenStatus_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reads the time spent to execute the solution the last it was run.\n\n @param solution Solution to get exection time\n @param time Pointer to a location where to write the execution time\n @return miopenStatus_t"] + pub fn miopenGetSolutionTime(solution: miopenSolution_t, time: *mut f32) -> miopenStatus_t; +} diff --git a/offline_compiler/Cargo.toml b/offline_compiler/Cargo.toml new file mode 100644 index 0000000..374fff8 --- /dev/null +++ b/offline_compiler/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "offline_compiler" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[[bin]] +name = "zoc" +path = "src/main.rs" + +[dependencies] +comgr = { path = "../comgr" } +hip_common = { path = "../hip_common" } +hiprt-sys = { path = "../hiprt-sys" } +hip_runtime-sys = { path = "../hip_runtime-sys" } +ptx = { path = "../ptx" } +argh = "0.1" +libloading = "0.8" + +[package.metadata.zluda] +debug_only = true diff --git a/offline_compiler/src/main.rs b/offline_compiler/src/main.rs new file mode 100644 index 0000000..2bde075 --- /dev/null +++ b/offline_compiler/src/main.rs @@ -0,0 +1,305 @@ +use argh::FromArgs; +use comgr::Comgr; +use hip_common::CompilationMode; +use hip_runtime_sys::*; +use hiprt_sys::*; +use ptx::ModuleParserExt; +use std::borrow::Cow; +use std::ffi::{c_void, CStr}; +use std::path::Path; +use std::rc::Rc; +use std::{ffi::CString, fs, path::PathBuf}; +use std::{iter, ptr}; + +#[derive(FromArgs)] +/// ZLUDA offline compiler +struct CompilerArguments { + /// LLVM AMDGPU ISA, defaults to "gfx1030" + #[argh(option, default = "default_isa()")] + isa: String, + /// paths to PTX files + #[argh(positional)] + inputs: Vec, + /// directory with output, will be created if does not exist + #[argh(option, short = 'o')] + output: Option, + /// name of an OptiX program, if provided PTX will be compiled in raytracing mode + #[argh(option)] + rt_program: Option, + /// compilation mode: 1 - Wave32, 2 - Wave32OnWave64, 3 - DoubleWave32OnWave64, defaults to Wave32 + #[argh(option, short = 'm')] + mode: Option, + /// print LLVM version + #[argh(switch, short = 'V')] + version: bool, +} + +fn default_isa() -> String { + "gfx1030".to_string() +} + +fn main() { + let args: CompilerArguments = argh::from_env(); + let comgr = comgr::Comgr::find_and_load().unwrap(); + if args.version { + println!("{}", comgr.version().unwrap()); + return; + } + let mut full_isa = "amdgcn-amd-amdhsa--".to_string(); + full_isa.push_str(&args.isa); + let main_path = &args.inputs[0]; + let inputs = args + .inputs + .iter() + .map(|input| fs::read_to_string(&input).unwrap()) + .collect::>(); + let asts = inputs + .iter() + .map(|input| ptx::ModuleParser::parse_checked(input).unwrap()) + .collect::>(); + let output_dir = if let Some(output) = args.output { + fs::create_dir_all(&output).unwrap(); + Cow::Owned(output) + } else { + Cow::Borrowed(args.inputs[0].parent().unwrap()) + }; + match args.rt_program { + Some(rt_program) => { + let comgr = Rc::new(comgr); + if asts.len() != 1 { + panic!("Raytracing compiler expects single .ptx input file") + } + compile_and_dump_raytracing( + full_isa, + output_dir, + &comgr, + rt_program, + main_path, + asts.into_iter().next().unwrap(), + ) + } + None => { + let mode = args + .mode + .map(CompilationMode::from_u8) + .flatten() + .unwrap_or(CompilationMode::Wave32); + compile_and_dump(full_isa, output_dir, mode, comgr, main_path, asts) + } + } +} + +fn compile_and_dump<'input>( + full_isa: String, + output_dir: Cow, + compilation_mode: CompilationMode, + comgr: Comgr, + main_path: &PathBuf, + asts: Vec>, +) { + let compiled_module = ptx::to_llvm_module(compilation_mode, asts).unwrap(); + let mut output_path = output_dir.to_path_buf(); + output_path.push(main_path.file_name().unwrap()); + output_path.set_extension("ll"); + fs::write(&output_path, compiled_module.get_llvm_text().to_string()).unwrap(); + output_path.set_extension("s"); + let metadata = compiled_module.metadata.to_elf_section(); + fs::write(&output_path, &metadata).unwrap(); + let binary = comgr + .compile( + compilation_mode, + CString::new(&*full_isa).unwrap().as_c_str(), + ptx::Module::get_bitcode_multi(iter::once(&compiled_module)).into_iter(), + &metadata, + ) + .unwrap(); + output_path.set_extension("elf"); + fs::write(&output_path, &binary).unwrap(); +} + +fn compile_and_dump_raytracing( + full_isa: String, + output_dir: Cow, + comgr: &Rc, + rt_program: String, + filename: &PathBuf, + ast: ptx::ast::Module, +) { + let mut empty_variable_block = hip_common::raytracing::VariablesBlock::empty(); + let raytracing_module = + ptx::to_llvm_module_for_raytracing(ast, &rt_program, &mut empty_variable_block).unwrap(); + let mut output_path = output_dir.into_owned(); + output_path.push(filename.file_name().unwrap()); + output_path.set_extension("ll"); + fs::write( + &output_path, + raytracing_module + .compilation_module + .get_llvm_text() + .to_string(), + ) + .unwrap(); + dump_headers(&output_path, &raytracing_module); + unsafe { compile_and_dump_relocatable(output_path, raytracing_module, comgr, full_isa) } +} + +unsafe fn compile_and_dump_relocatable( + mut output_path: PathBuf, + raytracing_module: ptx::raytracing::Module, + comgr: &Rc, + full_isa: String, +) { + let hiprt_bitcode = build_and_dump_hiprt(&mut output_path, &raytracing_module); + let full_isa = CString::from_vec_unchecked(full_isa.into_bytes()); + let binary = ptx::llvm::MemoryBuffer::create_no_copy(&hiprt_bitcode, false); + let main_name = CStr::from_bytes_with_nul_unchecked(b"raytracing_main\0"); + let bitcode = comgr + .link_bitcode( + raytracing_module.compilation_module.compilation_mode, + &full_isa, + iter::once((binary, main_name)) + .chain(raytracing_module.compilation_module.get_bitcode_all()), + ) + .unwrap(); + dump_bitcode(&output_path, &bitcode); + let relocatable_object = comgr + .bitcode_to_relocatable( + raytracing_module.compilation_module.compilation_mode, + &full_isa, + &bitcode, + ) + .unwrap(); + let relocatable = comgr + .link_relocatable(&full_isa, iter::once(&relocatable_object)) + .unwrap(); + //let relocatable = relocatable_object.get_data().unwrap(); + output_path.set_extension("elf"); + fs::write(&output_path, relocatable).unwrap(); +} + +fn dump_bitcode(output_path: &PathBuf, bitcode: &comgr::Bitcode) { + let mut output_path = output_path.clone(); + let mut file_name = output_path + .file_stem() + .unwrap() + .to_string_lossy() + .into_owned(); + file_name.push_str("_linked.bc"); + output_path.set_file_name(file_name); + let linked_bitcode = bitcode.get_data().unwrap(); + fs::write(output_path, linked_bitcode).unwrap(); +} + +unsafe fn build_and_dump_hiprt( + output_path: &mut PathBuf, + raytracing_module: &ptx::raytracing::Module, +) -> Vec { + let kernel_source = raytracing_module.kernel_source; + assert_eq!(hipInit(0), hipError_t(0)); + let mut hip_context = ptr::null_mut(); + assert_eq!(hipCtxCreate(&mut hip_context, 0, 0), hipError_t(0)); + let mut context_input = hiprtContextCreationInput { + ctxt: hip_context as _, + device: 0, + deviceType: hiprtDeviceType::hiprtDeviceAMD, + }; + let hiprt = hiprt_sys::HipRt::load().unwrap(); + let mut context = ptr::null_mut(); + assert!( + hiprt.hiprtCreateContext( + hiprt_sys::HIPRT_API_VERSION, + &mut context_input, + &mut context, + ) == hiprtError(0) + ); + let debug_level = if cfg!(debug_assertions) { + b"-g\0".as_ptr() + } else { + b"-g0\0".as_ptr() + }; + let options = [ + debug_level, + // We just want to emit LLVM, we'd use O0, but somehow IR emitted by O0 prevents inling. + // Weirdly, -disable-llvm-optzns produces much bigger code + b"-O1\0".as_ptr(), + // Stop compilation at LLVM + b"-fgpu-rdc\0".as_ptr(), + // hiprtc injects -mcumode which we don't want + b"-mno-cumode\0".as_ptr(), + // Internalization makes so that _rt_trace_time_mask_flags_64 is module-private + // and does not get linked with the code generated by ptx compiler + b"-mllvm\0".as_ptr(), + b"-amdgpu-internalize-symbols=0\0".as_ptr(), + ]; + let mut rt_program = ptr::null_mut::(); + let headers = raytracing_module + .headers + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + let header_names = raytracing_module + .header_names + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + assert!( + hiprt.hiprtBuildTraceProgram( + context, + ptx::raytracing::Module::KERNEL_NAME.as_ptr(), + kernel_source.as_ptr() as _, + "zluda_rt_kernel\0".as_ptr() as _, + headers.len() as i32, + headers.as_ptr() as _, + header_names.as_ptr() as _, + options.as_ptr() as _, + options.len() as i32, + (&mut rt_program) as *mut _ as _, + ) == hiprtError(0) + ); + let hiprt_bitcode = get_bitcode(rt_program); + let mut output_path = output_path.clone(); + let mut file_name = output_path + .file_stem() + .unwrap() + .to_string_lossy() + .into_owned(); + file_name.push_str("_hiprt.bc"); + output_path.set_file_name(file_name); + fs::write(&output_path, &hiprt_bitcode).unwrap(); + hiprt_bitcode +} + +#[cfg(windows)] +const HIPRTC: &'static str = "hiprtc\0"; + +#[cfg(not(windows))] +const HIPRTC: &'static str = "libhiprtc.so\0"; + +unsafe fn get_bitcode(rt_program: *mut c_void) -> Vec { + use libloading::{Library, Symbol}; + let hiprtc = Library::new(HIPRTC).unwrap(); + let hiprtc_get_bitcode_size: Symbol< + unsafe fn(prog: *mut c_void, bitcode_size: *mut usize) -> u32, + > = hiprtc.get(b"hiprtcGetBitcodeSize\0").unwrap(); + let hiprtc_get_bitcode: Symbol u32> = + hiprtc.get(b"hiprtcGetBitcode\0").unwrap(); + let mut program_size = 0; + let error = hiprtc_get_bitcode_size(rt_program, &mut program_size); + if error != 0 { + panic!("{}", error); + } + let mut main_bitcode = vec![0u8; program_size]; + let error = hiprtc_get_bitcode(rt_program, main_bitcode.as_mut_ptr()); + if error != 0 { + panic!("{}", error); + } + main_bitcode +} + +fn dump_headers(output_path: &PathBuf, rt_module: &ptx::raytracing::Module) { + let mut header_path = output_path.clone(); + for (header_name, header) in rt_module.header_names.iter().zip(rt_module.headers.iter()) { + header_path.set_file_name(header_name.to_str().unwrap()); + fs::write(&header_path, header.as_bytes()).unwrap(); + } +} diff --git a/optix_base/Cargo.toml b/optix_base/Cargo.toml new file mode 100644 index 0000000..45ab8c8 --- /dev/null +++ b/optix_base/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "optix_base" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0" +syn = { version = "1.0.93", features = ["full", "visit", "visit-mut"] } +proc-macro2 = "1.0" +rustc-hash = "1.1" diff --git a/optix_base/README b/optix_base/README new file mode 100644 index 0000000..9d1e1d6 --- /dev/null +++ b/optix_base/README @@ -0,0 +1,2 @@ +bindgen include/wrapper.hpp -o src/optix.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --whitelist-type="Optix.*" --whitelist-function "optix.*" --whitelist-var "OPTIX.*" -- -I"F:\dev\OptiX SDK 7.4.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.5\include +bindgen include/wrapper6.hpp -o src/optix6.rs --new-type-alias=RTobject --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --whitelist-type="RT.*" --whitelist-function "rt.*" --whitelist-var "RT.*" -- -I"F:\dev\OptiX SDK 6.5.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.5\include" "-D__int64=long long" diff --git a/optix_base/include/wrapper.hpp b/optix_base/include/wrapper.hpp new file mode 100644 index 0000000..0cbf13b --- /dev/null +++ b/optix_base/include/wrapper.hpp @@ -0,0 +1,2 @@ +#include +#include diff --git a/optix_base/include/wrapper6.hpp b/optix_base/include/wrapper6.hpp new file mode 100644 index 0000000..92359d8 --- /dev/null +++ b/optix_base/include/wrapper6.hpp @@ -0,0 +1,6 @@ +#include +#include +#include +#include +#include +#include diff --git a/optix_base/src/lib.rs b/optix_base/src/lib.rs new file mode 100644 index 0000000..9c43664 --- /dev/null +++ b/optix_base/src/lib.rs @@ -0,0 +1,316 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{Ident, Span}; +use quote::{format_ident, quote, ToTokens}; +use rustc_hash::{FxHashMap, FxHashSet}; +use syn::spanned::Spanned; +use syn::Fields; +use syn::{ + bracketed, + parse::{Parse, ParseStream}, + parse_macro_input, + punctuated::Punctuated, + visit::Visit, + File, ImplItem, Item, Path, Token, Type, TypePath, +}; + +const OPTIX_RS: &'static str = include_str! {"optix.rs"}; +const OPTIX6_RS: &'static str = include_str! {"optix6.rs"}; + +// This macro copies optix.rs as-is with some changes: +// * All function declarations are filtered out +// * All CUDA types are skipped +#[proc_macro] +pub fn optix_type_declarations(_: TokenStream) -> TokenStream { + let mut optix_module = syn::parse_str::(OPTIX_RS).unwrap(); + optix_module.items = optix_module + .items + .into_iter() + .filter_map(|item| match item { + Item::ForeignMod(_) => None, + Item::Type(type_) => { + if type_.ident.to_string().starts_with("CU") { + None + } else { + Some(Item::Type(type_)) + } + } + Item::Struct(struct_) => { + if struct_.ident.to_string().starts_with("CU") { + None + } else { + Some(Item::Struct(struct_)) + } + } + i => Some(i), + }) + .collect::>(); + optix_module.into_token_stream().into() +} + +// This macro accepts another macro which accepts a semicolon separated +// list of OptiX functions +// macro_foo!( +// "C" fn optixDeviceContextCreate( +// fromContext: CUcontext, +// options: *const OptixDeviceContextOptions, +// context: *mut OptixDeviceContext, +// ) -> OptixResult; +// "C" fn optixGetErrorName(result: OptixResult) -> *const ::std::os::raw::c_char +// ) +#[proc_macro] +pub fn optix_function_declarations(tokens: TokenStream) -> TokenStream { + let macro_ = parse_macro_input!(tokens as Path); + let optix_module = syn::parse_str::(OPTIX_RS).unwrap(); + let mut all_fns = FxHashMap::default(); + let mut ordered_exports = Vec::new(); + for item in optix_module.items.iter() { + match item { + Item::ForeignMod(extern_) => { + for item in extern_.items.iter() { + if let syn::ForeignItem::Fn(fn_) = item { + all_fns.insert(&fn_.sig.ident, &fn_.sig); + } + } + } + Item::Struct(struct_) if struct_.ident == "OptixFunctionTable" => { + for fn_ in struct_.fields.iter() { + ordered_exports.push(fn_.ident.as_ref().unwrap()); + } + } + _ => {} + } + } + let fns_ = ordered_exports + .into_iter() + .fold(Vec::new(), |mut vec, export| { + if export.to_string().starts_with("reserved") { + vec.push(quote! { + "C" fn #export() -> () + }); + } else { + let fn_signature = all_fns[export]; + let name = &fn_signature.ident; + let inputs = &fn_signature.inputs; + let output = &fn_signature.output; + vec.push(quote! { + "C" fn #name(#inputs) #output + }); + } + vec + }); + quote! { + #macro_ ! ( #(#fns_);* ); + } + .into() +} + +// This macro copies optix6.rs as-is with some changes: +// * All function declarations are filtered out +// * For selected enums we generate a safe version of the enum type and a conversion function +#[proc_macro] +pub fn optix6_type_declarations(tokens: TokenStream) -> TokenStream { + let type_decl = parse_macro_input!(tokens as TypeDeclInput); + let mut optix_module = syn::parse_str::(OPTIX6_RS).unwrap(); + optix_module.items = optix_module + .items + .into_iter() + .filter_map(|item| match item { + Item::ForeignMod(_) => None, + i => Some(i), + }) + .collect::>(); + + let mut safe_enum_gen = GenerateSafeEnums::new(type_decl.enums.iter()); + syn::visit::visit_file(&mut safe_enum_gen, &optix_module); + let safe_enums = safe_enum_gen.generate(); + let mut token_stream = optix_module.into_token_stream(); + token_stream.extend(safe_enums); + token_stream.into() +} + +struct GenerateSafeEnums<'ast> { + enums: FxHashMap<&'ast Ident, (Option<&'ast Type>, Vec<&'ast Ident>)>, +} + +impl<'ast> GenerateSafeEnums<'ast> { + fn new(enums: impl Iterator) -> Self { + let enums = enums.map(|e| (e, (None, Vec::new()))).collect(); + Self { enums } + } + + fn generate(self) -> TokenStream2 { + let mut token_stream = TokenStream2::new(); + for (enum_, (underlying_type, items)) in self.enums { + let safe_enum = format_ident!("{}Safe", enum_); + let underlying_type = Self::to_ident(underlying_type.unwrap()); + token_stream.extend(quote! { + #[repr(#underlying_type)] + #[derive(Copy, Clone, PartialEq, Eq)] + pub enum #safe_enum { + #( + #items = #enum_ :: #items .0, + )* + } + + impl #safe_enum { + pub fn new(e: #enum_) -> Option { + match e { + #( + #enum_ :: #items => Some(#safe_enum :: #items), + )* + _ => None + } + } + } + + impl From<#safe_enum> for #enum_ { + fn from(value: #safe_enum) -> #enum_ { + match value { + #( + #safe_enum :: #items => #enum_ :: #items, + )* + } + } + } + }); + } + token_stream + } + + fn to_ident(ty: &Type) -> Ident { + if let Type::Path(ty_path) = ty { + match &*ty_path.path.segments.last().unwrap().ident.to_string() { + "c_uint" => Ident::new("u32", ty_path.span()), + "c_int" => Ident::new("i32", ty_path.span()), + _ => unimplemented!(), + } + } else { + panic!() + } + } +} + +impl<'ast> Visit<'ast> for GenerateSafeEnums<'ast> { + fn visit_item_impl(&mut self, item: &'ast syn::ItemImpl) { + if let Type::Path(TypePath { path, .. }) = &*item.self_ty { + if let Some((_, entry)) = self.enums.get_mut(&path.segments[0].ident) { + for item in item.items.iter() { + if let ImplItem::Const(const_) = item { + entry.push(&const_.ident) + } + } + } + } + } + fn visit_item_struct(&mut self, item: &'ast syn::ItemStruct) { + if let Some((underlying, _)) = self.enums.get_mut(&item.ident) { + if let Fields::Unnamed(fields) = &item.fields { + *underlying = Some(&fields.unnamed[0].ty); + } + } + } +} + +struct TypeDeclInput { + enums: Punctuated, +} + +impl Parse for TypeDeclInput { + fn parse(input: ParseStream) -> syn::Result { + let enums = Punctuated::::parse_terminated(input)?; + Ok(TypeDeclInput { enums }) + } +} + +// This macro accepts following arguments: +// * `normal_macro`: ident for a normal macro +// * `override_macro`: ident for an override macro +// * `override_fns`: list of override functions +// Then macro goes through every function in optix6.rs, and for every fn `foo`: +// * if `foo` is contained in `override_fns` then pass it into `override_macro` +// * if `foo` is not contained in `override_fns` pass it to `normal_macro` +// Both macros expected a separated list of OptiX6 functions: +// macro_foo!( +// "C" fn rtContextCreate(context: *mut RTcontext) -> RTresult; +// "C" fn rtContextDestroy(context: RTcontext) -> RTresult +// ) +#[proc_macro] +pub fn optix6_function_declarations(tokens: TokenStream) -> TokenStream { + let function_decl = parse_macro_input!(tokens as FnDeclInput); + let override_idents = function_decl + .override_fns + .into_iter() + .collect::>(); + let optix_module = syn::parse_str::(OPTIX6_RS).unwrap(); + let mut fns = Vec::new(); + let mut override_fns = Vec::new(); + for item in optix_module.items.iter() { + match item { + Item::ForeignMod(extern_) => { + for item in extern_.items.iter() { + if let syn::ForeignItem::Fn(fn_) = item { + let abi = &extern_.abi.name; + let name = &fn_.sig.ident; + let inputs = &fn_.sig.inputs; + let mut output = &fn_.sig.output; + let unit_return = syn::ReturnType::Type( + Token![->](Span::call_site()), + Box::new(syn::Type::Tuple(syn::TypeTuple { + paren_token: syn::token::Paren { + span: Span::call_site(), + }, + elems: Punctuated::new(), + })), + ); + if let syn::ReturnType::Default = output { + output = &unit_return; + } + let fn_call = quote! { + #abi fn #name(#inputs) #output + }; + let insertion_target = if override_idents.contains(name) { + &mut override_fns + } else { + &mut fns + }; + insertion_target.push(fn_call); + } + } + } + _ => {} + } + } + let macro1 = function_decl.normal_macro; + let macro2 = function_decl.override_macro; + quote! { + #macro1 ! ( #(#fns);* ); + #macro2 ! ( #(#override_fns);* ); + } + .into() +} + +struct FnDeclInput { + normal_macro: Path, + override_macro: Path, + override_fns: Punctuated, +} + +impl Parse for FnDeclInput { + fn parse(input: ParseStream) -> syn::Result { + let normal_macro = input.parse::()?; + input.parse::()?; + let override_macro = input.parse::()?; + input.parse::()?; + let override_fns_content; + bracketed!(override_fns_content in input); + let override_fns = override_fns_content.parse_terminated(Ident::parse)?; + Ok(Self { + normal_macro, + override_macro, + override_fns, + }) + } +} diff --git a/optix_base/src/optix.rs b/optix_base/src/optix.rs new file mode 100644 index 0000000..82b9ae0 --- /dev/null +++ b/optix_base/src/optix.rs @@ -0,0 +1,3381 @@ +/* automatically generated by rust-bindgen 0.59.2 */ + +pub const OPTIX_SBT_RECORD_ALIGNMENT: u32 = 16; +pub const OPTIX_ACCEL_BUFFER_BYTE_ALIGNMENT: u32 = 128; +pub const OPTIX_INSTANCE_BYTE_ALIGNMENT: u32 = 16; +pub const OPTIX_AABB_BUFFER_BYTE_ALIGNMENT: u32 = 8; +pub const OPTIX_GEOMETRY_TRANSFORM_BYTE_ALIGNMENT: u32 = 16; +pub const OPTIX_TRANSFORM_BYTE_ALIGNMENT: u32 = 64; +pub const OPTIX_COMPILE_DEFAULT_MAX_REGISTER_COUNT: u32 = 0; +pub const OPTIX_COMPILE_DEFAULT_MAX_PAYLOAD_TYPE_COUNT: u32 = 8; +pub const OPTIX_COMPILE_DEFAULT_MAX_PAYLOAD_VALUE_COUNT: u32 = 32; +pub const OPTIX_ABI_VERSION: u32 = 55; +#[doc = " CUDA device pointer"] +pub type CUdeviceptr = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDeviceContext_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a device context"] +pub type OptixDeviceContext = *mut OptixDeviceContext_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixModule_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a module"] +pub type OptixModule = *mut OptixModule_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroup_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a program group"] +pub type OptixProgramGroup = *mut OptixProgramGroup_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixPipeline_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a pipeline"] +pub type OptixPipeline = *mut OptixPipeline_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiser_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a denoiser instance"] +pub type OptixDenoiser = *mut OptixDenoiser_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixTask_t { + _unused: [u8; 0], +} +#[doc = " Opaque type representing a work task"] +pub type OptixTask = *mut OptixTask_t; +#[doc = " Traversable handle"] +pub type OptixTraversableHandle = ::std::os::raw::c_ulonglong; +#[doc = " Visibility mask"] +pub type OptixVisibilityMask = ::std::os::raw::c_uint; +impl OptixResult { + pub const OPTIX_SUCCESS: OptixResult = OptixResult(0); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_VALUE: OptixResult = OptixResult(7001); +} +impl OptixResult { + pub const OPTIX_ERROR_HOST_OUT_OF_MEMORY: OptixResult = OptixResult(7002); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_OPERATION: OptixResult = OptixResult(7003); +} +impl OptixResult { + pub const OPTIX_ERROR_FILE_IO_ERROR: OptixResult = OptixResult(7004); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_FILE_FORMAT: OptixResult = OptixResult(7005); +} +impl OptixResult { + pub const OPTIX_ERROR_DISK_CACHE_INVALID_PATH: OptixResult = OptixResult(7010); +} +impl OptixResult { + pub const OPTIX_ERROR_DISK_CACHE_PERMISSION_ERROR: OptixResult = OptixResult(7011); +} +impl OptixResult { + pub const OPTIX_ERROR_DISK_CACHE_DATABASE_ERROR: OptixResult = OptixResult(7012); +} +impl OptixResult { + pub const OPTIX_ERROR_DISK_CACHE_INVALID_DATA: OptixResult = OptixResult(7013); +} +impl OptixResult { + pub const OPTIX_ERROR_LAUNCH_FAILURE: OptixResult = OptixResult(7050); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_DEVICE_CONTEXT: OptixResult = OptixResult(7051); +} +impl OptixResult { + pub const OPTIX_ERROR_CUDA_NOT_INITIALIZED: OptixResult = OptixResult(7052); +} +impl OptixResult { + pub const OPTIX_ERROR_VALIDATION_FAILURE: OptixResult = OptixResult(7053); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_PTX: OptixResult = OptixResult(7200); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_LAUNCH_PARAMETER: OptixResult = OptixResult(7201); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_PAYLOAD_ACCESS: OptixResult = OptixResult(7202); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_ATTRIBUTE_ACCESS: OptixResult = OptixResult(7203); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_FUNCTION_USE: OptixResult = OptixResult(7204); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_FUNCTION_ARGUMENTS: OptixResult = OptixResult(7205); +} +impl OptixResult { + pub const OPTIX_ERROR_PIPELINE_OUT_OF_CONSTANT_MEMORY: OptixResult = OptixResult(7250); +} +impl OptixResult { + pub const OPTIX_ERROR_PIPELINE_LINK_ERROR: OptixResult = OptixResult(7251); +} +impl OptixResult { + pub const OPTIX_ERROR_ILLEGAL_DURING_TASK_EXECUTE: OptixResult = OptixResult(7270); +} +impl OptixResult { + pub const OPTIX_ERROR_INTERNAL_COMPILER_ERROR: OptixResult = OptixResult(7299); +} +impl OptixResult { + pub const OPTIX_ERROR_DENOISER_MODEL_NOT_SET: OptixResult = OptixResult(7300); +} +impl OptixResult { + pub const OPTIX_ERROR_DENOISER_NOT_INITIALIZED: OptixResult = OptixResult(7301); +} +impl OptixResult { + pub const OPTIX_ERROR_ACCEL_NOT_COMPATIBLE: OptixResult = OptixResult(7400); +} +impl OptixResult { + pub const OPTIX_ERROR_PAYLOAD_TYPE_MISMATCH: OptixResult = OptixResult(7500); +} +impl OptixResult { + pub const OPTIX_ERROR_PAYLOAD_TYPE_RESOLUTION_FAILED: OptixResult = OptixResult(7501); +} +impl OptixResult { + pub const OPTIX_ERROR_PAYLOAD_TYPE_ID_INVALID: OptixResult = OptixResult(7502); +} +impl OptixResult { + pub const OPTIX_ERROR_NOT_SUPPORTED: OptixResult = OptixResult(7800); +} +impl OptixResult { + pub const OPTIX_ERROR_UNSUPPORTED_ABI_VERSION: OptixResult = OptixResult(7801); +} +impl OptixResult { + pub const OPTIX_ERROR_FUNCTION_TABLE_SIZE_MISMATCH: OptixResult = OptixResult(7802); +} +impl OptixResult { + pub const OPTIX_ERROR_INVALID_ENTRY_FUNCTION_OPTIONS: OptixResult = OptixResult(7803); +} +impl OptixResult { + pub const OPTIX_ERROR_LIBRARY_NOT_FOUND: OptixResult = OptixResult(7804); +} +impl OptixResult { + pub const OPTIX_ERROR_ENTRY_SYMBOL_NOT_FOUND: OptixResult = OptixResult(7805); +} +impl OptixResult { + pub const OPTIX_ERROR_LIBRARY_UNLOAD_FAILURE: OptixResult = OptixResult(7806); +} +impl OptixResult { + pub const OPTIX_ERROR_CUDA_ERROR: OptixResult = OptixResult(7900); +} +impl OptixResult { + pub const OPTIX_ERROR_INTERNAL_ERROR: OptixResult = OptixResult(7990); +} +impl OptixResult { + pub const OPTIX_ERROR_UNKNOWN: OptixResult = OptixResult(7999); +} +#[repr(transparent)] +#[doc = " Result codes returned from API functions"] +#[doc = ""] +#[doc = " All host side API functions return OptixResult with the exception of optixGetErrorName"] +#[doc = " and optixGetErrorString. When successful OPTIX_SUCCESS is returned. All return codes"] +#[doc = " except for OPTIX_SUCCESS should be assumed to be errors as opposed to a warning."] +#[doc = ""] +#[doc = " \\see #optixGetErrorName(), #optixGetErrorString()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixResult(pub ::std::os::raw::c_uint); +impl OptixDeviceProperty { + #[doc = " Maximum value for OptixPipelineLinkOptions::maxTraceDepth. sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_TRACE_DEPTH: OptixDeviceProperty = + OptixDeviceProperty(8193); +} +impl OptixDeviceProperty { + #[doc = " Maximum value to pass into optixPipelineSetStackSize for parameter"] + #[doc = " maxTraversableGraphDepth.v sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_TRAVERSABLE_GRAPH_DEPTH: OptixDeviceProperty = + OptixDeviceProperty(8194); +} +impl OptixDeviceProperty { + #[doc = " The maximum number of primitives (over all build inputs) as input to a single"] + #[doc = " Geometry Acceleration Structure (GAS). sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_PRIMITIVES_PER_GAS: OptixDeviceProperty = + OptixDeviceProperty(8195); +} +impl OptixDeviceProperty { + #[doc = " The maximum number of instances (over all build inputs) as input to a single"] + #[doc = " Instance Acceleration Structure (IAS). sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCES_PER_IAS: OptixDeviceProperty = + OptixDeviceProperty(8196); +} +impl OptixDeviceProperty { + #[doc = " The RT core version supported by the device (0 for no support, 10 for version"] + #[doc = " 1.0). sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_RTCORE_VERSION: OptixDeviceProperty = OptixDeviceProperty(8197); +} +impl OptixDeviceProperty { + #[doc = " The maximum value for #OptixInstance::instanceId. sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID: OptixDeviceProperty = + OptixDeviceProperty(8198); +} +impl OptixDeviceProperty { + #[doc = " The number of bits available for the #OptixInstance::visibilityMask."] + #[doc = " Higher bits must be set to zero. sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_NUM_BITS_INSTANCE_VISIBILITY_MASK: OptixDeviceProperty = + OptixDeviceProperty(8199); +} +impl OptixDeviceProperty { + #[doc = " The maximum number of instances that can be added to a single Instance"] + #[doc = " Acceleration Structure (IAS). sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_SBT_RECORDS_PER_GAS: OptixDeviceProperty = + OptixDeviceProperty(8200); +} +impl OptixDeviceProperty { + #[doc = " The maximum value for #OptixInstance::sbtOffset. sizeof( unsigned int )"] + pub const OPTIX_DEVICE_PROPERTY_LIMIT_MAX_SBT_OFFSET: OptixDeviceProperty = + OptixDeviceProperty(8201); +} +#[repr(transparent)] +#[doc = " Parameters used for #optixDeviceContextGetProperty()"] +#[doc = ""] +#[doc = " \\see #optixDeviceContextGetProperty()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixDeviceProperty(pub ::std::os::raw::c_uint); +#[doc = " Type of the callback function used for log messages."] +#[doc = ""] +#[doc = " \\param[in] level The log level indicates the severity of the message. See below for"] +#[doc = " possible values."] +#[doc = " \\param[in] tag A terse message category description (e.g., 'SCENE STAT')."] +#[doc = " \\param[in] message Null terminated log message (without newline at the end)."] +#[doc = " \\param[in] cbdata Callback data that was provided with the callback pointer."] +#[doc = ""] +#[doc = " It is the users responsibility to ensure thread safety within this function."] +#[doc = ""] +#[doc = " The following log levels are defined."] +#[doc = ""] +#[doc = " 0 disable Setting the callback level will disable all messages. The callback"] +#[doc = " function will not be called in this case."] +#[doc = " 1 fatal A non-recoverable error. The context and/or OptiX itself might no longer"] +#[doc = " be in a usable state."] +#[doc = " 2 error A recoverable error, e.g., when passing invalid call parameters."] +#[doc = " 3 warning Hints that OptiX might not behave exactly as requested by the user or"] +#[doc = " may perform slower than expected."] +#[doc = " 4 print Status or progress messages."] +#[doc = ""] +#[doc = " Higher levels might occur."] +#[doc = ""] +#[doc = " \\see #optixDeviceContextSetLogCallback(), #OptixDeviceContextOptions"] +pub type OptixLogCallback = ::std::option::Option< + unsafe extern "C" fn( + level: ::std::os::raw::c_uint, + tag: *const ::std::os::raw::c_char, + message: *const ::std::os::raw::c_char, + cbdata: *mut ::std::os::raw::c_void, + ), +>; +impl OptixDeviceContextValidationMode { + pub const OPTIX_DEVICE_CONTEXT_VALIDATION_MODE_OFF: OptixDeviceContextValidationMode = + OptixDeviceContextValidationMode(0); +} +impl OptixDeviceContextValidationMode { + pub const OPTIX_DEVICE_CONTEXT_VALIDATION_MODE_ALL: OptixDeviceContextValidationMode = + OptixDeviceContextValidationMode(4294967295); +} +#[repr(transparent)] +#[doc = " Validation mode settings."] +#[doc = ""] +#[doc = " When enabled, certain device code utilities will be enabled to provide as good debug and"] +#[doc = " error checking facilities as possible."] +#[doc = ""] +#[doc = ""] +#[doc = " \\see #optixDeviceContextCreate()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixDeviceContextValidationMode(pub ::std::os::raw::c_uint); +#[doc = " Parameters used for #optixDeviceContextCreate()"] +#[doc = ""] +#[doc = " \\see #optixDeviceContextCreate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDeviceContextOptions { + #[doc = " Function pointer used when OptiX wishes to generate messages"] + pub logCallbackFunction: OptixLogCallback, + #[doc = " Pointer stored and passed to logCallbackFunction when a message is generated"] + pub logCallbackData: *mut ::std::os::raw::c_void, + #[doc = " Maximum callback level to generate message for (see #OptixLogCallback)"] + pub logCallbackLevel: ::std::os::raw::c_int, + #[doc = " Validation mode of context."] + pub validationMode: OptixDeviceContextValidationMode, +} +impl OptixGeometryFlags { + #[doc = " No flags set"] + pub const OPTIX_GEOMETRY_FLAG_NONE: OptixGeometryFlags = OptixGeometryFlags(0); +} +impl OptixGeometryFlags { + #[doc = " Disables the invocation of the anyhit program."] + #[doc = " Can be overridden by OPTIX_INSTANCE_FLAG_ENFORCE_ANYHIT and OPTIX_RAY_FLAG_ENFORCE_ANYHIT."] + pub const OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT: OptixGeometryFlags = OptixGeometryFlags(1); +} +impl OptixGeometryFlags { + #[doc = " If set, an intersection with the primitive will trigger one and only one"] + #[doc = " invocation of the anyhit program. Otherwise, the anyhit program may be invoked"] + #[doc = " more than once."] + pub const OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL: OptixGeometryFlags = + OptixGeometryFlags(2); +} +#[repr(transparent)] +#[doc = " Flags used by #OptixBuildInputTriangleArray::flags"] +#[doc = " and #OptixBuildInput::flag"] +#[doc = " and #OptixBuildInputCustomPrimitiveArray::flags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixGeometryFlags(pub ::std::os::raw::c_uint); +impl OptixHitKind { + #[doc = " Ray hit the triangle on the front face"] + pub const OPTIX_HIT_KIND_TRIANGLE_FRONT_FACE: OptixHitKind = OptixHitKind(254); +} +impl OptixHitKind { + #[doc = " Ray hit the triangle on the back face"] + pub const OPTIX_HIT_KIND_TRIANGLE_BACK_FACE: OptixHitKind = OptixHitKind(255); +} +#[repr(transparent)] +#[doc = " Legacy type: A subset of the hit kinds for built-in primitive intersections."] +#[doc = " It is preferred to use optixGetPrimitiveType(), together with"] +#[doc = " optixIsFrontFaceHit() or optixIsBackFaceHit()."] +#[doc = ""] +#[doc = " \\see #optixGetHitKind()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixHitKind(pub ::std::os::raw::c_uint); +impl OptixIndicesFormat { + #[doc = " No indices, this format must only be used in combination with triangle soups, i.e., numIndexTriplets must be zero"] + pub const OPTIX_INDICES_FORMAT_NONE: OptixIndicesFormat = OptixIndicesFormat(0); +} +impl OptixIndicesFormat { + #[doc = " Three shorts"] + pub const OPTIX_INDICES_FORMAT_UNSIGNED_SHORT3: OptixIndicesFormat = OptixIndicesFormat(8450); +} +impl OptixIndicesFormat { + #[doc = " Three ints"] + pub const OPTIX_INDICES_FORMAT_UNSIGNED_INT3: OptixIndicesFormat = OptixIndicesFormat(8451); +} +#[repr(transparent)] +#[doc = " Format of indices used int #OptixBuildInputTriangleArray::indexFormat."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixIndicesFormat(pub ::std::os::raw::c_uint); +impl OptixVertexFormat { + #[doc = "< No vertices"] + pub const OPTIX_VERTEX_FORMAT_NONE: OptixVertexFormat = OptixVertexFormat(0); +} +impl OptixVertexFormat { + #[doc = "< Vertices are represented by three floats"] + pub const OPTIX_VERTEX_FORMAT_FLOAT3: OptixVertexFormat = OptixVertexFormat(8481); +} +impl OptixVertexFormat { + #[doc = "< Vertices are represented by two floats"] + pub const OPTIX_VERTEX_FORMAT_FLOAT2: OptixVertexFormat = OptixVertexFormat(8482); +} +impl OptixVertexFormat { + #[doc = "< Vertices are represented by three halfs"] + pub const OPTIX_VERTEX_FORMAT_HALF3: OptixVertexFormat = OptixVertexFormat(8483); +} +impl OptixVertexFormat { + #[doc = "< Vertices are represented by two halfs"] + pub const OPTIX_VERTEX_FORMAT_HALF2: OptixVertexFormat = OptixVertexFormat(8484); +} +impl OptixVertexFormat { + pub const OPTIX_VERTEX_FORMAT_SNORM16_3: OptixVertexFormat = OptixVertexFormat(8485); +} +impl OptixVertexFormat { + pub const OPTIX_VERTEX_FORMAT_SNORM16_2: OptixVertexFormat = OptixVertexFormat(8486); +} +#[repr(transparent)] +#[doc = " Format of vertices used in #OptixBuildInputTriangleArray::vertexFormat."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixVertexFormat(pub ::std::os::raw::c_uint); +impl OptixTransformFormat { + #[doc = "< no transform, default for zero initialization"] + pub const OPTIX_TRANSFORM_FORMAT_NONE: OptixTransformFormat = OptixTransformFormat(0); +} +impl OptixTransformFormat { + #[doc = "< 3x4 row major affine matrix"] + pub const OPTIX_TRANSFORM_FORMAT_MATRIX_FLOAT12: OptixTransformFormat = + OptixTransformFormat(8673); +} +#[repr(transparent)] +#[doc = " Format of transform used in #OptixBuildInputTriangleArray::transformFormat."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixTransformFormat(pub ::std::os::raw::c_uint); +#[doc = " Triangle inputs"] +#[doc = ""] +#[doc = " \\see #OptixBuildInput::triangleArray"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuildInputTriangleArray { + #[doc = " Points to host array of device pointers, one per motion step. Host array size must match the number of"] + #[doc = " motion keys as set in #OptixMotionOptions (or an array of size 1 if OptixMotionOptions::numKeys is set"] + #[doc = " to 0 or 1). Each per motion key device pointer must point to an array of vertices of the"] + #[doc = " triangles in the format as described by vertexFormat. The minimum alignment must match the natural"] + #[doc = " alignment of the type as specified in the vertexFormat, i.e., for OPTIX_VERTEX_FORMAT_FLOATX 4-byte,"] + #[doc = " for all others a 2-byte alignment. However, an 16-byte stride (and buffer alignment) is recommended for"] + #[doc = " vertices of format OPTIX_VERTEX_FORMAT_FLOAT3 for GAS build performance."] + pub vertexBuffers: *const CUdeviceptr, + #[doc = " Number of vertices in each of buffer in OptixBuildInputTriangleArray::vertexBuffers."] + pub numVertices: ::std::os::raw::c_uint, + #[doc = " \\see #OptixVertexFormat"] + pub vertexFormat: OptixVertexFormat, + #[doc = " Stride between vertices. If set to zero, vertices are assumed to be tightly"] + #[doc = " packed and stride is inferred from vertexFormat."] + pub vertexStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Optional pointer to array of 16 or 32-bit int triplets, one triplet per triangle."] + #[doc = " The minimum alignment must match the natural alignment of the type as specified in the indexFormat, i.e.,"] + #[doc = " for OPTIX_INDICES_FORMAT_UNSIGNED_INT3 4-byte and for OPTIX_INDICES_FORMAT_UNSIGNED_SHORT3 a 2-byte alignment."] + pub indexBuffer: CUdeviceptr, + #[doc = " Size of array in OptixBuildInputTriangleArray::indexBuffer. For build, needs to be zero if indexBuffer is \\c nullptr."] + pub numIndexTriplets: ::std::os::raw::c_uint, + #[doc = " \\see #OptixIndicesFormat"] + pub indexFormat: OptixIndicesFormat, + #[doc = " Stride between triplets of indices. If set to zero, indices are assumed to be tightly"] + #[doc = " packed and stride is inferred from indexFormat."] + pub indexStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Optional pointer to array of floats"] + #[doc = " representing a 3x4 row major affine"] + #[doc = " transformation matrix. This pointer must be a multiple of OPTIX_GEOMETRY_TRANSFORM_BYTE_ALIGNMENT"] + pub preTransform: CUdeviceptr, + #[doc = " Array of flags, to specify flags per sbt record,"] + #[doc = " combinations of OptixGeometryFlags describing the"] + #[doc = " primitive behavior, size must match numSbtRecords"] + pub flags: *const ::std::os::raw::c_uint, + #[doc = " Number of sbt records available to the sbt index offset override."] + pub numSbtRecords: ::std::os::raw::c_uint, + #[doc = " Device pointer to per-primitive local sbt index offset buffer. May be NULL."] + #[doc = " Every entry must be in range [0,numSbtRecords-1]."] + #[doc = " Size needs to be the number of primitives."] + pub sbtIndexOffsetBuffer: CUdeviceptr, + #[doc = " Size of type of the sbt index offset. Needs to be 0, 1, 2 or 4 (8, 16 or 32 bit)."] + pub sbtIndexOffsetSizeInBytes: ::std::os::raw::c_uint, + #[doc = " Stride between the index offsets. If set to zero, the offsets are assumed to be tightly"] + #[doc = " packed and the stride matches the size of the type (sbtIndexOffsetSizeInBytes)."] + pub sbtIndexOffsetStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Primitive index bias, applied in optixGetPrimitiveIndex()."] + #[doc = " Sum of primitiveIndexOffset and number of triangles must not overflow 32bits."] + pub primitiveIndexOffset: ::std::os::raw::c_uint, + #[doc = " \\see #OptixTransformFormat"] + pub transformFormat: OptixTransformFormat, +} +impl OptixPrimitiveType { + #[doc = " Custom primitive."] + pub const OPTIX_PRIMITIVE_TYPE_CUSTOM: OptixPrimitiveType = OptixPrimitiveType(9472); +} +impl OptixPrimitiveType { + #[doc = " B-spline curve of degree 2 with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_ROUND_QUADRATIC_BSPLINE: OptixPrimitiveType = + OptixPrimitiveType(9473); +} +impl OptixPrimitiveType { + #[doc = " B-spline curve of degree 3 with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE: OptixPrimitiveType = + OptixPrimitiveType(9474); +} +impl OptixPrimitiveType { + #[doc = " Piecewise linear curve with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR: OptixPrimitiveType = OptixPrimitiveType(9475); +} +impl OptixPrimitiveType { + #[doc = " CatmullRom curve with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_ROUND_CATMULLROM: OptixPrimitiveType = OptixPrimitiveType(9476); +} +impl OptixPrimitiveType { + #[doc = " Triangle."] + pub const OPTIX_PRIMITIVE_TYPE_TRIANGLE: OptixPrimitiveType = OptixPrimitiveType(9521); +} +#[repr(transparent)] +#[doc = " Builtin primitive types"] +#[doc = ""] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixPrimitiveType(pub ::std::os::raw::c_uint); +impl OptixPrimitiveTypeFlags { + #[doc = " Custom primitive."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(1); +} +impl OptixPrimitiveTypeFlags { + #[doc = " B-spline curve of degree 2 with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_QUADRATIC_BSPLINE: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(2); +} +impl OptixPrimitiveTypeFlags { + #[doc = " B-spline curve of degree 3 with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CUBIC_BSPLINE: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(4); +} +impl OptixPrimitiveTypeFlags { + #[doc = " Piecewise linear curve with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_LINEAR: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(8); +} +impl OptixPrimitiveTypeFlags { + #[doc = " CatmullRom curve with circular cross-section."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_ROUND_CATMULLROM: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(16); +} +impl OptixPrimitiveTypeFlags { + #[doc = " Triangle."] + pub const OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE: OptixPrimitiveTypeFlags = + OptixPrimitiveTypeFlags(-2147483648); +} +#[repr(transparent)] +#[doc = " Builtin flags may be bitwise combined."] +#[doc = ""] +#[doc = " \\see #OptixPipelineCompileOptions::usesPrimitiveTypeFlags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixPrimitiveTypeFlags(pub ::std::os::raw::c_int); +impl OptixCurveEndcapFlags { + #[doc = " Default end caps. Round end caps for linear, no end caps for quadratic/cubic."] + pub const OPTIX_CURVE_ENDCAP_DEFAULT: OptixCurveEndcapFlags = OptixCurveEndcapFlags(0); +} +impl OptixCurveEndcapFlags { + #[doc = " Flat end caps at both ends of quadratic/cubic curve segments. Not valid for linear."] + pub const OPTIX_CURVE_ENDCAP_ON: OptixCurveEndcapFlags = OptixCurveEndcapFlags(1); +} +#[repr(transparent)] +#[doc = " Curve end cap types, for non-linear curves"] +#[doc = ""] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixCurveEndcapFlags(pub ::std::os::raw::c_uint); +#[doc = " Curve inputs"] +#[doc = ""] +#[doc = " A curve is a swept surface defined by a 3D spline curve and a varying width (radius). A curve (or \"strand\") of"] +#[doc = " degree d (3=cubic, 2=quadratic, 1=linear) is represented by N > d vertices and N width values, and comprises N - d segments."] +#[doc = " Each segment is defined by d+1 consecutive vertices. Each curve may have a different number of vertices."] +#[doc = ""] +#[doc = " OptiX describes the curve array as a list of curve segments. The primitive id is the segment number."] +#[doc = " It is the user's responsibility to maintain a mapping between curves and curve segments."] +#[doc = " Each index buffer entry i = indexBuffer[primid] specifies the start of a curve segment,"] +#[doc = " represented by d+1 consecutive vertices in the vertex buffer,"] +#[doc = " and d+1 consecutive widths in the width buffer. Width is interpolated the same"] +#[doc = " way vertices are interpolated, that is, using the curve basis."] +#[doc = ""] +#[doc = " Each curves build input has only one SBT record."] +#[doc = " To create curves with different materials in the same BVH, use multiple build inputs."] +#[doc = ""] +#[doc = " \\see #OptixBuildInput::curveArray"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuildInputCurveArray { + #[doc = " Curve degree and basis"] + #[doc = " \\see #OptixPrimitiveType"] + pub curveType: OptixPrimitiveType, + #[doc = " Number of primitives. Each primitive is a polynomial curve segment."] + pub numPrimitives: ::std::os::raw::c_uint, + #[doc = " Pointer to host array of device pointers, one per motion step. Host array size must match number of"] + #[doc = " motion keys as set in #OptixMotionOptions (or an array of size 1 if OptixMotionOptions::numKeys is set"] + #[doc = " to 1). Each per-motion-key device pointer must point to an array of floats (the vertices of the"] + #[doc = " curves)."] + pub vertexBuffers: *const CUdeviceptr, + #[doc = " Number of vertices in each buffer in vertexBuffers."] + pub numVertices: ::std::os::raw::c_uint, + #[doc = " Stride between vertices. If set to zero, vertices are assumed to be tightly"] + #[doc = " packed and stride is sizeof( float3 )."] + pub vertexStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Parallel to vertexBuffers: a device pointer per motion step, each with numVertices float values,"] + #[doc = " specifying the curve width (radius) corresponding to each vertex."] + pub widthBuffers: *const CUdeviceptr, + #[doc = " Stride between widths. If set to zero, widths are assumed to be tightly"] + #[doc = " packed and stride is sizeof( float )."] + pub widthStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Reserved for future use."] + pub normalBuffers: *const CUdeviceptr, + #[doc = " Reserved for future use."] + pub normalStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Device pointer to array of unsigned ints, one per curve segment."] + #[doc = " This buffer is required (unlike for OptixBuildInputTriangleArray)."] + #[doc = " Each index is the start of degree+1 consecutive vertices in vertexBuffers,"] + #[doc = " and corresponding widths in widthBuffers and normals in normalBuffers."] + #[doc = " These define a single segment. Size of array is numPrimitives."] + pub indexBuffer: CUdeviceptr, + #[doc = " Stride between indices. If set to zero, indices are assumed to be tightly"] + #[doc = " packed and stride is sizeof( unsigned int )."] + pub indexStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Combination of OptixGeometryFlags describing the"] + #[doc = " primitive behavior."] + pub flag: ::std::os::raw::c_uint, + #[doc = " Primitive index bias, applied in optixGetPrimitiveIndex()."] + #[doc = " Sum of primitiveIndexOffset and number of primitives must not overflow 32bits."] + pub primitiveIndexOffset: ::std::os::raw::c_uint, + #[doc = " End cap flags, see OptixCurveEndcapFlags"] + pub endcapFlags: ::std::os::raw::c_uint, +} +#[doc = " AABB inputs"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixAabb { + #[doc = "< Lower extent in X direction."] + pub minX: f32, + #[doc = "< Lower extent in Y direction."] + pub minY: f32, + #[doc = "< Lower extent in Z direction."] + pub minZ: f32, + #[doc = "< Upper extent in X direction."] + pub maxX: f32, + #[doc = "< Upper extent in Y direction."] + pub maxY: f32, + #[doc = "< Upper extent in Z direction."] + pub maxZ: f32, +} +#[doc = " Custom primitive inputs"] +#[doc = ""] +#[doc = " \\see #OptixBuildInput::customPrimitiveArray"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuildInputCustomPrimitiveArray { + #[doc = " Points to host array of device pointers to AABBs (type OptixAabb), one per motion step."] + #[doc = " Host array size must match number of motion keys as set in OptixMotionOptions (or an array of size 1"] + #[doc = " if OptixMotionOptions::numKeys is set to 1)."] + #[doc = " Each device pointer must be a multiple of OPTIX_AABB_BUFFER_BYTE_ALIGNMENT."] + pub aabbBuffers: *const CUdeviceptr, + #[doc = " Number of primitives in each buffer (i.e., per motion step) in"] + #[doc = " #OptixBuildInputCustomPrimitiveArray::aabbBuffers."] + pub numPrimitives: ::std::os::raw::c_uint, + #[doc = " Stride between AABBs (per motion key). If set to zero, the aabbs are assumed to be tightly"] + #[doc = " packed and the stride is assumed to be sizeof( OptixAabb )."] + #[doc = " If non-zero, the value must be a multiple of OPTIX_AABB_BUFFER_BYTE_ALIGNMENT."] + pub strideInBytes: ::std::os::raw::c_uint, + #[doc = " Array of flags, to specify flags per sbt record,"] + #[doc = " combinations of OptixGeometryFlags describing the"] + #[doc = " primitive behavior, size must match numSbtRecords"] + pub flags: *const ::std::os::raw::c_uint, + #[doc = " Number of sbt records available to the sbt index offset override."] + pub numSbtRecords: ::std::os::raw::c_uint, + #[doc = " Device pointer to per-primitive local sbt index offset buffer. May be NULL."] + #[doc = " Every entry must be in range [0,numSbtRecords-1]."] + #[doc = " Size needs to be the number of primitives."] + pub sbtIndexOffsetBuffer: CUdeviceptr, + #[doc = " Size of type of the sbt index offset. Needs to be 0, 1, 2 or 4 (8, 16 or 32 bit)."] + pub sbtIndexOffsetSizeInBytes: ::std::os::raw::c_uint, + #[doc = " Stride between the index offsets. If set to zero, the offsets are assumed to be tightly"] + #[doc = " packed and the stride matches the size of the type (sbtIndexOffsetSizeInBytes)."] + pub sbtIndexOffsetStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Primitive index bias, applied in optixGetPrimitiveIndex()."] + #[doc = " Sum of primitiveIndexOffset and number of primitive must not overflow 32bits."] + pub primitiveIndexOffset: ::std::os::raw::c_uint, +} +#[doc = " Instance and instance pointer inputs"] +#[doc = ""] +#[doc = " \\see #OptixBuildInput::instanceArray"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuildInputInstanceArray { + #[doc = " If OptixBuildInput::type is OPTIX_BUILD_INPUT_TYPE_INSTANCE_POINTERS instances and"] + #[doc = " aabbs should be interpreted as arrays of pointers instead of arrays of structs."] + #[doc = ""] + #[doc = " This pointer must be a multiple of OPTIX_INSTANCE_BYTE_ALIGNMENT if"] + #[doc = " OptixBuildInput::type is OPTIX_BUILD_INPUT_TYPE_INSTANCES. The array elements must"] + #[doc = " be a multiple of OPTIX_INSTANCE_BYTE_ALIGNMENT if OptixBuildInput::type is"] + #[doc = " OPTIX_BUILD_INPUT_TYPE_INSTANCE_POINTERS."] + pub instances: CUdeviceptr, + #[doc = " Number of elements in #OptixBuildInputInstanceArray::instances."] + pub numInstances: ::std::os::raw::c_uint, +} +impl OptixBuildInputType { + #[doc = " Triangle inputs. \\see #OptixBuildInputTriangleArray"] + pub const OPTIX_BUILD_INPUT_TYPE_TRIANGLES: OptixBuildInputType = OptixBuildInputType(8513); +} +impl OptixBuildInputType { + #[doc = " Custom primitive inputs. \\see #OptixBuildInputCustomPrimitiveArray"] + pub const OPTIX_BUILD_INPUT_TYPE_CUSTOM_PRIMITIVES: OptixBuildInputType = + OptixBuildInputType(8514); +} +impl OptixBuildInputType { + #[doc = " Instance inputs. \\see #OptixBuildInputInstanceArray"] + pub const OPTIX_BUILD_INPUT_TYPE_INSTANCES: OptixBuildInputType = OptixBuildInputType(8515); +} +impl OptixBuildInputType { + #[doc = " Instance pointer inputs. \\see #OptixBuildInputInstanceArray"] + pub const OPTIX_BUILD_INPUT_TYPE_INSTANCE_POINTERS: OptixBuildInputType = + OptixBuildInputType(8516); +} +impl OptixBuildInputType { + #[doc = " Curve inputs. \\see #OptixBuildInputCurveArray"] + pub const OPTIX_BUILD_INPUT_TYPE_CURVES: OptixBuildInputType = OptixBuildInputType(8517); +} +#[repr(transparent)] +#[doc = " Enum to distinguish the different build input types."] +#[doc = ""] +#[doc = " \\see #OptixBuildInput::type"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixBuildInputType(pub ::std::os::raw::c_uint); +#[doc = " Build inputs."] +#[doc = ""] +#[doc = " All of them support motion and the size of the data arrays needs to match the number of motion steps"] +#[doc = ""] +#[doc = " \\see #optixAccelComputeMemoryUsage(), #optixAccelBuild()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuildInput { + #[doc = " The type of the build input."] + pub type_: OptixBuildInputType, + pub __bindgen_anon_1: OptixBuildInput__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union OptixBuildInput__bindgen_ty_1 { + #[doc = " Triangle inputs."] + pub triangleArray: OptixBuildInputTriangleArray, + #[doc = " Curve inputs."] + pub curveArray: OptixBuildInputCurveArray, + #[doc = " Custom primitive inputs."] + pub customPrimitiveArray: OptixBuildInputCustomPrimitiveArray, + #[doc = " Instance and instance pointer inputs."] + pub instanceArray: OptixBuildInputInstanceArray, + pub pad: [::std::os::raw::c_char; 1024usize], +} +impl OptixInstanceFlags { + #[doc = " No special flag set"] + pub const OPTIX_INSTANCE_FLAG_NONE: OptixInstanceFlags = OptixInstanceFlags(0); +} +impl OptixInstanceFlags { + #[doc = " Prevent triangles from getting culled due to their orientation."] + #[doc = " Effectively ignores ray flags"] + #[doc = " OPTIX_RAY_FLAG_CULL_BACK_FACING_TRIANGLES and OPTIX_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES."] + pub const OPTIX_INSTANCE_FLAG_DISABLE_TRIANGLE_FACE_CULLING: OptixInstanceFlags = + OptixInstanceFlags(1); +} +impl OptixInstanceFlags { + #[doc = " Flip triangle orientation."] + #[doc = " This affects front/backface culling as well as the reported face in case of a hit."] + pub const OPTIX_INSTANCE_FLAG_FLIP_TRIANGLE_FACING: OptixInstanceFlags = OptixInstanceFlags(2); +} +impl OptixInstanceFlags { + #[doc = " Disable anyhit programs for all geometries of the instance."] + #[doc = " Can be overridden by OPTIX_RAY_FLAG_ENFORCE_ANYHIT."] + #[doc = " This flag is mutually exclusive with OPTIX_INSTANCE_FLAG_ENFORCE_ANYHIT."] + pub const OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT: OptixInstanceFlags = OptixInstanceFlags(4); +} +impl OptixInstanceFlags { + #[doc = " Enables anyhit programs for all geometries of the instance."] + #[doc = " Overrides OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT"] + #[doc = " Can be overridden by OPTIX_RAY_FLAG_DISABLE_ANYHIT."] + #[doc = " This flag is mutually exclusive with OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT."] + pub const OPTIX_INSTANCE_FLAG_ENFORCE_ANYHIT: OptixInstanceFlags = OptixInstanceFlags(8); +} +#[repr(transparent)] +#[doc = " Flags set on the #OptixInstance::flags."] +#[doc = ""] +#[doc = " These can be or'ed together to combine multiple flags."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixInstanceFlags(pub ::std::os::raw::c_uint); +#[doc = " Instances"] +#[doc = ""] +#[doc = " \\see #OptixBuildInputInstanceArray::instances"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixInstance { + #[doc = " affine object-to-world transformation as 3x4 matrix in row-major layout"] + pub transform: [f32; 12usize], + #[doc = " Application supplied ID. The maximal ID can be queried using OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID."] + pub instanceId: ::std::os::raw::c_uint, + #[doc = " SBT record offset. Will only be used for instances of geometry acceleration structure (GAS) objects."] + #[doc = " Needs to be set to 0 for instances of instance acceleration structure (IAS) objects. The maximal SBT offset"] + #[doc = " can be queried using OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_SBT_OFFSET."] + pub sbtOffset: ::std::os::raw::c_uint, + #[doc = " Visibility mask. If rayMask & instanceMask == 0 the instance is culled. The number of available bits can be"] + #[doc = " queried using OPTIX_DEVICE_PROPERTY_LIMIT_NUM_BITS_INSTANCE_VISIBILITY_MASK."] + pub visibilityMask: ::std::os::raw::c_uint, + #[doc = " Any combination of OptixInstanceFlags is allowed."] + pub flags: ::std::os::raw::c_uint, + #[doc = " Set with an OptixTraversableHandle."] + pub traversableHandle: OptixTraversableHandle, + #[doc = " round up to 80-byte, to ensure 16-byte alignment"] + pub pad: [::std::os::raw::c_uint; 2usize], +} +impl OptixBuildFlags { + #[doc = " No special flags set."] + pub const OPTIX_BUILD_FLAG_NONE: OptixBuildFlags = OptixBuildFlags(0); +} +impl OptixBuildFlags { + #[doc = " Allow updating the build with new vertex positions with subsequent calls to"] + #[doc = " optixAccelBuild."] + pub const OPTIX_BUILD_FLAG_ALLOW_UPDATE: OptixBuildFlags = OptixBuildFlags(1); +} +impl OptixBuildFlags { + #[doc = " Allow updating the build with new vertex positions with subsequent calls to"] + #[doc = " optixAccelBuild."] + pub const OPTIX_BUILD_FLAG_ALLOW_COMPACTION: OptixBuildFlags = OptixBuildFlags(2); +} +impl OptixBuildFlags { + #[doc = " Allow updating the build with new vertex positions with subsequent calls to"] + #[doc = " optixAccelBuild."] + pub const OPTIX_BUILD_FLAG_PREFER_FAST_TRACE: OptixBuildFlags = OptixBuildFlags(4); +} +impl OptixBuildFlags { + #[doc = " Allow updating the build with new vertex positions with subsequent calls to"] + #[doc = " optixAccelBuild."] + pub const OPTIX_BUILD_FLAG_PREFER_FAST_BUILD: OptixBuildFlags = OptixBuildFlags(8); +} +impl OptixBuildFlags { + #[doc = " Allow random access to build input vertices"] + #[doc = " See optixGetTriangleVertexData"] + #[doc = " optixGetLinearCurveVertexData"] + #[doc = " optixGetQuadraticBSplineVertexData"] + #[doc = " optixGetCubicBSplineVertexData"] + #[doc = " optixGetCatmullRomVertexData"] + pub const OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS: OptixBuildFlags = OptixBuildFlags(16); +} +impl OptixBuildFlags { + #[doc = " Allow random access to instances"] + #[doc = " See optixGetInstanceTraversableFromIAS"] + pub const OPTIX_BUILD_FLAG_ALLOW_RANDOM_INSTANCE_ACCESS: OptixBuildFlags = OptixBuildFlags(32); +} +#[repr(transparent)] +#[doc = " Builder Options"] +#[doc = ""] +#[doc = " Used for #OptixAccelBuildOptions::buildFlags. Can be or'ed together."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixBuildFlags(pub ::std::os::raw::c_uint); +impl OptixBuildOperation { + #[doc = " Perform a full build operation"] + pub const OPTIX_BUILD_OPERATION_BUILD: OptixBuildOperation = OptixBuildOperation(8545); +} +impl OptixBuildOperation { + #[doc = " Perform an update using new bounds"] + pub const OPTIX_BUILD_OPERATION_UPDATE: OptixBuildOperation = OptixBuildOperation(8546); +} +#[repr(transparent)] +#[doc = " Enum to specify the acceleration build operation."] +#[doc = ""] +#[doc = " Used in OptixAccelBuildOptions, which is then passed to optixAccelBuild and"] +#[doc = " optixAccelComputeMemoryUsage, this enum indicates whether to do a build or an update"] +#[doc = " of the acceleration structure."] +#[doc = ""] +#[doc = " Acceleration structure updates utilize the same acceleration structure, but with"] +#[doc = " updated bounds. Updates are typically much faster than builds, however, large"] +#[doc = " perturbations can degrade the quality of the acceleration structure."] +#[doc = ""] +#[doc = " \\see #optixAccelComputeMemoryUsage(), #optixAccelBuild(), #OptixAccelBuildOptions"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixBuildOperation(pub ::std::os::raw::c_uint); +impl OptixMotionFlags { + pub const OPTIX_MOTION_FLAG_NONE: OptixMotionFlags = OptixMotionFlags(0); +} +impl OptixMotionFlags { + pub const OPTIX_MOTION_FLAG_START_VANISH: OptixMotionFlags = OptixMotionFlags(1); +} +impl OptixMotionFlags { + pub const OPTIX_MOTION_FLAG_END_VANISH: OptixMotionFlags = OptixMotionFlags(2); +} +#[repr(transparent)] +#[doc = " Enum to specify motion flags."] +#[doc = ""] +#[doc = " \\see #OptixMotionOptions::flags."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixMotionFlags(pub ::std::os::raw::c_uint); +#[doc = " Motion options"] +#[doc = ""] +#[doc = " \\see #OptixAccelBuildOptions::motionOptions, #OptixMatrixMotionTransform::motionOptions,"] +#[doc = " #OptixSRTMotionTransform::motionOptions"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixMotionOptions { + #[doc = " If numKeys > 1, motion is enabled. timeBegin,"] + #[doc = " timeEnd and flags are all ignored when motion is disabled."] + pub numKeys: ::std::os::raw::c_ushort, + #[doc = " Combinations of #OptixMotionFlags"] + pub flags: ::std::os::raw::c_ushort, + #[doc = " Point in time where motion starts."] + pub timeBegin: f32, + #[doc = " Point in time where motion ends."] + pub timeEnd: f32, +} +#[doc = " Build options for acceleration structures."] +#[doc = ""] +#[doc = " \\see #optixAccelComputeMemoryUsage(), #optixAccelBuild()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixAccelBuildOptions { + #[doc = " Combinations of OptixBuildFlags"] + pub buildFlags: ::std::os::raw::c_uint, + #[doc = " If OPTIX_BUILD_OPERATION_UPDATE the output buffer is assumed to contain the result"] + #[doc = " of a full build with OPTIX_BUILD_FLAG_ALLOW_UPDATE set and using the same number of"] + #[doc = " primitives. It is updated incrementally to reflect the current position of the"] + #[doc = " primitives."] + pub operation: OptixBuildOperation, + #[doc = " Options for motion."] + pub motionOptions: OptixMotionOptions, +} +#[doc = " Struct for querying builder allocation requirements."] +#[doc = ""] +#[doc = " Once queried the sizes should be used to allocate device memory of at least these sizes."] +#[doc = ""] +#[doc = " \\see #optixAccelComputeMemoryUsage()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixAccelBufferSizes { + #[doc = " The size in bytes required for the outputBuffer parameter to optixAccelBuild when"] + #[doc = " doing a build (OPTIX_BUILD_OPERATION_BUILD)."] + pub outputSizeInBytes: usize, + #[doc = " The size in bytes required for the tempBuffer paramter to optixAccelBuild when"] + #[doc = " doing a build (OPTIX_BUILD_OPERATION_BUILD)."] + pub tempSizeInBytes: usize, + #[doc = " The size in bytes required for the tempBuffer parameter to optixAccelBuild"] + #[doc = " when doing an update (OPTIX_BUILD_OPERATION_UPDATE). This value can be different"] + #[doc = " than tempSizeInBytes used for a full build. Only non-zero if"] + #[doc = " OPTIX_BUILD_FLAG_ALLOW_UPDATE flag is set in OptixAccelBuildOptions."] + pub tempUpdateSizeInBytes: usize, +} +impl OptixAccelPropertyType { + #[doc = " Size of a compacted acceleration structure. The device pointer points to a uint64."] + pub const OPTIX_PROPERTY_TYPE_COMPACTED_SIZE: OptixAccelPropertyType = + OptixAccelPropertyType(8577); +} +impl OptixAccelPropertyType { + #[doc = " OptixAabb * numMotionSteps"] + pub const OPTIX_PROPERTY_TYPE_AABBS: OptixAccelPropertyType = OptixAccelPropertyType(8578); +} +#[repr(transparent)] +#[doc = " Properties which can be emitted during acceleration structure build."] +#[doc = ""] +#[doc = " \\see #OptixAccelEmitDesc::type."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixAccelPropertyType(pub ::std::os::raw::c_uint); +#[doc = " Specifies a type and output destination for emitted post-build properties."] +#[doc = ""] +#[doc = " \\see #optixAccelBuild()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixAccelEmitDesc { + #[doc = " Output buffer for the properties"] + pub result: CUdeviceptr, + #[doc = " Requested property"] + pub type_: OptixAccelPropertyType, +} +#[doc = " Used to store information related to relocation of acceleration structures."] +#[doc = ""] +#[doc = " \\see #optixAccelGetRelocationInfo(), #optixAccelCheckRelocationCompatibility(), #optixAccelRelocate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixAccelRelocationInfo { + #[doc = " Opaque data, used internally, should not be modified"] + pub info: [::std::os::raw::c_ulonglong; 4usize], +} +#[doc = " Static transform"] +#[doc = ""] +#[doc = " The device address of instances of this type must be a multiple of OPTIX_TRANSFORM_BYTE_ALIGNMENT."] +#[doc = ""] +#[doc = " \\see #optixConvertPointerToTraversableHandle()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixStaticTransform { + #[doc = " The traversable transformed by this transformation"] + pub child: OptixTraversableHandle, + #[doc = " Padding to make the transformations 16 byte aligned"] + pub pad: [::std::os::raw::c_uint; 2usize], + #[doc = " Affine object-to-world transformation as 3x4 matrix in row-major layout"] + pub transform: [f32; 12usize], + #[doc = " Affine world-to-object transformation as 3x4 matrix in row-major layout"] + #[doc = " Must be the inverse of the transform matrix"] + pub invTransform: [f32; 12usize], +} +#[doc = " Represents a matrix motion transformation."] +#[doc = ""] +#[doc = " The device address of instances of this type must be a multiple of OPTIX_TRANSFORM_BYTE_ALIGNMENT."] +#[doc = ""] +#[doc = " This struct, as defined here, handles only N=2 motion keys due to the fixed array length of its transform member."] +#[doc = " The following example shows how to create instances for an arbitrary number N of motion keys:"] +#[doc = ""] +#[doc = " \\code"] +#[doc = " float matrixData[N][12];"] +#[doc = " ... // setup matrixData"] +#[doc = ""] +#[doc = " size_t transformSizeInBytes = sizeof( OptixMatrixMotionTransform ) + ( N-2 ) * 12 * sizeof( float );"] +#[doc = " OptixMatrixMotionTransform* matrixMoptionTransform = (OptixMatrixMotionTransform*) malloc( transformSizeInBytes );"] +#[doc = " memset( matrixMoptionTransform, 0, transformSizeInBytes );"] +#[doc = ""] +#[doc = " ... // setup other members of matrixMoptionTransform"] +#[doc = " matrixMoptionTransform->motionOptions.numKeys/// = N;"] +#[doc = " memcpy( matrixMoptionTransform->transform, matrixData, N * 12 * sizeof( float ) );"] +#[doc = ""] +#[doc = " ... // copy matrixMoptionTransform to device memory"] +#[doc = " free( matrixMoptionTransform )"] +#[doc = " \\endcode"] +#[doc = ""] +#[doc = " \\see #optixConvertPointerToTraversableHandle()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixMatrixMotionTransform { + #[doc = " The traversable that is transformed by this transformation"] + pub child: OptixTraversableHandle, + #[doc = " The motion options for this transformation"] + pub motionOptions: OptixMotionOptions, + #[doc = " Padding to make the transformation 16 byte aligned"] + pub pad: [::std::os::raw::c_uint; 3usize], + #[doc = " Affine object-to-world transformation as 3x4 matrix in row-major layout"] + pub transform: [[f32; 12usize]; 2usize], +} +#[doc = " defines another translation that is applied after the rotation. Typically, this translation includes"] +#[doc = " the inverse translation from the matrix S to reverse the translation for the pivot point for R."] +#[doc = ""] +#[doc = " To obtain the effective transformation at time t, the elements of the components of S, R, and T will be interpolated"] +#[doc = " linearly. The components are then multiplied to obtain the combined transformation C = T * R * S. The transformation"] +#[doc = " C is the effective object-to-world transformations at time t, and C^(-1) is the effective world-to-object"] +#[doc = " transformation at time t."] +#[doc = ""] +#[doc = " \\see #OptixSRTMotionTransform::srtData, #optixConvertPointerToTraversableHandle()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixSRTData { + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub sx: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub a: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub b: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub pvx: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub sy: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub c: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub pvy: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub sz: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub pvz: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub qx: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub qy: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub qz: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub qw: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub tx: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub ty: f32, + #[doc = " \\name Parameters describing the SRT transformation"] + #[doc = " @{"] + pub tz: f32, +} +#[doc = " Represents an SRT motion transformation."] +#[doc = ""] +#[doc = " The device address of instances of this type must be a multiple of OPTIX_TRANSFORM_BYTE_ALIGNMENT."] +#[doc = ""] +#[doc = " This struct, as defined here, handles only N=2 motion keys due to the fixed array length of its srtData member."] +#[doc = " The following example shows how to create instances for an arbitrary number N of motion keys:"] +#[doc = ""] +#[doc = " \\code"] +#[doc = " OptixSRTData srtData[N];"] +#[doc = " ... // setup srtData"] +#[doc = ""] +#[doc = " size_t transformSizeInBytes = sizeof( OptixSRTMotionTransform ) + ( N-2 ) * sizeof( OptixSRTData );"] +#[doc = " OptixSRTMotionTransform* srtMotionTransform = (OptixSRTMotionTransform*) malloc( transformSizeInBytes );"] +#[doc = " memset( srtMotionTransform, 0, transformSizeInBytes );"] +#[doc = ""] +#[doc = " ... // setup other members of srtMotionTransform"] +#[doc = " srtMotionTransform->motionOptions.numKeys = N;"] +#[doc = " memcpy( srtMotionTransform->srtData, srtData, N * sizeof( OptixSRTData ) );"] +#[doc = ""] +#[doc = " ... // copy srtMotionTransform to device memory"] +#[doc = " free( srtMotionTransform )"] +#[doc = " \\endcode"] +#[doc = ""] +#[doc = " \\see #optixConvertPointerToTraversableHandle()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixSRTMotionTransform { + #[doc = " The traversable transformed by this transformation"] + pub child: OptixTraversableHandle, + #[doc = " The motion options for this transformation"] + pub motionOptions: OptixMotionOptions, + #[doc = " Padding to make the SRT data 16 byte aligned"] + pub pad: [::std::os::raw::c_uint; 3usize], + #[doc = " The actual SRT data describing the transformation"] + pub srtData: [OptixSRTData; 2usize], +} +impl OptixTraversableType { + #[doc = " Static transforms. \\see #OptixStaticTransform"] + pub const OPTIX_TRAVERSABLE_TYPE_STATIC_TRANSFORM: OptixTraversableType = + OptixTraversableType(8641); +} +impl OptixTraversableType { + #[doc = " Matrix motion transform. \\see #OptixMatrixMotionTransform"] + pub const OPTIX_TRAVERSABLE_TYPE_MATRIX_MOTION_TRANSFORM: OptixTraversableType = + OptixTraversableType(8642); +} +impl OptixTraversableType { + #[doc = " SRT motion transform. \\see #OptixSRTMotionTransform"] + pub const OPTIX_TRAVERSABLE_TYPE_SRT_MOTION_TRANSFORM: OptixTraversableType = + OptixTraversableType(8643); +} +#[repr(transparent)] +#[doc = " Traversable Handles"] +#[doc = ""] +#[doc = " \\see #optixConvertPointerToTraversableHandle()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixTraversableType(pub ::std::os::raw::c_uint); +impl OptixPixelFormat { + #[doc = "< two halfs, XY"] + pub const OPTIX_PIXEL_FORMAT_HALF2: OptixPixelFormat = OptixPixelFormat(8711); +} +impl OptixPixelFormat { + #[doc = "< three halfs, RGB"] + pub const OPTIX_PIXEL_FORMAT_HALF3: OptixPixelFormat = OptixPixelFormat(8705); +} +impl OptixPixelFormat { + #[doc = "< four halfs, RGBA"] + pub const OPTIX_PIXEL_FORMAT_HALF4: OptixPixelFormat = OptixPixelFormat(8706); +} +impl OptixPixelFormat { + #[doc = "< two floats, XY"] + pub const OPTIX_PIXEL_FORMAT_FLOAT2: OptixPixelFormat = OptixPixelFormat(8712); +} +impl OptixPixelFormat { + #[doc = "< three floats, RGB"] + pub const OPTIX_PIXEL_FORMAT_FLOAT3: OptixPixelFormat = OptixPixelFormat(8707); +} +impl OptixPixelFormat { + #[doc = "< four floats, RGBA"] + pub const OPTIX_PIXEL_FORMAT_FLOAT4: OptixPixelFormat = OptixPixelFormat(8708); +} +impl OptixPixelFormat { + #[doc = "< three unsigned chars, RGB"] + pub const OPTIX_PIXEL_FORMAT_UCHAR3: OptixPixelFormat = OptixPixelFormat(8709); +} +impl OptixPixelFormat { + #[doc = "< four unsigned chars, RGBA"] + pub const OPTIX_PIXEL_FORMAT_UCHAR4: OptixPixelFormat = OptixPixelFormat(8710); +} +#[repr(transparent)] +#[doc = " Pixel formats used by the denoiser."] +#[doc = ""] +#[doc = " \\see #OptixImage2D::format"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixPixelFormat(pub ::std::os::raw::c_uint); +#[doc = " Image descriptor used by the denoiser."] +#[doc = ""] +#[doc = " \\see #optixDenoiserInvoke(), #optixDenoiserComputeIntensity()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixImage2D { + #[doc = " Pointer to the actual pixel data."] + pub data: CUdeviceptr, + #[doc = " Width of the image (in pixels)"] + pub width: ::std::os::raw::c_uint, + #[doc = " Height of the image (in pixels)"] + pub height: ::std::os::raw::c_uint, + #[doc = " Stride between subsequent rows of the image (in bytes)."] + pub rowStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Stride between subsequent pixels of the image (in bytes)."] + #[doc = " For now, only 0 or the value that corresponds to a dense packing of pixels (no gaps) is supported."] + pub pixelStrideInBytes: ::std::os::raw::c_uint, + #[doc = " Pixel format."] + pub format: OptixPixelFormat, +} +impl OptixDenoiserModelKind { + #[doc = " Use the built-in model appropriate for low dynamic range input."] + pub const OPTIX_DENOISER_MODEL_KIND_LDR: OptixDenoiserModelKind = OptixDenoiserModelKind(8994); +} +impl OptixDenoiserModelKind { + #[doc = " Use the built-in model appropriate for high dynamic range input."] + pub const OPTIX_DENOISER_MODEL_KIND_HDR: OptixDenoiserModelKind = OptixDenoiserModelKind(8995); +} +impl OptixDenoiserModelKind { + #[doc = " Use the built-in model appropriate for high dynamic range input and support for AOVs"] + pub const OPTIX_DENOISER_MODEL_KIND_AOV: OptixDenoiserModelKind = OptixDenoiserModelKind(8996); +} +impl OptixDenoiserModelKind { + #[doc = " Use the built-in model appropriate for high dynamic range input, temporally stable"] + pub const OPTIX_DENOISER_MODEL_KIND_TEMPORAL: OptixDenoiserModelKind = + OptixDenoiserModelKind(8997); +} +impl OptixDenoiserModelKind { + #[doc = " Use the built-in model appropriate for high dynamic range input and support for AOVs, temporally stable"] + pub const OPTIX_DENOISER_MODEL_KIND_TEMPORAL_AOV: OptixDenoiserModelKind = + OptixDenoiserModelKind(8998); +} +#[repr(transparent)] +#[doc = " Model kind used by the denoiser."] +#[doc = ""] +#[doc = " \\see #optixDenoiserCreate"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixDenoiserModelKind(pub ::std::os::raw::c_uint); +#[doc = " Options used by the denoiser"] +#[doc = ""] +#[doc = " \\see #optixDenoiserCreate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiserOptions { + pub guideAlbedo: ::std::os::raw::c_uint, + pub guideNormal: ::std::os::raw::c_uint, +} +#[doc = " Guide layer for the denoiser"] +#[doc = ""] +#[doc = " \\see #optixDenoiserInvoke()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiserGuideLayer { + pub albedo: OptixImage2D, + pub normal: OptixImage2D, + pub flow: OptixImage2D, +} +#[doc = " Input/Output layers for the denoiser"] +#[doc = ""] +#[doc = " \\see #optixDenoiserInvoke()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiserLayer { + pub input: OptixImage2D, + pub previousOutput: OptixImage2D, + pub output: OptixImage2D, +} +#[doc = " Various parameters used by the denoiser"] +#[doc = ""] +#[doc = " \\see #optixDenoiserInvoke()"] +#[doc = " \\see #optixDenoiserComputeIntensity()"] +#[doc = " \\see #optixDenoiserComputeAverageColor()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiserParams { + #[doc = " alpha denoise mode:"] + #[doc = " 0 Copy alpha (if present) from input layer, no denoising."] + #[doc = " 1 Denoise alpha separately. In AOV model kinds, treat alpha like an AOV."] + #[doc = " 2 In AOV model kinds, full denoise pass with alpha (slower than mode 1)."] + pub denoiseAlpha: ::std::os::raw::c_uint, + #[doc = " average log intensity of input image (default null pointer). points to a single float."] + #[doc = " with the default (null pointer) denoised results will not be optimal for very dark or"] + #[doc = " bright input images."] + pub hdrIntensity: CUdeviceptr, + #[doc = " blend factor."] + #[doc = " If set to 0 the output is 100% of the denoised input. If set to 1, the output is 100% of"] + #[doc = " the unmodified input. Values between 0 and 1 will linearly interpolate between the denoised"] + #[doc = " and unmodified input."] + pub blendFactor: f32, + #[doc = " this parameter is used when the OPTIX_DENOISER_MODEL_KIND_AOV model kind is set."] + #[doc = " average log color of input image, separate for RGB channels (default null pointer)."] + #[doc = " points to three floats. with the default (null pointer) denoised results will not be"] + #[doc = " optimal."] + pub hdrAverageColor: CUdeviceptr, +} +#[doc = " Various sizes related to the denoiser."] +#[doc = ""] +#[doc = " \\see #optixDenoiserComputeMemoryResources()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixDenoiserSizes { + pub stateSizeInBytes: usize, + pub withOverlapScratchSizeInBytes: usize, + pub withoutOverlapScratchSizeInBytes: usize, + pub overlapWindowSizeInPixels: ::std::os::raw::c_uint, +} +impl OptixRayFlags { + #[doc = " No change from the behavior configured for the individual AS."] + pub const OPTIX_RAY_FLAG_NONE: OptixRayFlags = OptixRayFlags(0); +} +impl OptixRayFlags { + #[doc = " Disables anyhit programs for the ray."] + #[doc = " Overrides OPTIX_INSTANCE_FLAG_ENFORCE_ANYHIT."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_ENFORCE_ANYHIT,"] + #[doc = " OPTIX_RAY_FLAG_CULL_DISABLED_ANYHIT, OPTIX_RAY_FLAG_CULL_ENFORCED_ANYHIT."] + pub const OPTIX_RAY_FLAG_DISABLE_ANYHIT: OptixRayFlags = OptixRayFlags(1); +} +impl OptixRayFlags { + #[doc = " Forces anyhit program execution for the ray."] + #[doc = " Overrides OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT as well as OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_DISABLE_ANYHIT,"] + #[doc = " OPTIX_RAY_FLAG_CULL_DISABLED_ANYHIT, OPTIX_RAY_FLAG_CULL_ENFORCED_ANYHIT."] + pub const OPTIX_RAY_FLAG_ENFORCE_ANYHIT: OptixRayFlags = OptixRayFlags(2); +} +impl OptixRayFlags { + #[doc = " Terminates the ray after the first hit and executes"] + #[doc = " the closesthit program of that hit."] + pub const OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT: OptixRayFlags = OptixRayFlags(4); +} +impl OptixRayFlags { + #[doc = " Disables closesthit programs for the ray, but still executes miss program in case of a miss."] + pub const OPTIX_RAY_FLAG_DISABLE_CLOSESTHIT: OptixRayFlags = OptixRayFlags(8); +} +impl OptixRayFlags { + #[doc = " Do not intersect triangle back faces"] + #[doc = " (respects a possible face change due to instance flag"] + #[doc = " OPTIX_INSTANCE_FLAG_FLIP_TRIANGLE_FACING)."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES."] + pub const OPTIX_RAY_FLAG_CULL_BACK_FACING_TRIANGLES: OptixRayFlags = OptixRayFlags(16); +} +impl OptixRayFlags { + #[doc = " Do not intersect triangle front faces"] + #[doc = " (respects a possible face change due to instance flag"] + #[doc = " OPTIX_INSTANCE_FLAG_FLIP_TRIANGLE_FACING)."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_CULL_BACK_FACING_TRIANGLES."] + pub const OPTIX_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES: OptixRayFlags = OptixRayFlags(32); +} +impl OptixRayFlags { + #[doc = " Do not intersect geometry which disables anyhit programs"] + #[doc = " (due to setting geometry flag OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT or"] + #[doc = " instance flag OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT)."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_CULL_ENFORCED_ANYHIT,"] + #[doc = " OPTIX_RAY_FLAG_ENFORCE_ANYHIT, OPTIX_RAY_FLAG_DISABLE_ANYHIT."] + pub const OPTIX_RAY_FLAG_CULL_DISABLED_ANYHIT: OptixRayFlags = OptixRayFlags(64); +} +impl OptixRayFlags { + #[doc = " Do not intersect geometry which have an enabled anyhit program"] + #[doc = " (due to not setting geometry flag OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT or"] + #[doc = " setting instance flag OPTIX_INSTANCE_FLAG_ENFORCE_ANYHIT)."] + #[doc = " This flag is mutually exclusive with OPTIX_RAY_FLAG_CULL_DISABLED_ANYHIT,"] + #[doc = " OPTIX_RAY_FLAG_ENFORCE_ANYHIT, OPTIX_RAY_FLAG_DISABLE_ANYHIT."] + pub const OPTIX_RAY_FLAG_CULL_ENFORCED_ANYHIT: OptixRayFlags = OptixRayFlags(128); +} +#[repr(transparent)] +#[doc = " Ray flags passed to the device function #optixTrace(). These affect the behavior of"] +#[doc = " traversal per invocation."] +#[doc = ""] +#[doc = " \\see #optixTrace()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixRayFlags(pub ::std::os::raw::c_uint); +impl OptixTransformType { + #[doc = "< Not a transformation"] + pub const OPTIX_TRANSFORM_TYPE_NONE: OptixTransformType = OptixTransformType(0); +} +impl OptixTransformType { + #[doc = "< \\see #OptixStaticTransform"] + pub const OPTIX_TRANSFORM_TYPE_STATIC_TRANSFORM: OptixTransformType = OptixTransformType(1); +} +impl OptixTransformType { + #[doc = "< \\see #OptixMatrixMotionTransform"] + pub const OPTIX_TRANSFORM_TYPE_MATRIX_MOTION_TRANSFORM: OptixTransformType = + OptixTransformType(2); +} +impl OptixTransformType { + #[doc = "< \\see #OptixSRTMotionTransform"] + pub const OPTIX_TRANSFORM_TYPE_SRT_MOTION_TRANSFORM: OptixTransformType = OptixTransformType(3); +} +impl OptixTransformType { + #[doc = "< \\see #OptixInstance"] + pub const OPTIX_TRANSFORM_TYPE_INSTANCE: OptixTransformType = OptixTransformType(4); +} +#[repr(transparent)] +#[doc = " Transform"] +#[doc = ""] +#[doc = " OptixTransformType is used by the device function #optixGetTransformTypeFromHandle() to"] +#[doc = " determine the type of the OptixTraversableHandle returned from"] +#[doc = " optixGetTransformListHandle()."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixTransformType(pub ::std::os::raw::c_uint); +impl OptixTraversableGraphFlags { + #[doc = " Used to signal that any traversable graphs is valid."] + #[doc = " This flag is mutually exclusive with all other flags."] + pub const OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_ANY: OptixTraversableGraphFlags = + OptixTraversableGraphFlags(0); +} +impl OptixTraversableGraphFlags { + #[doc = " Used to signal that a traversable graph of a single Geometry Acceleration"] + #[doc = " Structure (GAS) without any transforms is valid. This flag may be combined with"] + #[doc = " other flags except for OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_ANY."] + pub const OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS: OptixTraversableGraphFlags = + OptixTraversableGraphFlags(1); +} +impl OptixTraversableGraphFlags { + #[doc = " Used to signal that a traversable graph of a single Instance Acceleration"] + #[doc = " Structure (IAS) directly connected to Geometry Acceleration Structure (GAS)"] + #[doc = " traversables without transform traversables in between is valid. This flag may"] + #[doc = " be combined with other flags except for OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_ANY."] + pub const OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING: + OptixTraversableGraphFlags = OptixTraversableGraphFlags(2); +} +#[repr(transparent)] +#[doc = " Specifies the set of valid traversable graphs that may be"] +#[doc = " passed to invocation of #optixTrace(). Flags may be bitwise combined."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixTraversableGraphFlags(pub ::std::os::raw::c_uint); +impl OptixCompileOptimizationLevel { + #[doc = " Default is to run all optimizations"] + pub const OPTIX_COMPILE_OPTIMIZATION_DEFAULT: OptixCompileOptimizationLevel = + OptixCompileOptimizationLevel(0); +} +impl OptixCompileOptimizationLevel { + #[doc = " No optimizations"] + pub const OPTIX_COMPILE_OPTIMIZATION_LEVEL_0: OptixCompileOptimizationLevel = + OptixCompileOptimizationLevel(9024); +} +impl OptixCompileOptimizationLevel { + #[doc = " Some optimizations"] + pub const OPTIX_COMPILE_OPTIMIZATION_LEVEL_1: OptixCompileOptimizationLevel = + OptixCompileOptimizationLevel(9025); +} +impl OptixCompileOptimizationLevel { + #[doc = " Most optimizations"] + pub const OPTIX_COMPILE_OPTIMIZATION_LEVEL_2: OptixCompileOptimizationLevel = + OptixCompileOptimizationLevel(9026); +} +impl OptixCompileOptimizationLevel { + #[doc = " All optimizations"] + pub const OPTIX_COMPILE_OPTIMIZATION_LEVEL_3: OptixCompileOptimizationLevel = + OptixCompileOptimizationLevel(9027); +} +#[repr(transparent)] +#[doc = " Optimization levels"] +#[doc = ""] +#[doc = " \\see #OptixModuleCompileOptions::optLevel"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixCompileOptimizationLevel(pub ::std::os::raw::c_uint); +impl OptixCompileDebugLevel { + #[doc = " Default currently is minimal"] + pub const OPTIX_COMPILE_DEBUG_LEVEL_DEFAULT: OptixCompileDebugLevel = OptixCompileDebugLevel(0); +} +impl OptixCompileDebugLevel { + #[doc = " No debug information"] + pub const OPTIX_COMPILE_DEBUG_LEVEL_NONE: OptixCompileDebugLevel = OptixCompileDebugLevel(9040); +} +impl OptixCompileDebugLevel { + #[doc = " Generate information that does not impact performance."] + #[doc = " Note this replaces OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO."] + pub const OPTIX_COMPILE_DEBUG_LEVEL_MINIMAL: OptixCompileDebugLevel = + OptixCompileDebugLevel(9041); +} +impl OptixCompileDebugLevel { + #[doc = " Generate some debug information with slight performance cost"] + pub const OPTIX_COMPILE_DEBUG_LEVEL_MODERATE: OptixCompileDebugLevel = + OptixCompileDebugLevel(9043); +} +impl OptixCompileDebugLevel { + #[doc = " Generate full debug information"] + pub const OPTIX_COMPILE_DEBUG_LEVEL_FULL: OptixCompileDebugLevel = OptixCompileDebugLevel(9042); +} +#[repr(transparent)] +#[doc = " Debug levels"] +#[doc = ""] +#[doc = " \\see #OptixModuleCompileOptions::debugLevel"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixCompileDebugLevel(pub ::std::os::raw::c_uint); +impl OptixModuleCompileState { + #[doc = " No OptixTask objects have started"] + pub const OPTIX_MODULE_COMPILE_STATE_NOT_STARTED: OptixModuleCompileState = + OptixModuleCompileState(9056); +} +impl OptixModuleCompileState { + #[doc = " Started, but not all OptixTask objects have completed. No detected failures."] + pub const OPTIX_MODULE_COMPILE_STATE_STARTED: OptixModuleCompileState = + OptixModuleCompileState(9057); +} +impl OptixModuleCompileState { + #[doc = " Not all OptixTask objects have completed, but at least one has failed."] + pub const OPTIX_MODULE_COMPILE_STATE_IMPENDING_FAILURE: OptixModuleCompileState = + OptixModuleCompileState(9058); +} +impl OptixModuleCompileState { + #[doc = " All OptixTask objects have completed, and at least one has failed"] + pub const OPTIX_MODULE_COMPILE_STATE_FAILED: OptixModuleCompileState = + OptixModuleCompileState(9059); +} +impl OptixModuleCompileState { + #[doc = " All OptixTask objects have completed. The OptixModule is ready to be used."] + pub const OPTIX_MODULE_COMPILE_STATE_COMPLETED: OptixModuleCompileState = + OptixModuleCompileState(9060); +} +#[repr(transparent)] +#[doc = " Module compilation state."] +#[doc = ""] +#[doc = " \\see #optixModuleGetCompilationState(), #optixModuleCreateFromPTXWithTasks()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixModuleCompileState(pub ::std::os::raw::c_uint); +#[doc = " Struct for specifying specializations for pipelineParams as specified in"] +#[doc = " OptixPipelineCompileOptions::pipelineLaunchParamsVariableName."] +#[doc = ""] +#[doc = " The bound values are supposed to represent a constant value in the"] +#[doc = " pipelineParams. OptiX will attempt to locate all loads from the pipelineParams and"] +#[doc = " correlate them to the appropriate bound value, but there are cases where OptiX cannot"] +#[doc = " safely or reliably do this. For example if the pointer to the pipelineParams is passed"] +#[doc = " as an argument to a non-inline function or the offset of the load to the"] +#[doc = " pipelineParams cannot be statically determined (e.g. accessed in a loop). No module"] +#[doc = " should rely on the value being specialized in order to work correctly. The values in"] +#[doc = " the pipelineParams specified on optixLaunch should match the bound value. If"] +#[doc = " validation mode is enabled on the context, OptiX will verify that the bound values"] +#[doc = " specified matches the values in pipelineParams specified to optixLaunch."] +#[doc = ""] +#[doc = " These values are compiled in to the module as constants. Once the constants are"] +#[doc = " inserted into the code, an optimization pass will be run that will attempt to"] +#[doc = " propagate the consants and remove unreachable code."] +#[doc = ""] +#[doc = " If caching is enabled, changes in these values will result in newly compiled modules."] +#[doc = ""] +#[doc = " The pipelineParamOffset and sizeInBytes must be within the bounds of the"] +#[doc = " pipelineParams variable. OPTIX_ERROR_INVALID_VALUE will be returned from"] +#[doc = " optixModuleCreateFromPTX otherwise."] +#[doc = ""] +#[doc = " If more than one bound value overlaps or the size of a bound value is equal to 0,"] +#[doc = " an OPTIX_ERROR_INVALID_VALUE will be returned from optixModuleCreateFromPTX."] +#[doc = ""] +#[doc = " The same set of bound values do not need to be used for all modules in a pipeline, but"] +#[doc = " overlapping values between modules must have the same value."] +#[doc = " OPTIX_ERROR_INVALID_VALUE will be returned from optixPipelineCreate otherwise."] +#[doc = ""] +#[doc = " \\see #OptixModuleCompileOptions"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixModuleCompileBoundValueEntry { + pub pipelineParamOffsetInBytes: usize, + pub sizeInBytes: usize, + pub boundValuePtr: *const ::std::os::raw::c_void, + pub annotation: *const ::std::os::raw::c_char, +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_DEFAULT: OptixPayloadTypeID = OptixPayloadTypeID(0); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_0: OptixPayloadTypeID = OptixPayloadTypeID(1); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_1: OptixPayloadTypeID = OptixPayloadTypeID(2); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_2: OptixPayloadTypeID = OptixPayloadTypeID(4); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_3: OptixPayloadTypeID = OptixPayloadTypeID(8); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_4: OptixPayloadTypeID = OptixPayloadTypeID(16); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_5: OptixPayloadTypeID = OptixPayloadTypeID(32); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_6: OptixPayloadTypeID = OptixPayloadTypeID(64); +} +impl OptixPayloadTypeID { + pub const OPTIX_PAYLOAD_TYPE_ID_7: OptixPayloadTypeID = OptixPayloadTypeID(128); +} +#[repr(transparent)] +#[doc = " Payload type identifiers."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixPayloadTypeID(pub ::std::os::raw::c_uint); +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_TRACE_CALLER_NONE: OptixPayloadSemantics = + OptixPayloadSemantics(0); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_TRACE_CALLER_READ: OptixPayloadSemantics = + OptixPayloadSemantics(1); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_TRACE_CALLER_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(2); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_TRACE_CALLER_READ_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(3); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_CH_NONE: OptixPayloadSemantics = OptixPayloadSemantics(0); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_CH_READ: OptixPayloadSemantics = OptixPayloadSemantics(4); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_CH_WRITE: OptixPayloadSemantics = OptixPayloadSemantics(8); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_CH_READ_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(12); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_MS_NONE: OptixPayloadSemantics = OptixPayloadSemantics(0); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_MS_READ: OptixPayloadSemantics = OptixPayloadSemantics(16); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_MS_WRITE: OptixPayloadSemantics = OptixPayloadSemantics(32); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_MS_READ_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(48); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_AH_NONE: OptixPayloadSemantics = OptixPayloadSemantics(0); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_AH_READ: OptixPayloadSemantics = OptixPayloadSemantics(64); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_AH_WRITE: OptixPayloadSemantics = OptixPayloadSemantics(128); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_AH_READ_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(192); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_IS_NONE: OptixPayloadSemantics = OptixPayloadSemantics(0); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_IS_READ: OptixPayloadSemantics = OptixPayloadSemantics(256); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_IS_WRITE: OptixPayloadSemantics = OptixPayloadSemantics(512); +} +impl OptixPayloadSemantics { + pub const OPTIX_PAYLOAD_SEMANTICS_IS_READ_WRITE: OptixPayloadSemantics = + OptixPayloadSemantics(768); +} +#[repr(transparent)] +#[doc = " Semantic flags for a single payload word."] +#[doc = ""] +#[doc = " Used to specify the semantics of a payload word per shader type."] +#[doc = " \"read\": Shader of this type may read the payload word."] +#[doc = " \"write\": Shader of this type may write the payload word."] +#[doc = ""] +#[doc = " \"trace_caller_write\": Shaders may consume the value of the payload word passed to optixTrace by the caller."] +#[doc = " \"trace_caller_read\": The caller to optixTrace may read the payload word after the call to optixTrace."] +#[doc = ""] +#[doc = " Semantics can be bitwise combined."] +#[doc = " Combining \"read\" and \"write\" is equivalent to specifying \"read_write\"."] +#[doc = " A payload needs to be writable by the caller or at least one shader type."] +#[doc = " A payload needs to be readable by the caller or at least one shader type after a being writable."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixPayloadSemantics(pub ::std::os::raw::c_uint); +#[doc = " Specifies a single payload type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixPayloadType { + #[doc = " The number of 32b words the payload of this type holds"] + pub numPayloadValues: ::std::os::raw::c_uint, + #[doc = " Points to host array of payload word semantics, size must match numPayloadValues"] + pub payloadSemantics: *const ::std::os::raw::c_uint, +} +#[doc = " Compilation options for module"] +#[doc = ""] +#[doc = " \\see #optixModuleCreateFromPTX()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixModuleCompileOptions { + #[doc = " Maximum number of registers allowed when compiling to SASS."] + #[doc = " Set to 0 for no explicit limit. May vary within a pipeline."] + pub maxRegisterCount: ::std::os::raw::c_int, + #[doc = " Optimization level. May vary within a pipeline."] + pub optLevel: OptixCompileOptimizationLevel, + #[doc = " Generate debug information."] + pub debugLevel: OptixCompileDebugLevel, + #[doc = " Ingored if numBoundValues is set to 0"] + pub boundValues: *const OptixModuleCompileBoundValueEntry, + #[doc = " set to 0 if unused"] + pub numBoundValues: ::std::os::raw::c_uint, + #[doc = " The number of different payload types available for compilation."] + #[doc = " Must be zero if OptixPipelineCompileOptions::numPayloadValues is not zero."] + pub numPayloadTypes: ::std::os::raw::c_uint, + #[doc = " Points to host array of payload type definitions, size must match numPayloadTypes"] + pub payloadTypes: *mut OptixPayloadType, +} +impl OptixProgramGroupKind { + #[doc = " Program group containing a raygen (RG) program"] + #[doc = " \\see #OptixProgramGroupSingleModule, #OptixProgramGroupDesc::raygen"] + pub const OPTIX_PROGRAM_GROUP_KIND_RAYGEN: OptixProgramGroupKind = OptixProgramGroupKind(9249); +} +impl OptixProgramGroupKind { + #[doc = " Program group containing a miss (MS) program"] + #[doc = " \\see #OptixProgramGroupSingleModule, #OptixProgramGroupDesc::miss"] + pub const OPTIX_PROGRAM_GROUP_KIND_MISS: OptixProgramGroupKind = OptixProgramGroupKind(9250); +} +impl OptixProgramGroupKind { + #[doc = " Program group containing an exception (EX) program"] + #[doc = " \\see OptixProgramGroupHitgroup, #OptixProgramGroupDesc::exception"] + pub const OPTIX_PROGRAM_GROUP_KIND_EXCEPTION: OptixProgramGroupKind = + OptixProgramGroupKind(9251); +} +impl OptixProgramGroupKind { + #[doc = " Program group containing an intersection (IS), any hit (AH), and/or closest hit (CH) program"] + #[doc = " \\see #OptixProgramGroupSingleModule, #OptixProgramGroupDesc::hitgroup"] + pub const OPTIX_PROGRAM_GROUP_KIND_HITGROUP: OptixProgramGroupKind = + OptixProgramGroupKind(9252); +} +impl OptixProgramGroupKind { + #[doc = " Program group containing a direct (DC) or continuation (CC) callable program"] + #[doc = " \\see OptixProgramGroupCallables, #OptixProgramGroupDesc::callables"] + pub const OPTIX_PROGRAM_GROUP_KIND_CALLABLES: OptixProgramGroupKind = + OptixProgramGroupKind(9253); +} +#[repr(transparent)] +#[doc = " Distinguishes different kinds of program groups."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixProgramGroupKind(pub ::std::os::raw::c_uint); +impl OptixProgramGroupFlags { + #[doc = " Currently there are no flags"] + pub const OPTIX_PROGRAM_GROUP_FLAGS_NONE: OptixProgramGroupFlags = OptixProgramGroupFlags(0); +} +#[repr(transparent)] +#[doc = " Flags for program groups"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixProgramGroupFlags(pub ::std::os::raw::c_uint); +#[doc = " Program group representing a single module."] +#[doc = ""] +#[doc = " Used for raygen, miss, and exception programs. In case of raygen and exception programs, module and entry"] +#[doc = " function name need to be valid. For miss programs, module and entry function name might both be \\c nullptr."] +#[doc = ""] +#[doc = " \\see #OptixProgramGroupDesc::raygen, #OptixProgramGroupDesc::miss, #OptixProgramGroupDesc::exception"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroupSingleModule { + #[doc = " Module holding single program."] + pub module: OptixModule, + #[doc = " Entry function name of the single program."] + pub entryFunctionName: *const ::std::os::raw::c_char, +} +#[doc = " Program group representing the hitgroup."] +#[doc = ""] +#[doc = " For each of the three program types, module and entry function name might both be \\c nullptr."] +#[doc = ""] +#[doc = " \\see #OptixProgramGroupDesc::hitgroup"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroupHitgroup { + #[doc = " Module holding the closest hit (CH) program."] + pub moduleCH: OptixModule, + #[doc = " Entry function name of the closest hit (CH) program."] + pub entryFunctionNameCH: *const ::std::os::raw::c_char, + #[doc = " Module holding the any hit (AH) program."] + pub moduleAH: OptixModule, + #[doc = " Entry function name of the any hit (AH) program."] + pub entryFunctionNameAH: *const ::std::os::raw::c_char, + #[doc = " Module holding the intersection (Is) program."] + pub moduleIS: OptixModule, + #[doc = " Entry function name of the intersection (IS) program."] + pub entryFunctionNameIS: *const ::std::os::raw::c_char, +} +#[doc = " Program group representing callables."] +#[doc = ""] +#[doc = " Module and entry function name need to be valid for at least one of the two callables."] +#[doc = ""] +#[doc = " \\see ##OptixProgramGroupDesc::callables"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroupCallables { + #[doc = " Module holding the direct callable (DC) program."] + pub moduleDC: OptixModule, + #[doc = " Entry function name of the direct callable (DC) program."] + pub entryFunctionNameDC: *const ::std::os::raw::c_char, + #[doc = " Module holding the continuation callable (CC) program."] + pub moduleCC: OptixModule, + #[doc = " Entry function name of the continuation callable (CC) program."] + pub entryFunctionNameCC: *const ::std::os::raw::c_char, +} +#[doc = " Descriptor for program groups."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroupDesc { + #[doc = " The kind of program group."] + pub kind: OptixProgramGroupKind, + #[doc = " See #OptixProgramGroupFlags"] + pub flags: ::std::os::raw::c_uint, + pub __bindgen_anon_1: OptixProgramGroupDesc__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union OptixProgramGroupDesc__bindgen_ty_1 { + #[doc = " \\see #OPTIX_PROGRAM_GROUP_KIND_RAYGEN"] + pub raygen: OptixProgramGroupSingleModule, + #[doc = " \\see #OPTIX_PROGRAM_GROUP_KIND_MISS"] + pub miss: OptixProgramGroupSingleModule, + #[doc = " \\see #OPTIX_PROGRAM_GROUP_KIND_EXCEPTION"] + pub exception: OptixProgramGroupSingleModule, + #[doc = " \\see #OPTIX_PROGRAM_GROUP_KIND_CALLABLES"] + pub callables: OptixProgramGroupCallables, + #[doc = " \\see #OPTIX_PROGRAM_GROUP_KIND_HITGROUP"] + pub hitgroup: OptixProgramGroupHitgroup, +} +#[doc = " Program group options"] +#[doc = ""] +#[doc = " \\see #optixProgramGroupCreate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixProgramGroupOptions { + #[doc = " Specifies the payload type of this program group."] + #[doc = " All programs in the group must support the payload type"] + #[doc = " (Program support for a type is specified by calling"] + #[doc = " \\see #optixSetPayloadTypes or otherwise all types specified in"] + #[doc = " \\see #OptixModuleCompileOptions are supported)."] + #[doc = " If a program is not available for the requested payload type,"] + #[doc = " optixProgramGroupCreate returns OPTIX_ERROR_PAYLOAD_TYPE_MISMATCH."] + #[doc = " If the payloadType is left zero, a unique type is deduced."] + #[doc = " The payload type can be uniquely deduced if there is exactly one payload type"] + #[doc = " for which all programs in the group are available."] + #[doc = " If the payload type could not be deduced uniquely"] + #[doc = " optixProgramGroupCreate returns OPTIX_ERROR_PAYLOAD_TYPE_RESOLUTION_FAILED."] + pub payloadType: *mut OptixPayloadType, +} +impl OptixExceptionCodes { + #[doc = " Stack overflow of the continuation stack."] + #[doc = " no exception details."] + pub const OPTIX_EXCEPTION_CODE_STACK_OVERFLOW: OptixExceptionCodes = OptixExceptionCodes(-1); +} +impl OptixExceptionCodes { + #[doc = " The trace depth is exceeded."] + #[doc = " no exception details."] + pub const OPTIX_EXCEPTION_CODE_TRACE_DEPTH_EXCEEDED: OptixExceptionCodes = + OptixExceptionCodes(-2); +} +impl OptixExceptionCodes { + #[doc = " The traversal depth is exceeded."] + #[doc = " Exception details:"] + #[doc = " optixGetTransformListSize()"] + #[doc = " optixGetTransformListHandle()"] + pub const OPTIX_EXCEPTION_CODE_TRAVERSAL_DEPTH_EXCEEDED: OptixExceptionCodes = + OptixExceptionCodes(-3); +} +impl OptixExceptionCodes { + #[doc = " Traversal encountered an invalid traversable type."] + #[doc = " Exception details:"] + #[doc = " optixGetTransformListSize()"] + #[doc = " optixGetTransformListHandle()"] + #[doc = " optixGetExceptionInvalidTraversable()"] + pub const OPTIX_EXCEPTION_CODE_TRAVERSAL_INVALID_TRAVERSABLE: OptixExceptionCodes = + OptixExceptionCodes(-5); +} +impl OptixExceptionCodes { + #[doc = " The miss SBT record index is out of bounds"] + #[doc = " A miss SBT record index is valid within the range [0, OptixShaderBindingTable::missRecordCount) (See optixLaunch)"] + #[doc = " Exception details:"] + #[doc = " optixGetExceptionInvalidSbtOffset()"] + pub const OPTIX_EXCEPTION_CODE_TRAVERSAL_INVALID_MISS_SBT: OptixExceptionCodes = + OptixExceptionCodes(-6); +} +impl OptixExceptionCodes { + #[doc = " sbt-geometry-acceleration-structure-index (See optixGetSbtGASIndex),"] + #[doc = " sbt-stride-from-trace-call and sbt-offset-from-trace-call (See optixTrace)"] + #[doc = ""] + #[doc = " sbt-index = sbt-instance-offset + (sbt-geometry-acceleration-structure-index * sbt-stride-from-trace-call) + sbt-offset-from-trace-call"] + #[doc = ""] + #[doc = " Exception details:"] + #[doc = " optixGetTransformListSize()"] + #[doc = " optixGetTransformListHandle()"] + #[doc = " optixGetExceptionInvalidSbtOffset()"] + #[doc = " optixGetSbtGASIndex()"] + pub const OPTIX_EXCEPTION_CODE_TRAVERSAL_INVALID_HIT_SBT: OptixExceptionCodes = + OptixExceptionCodes(-7); +} +impl OptixExceptionCodes { + #[doc = " The shader encountered an unsupported primitive type (See OptixPipelineCompileOptions::usesPrimitiveTypeFlags)."] + #[doc = " no exception details."] + pub const OPTIX_EXCEPTION_CODE_UNSUPPORTED_PRIMITIVE_TYPE: OptixExceptionCodes = + OptixExceptionCodes(-8); +} +impl OptixExceptionCodes { + #[doc = " The shader encountered a call to optixTrace with at least"] + #[doc = " one of the float arguments being inf or nan."] + #[doc = " Exception details:"] + #[doc = " optixGetExceptionInvalidRay()"] + pub const OPTIX_EXCEPTION_CODE_INVALID_RAY: OptixExceptionCodes = OptixExceptionCodes(-9); +} +impl OptixExceptionCodes { + #[doc = " The shader encountered a call to either optixDirectCall or optixCallableCall"] + #[doc = " where the argument count does not match the parameter count of the callable"] + #[doc = " program which is called."] + #[doc = " Exception details:"] + #[doc = " optixGetExceptionParameterMismatch"] + pub const OPTIX_EXCEPTION_CODE_CALLABLE_PARAMETER_MISMATCH: OptixExceptionCodes = + OptixExceptionCodes(-10); +} +impl OptixExceptionCodes { + #[doc = " The invoked builtin IS does not match the current GAS"] + pub const OPTIX_EXCEPTION_CODE_BUILTIN_IS_MISMATCH: OptixExceptionCodes = + OptixExceptionCodes(-11); +} +impl OptixExceptionCodes { + #[doc = " Tried to call a callable program using an SBT offset that is larger"] + #[doc = " than the number of passed in callable SBT records."] + #[doc = " Exception details:"] + #[doc = " optixGetExceptionInvalidSbtOffset()"] + pub const OPTIX_EXCEPTION_CODE_CALLABLE_INVALID_SBT: OptixExceptionCodes = + OptixExceptionCodes(-12); +} +impl OptixExceptionCodes { + #[doc = " Tried to call a direct callable using an SBT offset of a record that"] + #[doc = " was built from a program group that did not include a direct callable."] + pub const OPTIX_EXCEPTION_CODE_CALLABLE_NO_DC_SBT_RECORD: OptixExceptionCodes = + OptixExceptionCodes(-13); +} +impl OptixExceptionCodes { + #[doc = " Tried to call a continuation callable using an SBT offset of a record"] + #[doc = " that was built from a program group that did not include a continuation callable."] + pub const OPTIX_EXCEPTION_CODE_CALLABLE_NO_CC_SBT_RECORD: OptixExceptionCodes = + OptixExceptionCodes(-14); +} +impl OptixExceptionCodes { + #[doc = " Tried to directly traverse a single gas while single gas traversable graphs are not enabled"] + #[doc = " (see OptixTraversableGraphFlags::OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS)."] + #[doc = " Exception details:"] + #[doc = " optixGetTransformListSize()"] + #[doc = " optixGetTransformListHandle()"] + #[doc = " optixGetExceptionInvalidTraversable()"] + pub const OPTIX_EXCEPTION_CODE_UNSUPPORTED_SINGLE_LEVEL_GAS: OptixExceptionCodes = + OptixExceptionCodes(-15); +} +impl OptixExceptionCodes { + #[doc = " argument passed to an optix call is"] + #[doc = " not within an acceptable range of values."] + pub const OPTIX_EXCEPTION_CODE_INVALID_VALUE_ARGUMENT_0: OptixExceptionCodes = + OptixExceptionCodes(-16); +} +impl OptixExceptionCodes { + #[doc = " argument passed to an optix call is"] + #[doc = " not within an acceptable range of values."] + pub const OPTIX_EXCEPTION_CODE_INVALID_VALUE_ARGUMENT_1: OptixExceptionCodes = + OptixExceptionCodes(-17); +} +impl OptixExceptionCodes { + #[doc = " argument passed to an optix call is"] + #[doc = " not within an acceptable range of values."] + pub const OPTIX_EXCEPTION_CODE_INVALID_VALUE_ARGUMENT_2: OptixExceptionCodes = + OptixExceptionCodes(-18); +} +impl OptixExceptionCodes { + #[doc = " Tried to access data on an AS without random data access support (See OptixBuildFlags)."] + pub const OPTIX_EXCEPTION_CODE_UNSUPPORTED_DATA_ACCESS: OptixExceptionCodes = + OptixExceptionCodes(-32); +} +impl OptixExceptionCodes { + #[doc = " The program payload type doesn't match the trace payload type."] + pub const OPTIX_EXCEPTION_CODE_PAYLOAD_TYPE_MISMATCH: OptixExceptionCodes = + OptixExceptionCodes(-33); +} +#[repr(transparent)] +#[doc = " The following values are used to indicate which exception was thrown."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixExceptionCodes(pub ::std::os::raw::c_int); +impl OptixExceptionFlags { + #[doc = " No exception are enabled."] + pub const OPTIX_EXCEPTION_FLAG_NONE: OptixExceptionFlags = OptixExceptionFlags(0); +} +impl OptixExceptionFlags { + #[doc = " Enables exceptions check related to the continuation stack."] + pub const OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW: OptixExceptionFlags = OptixExceptionFlags(1); +} +impl OptixExceptionFlags { + #[doc = " Enables exceptions check related to trace depth."] + pub const OPTIX_EXCEPTION_FLAG_TRACE_DEPTH: OptixExceptionFlags = OptixExceptionFlags(2); +} +impl OptixExceptionFlags { + #[doc = " Enables user exceptions via optixThrowException(). This flag must be specified for all modules in a pipeline"] + #[doc = " if any module calls optixThrowException()."] + pub const OPTIX_EXCEPTION_FLAG_USER: OptixExceptionFlags = OptixExceptionFlags(4); +} +impl OptixExceptionFlags { + #[doc = " Enables various exceptions check related to traversal."] + pub const OPTIX_EXCEPTION_FLAG_DEBUG: OptixExceptionFlags = OptixExceptionFlags(8); +} +#[repr(transparent)] +#[doc = " Exception flags."] +#[doc = ""] +#[doc = " \\see #OptixPipelineCompileOptions::exceptionFlags, #OptixExceptionCodes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixExceptionFlags(pub ::std::os::raw::c_uint); +#[doc = " Compilation options for all modules of a pipeline."] +#[doc = ""] +#[doc = " Similar to #OptixModuleCompileOptions, but these options here need to be equal for all modules of a pipeline."] +#[doc = ""] +#[doc = " \\see #optixModuleCreateFromPTX(), #optixPipelineCreate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixPipelineCompileOptions { + #[doc = " Boolean value indicating whether motion blur could be used"] + pub usesMotionBlur: ::std::os::raw::c_int, + #[doc = " Traversable graph bitfield. See OptixTraversableGraphFlags"] + pub traversableGraphFlags: ::std::os::raw::c_uint, + #[doc = " How much storage, in 32b words, to make available for the payload, [0..32]"] + #[doc = " Must be zero if numPayloadTypes is not zero."] + pub numPayloadValues: ::std::os::raw::c_int, + #[doc = " How much storage, in 32b words, to make available for the attributes. The"] + #[doc = " minimum number is 2. Values below that will automatically be changed to 2. [2..8]"] + pub numAttributeValues: ::std::os::raw::c_int, + #[doc = " A bitmask of OptixExceptionFlags indicating which exceptions are enabled."] + pub exceptionFlags: ::std::os::raw::c_uint, + #[doc = " The name of the pipeline parameter variable. If 0, no pipeline parameter"] + #[doc = " will be available. This will be ignored if the launch param variable was"] + #[doc = " optimized out or was not found in the modules linked to the pipeline."] + pub pipelineLaunchParamsVariableName: *const ::std::os::raw::c_char, + #[doc = " Bit field enabling primitive types. See OptixPrimitiveTypeFlags."] + #[doc = " Setting to zero corresponds to enabling OPTIX_PRIMITIVE_TYPE_FLAGS_CUSTOM and OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE."] + pub usesPrimitiveTypeFlags: ::std::os::raw::c_uint, +} +#[doc = " Link options for a pipeline"] +#[doc = ""] +#[doc = " \\see #optixPipelineCreate()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixPipelineLinkOptions { + #[doc = " Maximum trace recursion depth. 0 means a ray generation program can be"] + #[doc = " launched, but can't trace any rays. The maximum allowed value is 31."] + pub maxTraceDepth: ::std::os::raw::c_uint, + #[doc = " Generate debug information."] + pub debugLevel: OptixCompileDebugLevel, +} +#[doc = " Describes the shader binding table (SBT)"] +#[doc = ""] +#[doc = " \\see #optixLaunch()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixShaderBindingTable { + #[doc = " Device address of the SBT record of the ray gen program to start launch at. The address must be a multiple of"] + #[doc = " OPTIX_SBT_RECORD_ALIGNMENT."] + pub raygenRecord: CUdeviceptr, + #[doc = " Device address of the SBT record of the exception program. The address must be a multiple of"] + #[doc = " OPTIX_SBT_RECORD_ALIGNMENT."] + pub exceptionRecord: CUdeviceptr, + #[doc = " Arrays of SBT records for miss programs. The base address and the stride must be a multiple of"] + #[doc = " OPTIX_SBT_RECORD_ALIGNMENT."] + #[doc = " @{"] + pub missRecordBase: CUdeviceptr, + pub missRecordStrideInBytes: ::std::os::raw::c_uint, + pub missRecordCount: ::std::os::raw::c_uint, + #[doc = " Arrays of SBT records for hit groups. The base address and the stride must be a multiple of"] + #[doc = " OPTIX_SBT_RECORD_ALIGNMENT."] + #[doc = " @{"] + pub hitgroupRecordBase: CUdeviceptr, + pub hitgroupRecordStrideInBytes: ::std::os::raw::c_uint, + pub hitgroupRecordCount: ::std::os::raw::c_uint, + #[doc = " Arrays of SBT records for callable programs. If the base address is not null, the stride and count must not be"] + #[doc = " zero. If the base address is null, then the count needs to zero. The base address and the stride must be a"] + #[doc = " multiple of OPTIX_SBT_RECORD_ALIGNMENT."] + #[doc = " @{"] + pub callablesRecordBase: CUdeviceptr, + pub callablesRecordStrideInBytes: ::std::os::raw::c_uint, + pub callablesRecordCount: ::std::os::raw::c_uint, +} +#[doc = " Describes the stack size requirements of a program group."] +#[doc = ""] +#[doc = " \\see optixProgramGroupGetStackSize()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixStackSizes { + #[doc = " Continuation stack size of RG programs in bytes"] + pub cssRG: ::std::os::raw::c_uint, + #[doc = " Continuation stack size of MS programs in bytes"] + pub cssMS: ::std::os::raw::c_uint, + #[doc = " Continuation stack size of CH programs in bytes"] + pub cssCH: ::std::os::raw::c_uint, + #[doc = " Continuation stack size of AH programs in bytes"] + pub cssAH: ::std::os::raw::c_uint, + #[doc = " Continuation stack size of IS programs in bytes"] + pub cssIS: ::std::os::raw::c_uint, + #[doc = " Continuation stack size of CC programs in bytes"] + pub cssCC: ::std::os::raw::c_uint, + #[doc = " Direct stack size of DC programs in bytes"] + pub dssDC: ::std::os::raw::c_uint, +} +impl OptixQueryFunctionTableOptions { + #[doc = " Placeholder (there are no options yet)"] + pub const OPTIX_QUERY_FUNCTION_TABLE_OPTION_DUMMY: OptixQueryFunctionTableOptions = + OptixQueryFunctionTableOptions(0); +} +#[repr(transparent)] +#[doc = " Options that can be passed to \\c optixQueryFunctionTable()"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OptixQueryFunctionTableOptions(pub ::std::os::raw::c_uint); +#[doc = " Type of the function \\c optixQueryFunctionTable()"] +pub type OptixQueryFunctionTable_t = ::std::option::Option< + unsafe extern "C" fn( + abiId: ::std::os::raw::c_int, + numOptions: ::std::os::raw::c_uint, + arg1: *mut OptixQueryFunctionTableOptions, + arg2: *mut *const ::std::os::raw::c_void, + functionTable: *mut ::std::os::raw::c_void, + sizeOfTable: usize, + ) -> OptixResult, +>; +#[doc = " Specifies the options for retrieving an intersection program for a built-in primitive type."] +#[doc = " The primitive type must not be OPTIX_PRIMITIVE_TYPE_CUSTOM."] +#[doc = ""] +#[doc = " \\see #optixBuiltinISModuleGet()"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixBuiltinISOptions { + pub builtinISModuleType: OptixPrimitiveType, + #[doc = " Boolean value indicating whether vertex motion blur is used (but not motion transform blur)."] + pub usesMotionBlur: ::std::os::raw::c_int, + #[doc = " Build flags, see OptixBuildFlags."] + pub buildFlags: ::std::os::raw::c_uint, + #[doc = " End cap properties of curves, see OptixCurveEndcapFlags, 0 for non-curve types."] + pub curveEndcapFlags: ::std::os::raw::c_uint, +} +#[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 CUstream_st { + _unused: [u8; 0], +} +pub type CUstream = *mut CUstream_st; +extern "C" { + #[doc = " Returns a string containing the name of an error code in the enum."] + #[doc = ""] + #[doc = " Output is a string representation of the enum. For example \"OPTIX_SUCCESS\" for"] + #[doc = " OPTIX_SUCCESS and \"OPTIX_ERROR_INVALID_VALUE\" for OPTIX_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " If the error code is not recognized, \"Unrecognized OptixResult code\" is returned."] + #[doc = ""] + #[doc = " \\param[in] result OptixResult enum to generate string name for"] + #[doc = ""] + #[doc = " \\see #optixGetErrorString"] + pub fn optixGetErrorName(result: OptixResult) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " Returns the description string for an error code."] + #[doc = ""] + #[doc = " Output is a string description of the enum. For example \"Success\" for"] + #[doc = " OPTIX_SUCCESS and \"Invalid value\" for OPTIX_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " If the error code is not recognized, \"Unrecognized OptixResult code\" is returned."] + #[doc = ""] + #[doc = " \\param[in] result OptixResult enum to generate string description for"] + #[doc = ""] + #[doc = " \\see #optixGetErrorName"] + pub fn optixGetErrorString(result: OptixResult) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " Create a device context associated with the CUDA context specified with 'fromContext'."] + #[doc = ""] + #[doc = " If zero is specified for 'fromContext', OptiX will use the current CUDA context. The"] + #[doc = " CUDA context should be initialized before calling optixDeviceContextCreate."] + #[doc = ""] + #[doc = " \\param[in] fromContext"] + #[doc = " \\param[in] options"] + #[doc = " \\param[out] context"] + #[doc = " \\return"] + #[doc = " - OPTIX_ERROR_CUDA_NOT_INITIALIZED"] + #[doc = " If using zero for 'fromContext' and CUDA has not been initialized yet on the calling"] + #[doc = " thread."] + #[doc = " - OPTIX_ERROR_CUDA_ERROR"] + #[doc = " CUDA operation failed."] + #[doc = " - OPTIX_ERROR_HOST_OUT_OF_MEMORY"] + #[doc = " Heap allocation failed."] + #[doc = " - OPTIX_ERROR_INTERNAL_ERROR"] + #[doc = " Internal error"] + pub fn optixDeviceContextCreate( + fromContext: CUcontext, + options: *const OptixDeviceContextOptions, + context: *mut OptixDeviceContext, + ) -> OptixResult; +} +extern "C" { + #[doc = " Destroys all CPU and GPU state associated with the device."] + #[doc = ""] + #[doc = " It will attempt to block on CUDA streams that have launch work outstanding."] + #[doc = ""] + #[doc = " Any API objects, such as OptixModule and OptixPipeline, not already destroyed will be"] + #[doc = " destroyed."] + #[doc = ""] + #[doc = " Thread safety: A device context must not be destroyed while it is still in use by concurrent API calls in other threads."] + pub fn optixDeviceContextDestroy(context: OptixDeviceContext) -> OptixResult; +} +extern "C" { + #[doc = " Query properties of a device context."] + #[doc = ""] + #[doc = " \\param[in] context the device context to query the property for"] + #[doc = " \\param[in] property the property to query"] + #[doc = " \\param[out] value pointer to the returned"] + #[doc = " \\param[in] sizeInBytes size of output"] + pub fn optixDeviceContextGetProperty( + context: OptixDeviceContext, + property: OptixDeviceProperty, + value: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " Sets the current log callback method."] + #[doc = ""] + #[doc = " See #OptixLogCallback for more details."] + #[doc = ""] + #[doc = " Thread safety: It is guaranteed that the callback itself (callbackFunction and callbackData) are updated atomically."] + #[doc = " It is not guaranteed that the callback itself (callbackFunction and callbackData) and the callbackLevel are updated"] + #[doc = " atomically. It is unspecified when concurrent API calls using the same context start to make use of the new"] + #[doc = " callback method."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[in] callbackFunction the callback function to call"] + #[doc = " \\param[in] callbackData pointer to data passed to callback function while invoking it"] + #[doc = " \\param[in] callbackLevel callback level"] + pub fn optixDeviceContextSetLogCallback( + context: OptixDeviceContext, + callbackFunction: OptixLogCallback, + callbackData: *mut ::std::os::raw::c_void, + callbackLevel: ::std::os::raw::c_uint, + ) -> OptixResult; +} +extern "C" { + #[doc = " Enables or disables the disk cache."] + #[doc = ""] + #[doc = " If caching was previously disabled, enabling it will attempt to initialize"] + #[doc = " the disk cache database using the currently configured cache location. An"] + #[doc = " error will be returned if initialization fails."] + #[doc = ""] + #[doc = " Note that no in-memory cache is used, so no caching behavior will be observed if the disk cache"] + #[doc = " is disabled."] + #[doc = ""] + #[doc = " The cache can be disabled by setting the environment variable OPTIX_CACHE_MAXSIZE=0."] + #[doc = " The environment variable takes precedence over this setting."] + #[doc = " See #optixDeviceContextSetCacheDatabaseSizes for additional information."] + #[doc = ""] + #[doc = " Note that the disk cache can be disabled by the environment variable, but it cannot be enabled"] + #[doc = " via the environment if it is disabled via the API."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[in] enabled 1 to enabled, 0 to disable"] + pub fn optixDeviceContextSetCacheEnabled( + context: OptixDeviceContext, + enabled: ::std::os::raw::c_int, + ) -> OptixResult; +} +extern "C" { + #[doc = " Sets the location of the disk cache."] + #[doc = ""] + #[doc = " The location is specified by a directory. This directory should not be used for other purposes"] + #[doc = " and will be created if it does not exist. An error will be returned if is not possible to"] + #[doc = " create the disk cache at the specified location for any reason (e.g., the path is invalid or"] + #[doc = " the directory is not writable). Caching will be disabled if the disk cache cannot be"] + #[doc = " initialized in the new location. If caching is disabled, no error will be returned until caching"] + #[doc = " is enabled. If the disk cache is located on a network file share, behavior is undefined."] + #[doc = ""] + #[doc = " The location of the disk cache can be overridden with the environment variable OPTIX_CACHE_PATH."] + #[doc = " The environment variable takes precedence over this setting."] + #[doc = ""] + #[doc = " The default location depends on the operating system:"] + #[doc = " - Windows: %LOCALAPPDATA%\\\\NVIDIA\\\\OptixCache"] + #[doc = " - Linux: /var/tmp/OptixCache_\\ (or /tmp/OptixCache_\\ if the first choice is not usable),"] + #[doc = " the underscore and username suffix are omitted if the username cannot be obtained"] + #[doc = " - MacOS X: /Library/Application Support/NVIDIA/OptixCache"] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[in] location directory of disk cache"] + pub fn optixDeviceContextSetCacheLocation( + context: OptixDeviceContext, + location: *const ::std::os::raw::c_char, + ) -> OptixResult; +} +extern "C" { + #[doc = " Sets the low and high water marks for disk cache garbage collection."] + #[doc = ""] + #[doc = " Garbage collection is triggered when a new entry is written to the cache and"] + #[doc = " the current cache data size plus the size of the cache entry that is about"] + #[doc = " to be inserted exceeds the high water mark. Garbage collection proceeds until"] + #[doc = " the size reaches the low water mark. Garbage collection will always free enough"] + #[doc = " space to insert the new entry without exceeding the low water mark. Setting"] + #[doc = " either limit to zero will disable garbage collection. An error will be returned"] + #[doc = " if both limits are non-zero and the high water mark is smaller than the low water mark."] + #[doc = ""] + #[doc = " Note that garbage collection is performed only on writes to the disk cache. No garbage"] + #[doc = " collection is triggered on disk cache initialization or immediately when calling this function,"] + #[doc = " but on subsequent inserting of data into the database."] + #[doc = ""] + #[doc = " If the size of a compiled module exceeds the value configured for the high water"] + #[doc = " mark and garbage collection is enabled, the module will not be added to the cache"] + #[doc = " and a warning will be added to the log."] + #[doc = ""] + #[doc = " The high water mark can be overridden with the environment variable OPTIX_CACHE_MAXSIZE."] + #[doc = " The environment variable takes precedence over the function parameters. The low water mark"] + #[doc = " will be set to half the value of OPTIX_CACHE_MAXSIZE. Setting OPTIX_CACHE_MAXSIZE to 0 will"] + #[doc = " disable the disk cache, but will not alter the contents of the cache. Negative and non-integer"] + #[doc = " values will be ignored."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[in] lowWaterMark the low water mark"] + #[doc = " \\param[in] highWaterMark the high water mark"] + pub fn optixDeviceContextSetCacheDatabaseSizes( + context: OptixDeviceContext, + lowWaterMark: usize, + highWaterMark: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " Indicates whether the disk cache is enabled or disabled."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[out] enabled 1 if enabled, 0 if disabled"] + pub fn optixDeviceContextGetCacheEnabled( + context: OptixDeviceContext, + enabled: *mut ::std::os::raw::c_int, + ) -> OptixResult; +} +extern "C" { + #[doc = " Returns the location of the disk cache. If the cache has been disabled by setting the environment"] + #[doc = " variable OPTIX_CACHE_MAXSIZE=0, this function will return an empy string."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[out] location directory of disk cache, null terminated if locationSize > 0"] + #[doc = " \\param[in] locationSize locationSize"] + pub fn optixDeviceContextGetCacheLocation( + context: OptixDeviceContext, + location: *mut ::std::os::raw::c_char, + locationSize: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " Returns the low and high water marks for disk cache garbage collection. If the cache has been disabled by"] + #[doc = " setting the environment variable OPTIX_CACHE_MAXSIZE=0, this function will return 0 for the low and high"] + #[doc = " water marks."] + #[doc = ""] + #[doc = " \\param[in] context the device context"] + #[doc = " \\param[out] lowWaterMark the low water mark"] + #[doc = " \\param[out] highWaterMark the high water mark"] + pub fn optixDeviceContextGetCacheDatabaseSizes( + context: OptixDeviceContext, + lowWaterMark: *mut usize, + highWaterMark: *mut usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " logString is an optional buffer that contains compiler feedback and errors. This"] + #[doc = " information is also passed to the context logger (if enabled), however it may be"] + #[doc = " difficult to correlate output to the logger to specific API invocations when using"] + #[doc = " multiple threads. The output to logString will only contain feedback for this specific"] + #[doc = " invocation of this API call."] + #[doc = ""] + #[doc = " logStringSize as input should be a pointer to the number of bytes backing logString."] + #[doc = " Upon return it contains the length of the log message (including the null terminator)"] + #[doc = " which may be greater than the input value. In this case, the log message will be"] + #[doc = " truncated to fit into logString."] + #[doc = ""] + #[doc = " If logString or logStringSize are NULL, no output is written to logString. If"] + #[doc = " logStringSize points to a value that is zero, no output is written. This does not"] + #[doc = " affect output to the context logger if enabled."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] pipelineCompileOptions"] + #[doc = " \\param[in] pipelineLinkOptions"] + #[doc = " \\param[in] programGroups array of ProgramGroup objects"] + #[doc = " \\param[in] numProgramGroups number of ProgramGroup objects"] + #[doc = " \\param[out] logString Information will be written to this string. If logStringSize > 0 logString will be null terminated."] + #[doc = " \\param[in,out] logStringSize"] + #[doc = " \\param[out] pipeline"] + pub fn optixPipelineCreate( + context: OptixDeviceContext, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + pipelineLinkOptions: *const OptixPipelineLinkOptions, + programGroups: *const OptixProgramGroup, + numProgramGroups: ::std::os::raw::c_uint, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + pipeline: *mut OptixPipeline, + ) -> OptixResult; +} +extern "C" { + #[doc = " Thread safety: A pipeline must not be destroyed while it is still in use by concurrent API calls in other threads."] + pub fn optixPipelineDestroy(pipeline: OptixPipeline) -> OptixResult; +} +extern "C" { + #[doc = " Sets the stack sizes for a pipeline."] + #[doc = ""] + #[doc = " Users are encouraged to see the programming guide and the implementations of the helper functions"] + #[doc = " to understand how to construct the stack sizes based on their particular needs."] + #[doc = ""] + #[doc = " If this method is not used, an internal default implementation is used. The default implementation is correct (but"] + #[doc = " not necessarily optimal) as long as the maximum depth of call trees of CC and DC programs is at most 2 and no motion transforms are used."] + #[doc = ""] + #[doc = " The maxTraversableGraphDepth responds to the maximal number of traversables visited when calling trace."] + #[doc = " Every acceleration structure and motion transform count as one level of traversal."] + #[doc = " E.g., for a simple IAS (instance acceleration structure) -> GAS (geometry acceleration structure)"] + #[doc = " traversal graph, the maxTraversableGraphDepth is two."] + #[doc = " For IAS -> MT (motion transform) -> GAS, the maxTraversableGraphDepth is three."] + #[doc = " Note that it does not matter whether a IAS or GAS has motion or not, it always counts as one."] + #[doc = " Launching optix with exceptions turned on (see #OPTIX_EXCEPTION_FLAG_TRACE_DEPTH) will throw an exception"] + #[doc = " if the specified maxTraversableGraphDepth is too small."] + #[doc = ""] + #[doc = " \\param[in] pipeline The pipeline to configure the stack size for."] + #[doc = " \\param[in] directCallableStackSizeFromTraversal The direct stack size requirement for direct callables invoked from IS or AH."] + #[doc = " \\param[in] directCallableStackSizeFromState The direct stack size requirement for direct callables invoked from RG, MS, or CH."] + #[doc = " \\param[in] continuationStackSize The continuation stack requirement."] + #[doc = " \\param[in] maxTraversableGraphDepth The maximum depth of a traversable graph passed to trace."] + pub fn optixPipelineSetStackSize( + pipeline: OptixPipeline, + directCallableStackSizeFromTraversal: ::std::os::raw::c_uint, + directCallableStackSizeFromState: ::std::os::raw::c_uint, + continuationStackSize: ::std::os::raw::c_uint, + maxTraversableGraphDepth: ::std::os::raw::c_uint, + ) -> OptixResult; +} +extern "C" { + #[doc = " logString is an optional buffer that contains compiler feedback and errors. This"] + #[doc = " information is also passed to the context logger (if enabled), however it may be"] + #[doc = " difficult to correlate output to the logger to specific API invocations when using"] + #[doc = " multiple threads. The output to logString will only contain feedback for this specific"] + #[doc = " invocation of this API call."] + #[doc = ""] + #[doc = " logStringSize as input should be a pointer to the number of bytes backing logString."] + #[doc = " Upon return it contains the length of the log message (including the null terminator)"] + #[doc = " which may be greater than the input value. In this case, the log message will be"] + #[doc = " truncated to fit into logString."] + #[doc = ""] + #[doc = " If logString or logStringSize are NULL, no output is written to logString. If"] + #[doc = " logStringSize points to a value that is zero, no output is written. This does not"] + #[doc = " affect output to the context logger if enabled."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] moduleCompileOptions"] + #[doc = " \\param[in] pipelineCompileOptions All modules in a pipeline need to use the same values for the pipeline compile options."] + #[doc = " \\param[in] PTX Pointer to the PTX input string."] + #[doc = " \\param[in] PTXsize Parsing proceeds up to PTXsize characters, or the first NUL byte, whichever occurs first."] + #[doc = " \\param[out] logString Information will be written to this string. If logStringSize > 0 logString will be null terminated."] + #[doc = " \\param[in,out] logStringSize"] + #[doc = " \\param[out] module"] + #[doc = ""] + #[doc = " \\return OPTIX_ERROR_INVALID_VALUE - context is 0, moduleCompileOptions is 0, pipelineCompileOptions is 0, PTX is 0, module is 0."] + pub fn optixModuleCreateFromPTX( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + PTX: *const ::std::os::raw::c_char, + PTXsize: usize, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + module: *mut OptixModule, + ) -> OptixResult; +} +extern "C" { + #[doc = " All OptixTask objects associated with a given OptixModule will be cleaned up when"] + #[doc = " #optixModuleDestroy() is called regardless of whether the compilation was successful"] + #[doc = " or not. If the compilation state is OPTIX_MODULE_COMPILE_STATE_IMPENDIND_FAILURE, any"] + #[doc = " unstarted OptixTask objects do not need to be executed though there is no harm doing"] + #[doc = " so."] + #[doc = ""] + #[doc = " \\see #optixModuleCreateFromPTX"] + pub fn optixModuleCreateFromPTXWithTasks( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + PTX: *const ::std::os::raw::c_char, + PTXsize: usize, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + module: *mut OptixModule, + firstTask: *mut OptixTask, + ) -> OptixResult; +} +extern "C" { + #[doc = " When creating a module with tasks, the current state of the module can be queried"] + #[doc = " using this function."] + #[doc = ""] + #[doc = " Thread safety: Safe to call from any thread until optixModuleDestroy is called."] + #[doc = ""] + #[doc = " \\see #optixModuleCreateFromPTXWithTasks"] + pub fn optixModuleGetCompilationState( + module: OptixModule, + state: *mut OptixModuleCompileState, + ) -> OptixResult; +} +extern "C" { + #[doc = " Call for OptixModule objects created with optixModuleCreateFromPTX and optixModuleDeserialize."] + #[doc = ""] + #[doc = " Modules must not be destroyed while they are still used by any program group."] + #[doc = ""] + #[doc = " Thread safety: A module must not be destroyed while it is still in use by concurrent API calls in other threads."] + pub fn optixModuleDestroy(module: OptixModule) -> OptixResult; +} +extern "C" { + #[doc = " Returns a module containing the intersection program for the built-in primitive type specified"] + #[doc = " by the builtinISOptions. This module must be used as the moduleIS for the OptixProgramGroupHitgroup"] + #[doc = " in any SBT record for that primitive type. (The entryFunctionNameIS should be null.)"] + pub fn optixBuiltinISModuleGet( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + builtinISOptions: *const OptixBuiltinISOptions, + builtinModule: *mut OptixModule, + ) -> OptixResult; +} +extern "C" { + #[doc = " Each OptixTask should be executed with #optixTaskExecute(). If additional parallel"] + #[doc = " work is found, new OptixTask objects will be returned in additionalTasks along with"] + #[doc = " the number of additional tasks in numAdditionalTasksCreated. The parameter"] + #[doc = " additionalTasks should point to a user allocated array of minimum size"] + #[doc = " maxNumAdditionalTasks. OptiX can generate upto maxNumAdditionalTasks additional tasks."] + #[doc = ""] + #[doc = " Each task can be executed in parallel and in any order."] + #[doc = ""] + #[doc = " Thread safety: Safe to call from any thread until #optixModuleDestroy() is called for"] + #[doc = " any associated task."] + #[doc = ""] + #[doc = " \\see #optixModuleCreateFromPTXWithTasks"] + #[doc = ""] + #[doc = " \\param[in] task the OptixTask to execute"] + #[doc = " \\param[in] additionalTasks pointer to array of OptixTask objects to be filled in"] + #[doc = " \\param[in] maxNumAdditionalTasks maximum number of additional OptixTask objects"] + #[doc = " \\param[out] numAdditionalTasksCreated number of OptixTask objects created by OptiX and written into #additionalTasks"] + pub fn optixTaskExecute( + task: OptixTask, + additionalTasks: *mut OptixTask, + maxNumAdditionalTasks: ::std::os::raw::c_uint, + numAdditionalTasksCreated: *mut ::std::os::raw::c_uint, + ) -> OptixResult; +} +extern "C" { + #[doc = " Returns the stack sizes for the given program group."] + #[doc = ""] + #[doc = " \\param[in] programGroup the program group"] + #[doc = " \\param[out] stackSizes the corresponding stack sizes"] + pub fn optixProgramGroupGetStackSize( + programGroup: OptixProgramGroup, + stackSizes: *mut OptixStackSizes, + ) -> OptixResult; +} +extern "C" { + #[doc = " logString is an optional buffer that contains compiler feedback and errors. This"] + #[doc = " information is also passed to the context logger (if enabled), however it may be"] + #[doc = " difficult to correlate output to the logger to specific API invocations when using"] + #[doc = " multiple threads. The output to logString will only contain feedback for this specific"] + #[doc = " invocation of this API call."] + #[doc = ""] + #[doc = " logStringSize as input should be a pointer to the number of bytes backing logString."] + #[doc = " Upon return it contains the length of the log message (including the null terminator)"] + #[doc = " which may be greater than the input value. In this case, the log message will be"] + #[doc = " truncated to fit into logString."] + #[doc = ""] + #[doc = " If logString or logStringSize are NULL, no output is written to logString. If"] + #[doc = " logStringSize points to a value that is zero, no output is written. This does not"] + #[doc = " affect output to the context logger if enabled."] + #[doc = ""] + #[doc = " Creates numProgramGroups OptiXProgramGroup objects from the specified"] + #[doc = " OptixProgramGroupDesc array. The size of the arrays must match."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] programDescriptions N * OptixProgramGroupDesc"] + #[doc = " \\param[in] numProgramGroups N"] + #[doc = " \\param[in] options"] + #[doc = " \\param[out] logString Information will be written to this string. If logStringSize > 0 logString will be null terminated."] + #[doc = " \\param[in,out] logStringSize"] + #[doc = " \\param[out] programGroups"] + pub fn optixProgramGroupCreate( + context: OptixDeviceContext, + programDescriptions: *const OptixProgramGroupDesc, + numProgramGroups: ::std::os::raw::c_uint, + options: *const OptixProgramGroupOptions, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + programGroups: *mut OptixProgramGroup, + ) -> OptixResult; +} +extern "C" { + #[doc = " Thread safety: A program group must not be destroyed while it is still in use by concurrent API calls in other threads."] + pub fn optixProgramGroupDestroy(programGroup: OptixProgramGroup) -> OptixResult; +} +extern "C" { + #[doc = " Where the magic happens."] + #[doc = ""] + #[doc = " The stream and pipeline must belong to the same device context. Multiple launches"] + #[doc = " may be issues in parallel from multiple threads to different streams."] + #[doc = ""] + #[doc = " pipelineParamsSize number of bytes are copied from the device memory pointed to by"] + #[doc = " pipelineParams before launch. It is an error if pipelineParamsSize is greater than the"] + #[doc = " size of the variable declared in modules and identified by"] + #[doc = " OptixPipelineCompileOptions::pipelineLaunchParamsVariableName. If the launch params"] + #[doc = " variable was optimized out or not found in the modules linked to the pipeline then"] + #[doc = " the pipelineParams and pipelineParamsSize parameters are ignored."] + #[doc = ""] + #[doc = " sbt points to the shader binding table, which defines shader"] + #[doc = " groupings and their resources. See the SBT spec."] + #[doc = ""] + #[doc = " \\param[in] pipeline"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] pipelineParams"] + #[doc = " \\param[in] pipelineParamsSize"] + #[doc = " \\param[in] sbt"] + #[doc = " \\param[in] width number of elements to compute"] + #[doc = " \\param[in] height number of elements to compute"] + #[doc = " \\param[in] depth number of elements to compute"] + #[doc = ""] + #[doc = " Thread safety: In the current implementation concurrent launches to the same pipeline are not"] + #[doc = " supported. Concurrent launches require separate OptixPipeline objects."] + pub fn optixLaunch( + pipeline: OptixPipeline, + stream: CUstream, + pipelineParams: CUdeviceptr, + pipelineParamsSize: usize, + sbt: *const OptixShaderBindingTable, + width: ::std::os::raw::c_uint, + height: ::std::os::raw::c_uint, + depth: ::std::os::raw::c_uint, + ) -> OptixResult; +} +extern "C" { + #[doc = " \\param[in] programGroup the program group containing the program(s)"] + #[doc = " \\param[out] sbtRecordHeaderHostPointer the result sbt record header"] + pub fn optixSbtRecordPackHeader( + programGroup: OptixProgramGroup, + sbtRecordHeaderHostPointer: *mut ::std::os::raw::c_void, + ) -> OptixResult; +} +extern "C" { + #[doc = " \\param[in] context"] + #[doc = " \\param[in] accelOptions options for the accel build"] + #[doc = " \\param[in] buildInputs an array of OptixBuildInput objects"] + #[doc = " \\param[in] numBuildInputs number of elements in buildInputs (must be at least 1)"] + #[doc = " \\param[out] bufferSizes fills in buffer sizes"] + pub fn optixAccelComputeMemoryUsage( + context: OptixDeviceContext, + accelOptions: *const OptixAccelBuildOptions, + buildInputs: *const OptixBuildInput, + numBuildInputs: ::std::os::raw::c_uint, + bufferSizes: *mut OptixAccelBufferSizes, + ) -> OptixResult; +} +extern "C" { + #[doc = " \\param[in] context"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] accelOptions accel options"] + #[doc = " \\param[in] buildInputs an array of OptixBuildInput objects"] + #[doc = " \\param[in] numBuildInputs must be >= 1 for GAS, and == 1 for IAS"] + #[doc = " \\param[in] tempBuffer must be a multiple of OPTIX_ACCEL_BUFFER_BYTE_ALIGNMENT"] + #[doc = " \\param[in] tempBufferSizeInBytes"] + #[doc = " \\param[in] outputBuffer must be a multiple of OPTIX_ACCEL_BUFFER_BYTE_ALIGNMENT"] + #[doc = " \\param[in] outputBufferSizeInBytes"] + #[doc = " \\param[out] outputHandle"] + #[doc = " \\param[out] emittedProperties types of requested properties and output buffers"] + #[doc = " \\param[in] numEmittedProperties number of post-build properties to populate (may be zero)"] + pub fn optixAccelBuild( + context: OptixDeviceContext, + stream: CUstream, + accelOptions: *const OptixAccelBuildOptions, + buildInputs: *const OptixBuildInput, + numBuildInputs: ::std::os::raw::c_uint, + tempBuffer: CUdeviceptr, + tempBufferSizeInBytes: usize, + outputBuffer: CUdeviceptr, + outputBufferSizeInBytes: usize, + outputHandle: *mut OptixTraversableHandle, + emittedProperties: *const OptixAccelEmitDesc, + numEmittedProperties: ::std::os::raw::c_uint, + ) -> OptixResult; +} +extern "C" { + #[doc = " Obtain relocation information, stored in OptixAccelRelocationInfo, for a given context"] + #[doc = " and acceleration structure's traversable handle."] + #[doc = ""] + #[doc = " The relocation information can be passed to optixAccelCheckRelocationCompatibility to"] + #[doc = " determine if an acceleration structure, referenced by 'handle', can be relocated to a"] + #[doc = " different device's memory space (see #optixAccelCheckRelocationCompatibility)."] + #[doc = ""] + #[doc = " When used with optixAccelRelocate, it provides data necessary for doing the relocation."] + #[doc = ""] + #[doc = " If the acceleration structure data associated with 'handle' is copied multiple times,"] + #[doc = " the same OptixAccelRelocationInfo can also be used on all copies."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] handle"] + #[doc = " \\param[out] info"] + #[doc = " \\return OPTIX_ERROR_INVALID_VALUE will be returned for traversable handles that are not from"] + #[doc = " acceleration structure builds."] + pub fn optixAccelGetRelocationInfo( + context: OptixDeviceContext, + handle: OptixTraversableHandle, + info: *mut OptixAccelRelocationInfo, + ) -> OptixResult; +} +extern "C" { + #[doc = " Checks if an acceleration structure built using another OptixDeviceContext (that was"] + #[doc = " used to fill in 'info') is compatible with the OptixDeviceContext specified in the"] + #[doc = " 'context' parameter."] + #[doc = ""] + #[doc = " Any device is always compatible with itself."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] info"] + #[doc = " \\param[out] compatible If OPTIX_SUCCESS is returned 'compatible' will have the value of either:"] + #[doc = " - 0: This context is not compatible with acceleration structure data associated with 'info'."] + #[doc = " - 1: This context is compatible."] + pub fn optixAccelCheckRelocationCompatibility( + context: OptixDeviceContext, + info: *const OptixAccelRelocationInfo, + compatible: *mut ::std::os::raw::c_int, + ) -> OptixResult; +} +extern "C" { + #[doc = " optixAccelRelocate is called to update the acceleration structure after it has been"] + #[doc = " relocated. Relocation is necessary when the acceleration structure's location in device"] + #[doc = " memory has changed. optixAccelRelocate does not copy the memory. This function only"] + #[doc = " operates on the relocated memory who's new location is specified by 'targetAccel'."] + #[doc = " optixAccelRelocate also returns the new OptixTraversableHandle associated with"] + #[doc = " 'targetAccel'. The original memory (source) is not required to be valid, only the"] + #[doc = " OptixAccelRelocationInfo."] + #[doc = ""] + #[doc = " Before copying the data and calling optixAccelRelocate,"] + #[doc = " optixAccelCheckRelocationCompatibility should be called to ensure the copy will be"] + #[doc = " compatible with the destination device context."] + #[doc = ""] + #[doc = " The memory pointed to by 'targetAccel' should be allocated with the same size as the"] + #[doc = " source acceleration. Similar to the 'outputBuffer' used in optixAccelBuild, this"] + #[doc = " pointer must be a multiple of OPTIX_ACCEL_BUFFER_BYTE_ALIGNMENT."] + #[doc = ""] + #[doc = " The memory in 'targetAccel' must be allocated as long as the accel is in use."] + #[doc = ""] + #[doc = " When relocating an accel that contains instances, 'instanceTraversableHandles' and"] + #[doc = " 'numInstanceTraversableHandles' should be supplied. These are the traversable handles"] + #[doc = " of the instances. These can be used when also relocating the instances. No updates to"] + #[doc = " the bounds are performed. Use optixAccelBuild to update the bounds."] + #[doc = " 'instanceTraversableHandles' and 'numInstanceTraversableHandles' may be zero when"] + #[doc = " relocating bottom level accel (i.e. an accel with no instances)."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] info"] + #[doc = " \\param[in] instanceTraversableHandles"] + #[doc = " \\param[in] numInstanceTraversableHandles"] + #[doc = " \\param[in] targetAccel"] + #[doc = " \\param[in] targetAccelSizeInBytes"] + #[doc = " \\param[out] targetHandle"] + pub fn optixAccelRelocate( + context: OptixDeviceContext, + stream: CUstream, + info: *const OptixAccelRelocationInfo, + instanceTraversableHandles: CUdeviceptr, + numInstanceTraversableHandles: usize, + targetAccel: CUdeviceptr, + targetAccelSizeInBytes: usize, + targetHandle: *mut OptixTraversableHandle, + ) -> OptixResult; +} +extern "C" { + #[doc = " After building an acceleration structure, it can be copied in a compacted form to reduce"] + #[doc = " memory. In order to be compacted, OPTIX_BUILD_FLAG_ALLOW_COMPACTION must be supplied in"] + #[doc = " OptixAccelBuildOptions::buildFlags passed to optixAccelBuild."] + #[doc = ""] + #[doc = " 'outputBuffer' is the pointer to where the compacted acceleration structure will be"] + #[doc = " written. This pointer must be a multiple of OPTIX_ACCEL_BUFFER_BYTE_ALIGNMENT."] + #[doc = ""] + #[doc = " The size of the memory specified in 'outputBufferSizeInBytes' should be at least the"] + #[doc = " value computed using the OPTIX_PROPERTY_TYPE_COMPACTED_SIZE that was reported during"] + #[doc = " optixAccelBuild."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] inputHandle"] + #[doc = " \\param[in] outputBuffer"] + #[doc = " \\param[in] outputBufferSizeInBytes"] + #[doc = " \\param[out] outputHandle"] + pub fn optixAccelCompact( + context: OptixDeviceContext, + stream: CUstream, + inputHandle: OptixTraversableHandle, + outputBuffer: CUdeviceptr, + outputBufferSizeInBytes: usize, + outputHandle: *mut OptixTraversableHandle, + ) -> OptixResult; +} +extern "C" { + #[doc = " \\param[in] onDevice"] + #[doc = " \\param[in] pointer pointer to traversable allocated in OptixDeviceContext. This pointer must be a multiple of OPTIX_TRANSFORM_BYTE_ALIGNMENT"] + #[doc = " \\param[in] traversableType Type of OptixTraversableHandle to create"] + #[doc = " \\param[out] traversableHandle traversable handle. traversableHandle must be in host memory"] + pub fn optixConvertPointerToTraversableHandle( + onDevice: OptixDeviceContext, + pointer: CUdeviceptr, + traversableType: OptixTraversableType, + traversableHandle: *mut OptixTraversableHandle, + ) -> OptixResult; +} +extern "C" { + #[doc = " Creates a denoiser object with the given options, using built-in inference models"] + #[doc = ""] + #[doc = " 'modelKind' selects the model used for inference."] + #[doc = " Inference for the built-in models can be guided (giving hints to improve image quality) with"] + #[doc = " albedo and normal vector images in the guide layer (see 'optixDenoiserInvoke')."] + #[doc = " Use of these images must be enabled in 'OptixDenoiserOptions'."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] modelKind"] + #[doc = " \\param[in] options"] + #[doc = " \\param[out] denoiser"] + pub fn optixDenoiserCreate( + context: OptixDeviceContext, + modelKind: OptixDenoiserModelKind, + options: *const OptixDenoiserOptions, + denoiser: *mut OptixDenoiser, + ) -> OptixResult; +} +extern "C" { + #[doc = " Creates a denoiser object with the given options, using a provided inference model"] + #[doc = ""] + #[doc = " 'userData' and 'userDataSizeInBytes' provide a user model for inference."] + #[doc = " The memory passed in userData will be accessed only during the invocation of this function and"] + #[doc = " can be freed after it returns."] + #[doc = " The user model must export only one weight set which determines both the model kind and the"] + #[doc = " required set of guide images."] + #[doc = ""] + #[doc = " \\param[in] context"] + #[doc = " \\param[in] userData"] + #[doc = " \\param[in] userDataSizeInBytes"] + #[doc = " \\param[out] denoiser"] + pub fn optixDenoiserCreateWithUserModel( + context: OptixDeviceContext, + userData: *const ::std::os::raw::c_void, + userDataSizeInBytes: usize, + denoiser: *mut OptixDenoiser, + ) -> OptixResult; +} +extern "C" { + #[doc = " Destroys the denoiser object and any associated host resources."] + pub fn optixDenoiserDestroy(denoiser: OptixDenoiser) -> OptixResult; +} +extern "C" { + #[doc = " Computes the GPU memory resources required to execute the denoiser."] + #[doc = ""] + #[doc = " Memory for state and scratch buffers must be allocated with the sizes in 'returnSizes' and scratch memory"] + #[doc = " passed to optixDenoiserSetup, optixDenoiserInvoke,"] + #[doc = " optixDenoiserComputeIntensity and optixDenoiserComputeAverageColor."] + #[doc = " For tiled denoising an overlap area must be added to each tile on all sides which increases the amount of"] + #[doc = " memory needed to denoise a tile. In case of tiling use withOverlapScratchSizeInBytes."] + #[doc = " If only full resolution images are denoised, withoutOverlapScratchSizeInBytes can be used which is always"] + #[doc = " smaller than withOverlapScratchSizeInBytes."] + #[doc = ""] + #[doc = " 'outputWidth' and 'outputHeight' is the dimension of the image to be denoised (without overlap in case tiling"] + #[doc = " is being used)."] + #[doc = " 'outputWidth' and 'outputHeight' must be greater than or equal to the dimensions passed to optixDenoiserSetup."] + #[doc = ""] + #[doc = " \\param[in] denoiser"] + #[doc = " \\param[in] outputWidth"] + #[doc = " \\param[in] outputHeight"] + #[doc = " \\param[out] returnSizes"] + pub fn optixDenoiserComputeMemoryResources( + denoiser: OptixDenoiser, + outputWidth: ::std::os::raw::c_uint, + outputHeight: ::std::os::raw::c_uint, + returnSizes: *mut OptixDenoiserSizes, + ) -> OptixResult; +} +extern "C" { + #[doc = " Initializes the state required by the denoiser."] + #[doc = ""] + #[doc = " 'inputWidth' and 'inputHeight' must include overlap on both sides of the image if tiling is being used. The overlap is"] + #[doc = " returned by #optixDenoiserComputeMemoryResources."] + #[doc = " For subsequent calls to #optixDenoiserInvoke 'inputWidth' and 'inputHeight' are the maximum dimensions"] + #[doc = " of the input layers. Dimensions of the input layers passed to #optixDenoiserInvoke may be different in each"] + #[doc = " invocation however they always must be smaller than 'inputWidth' and 'inputHeight' passed to #optixDenoiserSetup."] + #[doc = ""] + #[doc = " \\param[in] denoiser"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] inputWidth"] + #[doc = " \\param[in] inputHeight"] + #[doc = " \\param[in] denoiserState"] + #[doc = " \\param[in] denoiserStateSizeInBytes"] + #[doc = " \\param[in] scratch"] + #[doc = " \\param[in] scratchSizeInBytes"] + pub fn optixDenoiserSetup( + denoiser: OptixDenoiser, + stream: CUstream, + inputWidth: ::std::os::raw::c_uint, + inputHeight: ::std::os::raw::c_uint, + denoiserState: CUdeviceptr, + denoiserStateSizeInBytes: usize, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " Invokes denoiser on a set of input data and produces at least one output image."] + #[doc = " State memory must be available during the execution of the"] + #[doc = " denoiser (or until optixDenoiserSetup is called with a new state memory pointer)."] + #[doc = " Scratch memory passed is used only for the duration of this function."] + #[doc = " Scratch and state memory sizes must have a size greater than or equal to the sizes as returned by"] + #[doc = " optixDenoiserComputeMemoryResources."] + #[doc = ""] + #[doc = " 'inputOffsetX' and 'inputOffsetY' are pixel offsets in the 'inputLayers' image"] + #[doc = " specifying the beginning of the image without overlap. When denoising an entire image without tiling"] + #[doc = " there is no overlap and 'inputOffsetX' and 'inputOffsetY' must be zero. When denoising a tile which is"] + #[doc = " adjacent to one of the four sides of the entire image the corresponding offsets must also be zero since"] + #[doc = " there is no overlap at the side adjacent to the image border."] + #[doc = ""] + #[doc = " 'guideLayer' provides additional information to the denoiser. When providing albedo and normal vector"] + #[doc = " guide images, the corresponding fields in the 'OptixDenoiserOptions' must be"] + #[doc = " enabled, see #optixDenoiserCreate."] + #[doc = " 'guideLayer' must not be null. If a guide image in 'OptixDenoiserOptions' is not enabled, the"] + #[doc = " corresponding image in 'OptixDenoiserGuideLayer' is ignored."] + #[doc = ""] + #[doc = " If OPTIX_DENOISER_MODEL_KIND_TEMPORAL or OPTIX_DENOISER_MODEL_KIND_TEMPORAL_AOV is selected, a 2d flow"] + #[doc = " image must be given in 'OptixDenoiserGuideLayer'."] + #[doc = " It describes for each pixel the flow from the previous to the current frame (a 2d vector in pixel space)."] + #[doc = " The denoised beauty/AOV of the previous frame must be given in 'previousOutput'."] + #[doc = " If this image is not available in the first frame of a sequence, the noisy beauty/AOV from the first frame"] + #[doc = " and zero flow vectors could be given as a substitute."] + #[doc = " For non-temporal model kinds the flow image in 'OptixDenoiserGuideLayer' is ignored."] + #[doc = " 'previousOutput' and"] + #[doc = " 'output' may refer to the same buffer, i.e. 'previousOutput' is first read by this function and later"] + #[doc = " overwritten with the denoised result. 'output' can be passed as 'previousOutput' to the next frame."] + #[doc = " In other model kinds (not temporal) 'previousOutput' is ignored."] + #[doc = ""] + #[doc = " The beauty layer must be given as the first entry in 'layers'."] + #[doc = " In AOV type model kinds (OPTIX_DENOISER_MODEL_KIND_AOV or in user defined models implementing"] + #[doc = " kernel-prediction) additional layers for the AOV images can be given."] + #[doc = " In each layer the noisy input image is given in 'input', the denoised output is written into the"] + #[doc = " 'output' image. input and output images may refer to the same buffer, with the restriction that"] + #[doc = " the pixel formats must be identical for input and output when the blend mode is selected (see"] + #[doc = " #OptixDenoiserParams)."] + #[doc = ""] + #[doc = " If OPTIX_DENOISER_MODEL_KIND_TEMPORAL or OPTIX_DENOISER_MODEL_KIND_TEMPORAL_AOV is selected, the denoised"] + #[doc = " image from the previous frame must be given in 'previousOutput' in the layer. 'previousOutput' and"] + #[doc = " 'output' may refer to the same buffer, i.e. 'previousOutput' is first read by this function and later"] + #[doc = " overwritten with the denoised result. 'output' can be passed as 'previousOutput' to the next frame."] + #[doc = " In other model kinds (not temporal) 'previousOutput' is ignored."] + #[doc = ""] + #[doc = " If OPTIX_DENOISER_MODEL_KIND_TEMPORAL or OPTIX_DENOISER_MODEL_KIND_TEMPORAL_AOV is selected, the"] + #[doc = " normal vector guide image must be given as 3d vectors in camera space. In the other models only"] + #[doc = " the x and y channels are used and other channels are ignored."] + #[doc = ""] + #[doc = " \\param[in] denoiser"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] params"] + #[doc = " \\param[in] denoiserState"] + #[doc = " \\param[in] denoiserStateSizeInBytes"] + #[doc = " \\param[in] guideLayer"] + #[doc = " \\param[in] layers"] + #[doc = " \\param[in] numLayers"] + #[doc = " \\param[in] inputOffsetX"] + #[doc = " \\param[in] inputOffsetY"] + #[doc = " \\param[in] scratch"] + #[doc = " \\param[in] scratchSizeInBytes"] + pub fn optixDenoiserInvoke( + denoiser: OptixDenoiser, + stream: CUstream, + params: *const OptixDenoiserParams, + denoiserState: CUdeviceptr, + denoiserStateSizeInBytes: usize, + guideLayer: *const OptixDenoiserGuideLayer, + layers: *const OptixDenoiserLayer, + numLayers: ::std::os::raw::c_uint, + inputOffsetX: ::std::os::raw::c_uint, + inputOffsetY: ::std::os::raw::c_uint, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " data type unsigned char is not supported for 'inputImage', it must be 3 or 4 component half/float."] + #[doc = ""] + #[doc = " \\param[in] denoiser"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] inputImage"] + #[doc = " \\param[out] outputIntensity single float"] + #[doc = " \\param[in] scratch"] + #[doc = " \\param[in] scratchSizeInBytes"] + pub fn optixDenoiserComputeIntensity( + denoiser: OptixDenoiser, + stream: CUstream, + inputImage: *const OptixImage2D, + outputIntensity: CUdeviceptr, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult; +} +extern "C" { + #[doc = " Compute average logarithmic for each of the first three channels for the given image."] + #[doc = " When denoising tiles the intensity of the entire image should be computed, i.e. not per tile to get"] + #[doc = " consistent results."] + #[doc = " This function needs scratch memory with a size of at least"] + #[doc = " sizeof( int ) * ( 3 + 3 * inputImage::width * inputImage::height ). When denoising entire images (no tiling)"] + #[doc = " the same scratch memory as passed to optixDenoiserInvoke could be used."] + #[doc = ""] + #[doc = " data type unsigned char is not supported for 'inputImage', it must be 3 or 4 component half/float."] + #[doc = ""] + #[doc = " \\param[in] denoiser"] + #[doc = " \\param[in] stream"] + #[doc = " \\param[in] inputImage"] + #[doc = " \\param[out] outputAverageColor three floats"] + #[doc = " \\param[in] scratch"] + #[doc = " \\param[in] scratchSizeInBytes"] + pub fn optixDenoiserComputeAverageColor( + denoiser: OptixDenoiser, + stream: CUstream, + inputImage: *const OptixImage2D, + outputAverageColor: CUdeviceptr, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult; +} +#[doc = " The function table containing all API functions."] +#[doc = ""] +#[doc = " See #optixInit() and #optixInitWithHandle()."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct OptixFunctionTable { + #[doc = " See ::optixGetErrorName()."] + pub optixGetErrorName: ::std::option::Option< + unsafe extern "C" fn(result: OptixResult) -> *const ::std::os::raw::c_char, + >, + #[doc = " See ::optixGetErrorString()."] + pub optixGetErrorString: ::std::option::Option< + unsafe extern "C" fn(result: OptixResult) -> *const ::std::os::raw::c_char, + >, + #[doc = " See ::optixDeviceContextCreate()."] + pub optixDeviceContextCreate: ::std::option::Option< + unsafe extern "C" fn( + fromContext: CUcontext, + options: *const OptixDeviceContextOptions, + context: *mut OptixDeviceContext, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextDestroy()."] + pub optixDeviceContextDestroy: + ::std::option::Option OptixResult>, + #[doc = " See ::optixDeviceContextGetProperty()."] + pub optixDeviceContextGetProperty: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + property: OptixDeviceProperty, + value: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextSetLogCallback()."] + pub optixDeviceContextSetLogCallback: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + callbackFunction: OptixLogCallback, + callbackData: *mut ::std::os::raw::c_void, + callbackLevel: ::std::os::raw::c_uint, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextSetCacheEnabled()."] + pub optixDeviceContextSetCacheEnabled: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + enabled: ::std::os::raw::c_int, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextSetCacheLocation()."] + pub optixDeviceContextSetCacheLocation: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + location: *const ::std::os::raw::c_char, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextSetCacheDatabaseSizes()."] + pub optixDeviceContextSetCacheDatabaseSizes: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + lowWaterMark: usize, + highWaterMark: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextGetCacheEnabled()."] + pub optixDeviceContextGetCacheEnabled: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + enabled: *mut ::std::os::raw::c_int, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextGetCacheLocation()."] + pub optixDeviceContextGetCacheLocation: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + location: *mut ::std::os::raw::c_char, + locationSize: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDeviceContextGetCacheDatabaseSizes()."] + pub optixDeviceContextGetCacheDatabaseSizes: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + lowWaterMark: *mut usize, + highWaterMark: *mut usize, + ) -> OptixResult, + >, + #[doc = " See ::optixModuleCreateFromPTX()."] + pub optixModuleCreateFromPTX: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + PTX: *const ::std::os::raw::c_char, + PTXsize: usize, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + module: *mut OptixModule, + ) -> OptixResult, + >, + #[doc = " See ::optixModuleCreateFromPTXWithTasks()."] + pub optixModuleCreateFromPTXWithTasks: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + PTX: *const ::std::os::raw::c_char, + PTXsize: usize, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + module: *mut OptixModule, + firstTask: *mut OptixTask, + ) -> OptixResult, + >, + #[doc = " See ::optixModuleGetCompilationState()."] + pub optixModuleGetCompilationState: ::std::option::Option< + unsafe extern "C" fn( + module: OptixModule, + state: *mut OptixModuleCompileState, + ) -> OptixResult, + >, + #[doc = " See ::optixModuleDestroy()."] + pub optixModuleDestroy: + ::std::option::Option OptixResult>, + #[doc = " See ::optixBuiltinISModuleGet()."] + pub optixBuiltinISModuleGet: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + moduleCompileOptions: *const OptixModuleCompileOptions, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + builtinISOptions: *const OptixBuiltinISOptions, + builtinModule: *mut OptixModule, + ) -> OptixResult, + >, + #[doc = " See ::optixTaskExecute()."] + pub optixTaskExecute: ::std::option::Option< + unsafe extern "C" fn( + task: OptixTask, + additionalTasks: *mut OptixTask, + maxNumAdditionalTasks: ::std::os::raw::c_uint, + numAdditionalTasksCreated: *mut ::std::os::raw::c_uint, + ) -> OptixResult, + >, + #[doc = " See ::optixProgramGroupCreate()."] + pub optixProgramGroupCreate: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + programDescriptions: *const OptixProgramGroupDesc, + numProgramGroups: ::std::os::raw::c_uint, + options: *const OptixProgramGroupOptions, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + programGroups: *mut OptixProgramGroup, + ) -> OptixResult, + >, + #[doc = " See ::optixProgramGroupDestroy()."] + pub optixProgramGroupDestroy: + ::std::option::Option OptixResult>, + #[doc = " See ::optixProgramGroupGetStackSize()."] + pub optixProgramGroupGetStackSize: ::std::option::Option< + unsafe extern "C" fn( + programGroup: OptixProgramGroup, + stackSizes: *mut OptixStackSizes, + ) -> OptixResult, + >, + #[doc = " See ::optixPipelineCreate()."] + pub optixPipelineCreate: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + pipelineCompileOptions: *const OptixPipelineCompileOptions, + pipelineLinkOptions: *const OptixPipelineLinkOptions, + programGroups: *const OptixProgramGroup, + numProgramGroups: ::std::os::raw::c_uint, + logString: *mut ::std::os::raw::c_char, + logStringSize: *mut usize, + pipeline: *mut OptixPipeline, + ) -> OptixResult, + >, + #[doc = " See ::optixPipelineDestroy()."] + pub optixPipelineDestroy: + ::std::option::Option OptixResult>, + #[doc = " See ::optixPipelineSetStackSize()."] + pub optixPipelineSetStackSize: ::std::option::Option< + unsafe extern "C" fn( + pipeline: OptixPipeline, + directCallableStackSizeFromTraversal: ::std::os::raw::c_uint, + directCallableStackSizeFromState: ::std::os::raw::c_uint, + continuationStackSize: ::std::os::raw::c_uint, + maxTraversableGraphDepth: ::std::os::raw::c_uint, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelComputeMemoryUsage()."] + pub optixAccelComputeMemoryUsage: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + accelOptions: *const OptixAccelBuildOptions, + buildInputs: *const OptixBuildInput, + numBuildInputs: ::std::os::raw::c_uint, + bufferSizes: *mut OptixAccelBufferSizes, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelBuild()."] + pub optixAccelBuild: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + stream: CUstream, + accelOptions: *const OptixAccelBuildOptions, + buildInputs: *const OptixBuildInput, + numBuildInputs: ::std::os::raw::c_uint, + tempBuffer: CUdeviceptr, + tempBufferSizeInBytes: usize, + outputBuffer: CUdeviceptr, + outputBufferSizeInBytes: usize, + outputHandle: *mut OptixTraversableHandle, + emittedProperties: *const OptixAccelEmitDesc, + numEmittedProperties: ::std::os::raw::c_uint, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelGetRelocationInfo()."] + pub optixAccelGetRelocationInfo: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + handle: OptixTraversableHandle, + info: *mut OptixAccelRelocationInfo, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelCheckRelocationCompatibility()."] + pub optixAccelCheckRelocationCompatibility: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + info: *const OptixAccelRelocationInfo, + compatible: *mut ::std::os::raw::c_int, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelRelocate()."] + pub optixAccelRelocate: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + stream: CUstream, + info: *const OptixAccelRelocationInfo, + instanceTraversableHandles: CUdeviceptr, + numInstanceTraversableHandles: usize, + targetAccel: CUdeviceptr, + targetAccelSizeInBytes: usize, + targetHandle: *mut OptixTraversableHandle, + ) -> OptixResult, + >, + #[doc = " See ::optixAccelCompact()."] + pub optixAccelCompact: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + stream: CUstream, + inputHandle: OptixTraversableHandle, + outputBuffer: CUdeviceptr, + outputBufferSizeInBytes: usize, + outputHandle: *mut OptixTraversableHandle, + ) -> OptixResult, + >, + #[doc = " See ::optixConvertPointerToTraversableHandle()."] + pub optixConvertPointerToTraversableHandle: ::std::option::Option< + unsafe extern "C" fn( + onDevice: OptixDeviceContext, + pointer: CUdeviceptr, + traversableType: OptixTraversableType, + traversableHandle: *mut OptixTraversableHandle, + ) -> OptixResult, + >, + pub reserved1: ::std::option::Option, + pub reserved2: ::std::option::Option, + #[doc = " See ::optixConvertPointerToTraversableHandle()."] + pub optixSbtRecordPackHeader: ::std::option::Option< + unsafe extern "C" fn( + programGroup: OptixProgramGroup, + sbtRecordHeaderHostPointer: *mut ::std::os::raw::c_void, + ) -> OptixResult, + >, + #[doc = " See ::optixConvertPointerToTraversableHandle()."] + pub optixLaunch: ::std::option::Option< + unsafe extern "C" fn( + pipeline: OptixPipeline, + stream: CUstream, + pipelineParams: CUdeviceptr, + pipelineParamsSize: usize, + sbt: *const OptixShaderBindingTable, + width: ::std::os::raw::c_uint, + height: ::std::os::raw::c_uint, + depth: ::std::os::raw::c_uint, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserCreate()."] + pub optixDenoiserCreate: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + modelKind: OptixDenoiserModelKind, + options: *const OptixDenoiserOptions, + returnHandle: *mut OptixDenoiser, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserDestroy()."] + pub optixDenoiserDestroy: + ::std::option::Option OptixResult>, + #[doc = " See ::optixDenoiserComputeMemoryResources()."] + pub optixDenoiserComputeMemoryResources: ::std::option::Option< + unsafe extern "C" fn( + handle: OptixDenoiser, + maximumInputWidth: ::std::os::raw::c_uint, + maximumInputHeight: ::std::os::raw::c_uint, + returnSizes: *mut OptixDenoiserSizes, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserSetup()."] + pub optixDenoiserSetup: ::std::option::Option< + unsafe extern "C" fn( + denoiser: OptixDenoiser, + stream: CUstream, + inputWidth: ::std::os::raw::c_uint, + inputHeight: ::std::os::raw::c_uint, + state: CUdeviceptr, + stateSizeInBytes: usize, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserInvoke()."] + pub optixDenoiserInvoke: ::std::option::Option< + unsafe extern "C" fn( + denoiser: OptixDenoiser, + stream: CUstream, + params: *const OptixDenoiserParams, + denoiserState: CUdeviceptr, + denoiserStateSizeInBytes: usize, + guideLayer: *const OptixDenoiserGuideLayer, + layers: *const OptixDenoiserLayer, + numLayers: ::std::os::raw::c_uint, + inputOffsetX: ::std::os::raw::c_uint, + inputOffsetY: ::std::os::raw::c_uint, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserComputeIntensity()."] + pub optixDenoiserComputeIntensity: ::std::option::Option< + unsafe extern "C" fn( + handle: OptixDenoiser, + stream: CUstream, + inputImage: *const OptixImage2D, + outputIntensity: CUdeviceptr, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserComputeAverageColor()."] + pub optixDenoiserComputeAverageColor: ::std::option::Option< + unsafe extern "C" fn( + handle: OptixDenoiser, + stream: CUstream, + inputImage: *const OptixImage2D, + outputAverageColor: CUdeviceptr, + scratch: CUdeviceptr, + scratchSizeInBytes: usize, + ) -> OptixResult, + >, + #[doc = " See ::optixDenoiserCreateWithUserModel()."] + pub optixDenoiserCreateWithUserModel: ::std::option::Option< + unsafe extern "C" fn( + context: OptixDeviceContext, + data: *const ::std::os::raw::c_void, + dataSizeInBytes: usize, + returnHandle: *mut OptixDenoiser, + ) -> OptixResult, + >, +} diff --git a/optix_base/src/optix6.rs b/optix_base/src/optix6.rs new file mode 100644 index 0000000..f6ba983 --- /dev/null +++ b/optix_base/src/optix6.rs @@ -0,0 +1,16049 @@ +/* automatically generated by rust-bindgen 0.59.2 */ + +impl RTformat { + #[doc = "< Format unknown"] + pub const RT_FORMAT_UNKNOWN: RTformat = RTformat(256); +} +impl RTformat { + #[doc = "< Float"] + pub const RT_FORMAT_FLOAT: RTformat = RTformat(257); +} +impl RTformat { + #[doc = "< sizeof(float)*2"] + pub const RT_FORMAT_FLOAT2: RTformat = RTformat(258); +} +impl RTformat { + #[doc = "< sizeof(float)*3"] + pub const RT_FORMAT_FLOAT3: RTformat = RTformat(259); +} +impl RTformat { + #[doc = "< sizeof(float)*4"] + pub const RT_FORMAT_FLOAT4: RTformat = RTformat(260); +} +impl RTformat { + #[doc = "< BYTE"] + pub const RT_FORMAT_BYTE: RTformat = RTformat(261); +} +impl RTformat { + #[doc = "< sizeof(CHAR)*2"] + pub const RT_FORMAT_BYTE2: RTformat = RTformat(262); +} +impl RTformat { + #[doc = "< sizeof(CHAR)*3"] + pub const RT_FORMAT_BYTE3: RTformat = RTformat(263); +} +impl RTformat { + #[doc = "< sizeof(CHAR)*4"] + pub const RT_FORMAT_BYTE4: RTformat = RTformat(264); +} +impl RTformat { + #[doc = "< UCHAR"] + pub const RT_FORMAT_UNSIGNED_BYTE: RTformat = RTformat(265); +} +impl RTformat { + #[doc = "< sizeof(UCHAR)*2"] + pub const RT_FORMAT_UNSIGNED_BYTE2: RTformat = RTformat(266); +} +impl RTformat { + #[doc = "< sizeof(UCHAR)*3"] + pub const RT_FORMAT_UNSIGNED_BYTE3: RTformat = RTformat(267); +} +impl RTformat { + #[doc = "< sizeof(UCHAR)*4"] + pub const RT_FORMAT_UNSIGNED_BYTE4: RTformat = RTformat(268); +} +impl RTformat { + #[doc = "< SHORT"] + pub const RT_FORMAT_SHORT: RTformat = RTformat(269); +} +impl RTformat { + #[doc = "< sizeof(SHORT)*2"] + pub const RT_FORMAT_SHORT2: RTformat = RTformat(270); +} +impl RTformat { + #[doc = "< sizeof(SHORT)*3"] + pub const RT_FORMAT_SHORT3: RTformat = RTformat(271); +} +impl RTformat { + #[doc = "< sizeof(SHORT)*4"] + pub const RT_FORMAT_SHORT4: RTformat = RTformat(272); +} +impl RTformat { + #[doc = "< USHORT"] + pub const RT_FORMAT_UNSIGNED_SHORT: RTformat = RTformat(273); +} +impl RTformat { + #[doc = "< sizeof(USHORT)*2"] + pub const RT_FORMAT_UNSIGNED_SHORT2: RTformat = RTformat(274); +} +impl RTformat { + #[doc = "< sizeof(USHORT)*3"] + pub const RT_FORMAT_UNSIGNED_SHORT3: RTformat = RTformat(275); +} +impl RTformat { + #[doc = "< sizeof(USHORT)*4"] + pub const RT_FORMAT_UNSIGNED_SHORT4: RTformat = RTformat(276); +} +impl RTformat { + #[doc = "< INT"] + pub const RT_FORMAT_INT: RTformat = RTformat(277); +} +impl RTformat { + #[doc = "< sizeof(INT)*2"] + pub const RT_FORMAT_INT2: RTformat = RTformat(278); +} +impl RTformat { + #[doc = "< sizeof(INT)*3"] + pub const RT_FORMAT_INT3: RTformat = RTformat(279); +} +impl RTformat { + #[doc = "< sizeof(INT)*4"] + pub const RT_FORMAT_INT4: RTformat = RTformat(280); +} +impl RTformat { + #[doc = "< sizeof(UINT)"] + pub const RT_FORMAT_UNSIGNED_INT: RTformat = RTformat(281); +} +impl RTformat { + #[doc = "< sizeof(UINT)*2"] + pub const RT_FORMAT_UNSIGNED_INT2: RTformat = RTformat(282); +} +impl RTformat { + #[doc = "< sizeof(UINT)*3"] + pub const RT_FORMAT_UNSIGNED_INT3: RTformat = RTformat(283); +} +impl RTformat { + #[doc = "< sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_INT4: RTformat = RTformat(284); +} +impl RTformat { + #[doc = "< User Format"] + pub const RT_FORMAT_USER: RTformat = RTformat(285); +} +impl RTformat { + #[doc = "< Buffer Id"] + pub const RT_FORMAT_BUFFER_ID: RTformat = RTformat(286); +} +impl RTformat { + #[doc = "< Program Id"] + pub const RT_FORMAT_PROGRAM_ID: RTformat = RTformat(287); +} +impl RTformat { + #[doc = "< half float"] + pub const RT_FORMAT_HALF: RTformat = RTformat(288); +} +impl RTformat { + #[doc = "< sizeof(half float)*2"] + pub const RT_FORMAT_HALF2: RTformat = RTformat(289); +} +impl RTformat { + #[doc = "< sizeof(half float)*3"] + pub const RT_FORMAT_HALF3: RTformat = RTformat(290); +} +impl RTformat { + #[doc = "< sizeof(half float)*4"] + pub const RT_FORMAT_HALF4: RTformat = RTformat(291); +} +impl RTformat { + #[doc = "< LONG_LONG"] + pub const RT_FORMAT_LONG_LONG: RTformat = RTformat(292); +} +impl RTformat { + #[doc = "< sizeof(LONG_LONG)*2"] + pub const RT_FORMAT_LONG_LONG2: RTformat = RTformat(293); +} +impl RTformat { + #[doc = "< sizeof(LONG_LONG)*3"] + pub const RT_FORMAT_LONG_LONG3: RTformat = RTformat(294); +} +impl RTformat { + #[doc = "< sizeof(LONG_LONG)*4"] + pub const RT_FORMAT_LONG_LONG4: RTformat = RTformat(295); +} +impl RTformat { + #[doc = "< sizeof(ULONG_LONG)"] + pub const RT_FORMAT_UNSIGNED_LONG_LONG: RTformat = RTformat(296); +} +impl RTformat { + #[doc = "< sizeof(ULONG_LONG)*2"] + pub const RT_FORMAT_UNSIGNED_LONG_LONG2: RTformat = RTformat(297); +} +impl RTformat { + #[doc = "< sizeof(ULONG_LONG)*3"] + pub const RT_FORMAT_UNSIGNED_LONG_LONG3: RTformat = RTformat(298); +} +impl RTformat { + #[doc = "< sizeof(ULONG_LONG)*4"] + pub const RT_FORMAT_UNSIGNED_LONG_LONG4: RTformat = RTformat(299); +} +impl RTformat { + #[doc = "< Block Compressed RGB + optional 1-bit alpha BC1,"] + #[doc = "sizeof(UINT)*2"] + pub const RT_FORMAT_UNSIGNED_BC1: RTformat = RTformat(300); +} +impl RTformat { + #[doc = "< Block Compressed RGB + 4-bit alpha BC2,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_BC2: RTformat = RTformat(301); +} +impl RTformat { + #[doc = "< Block Compressed RGBA BC3,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_BC3: RTformat = RTformat(302); +} +impl RTformat { + #[doc = "< Block Compressed unsigned grayscale BC4,"] + #[doc = "sizeof(UINT)*2"] + pub const RT_FORMAT_UNSIGNED_BC4: RTformat = RTformat(303); +} +impl RTformat { + #[doc = "< Block Compressed signed grayscale BC4,"] + #[doc = "sizeof(UINT)*2"] + pub const RT_FORMAT_BC4: RTformat = RTformat(304); +} +impl RTformat { + #[doc = "< Block Compressed unsigned 2 x grayscale BC5,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_BC5: RTformat = RTformat(305); +} +impl RTformat { + #[doc = "< Block compressed signed 2 x grayscale BC5,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_BC5: RTformat = RTformat(306); +} +impl RTformat { + #[doc = "< Block compressed BC6 unsigned half-float,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_BC6H: RTformat = RTformat(307); +} +impl RTformat { + #[doc = "< Block compressed BC6 signed half-float,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_BC6H: RTformat = RTformat(308); +} +impl RTformat { + #[doc = "< Block compressed BC7,"] + #[doc = "sizeof(UINT)*4"] + pub const RT_FORMAT_UNSIGNED_BC7: RTformat = RTformat(309); +} +#[repr(transparent)] +#[doc = " OptiX formats"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTformat(pub ::std::os::raw::c_uint); +impl RTobjecttype { + #[doc = "< Object Type Unknown"] + pub const RT_OBJECTTYPE_UNKNOWN: RTobjecttype = RTobjecttype(512); +} +impl RTobjecttype { + #[doc = "< Group Type"] + pub const RT_OBJECTTYPE_GROUP: RTobjecttype = RTobjecttype(513); +} +impl RTobjecttype { + #[doc = "< Geometry Group Type"] + pub const RT_OBJECTTYPE_GEOMETRY_GROUP: RTobjecttype = RTobjecttype(514); +} +impl RTobjecttype { + #[doc = "< Transform Type"] + pub const RT_OBJECTTYPE_TRANSFORM: RTobjecttype = RTobjecttype(515); +} +impl RTobjecttype { + #[doc = "< Selector Type"] + pub const RT_OBJECTTYPE_SELECTOR: RTobjecttype = RTobjecttype(516); +} +impl RTobjecttype { + #[doc = "< Geometry Instance Type"] + pub const RT_OBJECTTYPE_GEOMETRY_INSTANCE: RTobjecttype = RTobjecttype(517); +} +impl RTobjecttype { + #[doc = "< Buffer Type"] + pub const RT_OBJECTTYPE_BUFFER: RTobjecttype = RTobjecttype(518); +} +impl RTobjecttype { + #[doc = "< Texture Sampler Type"] + pub const RT_OBJECTTYPE_TEXTURE_SAMPLER: RTobjecttype = RTobjecttype(519); +} +impl RTobjecttype { + #[doc = "< Object Type"] + pub const RT_OBJECTTYPE_OBJECT: RTobjecttype = RTobjecttype(520); +} +impl RTobjecttype { + #[doc = "< Matrix Float 2x2"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT2x2: RTobjecttype = RTobjecttype(521); +} +impl RTobjecttype { + #[doc = "< Matrix Float 2x3"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT2x3: RTobjecttype = RTobjecttype(522); +} +impl RTobjecttype { + #[doc = "< Matrix Float 2x4"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT2x4: RTobjecttype = RTobjecttype(523); +} +impl RTobjecttype { + #[doc = "< Matrix Float 3x2"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT3x2: RTobjecttype = RTobjecttype(524); +} +impl RTobjecttype { + #[doc = "< Matrix Float 3x3"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT3x3: RTobjecttype = RTobjecttype(525); +} +impl RTobjecttype { + #[doc = "< Matrix Float 3x4"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT3x4: RTobjecttype = RTobjecttype(526); +} +impl RTobjecttype { + #[doc = "< Matrix Float 4x2"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT4x2: RTobjecttype = RTobjecttype(527); +} +impl RTobjecttype { + #[doc = "< Matrix Float 4x3"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT4x3: RTobjecttype = RTobjecttype(528); +} +impl RTobjecttype { + #[doc = "< Matrix Float 4x4"] + pub const RT_OBJECTTYPE_MATRIX_FLOAT4x4: RTobjecttype = RTobjecttype(529); +} +impl RTobjecttype { + #[doc = "< Float Type"] + pub const RT_OBJECTTYPE_FLOAT: RTobjecttype = RTobjecttype(530); +} +impl RTobjecttype { + #[doc = "< Float2 Type"] + pub const RT_OBJECTTYPE_FLOAT2: RTobjecttype = RTobjecttype(531); +} +impl RTobjecttype { + #[doc = "< Float3 Type"] + pub const RT_OBJECTTYPE_FLOAT3: RTobjecttype = RTobjecttype(532); +} +impl RTobjecttype { + #[doc = "< Float4 Type"] + pub const RT_OBJECTTYPE_FLOAT4: RTobjecttype = RTobjecttype(533); +} +impl RTobjecttype { + #[doc = "< 32 Bit Integer Type"] + pub const RT_OBJECTTYPE_INT: RTobjecttype = RTobjecttype(534); +} +impl RTobjecttype { + #[doc = "< 32 Bit Integer2 Type"] + pub const RT_OBJECTTYPE_INT2: RTobjecttype = RTobjecttype(535); +} +impl RTobjecttype { + #[doc = "< 32 Bit Integer3 Type"] + pub const RT_OBJECTTYPE_INT3: RTobjecttype = RTobjecttype(536); +} +impl RTobjecttype { + #[doc = "< 32 Bit Integer4 Type"] + pub const RT_OBJECTTYPE_INT4: RTobjecttype = RTobjecttype(537); +} +impl RTobjecttype { + #[doc = "< 32 Bit Unsigned Integer Type"] + pub const RT_OBJECTTYPE_UNSIGNED_INT: RTobjecttype = RTobjecttype(538); +} +impl RTobjecttype { + #[doc = "< 32 Bit Unsigned Integer2 Type"] + pub const RT_OBJECTTYPE_UNSIGNED_INT2: RTobjecttype = RTobjecttype(539); +} +impl RTobjecttype { + #[doc = "< 32 Bit Unsigned Integer3 Type"] + pub const RT_OBJECTTYPE_UNSIGNED_INT3: RTobjecttype = RTobjecttype(540); +} +impl RTobjecttype { + #[doc = "< 32 Bit Unsigned Integer4 Type"] + pub const RT_OBJECTTYPE_UNSIGNED_INT4: RTobjecttype = RTobjecttype(541); +} +impl RTobjecttype { + #[doc = "< User Object Type"] + pub const RT_OBJECTTYPE_USER: RTobjecttype = RTobjecttype(542); +} +impl RTobjecttype { + #[doc = "< Object Type Program - Added in OptiX 3.0"] + pub const RT_OBJECTTYPE_PROGRAM: RTobjecttype = RTobjecttype(543); +} +impl RTobjecttype { + #[doc = "< Object Type Command List - Added in OptiX 5.0"] + pub const RT_OBJECTTYPE_COMMANDLIST: RTobjecttype = RTobjecttype(544); +} +impl RTobjecttype { + #[doc = "< Object Type Postprocessing Stage - Added in OptiX 5.0"] + pub const RT_OBJECTTYPE_POSTPROCESSINGSTAGE: RTobjecttype = RTobjecttype(545); +} +impl RTobjecttype { + #[doc = "< 64 Bit Integer Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_LONG_LONG: RTobjecttype = RTobjecttype(546); +} +impl RTobjecttype { + #[doc = "< 64 Bit Integer2 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_LONG_LONG2: RTobjecttype = RTobjecttype(547); +} +impl RTobjecttype { + #[doc = "< 64 Bit Integer3 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_LONG_LONG3: RTobjecttype = RTobjecttype(548); +} +impl RTobjecttype { + #[doc = "< 64 Bit Integer4 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_LONG_LONG4: RTobjecttype = RTobjecttype(549); +} +impl RTobjecttype { + #[doc = "< 64 Bit Unsigned Integer Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_UNSIGNED_LONG_LONG: RTobjecttype = RTobjecttype(550); +} +impl RTobjecttype { + #[doc = "< 64 Bit Unsigned Integer2 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_UNSIGNED_LONG_LONG2: RTobjecttype = RTobjecttype(551); +} +impl RTobjecttype { + #[doc = "< 64 Bit Unsigned Integer3 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_UNSIGNED_LONG_LONG3: RTobjecttype = RTobjecttype(552); +} +impl RTobjecttype { + #[doc = "< 64 Bit Unsigned Integer4 Type - Added in Optix 6.0"] + pub const RT_OBJECTTYPE_UNSIGNED_LONG_LONG4: RTobjecttype = RTobjecttype(553); +} +#[repr(transparent)] +#[doc = " OptiX Object Types"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTobjecttype(pub ::std::os::raw::c_uint); +impl RTwrapmode { + #[doc = "< Wrap repeat"] + pub const RT_WRAP_REPEAT: RTwrapmode = RTwrapmode(0); +} +impl RTwrapmode { + #[doc = "< Clamp to edge"] + pub const RT_WRAP_CLAMP_TO_EDGE: RTwrapmode = RTwrapmode(1); +} +impl RTwrapmode { + #[doc = "< Mirror"] + pub const RT_WRAP_MIRROR: RTwrapmode = RTwrapmode(2); +} +impl RTwrapmode { + #[doc = "< Clamp to border"] + pub const RT_WRAP_CLAMP_TO_BORDER: RTwrapmode = RTwrapmode(3); +} +#[repr(transparent)] +#[doc = " Wrap mode"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTwrapmode(pub ::std::os::raw::c_uint); +impl RTfiltermode { + #[doc = "< Nearest"] + pub const RT_FILTER_NEAREST: RTfiltermode = RTfiltermode(0); +} +impl RTfiltermode { + #[doc = "< Linear"] + pub const RT_FILTER_LINEAR: RTfiltermode = RTfiltermode(1); +} +impl RTfiltermode { + #[doc = "< No filter"] + pub const RT_FILTER_NONE: RTfiltermode = RTfiltermode(2); +} +#[repr(transparent)] +#[doc = " Filter mode"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTfiltermode(pub ::std::os::raw::c_uint); +impl RTtexturereadmode { + #[doc = "< Read element type"] + pub const RT_TEXTURE_READ_ELEMENT_TYPE: RTtexturereadmode = RTtexturereadmode(0); +} +impl RTtexturereadmode { + #[doc = "< Read normalized float"] + pub const RT_TEXTURE_READ_NORMALIZED_FLOAT: RTtexturereadmode = RTtexturereadmode(1); +} +impl RTtexturereadmode { + #[doc = "< Read element type and apply sRGB to linear conversion during texture read for 8-bit integer buffer formats"] + pub const RT_TEXTURE_READ_ELEMENT_TYPE_SRGB: RTtexturereadmode = RTtexturereadmode(2); +} +impl RTtexturereadmode { + #[doc = "< Read normalized float and apply sRGB to linear conversion during texture read for 8-bit integer buffer formats"] + pub const RT_TEXTURE_READ_NORMALIZED_FLOAT_SRGB: RTtexturereadmode = RTtexturereadmode(3); +} +#[repr(transparent)] +#[doc = " Texture read mode"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTtexturereadmode(pub ::std::os::raw::c_uint); +impl RTgltarget { + #[doc = "< GL texture 2D"] + pub const RT_TARGET_GL_TEXTURE_2D: RTgltarget = RTgltarget(0); +} +impl RTgltarget { + #[doc = "< GL texture rectangle"] + pub const RT_TARGET_GL_TEXTURE_RECTANGLE: RTgltarget = RTgltarget(1); +} +impl RTgltarget { + #[doc = "< GL texture 3D"] + pub const RT_TARGET_GL_TEXTURE_3D: RTgltarget = RTgltarget(2); +} +impl RTgltarget { + #[doc = "< GL render buffer"] + pub const RT_TARGET_GL_RENDER_BUFFER: RTgltarget = RTgltarget(3); +} +impl RTgltarget { + #[doc = "< GL texture 1D"] + pub const RT_TARGET_GL_TEXTURE_1D: RTgltarget = RTgltarget(4); +} +impl RTgltarget { + #[doc = "< GL array of 1D textures"] + pub const RT_TARGET_GL_TEXTURE_1D_ARRAY: RTgltarget = RTgltarget(5); +} +impl RTgltarget { + #[doc = "< GL array of 2D textures"] + pub const RT_TARGET_GL_TEXTURE_2D_ARRAY: RTgltarget = RTgltarget(6); +} +impl RTgltarget { + #[doc = "< GL cube map texture"] + pub const RT_TARGET_GL_TEXTURE_CUBE_MAP: RTgltarget = RTgltarget(7); +} +impl RTgltarget { + #[doc = "< GL array of cube maps"] + pub const RT_TARGET_GL_TEXTURE_CUBE_MAP_ARRAY: RTgltarget = RTgltarget(8); +} +#[repr(transparent)] +#[doc = " GL Target"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTgltarget(pub ::std::os::raw::c_uint); +impl RTtextureindexmode { + #[doc = "< Texture Index normalized coordinates"] + pub const RT_TEXTURE_INDEX_NORMALIZED_COORDINATES: RTtextureindexmode = RTtextureindexmode(0); +} +impl RTtextureindexmode { + #[doc = "< Texture Index Array"] + pub const RT_TEXTURE_INDEX_ARRAY_INDEX: RTtextureindexmode = RTtextureindexmode(1); +} +#[repr(transparent)] +#[doc = " Texture index mode"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTtextureindexmode(pub ::std::os::raw::c_uint); +impl RTbuffertype { + #[doc = "< Input buffer for the GPU"] + pub const RT_BUFFER_INPUT: RTbuffertype = RTbuffertype(1); +} +impl RTbuffertype { + #[doc = "< Output buffer for the GPU"] + pub const RT_BUFFER_OUTPUT: RTbuffertype = RTbuffertype(2); +} +impl RTbuffertype { + #[doc = "< Ouput/Input buffer for the GPU"] + pub const RT_BUFFER_INPUT_OUTPUT: RTbuffertype = RTbuffertype(3); +} +impl RTbuffertype { + #[doc = "< Progressive stream buffer"] + pub const RT_BUFFER_PROGRESSIVE_STREAM: RTbuffertype = RTbuffertype(16); +} +#[repr(transparent)] +#[doc = " Buffer type"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTbuffertype(pub ::std::os::raw::c_uint); +impl RTbufferflag { + #[doc = "< An @ref RT_BUFFER_INPUT_OUTPUT has separate copies on each device that are not synchronized"] + pub const RT_BUFFER_GPU_LOCAL: RTbufferflag = RTbufferflag(4); +} +impl RTbufferflag { + #[doc = "< A CUDA Interop buffer will only be synchronized across devices when dirtied by @ref rtBufferMap or @ref rtBufferMarkDirty"] + pub const RT_BUFFER_COPY_ON_DIRTY: RTbufferflag = RTbufferflag(8); +} +impl RTbufferflag { + #[doc = "< An @ref RT_BUFFER_INPUT for which a synchronize is forced on unmapping from host and the host memory is freed"] + pub const RT_BUFFER_DISCARD_HOST_MEMORY: RTbufferflag = RTbufferflag(32); +} +impl RTbufferflag { + #[doc = "< Depth specifies the number of layers, not the depth of a 3D array"] + pub const RT_BUFFER_LAYERED: RTbufferflag = RTbufferflag(2097152); +} +impl RTbufferflag { + #[doc = "< Enables creation of cubemaps. If this flag is set, Width must be equal to Height, and Depth must be six. If the @ref RT_BUFFER_LAYERED flag is also set, then Depth must be a multiple of six"] + pub const RT_BUFFER_CUBEMAP: RTbufferflag = RTbufferflag(4194304); +} +#[repr(transparent)] +#[doc = " Buffer flags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTbufferflag(pub ::std::os::raw::c_uint); +impl RTbuffermapflag { + #[doc = "< Map buffer memory for reading"] + pub const RT_BUFFER_MAP_READ: RTbuffermapflag = RTbuffermapflag(1); +} +impl RTbuffermapflag { + #[doc = "< Map buffer memory for both reading and writing"] + pub const RT_BUFFER_MAP_READ_WRITE: RTbuffermapflag = RTbuffermapflag(2); +} +impl RTbuffermapflag { + #[doc = "< Map buffer memory for writing"] + pub const RT_BUFFER_MAP_WRITE: RTbuffermapflag = RTbuffermapflag(4); +} +impl RTbuffermapflag { + #[doc = "< Map buffer memory for writing, with the previous contents being undefined"] + pub const RT_BUFFER_MAP_WRITE_DISCARD: RTbuffermapflag = RTbuffermapflag(8); +} +#[repr(transparent)] +#[doc = " Buffer mapping flags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTbuffermapflag(pub ::std::os::raw::c_uint); +impl RTexception { + #[doc = "< Payload access out of bounds - Added in OptiX 6.0"] + pub const RT_EXCEPTION_PAYLOAD_ACCESS_OUT_OF_BOUNDS: RTexception = RTexception(1003); +} +impl RTexception { + #[doc = "< Exception code of user exception out of bounds - Added in OptiX 6.0"] + pub const RT_EXCEPTION_USER_EXCEPTION_CODE_OUT_OF_BOUNDS: RTexception = RTexception(1004); +} +impl RTexception { + #[doc = "< Trace depth exceeded - Added in Optix 6.0"] + pub const RT_EXCEPTION_TRACE_DEPTH_EXCEEDED: RTexception = RTexception(1005); +} +impl RTexception { + #[doc = "< Program ID not valid"] + pub const RT_EXCEPTION_PROGRAM_ID_INVALID: RTexception = RTexception(1006); +} +impl RTexception { + #[doc = "< Texture ID not valid"] + pub const RT_EXCEPTION_TEXTURE_ID_INVALID: RTexception = RTexception(1007); +} +impl RTexception { + #[doc = "< Buffer ID not valid"] + pub const RT_EXCEPTION_BUFFER_ID_INVALID: RTexception = RTexception(1018); +} +impl RTexception { + #[doc = "< Index out of bounds"] + pub const RT_EXCEPTION_INDEX_OUT_OF_BOUNDS: RTexception = RTexception(1019); +} +impl RTexception { + #[doc = "< Stack overflow"] + pub const RT_EXCEPTION_STACK_OVERFLOW: RTexception = RTexception(1020); +} +impl RTexception { + #[doc = "< Buffer index out of bounds"] + pub const RT_EXCEPTION_BUFFER_INDEX_OUT_OF_BOUNDS: RTexception = RTexception(1021); +} +impl RTexception { + #[doc = "< Invalid ray"] + pub const RT_EXCEPTION_INVALID_RAY: RTexception = RTexception(1022); +} +impl RTexception { + #[doc = "< Internal error"] + pub const RT_EXCEPTION_INTERNAL_ERROR: RTexception = RTexception(1023); +} +impl RTexception { + #[doc = "< First user exception code"] + pub const RT_EXCEPTION_USER: RTexception = RTexception(1024); +} +impl RTexception { + #[doc = "< Last user exception code"] + pub const RT_EXCEPTION_USER_MAX: RTexception = RTexception(65535); +} +impl RTexception { + #[doc = "< All exceptions"] + pub const RT_EXCEPTION_ALL: RTexception = RTexception(2147483647); +} +#[repr(transparent)] +#[doc = " Exceptions"] +#[doc = ""] +#[doc = " See also"] +#[doc = " @ref rtContextSetExceptionEnabled,"] +#[doc = " @ref rtContextGetExceptionEnabled,"] +#[doc = " @ref rtGetExceptionCode,"] +#[doc = " @ref rtThrow,"] +#[doc = " @ref rtPrintf"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTexception(pub ::std::os::raw::c_uint); +impl RTresult { + #[doc = "< Success"] + pub const RT_SUCCESS: RTresult = RTresult(0); +} +impl RTresult { + #[doc = "< Timeout callback"] + pub const RT_TIMEOUT_CALLBACK: RTresult = RTresult(256); +} +impl RTresult { + #[doc = "< Invalid Context"] + pub const RT_ERROR_INVALID_CONTEXT: RTresult = RTresult(1280); +} +impl RTresult { + #[doc = "< Invalid Value"] + pub const RT_ERROR_INVALID_VALUE: RTresult = RTresult(1281); +} +impl RTresult { + #[doc = "< Timeout callback"] + pub const RT_ERROR_MEMORY_ALLOCATION_FAILED: RTresult = RTresult(1282); +} +impl RTresult { + #[doc = "< Type Mismatch"] + pub const RT_ERROR_TYPE_MISMATCH: RTresult = RTresult(1283); +} +impl RTresult { + #[doc = "< Variable not found"] + pub const RT_ERROR_VARIABLE_NOT_FOUND: RTresult = RTresult(1284); +} +impl RTresult { + #[doc = "< Variable redeclared"] + pub const RT_ERROR_VARIABLE_REDECLARED: RTresult = RTresult(1285); +} +impl RTresult { + #[doc = "< Illegal symbol"] + pub const RT_ERROR_ILLEGAL_SYMBOL: RTresult = RTresult(1286); +} +impl RTresult { + #[doc = "< Invalid source"] + pub const RT_ERROR_INVALID_SOURCE: RTresult = RTresult(1287); +} +impl RTresult { + #[doc = "< Version mismatch"] + pub const RT_ERROR_VERSION_MISMATCH: RTresult = RTresult(1288); +} +impl RTresult { + #[doc = "< Object creation failed"] + pub const RT_ERROR_OBJECT_CREATION_FAILED: RTresult = RTresult(1536); +} +impl RTresult { + #[doc = "< No device"] + pub const RT_ERROR_NO_DEVICE: RTresult = RTresult(1537); +} +impl RTresult { + #[doc = "< Invalid device"] + pub const RT_ERROR_INVALID_DEVICE: RTresult = RTresult(1538); +} +impl RTresult { + #[doc = "< Invalid image"] + pub const RT_ERROR_INVALID_IMAGE: RTresult = RTresult(1539); +} +impl RTresult { + #[doc = "< File not found"] + pub const RT_ERROR_FILE_NOT_FOUND: RTresult = RTresult(1540); +} +impl RTresult { + #[doc = "< Already mapped"] + pub const RT_ERROR_ALREADY_MAPPED: RTresult = RTresult(1541); +} +impl RTresult { + #[doc = "< Invalid driver version"] + pub const RT_ERROR_INVALID_DRIVER_VERSION: RTresult = RTresult(1542); +} +impl RTresult { + #[doc = "< Context creation failed"] + pub const RT_ERROR_CONTEXT_CREATION_FAILED: RTresult = RTresult(1543); +} +impl RTresult { + #[doc = "< Resource not registered"] + pub const RT_ERROR_RESOURCE_NOT_REGISTERED: RTresult = RTresult(1544); +} +impl RTresult { + #[doc = "< Resource already registered"] + pub const RT_ERROR_RESOURCE_ALREADY_REGISTERED: RTresult = RTresult(1545); +} +impl RTresult { + #[doc = "< OptiX DLL failed to load"] + pub const RT_ERROR_OPTIX_NOT_LOADED: RTresult = RTresult(1546); +} +impl RTresult { + #[doc = "< Denoiser DLL failed to load"] + pub const RT_ERROR_DENOISER_NOT_LOADED: RTresult = RTresult(1547); +} +impl RTresult { + #[doc = "< SSIM predictor DLL failed to load"] + pub const RT_ERROR_SSIM_PREDICTOR_NOT_LOADED: RTresult = RTresult(1548); +} +impl RTresult { + #[doc = "< Driver version retrieval failed"] + pub const RT_ERROR_DRIVER_VERSION_FAILED: RTresult = RTresult(1549); +} +impl RTresult { + #[doc = "< No write permission on disk cache file"] + pub const RT_ERROR_DATABASE_FILE_PERMISSIONS: RTresult = RTresult(1550); +} +impl RTresult { + #[doc = "< Launch failed"] + pub const RT_ERROR_LAUNCH_FAILED: RTresult = RTresult(2304); +} +impl RTresult { + #[doc = "< Not supported"] + pub const RT_ERROR_NOT_SUPPORTED: RTresult = RTresult(2560); +} +impl RTresult { + #[doc = "< Connection failed"] + pub const RT_ERROR_CONNECTION_FAILED: RTresult = RTresult(2816); +} +impl RTresult { + #[doc = "< Authentication failed"] + pub const RT_ERROR_AUTHENTICATION_FAILED: RTresult = RTresult(2817); +} +impl RTresult { + #[doc = "< Connection already exists"] + pub const RT_ERROR_CONNECTION_ALREADY_EXISTS: RTresult = RTresult(2818); +} +impl RTresult { + #[doc = "< Network component failed to load"] + pub const RT_ERROR_NETWORK_LOAD_FAILED: RTresult = RTresult(2819); +} +impl RTresult { + #[doc = "< Network initialization failed"] + pub const RT_ERROR_NETWORK_INIT_FAILED: RTresult = RTresult(2820); +} +impl RTresult { + #[doc = "< No cluster is running"] + pub const RT_ERROR_CLUSTER_NOT_RUNNING: RTresult = RTresult(2822); +} +impl RTresult { + #[doc = "< Cluster is already running"] + pub const RT_ERROR_CLUSTER_ALREADY_RUNNING: RTresult = RTresult(2823); +} +impl RTresult { + #[doc = "< Not enough free nodes"] + pub const RT_ERROR_INSUFFICIENT_FREE_NODES: RTresult = RTresult(2824); +} +impl RTresult { + #[doc = "< Invalid global attribute"] + pub const RT_ERROR_INVALID_GLOBAL_ATTRIBUTE: RTresult = RTresult(3072); +} +impl RTresult { + #[doc = "< Error unknown"] + pub const RT_ERROR_UNKNOWN: RTresult = RTresult(-1); +} +#[repr(transparent)] +#[doc = " Result"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTresult(pub ::std::os::raw::c_int); +impl RTdeviceattribute { + #[doc = "< Max Threads per Block sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: RTdeviceattribute = RTdeviceattribute(0); +} +impl RTdeviceattribute { + #[doc = "< Clock rate sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_CLOCK_RATE: RTdeviceattribute = RTdeviceattribute(1); +} +impl RTdeviceattribute { + #[doc = "< Multiprocessor count sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT: RTdeviceattribute = RTdeviceattribute(2); +} +impl RTdeviceattribute { + #[doc = "< Execution timeout enabled sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_EXECUTION_TIMEOUT_ENABLED: RTdeviceattribute = + RTdeviceattribute(3); +} +impl RTdeviceattribute { + #[doc = "< Hardware Texture count sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_MAX_HARDWARE_TEXTURE_COUNT: RTdeviceattribute = + RTdeviceattribute(4); +} +impl RTdeviceattribute { + #[doc = "< Attribute Name"] + pub const RT_DEVICE_ATTRIBUTE_NAME: RTdeviceattribute = RTdeviceattribute(5); +} +impl RTdeviceattribute { + #[doc = "< Compute Capabilities sizeof(int2)"] + pub const RT_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY: RTdeviceattribute = RTdeviceattribute(6); +} +impl RTdeviceattribute { + #[doc = "< Total Memory sizeof(RTsize)"] + pub const RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY: RTdeviceattribute = RTdeviceattribute(7); +} +impl RTdeviceattribute { + #[doc = "< TCC driver sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_TCC_DRIVER: RTdeviceattribute = RTdeviceattribute(8); +} +impl RTdeviceattribute { + #[doc = "< CUDA device ordinal sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL: RTdeviceattribute = RTdeviceattribute(9); +} +impl RTdeviceattribute { + #[doc = "< PCI Bus Id"] + pub const RT_DEVICE_ATTRIBUTE_PCI_BUS_ID: RTdeviceattribute = RTdeviceattribute(10); +} +impl RTdeviceattribute { + #[doc = "< Ordinals of compatible devices sizeof(int=N) + N*sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_COMPATIBLE_DEVICES: RTdeviceattribute = RTdeviceattribute(11); +} +impl RTdeviceattribute { + #[doc = "< RT core version (0 for no support, 10 for version 1.0) sizeof(int)"] + pub const RT_DEVICE_ATTRIBUTE_RTCORE_VERSION: RTdeviceattribute = RTdeviceattribute(12); +} +#[repr(transparent)] +#[doc = " Device attributes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTdeviceattribute(pub ::std::os::raw::c_uint); +impl RTglobalattribute { + #[doc = "< sizeof(int)"] + pub const RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MAJOR: RTglobalattribute = + RTglobalattribute(1); +} +impl RTglobalattribute { + #[doc = "< sizeof(int)"] + pub const RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MINOR: RTglobalattribute = + RTglobalattribute(2); +} +impl RTglobalattribute { + #[doc = "< sizeof(int)"] + pub const RT_GLOBAL_ATTRIBUTE_ENABLE_RTX: RTglobalattribute = RTglobalattribute(268435456); +} +impl RTglobalattribute { + #[doc = "< Knobs string"] + pub const RT_GLOBAL_ATTRIBUTE_DEVELOPER_OPTIONS: RTglobalattribute = + RTglobalattribute(268435457); +} +#[repr(transparent)] +#[doc = " Global attributes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTglobalattribute(pub ::std::os::raw::c_uint); +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_MAX_TEXTURE_COUNT: RTcontextattribute = RTcontextattribute(0); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_CPU_NUM_THREADS: RTcontextattribute = RTcontextattribute(1); +} +impl RTcontextattribute { + #[doc = "< sizeof(RTsize)"] + pub const RT_CONTEXT_ATTRIBUTE_USED_HOST_MEMORY: RTcontextattribute = RTcontextattribute(2); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_GPU_PAGING_ACTIVE: RTcontextattribute = RTcontextattribute(3); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_GPU_PAGING_FORCED_OFF: RTcontextattribute = + RTcontextattribute(4); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_DISK_CACHE_ENABLED: RTcontextattribute = RTcontextattribute(5); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_PREFER_FAST_RECOMPILES: RTcontextattribute = + RTcontextattribute(6); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_FORCE_INLINE_USER_FUNCTIONS: RTcontextattribute = + RTcontextattribute(7); +} +impl RTcontextattribute { + #[doc = "< 32"] + pub const RT_CONTEXT_ATTRIBUTE_OPTIX_SALT: RTcontextattribute = RTcontextattribute(8); +} +impl RTcontextattribute { + #[doc = "< 32"] + pub const RT_CONTEXT_ATTRIBUTE_VENDOR_SALT: RTcontextattribute = RTcontextattribute(9); +} +impl RTcontextattribute { + #[doc = "< variable"] + pub const RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY: RTcontextattribute = RTcontextattribute(10); +} +impl RTcontextattribute { + #[doc = "< sizeof(char*)"] + pub const RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION: RTcontextattribute = RTcontextattribute(11); +} +impl RTcontextattribute { + #[doc = "< sizeof(RTsize[2])"] + pub const RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS: RTcontextattribute = + RTcontextattribute(12); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_PREFER_WATERTIGHT_TRAVERSAL: RTcontextattribute = + RTcontextattribute(13); +} +impl RTcontextattribute { + #[doc = "< sizeof(int)"] + pub const RT_CONTEXT_ATTRIBUTE_MAX_CONCURRENT_LAUNCHES: RTcontextattribute = + RTcontextattribute(14); +} +impl RTcontextattribute { + #[doc = "< sizeof(RTsize)"] + pub const RT_CONTEXT_ATTRIBUTE_AVAILABLE_DEVICE_MEMORY: RTcontextattribute = + RTcontextattribute(268435456); +} +#[repr(transparent)] +#[doc = " Context attributes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTcontextattribute(pub ::std::os::raw::c_uint); +impl RTbufferattribute { + #[doc = "< Format string"] + pub const RT_BUFFER_ATTRIBUTE_STREAM_FORMAT: RTbufferattribute = RTbufferattribute(0); +} +impl RTbufferattribute { + #[doc = "< sizeof(int)"] + pub const RT_BUFFER_ATTRIBUTE_STREAM_BITRATE: RTbufferattribute = RTbufferattribute(1); +} +impl RTbufferattribute { + #[doc = "< sizeof(int)"] + pub const RT_BUFFER_ATTRIBUTE_STREAM_FPS: RTbufferattribute = RTbufferattribute(2); +} +impl RTbufferattribute { + #[doc = "< sizeof(float)"] + pub const RT_BUFFER_ATTRIBUTE_STREAM_GAMMA: RTbufferattribute = RTbufferattribute(3); +} +impl RTbufferattribute { + #[doc = "< sizeof(int)"] + pub const RT_BUFFER_ATTRIBUTE_PAGE_SIZE: RTbufferattribute = RTbufferattribute(4); +} +#[repr(transparent)] +#[doc = " Buffer attributes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTbufferattribute(pub ::std::os::raw::c_uint); +impl RTmotionbordermode { + #[doc = "< Clamp outside of bounds"] + pub const RT_MOTIONBORDERMODE_CLAMP: RTmotionbordermode = RTmotionbordermode(0); +} +impl RTmotionbordermode { + #[doc = "< Vanish outside of bounds"] + pub const RT_MOTIONBORDERMODE_VANISH: RTmotionbordermode = RTmotionbordermode(1); +} +#[repr(transparent)] +#[doc = " Motion border modes"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTmotionbordermode(pub ::std::os::raw::c_uint); +impl RTmotionkeytype { + #[doc = "< No motion keys set"] + pub const RT_MOTIONKEYTYPE_NONE: RTmotionkeytype = RTmotionkeytype(0); +} +impl RTmotionkeytype { + #[doc = "< Affine matrix format - 12 floats"] + pub const RT_MOTIONKEYTYPE_MATRIX_FLOAT12: RTmotionkeytype = RTmotionkeytype(1); +} +impl RTmotionkeytype { + #[doc = "< SRT format - 16 floats"] + pub const RT_MOTIONKEYTYPE_SRT_FLOAT16: RTmotionkeytype = RTmotionkeytype(2); +} +#[repr(transparent)] +#[doc = " Motion key type"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTmotionkeytype(pub ::std::os::raw::c_uint); +impl RTgeometrybuildflags { + #[doc = "< No special flags set"] + pub const RT_GEOMETRY_BUILD_FLAG_NONE: RTgeometrybuildflags = RTgeometrybuildflags(0); +} +impl RTgeometrybuildflags { + #[doc = "< User buffers are released after consumption by acceleration structure build"] + pub const RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS: RTgeometrybuildflags = + RTgeometrybuildflags(16); +} +#[repr(transparent)] +#[doc = " GeometryX build flags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTgeometrybuildflags(pub ::std::os::raw::c_uint); +impl RTgeometryflags { + #[doc = "< No special flags set"] + pub const RT_GEOMETRY_FLAG_NONE: RTgeometryflags = RTgeometryflags(0); +} +impl RTgeometryflags { + #[doc = "< Disable any-hit program execution (execution will be skipped,including the no-op any-hit program"] + #[doc = "used when an any-hit program is not specified)."] + #[doc = "Can be overridden by ray and instance flags, precedence: RTrayflags > RTinstanceflags > RTgeometryflags"] + pub const RT_GEOMETRY_FLAG_DISABLE_ANYHIT: RTgeometryflags = RTgeometryflags(1); +} +impl RTgeometryflags { + #[doc = "< Disable primitive splitting to avoid potential multiple any-hit program execution for a single intersection"] + pub const RT_GEOMETRY_FLAG_NO_SPLITTING: RTgeometryflags = RTgeometryflags(2); +} +#[repr(transparent)] +#[doc = " Material-dependent flags set on Geometry/GeometryTriangles"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTgeometryflags(pub ::std::os::raw::c_uint); +impl RTinstanceflags { + #[doc = "< No special flag set"] + pub const RT_INSTANCE_FLAG_NONE: RTinstanceflags = RTinstanceflags(0); +} +impl RTinstanceflags { + #[doc = "< Prevent triangles from getting culled due to face orientation (overrides ray culling flags)."] + pub const RT_INSTANCE_FLAG_DISABLE_TRIANGLE_CULLING: RTinstanceflags = RTinstanceflags(1); +} +impl RTinstanceflags { + #[doc = "< Flip triangle orientation. This affects front/back face culling."] + pub const RT_INSTANCE_FLAG_FLIP_TRIANGLE_FACING: RTinstanceflags = RTinstanceflags(2); +} +impl RTinstanceflags { + #[doc = "< Disable any-hit program execution (including the no-op any-hit program"] + #[doc = "used when an any-hit program is not specified)."] + #[doc = "This may yield significantly higher performance even in cases"] + #[doc = "where no any-hit programs are set."] + #[doc = "Mutually exclusive with RT_INSTANCE_FLAG_FORCE_ANYHIT."] + #[doc = "If set, overrides any potentially set @ref RT_RAY_FLAG_FORCE_ANYHIT, @ref RT_RAY_FLAG_DISABLE_ANYHIT, @ref RT_GEOMETRY_FLAG_DISABLE_ANYHIT."] + #[doc = "Can be overridden by ray flag @ref RT_RAY_FLAG_FORCE_ANYHIT."] + #[doc = "Precedence: RTrayflags > RTinstanceflags > RTgeometryflags"] + pub const RT_INSTANCE_FLAG_DISABLE_ANYHIT: RTinstanceflags = RTinstanceflags(4); +} +impl RTinstanceflags { + #[doc = "< Force any-hit program execution."] + #[doc = "Mutually exclusive with RT_INSTANCE_FLAG_DISABLE_ANYHIT."] + #[doc = "If set, overrides any potentially set @ref RT_RAY_FLAG_FORCE_ANYHIT, @ref RT_RAY_FLAG_DISABLE_ANYHIT, @ref RT_GEOMETRY_FLAG_DISABLE_ANYHIT."] + #[doc = "Can be overridden by ray flag @ref RT_RAY_FLAG_DISABLE_ANYHIT."] + #[doc = "Overriding precedence: RTrayflags > RTinstanceflags > RTgeometryflags"] + pub const RT_INSTANCE_FLAG_FORCE_ANYHIT: RTinstanceflags = RTinstanceflags(8); +} +#[repr(transparent)] +#[doc = " Instance flags which override the behavior of geometry."] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTinstanceflags(pub ::std::os::raw::c_uint); +impl RTrayflags { + pub const RT_RAY_FLAG_NONE: RTrayflags = RTrayflags(0); +} +impl RTrayflags { + #[doc = "< Disable any-hit program execution for the ray (execution will be skipped,including the no-op any-hit program"] + #[doc = "used when an any-hit program is not specified)."] + #[doc = "Mutually exclusive with RT_RAY_FLAG_FORCE_ANYHIT."] + #[doc = "If set, overrides any potentially set @ref RT_INSTANCE_FLAG_FORCE_ANYHIT."] + #[doc = "Overriding precedence: RTrayflags > RTinstanceflags > RTgeometryflags"] + pub const RT_RAY_FLAG_DISABLE_ANYHIT: RTrayflags = RTrayflags(1); +} +impl RTrayflags { + #[doc = "< Force any-hit program execution for the ray. See @ref RT_RAY_FLAG_DISABLE_ANYHIT."] + #[doc = "Mutually exclusive with RT_RAY_FLAG_DISABLE_ANYHIT."] + #[doc = "If set, overrides any potentially set @ref RT_GEOMETRY_FLAG_DISABLE_ANYHIT, @ref RT_INSTANCE_FLAG_DISABLE_ANYHIT."] + #[doc = "Overriding precedence: RTrayflags > RTinstanceflags > RTgeometryflags"] + pub const RT_RAY_FLAG_FORCE_ANYHIT: RTrayflags = RTrayflags(2); +} +impl RTrayflags { + #[doc = "< Terminate the ray after the first hit, also reports the first hit as closest hit."] + pub const RT_RAY_FLAG_TERMINATE_ON_FIRST_HIT: RTrayflags = RTrayflags(4); +} +impl RTrayflags { + #[doc = "< Disable closest-hit program execution for the ray."] + pub const RT_RAY_FLAG_DISABLE_CLOSESTHIT: RTrayflags = RTrayflags(8); +} +impl RTrayflags { + #[doc = "< Do not intersect triangle back faces."] + pub const RT_RAY_FLAG_CULL_BACK_FACING_TRIANGLES: RTrayflags = RTrayflags(16); +} +impl RTrayflags { + #[doc = "< Do not intersect triangle front faces."] + pub const RT_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES: RTrayflags = RTrayflags(32); +} +impl RTrayflags { + #[doc = "< Do not intersect geometry which disables any-hit programs (due to any geometry, instance, or ray flag)."] + pub const RT_RAY_FLAG_CULL_DISABLED_ANYHIT: RTrayflags = RTrayflags(64); +} +impl RTrayflags { + #[doc = "< Do not intersect geometry which executes any-hit programs (i.e., forced or not disabled any-hit program execution, this includes a potential no-op any-hit program)."] + pub const RT_RAY_FLAG_CULL_ENABLED_ANYHIT: RTrayflags = RTrayflags(128); +} +#[repr(transparent)] +#[doc = " Ray flags"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTrayflags(pub ::std::os::raw::c_uint); +pub type RTvisibilitymask = ::std::os::raw::c_uint; +#[doc = "< Default @ref RTvisibilitymask"] +pub const RT_VISIBILITY_ALL: _bindgen_ty_1 = _bindgen_ty_1(255); +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct _bindgen_ty_1(pub ::std::os::raw::c_uint); +impl RTbufferidnull { + #[doc = "< sentinel for describing a non-existent buffer id"] + pub const RT_BUFFER_ID_NULL: RTbufferidnull = RTbufferidnull(0); +} +#[repr(transparent)] +#[doc = " Sentinel values"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTbufferidnull(pub ::std::os::raw::c_uint); +impl RTprogramidnull { + #[doc = "< sentinel for describing a non-existent program id"] + pub const RT_PROGRAM_ID_NULL: RTprogramidnull = RTprogramidnull(0); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTprogramidnull(pub ::std::os::raw::c_uint); +impl RTtextureidnull { + #[doc = "< sentinel for describing a non-existent texture id"] + pub const RT_TEXTURE_ID_NULL: RTtextureidnull = RTtextureidnull(0); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTtextureidnull(pub ::std::os::raw::c_uint); +impl RTcommandlistidnull { + #[doc = "< sentinel for describing a non-existent command list id"] + pub const RT_COMMAND_LIST_ID_NULL: RTcommandlistidnull = RTcommandlistidnull(0); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTcommandlistidnull(pub ::std::os::raw::c_uint); +impl RTpostprocessingstagenull { + #[doc = "< sentinel for describing a non-existent post-processing stage id"] + pub const RT_POSTPROCESSING_STAGE_ID_NULL: RTpostprocessingstagenull = + RTpostprocessingstagenull(0); +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RTpostprocessingstagenull(pub ::std::os::raw::c_uint); +pub type RTsize = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTacceleration_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Acceleration Structures - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTacceleration = *mut RTacceleration_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTbuffer_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Buffers - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTbuffer = *mut RTbuffer_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTcontext_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Contexts - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTcontext = *mut RTcontext_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTgeometry_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Geometry - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTgeometry = *mut RTgeometry_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTgeometrytriangles_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle GeometryTriangles - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTgeometrytriangles = *mut RTgeometrytriangles_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTgeometryinstance_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Geometry Instance - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTgeometryinstance = *mut RTgeometryinstance_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTgeometrygroup_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Geometry Group - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTgeometrygroup = *mut RTgeometrygroup_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTgroup_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Group - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTgroup = *mut RTgroup_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTmaterial_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Material - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTmaterial = *mut RTmaterial_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTprogram_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Program - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTprogram = *mut RTprogram_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTselector_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Selector - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTselector = *mut RTselector_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTtexturesampler_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Texture Sampler - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTtexturesampler = *mut RTtexturesampler_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTtransform_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Transform - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTtransform = *mut RTtransform_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTvariable_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle Variable - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTvariable = *mut RTvariable_api; +#[doc = " Opaque type to handle Object - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +#[repr(transparent)] +#[derive(Copy, Clone)] +pub struct RTobject(pub *mut ::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTpostprocessingstage_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle PostprocessingStage - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTpostprocessingstage = *mut RTpostprocessingstage_api; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTcommandlist_api { + _unused: [u8; 0], +} +#[doc = " Opaque type to handle CommandList - Note that the *_api type should never be used directly."] +#[doc = "Only the typedef target name will be guaranteed to remain unchanged"] +pub type RTcommandlist = *mut RTcommandlist_api; +#[doc = " Callback signature for use with rtContextSetTimeoutCallback."] +#[doc = " Deprecated in OptiX 6.0."] +pub type RTtimeoutcallback = ::std::option::Option ::std::os::raw::c_int>; +#[doc = " Callback signature for use with rtContextSetUsageReportCallback."] +pub type RTusagereportcallback = ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: *const ::std::os::raw::c_char, + arg3: *const ::std::os::raw::c_char, + arg4: *mut ::std::os::raw::c_void, + ), +>; +extern "C" { + #[doc = " @brief Returns the current OptiX version"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGetVersion returns in \\a version a numerically comparable"] + #[doc = " version number of the current OptiX library."] + #[doc = ""] + #[doc = " The encoding for the version number prior to OptiX 4.0.0 is major*1000 + minor*10 + micro."] + #[doc = " For versions 4.0.0 and higher, the encoding is major*10000 + minor*100 + micro."] + #[doc = " For example, for version 3.5.1 this function would return 3051, and for version 4.5.1 it would return 40501."] + #[doc = ""] + #[doc = " @param[out] version OptiX version number"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGetVersion was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount"] + #[doc = ""] + pub fn rtGetVersion(version: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Set a global attribute"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGlobalSetAttribute sets \\a p as the value of the global attribute"] + #[doc = " specified by \\a attrib."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_GLOBAL_ATTRIBUTE_ENABLE_RTX sizeof(int)"] + #[doc = ""] + #[doc = " @ref RT_GLOBAL_ATTRIBUTE_ENABLE_RTX sets the execution strategy used by Optix for the"] + #[doc = " next context to be created."] + #[doc = " Possible values: 0 (legacy megakernel execution strategy), 1 (RTX execution strategy)."] + #[doc = ""] + #[doc = " @param[in] attrib Attribute to set"] + #[doc = " @param[in] size Size of the attribute being set"] + #[doc = " @param[in] p Pointer to where the value of the attribute will be copied from. This must point to at least \\a size bytes of memory"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_GLOBAL_ATTRIBUTE - Can be returned if an unknown attribute was addressed."] + #[doc = " - @ref RT_ERROR_INVALID_VALUE - Can be returned if \\a size does not match the proper size of the attribute, or if \\a p"] + #[doc = " is \\a NULL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGlobalSetAttribute was introduced in OptiX 5.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGlobalGetAttribute"] + #[doc = ""] + pub fn rtGlobalSetAttribute( + attrib: RTglobalattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a global attribute"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGlobalGetAttribute returns in \\a p the value of the global attribute"] + #[doc = " specified by \\a attrib."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_GLOBAL_ATTRIBUTE_ENABLE_RTX sizeof(int)"] + #[doc = " - @ref RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MAJOR sizeof(unsigned int)"] + #[doc = " - @ref RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MINOR sizeof(unsigend int)"] + #[doc = ""] + #[doc = " @ref RT_GLOBAL_ATTRIBUTE_ENABLE_RTX is an experimental setting which sets the execution strategy"] + #[doc = " used by Optix for the next context to be created."] + #[doc = ""] + #[doc = " @ref RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MAJOR is an attribute to query the major version of the display driver"] + #[doc = " found on the system. It's the first number in the driver version displayed as xxx.yy."] + #[doc = ""] + #[doc = " @ref RT_GLOBAL_ATTRIBUTE_DISPLAY_DRIVER_VERSION_MINOR is an attribute to query the minor version of the display driver"] + #[doc = " found on the system. It's the second number in the driver version displayed as xxx.yy."] + #[doc = ""] + #[doc = " @param[in] attrib Attribute to query"] + #[doc = " @param[in] size Size of the attribute being queried. Parameter \\a p must have at least this much memory allocated"] + #[doc = " @param[out] p Return pointer where the value of the attribute will be copied into. This must point to at least \\a size bytes of memory"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_GLOBAL_ATTRIBUTE - Can be returned if an unknown attribute was addressed."] + #[doc = " - @ref RT_ERROR_INVALID_VALUE - Can be returned if \\a size does not match the proper size of the attribute, if \\a p is"] + #[doc = " \\a NULL, or if \\a attribute+ordinal does not correspond to an OptiX device"] + #[doc = " - @ref RT_ERROR_DRIVER_VERSION_FAILED - Can be returned if the display driver version could not be obtained."] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGlobalGetAttribute was introduced in OptiX 5.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGlobalSetAttribute,"] + #[doc = ""] + pub fn rtGlobalGetAttribute( + attrib: RTglobalattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of OptiX capable devices"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetDeviceCount returns in \\a count the number of compute"] + #[doc = " devices that are available in the host system and will be used by"] + #[doc = " OptiX."] + #[doc = ""] + #[doc = " @param[out] count Number devices available for OptiX"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetDeviceCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGetVersion"] + #[doc = ""] + pub fn rtDeviceGetDeviceCount(count: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns an attribute specific to an OptiX device"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetAttribute returns in \\a p the value of the per device attribute"] + #[doc = " specified by \\a attrib for device \\a ordinal."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_CLOCK_RATE sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_EXECUTION_TIMEOUT_ENABLED sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_MAX_HARDWARE_TEXTURE_COUNT sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_NAME up to size-1"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY sizeof(int2)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY sizeof(RTsize)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_TCC_DRIVER sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL sizeof(int)"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_PCI_BUS_ID up to size-1, at most 13 chars"] + #[doc = " - @ref RT_DEVICE_ATTRIBUTE_COMPATIBLE_DEVICES sizeof(int)*(number of devices + 1)"] + #[doc = ""] + #[doc = " For \\a RT_DEVICE_ATTRIBUTE_COMPATIBLE_DEVICES, the first \\a int returned is the number"] + #[doc = " of compatible device ordinals returned. A device is always compatible with itself, so"] + #[doc = " the count will always be at least one. Size the output buffer based on the number of"] + #[doc = " devices as returned by \\a rtDeviceGetDeviceCount."] + #[doc = ""] + #[doc = " @param[in] ordinal OptiX device ordinal"] + #[doc = " @param[in] attrib Attribute to query"] + #[doc = " @param[in] size Size of the attribute being queried. Parameter \\a p must have at least this much memory allocated"] + #[doc = " @param[out] p Return pointer where the value of the attribute will be copied into. This must point to at least \\a size bytes of memory"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE - Can be returned if size does not match the proper size of the attribute, if \\a p is"] + #[doc = " \\a NULL, or if \\a ordinal does not correspond to an OptiX device"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetAttribute was introduced in OptiX 2.0."] + #[doc = " @ref RT_DEVICE_ATTRIBUTE_TCC_DRIVER was introduced in OptiX 3.0."] + #[doc = " @ref RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL was introduced in OptiX 3.0."] + #[doc = " @ref RT_DEVICE_ATTRIBUTE_COMPATIBLE_DEVICES was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount,"] + #[doc = " @ref rtContextGetAttribute"] + #[doc = ""] + pub fn rtDeviceGetAttribute( + ordinal: ::std::os::raw::c_int, + attrib: RTdeviceattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @ingroup rtVariableSet Variable setters"] + #[doc = ""] + #[doc = " @brief Functions designed to modify the value of a program variable"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableSet functions modify the value of a program variable or variable array. The"] + #[doc = " target variable is specificed by \\a v, which should be a value returned by"] + #[doc = " @ref rtContextGetVariable."] + #[doc = ""] + #[doc = " The commands \\a rtVariableSet{1-2-3-4}{f-i-ui}v are used to modify the value of a"] + #[doc = " program variable specified by \\a v using the values passed as arguments."] + #[doc = " The number specified in the command should match the number of components in"] + #[doc = " the data type of the specified program variable (e.g., 1 for float, int,"] + #[doc = " unsigned int; 2 for float2, int2, uint2, etc.). The suffix \\a f indicates"] + #[doc = " that \\a v has floating point type, the suffix \\a i indicates that"] + #[doc = " \\a v has integral type, and the suffix \\a ui indicates that that"] + #[doc = " \\a v has unsigned integral type. The \\a v variants of this function"] + #[doc = " should be used to load the program variable's value from the array specified by"] + #[doc = " parameter \\a v. In this case, the array \\a v should contain as many elements as"] + #[doc = " there are program variable components."] + #[doc = ""] + #[doc = " The commands \\a rtVariableSetMatrix{2-3-4}x{2-3-4}fv are used to modify the value"] + #[doc = " of a program variable whose data type is a matrix. The numbers in the command"] + #[doc = " names are the number of rows and columns, respectively."] + #[doc = " For example, \\a 2x4 indicates a matrix with 2 rows and 4 columns (i.e., 8 values)."] + #[doc = " If \\a transpose is \\a 0, the matrix is specified in row-major order, otherwise"] + #[doc = " in column-major order or, equivalently, as a matrix with the number of rows and"] + #[doc = " columns swapped in row-major order."] + #[doc = ""] + #[doc = " If \\a v is not a valid variable, these calls have no effect and return"] + #[doc = " @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableSet were introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableGet,"] + #[doc = " @ref rtVariableSet,"] + #[doc = " @ref rtDeclareVariable"] + #[doc = ""] + #[doc = " @{"] + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f1 Specifies the new float value of the program variable"] + pub fn rtVariableSet1f(v: RTvariable, f1: f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f1 Specifies the new float value of the program variable"] + #[doc = " @param[in] f2 Specifies the new float value of the program variable"] + pub fn rtVariableSet2f(v: RTvariable, f1: f32, f2: f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f1 Specifies the new float value of the program variable"] + #[doc = " @param[in] f2 Specifies the new float value of the program variable"] + #[doc = " @param[in] f3 Specifies the new float value of the program variable"] + pub fn rtVariableSet3f(v: RTvariable, f1: f32, f2: f32, f3: f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f1 Specifies the new float value of the program variable"] + #[doc = " @param[in] f2 Specifies the new float value of the program variable"] + #[doc = " @param[in] f3 Specifies the new float value of the program variable"] + #[doc = " @param[in] f4 Specifies the new float value of the program variable"] + pub fn rtVariableSet4f(v: RTvariable, f1: f32, f2: f32, f3: f32, f4: f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f Array of float values to set the variable to"] + pub fn rtVariableSet1fv(v: RTvariable, f: *const f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f Array of float values to set the variable to"] + pub fn rtVariableSet2fv(v: RTvariable, f: *const f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f Array of float values to set the variable to"] + pub fn rtVariableSet3fv(v: RTvariable, f: *const f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] f Array of float values to set the variable to"] + pub fn rtVariableSet4fv(v: RTvariable, f: *const f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i1 Specifies the new integer value of the program variable"] + pub fn rtVariableSet1i(v: RTvariable, i1: ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i1 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i2 Specifies the new integer value of the program variable"] + pub fn rtVariableSet2i( + v: RTvariable, + i1: ::std::os::raw::c_int, + i2: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i1 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i2 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i3 Specifies the new integer value of the program variable"] + pub fn rtVariableSet3i( + v: RTvariable, + i1: ::std::os::raw::c_int, + i2: ::std::os::raw::c_int, + i3: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i1 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i2 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i3 Specifies the new integer value of the program variable"] + #[doc = " @param[in] i4 Specifies the new integer value of the program variable"] + pub fn rtVariableSet4i( + v: RTvariable, + i1: ::std::os::raw::c_int, + i2: ::std::os::raw::c_int, + i3: ::std::os::raw::c_int, + i4: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i Array of integer values to set the variable to"] + pub fn rtVariableSet1iv(v: RTvariable, i: *const ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i Array of integer values to set the variable to"] + pub fn rtVariableSet2iv(v: RTvariable, i: *const ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i Array of integer values to set the variable to"] + pub fn rtVariableSet3iv(v: RTvariable, i: *const ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] i Array of integer values to set the variable to"] + pub fn rtVariableSet4iv(v: RTvariable, i: *const ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u1 Specifies the new unsigned integer value of the program variable"] + pub fn rtVariableSet1ui(v: RTvariable, u1: ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u1 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u2 Specifies the new unsigned integer value of the program variable"] + pub fn rtVariableSet2ui( + v: RTvariable, + u1: ::std::os::raw::c_uint, + u2: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u1 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u2 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u3 Specifies the new unsigned integer value of the program variable"] + pub fn rtVariableSet3ui( + v: RTvariable, + u1: ::std::os::raw::c_uint, + u2: ::std::os::raw::c_uint, + u3: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u1 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u2 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u3 Specifies the new unsigned integer value of the program variable"] + #[doc = " @param[in] u4 Specifies the new unsigned integer value of the program variable"] + pub fn rtVariableSet4ui( + v: RTvariable, + u1: ::std::os::raw::c_uint, + u2: ::std::os::raw::c_uint, + u3: ::std::os::raw::c_uint, + u4: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u Array of unsigned integer values to set the variable to"] + pub fn rtVariableSet1uiv(v: RTvariable, u: *const ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u Array of unsigned integer values to set the variable to"] + pub fn rtVariableSet2uiv(v: RTvariable, u: *const ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u Array of unsigned integer values to set the variable to"] + pub fn rtVariableSet3uiv(v: RTvariable, u: *const ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] u Array of unsigned integer values to set the variable to"] + pub fn rtVariableSet4uiv(v: RTvariable, u: *const ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll1 Specifies the new long long value of the program variable"] + pub fn rtVariableSet1ll(v: RTvariable, ll1: ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll1 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll2 Specifies the new long long value of the program variable"] + pub fn rtVariableSet2ll( + v: RTvariable, + ll1: ::std::os::raw::c_longlong, + ll2: ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll1 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll2 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll3 Specifies the new long long value of the program variable"] + pub fn rtVariableSet3ll( + v: RTvariable, + ll1: ::std::os::raw::c_longlong, + ll2: ::std::os::raw::c_longlong, + ll3: ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll1 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll2 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll3 Specifies the new long long value of the program variable"] + #[doc = " @param[in] ll4 Specifies the new long long value of the program variable"] + pub fn rtVariableSet4ll( + v: RTvariable, + ll1: ::std::os::raw::c_longlong, + ll2: ::std::os::raw::c_longlong, + ll3: ::std::os::raw::c_longlong, + ll4: ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll Array of long long values to set the variable to"] + pub fn rtVariableSet1llv(v: RTvariable, ll: *const ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll Array of long long values to set the variable to"] + pub fn rtVariableSet2llv(v: RTvariable, ll: *const ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll Array of long long values to set the variable to"] + pub fn rtVariableSet3llv(v: RTvariable, ll: *const ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ll Array of long long values to set the variable to"] + pub fn rtVariableSet4llv(v: RTvariable, ll: *const ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull1 Specifies the new unsigned long long value of the program variable"] + pub fn rtVariableSet1ull(v: RTvariable, ull1: ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull1 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull2 Specifies the new unsigned long long value of the program variable"] + pub fn rtVariableSet2ull( + v: RTvariable, + ull1: ::std::os::raw::c_ulonglong, + ull2: ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull1 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull2 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull3 Specifies the new unsigned long long value of the program variable"] + pub fn rtVariableSet3ull( + v: RTvariable, + ull1: ::std::os::raw::c_ulonglong, + ull2: ::std::os::raw::c_ulonglong, + ull3: ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull1 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull2 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull3 Specifies the new unsigned long long value of the program variable"] + #[doc = " @param[in] ull4 Specifies the new unsigned long long value of the program variable"] + pub fn rtVariableSet4ull( + v: RTvariable, + ull1: ::std::os::raw::c_ulonglong, + ull2: ::std::os::raw::c_ulonglong, + ull3: ::std::os::raw::c_ulonglong, + ull4: ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull Array of unsigned long long values to set the variable to"] + pub fn rtVariableSet1ullv(v: RTvariable, ull: *const ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull Array of unsigned long long values to set the variable to"] + pub fn rtVariableSet2ullv(v: RTvariable, ull: *const ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull Array of unsigned long long values to set the variable to"] + pub fn rtVariableSet3ullv(v: RTvariable, ull: *const ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] ull Array of unsigned long long values to set the variable to"] + pub fn rtVariableSet4ullv(v: RTvariable, ull: *const ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix2x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix2x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix2x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix3x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix3x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix3x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix4x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix4x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] transpose Specifies row-major or column-major order"] + #[doc = " @param[in] m Array of float values to set the matrix to"] + pub fn rtVariableSetMatrix4x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets a program variable value to a OptiX object"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableSetObject sets a program variable to an OptiX object value. The target"] + #[doc = " variable is specified by \\a v. The new value of the program variable is"] + #[doc = " specified by \\a object. The concrete type of \\a object can be one of @ref RTbuffer,"] + #[doc = " @ref RTtexturesampler, @ref RTgroup, @ref RTprogram, @ref RTselector, @ref"] + #[doc = " RTgeometrygroup, or @ref RTtransform. If \\a v is not a valid variable or \\a"] + #[doc = " object is not a valid OptiX object, this call has no effect and returns @ref"] + #[doc = " RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be set"] + #[doc = " @param[in] object Specifies the new value of the program variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableSetObject was introduced in OptiX 1.0. The ability to bind an @ref"] + #[doc = " RTprogram to a variable was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableGetObject,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableSetObject(v: RTvariable, object: RTobject) -> RTresult; +} +extern "C" { + #[doc = " @brief Defined"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableSetUserData modifies the value of a program variable whose data type is"] + #[doc = " user-defined. The value copied into the variable is defined by an arbitrary region of"] + #[doc = " memory, pointed to by \\a ptr. The size of the memory region is given by \\a size. The"] + #[doc = " target variable is specified by \\a v. If \\a v is not a valid variable,"] + #[doc = " this call has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be modified"] + #[doc = " @param[in] size Specifies the size of the new value, in bytes"] + #[doc = " @param[in] ptr Specifies a pointer to the new value of the program variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableSetUserData was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableGetUserData,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableSetUserData( + v: RTvariable, + size: RTsize, + ptr: *const ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @ingroup rtVariableGet"] + #[doc = ""] + #[doc = " @brief Functions designed to modify the value of a program variable"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGet functions return the value of a program variable or variable"] + #[doc = " array. The target variable is specificed by \\a v."] + #[doc = ""] + #[doc = " The commands \\a rtVariableGet{1-2-3-4}{f-i-ui}v are used to query the value"] + #[doc = " of a program variable specified by \\a v using the pointers passed as arguments"] + #[doc = " as return locations for each component of the vector-typed variable. The number"] + #[doc = " specified in the command should match the number of components in the data type"] + #[doc = " of the specified program variable (e.g., 1 for float, int, unsigned int; 2 for"] + #[doc = " float2, int2, uint2, etc.). The suffix \\a f indicates that floating-point"] + #[doc = " values are expected to be returned, the suffix \\a i indicates that integer"] + #[doc = " values are expected, and the suffix \\a ui indicates that unsigned integer"] + #[doc = " values are expected, and this type should also match the data type of the"] + #[doc = " specified program variable. The \\a f variants of this function should be used"] + #[doc = " to query values for program variables defined as float, float2, float3, float4,"] + #[doc = " or arrays of these. The \\a i variants of this function should be used to"] + #[doc = " query values for program variables defined as int, int2, int3, int4, or"] + #[doc = " arrays of these. The \\a ui variants of this function should be used to query"] + #[doc = " values for program variables defined as unsigned int, uint2, uint3, uint4,"] + #[doc = " or arrays of these. The \\a v variants of this function should be used to"] + #[doc = " return the program variable's value to the array specified by parameter"] + #[doc = " \\a v. In this case, the array \\a v should be large enough to accommodate all"] + #[doc = " of the program variable's components."] + #[doc = ""] + #[doc = " The commands \\a rtVariableGetMatrix{2-3-4}x{2-3-4}fv are used to query the"] + #[doc = " value of a program variable whose data type is a matrix. The numbers in the"] + #[doc = " command names are interpreted as the dimensionality of the matrix. For example,"] + #[doc = " \\a 2x4 indicates a 2 x 4 matrix with 2 columns and 4 rows (i.e., 8"] + #[doc = " values). If \\a transpose is \\a 0, the matrix is returned in row major order,"] + #[doc = " otherwise in column major order."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGet were introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableSet,"] + #[doc = " @ref rtVariableGetType,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + #[doc = " @{"] + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f1 Float value to be returned"] + pub fn rtVariableGet1f(v: RTvariable, f1: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f1 Float value to be returned"] + #[doc = " @param[in] f2 Float value to be returned"] + pub fn rtVariableGet2f(v: RTvariable, f1: *mut f32, f2: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f1 Float value to be returned"] + #[doc = " @param[in] f2 Float value to be returned"] + #[doc = " @param[in] f3 Float value to be returned"] + pub fn rtVariableGet3f(v: RTvariable, f1: *mut f32, f2: *mut f32, f3: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f1 Float value to be returned"] + #[doc = " @param[in] f2 Float value to be returned"] + #[doc = " @param[in] f3 Float value to be returned"] + #[doc = " @param[in] f4 Float value to be returned"] + pub fn rtVariableGet4f( + v: RTvariable, + f1: *mut f32, + f2: *mut f32, + f3: *mut f32, + f4: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f Array of float value(s) to be returned"] + pub fn rtVariableGet1fv(v: RTvariable, f: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f Array of float value(s) to be returned"] + pub fn rtVariableGet2fv(v: RTvariable, f: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f Array of float value(s) to be returned"] + pub fn rtVariableGet3fv(v: RTvariable, f: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] f Array of float value(s) to be returned"] + pub fn rtVariableGet4fv(v: RTvariable, f: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i1 Integer value to be returned"] + pub fn rtVariableGet1i(v: RTvariable, i1: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i1 Integer value to be returned"] + #[doc = " @param[in] i2 Integer value to be returned"] + pub fn rtVariableGet2i( + v: RTvariable, + i1: *mut ::std::os::raw::c_int, + i2: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i1 Integer value to be returned"] + #[doc = " @param[in] i2 Integer value to be returned"] + #[doc = " @param[in] i3 Integer value to be returned"] + pub fn rtVariableGet3i( + v: RTvariable, + i1: *mut ::std::os::raw::c_int, + i2: *mut ::std::os::raw::c_int, + i3: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i1 Integer value to be returned"] + #[doc = " @param[in] i2 Integer value to be returned"] + #[doc = " @param[in] i3 Integer value to be returned"] + #[doc = " @param[in] i4 Integer value to be returned"] + pub fn rtVariableGet4i( + v: RTvariable, + i1: *mut ::std::os::raw::c_int, + i2: *mut ::std::os::raw::c_int, + i3: *mut ::std::os::raw::c_int, + i4: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i Array of integer values to be returned"] + pub fn rtVariableGet1iv(v: RTvariable, i: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i Array of integer values to be returned"] + pub fn rtVariableGet2iv(v: RTvariable, i: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i Array of integer values to be returned"] + pub fn rtVariableGet3iv(v: RTvariable, i: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] i Array of integer values to be returned"] + pub fn rtVariableGet4iv(v: RTvariable, i: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + pub fn rtVariableGet1ui(v: RTvariable, u1: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + pub fn rtVariableGet2ui( + v: RTvariable, + u1: *mut ::std::os::raw::c_uint, + u2: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + #[doc = " @param[in] u3 Unsigned integer value to be returned"] + pub fn rtVariableGet3ui( + v: RTvariable, + u1: *mut ::std::os::raw::c_uint, + u2: *mut ::std::os::raw::c_uint, + u3: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + #[doc = " @param[in] u3 Unsigned integer value to be returned"] + #[doc = " @param[in] u4 Unsigned integer value to be returned"] + pub fn rtVariableGet4ui( + v: RTvariable, + u1: *mut ::std::os::raw::c_uint, + u2: *mut ::std::os::raw::c_uint, + u3: *mut ::std::os::raw::c_uint, + u4: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u Array of unsigned integer values to be returned"] + pub fn rtVariableGet1uiv(v: RTvariable, u: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u Array of unsigned integer values to be returned"] + pub fn rtVariableGet2uiv(v: RTvariable, u: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u Array of unsigned integer values to be returned"] + pub fn rtVariableGet3uiv(v: RTvariable, u: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u Array of unsigned integer values to be returned"] + pub fn rtVariableGet4uiv(v: RTvariable, u: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll1 Integer value to be returned"] + pub fn rtVariableGet1ll(v: RTvariable, ll1: *mut ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll1 Integer value to be returned"] + #[doc = " @param[in] ll2 Integer value to be returned"] + pub fn rtVariableGet2ll( + v: RTvariable, + ll1: *mut ::std::os::raw::c_longlong, + ll2: *mut ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll1 Integer value to be returned"] + #[doc = " @param[in] ll2 Integer value to be returned"] + #[doc = " @param[in] ll3 Integer value to be returned"] + pub fn rtVariableGet3ll( + v: RTvariable, + ll1: *mut ::std::os::raw::c_longlong, + ll2: *mut ::std::os::raw::c_longlong, + ll3: *mut ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll1 Integer value to be returned"] + #[doc = " @param[in] ll2 Integer value to be returned"] + #[doc = " @param[in] ll3 Integer value to be returned"] + #[doc = " @param[in] ll4 Integer value to be returned"] + pub fn rtVariableGet4ll( + v: RTvariable, + ll1: *mut ::std::os::raw::c_longlong, + ll2: *mut ::std::os::raw::c_longlong, + ll3: *mut ::std::os::raw::c_longlong, + ll4: *mut ::std::os::raw::c_longlong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll Array of integer values to be returned"] + pub fn rtVariableGet1llv(v: RTvariable, ll: *mut ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll Array of integer values to be returned"] + pub fn rtVariableGet2llv(v: RTvariable, ll: *mut ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll Array of integer values to be returned"] + pub fn rtVariableGet3llv(v: RTvariable, ll: *mut ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ll Array of integer values to be returned"] + pub fn rtVariableGet4llv(v: RTvariable, ll: *mut ::std::os::raw::c_longlong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + pub fn rtVariableGet1ull(v: RTvariable, u1: *mut ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + pub fn rtVariableGet2ull( + v: RTvariable, + u1: *mut ::std::os::raw::c_ulonglong, + u2: *mut ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + #[doc = " @param[in] u3 Unsigned integer value to be returned"] + pub fn rtVariableGet3ull( + v: RTvariable, + u1: *mut ::std::os::raw::c_ulonglong, + u2: *mut ::std::os::raw::c_ulonglong, + u3: *mut ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] u1 Unsigned integer value to be returned"] + #[doc = " @param[in] u2 Unsigned integer value to be returned"] + #[doc = " @param[in] u3 Unsigned integer value to be returned"] + #[doc = " @param[in] u4 Unsigned integer value to be returned"] + pub fn rtVariableGet4ull( + v: RTvariable, + u1: *mut ::std::os::raw::c_ulonglong, + u2: *mut ::std::os::raw::c_ulonglong, + u3: *mut ::std::os::raw::c_ulonglong, + u4: *mut ::std::os::raw::c_ulonglong, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ull Array of unsigned integer values to be returned"] + pub fn rtVariableGet1ullv(v: RTvariable, ull: *mut ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ull Array of unsigned integer values to be returned"] + pub fn rtVariableGet2ullv(v: RTvariable, ull: *mut ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ull Array of unsigned integer values to be returned"] + pub fn rtVariableGet3ullv(v: RTvariable, ull: *mut ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] ull Array of unsigned integer values to be returned"] + pub fn rtVariableGet4ullv(v: RTvariable, ull: *mut ::std::os::raw::c_ulonglong) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix2x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix2x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix2x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix3x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix3x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix3x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix4x2fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix4x3fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @param[in] v Specifies the program variable whose value is to be returned"] + #[doc = " @param[in] transpose Specify(ies) row-major or column-major order"] + #[doc = " @param[in] m Array of float values to be returned"] + pub fn rtVariableGetMatrix4x4fv( + v: RTvariable, + transpose: ::std::os::raw::c_int, + m: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the value of a OptiX object program variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetObject queries the value of a program variable whose data type is a"] + #[doc = " OptiX object. The target variable is specified by \\a v. The value of the"] + #[doc = " program variable is returned in \\a *object. The concrete"] + #[doc = " type of the program variable can be queried using @ref rtVariableGetType, and the @ref"] + #[doc = " RTobject handle returned by @ref rtVariableGetObject may safely be cast to an OptiX"] + #[doc = " handle of corresponding type. If \\a v is not a valid variable, this call sets"] + #[doc = " \\a *object to \\a NULL and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] object Returns the value of the program variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetObject was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableSetObject,"] + #[doc = " @ref rtVariableGetType,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetObject(v: RTvariable, object: *mut RTobject) -> RTresult; +} +extern "C" { + #[doc = " @brief Defined"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetUserData queries the value of a program variable whose data type is"] + #[doc = " user-defined. The variable of interest is specified by \\a v. The size of the"] + #[doc = " variable's value must match the value given by the parameter \\a size. The value of"] + #[doc = " the program variable is copied to the memory region pointed to by \\a ptr. The storage"] + #[doc = " at location \\a ptr must be large enough to accommodate all of the program variable's"] + #[doc = " value data. If \\a v is not a valid variable, this call has no effect and"] + #[doc = " returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[in] size Specifies the size of the program variable, in bytes"] + #[doc = " @param[out] ptr Location in which to store the value of the variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetUserData was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableSetUserData,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetUserData( + v: RTvariable, + size: RTsize, + ptr: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the name of a program variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Queries a program variable's name. The variable of interest is specified by \\a"] + #[doc = " variable, which should be a value returned by @ref rtContextDeclareVariable. A pointer"] + #[doc = " to the string containing the name of the variable is returned in \\a *nameReturn."] + #[doc = " If \\a v is not a valid variable, this"] + #[doc = " call sets \\a *nameReturn to \\a NULL and returns @ref RT_ERROR_INVALID_VALUE. \\a"] + #[doc = " *nameReturn will point to valid memory until another API function that returns a"] + #[doc = " string is called."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] nameReturn Returns the program variable's name"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetName was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetName( + v: RTvariable, + nameReturn: *mut *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the annotation string of a program variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetAnnotation queries a program variable's annotation string. A pointer"] + #[doc = " to the string containing the annotation is returned in \\a *annotationReturn."] + #[doc = " If \\a v is not a valid variable, this call sets"] + #[doc = " \\a *annotationReturn to \\a NULL and returns @ref RT_ERROR_INVALID_VALUE. \\a"] + #[doc = " *annotationReturn will point to valid memory until another API function that returns"] + #[doc = " a string is called."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] annotationReturn Returns the program variable's annotation string"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetAnnotation was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeclareVariable,"] + #[doc = " @ref rtDeclareAnnotation"] + #[doc = ""] + pub fn rtVariableGetAnnotation( + v: RTvariable, + annotationReturn: *mut *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns type information about a program variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetType queries a program variable's type. The variable of interest is"] + #[doc = " specified by \\a v. The program variable's type enumeration is returned in \\a *typeReturn,"] + #[doc = " if it is not \\a NULL. It is one of the following:"] + #[doc = ""] + #[doc = " - @ref RT_OBJECTTYPE_UNKNOWN"] + #[doc = " - @ref RT_OBJECTTYPE_GROUP"] + #[doc = " - @ref RT_OBJECTTYPE_GEOMETRY_GROUP"] + #[doc = " - @ref RT_OBJECTTYPE_TRANSFORM"] + #[doc = " - @ref RT_OBJECTTYPE_SELECTOR"] + #[doc = " - @ref RT_OBJECTTYPE_GEOMETRY_INSTANCE"] + #[doc = " - @ref RT_OBJECTTYPE_BUFFER"] + #[doc = " - @ref RT_OBJECTTYPE_TEXTURE_SAMPLER"] + #[doc = " - @ref RT_OBJECTTYPE_OBJECT"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT2x2"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT2x3"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT2x4"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT3x2"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT3x3"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT3x4"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT4x2"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT4x3"] + #[doc = " - @ref RT_OBJECTTYPE_MATRIX_FLOAT4x4"] + #[doc = " - @ref RT_OBJECTTYPE_FLOAT"] + #[doc = " - @ref RT_OBJECTTYPE_FLOAT2"] + #[doc = " - @ref RT_OBJECTTYPE_FLOAT3"] + #[doc = " - @ref RT_OBJECTTYPE_FLOAT4"] + #[doc = " - @ref RT_OBJECTTYPE_INT"] + #[doc = " - @ref RT_OBJECTTYPE_INT2"] + #[doc = " - @ref RT_OBJECTTYPE_INT3"] + #[doc = " - @ref RT_OBJECTTYPE_INT4"] + #[doc = " - @ref RT_OBJECTTYPE_UNSIGNED_INT"] + #[doc = " - @ref RT_OBJECTTYPE_UNSIGNED_INT2"] + #[doc = " - @ref RT_OBJECTTYPE_UNSIGNED_INT3"] + #[doc = " - @ref RT_OBJECTTYPE_UNSIGNED_INT4"] + #[doc = " - @ref RT_OBJECTTYPE_USER"] + #[doc = ""] + #[doc = " Sets \\a *typeReturn to @ref RT_OBJECTTYPE_UNKNOWN if \\a v is not a valid variable."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] typeReturn Returns the type of the program variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetType was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetType(v: RTvariable, typeReturn: *mut RTobjecttype) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a program variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetContext queries the context associated with a program variable. The"] + #[doc = " target variable is specified by \\a v. The context of the program variable is"] + #[doc = " returned to \\a *context if the pointer \\a context is not \\a NULL. If \\a v is"] + #[doc = " not a valid variable, \\a *context is set to \\a NULL and @ref RT_ERROR_INVALID_VALUE is"] + #[doc = " returned."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] context Returns the context associated with the program variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetContext(v: RTvariable, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the size, in bytes, of a variable"] + #[doc = ""] + #[doc = " @ingroup Variables"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtVariableGetSize queries a declared program variable for its size in bytes."] + #[doc = " This is most often used to query the size of a variable that has a user-defined type."] + #[doc = " Builtin types (int, float, unsigned int, etc.) may be queried, but object typed"] + #[doc = " variables, such as buffers, texture samplers and graph nodes, cannot be queried and"] + #[doc = " will return @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] v Specifies the program variable to be queried"] + #[doc = " @param[out] size Specifies a pointer where the size of the variable, in bytes, will be returned"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtVariableGetSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtVariableGetUserData,"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtVariableGetSize(v: RTvariable, size: *mut RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new context object"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextCreate allocates and returns a handle to a new context object."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[out] context Handle to context for return value"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_NO_DEVICE"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = ""] + #[doc = ""] + pub fn rtContextCreate(context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a context and frees all associated resources"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextDestroy frees all resources, including OptiX objects, associated with"] + #[doc = " this object. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL context. @ref"] + #[doc = " RT_ERROR_LAUNCH_FAILED may be returned if a previous call to @ref rtContextLaunch \"rtContextLaunch\""] + #[doc = " failed."] + #[doc = ""] + #[doc = " @param[in] context Handle of the context to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_LAUNCH_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtContextDestroy(context: RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Checks the given context for valid internal state"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextValidate checks the the given context and all of its associated OptiX"] + #[doc = " objects for a valid state. These checks include tests for presence of necessary"] + #[doc = " programs (e.g. an intersection program for a geometry node), invalid internal state"] + #[doc = " such as \\a NULL children in graph nodes, and presence of variables required by all"] + #[doc = " specified programs. @ref rtContextGetErrorString can be used to retrieve a description"] + #[doc = " of a validation failure."] + #[doc = ""] + #[doc = " @param[in] context The context to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetErrorString"] + #[doc = ""] + pub fn rtContextValidate(context: RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the error string associated with a given"] + #[doc = " error"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetErrorString return a descriptive string given an error code. If \\a"] + #[doc = " context is valid and additional information is available from the last OptiX failure,"] + #[doc = " it will be appended to the generic error code description. \\a stringReturn will be"] + #[doc = " set to point to this string. The memory \\a stringReturn points to will be valid"] + #[doc = " until the next API call that returns a string."] + #[doc = ""] + #[doc = " @param[in] context The context object to be queried, or \\a NULL"] + #[doc = " @param[in] code The error code to be converted to string"] + #[doc = " @param[out] stringReturn The return parameter for the error string"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " @ref rtContextGetErrorString does not return a value"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetErrorString was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = ""] + #[doc = ""] + pub fn rtContextGetErrorString( + context: RTcontext, + code: RTresult, + stringReturn: *mut *const ::std::os::raw::c_char, + ); +} +extern "C" { + #[doc = " @brief Set an attribute specific to an OptiX context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetAttribute sets \\a p as the value of the per context attribute"] + #[doc = " specified by \\a attrib."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_CPU_NUM_THREADS sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_PREFER_FAST_RECOMPILES sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_FORCE_INLINE_USER_FUNCTIONS sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION sizeof(char*)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS sizeof(RTSize[2])"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_MAX_CONCURRENT_LAUNCHES sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_PREFER_WATERTIGHT_TRAVERSAL sizeof(int)"] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_CPU_NUM_THREADS sets the number of host CPU threads OptiX"] + #[doc = " can use for various tasks."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_PREFER_FAST_RECOMPILES is a hint about scene usage. By"] + #[doc = " default OptiX produces device kernels that are optimized for the current scene. Such"] + #[doc = " kernels generally run faster, but must be recompiled after some types of scene"] + #[doc = " changes, causing delays. Setting PREFER_FAST_RECOMPILES to 1 will leave out some"] + #[doc = " scene-specific optimizations, producing kernels that generally run slower but are less"] + #[doc = " sensitive to changes in the scene."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_FORCE_INLINE_USER_FUNCTIONS sets whether or not OptiX will"] + #[doc = " automatically inline user functions, which is the default behavior. Please see the"] + #[doc = " Programming Guide for more information about the benefits and limitations of disabling"] + #[doc = " automatic inlining."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION sets the location where the OptiX disk"] + #[doc = " cache will be created. The location must be provided as a \\a NULL-terminated"] + #[doc = " string. OptiX will attempt to create the directory if it does not exist. An exception"] + #[doc = " will be thrown if OptiX is unable to create the cache database file at the specified"] + #[doc = " location for any reason (e.g., the path is invalid or the directory is not writable)."] + #[doc = " The location of the disk cache can be overridden with the environment variable \\a"] + #[doc = " OPTIX_CACHE_PATH. This environment variable takes precedence over the RTcontext"] + #[doc = " attribute. The default location depends on the operating system:"] + #[doc = ""] + #[doc = " - Windows: %LOCALAPPDATA%\\\\NVIDIA\\\\OptixCache"] + #[doc = " - Linux: /var/tmp/OptixCache_\\ (or /tmp/OptixCache_\\ if the first"] + #[doc = " choice is not usable), the underscore and username suffix are omitted if the"] + #[doc = " username cannot be obtained"] + #[doc = " - MacOS X: /Library/Application Support/NVIDIA/OptixCache"] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS sets the low and high watermarks"] + #[doc = " for disk cache garbage collection. The limits must be passed in as a two-element"] + #[doc = " array of \\a RTsize values, with the low limit as the first element. OptiX will throw"] + #[doc = " an exception if either limit is non-zero and the high limit is not greater than the"] + #[doc = " low limit. Setting either limit to zero will disable garbage collection. Garbage"] + #[doc = " collection is triggered whenever the cache data size exceeds the high watermark and"] + #[doc = " proceeds until the size reaches the low watermark."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_MAX_CONCURRENT_LAUNCHES sets the maximum number of allowed"] + #[doc = " concurrent asynchronous launches per device. The actual number of launches can be less than"] + #[doc = " the set limit, and actual GPU scheduling may affect concurrency. This limit affects only"] + #[doc = " asynchronous launches. Valid values are from 1 to the maximum number of CUDA streams"] + #[doc = " supported by a device. Default value is 2."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_PREFER_WATERTIGHT_TRAVERSAL sets whether or not OptiX should prefer"] + #[doc = " to use a watertight traversal method or not. The default behaviour is preferring to use"] + #[doc = " watertight traversal. Note that OptiX might still choose to decide otherwise though."] + #[doc = " Please see the Programming Guide for more information about the different traversal methods."] + #[doc = ""] + #[doc = " @param[in] context The context object to be modified"] + #[doc = " @param[in] attrib Attribute to set"] + #[doc = " @param[in] size Size of the attribute being set"] + #[doc = " @param[in] p Pointer to where the value of the attribute will be copied from. This must point to at least \\a size bytes of memory"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE - Can be returned if \\a size does not match the proper size of the attribute, or if \\a p"] + #[doc = " is \\a NULL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetAttribute was introduced in OptiX 2.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetAttribute"] + #[doc = ""] + pub fn rtContextSetAttribute( + context: RTcontext, + attrib: RTcontextattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns an attribute specific to an OptiX context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetAttribute returns in \\a p the value of the per context attribute"] + #[doc = " specified by \\a attrib."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_MAX_TEXTURE_COUNT sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_CPU_NUM_THREADS sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_USED_HOST_MEMORY sizeof(RTsize)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_AVAILABLE_DEVICE_MEMORY sizeof(RTsize)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_ENABLED sizeof(int)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION sizeof(char**)"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS sizeof(RTSize[2])"] + #[doc = " - @ref RT_CONTEXT_ATTRIBUTE_MAX_CONCURRENT_LAUNCHES sizeof(int)"] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_MAX_TEXTURE_COUNT queries the maximum number of textures"] + #[doc = " handled by OptiX. For OptiX versions below 2.5 this value depends on the number of"] + #[doc = " textures supported by CUDA."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_CPU_NUM_THREADS queries the number of host CPU threads OptiX"] + #[doc = " can use for various tasks."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_USED_HOST_MEMORY queries the amount of host memory allocated"] + #[doc = " by OptiX."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_AVAILABLE_DEVICE_MEMORY queries the amount of free device"] + #[doc = " memory."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_ENABLED queries whether or not the OptiX disk"] + #[doc = " cache is enabled."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION queries the file path of the OptiX"] + #[doc = " disk cache."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS queries the low and high watermark values"] + #[doc = " for the OptiX disk cache."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_MAX_CONCURRENT_LAUNCHES queries the number of concurrent asynchronous"] + #[doc = " launches allowed per device."] + #[doc = ""] + #[doc = " Some attributes are used to get per device information. In contrast to @ref"] + #[doc = " rtDeviceGetAttribute, these attributes are determined by the context and are therefore"] + #[doc = " queried through the context. This is done by adding the attribute with the OptiX"] + #[doc = " device ordinal number when querying the attribute. The following are per device attributes."] + #[doc = ""] + #[doc = " @ref RT_CONTEXT_ATTRIBUTE_AVAILABLE_DEVICE_MEMORY"] + #[doc = ""] + #[doc = " @param[in] context The context object to be queried"] + #[doc = " @param[in] attrib Attribute to query"] + #[doc = " @param[in] size Size of the attribute being queried. Parameter \\a p must have at least this much memory allocated"] + #[doc = " @param[out] p Return pointer where the value of the attribute will be copied into. This must point to at least \\a size bytes of memory"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE - Can be returned if \\a size does not match the proper size of the attribute, if \\a p is"] + #[doc = " \\a NULL, or if \\a attribute+ordinal does not correspond to an OptiX device"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetAttribute was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetDeviceCount,"] + #[doc = " @ref rtContextSetAttribute,"] + #[doc = " @ref rtDeviceGetAttribute"] + #[doc = ""] + pub fn rtContextGetAttribute( + context: RTcontext, + attrib: RTcontextattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specify a list of hardware devices to be used by the"] + #[doc = " kernel"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetDevices specifies a list of hardware devices to be used during"] + #[doc = " execution of the subsequent trace kernels. Note that the device numbers are"] + #[doc = " OptiX device ordinals, which may not be the same as CUDA device ordinals."] + #[doc = " Use @ref rtDeviceGetAttribute with @ref RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL to query the CUDA device"] + #[doc = " corresponding to a particular OptiX device."] + #[doc = ""] + #[doc = " @param[in] context The context to which the hardware list is applied"] + #[doc = " @param[in] count The number of devices in the list"] + #[doc = " @param[in] devices The list of devices"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_NO_DEVICE"] + #[doc = " - @ref RT_ERROR_INVALID_DEVICE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetDevices was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetDevices,"] + #[doc = " @ref rtContextGetDeviceCount"] + #[doc = ""] + pub fn rtContextSetDevices( + context: RTcontext, + count: ::std::os::raw::c_uint, + devices: *const ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Retrieve a list of hardware devices being used by the"] + #[doc = " kernel"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetDevices retrieves a list of hardware devices used by the context."] + #[doc = " Note that the device numbers are OptiX device ordinals, which may not be the same as CUDA device ordinals."] + #[doc = " Use @ref rtDeviceGetAttribute with @ref RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL to query the CUDA device"] + #[doc = " corresponding to a particular OptiX device."] + #[doc = ""] + #[doc = " @param[in] context The context to which the hardware list is applied"] + #[doc = " @param[out] devices Return parameter for the list of devices. The memory must be able to hold entries"] + #[doc = " numbering least the number of devices as returned by @ref rtContextGetDeviceCount"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetDevices was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetDevices,"] + #[doc = " @ref rtContextGetDeviceCount"] + #[doc = ""] + pub fn rtContextGetDevices(context: RTcontext, devices: *mut ::std::os::raw::c_int) + -> RTresult; +} +extern "C" { + #[doc = " @brief Query the number of devices currently being used"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetDeviceCount - Query the number of devices currently being used."] + #[doc = ""] + #[doc = " @param[in] context The context containing the devices"] + #[doc = " @param[out] count Return parameter for the device count"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetDeviceCount was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetDevices,"] + #[doc = " @ref rtContextGetDevices"] + #[doc = ""] + pub fn rtContextGetDeviceCount( + context: RTcontext, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the stack size for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetStackSize sets the stack size for the given context to"] + #[doc = " \\a bytes bytes. Not supported with the RTX execution strategy."] + #[doc = " With RTX execution strategy @ref rtContextSetMaxTraceDepth and @ref rtContextSetMaxCallableProgramDepth"] + #[doc = " should be used to control stack size."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if context is not valid."] + #[doc = ""] + #[doc = " @param[in] context The context node to be modified"] + #[doc = " @param[in] bytes The desired stack size in bytes"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetStackSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetStackSize"] + #[doc = ""] + pub fn rtContextSetStackSize(context: RTcontext, bytes: RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the stack size for this context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetStackSize passes back the stack size associated with this context in"] + #[doc = " \\a bytes. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] bytes Return parameter to store the size of the stack"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetStackSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetStackSize"] + #[doc = ""] + pub fn rtContextGetStackSize(context: RTcontext, bytes: *mut RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Set maximum callable program call depth for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetMaxCallableProgramDepth sets the maximum call depth of a chain of callable programs"] + #[doc = " for the given context to \\a maxDepth. This value is only used for stack size computation."] + #[doc = " Only supported for RTX execution mode. Default value is 5."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if context is not valid."] + #[doc = ""] + #[doc = " @param[in] context The context node to be modified"] + #[doc = " @param[in] maxDepth The desired maximum depth"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetMaxCallableProgramDepth was introduced in OptiX 6.0"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetMaxCallableProgramDepth"] + #[doc = ""] + pub fn rtContextSetMaxCallableProgramDepth( + context: RTcontext, + maxDepth: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the maximum call depth for callable programs"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetMaxCallableProgramDepth passes back the maximum callable program call depth"] + #[doc = " associated with this context in \\a maxDepth."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] maxDepth Return parameter to store the maximum callable program depth"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetMaxCallableProgramDepth was introduced in OptiX 6.0"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetMaxCallableProgramDepth"] + #[doc = ""] + pub fn rtContextGetMaxCallableProgramDepth( + context: RTcontext, + maxDepth: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the maximum trace depth for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetMaxTraceDepth sets the maximum trace depth for the given context to"] + #[doc = " \\a maxDepth. Only supported for RTX execution mode. Default value is 5. Maximum trace depth is 31."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if context is not valid."] + #[doc = ""] + #[doc = " @param[in] context The context node to be modified"] + #[doc = " @param[in] maxDepth The desired maximum depth"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetMaxTraceDepth was introduced in OptiX 6.0"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetMaxTraceDepth"] + #[doc = ""] + pub fn rtContextSetMaxTraceDepth( + context: RTcontext, + maxDepth: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the maximum trace depth for this context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetMaxTraceDepth passes back the maximum trace depth associated with this context in"] + #[doc = " \\a maxDepth. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] maxDepth Return parameter to store the maximum trace depth"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetMaxTraceDepth was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetMaxTraceDepth"] + #[doc = ""] + pub fn rtContextGetMaxTraceDepth( + context: RTcontext, + maxDepth: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 6.0. Calling this function has no effect."] + pub fn rtContextSetTimeoutCallback( + context: RTcontext, + callback: RTtimeoutcallback, + minPollingSeconds: f64, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set usage report callback function"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetUsageReportCallback sets an application-side callback"] + #[doc = " function \\a callback and a verbosity level \\a verbosity."] + #[doc = ""] + #[doc = " @ref RTusagereportcallback is defined as"] + #[doc = " \\a void (*RTusagereportcallback)(int, const char*, const char*, void*)."] + #[doc = ""] + #[doc = " The provided callback will be invoked with the message's verbosity level as"] + #[doc = " the first parameter. The second parameter is a descriptive tag string and"] + #[doc = " the third parameter is the message itself. The fourth parameter is a pointer"] + #[doc = " to user-defined data, which may be NULL. The descriptive tag will give a"] + #[doc = " terse message category description (eg, 'SCENE STAT'). The messages will"] + #[doc = " be unstructured and subject to change with subsequent releases. The"] + #[doc = " verbosity argument specifies the granularity of these messages."] + #[doc = ""] + #[doc = " \\a verbosity of 0 disables reporting. \\a callback is ignored in this case."] + #[doc = ""] + #[doc = " \\a verbosity of 1 enables error messages and important warnings. This"] + #[doc = " verbosity level can be expected to be efficient and have no significant"] + #[doc = " overhead."] + #[doc = ""] + #[doc = " \\a verbosity of 2 additionally enables minor warnings, performance"] + #[doc = " recommendations, and scene statistics at startup or recompilation"] + #[doc = " granularity. This level may have a performance cost."] + #[doc = ""] + #[doc = " \\a verbosity of 3 additionally enables informational messages and per-launch"] + #[doc = " statistics and messages."] + #[doc = ""] + #[doc = " A NULL \\a callback when verbosity is non-zero or a \\a verbosity outside of"] + #[doc = " [0, 3] will result in @ref RT_ERROR_INVALID_VALUE return code."] + #[doc = ""] + #[doc = " Only one report callback function can be specified at any time."] + #[doc = ""] + #[doc = " @param[in] context The context node to be modified"] + #[doc = " @param[in] callback The function to be called"] + #[doc = " @param[in] verbosity The verbosity of report messages"] + #[doc = " @param[in] cbdata Pointer to user-defined data that will be sent to the callback. Can be NULL."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetUsageReportCallback was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = ""] + pub fn rtContextSetUsageReportCallback( + context: RTcontext, + callback: RTusagereportcallback, + verbosity: ::std::os::raw::c_int, + cbdata: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the number of entry points for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetEntryPointCount sets the number of entry points associated with"] + #[doc = " the given context to \\a count."] + #[doc = ""] + #[doc = " @param[in] context The context to be modified"] + #[doc = " @param[in] count The number of entry points to use"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetEntryPointCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetEntryPointCount"] + #[doc = ""] + pub fn rtContextSetEntryPointCount( + context: RTcontext, + count: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the number of entry points for this"] + #[doc = " context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetEntryPointCount passes back the number of entry points associated"] + #[doc = " with this context in \\a count. Returns @ref RT_ERROR_INVALID_VALUE if"] + #[doc = " passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] count Return parameter for passing back the entry point count"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetEntryPointCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetEntryPointCount"] + #[doc = ""] + pub fn rtContextGetEntryPointCount( + context: RTcontext, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the ray generation program for"] + #[doc = " a given context entry point"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetRayGenerationProgram sets \\a context's ray generation program at"] + #[doc = " entry point \\a entryPointIndex. @ref RT_ERROR_INVALID_VALUE is returned if \\a"] + #[doc = " entryPointIndex is outside of the range [\\a 0, @ref rtContextGetEntryPointCount"] + #[doc = " \\a -1]."] + #[doc = ""] + #[doc = " @param[in] context The context node to which the exception program will be added"] + #[doc = " @param[in] entryPointIndex The entry point the program will be associated with"] + #[doc = " @param[in] program The ray generation program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetRayGenerationProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetEntryPointCount,"] + #[doc = " @ref rtContextGetRayGenerationProgram"] + #[doc = ""] + pub fn rtContextSetRayGenerationProgram( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the ray generation program"] + #[doc = " associated with the given context and entry point"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetRayGenerationProgram passes back the ray generation program"] + #[doc = " associated with the given context and entry point. This program is set via @ref"] + #[doc = " rtContextSetRayGenerationProgram. Returns @ref RT_ERROR_INVALID_VALUE if given an"] + #[doc = " invalid entry point index or \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node associated with the ray generation program"] + #[doc = " @param[in] entryPointIndex The entry point index for the desired ray generation program"] + #[doc = " @param[out] program Return parameter to store the ray generation program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetRayGenerationProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetRayGenerationProgram"] + #[doc = ""] + pub fn rtContextGetRayGenerationProgram( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the exception program for a given context entry point"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetExceptionProgram sets \\a context's exception program at entry point"] + #[doc = " \\a entryPointIndex. @ref RT_ERROR_INVALID_VALUE is returned if \\a entryPointIndex"] + #[doc = " is outside of the range [\\a 0, @ref rtContextGetEntryPointCount \\a -1]."] + #[doc = ""] + #[doc = " @param[in] context The context node to which the exception program will be added"] + #[doc = " @param[in] entryPointIndex The entry point the program will be associated with"] + #[doc = " @param[in] program The exception program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetExceptionProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetEntryPointCount,"] + #[doc = " @ref rtContextGetExceptionProgram"] + #[doc = " @ref rtContextSetExceptionEnabled,"] + #[doc = " @ref rtContextGetExceptionEnabled,"] + #[doc = " @ref rtGetExceptionCode,"] + #[doc = " @ref rtThrow,"] + #[doc = " @ref rtPrintExceptionDetails"] + #[doc = ""] + pub fn rtContextSetExceptionProgram( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the exception program associated with"] + #[doc = " the given context and entry point"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetExceptionProgram passes back the exception program associated with"] + #[doc = " the given context and entry point. This program is set via @ref"] + #[doc = " rtContextSetExceptionProgram. Returns @ref RT_ERROR_INVALID_VALUE if given an invalid"] + #[doc = " entry point index or \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node associated with the exception program"] + #[doc = " @param[in] entryPointIndex The entry point index for the desired exception program"] + #[doc = " @param[out] program Return parameter to store the exception program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetExceptionProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetExceptionProgram,"] + #[doc = " @ref rtContextSetEntryPointCount,"] + #[doc = " @ref rtContextSetExceptionEnabled,"] + #[doc = " @ref rtContextGetExceptionEnabled,"] + #[doc = " @ref rtGetExceptionCode,"] + #[doc = " @ref rtThrow,"] + #[doc = " @ref rtPrintExceptionDetails"] + #[doc = ""] + pub fn rtContextGetExceptionProgram( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Enable or disable an exception"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetExceptionEnabled is used to enable or disable specific exceptions."] + #[doc = " If an exception is enabled, the exception condition is checked for at runtime, and the"] + #[doc = " exception program is invoked if the condition is met. The exception program can query"] + #[doc = " the type of the caught exception by calling @ref rtGetExceptionCode."] + #[doc = " \\a exception may take one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_EXCEPTION_PAYLOAD_ACCESS_OUT_OF_BOUNDS"] + #[doc = " - @ref RT_EXCEPTION_USER_EXCEPTION_CODE_OUT_OF_BOUNDS"] + #[doc = " - @ref RT_EXCEPTION_TRACE_DEPTH_EXCEEDED"] + #[doc = " - @ref RT_EXCEPTION_TEXTURE_ID_INVALID"] + #[doc = " - @ref RT_EXCEPTION_BUFFER_ID_INVALID"] + #[doc = " - @ref RT_EXCEPTION_INDEX_OUT_OF_BOUNDS"] + #[doc = " - @ref RT_EXCEPTION_STACK_OVERFLOW"] + #[doc = " - @ref RT_EXCEPTION_BUFFER_INDEX_OUT_OF_BOUNDS"] + #[doc = " - @ref RT_EXCEPTION_INVALID_RAY"] + #[doc = " - @ref RT_EXCEPTION_INTERNAL_ERROR"] + #[doc = " - @ref RT_EXCEPTION_USER"] + #[doc = " - @ref RT_EXCEPTION_ALL"] + #[doc = ""] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_PAYLOAD_ACCESS_OUT_OF_BOUNDS verifies that accesses to the ray payload are"] + #[doc = " within valid bounds. This exception is only supported with the RTX execution strategy."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_USER_EXCEPTION_CODE_OUT_OF_BOUNDS verifies that the exception code passed"] + #[doc = " to @ref rtThrow is within the valid range from RT_EXCEPTION_USER to RT_EXCEPTION_USER_MAX."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_TRACE_DEPTH_EXCEEDED verifies that the depth of the @ref rtTrace"] + #[doc = " tree does not exceed the configured trace depth (see @ref rtContextSetMaxTraceDepth). This"] + #[doc = " exception is only supported with the RTX execution strategy."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_TEXTURE_ID_INVALID verifies that every access of a texture id is"] + #[doc = " valid, including use of RT_TEXTURE_ID_NULL and IDs out of bounds."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_BUFFER_ID_INVALID verifies that every access of a buffer id is"] + #[doc = " valid, including use of RT_BUFFER_ID_NULL and IDs out of bounds."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_INDEX_OUT_OF_BOUNDS checks that @ref rtIntersectChild and @ref"] + #[doc = " rtReportIntersection are called with a valid index."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_STACK_OVERFLOW checks the runtime stack against overflow. The most common"] + #[doc = " cause for an overflow is a too small trace depth (see @ref rtContextSetMaxTraceDepth). In rare"] + #[doc = " cases, stack overflows might not be detected unless @ref RT_EXCEPTION_TRACE_DEPTH_EXCEEDED is"] + #[doc = " enabled as well."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_BUFFER_INDEX_OUT_OF_BOUNDS checks every read and write access to"] + #[doc = " @ref rtBuffer objects to be within valid bounds. This exception is supported with the RTX"] + #[doc = " execution strategy only."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_INVALID_RAY checks the each ray's origin and direction values"] + #[doc = " against \\a NaNs and \\a infinity values."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_INTERNAL_ERROR indicates an unexpected internal error in the"] + #[doc = " runtime."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_USER is used to enable or disable all user-defined exceptions. See"] + #[doc = " @ref rtThrow for more information."] + #[doc = ""] + #[doc = " @ref RT_EXCEPTION_ALL is a placeholder value which can be used to enable or disable"] + #[doc = " all possible exceptions with a single call to @ref rtContextSetExceptionEnabled."] + #[doc = ""] + #[doc = " By default, @ref RT_EXCEPTION_STACK_OVERFLOW is enabled and all other exceptions are"] + #[doc = " disabled."] + #[doc = ""] + #[doc = " @param[in] context The context for which the exception is to be enabled or disabled"] + #[doc = " @param[in] exception The exception which is to be enabled or disabled"] + #[doc = " @param[in] enabled Nonzero to enable the exception, \\a 0 to disable the exception"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetExceptionEnabled was introduced in OptiX 1.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetExceptionEnabled,"] + #[doc = " @ref rtContextSetExceptionProgram,"] + #[doc = " @ref rtContextGetExceptionProgram,"] + #[doc = " @ref rtGetExceptionCode,"] + #[doc = " @ref rtThrow,"] + #[doc = " @ref rtPrintExceptionDetails,"] + #[doc = " @ref RTexception"] + #[doc = ""] + pub fn rtContextSetExceptionEnabled( + context: RTcontext, + exception: RTexception, + enabled: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query whether a specified exception is enabled"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetExceptionEnabled passes back \\a 1 in \\a *enabled if the given exception is"] + #[doc = " enabled, \\a 0 otherwise. \\a exception specifies the type of exception to be queried. For a list"] + #[doc = " of available types, see @ref rtContextSetExceptionEnabled. If \\a exception"] + #[doc = " is @ref RT_EXCEPTION_ALL, \\a enabled is set to \\a 1 only if all possible"] + #[doc = " exceptions are enabled."] + #[doc = ""] + #[doc = " @param[in] context The context to be queried"] + #[doc = " @param[in] exception The exception of which to query the state"] + #[doc = " @param[out] enabled Return parameter to store whether the exception is enabled"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetExceptionEnabled was introduced in OptiX 1.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetExceptionEnabled,"] + #[doc = " @ref rtContextSetExceptionProgram,"] + #[doc = " @ref rtContextGetExceptionProgram,"] + #[doc = " @ref rtGetExceptionCode,"] + #[doc = " @ref rtThrow,"] + #[doc = " @ref rtPrintExceptionDetails,"] + #[doc = " @ref RTexception"] + #[doc = ""] + pub fn rtContextGetExceptionEnabled( + context: RTcontext, + exception: RTexception, + enabled: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of ray types for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetRayTypeCount Sets the number of ray types associated with the given"] + #[doc = " context."] + #[doc = ""] + #[doc = " @param[in] context The context node"] + #[doc = " @param[in] rayTypeCount The number of ray types to be used"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetRayTypeCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetRayTypeCount"] + #[doc = ""] + pub fn rtContextSetRayTypeCount( + context: RTcontext, + rayTypeCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the number of ray types associated with this"] + #[doc = " context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetRayTypeCount passes back the number of entry points associated with"] + #[doc = " this context in \\a rayTypeCount. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a"] + #[doc = " NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] rayTypeCount Return parameter to store the number of ray types"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetRayTypeCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetRayTypeCount"] + #[doc = ""] + pub fn rtContextGetRayTypeCount( + context: RTcontext, + rayTypeCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the miss program for a given context ray type"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetMissProgram sets \\a context's miss program associated with ray type"] + #[doc = " \\a rayTypeIndex. @ref RT_ERROR_INVALID_VALUE is returned if \\a rayTypeIndex"] + #[doc = " is outside of the range [\\a 0, @ref rtContextGetRayTypeCount \\a -1]."] + #[doc = ""] + #[doc = " @param[in] context The context node to which the miss program will be added"] + #[doc = " @param[in] rayTypeIndex The ray type the program will be associated with"] + #[doc = " @param[in] program The miss program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetMissProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetRayTypeCount,"] + #[doc = " @ref rtContextGetMissProgram"] + #[doc = ""] + pub fn rtContextSetMissProgram( + context: RTcontext, + rayTypeIndex: ::std::os::raw::c_uint, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries the miss program associated with the given"] + #[doc = " context and ray type"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetMissProgram passes back the miss program associated with the"] + #[doc = " given context and ray type. This program is set via @ref rtContextSetMissProgram."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given an invalid ray type index or a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context node associated with the miss program"] + #[doc = " @param[in] rayTypeIndex The ray type index for the desired miss program"] + #[doc = " @param[out] program Return parameter to store the miss program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetMissProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetMissProgram,"] + #[doc = " @ref rtContextGetRayTypeCount"] + #[doc = ""] + pub fn rtContextGetMissProgram( + context: RTcontext, + rayTypeIndex: ::std::os::raw::c_uint, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets an RTtexturesampler corresponding to the texture id"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetTextureSamplerFromId returns a handle to the texture sampler in \\a *sampler"] + #[doc = " corresponding to the \\a samplerId supplied. If \\a samplerId does not map to a valid"] + #[doc = " texture handle, \\a *sampler is \\a NULL or if \\a context is invalid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] context The context the sampler should be originated from"] + #[doc = " @param[in] samplerId The ID of the sampler to query"] + #[doc = " @param[out] sampler The return handle for the sampler object corresponding to the samplerId"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetTextureSamplerFromId was introduced in OptiX 3.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetId"] + #[doc = ""] + pub fn rtContextGetTextureSamplerFromId( + context: RTcontext, + samplerId: ::std::os::raw::c_int, + sampler: *mut RTtexturesampler, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Calling this function has no effect. The kernel is automatically compiled at launch if needed."] + #[doc = ""] + pub fn rtContextCompile(context: RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Executes the computation kernel for a given context"] + #[doc = ""] + #[doc = " @ingroup rtContextLaunch"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextLaunch \"rtContextLaunch\" functions execute the computation kernel associated with the"] + #[doc = " given context. If the context has not yet been compiled, or if the context has been"] + #[doc = " modified since the last compile, @ref rtContextLaunch \"rtContextLaunch\" will recompile the kernel"] + #[doc = " internally. Acceleration structures of the context which are marked dirty will be"] + #[doc = " updated and their dirty flags will be cleared. Similarly, validation will occur if"] + #[doc = " necessary. The ray generation program specified by \\a entryPointIndex will be"] + #[doc = " invoked once for every element (pixel or voxel) of the computation grid specified by"] + #[doc = " \\a width, \\a height, and \\a depth."] + #[doc = ""] + #[doc = " For 3D launches, the product of \\a width and \\a depth must be smaller than 4294967296 (2^32)."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = " - @ref RT_ERROR_LAUNCH_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextLaunch \"rtContextLaunch\" was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetRunningState,"] + #[doc = " @ref rtContextValidate"] + #[doc = ""] + #[doc = " @ingroup rtContextLaunch"] + #[doc = " @param[in] context The context to be executed"] + #[doc = " @param[in] entryPointIndex The initial entry point into kernel"] + #[doc = " @param[in] width Width of the computation grid"] + pub fn rtContextLaunch1D( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + width: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @ingroup rtContextLaunch"] + #[doc = " @param[in] context The context to be executed"] + #[doc = " @param[in] entryPointIndex The initial entry point into kernel"] + #[doc = " @param[in] width Width of the computation grid"] + #[doc = " @param[in] height Height of the computation grid"] + pub fn rtContextLaunch2D( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + width: RTsize, + height: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @ingroup rtContextLaunch"] + #[doc = " @param[in] context The context to be executed"] + #[doc = " @param[in] entryPointIndex The initial entry point into kernel"] + #[doc = " @param[in] width Width of the computation grid"] + #[doc = " @param[in] height Height of the computation grid"] + #[doc = " @param[in] depth Depth of the computation grid"] + pub fn rtContextLaunch3D( + context: RTcontext, + entryPointIndex: ::std::os::raw::c_uint, + width: RTsize, + height: RTsize, + depth: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query whether the given context is currently"] + #[doc = " running"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " This function is currently unimplemented and it is provided as a placeholder for a future implementation."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried"] + #[doc = " @param[out] running Return parameter to store the running state"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Since unimplemented, this function will always throw an assertion failure."] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetRunningState was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextLaunch1D,"] + #[doc = " @ref rtContextLaunch2D,"] + #[doc = " @ref rtContextLaunch3D"] + #[doc = ""] + pub fn rtContextGetRunningState( + context: RTcontext, + running: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Executes a Progressive Launch for a given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Starts the (potentially parallel) generation of subframes for progressive rendering. If"] + #[doc = " \\a maxSubframes is zero, there is no limit on the number of subframes generated. The"] + #[doc = " generated subframes are automatically composited into a single result and streamed to"] + #[doc = " the client at regular intervals, where they can be read by mapping an associated stream"] + #[doc = " buffer. An application can therefore initiate a progressive launch, and then repeatedly"] + #[doc = " map and display the contents of the stream buffer in order to visualize the progressive"] + #[doc = " refinement of the image."] + #[doc = ""] + #[doc = " The call is nonblocking. A polling approach should be used to decide when to map and"] + #[doc = " display the stream buffer contents (see @ref rtBufferGetProgressiveUpdateReady). If a"] + #[doc = " progressive launch is already in progress at the time of the call and its parameters"] + #[doc = " match the initial launch, the call has no effect. Otherwise, the accumulated result will be"] + #[doc = " reset and a new progressive launch will be started."] + #[doc = ""] + #[doc = " If any other OptiX function is called while a progressive launch is in progress, it will"] + #[doc = " cause the launch to stop generating new subframes (however, subframes that have"] + #[doc = " already been generated and are currently in flight may still arrive at the client). The only"] + #[doc = " exceptions to this rule are the operations to map a stream buffer, issuing another"] + #[doc = " progressive launch with unchanged parameters, and polling for an update. Those"] + #[doc = " exceptions do not cause the progressive launch to stop generating subframes."] + #[doc = ""] + #[doc = " There is no guarantee that the call actually produces any subframes, especially if"] + #[doc = " @ref rtContextLaunchProgressive2D and other OptiX commands are called in short"] + #[doc = " succession. For example, during an animation, @ref rtVariableSet calls may be tightly"] + #[doc = " interleaved with progressive launches, and when rendering remotely the server may decide to skip some of the"] + #[doc = " launches in order to avoid a large backlog in the command pipeline."] + #[doc = ""] + #[doc = " @param[in] context The context in which the launch is to be executed"] + #[doc = " @param[in] entryIndex The initial entry point into kernel"] + #[doc = " @param[in] width Width of the computation grid"] + #[doc = " @param[in] height Height of the computation grid"] + #[doc = " @param[in] maxSubframes The maximum number of subframes to be generated. Set to zero to generate an unlimited number of subframes"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_LAUNCH_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextLaunchProgressive2D was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextStopProgressive"] + #[doc = " @ref rtBufferGetProgressiveUpdateReady"] + #[doc = ""] + pub fn rtContextLaunchProgressive2D( + context: RTcontext, + entryIndex: ::std::os::raw::c_uint, + width: RTsize, + height: RTsize, + maxSubframes: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Stops a Progressive Launch"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " If a progressive launch is currently in progress, calling @ref rtContextStopProgressive"] + #[doc = " terminates it. Otherwise, the call has no effect. If a launch is stopped using this function,"] + #[doc = " no further subframes will arrive at the client, even if they have already been generated"] + #[doc = " by the server and are currently in flight."] + #[doc = ""] + #[doc = " This call should only be used if the application must guarantee that frames generated by"] + #[doc = " previous progressive launches won't be accessed. Do not call @ref rtContextStopProgressive in"] + #[doc = " the main rendering loop if the goal is only to change OptiX state (e.g. rtVariable values)."] + #[doc = " The call is unnecessary in that case and will degrade performance."] + #[doc = ""] + #[doc = " @param[in] context The context associated with the progressive launch"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextStopProgressive was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextLaunchProgressive2D"] + #[doc = ""] + pub fn rtContextStopProgressive(context: RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Enable or disable text printing from programs"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintEnabled is used to control whether text printing in programs"] + #[doc = " through @ref rtPrintf is currently enabled for this context."] + #[doc = ""] + #[doc = " @param[in] context The context for which printing is to be enabled or disabled"] + #[doc = " @param[in] enabled Setting this parameter to a nonzero value enables printing, \\a 0 disables printing"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintEnabled was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextGetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintBufferSize,"] + #[doc = " @ref rtContextGetPrintBufferSize,"] + #[doc = " @ref rtContextSetPrintLaunchIndex,"] + #[doc = " @ref rtContextGetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextSetPrintEnabled(context: RTcontext, enabled: ::std::os::raw::c_int) + -> RTresult; +} +extern "C" { + #[doc = " @brief Query whether text printing from programs"] + #[doc = " is enabled"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintEnabled passes back \\a 1 if text printing from programs through"] + #[doc = " @ref rtPrintf is currently enabled for this context; \\a 0 otherwise. Returns @ref"] + #[doc = " RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context to be queried"] + #[doc = " @param[out] enabled Return parameter to store whether printing is enabled"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintEnabled was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextSetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintBufferSize,"] + #[doc = " @ref rtContextGetPrintBufferSize,"] + #[doc = " @ref rtContextSetPrintLaunchIndex,"] + #[doc = " @ref rtContextGetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextGetPrintEnabled( + context: RTcontext, + enabled: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the size of the print buffer"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintBufferSize is used to set the buffer size available to hold"] + #[doc = " data generated by @ref rtPrintf."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if it is called after the first invocation of rtContextLaunch."] + #[doc = ""] + #[doc = ""] + #[doc = " @param[in] context The context for which to set the print buffer size"] + #[doc = " @param[in] bufferSizeBytes The print buffer size in bytes"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintBufferSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextSetPrintEnabled,"] + #[doc = " @ref rtContextGetPrintEnabled,"] + #[doc = " @ref rtContextGetPrintBufferSize,"] + #[doc = " @ref rtContextSetPrintLaunchIndex,"] + #[doc = " @ref rtContextGetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextSetPrintBufferSize(context: RTcontext, bufferSizeBytes: RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Get the current size of the print buffer"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintBufferSize is used to query the buffer size available to hold"] + #[doc = " data generated by @ref rtPrintf. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a"] + #[doc = " NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context from which to query the print buffer size"] + #[doc = " @param[out] bufferSizeBytes The returned print buffer size in bytes"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintBufferSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextSetPrintEnabled,"] + #[doc = " @ref rtContextGetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintBufferSize,"] + #[doc = " @ref rtContextSetPrintLaunchIndex,"] + #[doc = " @ref rtContextGetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextGetPrintBufferSize( + context: RTcontext, + bufferSizeBytes: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the active launch index to limit text output"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintLaunchIndex is used to control for which launch indices @ref"] + #[doc = " rtPrintf generates output. The initial value of (x,y,z) is (\\a -1,\\a -1,\\a -1), which"] + #[doc = " generates output for all indices."] + #[doc = ""] + #[doc = " @param[in] context The context for which to set the print launch index"] + #[doc = " @param[in] x The launch index in the x dimension to which to limit the output of @ref rtPrintf invocations."] + #[doc = " If set to \\a -1, output is generated for all launch indices in the x dimension"] + #[doc = " @param[in] y The launch index in the y dimension to which to limit the output of @ref rtPrintf invocations."] + #[doc = " If set to \\a -1, output is generated for all launch indices in the y dimension"] + #[doc = " @param[in] z The launch index in the z dimension to which to limit the output of @ref rtPrintf invocations."] + #[doc = " If set to \\a -1, output is generated for all launch indices in the z dimension"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetPrintLaunchIndex was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextGetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintBufferSize,"] + #[doc = " @ref rtContextGetPrintBufferSize,"] + #[doc = " @ref rtContextGetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextSetPrintLaunchIndex( + context: RTcontext, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + z: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the active print launch index"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintLaunchIndex is used to query for which launch indices @ref"] + #[doc = " rtPrintf generates output. The initial value of (x,y,z) is (\\a -1,\\a -1,\\a -1), which"] + #[doc = " generates output for all indices."] + #[doc = ""] + #[doc = " @param[in] context The context from which to query the print launch index"] + #[doc = " @param[out] x Returns the launch index in the x dimension to which the output of @ref rtPrintf invocations"] + #[doc = " is limited. Will not be written to if a \\a NULL pointer is passed"] + #[doc = " @param[out] y Returns the launch index in the y dimension to which the output of @ref rtPrintf invocations"] + #[doc = " is limited. Will not be written to if a \\a NULL pointer is passed"] + #[doc = " @param[out] z Returns the launch index in the z dimension to which the output of @ref rtPrintf invocations"] + #[doc = " is limited. Will not be written to if a \\a NULL pointer is passed"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetPrintLaunchIndex was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPrintf,"] + #[doc = " @ref rtContextGetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintEnabled,"] + #[doc = " @ref rtContextSetPrintBufferSize,"] + #[doc = " @ref rtContextGetPrintBufferSize,"] + #[doc = " @ref rtContextSetPrintLaunchIndex"] + #[doc = ""] + pub fn rtContextGetPrintLaunchIndex( + context: RTcontext, + x: *mut ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_int, + z: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable associated with this"] + #[doc = " context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextDeclareVariable - Declares a new variable named \\a name and associated"] + #[doc = " with this context. Only a single variable of a given name can exist for a given"] + #[doc = " context and any attempt to create multiple variables with the same name will cause a"] + #[doc = " failure with a return value of @ref RT_ERROR_VARIABLE_REDECLARED. Returns @ref"] + #[doc = " RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer. Return @ref"] + #[doc = " RT_ERROR_ILLEGAL_SYMBOL if \\a name is not syntactically valid."] + #[doc = ""] + #[doc = " @param[in] context The context node to which the variable will be attached"] + #[doc = " @param[in] name The name that identifies the variable to be queried"] + #[doc = " @param[out] v Pointer to variable handle used to return the new object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_VARIABLE_REDECLARED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryDeclareVariable,"] + #[doc = " @ref rtGeometryInstanceDeclareVariable,"] + #[doc = " @ref rtMaterialDeclareVariable,"] + #[doc = " @ref rtProgramDeclareVariable,"] + #[doc = " @ref rtSelectorDeclareVariable,"] + #[doc = " @ref rtContextGetVariable,"] + #[doc = " @ref rtContextGetVariableCount,"] + #[doc = " @ref rtContextQueryVariable,"] + #[doc = " @ref rtContextRemoveVariable"] + #[doc = ""] + pub fn rtContextDeclareVariable( + context: RTcontext, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a named variable associated with this context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextQueryVariable queries a variable identified by the string \\a name"] + #[doc = " from \\a context and stores the result in \\a *v. A variable must"] + #[doc = " be declared with @ref rtContextDeclareVariable before it can be queried, otherwise \\a *v will be set to \\a NULL."] + #[doc = " @ref RT_ERROR_INVALID_VALUE will be returned if \\a name or \\a v is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context The context node to query a variable from"] + #[doc = " @param[in] name The name that identifies the variable to be queried"] + #[doc = " @param[out] v Return value to store the queried variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryQueryVariable,"] + #[doc = " @ref rtGeometryInstanceQueryVariable,"] + #[doc = " @ref rtMaterialQueryVariable,"] + #[doc = " @ref rtProgramQueryVariable,"] + #[doc = " @ref rtSelectorQueryVariable,"] + #[doc = " @ref rtContextDeclareVariable,"] + #[doc = " @ref rtContextGetVariableCount,"] + #[doc = " @ref rtContextGetVariable,"] + #[doc = " @ref rtContextRemoveVariable"] + #[doc = ""] + pub fn rtContextQueryVariable( + context: RTcontext, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a variable from the given context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextRemoveVariable removes variable \\a v from \\a context if present."] + #[doc = " Returns @ref RT_ERROR_VARIABLE_NOT_FOUND if the variable is not attached to this"] + #[doc = " context. Returns @ref RT_ERROR_INVALID_VALUE if passed an invalid variable."] + #[doc = ""] + #[doc = " @param[in] context The context node from which to remove a variable"] + #[doc = " @param[in] v The variable to be removed"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryRemoveVariable,"] + #[doc = " @ref rtGeometryInstanceRemoveVariable,"] + #[doc = " @ref rtMaterialRemoveVariable,"] + #[doc = " @ref rtProgramRemoveVariable,"] + #[doc = " @ref rtSelectorRemoveVariable,"] + #[doc = " @ref rtContextDeclareVariable,"] + #[doc = " @ref rtContextGetVariable,"] + #[doc = " @ref rtContextGetVariableCount,"] + #[doc = " @ref rtContextQueryVariable,"] + #[doc = ""] + pub fn rtContextRemoveVariable(context: RTcontext, v: RTvariable) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of variables associated"] + #[doc = " with this context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetVariableCount returns the number of variables that are currently"] + #[doc = " attached to \\a context. Returns @ref RT_ERROR_INVALID_VALUE if passed a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] context The context to be queried for number of attached variables"] + #[doc = " @param[out] count Return parameter to store the number of variables"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetVariableCount,"] + #[doc = " @ref rtGeometryInstanceGetVariableCount,"] + #[doc = " @ref rtMaterialGetVariableCount,"] + #[doc = " @ref rtProgramGetVariableCount,"] + #[doc = " @ref rtSelectorGetVariable,"] + #[doc = " @ref rtContextDeclareVariable,"] + #[doc = " @ref rtContextGetVariable,"] + #[doc = " @ref rtContextQueryVariable,"] + #[doc = " @ref rtContextRemoveVariable"] + #[doc = ""] + pub fn rtContextGetVariableCount( + context: RTcontext, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries an indexed variable associated with this context"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetVariable queries the variable at position \\a index in the"] + #[doc = " variable array from \\a context and stores the result in the parameter \\a v."] + #[doc = " A variable must be declared first with @ref rtContextDeclareVariable and"] + #[doc = " \\a index must be in the range [\\a 0, @ref rtContextGetVariableCount \\a -1]."] + #[doc = ""] + #[doc = " @param[in] context The context node to be queried for an indexed variable"] + #[doc = " @param[in] index The index that identifies the variable to be queried"] + #[doc = " @param[out] v Return value to store the queried variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetVariable,"] + #[doc = " @ref rtGeometryInstanceGetVariable,"] + #[doc = " @ref rtMaterialGetVariable,"] + #[doc = " @ref rtProgramGetVariable,"] + #[doc = " @ref rtSelectorGetVariable,"] + #[doc = " @ref rtContextDeclareVariable,"] + #[doc = " @ref rtContextGetVariableCount,"] + #[doc = " @ref rtContextQueryVariable,"] + #[doc = " @ref rtContextRemoveVariable"] + #[doc = ""] + pub fn rtContextGetVariable( + context: RTcontext, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXString allocates and returns a handle to a new program"] + #[doc = " object. The program is created from PTX code held in the \\a NULL-terminated string \\a"] + #[doc = " ptx from function \\a programName."] + #[doc = ""] + #[doc = " @param[in] context The context to create the program in"] + #[doc = " @param[in] ptx The string containing the PTX code"] + #[doc = " @param[in] programName The name of the PTX function to create the program from"] + #[doc = " @param[in] program Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXString was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RT_PROGRAM,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXFiles,"] + #[doc = " @ref rtProgramCreateFromPTXStrings,"] + #[doc = " @ref rtProgramDestroy"] + #[doc = ""] + pub fn rtProgramCreateFromPTXString( + context: RTcontext, + ptx: *const ::std::os::raw::c_char, + programName: *const ::std::os::raw::c_char, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXStrings allocates and returns a handle to a new program"] + #[doc = " object. The program is created by linking PTX code held in one or more \\a NULL-terminated strings."] + #[doc = " C-style linking rules apply: global functions and variables are visible across input strings and must"] + #[doc = " be defined uniquely. There must be a visible function for \\a programName."] + #[doc = ""] + #[doc = " @param[in] context The context to create the program in"] + #[doc = " @param[in] n Number of ptx strings"] + #[doc = " @param[in] ptxStrings Array of strings containing PTX code"] + #[doc = " @param[in] programName The name of the PTX function to create the program from"] + #[doc = " @param[in] program Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RT_PROGRAM,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXFiles,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramDestroy"] + #[doc = ""] + pub fn rtProgramCreateFromPTXStrings( + context: RTcontext, + n: ::std::os::raw::c_uint, + ptxStrings: *mut *const ::std::os::raw::c_char, + programName: *const ::std::os::raw::c_char, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXFile allocates and returns a handle to a new program object."] + #[doc = " The program is created from PTX code held in \\a filename from function \\a programName."] + #[doc = ""] + #[doc = " @param[in] context The context to create the program in"] + #[doc = " @param[in] filename Path to the file containing the PTX code"] + #[doc = " @param[in] programName The name of the PTX function to create the program from"] + #[doc = " @param[in] program Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = " - @ref RT_ERROR_FILE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXFile was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RT_PROGRAM,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramDestroy"] + #[doc = ""] + pub fn rtProgramCreateFromPTXFile( + context: RTcontext, + filename: *const ::std::os::raw::c_char, + programName: *const ::std::os::raw::c_char, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromPTXFiles allocates and returns a handle to a new program object."] + #[doc = " The program is created by linking PTX code held in one or more files."] + #[doc = " C-style linking rules apply: global functions and variables are visible across input files and must"] + #[doc = " be defined uniquely. There must be a visible function for \\a programName."] + #[doc = ""] + #[doc = " @param[in] context The context to create the program in"] + #[doc = " @param[in] n Number of filenames"] + #[doc = " @param[in] filenames Array of one or more paths to files containing PTX code"] + #[doc = " @param[in] programName The name of the PTX function to create the program from"] + #[doc = " @param[in] program Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_INVALID_SOURCE"] + #[doc = " - @ref RT_ERROR_FILE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RT_PROGRAM,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramCreateFromPTXStrings,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromProgram,"] + #[doc = " @ref rtProgramDestroy"] + #[doc = ""] + pub fn rtProgramCreateFromPTXFiles( + context: RTcontext, + n: ::std::os::raw::c_uint, + filenames: *mut *const ::std::os::raw::c_char, + programName: *const ::std::os::raw::c_char, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCreateFromProgram allocates and returns a handle to a new program object."] + #[doc = " The program code is taken from another program, but none of the other attributes are taken."] + #[doc = ""] + #[doc = " @param[in] context The context to create the program in"] + #[doc = " @param[in] program_in The program whose program code to use."] + #[doc = " @param[in] program_out Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RT_PROGRAM,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramCreateFromPTXStrings,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramDestroy"] + #[doc = ""] + pub fn rtProgramCreateFromProgram( + context: RTcontext, + program_in: RTprogram, + program_out: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramDestroy removes \\a program from its context and deletes it."] + #[doc = " \\a program should be a value returned by \\a rtProgramCreate*."] + #[doc = " Associated variables declared via @ref rtProgramDeclareVariable are destroyed."] + #[doc = " After the call, \\a program is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] program Handle of the program to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtProgramDestroy(program: RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the state of a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramValidate checks \\a program for completeness. If \\a program or any of"] + #[doc = " the objects attached to \\a program are not valid, returns @ref"] + #[doc = " RT_ERROR_INVALID_CONTEXT."] + #[doc = ""] + #[doc = " @param[in] program The program to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtProgramValidate(program: RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the context object that created a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramGetContext returns a handle to the context object that was used to"] + #[doc = " create \\a program. Returns @ref RT_ERROR_INVALID_VALUE if \\a context is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] program The program to be queried for its context object"] + #[doc = " @param[out] context The return handle for the requested context object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtProgramGetContext(program: RTprogram, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable associated with a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramDeclareVariable declares a new variable, \\a name, and associates it with"] + #[doc = " the program. A variable can only be declared with the same name once on the program."] + #[doc = " Any attempt to declare multiple variables with the same name will cause the call to"] + #[doc = " fail and return @ref RT_ERROR_VARIABLE_REDECLARED. If \\a name or\\a v is \\a NULL"] + #[doc = " returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] program The program the declared variable will be attached to"] + #[doc = " @param[in] name The name of the variable to be created"] + #[doc = " @param[out] v Return handle to the variable to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_REDECLARED"] + #[doc = " - @ref RT_ERROR_ILLEGAL_SYMBOL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramRemoveVariable,"] + #[doc = " @ref rtProgramGetVariable,"] + #[doc = " @ref rtProgramGetVariableCount,"] + #[doc = " @ref rtProgramQueryVariable"] + #[doc = ""] + pub fn rtProgramDeclareVariable( + program: RTprogram, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to the named variable attached to a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramQueryVariable returns a handle to a variable object, in \\a *v, attached"] + #[doc = " to \\a program referenced by the \\a NULL-terminated string \\a name. If \\a name is not"] + #[doc = " the name of a variable attached to \\a program, \\a *v will be \\a NULL after the call."] + #[doc = ""] + #[doc = " @param[in] program The program to be queried for the named variable"] + #[doc = " @param[in] name The name of the program to be queried for"] + #[doc = " @param[out] v The return handle to the variable object"] + #[doc = " @param program Handle to the program to be created"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramDeclareVariable,"] + #[doc = " @ref rtProgramRemoveVariable,"] + #[doc = " @ref rtProgramGetVariable,"] + #[doc = " @ref rtProgramGetVariableCount"] + #[doc = ""] + pub fn rtProgramQueryVariable( + program: RTprogram, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes the named variable from a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramRemoveVariable removes variable \\a v from the \\a program object. Once a"] + #[doc = " variable has been removed from this program, another variable with the same name as"] + #[doc = " the removed variable may be declared."] + #[doc = ""] + #[doc = " @param[in] program The program to remove the variable from"] + #[doc = " @param[in] v The variable to remove"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramDeclareVariable,"] + #[doc = " @ref rtProgramGetVariable,"] + #[doc = " @ref rtProgramGetVariableCount,"] + #[doc = " @ref rtProgramQueryVariable"] + #[doc = ""] + pub fn rtProgramRemoveVariable(program: RTprogram, v: RTvariable) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of variables attached to a program"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramGetVariableCount returns, in \\a *count, the number of variable objects that"] + #[doc = " have been attached to \\a program."] + #[doc = ""] + #[doc = " @param[in] program The program to be queried for its variable count"] + #[doc = " @param[out] count The return handle for the number of variables attached to this program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramDeclareVariable,"] + #[doc = " @ref rtProgramRemoveVariable,"] + #[doc = " @ref rtProgramGetVariable,"] + #[doc = " @ref rtProgramQueryVariable"] + #[doc = ""] + pub fn rtProgramGetVariableCount( + program: RTprogram, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to a variable attached to a program by index"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramGetVariable returns a handle to a variable in \\a *v attached to \\a"] + #[doc = " program with @ref rtProgramDeclareVariable by \\a index. \\a index must be between"] + #[doc = " 0 and one less than the value returned by @ref rtProgramGetVariableCount. The order"] + #[doc = " in which variables are enumerated is not constant and may change as variables are"] + #[doc = " attached and removed from the program object."] + #[doc = ""] + #[doc = " @param[in] program The program to be queried for the indexed variable object"] + #[doc = " @param[in] index The index of the variable to return"] + #[doc = " @param[out] v Return handle to the variable object specified by the index"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramDeclareVariable,"] + #[doc = " @ref rtProgramRemoveVariable,"] + #[doc = " @ref rtProgramGetVariableCount,"] + #[doc = " @ref rtProgramQueryVariable"] + #[doc = ""] + pub fn rtProgramGetVariable( + program: RTprogram, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the ID for the Program object"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramGetId returns an ID for the provided program. The returned ID is used"] + #[doc = " to reference \\a program from device code. If \\a programId is \\a NULL or the \\a"] + #[doc = " program is not a valid \\a RTprogram, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = " @ref RT_PROGRAM_ID_NULL can be used as a sentinel for a non-existent program, since"] + #[doc = " this value will never be returned as a valid program id."] + #[doc = ""] + #[doc = " @param[in] program The program to be queried for its id"] + #[doc = " @param[out] programId The returned ID of the program."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramGetId was introduced in OptiX 3.6."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetProgramFromId"] + #[doc = ""] + pub fn rtProgramGetId(program: RTprogram, programId: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the program ids that may potentially be called at a call site"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtProgramCallsiteSetPotentialCallees specifies the program IDs of potential"] + #[doc = " callees at the call site in the \\a program identified by \\a name to the list"] + #[doc = " provided in \\a ids. If \\a program is bit a valid \\a RTprogram or the \\a program"] + #[doc = " does not contain a call site with the identifier \\a name or \\a ids contains"] + #[doc = " invalid program ids, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] program The program that includes the call site."] + #[doc = " @param[in] name The string identifier for the call site to modify."] + #[doc = " @param[in] ids The program IDs of the programs that may potentially be called at the call site"] + #[doc = " @param[in] numIds The size of the array passed in for \\a ids."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtProgramCallsiteSetPotentialCallees was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramGetId"] + #[doc = ""] + pub fn rtProgramCallsiteSetPotentialCallees( + program: RTprogram, + name: *const ::std::os::raw::c_char, + ids: *const ::std::os::raw::c_int, + numIds: ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets an RTprogram corresponding to the program id"] + #[doc = ""] + #[doc = " @ingroup Program"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetProgramFromId returns a handle to the program in \\a *program"] + #[doc = " corresponding to the \\a programId supplied. If \\a programId is not a valid"] + #[doc = " program handle, \\a *program is set to \\a NULL. Returns @ref RT_ERROR_INVALID_VALUE"] + #[doc = " if \\a context is invalid or \\a programId is not a valid program handle."] + #[doc = ""] + #[doc = " @param[in] context The context the program should be originated from"] + #[doc = " @param[in] programId The ID of the program to query"] + #[doc = " @param[out] program The return handle for the program object corresponding to the programId"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetProgramFromId was introduced in OptiX 3.6."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtProgramGetId"] + #[doc = ""] + pub fn rtContextGetProgramFromId( + context: RTcontext, + programId: ::std::os::raw::c_int, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupCreate creates a new group within a context. \\a context"] + #[doc = " specifies the target context, and should be a value returned by"] + #[doc = " @ref rtContextCreate. Sets \\a *group to the handle of a newly created group"] + #[doc = " within \\a context. Returns @ref RT_ERROR_INVALID_VALUE if \\a group is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies a context within which to create a new group"] + #[doc = " @param[out] group Returns a newly created group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupDestroy,"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtGroupCreate(context: RTcontext, group: *mut RTgroup) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a group node"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupDestroy removes \\a group from its context and deletes it."] + #[doc = " \\a group should be a value returned by @ref rtGroupCreate."] + #[doc = " No child graph nodes are destroyed."] + #[doc = " After the call, \\a group is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] group Handle of the group node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupCreate"] + #[doc = ""] + pub fn rtGroupDestroy(group: RTgroup) -> RTresult; +} +extern "C" { + #[doc = " @brief Verifies the state of the group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupValidate checks \\a group for completeness. If \\a group or"] + #[doc = " any of the objects attached to \\a group are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] group Specifies the group to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupCreate"] + #[doc = ""] + pub fn rtGroupValidate(group: RTgroup) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupGetContext queries a group for its associated context."] + #[doc = " \\a group specifies the group to query, and must be a value returned by"] + #[doc = " @ref rtGroupCreate. Sets \\a *context to the context"] + #[doc = " associated with \\a group."] + #[doc = ""] + #[doc = " @param[in] group Specifies the group to query"] + #[doc = " @param[out] context Returns the context associated with the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate,"] + #[doc = " @ref rtGroupCreate"] + #[doc = ""] + pub fn rtGroupGetContext(group: RTgroup, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the acceleration structure for a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupSetAcceleration attaches an acceleration structure to a group. The acceleration"] + #[doc = " structure must have been previously created using @ref rtAccelerationCreate. Every group is"] + #[doc = " required to have an acceleration structure assigned in order to pass validation. The acceleration"] + #[doc = " structure will be built over the children of the group. For example, if an acceleration structure"] + #[doc = " is attached to a group that has a selector, a geometry group, and a transform child,"] + #[doc = " the acceleration structure will be built over the bounding volumes of these three objects."] + #[doc = ""] + #[doc = " Note that it is legal to attach a single RTacceleration object to multiple groups, as long as"] + #[doc = " the underlying bounds of the children are the same. For example, if another group has three"] + #[doc = " children which are known to have the same bounding volumes as the ones in the example"] + #[doc = " above, the two groups can share an acceleration structure, thus saving build time. This is"] + #[doc = " true even if the details of the children, such as the actual type of a node or its geometry"] + #[doc = " content, differ from the first set of group children. All that is required is for a child"] + #[doc = " node at a given index to have the same bounds as the other group's child node at the same index."] + #[doc = ""] + #[doc = " Sharing an acceleration structure this way corresponds to attaching an acceleration structure"] + #[doc = " to multiple geometry groups at lower graph levels using @ref rtGeometryGroupSetAcceleration."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[in] acceleration The acceleration structure to attach to the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupSetAcceleration was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupGetAcceleration,"] + #[doc = " @ref rtAccelerationCreate,"] + #[doc = " @ref rtGeometryGroupSetAcceleration"] + #[doc = ""] + pub fn rtGroupSetAcceleration(group: RTgroup, acceleration: RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the visibility mask for a group."] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " Geometry is intersected by rays if the ray's @ref RTvisibilitymask shares at"] + #[doc = " least one bit with the group's mask. This mechanism allows for a number of"] + #[doc = " user-defined visibility groups that can be excluded from certain types of rays"] + #[doc = " as needed."] + #[doc = " Note that the visibility mask is not checked for the root node of a trace call."] + #[doc = " (It is assumed to be visible otherwise trace should not be called)."] + #[doc = " Note that the @pre mask is currently limited to 8 bits."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[in] mask A set of bits for which rays will intersect the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupSetVisibilityMask was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetVisibilityMask,"] + #[doc = " @ref rtGroupGetVisibilityMask,"] + #[doc = " @ref rtTrace"] + pub fn rtGroupSetVisibilityMask(group: RTgroup, mask: RTvisibilitymask) -> RTresult; +} +extern "C" { + #[doc = " @brief Retrieves the visibility mask of a group."] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " See @ref rtGroupSetVisibilityMask for details."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[out] mask A set of bits for which rays will intersect the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetVisibilityMask was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupGetVisibilityMask,"] + #[doc = " @ref rtGroupSetVisibilityMask,"] + #[doc = " @ref rtTrace"] + pub fn rtGroupGetVisibilityMask(group: RTgroup, mask: *mut RTvisibilitymask) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the acceleration structure attached to a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupGetAcceleration returns the acceleration structure attached to a group using @ref rtGroupSetAcceleration."] + #[doc = " If no acceleration structure has previously been set, \\a *acceleration is set to \\a NULL."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[out] acceleration The returned acceleration structure object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetAcceleration was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetAcceleration,"] + #[doc = " @ref rtAccelerationCreate"] + #[doc = ""] + pub fn rtGroupGetAcceleration(group: RTgroup, acceleration: *mut RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of child nodes to be attached to the group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupSetChildCount specifies the number of child slots in this group. Potentially existing links to children"] + #[doc = " at indices greater than \\a count-1 are removed. If the call increases the number of slots, the newly"] + #[doc = " created slots are empty and need to be filled using @ref rtGroupSetChild before validation."] + #[doc = ""] + #[doc = " @param[in] group The parent group handle"] + #[doc = " @param[in] count Number of child slots to allocate for the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupSetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupGetChild,"] + #[doc = " @ref rtGroupGetChildCount,"] + #[doc = " @ref rtGroupGetChildType,"] + #[doc = " @ref rtGroupSetChild"] + #[doc = ""] + pub fn rtGroupSetChildCount(group: RTgroup, count: ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of child slots for a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupGetChildCount returns the number of child slots allocated using @ref"] + #[doc = " rtGroupSetChildCount. This includes empty slots which may not yet have actual children assigned"] + #[doc = " by @ref rtGroupSetChild. Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] group The parent group handle"] + #[doc = " @param[out] count Returned number of child slots"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetChild,"] + #[doc = " @ref rtGroupGetChild,"] + #[doc = " @ref rtGroupSetChildCount,"] + #[doc = " @ref rtGroupGetChildType"] + #[doc = ""] + pub fn rtGroupGetChildCount(group: RTgroup, count: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a child node to a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Attaches a new child node \\a child to the parent node"] + #[doc = " \\a group. \\a index specifies the number of the slot where the child"] + #[doc = " node gets attached. A sufficient number of slots must be allocated"] + #[doc = " using @ref rtGroupSetChildCount."] + #[doc = " Legal child node types are @ref RTgroup, @ref RTselector, @ref RTgeometrygroup, and"] + #[doc = " @ref RTtransform."] + #[doc = ""] + #[doc = " @param[in] group The parent group handle"] + #[doc = " @param[in] index The index in the parent's child slot array"] + #[doc = " @param[in] child The child node to be attached. Can be of type {@ref RTgroup, @ref RTselector,"] + #[doc = " @ref RTgeometrygroup, @ref RTtransform}"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupSetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetChildCount,"] + #[doc = " @ref rtGroupGetChildCount,"] + #[doc = " @ref rtGroupGetChild,"] + #[doc = " @ref rtGroupGetChildType"] + #[doc = ""] + pub fn rtGroupSetChild( + group: RTgroup, + index: ::std::os::raw::c_uint, + child: RTobject, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a child node of a group"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupGetChild returns the child object at slot \\a index of the parent \\a group."] + #[doc = " If no child has been assigned to the given slot, \\a *child is set to \\a NULL."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given an invalid child index or \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] group The parent group handle"] + #[doc = " @param[in] index The index of the child slot to query"] + #[doc = " @param[out] child The returned child object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetChild,"] + #[doc = " @ref rtGroupSetChildCount,"] + #[doc = " @ref rtGroupGetChildCount,"] + #[doc = " @ref rtGroupGetChildType"] + #[doc = ""] + pub fn rtGroupGetChild( + group: RTgroup, + index: ::std::os::raw::c_uint, + child: *mut RTobject, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Get the type of a group child"] + #[doc = ""] + #[doc = " @ingroup GroupNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGroupGetChildType returns the type of the group child at slot \\a index."] + #[doc = " If no child is associated with the given index, \\a *type is set to"] + #[doc = " @ref RT_OBJECTTYPE_UNKNOWN and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] group The parent group handle"] + #[doc = " @param[in] index The index of the child slot to query"] + #[doc = " @param[out] type The returned child type"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGroupGetChildType was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetChild,"] + #[doc = " @ref rtGroupGetChild,"] + #[doc = " @ref rtGroupSetChildCount,"] + #[doc = " @ref rtGroupGetChildCount"] + #[doc = ""] + pub fn rtGroupGetChildType( + group: RTgroup, + index: ::std::os::raw::c_uint, + type_: *mut RTobjecttype, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Creates a new Selector node within \\a context. After calling"] + #[doc = " @ref rtSelectorCreate the new node is in an invalid state. For the node"] + #[doc = " to be valid, a visit program must be assigned using"] + #[doc = " @ref rtSelectorSetVisitProgram. Furthermore, a number of (zero or"] + #[doc = " more) children can be attached by using @ref rtSelectorSetChildCount and"] + #[doc = " @ref rtSelectorSetChild. Sets \\a *selector to the handle of a newly"] + #[doc = " created selector within \\a context. Returns @ref RT_ERROR_INVALID_VALUE if \\a selector is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the Selector node"] + #[doc = " @param[out] selector New Selector node handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorDestroy,"] + #[doc = " @ref rtSelectorValidate,"] + #[doc = " @ref rtSelectorGetContext,"] + #[doc = " @ref rtSelectorSetVisitProgram,"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorSetChild"] + #[doc = ""] + pub fn rtSelectorCreate(context: RTcontext, selector: *mut RTselector) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorDestroy removes \\a selector from its context and deletes it. \\a selector should"] + #[doc = " be a value returned by @ref rtSelectorCreate. Associated variables declared via @ref"] + #[doc = " rtSelectorDeclareVariable are destroyed, but no child graph nodes are destroyed. After the"] + #[doc = " call, \\a selector is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] selector Handle of the selector node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorCreate,"] + #[doc = " @ref rtSelectorValidate,"] + #[doc = " @ref rtSelectorGetContext"] + #[doc = ""] + pub fn rtSelectorDestroy(selector: RTselector) -> RTresult; +} +extern "C" { + #[doc = " @brief Checks a Selector node for internal consistency"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorValidate recursively checks consistency of the Selector"] + #[doc = " node \\a selector and its children, i.e., it tries to validate the"] + #[doc = " whole model sub-tree with \\a selector as root. For a Selector node to"] + #[doc = " be valid, it must be assigned a visit program, and the number of its"] + #[doc = " children must match the number specified by"] + #[doc = " @ref rtSelectorSetChildCount."] + #[doc = ""] + #[doc = " @param[in] selector Selector root node of a model sub-tree to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorCreate,"] + #[doc = " @ref rtSelectorDestroy,"] + #[doc = " @ref rtSelectorGetContext,"] + #[doc = " @ref rtSelectorSetVisitProgram,"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorSetChild"] + #[doc = ""] + pub fn rtSelectorValidate(selector: RTselector) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context of a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetContext returns in \\a context the rendering context"] + #[doc = " in which the Selector node \\a selector has been created."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[out] context The context, \\a selector belongs to"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorCreate,"] + #[doc = " @ref rtSelectorDestroy,"] + #[doc = " @ref rtSelectorValidate"] + #[doc = ""] + pub fn rtSelectorGetContext(selector: RTselector, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Assigns a visit program to a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorSetVisitProgram specifies a visit program that is"] + #[doc = " executed when the Selector node \\a selector gets visited by a ray"] + #[doc = " during traversal of the model graph. A visit program steers how"] + #[doc = " traversal of the Selectors's children is performed. It usually"] + #[doc = " chooses only a single child to continue traversal, but is also allowed"] + #[doc = " to process zero or multiple children. Programs can be created from PTX"] + #[doc = " files using @ref rtProgramCreateFromPTXFile."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] program Program handle associated with a visit program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorSetVisitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorGetVisitProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile"] + #[doc = ""] + pub fn rtSelectorSetVisitProgram(selector: RTselector, program: RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the currently assigned visit program"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetVisitProgram returns in \\a program a handle of the"] + #[doc = " visit program curently bound to \\a selector."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[out] program Current visit progam assigned to \\a selector"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetVisitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorSetVisitProgram"] + #[doc = ""] + pub fn rtSelectorGetVisitProgram(selector: RTselector, program: *mut RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the number of child nodes to be"] + #[doc = " attached to a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorSetChildCount allocates a number of children slots,"] + #[doc = " i.e., it pre-defines the exact number of child nodes the parent"] + #[doc = " Selector node \\a selector will have. Child nodes have to be attached"] + #[doc = " to the Selector node using @ref rtSelectorSetChild. Empty slots will"] + #[doc = " cause a validation error."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] count Number of child nodes to be attached to \\a selector"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorSetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorValidate,"] + #[doc = " @ref rtSelectorGetChildCount,"] + #[doc = " @ref rtSelectorSetChild,"] + #[doc = " @ref rtSelectorGetChild,"] + #[doc = " @ref rtSelectorGetChildType"] + #[doc = ""] + pub fn rtSelectorSetChildCount(selector: RTselector, count: ::std::os::raw::c_uint) + -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of child node slots of"] + #[doc = " a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChildCount returns in \\a count the number of child"] + #[doc = " node slots that have been previously reserved for the Selector node"] + #[doc = " \\a selector by @ref rtSelectorSetChildCount. The value of \\a count"] + #[doc = " does not reflect the actual number of child nodes that have so far"] + #[doc = " been attached to the Selector node using @ref rtSelectorSetChild."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[out] count Number of child node slots reserved for \\a selector"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorSetChild,"] + #[doc = " @ref rtSelectorGetChild,"] + #[doc = " @ref rtSelectorGetChildType"] + #[doc = ""] + pub fn rtSelectorGetChildCount( + selector: RTselector, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a child node to a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Attaches a new child node \\a child to the parent node"] + #[doc = " \\a selector. \\a index specifies the number of the slot where the child"] + #[doc = " node gets attached. The index value must be lower than the number"] + #[doc = " previously set by @ref rtSelectorSetChildCount, thus it must be in"] + #[doc = " the range from \\a 0 to @ref rtSelectorGetChildCount \\a -1. Legal child"] + #[doc = " node types are @ref RTgroup, @ref RTselector, @ref RTgeometrygroup, and"] + #[doc = " @ref RTtransform."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] index Index of the parent slot the node \\a child gets attached to"] + #[doc = " @param[in] child Child node to be attached. Can be {@ref RTgroup, @ref RTselector,"] + #[doc = " @ref RTgeometrygroup, @ref RTtransform}"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorSetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorGetChildCount,"] + #[doc = " @ref rtSelectorGetChild,"] + #[doc = " @ref rtSelectorGetChildType"] + #[doc = ""] + pub fn rtSelectorSetChild( + selector: RTselector, + index: ::std::os::raw::c_uint, + child: RTobject, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a child node that is attached to a"] + #[doc = " Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChild returns in \\a child a handle of the child node"] + #[doc = " currently attached to \\a selector at slot \\a index. The index value"] + #[doc = " must be lower than the number previously set by"] + #[doc = " @ref rtSelectorSetChildCount, thus it must be in the range from \\a 0"] + #[doc = " to @ref rtSelectorGetChildCount \\a - 1. The returned pointer is of generic"] + #[doc = " type @ref RTobject and needs to be cast to the actual child type, which"] + #[doc = " can be @ref RTgroup, @ref RTselector, @ref RTgeometrygroup, or"] + #[doc = " @ref RTtransform. The actual type of \\a child can be queried using"] + #[doc = " @ref rtSelectorGetChildType;"] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] index Child node index"] + #[doc = " @param[out] child Child node handle. Can be {@ref RTgroup, @ref RTselector,"] + #[doc = " @ref RTgeometrygroup, @ref RTtransform}"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorGetChildCount,"] + #[doc = " @ref rtSelectorSetChild,"] + #[doc = " @ref rtSelectorGetChildType"] + #[doc = ""] + pub fn rtSelectorGetChild( + selector: RTselector, + index: ::std::os::raw::c_uint, + child: *mut RTobject, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns type information about a Selector"] + #[doc = " child node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChildType queries the type of the child node"] + #[doc = " attached to \\a selector at slot \\a index."] + #[doc = " If no child is associated with the given index, \\a *type is set to"] + #[doc = " @ref RT_OBJECTTYPE_UNKNOWN and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = " The returned type is one of:"] + #[doc = ""] + #[doc = " @ref RT_OBJECTTYPE_GROUP"] + #[doc = " @ref RT_OBJECTTYPE_GEOMETRY_GROUP"] + #[doc = " @ref RT_OBJECTTYPE_TRANSFORM"] + #[doc = " @ref RT_OBJECTTYPE_SELECTOR"] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] index Child node index"] + #[doc = " @param[out] type Type of the child node"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetChildType was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorSetChildCount,"] + #[doc = " @ref rtSelectorGetChildCount,"] + #[doc = " @ref rtSelectorSetChild,"] + #[doc = " @ref rtSelectorGetChild"] + #[doc = ""] + pub fn rtSelectorGetChildType( + selector: RTselector, + index: ::std::os::raw::c_uint, + type_: *mut RTobjecttype, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a variable associated with a"] + #[doc = " Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Declares a new variable identified by \\a name, and associates it with"] + #[doc = " the Selector node \\a selector. The new variable handle is returned in"] + #[doc = " \\a v. After declaration, a variable does not have a type until its"] + #[doc = " value is set by an \\a rtVariableSet{...} function. Once a variable"] + #[doc = " type has been set, it cannot be changed, i.e., only"] + #[doc = " \\a rtVariableSet{...} functions of the same type can be used to"] + #[doc = " change the value of the variable."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] name Variable identifier"] + #[doc = " @param[out] v New variable handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_REDECLARED"] + #[doc = " - @ref RT_ERROR_ILLEGAL_SYMBOL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorQueryVariable,"] + #[doc = " @ref rtSelectorRemoveVariable,"] + #[doc = " @ref rtSelectorGetVariableCount,"] + #[doc = " @ref rtSelectorGetVariable,"] + #[doc = " @ref rtVariableSet{...}"] + #[doc = ""] + pub fn rtSelectorDeclareVariable( + selector: RTselector, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a variable associated with a"] + #[doc = " Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Returns in \\a v a handle to the variable identified by \\a name, which"] + #[doc = " is associated with the Selector node \\a selector. The current value of"] + #[doc = " a variable can be retrieved from its handle by using an appropriate"] + #[doc = " \\a rtVariableGet{...} function matching the variable's type."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] name Variable identifier"] + #[doc = " @param[out] v Variable handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorDeclareVariable,"] + #[doc = " @ref rtSelectorRemoveVariable,"] + #[doc = " @ref rtSelectorGetVariableCount,"] + #[doc = " @ref rtSelectorGetVariable,"] + #[doc = " \\a rtVariableGet{...}"] + #[doc = ""] + pub fn rtSelectorQueryVariable( + selector: RTselector, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a variable from a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorRemoveVariable removes the variable \\a v from the"] + #[doc = " Selector node \\a selector and deletes it. The handle \\a v must be"] + #[doc = " considered invalid afterwards."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] v Variable handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorDeclareVariable,"] + #[doc = " @ref rtSelectorQueryVariable,"] + #[doc = " @ref rtSelectorGetVariableCount,"] + #[doc = " @ref rtSelectorGetVariable"] + #[doc = ""] + pub fn rtSelectorRemoveVariable(selector: RTselector, v: RTvariable) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of variables"] + #[doc = " attached to a Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtSelectorGetVariableCount returns in \\a count the number of"] + #[doc = " variables that are currently attached to the Selector node"] + #[doc = " \\a selector."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[out] count Number of variables associated with \\a selector"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorDeclareVariable,"] + #[doc = " @ref rtSelectorQueryVariable,"] + #[doc = " @ref rtSelectorRemoveVariable,"] + #[doc = " @ref rtSelectorGetVariable"] + #[doc = ""] + pub fn rtSelectorGetVariableCount( + selector: RTselector, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a variable associated with a"] + #[doc = " Selector node"] + #[doc = ""] + #[doc = " @ingroup SelectorNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Returns in \\a v a handle to the variable located at position \\a index"] + #[doc = " in the Selectors's variable array. \\a index is a sequential number"] + #[doc = " depending on the order of variable declarations. The index must be"] + #[doc = " in the range from \\a 0 to @ref rtSelectorGetVariableCount \\a - 1. The"] + #[doc = " current value of a variable can be retrieved from its handle by using"] + #[doc = " an appropriate \\a rtVariableGet{...} function matching the"] + #[doc = " variable's type."] + #[doc = ""] + #[doc = " @param[in] selector Selector node handle"] + #[doc = " @param[in] index Variable index"] + #[doc = " @param[out] v Variable handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtSelectorGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtSelectorDeclareVariable,"] + #[doc = " @ref rtSelectorQueryVariable,"] + #[doc = " @ref rtSelectorRemoveVariable,"] + #[doc = " @ref rtSelectorGetVariableCount,"] + #[doc = " \\a rtVariableGet{...}"] + #[doc = ""] + pub fn rtSelectorGetVariable( + selector: RTselector, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Creates a new Transform node within the given context. For the node to be functional, a child"] + #[doc = " node must be attached using @ref rtTransformSetChild. A transformation matrix can be associated"] + #[doc = " with the transform node with @ref rtTransformSetMatrix. Sets \\a *transform to the handle of a"] + #[doc = " newly created transform within \\a context. Returns @ref RT_ERROR_INVALID_VALUE if \\a transform"] + #[doc = " is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the Transform node"] + #[doc = " @param[out] transform New Transform node handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformDestroy,"] + #[doc = " @ref rtTransformValidate,"] + #[doc = " @ref rtTransformGetContext,"] + #[doc = " @ref rtTransformSetMatrix,"] + #[doc = " @ref rtTransformGetMatrix,"] + #[doc = " @ref rtTransformSetChild,"] + #[doc = " @ref rtTransformGetChild,"] + #[doc = " @ref rtTransformGetChildType"] + #[doc = ""] + pub fn rtTransformCreate(context: RTcontext, transform: *mut RTtransform) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformDestroy removes \\a transform from its context and deletes it."] + #[doc = " \\a transform should be a value returned by @ref rtTransformCreate."] + #[doc = " No child graph nodes are destroyed."] + #[doc = " After the call, \\a transform is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] transform Handle of the transform node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformCreate,"] + #[doc = " @ref rtTransformValidate,"] + #[doc = " @ref rtTransformGetContext"] + #[doc = ""] + pub fn rtTransformDestroy(transform: RTtransform) -> RTresult; +} +extern "C" { + #[doc = " @brief Checks a Transform node for internal"] + #[doc = " consistency"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformValidate recursively checks consistency of the"] + #[doc = " Transform node \\a transform and its child, i.e., it tries to validate"] + #[doc = " the whole model sub-tree with \\a transform as root. For a Transform"] + #[doc = " node to be valid, it must have a child node attached. It is, however,"] + #[doc = " not required to explicitly set a transformation matrix. Without a specified"] + #[doc = " transformation matrix, the identity matrix is applied."] + #[doc = ""] + #[doc = " @param[in] transform Transform root node of a model sub-tree to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformCreate,"] + #[doc = " @ref rtTransformDestroy,"] + #[doc = " @ref rtTransformGetContext,"] + #[doc = " @ref rtTransformSetMatrix,"] + #[doc = " @ref rtTransformSetChild"] + #[doc = ""] + pub fn rtTransformValidate(transform: RTtransform) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context of a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformGetContext queries a transform node for its associated context. \\a transform"] + #[doc = " specifies the transform node to query, and should be a value returned by @ref"] + #[doc = " rtTransformCreate. Sets \\a *context to the context associated with \\a transform."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] context The context associated with \\a transform"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformCreate,"] + #[doc = " @ref rtTransformDestroy,"] + #[doc = " @ref rtTransformValidate"] + #[doc = ""] + pub fn rtTransformGetContext(transform: RTtransform, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Associates an affine transformation matrix"] + #[doc = " with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformSetMatrix associates a 4x4 matrix with the Transform"] + #[doc = " node \\a transform. The provided transformation matrix results in a"] + #[doc = " corresponding affine transformation of all geometry contained in the"] + #[doc = " sub-tree with \\a transform as root. At least one of the pointers"] + #[doc = " \\a matrix and \\a inverseMatrix must be non-\\a NULL. If exactly one"] + #[doc = " pointer is valid, the other matrix will be computed. If both are"] + #[doc = " valid, the matrices will be used as-is. If \\a transpose is \\a 0,"] + #[doc = " source matrices are expected to be in row-major format, i.e., matrix"] + #[doc = " rows are contiguously laid out in memory:"] + #[doc = ""] + #[doc = " float matrix[4*4] = { a11, a12, a13, a14,"] + #[doc = " a21, a22, a23, a24,"] + #[doc = " a31, a32, a33, a34,"] + #[doc = " a41, a42, a43, a44 };"] + #[doc = ""] + #[doc = " Here, the translational elements \\a a14, \\a a24, and \\a a34 are at the"] + #[doc = " 4th, 8th, and 12th position the matrix array. If the supplied"] + #[doc = " matrices are in column-major format, a non-0 \\a transpose flag"] + #[doc = " can be used to trigger an automatic transpose of the input matrices."] + #[doc = ""] + #[doc = " Calling this function clears any motion keys previously set for the Transform."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] transpose Flag indicating whether \\a matrix and \\a inverseMatrix should be"] + #[doc = " transposed"] + #[doc = " @param[in] matrix Affine matrix (4x4 float array)"] + #[doc = " @param[in] inverseMatrix Inverted form of \\a matrix"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformSetMatrix was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformGetMatrix"] + #[doc = ""] + pub fn rtTransformSetMatrix( + transform: RTtransform, + transpose: ::std::os::raw::c_int, + matrix: *const f32, + inverseMatrix: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the affine matrix and its inverse associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformGetMatrix returns in \\a matrix the affine matrix that"] + #[doc = " is currently used to perform a transformation of the geometry"] + #[doc = " contained in the sub-tree with \\a transform as root. The corresponding"] + #[doc = " inverse matrix will be returned in \\a inverseMatrix. One or both"] + #[doc = " pointers are allowed to be \\a NULL. If \\a transpose is \\a 0, matrices"] + #[doc = " are returned in row-major format, i.e., matrix rows are contiguously"] + #[doc = " laid out in memory. If \\a transpose is non-zero, matrices are returned"] + #[doc = " in column-major format. If non-\\a NULL, matrix pointers must point to a"] + #[doc = " float array of at least 16 elements."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] transpose Flag indicating whether \\a matrix and \\a inverseMatrix should be"] + #[doc = " transposed"] + #[doc = " @param[out] matrix Affine matrix (4x4 float array)"] + #[doc = " @param[out] inverseMatrix Inverted form of \\a matrix"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMatrix was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMatrix"] + #[doc = ""] + pub fn rtTransformGetMatrix( + transform: RTtransform, + transpose: ::std::os::raw::c_int, + matrix: *mut f32, + inverseMatrix: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion time range for a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " Sets the inclusive motion time range [timeBegin, timeEnd] for \\a transform, where timeBegin <= timeEnd."] + #[doc = " The default time range is [0.0, 1.0]. Has no effect unless @ref rtTransformSetMotionKeys"] + #[doc = " is also called, in which case the left endpoint of the time range, \\a timeBegin, is associated with"] + #[doc = " the first motion key, and the right endpoint, \\a timeEnd, with the last motion key. The keys uniformly"] + #[doc = " divide the time range."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] timeBegin Beginning time value of range"] + #[doc = " @param[in] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformSetMotionRange was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformGetMotionRange,"] + #[doc = " @ref rtTransformSetMotionBorderMode,"] + #[doc = " @ref rtTransformSetMotionKeys,"] + #[doc = ""] + pub fn rtTransformSetMotionRange( + transform: RTtransform, + timeBegin: f32, + timeEnd: f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion time range associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformGetMotionRange returns the motion time range set for the Transform."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] timeBegin Beginning time value of range"] + #[doc = " @param[out] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMotionRange was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMotionRange,"] + #[doc = " @ref rtTransformGetMotionBorderMode,"] + #[doc = " @ref rtTransformGetMotionKeyCount,"] + #[doc = " @ref rtTransformGetMotionKeyType,"] + #[doc = " @ref rtTransformGetMotionKeys,"] + #[doc = ""] + pub fn rtTransformGetMotionRange( + transform: RTtransform, + timeBegin: *mut f32, + timeEnd: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion border modes of a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformSetMotionBorderMode sets the behavior of \\a transform"] + #[doc = " outside its motion time range. The \\a beginMode and \\a endMode arguments"] + #[doc = " correspond to timeBegin and timeEnd set with @ref rtTransformSetMotionRange."] + #[doc = " The arguments are independent, and each has one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_MOTIONBORDERMODE_CLAMP :"] + #[doc = " The transform and the scene under it still exist at times less than timeBegin"] + #[doc = " or greater than timeEnd, with the transform clamped to its values at timeBegin"] + #[doc = " or timeEnd, respectively."] + #[doc = ""] + #[doc = " - @ref RT_MOTIONBORDERMODE_VANISH :"] + #[doc = " The transform and the scene under it vanish for times less than timeBegin"] + #[doc = " or greater than timeEnd."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] beginMode Motion border mode at motion range begin"] + #[doc = " @param[in] endMode Motion border mode at motion range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformSetMotionBorderMode was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformGetMotionBorderMode,"] + #[doc = " @ref rtTransformSetMotionRange,"] + #[doc = " @ref rtTransformSetMotionKeys,"] + #[doc = ""] + pub fn rtTransformSetMotionBorderMode( + transform: RTtransform, + beginMode: RTmotionbordermode, + endMode: RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion border modes of a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformGetMotionBorderMode returns the motion border modes"] + #[doc = " for the time range associated with \\a transform."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] beginMode Motion border mode at motion time range begin"] + #[doc = " @param[out] endMode Motion border mode at motion time range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMotionBorderMode was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMotionBorderMode,"] + #[doc = " @ref rtTransformGetMotionRange,"] + #[doc = " @ref rtTransformGetMotionKeyCount,"] + #[doc = " @ref rtTransformGetMotionKeyType,"] + #[doc = " @ref rtTransformGetMotionKeys,"] + #[doc = ""] + pub fn rtTransformGetMotionBorderMode( + transform: RTtransform, + beginMode: *mut RTmotionbordermode, + endMode: *mut RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion keys associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformSetMotionKeys sets a series of key values defining how"] + #[doc = " \\a transform varies with time. The float values in \\a keys are one of the"] + #[doc = " following types:"] + #[doc = ""] + #[doc = " - @ref RT_MOTIONKEYTYPE_MATRIX_FLOAT12"] + #[doc = " Each key is a 12-float 3x4 matrix in row major order (3 rows, 4 columns)."] + #[doc = " The length of \\a keys is 12*n."] + #[doc = ""] + #[doc = " - @ref RT_MOTIONKEYTYPE_SRT_FLOAT16"] + #[doc = " Each key is a packed 16-float array in this order:"] + #[doc = " [sx, a, b, pvx, sy, c, pvy, sz, pvz, qx, qy, qz, qw, tx, ty, tz]"] + #[doc = " The length of \\a keys is 16*n."] + #[doc = ""] + #[doc = " These are packed components of a scale/shear S, a quaternion R, and a translation T."] + #[doc = ""] + #[doc = " S = [ sx a b pvx ]"] + #[doc = " [ * sy c pvy ]"] + #[doc = " [ * * sz pvz ]"] + #[doc = ""] + #[doc = " R = [ qx, qy, qz, qw ]"] + #[doc = " where qw = cos(theta/2) and [qx, qy, qz] = sin(theta/2)*normalized_axis."] + #[doc = ""] + #[doc = " T = [ tx, ty, tz ]"] + #[doc = ""] + #[doc = " Removing motion keys:"] + #[doc = ""] + #[doc = " Passing a single key with \\a n == 1, or calling @ref rtTransformSetMatrix, removes any"] + #[doc = " motion data from \\a transform, and sets its matrix to values derived from the single key."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] n Number of motion keys >= 1"] + #[doc = " @param[in] type Type of motion keys"] + #[doc = " @param[in] keys \\a n Motion keys associated with this Transform"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformSetMotionKeys was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformGetMotionKeyCount,"] + #[doc = " @ref rtTransformGetMotionKeyType,"] + #[doc = " @ref rtTransformGetMotionKeys,"] + #[doc = " @ref rtTransformSetMotionBorderMode,"] + #[doc = " @ref rtTransformSetMotionRange,"] + #[doc = ""] + pub fn rtTransformSetMotionKeys( + transform: RTtransform, + n: ::std::os::raw::c_uint, + type_: RTmotionkeytype, + keys: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion key type associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformGetMotionKeyType returns the key type from the most recent"] + #[doc = " call to @ref rtTransformSetMotionKeys, or @ref RT_MOTIONKEYTYPE_NONE if no"] + #[doc = " keys have been set."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] type Motion key type associated with this Transform"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMotionKeyType was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMotionKeys,"] + #[doc = " @ref rtTransformGetMotionBorderMode,"] + #[doc = " @ref rtTransformGetMotionRange,"] + #[doc = " @ref rtTransformGetMotionKeyCount,"] + #[doc = " @ref rtTransformGetMotionKeys"] + #[doc = ""] + pub fn rtTransformGetMotionKeyType( + transform: RTtransform, + type_: *mut RTmotionkeytype, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of motion keys associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformGetMotionKeyCount returns in \\a n the number of motion keys associated"] + #[doc = " with \\a transform using @ref rtTransformSetMotionKeys. Note that the default value"] + #[doc = " is 1, not 0, for a transform without motion."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] n Number of motion steps n >= 1"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMotionKeyCount was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMotionKeys,"] + #[doc = " @ref rtTransformGetMotionBorderMode,"] + #[doc = " @ref rtTransformGetMotionRange,"] + #[doc = " @ref rtTransformGetMotionKeyType"] + #[doc = " @ref rtTransformGetMotionKeys"] + #[doc = ""] + pub fn rtTransformGetMotionKeyCount( + transform: RTtransform, + n: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion keys associated with a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtTransformGetMotionKeys returns in \\a keys packed float values for"] + #[doc = " all motion keys. The \\a keys array must be large enough to hold all the keys,"] + #[doc = " based on the key type returned by @ref rtTransformGetMotionKeyType and the"] + #[doc = " number of keys returned by @ref rtTransformGetMotionKeyCount. A single key"] + #[doc = " consists of either 12 floats (type RT_MOTIONKEYTYPE_MATRIX_FLOAT12) or"] + #[doc = " 16 floats (type RT_MOTIONKEYTYPE_SRT_FLOAT16)."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] keys Motion keys associated with this Transform"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetMotionKeys was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMotionKeys,"] + #[doc = " @ref rtTransformGetMotionBorderMode,"] + #[doc = " @ref rtTransformGetMotionRange,"] + #[doc = " @ref rtTransformGetMotionKeyCount,"] + #[doc = " @ref rtTransformGetMotionKeyType"] + #[doc = ""] + pub fn rtTransformGetMotionKeys(transform: RTtransform, keys: *mut f32) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a child node to a Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Attaches a child node \\a child to the parent node \\a transform. Legal"] + #[doc = " child node types are @ref RTgroup, @ref RTselector, @ref RTgeometrygroup,"] + #[doc = " and @ref RTtransform. A transform node must have exactly one child. If"] + #[doc = " a transformation matrix has been attached to \\a transform with"] + #[doc = " @ref rtTransformSetMatrix, it is effective on the model sub-tree with"] + #[doc = " \\a child as root node."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[in] child Child node to be attached. Can be {@ref RTgroup, @ref RTselector,"] + #[doc = " @ref RTgeometrygroup, @ref RTtransform}"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformSetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetMatrix,"] + #[doc = " @ref rtTransformGetChild,"] + #[doc = " @ref rtTransformGetChildType"] + #[doc = ""] + pub fn rtTransformSetChild(transform: RTtransform, child: RTobject) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the child node that is attached to a"] + #[doc = " Transform node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformGetChild returns in \\a child a handle of the child"] + #[doc = " node currently attached to \\a transform. The returned pointer is of"] + #[doc = " generic type @ref RTobject and needs to be cast to the actual child"] + #[doc = " type, which can be @ref RTgroup, @ref RTselector, @ref RTgeometrygroup, or"] + #[doc = " @ref RTtransform. The actual type of \\a child can be queried using"] + #[doc = " @ref rtTransformGetChildType."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] child Child node handle. Can be {@ref RTgroup, @ref RTselector,"] + #[doc = " @ref RTgeometrygroup, @ref RTtransform}"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetChild,"] + #[doc = " @ref rtTransformGetChildType"] + #[doc = ""] + pub fn rtTransformGetChild(transform: RTtransform, child: *mut RTobject) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns type information about a"] + #[doc = " Transform child node"] + #[doc = ""] + #[doc = " @ingroup TransformNode"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTransformGetChildType queries the type of the child node"] + #[doc = " attached to \\a transform. If no child is attached, \\a *type is set to"] + #[doc = " @ref RT_OBJECTTYPE_UNKNOWN and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = " The returned type is one of:"] + #[doc = ""] + #[doc = " - @ref RT_OBJECTTYPE_GROUP"] + #[doc = " - @ref RT_OBJECTTYPE_GEOMETRY_GROUP"] + #[doc = " - @ref RT_OBJECTTYPE_TRANSFORM"] + #[doc = " - @ref RT_OBJECTTYPE_SELECTOR"] + #[doc = ""] + #[doc = " @param[in] transform Transform node handle"] + #[doc = " @param[out] type Type of the child node"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTransformGetChildType was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTransformSetChild,"] + #[doc = " @ref rtTransformGetChild"] + #[doc = ""] + pub fn rtTransformGetChildType(transform: RTtransform, type_: *mut RTobjecttype) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupCreate creates a new geometry group within a context. \\a context"] + #[doc = " specifies the target context, and should be a value returned by @ref rtContextCreate."] + #[doc = " Sets \\a *geometrygroup to the handle of a newly created geometry group within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a geometrygroup is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies a context within which to create a new geometry group"] + #[doc = " @param[out] geometrygroup Returns a newly created geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupDestroy,"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtGeometryGroupCreate( + context: RTcontext, + geometrygroup: *mut RTgeometrygroup, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a geometry group node"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupDestroy removes \\a geometrygroup from its context and deletes it."] + #[doc = " \\a geometrygroup should be a value returned by @ref rtGeometryGroupCreate."] + #[doc = " No child graph nodes are destroyed."] + #[doc = " After the call, \\a geometrygroup is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] geometrygroup Handle of the geometry group node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupCreate"] + #[doc = ""] + pub fn rtGeometryGroupDestroy(geometrygroup: RTgeometrygroup) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the state of the geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupValidate checks \\a geometrygroup for completeness. If \\a geometrygroup or"] + #[doc = " any of the objects attached to \\a geometrygroup are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] geometrygroup Specifies the geometry group to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupCreate"] + #[doc = ""] + pub fn rtGeometryGroupValidate(geometrygroup: RTgeometrygroup) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetContext queries a geometry group for its associated context."] + #[doc = " \\a geometrygroup specifies the geometry group to query, and must be a value returned by"] + #[doc = " @ref rtGeometryGroupCreate. Sets \\a *context to the context"] + #[doc = " associated with \\a geometrygroup."] + #[doc = ""] + #[doc = " @param[in] geometrygroup Specifies the geometry group to query"] + #[doc = " @param[out] context Returns the context associated with the geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate,"] + #[doc = " @ref rtGeometryGroupCreate"] + #[doc = ""] + pub fn rtGeometryGroupGetContext( + geometrygroup: RTgeometrygroup, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Set the acceleration structure for a group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetAcceleration attaches an acceleration structure to a geometry group. The"] + #[doc = " acceleration structure must have been previously created using @ref rtAccelerationCreate. Every"] + #[doc = " geometry group is required to have an acceleration structure assigned in order to pass"] + #[doc = " validation. The acceleration structure will be built over the primitives contained in all"] + #[doc = " children of the geometry group. This enables a single acceleration structure to be built over"] + #[doc = " primitives of multiple geometry instances. Note that it is legal to attach a single"] + #[doc = " RTacceleration object to multiple geometry groups, as long as the underlying geometry of all"] + #[doc = " children is the same. This corresponds to attaching an acceleration structure to multiple groups"] + #[doc = " at higher graph levels using @ref rtGroupSetAcceleration."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The geometry group handle"] + #[doc = " @param[in] acceleration The acceleration structure to attach to the geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetAcceleration was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupGetAcceleration,"] + #[doc = " @ref rtAccelerationCreate,"] + #[doc = " @ref rtGroupSetAcceleration"] + #[doc = ""] + pub fn rtGeometryGroupSetAcceleration( + geometrygroup: RTgeometrygroup, + acceleration: RTacceleration, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the acceleration structure attached to a geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetAcceleration returns the acceleration structure attached to a geometry"] + #[doc = " group using @ref rtGeometryGroupSetAcceleration. If no acceleration structure has previously"] + #[doc = " been set, \\a *acceleration is set to \\a NULL."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The geometry group handle"] + #[doc = " @param[out] acceleration The returned acceleration structure object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetAcceleration was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetAcceleration,"] + #[doc = " @ref rtAccelerationCreate"] + #[doc = ""] + pub fn rtGeometryGroupGetAcceleration( + geometrygroup: RTgeometrygroup, + acceleration: *mut RTacceleration, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets instance flags for a geometry group."] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " This function controls the @ref RTinstanceflags of the given geometry group."] + #[doc = " Note that flags are only considered when tracing against an RTgroup with this GeometryGroup"] + #[doc = " as a child (potentially with Transforms)."] + #[doc = " Tracing directly against the GeometryGroup will ignore the flags."] + #[doc = " The flags override the @ref RTgeometryflags of the underlying geometry where appropriate."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[in] flags Instance flags for the given geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetFlags was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial,"] + #[doc = " @ref rtGeometrySetFlags,"] + #[doc = " @ref rtGeometryGroupGetFlags,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryGroupSetFlags(group: RTgeometrygroup, flags: RTinstanceflags) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets instance flags of a geometry group."] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " See @ref rtGeometryGroupSetFlags for details."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[out] flags Instance flags for the given geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetFlags was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetFlags,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryGroupGetFlags(group: RTgeometrygroup, flags: *mut RTinstanceflags) + -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the visibility mask of a geometry group."] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = " Geometry is intersected by rays if the ray's @ref RTvisibilitymask shares at"] + #[doc = " least one bit with the group's mask. This mechanism allows for a number of"] + #[doc = " user-defined visibility groups that can be excluded from certain types of rays"] + #[doc = " as needed."] + #[doc = " Note that the visibility mask is not checked for the root node of a trace call."] + #[doc = " (It is assumed to be visible otherwise trace should not be called)."] + #[doc = " Note that the @pre mask is currently limited to 8 bits."] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[in] mask A set of bits for which rays will intersect the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetVisibilityMask was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupSetVisibilityMask"] + #[doc = " @ref rtGeometryGroupGetVisibilityMask,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryGroupSetVisibilityMask( + group: RTgeometrygroup, + mask: RTvisibilitymask, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the visibility mask of a geometry group."] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = " See @ref rtGeometryGroupSetVisibilityMask for details/"] + #[doc = ""] + #[doc = " @param[in] group The group handle"] + #[doc = " @param[out] mask A set of bits for which rays will intersect the group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetVisibilityMask was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGroupGetVisibilityMask"] + #[doc = " @ref rtGeometryGroupSetVisibilityMask,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryGroupGetVisibilityMask( + group: RTgeometrygroup, + mask: *mut RTvisibilitymask, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of child nodes to be attached to the group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetChildCount specifies the number of child slots in this geometry"] + #[doc = " group. Potentially existing links to children at indices greater than \\a count-1 are removed. If"] + #[doc = " the call increases the number of slots, the newly created slots are empty and need to be filled"] + #[doc = " using @ref rtGeometryGroupSetChild before validation."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The parent geometry group handle"] + #[doc = " @param[in] count Number of child slots to allocate for the geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupGetChild,"] + #[doc = " @ref rtGeometryGroupGetChildCount"] + #[doc = " @ref rtGeometryGroupSetChild"] + #[doc = ""] + pub fn rtGeometryGroupSetChildCount( + geometrygroup: RTgeometrygroup, + count: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of child slots for a group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetChildCount returns the number of child slots allocated using @ref"] + #[doc = " rtGeometryGroupSetChildCount. This includes empty slots which may not yet have actual children"] + #[doc = " assigned by @ref rtGeometryGroupSetChild."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The parent geometry group handle"] + #[doc = " @param[out] count Returned number of child slots"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetChildCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetChild,"] + #[doc = " @ref rtGeometryGroupGetChild,"] + #[doc = " @ref rtGeometryGroupSetChildCount"] + #[doc = ""] + pub fn rtGeometryGroupGetChildCount( + geometrygroup: RTgeometrygroup, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a child node to a geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetChild attaches a new child node \\a geometryinstance to the parent node"] + #[doc = " \\a geometrygroup. \\a index specifies the number of the slot where the child"] + #[doc = " node gets attached. The index value must be lower than the number"] + #[doc = " previously set by @ref rtGeometryGroupSetChildCount."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The parent geometry group handle"] + #[doc = " @param[in] index The index in the parent's child slot array"] + #[doc = " @param[in] geometryinstance The child node to be attached"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupSetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetChildCount,"] + #[doc = " @ref rtGeometryGroupGetChildCount,"] + #[doc = " @ref rtGeometryGroupGetChild"] + #[doc = ""] + pub fn rtGeometryGroupSetChild( + geometrygroup: RTgeometrygroup, + index: ::std::os::raw::c_uint, + geometryinstance: RTgeometryinstance, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a child node of a geometry group"] + #[doc = ""] + #[doc = " @ingroup GeometryGroup"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetChild returns the child geometry instance at slot \\a index of the parent"] + #[doc = " \\a geometrygroup. If no child has been assigned to the given slot, \\a *geometryinstance is set"] + #[doc = " to \\a NULL. Returns @ref RT_ERROR_INVALID_VALUE if given an invalid child index or \\a NULL"] + #[doc = " pointer."] + #[doc = ""] + #[doc = " @param[in] geometrygroup The parent geometry group handle"] + #[doc = " @param[in] index The index of the child slot to query"] + #[doc = " @param[out] geometryinstance The returned child geometry instance"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGroupGetChild was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGroupSetChild,"] + #[doc = " @ref rtGeometryGroupSetChildCount,"] + #[doc = " @ref rtGeometryGroupGetChildCount,"] + #[doc = ""] + pub fn rtGeometryGroupGetChild( + geometrygroup: RTgeometrygroup, + index: ::std::os::raw::c_uint, + geometryinstance: *mut RTgeometryinstance, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationCreate creates a new ray tracing acceleration structure within a context. An"] + #[doc = " acceleration structure is used by attaching it to a group or geometry group by calling @ref"] + #[doc = " rtGroupSetAcceleration or @ref rtGeometryGroupSetAcceleration. Note that an acceleration"] + #[doc = " structure can be shared by attaching it to multiple groups or geometry groups if the underlying"] + #[doc = " geometric structures are the same, see @ref rtGroupSetAcceleration and @ref"] + #[doc = " rtGeometryGroupSetAcceleration for more details. A newly created acceleration structure is"] + #[doc = " initially in dirty state. Sets \\a *acceleration to the handle of a newly created acceleration"] + #[doc = " structure within \\a context. Returns @ref RT_ERROR_INVALID_VALUE if \\a acceleration is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies a context within which to create a new acceleration structure"] + #[doc = " @param[out] acceleration Returns the newly created acceleration structure"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationDestroy,"] + #[doc = " @ref rtContextCreate,"] + #[doc = " @ref rtAccelerationMarkDirty,"] + #[doc = " @ref rtAccelerationIsDirty,"] + #[doc = " @ref rtGroupSetAcceleration,"] + #[doc = " @ref rtGeometryGroupSetAcceleration"] + #[doc = ""] + pub fn rtAccelerationCreate(context: RTcontext, acceleration: *mut RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys an acceleration structure object"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationDestroy removes \\a acceleration from its context and deletes it."] + #[doc = " \\a acceleration should be a value returned by @ref rtAccelerationCreate."] + #[doc = " After the call, \\a acceleration is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] acceleration Handle of the acceleration structure to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationCreate"] + #[doc = ""] + pub fn rtAccelerationDestroy(acceleration: RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the state of an acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationValidate checks \\a acceleration for completeness. If \\a acceleration is"] + #[doc = " not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationCreate"] + #[doc = ""] + pub fn rtAccelerationValidate(acceleration: RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with an acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetContext queries an acceleration structure for its associated context."] + #[doc = " The context handle is returned in \\a *context."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[out] context Returns the context associated with the acceleration structure"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationCreate"] + #[doc = ""] + pub fn rtAccelerationGetContext( + acceleration: RTacceleration, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the builder to be used for an acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationSetBuilder specifies the method used to construct the ray tracing"] + #[doc = " acceleration structure represented by \\a acceleration. A builder must be set for the"] + #[doc = " acceleration structure to pass validation. The current builder can be changed at any time,"] + #[doc = " including after a call to @ref rtContextLaunch \"rtContextLaunch\". In this case, data previously"] + #[doc = " computed for the acceleration structure is invalidated and the acceleration will be marked"] + #[doc = " dirty."] + #[doc = ""] + #[doc = " \\a builder can take one of the following values:"] + #[doc = ""] + #[doc = " - \"NoAccel\": Specifies that no acceleration structure is explicitly built. Traversal linearly loops through the"] + #[doc = " list of primitives to intersect. This can be useful e.g. for higher level groups with only few children, where managing a more complex structure introduces unnecessary overhead."] + #[doc = ""] + #[doc = " - \"Bvh\": A standard bounding volume hierarchy, useful for most types of graph levels and geometry. Medium build speed, good ray tracing performance."] + #[doc = ""] + #[doc = " - \"Sbvh\": A high quality BVH variant for maximum ray tracing performance. Slower build speed and slightly higher memory footprint than \"Bvh\"."] + #[doc = ""] + #[doc = " - \"Trbvh\": High quality similar to Sbvh but with fast build performance. The Trbvh builder uses about 2.5 times the size of the final BVH for scratch space. A CPU-based Trbvh builder that does not have the memory constraints is available. OptiX includes an optional automatic fallback to the CPU version when out of GPU memory. Please refer to the Programming Guide for more details. Supports motion blur."] + #[doc = ""] + #[doc = " - \"MedianBvh\": Deprecated in OptiX 4.0. This builder is now internally remapped to Trbvh."] + #[doc = ""] + #[doc = " - \"Lbvh\": Deprecated in OptiX 4.0. This builder is now internally remapped to Trbvh."] + #[doc = ""] + #[doc = " - \"TriangleKdTree\": Deprecated in OptiX 4.0. This builder is now internally remapped to Trbvh."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[in] builder String value specifying the builder type"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationSetBuilder was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationGetBuilder,"] + #[doc = " @ref rtAccelerationSetProperty"] + #[doc = ""] + pub fn rtAccelerationSetBuilder( + acceleration: RTacceleration, + builder: *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the current builder from an acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetBuilder returns the name of the builder currently"] + #[doc = " used in the acceleration structure \\a acceleration. If no builder has"] + #[doc = " been set for \\a acceleration, an empty string is returned."] + #[doc = " \\a stringReturn will be set to point to the returned string. The"] + #[doc = " memory \\a stringReturn points to will be valid until the next API"] + #[doc = " call that returns a string."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[out] stringReturn Return string buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetBuilder was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationSetBuilder"] + #[doc = ""] + pub fn rtAccelerationGetBuilder( + acceleration: RTacceleration, + stringReturn: *mut *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Setting a traverser is no longer necessary and will be ignored."] + #[doc = ""] + pub fn rtAccelerationSetTraverser( + acceleration: RTacceleration, + traverser: *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0."] + #[doc = ""] + pub fn rtAccelerationGetTraverser( + acceleration: RTacceleration, + stringReturn: *mut *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets an acceleration structure property"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationSetProperty sets a named property value for an"] + #[doc = " acceleration structure. Properties can be used to fine tune the way an"] + #[doc = " acceleration structure is built, in order to achieve faster build"] + #[doc = " times or better ray tracing performance. Properties are evaluated and"] + #[doc = " applied by the acceleration structure during build time, and"] + #[doc = " different builders recognize different properties. Setting a property"] + #[doc = " will never fail as long as \\a acceleration is a valid"] + #[doc = " handle. Properties that are not recognized by an acceleration"] + #[doc = " structure will be ignored."] + #[doc = ""] + #[doc = " The following is a list of the properties used by the individual builders:"] + #[doc = ""] + #[doc = " - \"refit\":"] + #[doc = " Available in: Trbvh, Bvh"] + #[doc = " If set to \"1\", the builder will only readjust the node bounds of the bounding"] + #[doc = " volume hierarchy instead of constructing it from scratch. Refit is only"] + #[doc = " effective if there is an initial BVH already in place, and the underlying"] + #[doc = " geometry has undergone relatively modest deformation. In this case, the"] + #[doc = " builder delivers a very fast BVH update without sacrificing too much ray"] + #[doc = " tracing performance. The default is \"0\"."] + #[doc = ""] + #[doc = " - \"vertex_buffer_name\":"] + #[doc = " Available in: Trbvh, Sbvh"] + #[doc = " The name of the buffer variable holding triangle vertex data. Each vertex"] + #[doc = " consists of 3 floats. The default is \"vertex_buffer\"."] + #[doc = ""] + #[doc = " - \"vertex_buffer_stride\":"] + #[doc = " Available in: Trbvh, Sbvh"] + #[doc = " The offset between two vertices in the vertex buffer, given in bytes. The"] + #[doc = " default value is \"0\", which assumes the vertices are tightly packed."] + #[doc = ""] + #[doc = " - \"index_buffer_name\":"] + #[doc = " Available in: Trbvh, Sbvh"] + #[doc = " The name of the buffer variable holding vertex index data. The entries in"] + #[doc = " this buffer are indices of type int, where each index refers to one entry in"] + #[doc = " the vertex buffer. A sequence of three indices represents one triangle. If no"] + #[doc = " index buffer is given, the vertices in the vertex buffer are assumed to be a"] + #[doc = " list of triangles, i.e. every 3 vertices in a row form a triangle. The"] + #[doc = " default is \"index_buffer\"."] + #[doc = ""] + #[doc = " - \"index_buffer_stride\":"] + #[doc = " Available in: Trbvh, Sbvh"] + #[doc = " The offset between two indices in the index buffer, given in bytes. The"] + #[doc = " default value is \"0\", which assumes the indices are tightly packed."] + #[doc = ""] + #[doc = " - \"chunk_size\":"] + #[doc = " Available in: Trbvh"] + #[doc = " Number of bytes to be used for a partitioned acceleration structure build. If"] + #[doc = " no chunk size is set, or set to \"0\", the chunk size is chosen automatically."] + #[doc = " If set to \"-1\", the chunk size is unlimited. The minimum chunk size is 64MB."] + #[doc = " Please note that specifying a small chunk size reduces the peak-memory"] + #[doc = " footprint of the Trbvh but can result in slower rendering performance."] + #[doc = ""] + #[doc = " - \" motion_steps\""] + #[doc = " Available in: Trbvh"] + #[doc = " Number of motion steps to build into an acceleration structure that contains"] + #[doc = " motion geometry or motion transforms. Ignored for acceleration structures"] + #[doc = " built over static nodes. Gives a tradeoff between device memory"] + #[doc = " and time: if the input geometry or transforms have many motion steps,"] + #[doc = " then increasing the motion steps in the acceleration structure may result in"] + #[doc = " faster traversal, at the cost of linear increase in memory usage."] + #[doc = " Default 2, and clamped >=1."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[in] name String value specifying the name of the property"] + #[doc = " @param[in] value String value specifying the value of the property"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationSetProperty was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationGetProperty,"] + #[doc = " @ref rtAccelerationSetBuilder,"] + #[doc = ""] + pub fn rtAccelerationSetProperty( + acceleration: RTacceleration, + name: *const ::std::os::raw::c_char, + value: *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries an acceleration structure property"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetProperty returns the value of the acceleration"] + #[doc = " structure property \\a name. See @ref rtAccelerationSetProperty for a"] + #[doc = " list of supported properties. If the property name is not found, an"] + #[doc = " empty string is returned. \\a stringReturn will be set to point to"] + #[doc = " the returned string. The memory \\a stringReturn points to will be"] + #[doc = " valid until the next API call that returns a string."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[in] name The name of the property to be queried"] + #[doc = " @param[out] stringReturn Return string buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationGetProperty was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationSetProperty,"] + #[doc = " @ref rtAccelerationSetBuilder,"] + #[doc = ""] + pub fn rtAccelerationGetProperty( + acceleration: RTacceleration, + name: *const ::std::os::raw::c_char, + stringReturn: *mut *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Should not be called."] + #[doc = ""] + pub fn rtAccelerationGetDataSize(acceleration: RTacceleration, size: *mut RTsize) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Should not be called."] + #[doc = ""] + pub fn rtAccelerationGetData( + acceleration: RTacceleration, + data: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Should not be called."] + #[doc = ""] + pub fn rtAccelerationSetData( + acceleration: RTacceleration, + data: *const ::std::os::raw::c_void, + size: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Marks an acceleration structure as dirty"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationMarkDirty sets the dirty flag for \\a acceleration."] + #[doc = ""] + #[doc = " Any acceleration structure which is marked dirty will be rebuilt on a call to one of the @ref"] + #[doc = " rtContextLaunch \"rtContextLaunch\" functions, and its dirty flag will be reset."] + #[doc = ""] + #[doc = " An acceleration structure which is not marked dirty will never be rebuilt, even if associated"] + #[doc = " groups, geometry, properties, or any other values have changed."] + #[doc = ""] + #[doc = " Initially after creation, acceleration structures are marked dirty."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationMarkDirty was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationIsDirty,"] + #[doc = " @ref rtContextLaunch"] + #[doc = ""] + pub fn rtAccelerationMarkDirty(acceleration: RTacceleration) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the dirty flag of an acceleration structure"] + #[doc = ""] + #[doc = " @ingroup AccelerationStructure"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtAccelerationIsDirty returns whether the acceleration structure is currently marked dirty."] + #[doc = " If the flag is set, a nonzero value will be returned in \\a *dirty. Otherwise, zero is returned."] + #[doc = ""] + #[doc = " Any acceleration structure which is marked dirty will be rebuilt on a call to one of the @ref"] + #[doc = " rtContextLaunch \"rtContextLaunch\" functions, and its dirty flag will be reset."] + #[doc = ""] + #[doc = " An acceleration structure which is not marked dirty will never be rebuilt, even if associated"] + #[doc = " groups, geometry, properties, or any other values have changed."] + #[doc = ""] + #[doc = " Initially after creation, acceleration structures are marked dirty."] + #[doc = ""] + #[doc = " @param[in] acceleration The acceleration structure handle"] + #[doc = " @param[out] dirty Returned dirty flag"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtAccelerationIsDirty was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtAccelerationMarkDirty,"] + #[doc = " @ref rtContextLaunch"] + #[doc = ""] + pub fn rtAccelerationIsDirty( + acceleration: RTacceleration, + dirty: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new geometry instance node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceCreate creates a new geometry instance node within a context. \\a context"] + #[doc = " specifies the target context, and should be a value returned by @ref rtContextCreate."] + #[doc = " Sets \\a *geometryinstance to the handle of a newly created geometry instance within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a geometryinstance is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the GeometryInstance node"] + #[doc = " @param[out] geometryinstance New GeometryInstance node handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceDestroy,"] + #[doc = " @ref rtGeometryInstanceDestroy,"] + #[doc = " @ref rtGeometryInstanceGetContext"] + #[doc = ""] + pub fn rtGeometryInstanceCreate( + context: RTcontext, + geometryinstance: *mut RTgeometryinstance, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a geometry instance node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceDestroy removes \\a geometryinstance from its context and deletes it. \\a"] + #[doc = " geometryinstance should be a value returned by @ref rtGeometryInstanceCreate. Associated"] + #[doc = " variables declared via @ref rtGeometryInstanceDeclareVariable are destroyed, but no child graph"] + #[doc = " nodes are destroyed. After the call, \\a geometryinstance is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] geometryinstance Handle of the geometry instance node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceCreate"] + #[doc = ""] + pub fn rtGeometryInstanceDestroy(geometryinstance: RTgeometryinstance) -> RTresult; +} +extern "C" { + #[doc = " @brief Checks a GeometryInstance node for internal consistency"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceValidate checks \\a geometryinstance for completeness. If \\a geomertryinstance or"] + #[doc = " any of the objects attached to \\a geometry are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node of a model sub-tree to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceCreate"] + #[doc = ""] + pub fn rtGeometryInstanceValidate(geometryinstance: RTgeometryinstance) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a geometry instance node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetContext queries a geometry instance node for its associated context."] + #[doc = " \\a geometryinstance specifies the geometry node to query, and should be a value returned by"] + #[doc = " @ref rtGeometryInstanceCreate. Sets \\a *context to the context"] + #[doc = " associated with \\a geometryinstance."] + #[doc = ""] + #[doc = " @param[in] geometryinstance Specifies the geometry instance"] + #[doc = " @param[out] context Handle for queried context"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetContext"] + #[doc = ""] + pub fn rtGeometryInstanceGetContext( + geometryinstance: RTgeometryinstance, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a Geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetGeometry attaches a Geometry node to a GeometryInstance."] + #[doc = " Only one GeometryTriangles or Geometry node can be attached to a GeometryInstance at a time."] + #[doc = " However, it is possible at any time to attach a different GeometryTriangles or Geometry via"] + #[doc = " rtGeometryInstanceSetGeometryTriangles or rtGeometryInstanceSetGeometry respectively."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node handle to attach \\a geometry to"] + #[doc = " @param[in] geometry Geometry handle to attach to \\a geometryinstance"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetGeometry was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetGeometry"] + #[doc = " @ref rtGeometryInstanceGetGeometryTriangles"] + #[doc = " @ref rtGeometryInstanceSetGeometryTriangles"] + #[doc = ""] + pub fn rtGeometryInstanceSetGeometry( + geometryinstance: RTgeometryinstance, + geometry: RTgeometry, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the attached Geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetGeometry sets \\a geometry to the handle of the attached Geometry node."] + #[doc = " Only one GeometryTriangles or Geometry node can be attached to a GeometryInstance at a time."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node handle to query geometry"] + #[doc = " @param[out] geometry Handle to attached Geometry node"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetGeometry was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceCreate,"] + #[doc = " @ref rtGeometryInstanceDestroy,"] + #[doc = " @ref rtGeometryInstanceValidate,"] + #[doc = " @ref rtGeometryInstanceSetGeometry"] + #[doc = " @ref rtGeometryInstanceSetGeometryTriangles"] + #[doc = " @ref rtGeometryInstanceGetGeometryTriangles"] + #[doc = ""] + pub fn rtGeometryInstanceGetGeometry( + geometryinstance: RTgeometryinstance, + geometry: *mut RTgeometry, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a Geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetGeometryTriangles attaches a GeometryTriangles node to a GeometryInstance."] + #[doc = " Only one GeometryTriangles or Geometry node can be attached to a GeometryInstance at a time."] + #[doc = " However, it is possible at any time to attach a different GeometryTriangles or Geometry via"] + #[doc = " rtGeometryInstanceSetGeometryTriangles or rtGeometryInstanceSetGeometry respectively."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node handle to attach \\a geometrytriangles to"] + #[doc = " @param[in] geometrytriangles GeometryTriangles handle to attach to \\a geometryinstance"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetGeometryTriangles was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetGeometryTriangles"] + #[doc = " @ref rtGeometryInstanceSetGeometry"] + #[doc = " @ref rtGeometryInstanceGetGeometry"] + #[doc = ""] + pub fn rtGeometryInstanceSetGeometryTriangles( + geometryinstance: RTgeometryinstance, + geometrytriangles: RTgeometrytriangles, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the attached Geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetGeometryTriangles sets \\a geometrytriangles to the handle of the attached GeometryTriangles node."] + #[doc = " If no GeometryTriangles node is attached or a Geometry node is attached, @ref RT_ERROR_INVALID_VALUE is returned, else @ref RT_SUCCESS."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node handle to query geometrytriangles"] + #[doc = " @param[out] geometrytriangles Handle to attached GeometryTriangles node"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetGeometryTriangles was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceCreate,"] + #[doc = " @ref rtGeometryInstanceDestroy,"] + #[doc = " @ref rtGeometryInstanceValidate,"] + #[doc = " @ref rtGeometryInstanceSetGeometryTriangles"] + #[doc = " @ref rtGeometryInstanceSetGeometry"] + #[doc = " @ref rtGeometryInstanceGetGeometry"] + #[doc = ""] + pub fn rtGeometryInstanceGetGeometryTriangles( + geometryinstance: RTgeometryinstance, + geometrytriangles: *mut RTgeometrytriangles, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of materials"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetMaterialCount sets the number of materials \\a count that will be"] + #[doc = " attached to \\a geometryinstance. The number of attached materials can be changed at any"] + #[doc = " time. Increasing the number of materials will not modify already assigned materials."] + #[doc = " Decreasing the number of materials will not modify the remaining already assigned"] + #[doc = " materials."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node to set number of materials"] + #[doc = " @param[in] count Number of materials to be set"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetMaterialCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetMaterialCount"] + #[doc = ""] + pub fn rtGeometryInstanceSetMaterialCount( + geometryinstance: RTgeometryinstance, + count: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of attached materials"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetMaterialCount returns for \\a geometryinstance the number of attached"] + #[doc = " Material nodes \\a count. The number of materials can be set with @ref"] + #[doc = " rtGeometryInstanceSetMaterialCount."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node to query from the number of materials"] + #[doc = " @param[out] count Number of attached materials"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetMaterialCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceSetMaterialCount"] + #[doc = ""] + pub fn rtGeometryInstanceGetMaterialCount( + geometryinstance: RTgeometryinstance, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets a material"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetMaterial attaches \\a material to \\a geometryinstance at position \\a index"] + #[doc = " in its internal Material node list. \\a index must be in the range \\a 0 to @ref"] + #[doc = " rtGeometryInstanceGetMaterialCount \\a - 1."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node for which to set a material"] + #[doc = " @param[in] index Index into the material list"] + #[doc = " @param[in] material Material handle to attach to \\a geometryinstance"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceSetMaterial was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetMaterialCount,"] + #[doc = " @ref rtGeometryInstanceSetMaterialCount"] + #[doc = ""] + pub fn rtGeometryInstanceSetMaterial( + geometryinstance: RTgeometryinstance, + index: ::std::os::raw::c_uint, + material: RTmaterial, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a material handle"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetMaterial returns handle \\a material for the Material node at position"] + #[doc = " \\a index in the material list of \\a geometryinstance. Returns @ref RT_ERROR_INVALID_VALUE if \\a"] + #[doc = " index is invalid."] + #[doc = ""] + #[doc = " @param[in] geometryinstance GeometryInstance node handle to query material"] + #[doc = " @param[in] index Index of material"] + #[doc = " @param[out] material Handle to material"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetMaterial was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetMaterialCount,"] + #[doc = " @ref rtGeometryInstanceSetMaterial"] + #[doc = ""] + pub fn rtGeometryInstanceGetMaterial( + geometryinstance: RTgeometryinstance, + index: ::std::os::raw::c_uint, + material: *mut RTmaterial, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable associated with a geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceDeclareVariable declares a new variable associated with a geometry"] + #[doc = " instance node. \\a geometryinstance specifies the target geometry node, and should be a value"] + #[doc = " returned by @ref rtGeometryInstanceCreate. \\a name specifies the name of the variable, and"] + #[doc = " should be a \\a NULL-terminated string. If there is currently no variable associated with \\a"] + #[doc = " geometryinstance named \\a name, a new variable named \\a name will be created and associated with"] + #[doc = " \\a geometryinstance. After the call, \\a *v will be set to the handle of the newly-created"] + #[doc = " variable. Otherwise, \\a *v will be set to \\a NULL. After declaration, the variable can be"] + #[doc = " queried with @ref rtGeometryInstanceQueryVariable or @ref rtGeometryInstanceGetVariable. A"] + #[doc = " declared variable does not have a type until its value is set with one of the @ref rtVariableSet"] + #[doc = " functions. Once a variable is set, its type cannot be changed anymore."] + #[doc = ""] + #[doc = " @param[in] geometryinstance Specifies the associated GeometryInstance node"] + #[doc = " @param[in] name The name that identifies the variable"] + #[doc = " @param[out] v Returns a handle to a newly declared variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref Variables,"] + #[doc = " @ref rtGeometryInstanceQueryVariable,"] + #[doc = " @ref rtGeometryInstanceGetVariable,"] + #[doc = " @ref rtGeometryInstanceRemoveVariable"] + #[doc = ""] + pub fn rtGeometryInstanceDeclareVariable( + geometryinstance: RTgeometryinstance, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to a named variable of a geometry node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceQueryVariable queries the handle of a geometry instance node's named"] + #[doc = " variable. \\a geometryinstance specifies the target geometry instance node, as returned by"] + #[doc = " @ref rtGeometryInstanceCreate. \\a name specifies the name of the variable, and should be a \\a"] + #[doc = " \\a NULL -terminated string. If \\a name is the name of a variable attached to \\a geometryinstance,"] + #[doc = " returns a handle to that variable in \\a *v, otherwise \\a NULL. Geometry instance variables have"] + #[doc = " to be declared with @ref rtGeometryInstanceDeclareVariable before they can be queried."] + #[doc = ""] + #[doc = " @param[in] geometryinstance The GeometryInstance node to query from a variable"] + #[doc = " @param[in] name The name that identifies the variable to be queried"] + #[doc = " @param[out] v Returns the named variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceDeclareVariable,"] + #[doc = " @ref rtGeometryInstanceRemoveVariable,"] + #[doc = " @ref rtGeometryInstanceGetVariableCount,"] + #[doc = " @ref rtGeometryInstanceGetVariable"] + #[doc = ""] + pub fn rtGeometryInstanceQueryVariable( + geometryinstance: RTgeometryinstance, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a named variable from a geometry instance node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceRemoveVariable removes a named variable from a geometry instance. The"] + #[doc = " target geometry instance is specified by \\a geometryinstance, which should be a value returned"] + #[doc = " by @ref rtGeometryInstanceCreate. The variable to be removed is specified by \\a v, which should"] + #[doc = " be a value returned by @ref rtGeometryInstanceDeclareVariable. Once a variable has been removed"] + #[doc = " from this geometry instance, another variable with the same name as the removed variable may be"] + #[doc = " declared."] + #[doc = ""] + #[doc = " @param[in] geometryinstance The GeometryInstance node from which to remove a variable"] + #[doc = " @param[in] v The variable to be removed"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextRemoveVariable,"] + #[doc = " @ref rtGeometryInstanceDeclareVariable"] + #[doc = ""] + pub fn rtGeometryInstanceRemoveVariable( + geometryinstance: RTgeometryinstance, + v: RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of attached variables"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetVariableCount queries the number of variables attached to a geometry instance."] + #[doc = " \\a geometryinstance specifies the geometry instance, and should be a value returned by @ref rtGeometryInstanceCreate."] + #[doc = " After the call, the number of variables attached to \\a geometryinstance is returned to \\a *count."] + #[doc = ""] + #[doc = " @param[in] geometryinstance The GeometryInstance node to query from the number of attached variables"] + #[doc = " @param[out] count Returns the number of attached variables"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryInstanceGetVariableCount,"] + #[doc = " @ref rtGeometryInstanceDeclareVariable,"] + #[doc = " @ref rtGeometryInstanceRemoveVariable"] + #[doc = ""] + pub fn rtGeometryInstanceGetVariableCount( + geometryinstance: RTgeometryinstance, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to an indexed variable of a geometry instance node"] + #[doc = ""] + #[doc = " @ingroup GeometryInstance"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetVariable queries the handle of a geometry instance's indexed variable."] + #[doc = " \\a geometryinstance specifies the target geometry instance and should be a value returned by"] + #[doc = " @ref rtGeometryInstanceCreate. \\a index specifies the index of the variable, and should be a"] + #[doc = " value less than @ref rtGeometryInstanceGetVariableCount. If \\a index is the index of a variable"] + #[doc = " attached to \\a geometryinstance, returns a handle to that variable in \\a *v, and \\a NULL"] + #[doc = " otherwise. \\a *v must be declared first with @ref rtGeometryInstanceDeclareVariable before it"] + #[doc = " can be queried."] + #[doc = ""] + #[doc = " @param[in] geometryinstance The GeometryInstance node from which to query a variable"] + #[doc = " @param[in] index The index that identifies the variable to be queried"] + #[doc = " @param[out] v Returns handle to indexed variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryInstanceGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryDeclareVariable,"] + #[doc = " @ref rtGeometryGetVariableCount,"] + #[doc = " @ref rtGeometryRemoveVariable,"] + #[doc = " @ref rtGeometryQueryVariable"] + #[doc = ""] + pub fn rtGeometryInstanceGetVariable( + geometryinstance: RTgeometryinstance, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryCreate creates a new geometry node within a context. \\a context"] + #[doc = " specifies the target context, and should be a value returned by @ref rtContextCreate."] + #[doc = " Sets \\a *geometry to the handle of a newly created geometry within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a geometry is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the Geometry node"] + #[doc = " @param[out] geometry New Geometry node handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryDestroy,"] + #[doc = " @ref rtGeometrySetBoundingBoxProgram,"] + #[doc = " @ref rtGeometrySetIntersectionProgram"] + #[doc = ""] + pub fn rtGeometryCreate(context: RTcontext, geometry: *mut RTgeometry) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryDestroy removes \\a geometry from its context and deletes it. \\a geometry should"] + #[doc = " be a value returned by @ref rtGeometryCreate. Associated variables declared via"] + #[doc = " @ref rtGeometryDeclareVariable are destroyed, but no child graph nodes are destroyed. After the"] + #[doc = " call, \\a geometry is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] geometry Handle of the geometry node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryCreate,"] + #[doc = " @ref rtGeometrySetPrimitiveCount,"] + #[doc = " @ref rtGeometryGetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometryDestroy(geometry: RTgeometry) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the geometry nodes integrity"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryValidate checks \\a geometry for completeness. If \\a geometry or any of the"] + #[doc = " objects attached to \\a geometry are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextValidate"] + #[doc = ""] + pub fn rtGeometryValidate(geometry: RTgeometry) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetContext queries a geometry node for its associated context. \\a geometry"] + #[doc = " specifies the geometry node to query, and should be a value returned by @ref"] + #[doc = " rtGeometryCreate. Sets \\a *context to the context associated with \\a geometry."] + #[doc = ""] + #[doc = " @param[in] geometry Specifies the geometry to query"] + #[doc = " @param[out] context The context associated with \\a geometry"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryCreate"] + #[doc = ""] + pub fn rtGeometryGetContext(geometry: RTgeometry, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of primitives"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometrySetPrimitiveCount sets the number of primitives \\a primitiveCount in \\a geometry."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node for which to set the number of primitives"] + #[doc = " @param[in] primitiveCount The number of primitives"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetPrimitiveCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometrySetPrimitiveCount( + geometry: RTgeometry, + primitiveCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of primitives"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetPrimitiveCount returns for \\a geometry the number of set primitives. The"] + #[doc = " number of primitvies can be set with @ref rtGeometryGetPrimitiveCount."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node to query from the number of primitives"] + #[doc = " @param[out] primitiveCount Number of primitives"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetPrimitiveCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometryGetPrimitiveCount( + geometry: RTgeometry, + primitiveCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the primitive index offset"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometrySetPrimitiveIndexOffset sets the primitive index offset"] + #[doc = " \\a indexOffset in \\a geometry. In the past, a @ref Geometry object's primitive"] + #[doc = " index range always started at zero (i.e., a Geometry with \\a N primitives would"] + #[doc = " have a primitive index range of [0,N-1]). The index offset is used to allow"] + #[doc = " @ref Geometry objects to have primitive index ranges starting at non-zero"] + #[doc = " positions (i.e., a Geometry with \\a N primitives and an index offset of \\a M"] + #[doc = " would have a primitive index range of [M,M+N-1]). This feature enables the"] + #[doc = " sharing of vertex index buffers between multiple @ref Geometry objects."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node for which to set the primitive index offset"] + #[doc = " @param[in] indexOffset The primitive index offset"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetPrimitiveIndexOffset was introduced in OptiX 3.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetPrimitiveIndexOffset"] + #[doc = ""] + pub fn rtGeometrySetPrimitiveIndexOffset( + geometry: RTgeometry, + indexOffset: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the current primitive index offset"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetPrimitiveIndexOffset returns for \\a geometry the primitive index offset. The"] + #[doc = " primitive index offset can be set with @ref rtGeometrySetPrimitiveIndexOffset."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node to query for the primitive index offset"] + #[doc = " @param[out] indexOffset Primitive index offset"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetPrimitiveIndexOffset was introduced in OptiX 3.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetPrimitiveIndexOffset"] + #[doc = ""] + pub fn rtGeometryGetPrimitiveIndexOffset( + geometry: RTgeometry, + indexOffset: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion time range for a Geometry node."] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " Sets the inclusive motion time range [timeBegin, timeEnd] for \\a geometry,"] + #[doc = " where timeBegin <= timeEnd. The default time range is [0.0, 1.0]. The"] + #[doc = " time range has no effect unless @ref rtGeometrySetMotionSteps is"] + #[doc = " called, in which case the time steps uniformly divide the time range. See"] + #[doc = " @ref rtGeometrySetMotionSteps for additional requirements on the bounds"] + #[doc = " program."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[out] timeBegin Beginning time value of range"] + #[doc = " @param[out] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetMotionRange was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetMotionRange"] + #[doc = " @ref rtGeometrySetMotionBorderMode"] + #[doc = " @ref rtGeometrySetMotionSteps"] + #[doc = ""] + pub fn rtGeometrySetMotionRange(geometry: RTgeometry, timeBegin: f32, timeEnd: f32) + -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion time range associated with a Geometry node."] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryGetMotionRange returns the motion time range associated with"] + #[doc = " \\a geometry from a previous call to @ref rtGeometrySetMotionRange, or the"] + #[doc = " default values of [0.0, 1.0]."] + #[doc = ""] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[out] timeBegin Beginning time value of range"] + #[doc = " @param[out] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetMotionRange was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetMotionRange"] + #[doc = " @ref rtGeometryGetMotionBorderMode"] + #[doc = " @ref rtGeometryGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryGetMotionRange( + geometry: RTgeometry, + timeBegin: *mut f32, + timeEnd: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion border modes of a Geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometrySetMotionBorderMode sets the behavior of \\a geometry"] + #[doc = " outside its motion time range. Options are @ref RT_MOTIONBORDERMODE_CLAMP"] + #[doc = " or @ref RT_MOTIONBORDERMODE_VANISH. See @ref rtTransformSetMotionBorderMode"] + #[doc = " for details."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[in] beginMode Motion border mode at motion range begin"] + #[doc = " @param[in] endMode Motion border mode at motion range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetMotionBorderMode was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetMotionBorderMode"] + #[doc = " @ref rtGeometrySetMotionRange"] + #[doc = " @ref rtGeometrySetMotionSteps"] + #[doc = ""] + pub fn rtGeometrySetMotionBorderMode( + geometry: RTgeometry, + beginMode: RTmotionbordermode, + endMode: RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion border modes of a Geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryGetMotionBorderMode returns the motion border modes"] + #[doc = " for the time range associated with \\a geometry."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[out] beginMode Motion border mode at motion range begin"] + #[doc = " @param[out] endMode Motion border mode at motion range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetMotionBorderMode was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetMotionBorderMode"] + #[doc = " @ref rtGeometryGetMotionRange"] + #[doc = " @ref rtGeometryGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryGetMotionBorderMode( + geometry: RTgeometry, + beginMode: *mut RTmotionbordermode, + endMode: *mut RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Specifies the number of motion steps associated with a Geometry"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometrySetMotionSteps sets the number of motion steps associated"] + #[doc = " with \\a geometry. If the value of \\a n is greater than 1, then \\a geometry"] + #[doc = " must have an associated bounding box program that takes both a primitive index"] + #[doc = " and a motion index as arguments, and computes an aabb at the motion index."] + #[doc = " See @ref rtGeometrySetBoundingBoxProgram."] + #[doc = ""] + #[doc = " Note that all Geometry has at least one 1 motion step (the default), and"] + #[doc = " Geometry that linearly moves has 2 motion steps."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[in] n Number of motion steps >= 1"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetMotionSteps was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetMotionSteps"] + #[doc = " @ref rtGeometrySetMotionBorderMode"] + #[doc = " @ref rtGeometrySetMotionRange"] + #[doc = ""] + pub fn rtGeometrySetMotionSteps(geometry: RTgeometry, n: ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of motion steps associated with a Geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryGetMotionSteps returns in \\a n the number of motion steps"] + #[doc = " associated with \\a geometry. Note that the default value is 1, not 0,"] + #[doc = " for geometry without motion."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle"] + #[doc = " @param[out] n Number of motion steps n >= 1"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetMotionSteps was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetMotionSteps"] + #[doc = " @ref rtGeometrySetMotionBorderMode"] + #[doc = " @ref rtGeometrySetMotionRange"] + #[doc = ""] + pub fn rtGeometryGetMotionSteps( + geometry: RTgeometry, + n: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the bounding box program"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometrySetBoundingBoxProgram sets for \\a geometry the \\a program that computes an axis aligned bounding box"] + #[doc = " for each attached primitive to \\a geometry. RTprogram's can be either generated with @ref rtProgramCreateFromPTXFile or"] + #[doc = " @ref rtProgramCreateFromPTXString. A bounding box program is mandatory for every geometry node."] + #[doc = ""] + #[doc = " If \\a geometry has more than one motion step, set using @ref rtGeometrySetMotionSteps, then the bounding"] + #[doc = " box program must compute a bounding box per primitive and per motion step."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node for which to set the bounding box program"] + #[doc = " @param[in] program Handle to the bounding box program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetBoundingBoxProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetBoundingBoxProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtGeometrySetBoundingBoxProgram(geometry: RTgeometry, program: RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the attached bounding box program"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetBoundingBoxProgram returns the handle \\a program for"] + #[doc = " the attached bounding box program of \\a geometry."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle from which to query program"] + #[doc = " @param[out] program Handle to attached bounding box program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetBoundingBoxProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetBoundingBoxProgram"] + #[doc = ""] + pub fn rtGeometryGetBoundingBoxProgram( + geometry: RTgeometry, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the intersection program"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometrySetIntersectionProgram sets for \\a geometry the \\a program that performs ray primitive intersections."] + #[doc = " RTprogram's can be either generated with @ref rtProgramCreateFromPTXFile or @ref rtProgramCreateFromPTXString. An intersection"] + #[doc = " program is mandatory for every geometry node."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node for which to set the intersection program"] + #[doc = " @param[in] program A handle to the ray primitive intersection program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetIntersectionProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetIntersectionProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtGeometrySetIntersectionProgram(geometry: RTgeometry, program: RTprogram) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the attached intersection program"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetIntersectionProgram returns in \\a program a handle of the attached intersection program."] + #[doc = ""] + #[doc = " @param[in] geometry Geometry node handle to query program"] + #[doc = " @param[out] program Handle to attached intersection program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetIntersectionProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetIntersectionProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtGeometryGetIntersectionProgram( + geometry: RTgeometry, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets geometry flags"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " See @ref rtGeometryTrianglesSetFlagsPerMaterial for a description of the behavior of the"] + #[doc = " various flags."] + #[doc = ""] + #[doc = " @param[in] geometry The group handle"] + #[doc = " @param[out] flags Flags for the given geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometrySetFlags was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometrySetFlags(geometry: RTgeometry, flags: RTgeometryflags) -> RTresult; +} +extern "C" { + #[doc = " @brief Retrieves geometry flags"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " See @ref rtGeometrySetFlags for details."] + #[doc = ""] + #[doc = " @param[in] geometry The group handle"] + #[doc = " @param[out] flags Flags for the given geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetFlags was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial,"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryGetFlags(geometry: RTgeometry, flags: *mut RTgeometryflags) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Calling this function has no effect."] + #[doc = ""] + pub fn rtGeometryMarkDirty(geometry: RTgeometry) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 4.0. Calling this function has no effect."] + #[doc = ""] + pub fn rtGeometryIsDirty(geometry: RTgeometry, dirty: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable associated with a geometry instance"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryDeclareVariable declares a new variable associated with a geometry node. \\a"] + #[doc = " geometry specifies the target geometry node, and should be a value returned by @ref"] + #[doc = " rtGeometryCreate. \\a name specifies the name of the variable, and should be a \\a NULL-terminated"] + #[doc = " string. If there is currently no variable associated with \\a geometry named \\a name, a new"] + #[doc = " variable named \\a name will be created and associated with \\a geometry. Returns the handle of"] + #[doc = " the newly-created variable in \\a *v or \\a NULL otherwise. After declaration, the variable can"] + #[doc = " be queried with @ref rtGeometryQueryVariable or @ref rtGeometryGetVariable. A declared variable"] + #[doc = " does not have a type until its value is set with one of the @ref rtVariableSet functions. Once a"] + #[doc = " variable is set, its type cannot be changed anymore."] + #[doc = ""] + #[doc = " @param[in] geometry Specifies the associated Geometry node"] + #[doc = " @param[in] name The name that identifies the variable"] + #[doc = " @param[out] v Returns a handle to a newly declared variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_REDECLARED"] + #[doc = " - @ref RT_ERROR_ILLEGAL_SYMBOL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref Variables,"] + #[doc = " @ref rtGeometryQueryVariable,"] + #[doc = " @ref rtGeometryGetVariable,"] + #[doc = " @ref rtGeometryRemoveVariable"] + #[doc = ""] + pub fn rtGeometryDeclareVariable( + geometry: RTgeometry, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to a named variable of a geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryQueryVariable queries the handle of a geometry node's named variable."] + #[doc = " \\a geometry specifies the target geometry node and should be a value returned"] + #[doc = " by @ref rtGeometryCreate. \\a name specifies the name of the variable, and should"] + #[doc = " be a \\a NULL-terminated string. If \\a name is the name of a variable attached to"] + #[doc = " \\a geometry, returns a handle to that variable in \\a *v or \\a NULL otherwise. Geometry"] + #[doc = " variables must be declared with @ref rtGeometryDeclareVariable before they can be queried."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node to query from a variable"] + #[doc = " @param[in] name The name that identifies the variable to be queried"] + #[doc = " @param[out] v Returns the named variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryDeclareVariable,"] + #[doc = " @ref rtGeometryRemoveVariable,"] + #[doc = " @ref rtGeometryGetVariableCount,"] + #[doc = " @ref rtGeometryGetVariable"] + #[doc = ""] + pub fn rtGeometryQueryVariable( + geometry: RTgeometry, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a named variable from a geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryRemoveVariable removes a named variable from a geometry node. The"] + #[doc = " target geometry is specified by \\a geometry, which should be a value"] + #[doc = " returned by @ref rtGeometryCreate. The variable to remove is specified by"] + #[doc = " \\a v, which should be a value returned by @ref rtGeometryDeclareVariable."] + #[doc = " Once a variable has been removed from this geometry node, another variable with the"] + #[doc = " same name as the removed variable may be declared."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node from which to remove a variable"] + #[doc = " @param[in] v The variable to be removed"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextRemoveVariable"] + #[doc = ""] + pub fn rtGeometryRemoveVariable(geometry: RTgeometry, v: RTvariable) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of attached variables"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetVariableCount queries the number of variables attached to a geometry node."] + #[doc = " \\a geometry specifies the geometry node, and should be a value returned by @ref rtGeometryCreate."] + #[doc = " After the call, the number of variables attached to \\a geometry is returned to \\a *count."] + #[doc = ""] + #[doc = " @param[in] geometry The Geometry node to query from the number of attached variables"] + #[doc = " @param[out] count Returns the number of attached variables"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryGetVariableCount,"] + #[doc = " @ref rtGeometryDeclareVariable,"] + #[doc = " @ref rtGeometryRemoveVariable"] + #[doc = ""] + pub fn rtGeometryGetVariableCount( + geometry: RTgeometry, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to an indexed variable of a geometry node"] + #[doc = ""] + #[doc = " @ingroup Geometry"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryGetVariable queries the handle of a geometry node's indexed variable."] + #[doc = " \\a geometry specifies the target geometry and should be a value returned"] + #[doc = " by @ref rtGeometryCreate. \\a index specifies the index of the variable, and"] + #[doc = " should be a value less than @ref rtGeometryGetVariableCount. If \\a index is the"] + #[doc = " index of a variable attached to \\a geometry, returns its handle in \\a *v or \\a NULL otherwise."] + #[doc = " \\a *v must be declared first with @ref rtGeometryDeclareVariable before it can be queried."] + #[doc = ""] + #[doc = " @param[in] geometry The geometry node from which to query a variable"] + #[doc = " @param[in] index The index that identifies the variable to be queried"] + #[doc = " @param[out] v Returns handle to indexed variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryDeclareVariable,"] + #[doc = " @ref rtGeometryGetVariableCount,"] + #[doc = " @ref rtGeometryRemoveVariable,"] + #[doc = " @ref rtGeometryQueryVariable"] + #[doc = ""] + pub fn rtGeometryGetVariable( + geometry: RTgeometry, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesCreate creates a new GeometryTriangles node within a context. \\a context"] + #[doc = " specifies the target context, and should be a value returned by @ref rtContextCreate."] + #[doc = " Sets \\a *geometrytriangles to the handle of a newly created GeometryTriangles node within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a geometrytriangles is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the GeometryTriangles node"] + #[doc = " @param[out] geometrytriangles New GeometryTriangles node handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesCreate was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesDestroy,"] + #[doc = ""] + pub fn rtGeometryTrianglesCreate( + context: RTcontext, + geometrytriangles: *mut RTgeometrytriangles, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesDestroy removes \\a geometrytriangles from its context and deletes it. \\a geometrytriangles should"] + #[doc = " be a value returned by @ref rtGeometryTrianglesCreate. After the call, \\a geometrytriangles is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles Handle of the GeometryTriangles node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesDestroy was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesCreate,"] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveCount,"] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometryTrianglesDestroy(geometrytriangles: RTgeometrytriangles) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the GeometryTriangles nodes integrity"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesValidate checks \\a geometrytriangles for completeness. If \\a geometrytriangles or any of the"] + #[doc = " objects attached to \\a geometrytriangles are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles The GeometryTriangles node to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesValidate was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextValidate"] + #[doc = ""] + pub fn rtGeometryTrianglesValidate(geometrytriangles: RTgeometrytriangles) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetContext queries a GeometryTriangles node for its associated context. \\a geometrytriangles"] + #[doc = " specifies the GeometryTriangles node to query, and should be a value returned by @ref"] + #[doc = " rtGeometryTrianglesCreate. Sets \\a *context to the context associated with \\a geometrytriangles."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles Specifies the GeometryTriangles to query"] + #[doc = " @param[out] context The context associated with \\a geometrytriangles"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetContext was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesCreate"] + #[doc = ""] + pub fn rtGeometryTrianglesGetContext( + geometrytriangles: RTgeometrytriangles, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the primitive index offset"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveIndexOffset sets the primitive index offset"] + #[doc = " \\a indexOffset in \\a geometrytriangles."] + #[doc = " With an offset of zero, a GeometryTriangles with \\a N triangles has a primitive index range of [0,N-1]."] + #[doc = " The index offset is used to allow GeometryTriangles objects to have primitive index ranges starting at non-zero"] + #[doc = " positions (i.e., a GeometryTriangles with \\a N triangles and an index offset of \\a M"] + #[doc = " has a primitive index range of [M,M+N-1])."] + #[doc = " Note that this offset only affects the primitive index that is reported in case of an intersection and does not"] + #[doc = " affect the input data that is specified via @ref rtGeometryTrianglesSetVertices or @ref"] + #[doc = " rtGeometryTrianglesSetTriangleIndices."] + #[doc = " This feature enables the packing of multiple Geometries or GeometryTriangles into a single buffer."] + #[doc = " While the same effect could be reached via a user variable, it is recommended to specify the offset via"] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveIndexOffset."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles The GeometryTriangles node for which to set the primitive index offset"] + #[doc = " @param[in] indexOffset The primitive index offset"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveIndexOffset was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometrySetPrimitiveIndexOffset"] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveIndexOffset"] + #[doc = ""] + pub fn rtGeometryTrianglesSetPrimitiveIndexOffset( + geometrytriangles: RTgeometrytriangles, + indexOffset: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the current primitive index offset"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveIndexOffset returns for \\a geometrytriangles the primitive index offset. The"] + #[doc = " primitive index offset can be set with @ref rtGeometryTrianglesSetPrimitiveIndexOffset."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[out] indexOffset Primitive index offset"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveIndexOffset was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveIndexOffset"] + #[doc = ""] + pub fn rtGeometryTrianglesGetPrimitiveIndexOffset( + geometrytriangles: RTgeometrytriangles, + indexOffset: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets a pre-transform matrix"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPreTransformMatrix can be used to bake a transformation for a mesh."] + #[doc = " Vertices of triangles are multiplied by the user-specified 3x4 matrix before the acceleration build."] + #[doc = " Note that the input triangle data stays untouched (set via @ref rtGeometryTrianglesSetVertices)."] + #[doc = " Triangle intersection uses transformed triangles."] + #[doc = " The 3x4 matrix is expected to be in a row-major data layout, use the transpose option if \\a matrix is in a column-major data layout."] + #[doc = " Use rtGeometryTrianglesSetPreTransformMatrix(geometrytriangles, false, 0); to unset a previously set matrix."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles Geometry node to query from the number of primitives"] + #[doc = " @param[in] transpose If the input matrix is column-major and needs to be transposed before usage"] + #[doc = " @param[in] matrix The 3x4 matrix that is used to transform the vertices"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPreTransformMatrix was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetPreTransformMatrix"] + #[doc = ""] + pub fn rtGeometryTrianglesSetPreTransformMatrix( + geometrytriangles: RTgeometrytriangles, + transpose: ::std::os::raw::c_int, + matrix: *const f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets a pre-transform matrix"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPreTransformMatrix returns a previously set 3x4 matrix or the 'identity' matrix (with ones in the main diagonal of the 3x3 submatrix) if no matrix is set."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles Geometry node to query from the number of primitives"] + #[doc = " @param[in] transpose Set to true if the output matrix is expected to be column-major rather than row-major"] + #[doc = " @param[out] matrix The 3x4 matrix that is used to transform the vertices"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPreTransformMatrix was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetPreTransformMatrix"] + #[doc = ""] + pub fn rtGeometryTrianglesGetPreTransformMatrix( + geometrytriangles: RTgeometrytriangles, + transpose: ::std::os::raw::c_int, + matrix: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveCount sets the number of triangles \\a triangleCount in \\a geometrytriangles."] + #[doc = " A triangle geometry is either a triangle soup for which every three vertices stored in the vertex buffer form a triangle,"] + #[doc = " or indexed triangles are used for which three indices reference different vertices."] + #[doc = " In the latter case, an index buffer must be set (@ref rtGeometryTrianglesSetTriangleIndices)."] + #[doc = " The vertices of the triangles are specified via one of the SetVertices functions."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node for which to set the number of triangles"] + #[doc = " @param[in] triangleCount Number of triangles"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveCount was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveCount"] + #[doc = " @ref rtGeometrySetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometryTrianglesSetPrimitiveCount( + geometrytriangles: RTgeometrytriangles, + triangleCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveCount returns the number of set triangles for \\a geometrytriangles. The"] + #[doc = " number of primitives can be set with @ref rtGeometryTrianglesSetPrimitiveCount."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query from the number of primitives"] + #[doc = " @param[out] triangleCount Number of triangles"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetPrimitiveCount was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetPrimitiveCount"] + #[doc = " @ref rtGeometryGetPrimitiveCount"] + #[doc = ""] + pub fn rtGeometryTrianglesGetPrimitiveCount( + geometrytriangles: RTgeometrytriangles, + triangleCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the index buffer of indexed triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetTriangleIndices is used to set the index buffer for indexed triangles."] + #[doc = " Triplets of indices from buffer \\a indexBuffer index vertices to form triangles."] + #[doc = " If the buffer is set, it is assumed that the geometry is given as indexed triangles."] + #[doc = " If the index buffer is not set, it is assumed that the geometry is given as a triangle soup."] + #[doc = " A previously set index buffer can be unset by passing NULL as \\a indexBuffer parameter, e.g., rtGeometryTrianglesSetTriangleIndices( geometrytriangles, NULL, 0, 0, RT_FORMAT_UNSIGNED_INT3);"] + #[doc = " Buffer \\a indexBuffer is expected to hold 3 times \\a triangleCount indices (see @ref rtGeometryTrianglesSetPrimitiveCount)."] + #[doc = " Parameter \\a indexBufferByteOffset can be used to specify a byte offset to the first index in buffer \\a indexBuffer."] + #[doc = " Parameter \\a triIndicesByteStride sets the stride in bytes between triplets of indices. There mustn't be any spacing between indices within a triplet, spacing is only supported between triplets."] + #[doc = " Parameter \\a triIndicesFormat must be one of the following: RT_FORMAT_UNSIGNED_INT3, RT_FORMAT_UNSIGNED_SHORT3."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[in] indexBuffer Buffer that holds the indices into the vertex buffer of the triangles"] + #[doc = " @param[in] indexBufferByteOffset Offset in bytes to the first index in buffer indexBuffer"] + #[doc = " @param[in] triIndicesByteStride Stride in bytes between triplets of indices"] + #[doc = " @param[in] triIndicesFormat Format of the triplet of indices to index the vertices of a triangle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetTriangleIndices was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetVertices"] + #[doc = ""] + pub fn rtGeometryTrianglesSetTriangleIndices( + geometrytriangles: RTgeometrytriangles, + indexBuffer: RTbuffer, + indexBufferByteOffset: RTsize, + triIndicesByteStride: RTsize, + triIndicesFormat: RTformat, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the vertex buffer of a triangle soup"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetVertices interprets the buffer \\a vertexBuffer as the vertices of triangles of the GeometryTriangles \\a geometrytriangles."] + #[doc = " The number of vertices is set as \\a vertexCount."] + #[doc = " If an index buffer is set, it is assumed that the geometry is given as indexed triangles."] + #[doc = " If the index buffer is not set, it is assumed that the geometry is given as a triangle soup and \\a vertexCount must be 3 times triangleCount (see @ref rtGeometryTrianglesSetPrimitiveCount)."] + #[doc = " Buffer \\a vertexBuffer is expected to hold \\a vertexCount vertices."] + #[doc = " Parameter \\a vertexBufferByteOffset can be used to specify a byte offset to the position of the first vertex in buffer \\a vertexBuffer."] + #[doc = " Parameter \\a vertexByteStride sets the stride in bytes between vertices."] + #[doc = " Parameter \\a positionFormat must be one of the following: RT_FORMAT_FLOAT3, RT_FORMAT_HALF3, RT_FORMAT_FLOAT2, RT_FORMAT_HALF2."] + #[doc = " In case of formats RT_FORMAT_FLOAT2 or RT_FORMAT_HALF2 the third component is assumed to be zero, which can be useful for planar geometry."] + #[doc = " Calling this function overrides any previous call to any of the set(Motion)Vertices functions."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[in] vertexCount Number of vertices of the geometry"] + #[doc = " @param[in] vertexBuffer Buffer that holds the vertices of the triangles"] + #[doc = " @param[in] vertexBufferByteOffset Offset in bytes to the first vertex in buffer vertexBuffer"] + #[doc = " @param[in] vertexByteStride Stride in bytes between vertices"] + #[doc = " @param[in] positionFormat Format of the position attribute of a vertex"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetVertices was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetTriangleIndices"] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices"] + #[doc = ""] + pub fn rtGeometryTrianglesSetVertices( + geometrytriangles: RTgeometrytriangles, + vertexCount: ::std::os::raw::c_uint, + vertexBuffer: RTbuffer, + vertexBufferByteOffset: RTsize, + vertexByteStride: RTsize, + positionFormat: RTformat, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the vertex buffer of motion triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices interprets the buffer \\a vertexBuffer as the vertices of triangles of the GeometryTriangles \\a geometrytriangles."] + #[doc = " The number of triangles for one motion step is set as \\a vertexCount."] + #[doc = " Similar to it's non-motion counterpart, \\a vertexCount must be 3 times \\a triangleCount if no index buffer is set."] + #[doc = " The total number of vertices stored in \\a vertexBuffer is \\a vertexCount times \\a motionStepCount (see @ref rtGeometryTrianglesSetMotionSteps)."] + #[doc = " Triangles are linearly interpolated between motion steps."] + #[doc = " Parameter \\a vertexBufferByteOffset can be used to specify a byte offset to the position of the first vertex of the first motion step in buffer \\a vertexBuffer."] + #[doc = " Parameter \\a vertexByteStride sets the stride in bytes between vertices within a motion step."] + #[doc = " Parameter \\a vertexMotionStepByteStride sets the stride in bytes between motion steps for a single vertex."] + #[doc = " The stride parameters allow for two types of layouts of the motion data:"] + #[doc = " a) serialized: vertexByteStride = sizeof(Vertex), vertexMotionStepByteStride = vertexCount * vertexByteStride"] + #[doc = " b) interleaved: vertexMotionStepByteStride = sizeof(Vertex), vertexByteStride = sizeof(Vertex) * motion_steps"] + #[doc = " Vertex N at time step i is at: vertexBuffer[N * vertexByteStride + i * vertexMotionStepByteStride + vertexBufferByteOffset]"] + #[doc = " Parameter \\a positionFormat must be one of the following: RT_FORMAT_FLOAT3, RT_FORMAT_HALF3, RT_FORMAT_FLOAT2, RT_FORMAT_HALF2."] + #[doc = " In case of formats RT_FORMAT_FLOAT2 or RT_FORMAT_HALF2 the third component is assumed to be zero, which can be useful for planar geometry."] + #[doc = " Calling this function overrides any previous call to any of the set(Motion)Vertices functions."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[in] vertexCount Number of vertices for one motion step"] + #[doc = " @param[in] vertexBuffer Buffer that holds the vertices of the triangles for all motion steps"] + #[doc = " @param[in] vertexBufferByteOffset Offset in bytes to the first vertex of the first motion step in buffer vertexBuffer"] + #[doc = " @param[in] vertexByteStride Stride in bytes between vertices, belonging to the same motion step"] + #[doc = " @param[in] vertexMotionStepByteStride Stride in bytes between vertices of the same triangle, but neighboring motion step"] + #[doc = " @param[in] positionFormat Format of the position attribute of a vertex"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetVertices"] + #[doc = " @ref rtGeometryTrianglesSetMotionVerticesMultiBuffer"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMotionVertices( + geometrytriangles: RTgeometrytriangles, + vertexCount: ::std::os::raw::c_uint, + vertexBuffer: RTbuffer, + vertexBufferByteOffset: RTsize, + vertexByteStride: RTsize, + vertexMotionStepByteStride: RTsize, + positionFormat: RTformat, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the vertex buffer of motion triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionVerticesMultiBuffer can be used instead of @ref rtGeometryTrianglesSetMotionVertices if the vertices for the different motion steps are stored in separate buffers."] + #[doc = " Parameter \\a vertexBuffers must point to an array of buffers of minimal size \\a motionStepCount (see @ref rtGeometryTrianglesSetMotionSteps)."] + #[doc = " All buffers must, however, share the same byte offset as well as vertex stride and position format."] + #[doc = " Calling this function overrides any previous call to any of the set(Motion)Vertices functions."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[in] vertexCount Number of vertices for one motion step"] + #[doc = " @param[in] vertexBuffers Buffers that hold the vertices of the triangles per motion step"] + #[doc = " @param[in] vertexBufferCount Number of buffers passed, must match the number of motion steps before a launch call"] + #[doc = " @param[in] vertexBufferByteOffset Offset in bytes to the first vertex in every buffer vertexBuffers"] + #[doc = " @param[in] vertexByteStride Stride in bytes between vertices, belonging to the same motion step"] + #[doc = " @param[in] positionFormat Format of the position attribute of a vertex"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetVertices"] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMotionVerticesMultiBuffer( + geometrytriangles: RTgeometrytriangles, + vertexCount: ::std::os::raw::c_uint, + vertexBuffers: *mut RTbuffer, + vertexBufferCount: ::std::os::raw::c_uint, + vertexBufferByteOffset: RTsize, + vertexByteStride: RTsize, + positionFormat: RTformat, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of motion steps associated with a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesSetMotionSteps sets the number of motion steps as specified in \\a motionStepCount"] + #[doc = " associated with \\a geometrytriangles. Note that the default value is 1, not 0,"] + #[doc = " for geometry without motion."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[in] motionStepCount Number of motion steps, motionStepCount >= 1"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMotionVertices"] + #[doc = " @ref rtGeometryTrianglesSetMotionVerticesMultiBuffer"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps"] + #[doc = " @ref rtGeometryTrianglesSetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesSetMotionRange"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMotionSteps( + geometrytriangles: RTgeometrytriangles, + motionStepCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of motion steps associated with a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps returns in \\a motionStepCount the number of motion steps"] + #[doc = " associated with \\a geometrytriangles. Note that the default value is 1, not 0,"] + #[doc = " for geometry without motion."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[out] motionStepCount Number of motion steps motionStepCount >= 1"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMotionSteps"] + #[doc = " @ref rtGeometryTrianglesGetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesGetMotionRange"] + #[doc = ""] + pub fn rtGeometryTrianglesGetMotionSteps( + geometrytriangles: RTgeometrytriangles, + motionStepCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion time range for a GeometryTriangles node."] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " Sets the inclusive motion time range [timeBegin, timeEnd] for \\a geometrytriangles,"] + #[doc = " where timeBegin <= timeEnd. The default time range is [0.0, 1.0]. The"] + #[doc = " time range has no effect unless @ref rtGeometryTrianglesSetMotionVertices or"] + #[doc = " @ref rtGeometryTrianglesSetMotionVerticesMultiBuffer with motionStepCount > 1 is"] + #[doc = " called, in which case the time steps uniformly divide the time range."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[out] timeBegin Beginning time value of range"] + #[doc = " @param[out] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionRange was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetMotionRange"] + #[doc = " @ref rtGeometryTrianglesSetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMotionRange( + geometrytriangles: RTgeometrytriangles, + timeBegin: f32, + timeEnd: f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion time range associated with a GeometryTriangles node."] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesGetMotionRange returns the motion time range associated with"] + #[doc = " \\a geometrytriangles from a previous call to @ref rtGeometryTrianglesSetMotionRange, or the"] + #[doc = " default values of [0.0, 1.0]."] + #[doc = ""] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[out] timeBegin Beginning time value of range"] + #[doc = " @param[out] timeEnd Ending time value of range"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetMotionRange was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMotionRange"] + #[doc = " @ref rtGeometryTrianglesGetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryTrianglesGetMotionRange( + geometrytriangles: RTgeometrytriangles, + timeBegin: *mut f32, + timeEnd: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the motion border modes of a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesSetMotionBorderMode sets the behavior of \\a geometrytriangles"] + #[doc = " outside its motion time range. Options are @ref RT_MOTIONBORDERMODE_CLAMP"] + #[doc = " or @ref RT_MOTIONBORDERMODE_VANISH. See @ref rtTransformSetMotionBorderMode"] + #[doc = " for details."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[in] beginMode Motion border mode at motion range begin"] + #[doc = " @param[in] endMode Motion border mode at motion range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMotionBorderMode was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesSetMotionRange"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMotionBorderMode( + geometrytriangles: RTgeometrytriangles, + beginMode: RTmotionbordermode, + endMode: RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the motion border modes of a GeometryTriangles node"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesGetMotionBorderMode returns the motion border modes"] + #[doc = " for the time range associated with \\a geometrytriangles."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[out] beginMode Motion border mode at motion range begin"] + #[doc = " @param[out] endMode Motion border mode at motion range end"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetMotionBorderMode was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMotionBorderMode"] + #[doc = " @ref rtGeometryTrianglesGetMotionRange"] + #[doc = " @ref rtGeometryTrianglesGetMotionSteps"] + #[doc = ""] + pub fn rtGeometryTrianglesGetMotionBorderMode( + geometrytriangles: RTgeometrytriangles, + beginMode: *mut RTmotionbordermode, + endMode: *mut RTmotionbordermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets flags that influence the behavior of traversal"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesSetBuildFlags can be used to set object-specific flags that affect the acceleration-structure-build behavior."] + #[doc = " If parameter \\a buildFlags contains the RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS flag, all buffers (including the vertex, index, and materialIndex buffer) holding"] + #[doc = " information that is evaluated at acceleration-structure-build time will be released after the build."] + #[doc = " OptiX does not take ownership over the buffers, but simply frees the corresponding device memory."] + #[doc = " Sharing buffers with other GeometryTriangles nodes is possible if all of them are built within one OptiX launch."] + #[doc = " Note that it is the users responsibility that the buffers hold data for the next acceleration structure build if the acceleration structure is marked dirty."] + #[doc = " E.g., if the flag is set, an OptiX launch will cause the acceleration structure build and release the memory afterwards."] + #[doc = " If the acceleration structure is marked dirty before the next launch (e.g., due to refitting), the user needs to map the buffers before the launch to fill them with data."] + #[doc = " Further, there are certain configurations with motion when the buffers cannot be released in which case the flag is ignored and the data is not freed."] + #[doc = " The buffers can only be released if all GeometryTriangles belonging to a GeometryGroup have the same number of motion steps and equal motion begin / end times."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[in] buildFlags The flags to set"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetBuildFlags was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetBuildFlags"] + #[doc = ""] + pub fn rtGeometryTrianglesSetBuildFlags( + geometrytriangles: RTgeometrytriangles, + buildFlags: RTgeometrybuildflags, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of materials used for the GeometryTriangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesGetMaterialCount returns the number of materials that are used with \\a geometrytriangles."] + #[doc = " By default there is one material slot."] + #[doc = ""] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[out] numMaterials Number of materials used with this GeometryTriangles node"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetMaterialCount was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMaterialCount"] + #[doc = ""] + pub fn rtGeometryTrianglesGetMaterialCount( + geometrytriangles: RTgeometrytriangles, + numMaterials: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the number of materials used for the GeometryTriangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesSetMaterialCount sets the number of materials that are used with \\a geometrytriangles."] + #[doc = " By default there is one material slot."] + #[doc = " This number must be equal to the number of materials that is set at the GeometryInstance where \\a geometrytriangles is attached to."] + #[doc = " Multi-material support for GeometryTriangles is limited to a fixed partition of the geometry into sets of triangles."] + #[doc = " Each triangle set maps to one material slot (within range [0, numMaterials-1])."] + #[doc = " The mapping is set via @ref rtGeometryTrianglesSetMaterialIndices."] + #[doc = " The actual materials are set at the GeometryInstance."] + #[doc = " The geometry can be instanced when attached to multiple GeometryInstances."] + #[doc = " In that case, the materials attached to each GeometryInstance can differ (effectively causing different materials per instance of the geometry)."] + #[doc = " \\a numMaterials must be >=1 and <=2^16."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[in] numMaterials Number of materials used with this geometry"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMaterialCount was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetMaterialCount"] + #[doc = " @ref rtGeometryTrianglesSetMaterialIndices"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMaterialCount( + geometrytriangles: RTgeometrytriangles, + numMaterials: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the index buffer of indexed triangles"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMaterialIndices set the material slot per triangle of \\a geometrytriangles."] + #[doc = " Hence, buffer \\a materialIndexBuffer must hold triangleCount entries."] + #[doc = " Every material index must be in range [0, numMaterials-1] (see @ref rtGeometryTrianglesSetMaterialCount)."] + #[doc = " Parameter \\a materialIndexBufferByteOffset can be used to specify a byte offset to the first index in buffer \\a materialIndexBuffer."] + #[doc = " Parameter \\a materialIndexByteStride sets the stride in bytes between indices."] + #[doc = " Parameter \\a materialIndexFormat must be one of the following: RT_FORMAT_UNSIGNED_INT, RT_FORMAT_UNSIGNED_SHORT, RT_FORMAT_UNSIGNED_BYTE."] + #[doc = " The buffer is only used if the number of materials as set via @ref rtGeometryTrianglesSetMaterialCount is larger than one."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node to query for the primitive index offset"] + #[doc = " @param[in] materialIndexBuffer Buffer that holds the indices into the vertex buffer of the triangles"] + #[doc = " @param[in] materialIndexBufferByteOffset Offset to first index in buffer indexBuffer"] + #[doc = " @param[in] materialIndexByteStride Stride in bytes between triplets of indices"] + #[doc = " @param[in] materialIndexFormat Format of the triplet of indices to index the vertices of a triangle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetMaterialIndices was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMaterialCount"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial"] + #[doc = ""] + pub fn rtGeometryTrianglesSetMaterialIndices( + geometrytriangles: RTgeometrytriangles, + materialIndexBuffer: RTbuffer, + materialIndexBufferByteOffset: RTsize, + materialIndexByteStride: RTsize, + materialIndexFormat: RTformat, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets geometry-specific flags that influence the behavior of traversal"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial can be used to set geometry-specific flags that may"] + #[doc = " change the behavior of traversal when intersecting the geometry."] + #[doc = " Note that the flags are evaluated at acceleration structure build time."] + #[doc = " An acceleration must be marked dirty for changes to the flags to take effect."] + #[doc = " Setting the flags RT_GEOMETRY_FLAG_NO_SPLITTING and/or RT_GEOMETRY_FLAG_DISABLE_ANYHIT should be dependent on the"] + #[doc = " material that is used for the intersection."] + #[doc = " Therefore, the flags are set per material slot (with the actual material binding being set on the GeomteryInstance)."] + #[doc = " If the geometry is instanced and different instances apply different materials to the geometry, the per-material geometry-specific flags"] + #[doc = " need to apply to the materials of all instances."] + #[doc = " Example with two instances with each having two materials, node graph:"] + #[doc = " G"] + #[doc = " / \\"] + #[doc = " / \\"] + #[doc = " T0 T1"] + #[doc = " | |"] + #[doc = " GG0-A-GG1"] + #[doc = " | |"] + #[doc = " M0-GI0 GI1-M2"] + #[doc = " / \\ / \\"] + #[doc = " M1 GT M3"] + #[doc = " with: G-Group, GG-GeometryGroup, T-Transform, A-Acceleration, GI-GeometryInstance, M-Material, GT-GeometryTriangles"] + #[doc = " RT_GEOMETRY_FLAG_NO_SPLITTING needs to be set for material index 0, if M0 or M2 require it."] + #[doc = " RT_GEOMETRY_FLAG_DISABLE_ANYHIT should be set for material index 0, if M0 and M2 allow it."] + #[doc = " RT_GEOMETRY_FLAG_NO_SPLITTING needs to be set for material index 1, if M1 or M3 require it."] + #[doc = " RT_GEOMETRY_FLAG_DISABLE_ANYHIT should be set for material index 1, if M1 and M3 allow it."] + #[doc = ""] + #[doc = " Setting RT_GEOMETRY_FLAG_NO_SPLITTING prevents splitting the primitive during the acceleration structure build."] + #[doc = " Splitting is done to increase performance, but as a side-effect may result in multiple executions of"] + #[doc = " the any-hit program for a single intersection."] + #[doc = " To avoid further side effects (e.g., multiple accumulations of a value) that may result of a multiple execution,"] + #[doc = " RT_GEOMETRY_FLAG_NO_SPLITTING needs to be set."] + #[doc = " RT_GEOMETRY_FLAG_DISABLE_ANYHIT is an optimization due to which the execution of the any-hit program is skipped."] + #[doc = " If possible, the flag should be set."] + #[doc = " Note that if no any-hit program is set on a material by the user, a no-op any-hit program will be used."] + #[doc = " Therefore, this flag still needs to be set to skip the execution of any any-hit program."] + #[doc = " An automatic determination of whether to set the DISABLE_ANYHIT flag is not possible since the information"] + #[doc = " whether or not to skip the any-hit program depends on the materials that are used, and this information"] + #[doc = " may not be available at acceleration build time."] + #[doc = " For example, materials can change afterwards (e.g., between frames) without a rebuild of an acceleration."] + #[doc = " Note that the final decision whether or not to execute the any-hit program at run time also depends on the flags set on"] + #[doc = " the ray as well as the geometry group that this geometry is part of."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles GeometryTriangles node handle"] + #[doc = " @param[in] materialIndex The material index for which to set the flags"] + #[doc = " @param[in] flags The flags to set."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetMaterialCount"] + #[doc = " @ref rtGeometryTrianglesSetMaterialIndices"] + #[doc = " @ref rtGeometryTrianglesSetBuildFlags"] + #[doc = ""] + pub fn rtGeometryTrianglesSetFlagsPerMaterial( + geometrytriangles: RTgeometrytriangles, + materialIndex: ::std::os::raw::c_uint, + flags: RTgeometryflags, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets geometry flags for triangles."] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " See @ref rtGeometryTrianglesSetFlagsPerMaterial for details."] + #[doc = ""] + #[doc = " @param[in] triangles The triangles handle"] + #[doc = " @param[in] materialIndex The index of the material for which to retrieve the flags"] + #[doc = " @param[out] flags Flags for the given geometry group"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetFlagsPerMaterial was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesSetFlagsPerMaterial,"] + #[doc = " @ref rtGeometryTrianglesSetMaterialIndices"] + #[doc = " @ref rtTrace"] + pub fn rtGeometryTrianglesGetFlagsPerMaterial( + triangles: RTgeometrytriangles, + materialIndex: ::std::os::raw::c_uint, + flags: *mut RTgeometryflags, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialCreate creates a new material within a context. \\a context specifies the target"] + #[doc = " context, as returned by @ref rtContextCreate. Sets \\a *material to the handle of a newly"] + #[doc = " created material within \\a context. Returns @ref RT_ERROR_INVALID_VALUE if \\a material is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context Specifies a context within which to create a new material"] + #[doc = " @param[out] material Returns a newly created material"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialDestroy,"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtMaterialCreate(context: RTcontext, material: *mut RTmaterial) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a material object"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialDestroy removes \\a material from its context and deletes it. \\a material should"] + #[doc = " be a value returned by @ref rtMaterialCreate. Associated variables declared via @ref"] + #[doc = " rtMaterialDeclareVariable are destroyed, but no child graph nodes are destroyed. After the"] + #[doc = " call, \\a material is no longer a valid handle."] + #[doc = ""] + #[doc = " @param[in] material Handle of the material node to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialDestroy(material: RTmaterial) -> RTresult; +} +extern "C" { + #[doc = " @brief Verifies the state of a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialValidate checks \\a material for completeness. If \\a material or"] + #[doc = " any of the objects attached to \\a material are not valid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialValidate(material: RTmaterial) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialGetContext queries a material for its associated context."] + #[doc = " \\a material specifies the material to query, and should be a value returned by"] + #[doc = " @ref rtMaterialCreate. If both parameters are valid, \\a *context"] + #[doc = " sets to the context associated with \\a material. Otherwise, the call"] + #[doc = " has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to query"] + #[doc = " @param[out] context Returns the context associated with the material"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialGetContext(material: RTmaterial, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the closest-hit program associated with a (material, ray type) tuple"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialSetClosestHitProgram specifies a closest-hit program to associate"] + #[doc = " with a (material, ray type) tuple. \\a material specifies the material of"] + #[doc = " interest and should be a value returned by @ref rtMaterialCreate."] + #[doc = " \\a rayTypeIndex specifies the type of ray to which the program applies and"] + #[doc = " should be a value less than the value returned by @ref rtContextGetRayTypeCount."] + #[doc = " \\a program specifies the target closest-hit program which applies to"] + #[doc = " the tuple (\\a material, \\a rayTypeIndex) and should be a value returned by"] + #[doc = " either @ref rtProgramCreateFromPTXString or @ref rtProgramCreateFromPTXFile."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material of the (material, ray type) tuple to modify"] + #[doc = " @param[in] rayTypeIndex Specifies the ray type of the (material, ray type) tuple to modify"] + #[doc = " @param[in] program Specifies the closest-hit program to associate with the (material, ray type) tuple"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialSetClosestHitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialGetClosestHitProgram,"] + #[doc = " @ref rtMaterialCreate,"] + #[doc = " @ref rtContextGetRayTypeCount,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramCreateFromPTXFile"] + #[doc = ""] + pub fn rtMaterialSetClosestHitProgram( + material: RTmaterial, + rayTypeIndex: ::std::os::raw::c_uint, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the closest-hit program associated with a (material, ray type) tuple"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialGetClosestHitProgram queries the closest-hit program associated"] + #[doc = " with a (material, ray type) tuple. \\a material specifies the material of"] + #[doc = " interest and should be a value returned by @ref rtMaterialCreate."] + #[doc = " \\a rayTypeIndex specifies the target ray type and should be a value"] + #[doc = " less than the value returned by @ref rtContextGetRayTypeCount."] + #[doc = " If all parameters are valid, \\a *program sets to the handle of the"] + #[doc = " any-hit program associated with the tuple (\\a material, \\a rayTypeIndex)."] + #[doc = " Otherwise, the call has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material of the (material, ray type) tuple to query"] + #[doc = " @param[in] rayTypeIndex Specifies the type of ray of the (material, ray type) tuple to query"] + #[doc = " @param[out] program Returns the closest-hit program associated with the (material, ray type) tuple"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialGetClosestHitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialSetClosestHitProgram,"] + #[doc = " @ref rtMaterialCreate,"] + #[doc = " @ref rtContextGetRayTypeCount"] + #[doc = ""] + pub fn rtMaterialGetClosestHitProgram( + material: RTmaterial, + rayTypeIndex: ::std::os::raw::c_uint, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the any-hit program associated with a (material, ray type) tuple"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialSetAnyHitProgram specifies an any-hit program to associate with a"] + #[doc = " (material, ray type) tuple. \\a material specifies the target material and"] + #[doc = " should be a value returned by @ref rtMaterialCreate. \\a rayTypeIndex specifies"] + #[doc = " the type of ray to which the program applies and should be a value less than"] + #[doc = " the value returned by @ref rtContextGetRayTypeCount. \\a program specifies the"] + #[doc = " target any-hit program which applies to the tuple (\\a material,"] + #[doc = " \\a rayTypeIndex) and should be a value returned by either"] + #[doc = " @ref rtProgramCreateFromPTXString or @ref rtProgramCreateFromPTXFile."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material of the (material, ray type) tuple to modify"] + #[doc = " @param[in] rayTypeIndex Specifies the type of ray of the (material, ray type) tuple to modify"] + #[doc = " @param[in] program Specifies the any-hit program to associate with the (material, ray type) tuple"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialSetAnyHitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialGetAnyHitProgram,"] + #[doc = " @ref rtMaterialCreate,"] + #[doc = " @ref rtContextGetRayTypeCount,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtProgramCreateFromPTXFile"] + #[doc = ""] + pub fn rtMaterialSetAnyHitProgram( + material: RTmaterial, + rayTypeIndex: ::std::os::raw::c_uint, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the any-hit program associated with a (material, ray type) tuple"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialGetAnyHitProgram queries the any-hit program associated"] + #[doc = " with a (material, ray type) tuple. \\a material specifies the material of"] + #[doc = " interest and should be a value returned by @ref rtMaterialCreate."] + #[doc = " \\a rayTypeIndex specifies the target ray type and should be a value"] + #[doc = " less than the value returned by @ref rtContextGetRayTypeCount."] + #[doc = " if all parameters are valid, \\a *program sets to the handle of the"] + #[doc = " any-hit program associated with the tuple (\\a material, \\a rayTypeIndex)."] + #[doc = " Otherwise, the call has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material of the (material, ray type) tuple to query"] + #[doc = " @param[in] rayTypeIndex Specifies the type of ray of the (material, ray type) tuple to query"] + #[doc = " @param[out] program Returns the any-hit program associated with the (material, ray type) tuple"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialGetAnyHitProgram was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialSetAnyHitProgram,"] + #[doc = " @ref rtMaterialCreate,"] + #[doc = " @ref rtContextGetRayTypeCount"] + #[doc = ""] + pub fn rtMaterialGetAnyHitProgram( + material: RTmaterial, + rayTypeIndex: ::std::os::raw::c_uint, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable to be associated with a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialDeclareVariable declares a new variable to be associated with a material."] + #[doc = " \\a material specifies the target material, and should be a value returned by @ref"] + #[doc = " rtMaterialCreate. \\a name specifies the name of the variable, and should be a \\a NULL-terminated"] + #[doc = " string. If there is currently no variable associated with \\a material named \\a name, and \\a v is"] + #[doc = " not \\a NULL, a new variable named \\a name will be created and associated with \\a material and \\a"] + #[doc = " *v will be set to the handle of the newly-created variable. Otherwise, this call has no effect"] + #[doc = " and returns either @ref RT_ERROR_INVALID_VALUE if either \\a name or \\a v is \\a NULL or @ref"] + #[doc = " RT_ERROR_VARIABLE_REDECLARED if \\a name is the name of an existing variable associated with the"] + #[doc = " material."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to modify"] + #[doc = " @param[in] name Specifies the name of the variable"] + #[doc = " @param[out] v Returns a handle to a newly declared variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_REDECLARED"] + #[doc = " - @ref RT_ERROR_ILLEGAL_SYMBOL"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialDeclareVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialGetVariable,"] + #[doc = " @ref rtMaterialQueryVariable,"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialDeclareVariable( + material: RTmaterial, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries for the existence of a named variable of a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialQueryVariable queries for the existence of a material's named variable. \\a"] + #[doc = " material specifies the target material and should be a value returned by @ref rtMaterialCreate."] + #[doc = " \\a name specifies the name of the variable, and should be a \\a NULL-terminated"] + #[doc = " string. If \\a material is a valid material and \\a name is the name of a variable attached to \\a"] + #[doc = " material, \\a *v is set to a handle to that variable after the call. Otherwise, \\a *v is set to"] + #[doc = " \\a NULL. If \\a material is not a valid material, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to query"] + #[doc = " @param[in] name Specifies the name of the variable to query"] + #[doc = " @param[out] v Returns a the named variable, if it exists"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialQueryVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialGetVariable,"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialQueryVariable( + material: RTmaterial, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a variable from a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialRemoveVariable removes a variable from a material. The material of"] + #[doc = " interest is specified by \\a material, which should be a value returned by"] + #[doc = " @ref rtMaterialCreate. The variable to remove is specified by \\a v, which"] + #[doc = " should be a value returned by @ref rtMaterialDeclareVariable. Once a variable"] + #[doc = " has been removed from this material, another variable with the same name as the"] + #[doc = " removed variable may be declared. If \\a material does not refer to a valid material,"] + #[doc = " this call has no effect and returns @ref RT_ERROR_INVALID_VALUE. If \\a v is not"] + #[doc = " a valid variable or does not belong to \\a material, this call has no effect and"] + #[doc = " returns @ref RT_ERROR_INVALID_VALUE or @ref RT_ERROR_VARIABLE_NOT_FOUND, respectively."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to modify"] + #[doc = " @param[in] v Specifies the variable to remove"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialRemoveVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialDeclareVariable,"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialRemoveVariable(material: RTmaterial, v: RTvariable) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of variables attached to a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialGetVariableCount queries the number of variables attached to a"] + #[doc = " material. \\a material specifies the material, and should be a value returned by"] + #[doc = " @ref rtMaterialCreate. After the call, if both parameters are valid, the number"] + #[doc = " of variables attached to \\a material is returned to \\a *count. Otherwise, the"] + #[doc = " call has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to query"] + #[doc = " @param[out] count Returns the number of variables"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialGetVariableCount was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialGetVariableCount( + material: RTmaterial, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to an indexed variable of a material"] + #[doc = ""] + #[doc = " @ingroup Material"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtMaterialGetVariable queries the handle of a material's indexed variable. \\a material"] + #[doc = " specifies the target material and should be a value returned by @ref rtMaterialCreate. \\a index"] + #[doc = " specifies the index of the variable, and should be a value less than"] + #[doc = " @ref rtMaterialGetVariableCount. If \\a material is a valid material and \\a index is the index of a"] + #[doc = " variable attached to \\a material, \\a *v is set to a handle to that variable. Otherwise, \\a *v is"] + #[doc = " set to \\a NULL and either @ref RT_ERROR_INVALID_VALUE or @ref RT_ERROR_VARIABLE_NOT_FOUND is"] + #[doc = " returned depending on the validity of \\a material, or \\a index, respectively."] + #[doc = ""] + #[doc = " @param[in] material Specifies the material to query"] + #[doc = " @param[in] index Specifies the index of the variable to query"] + #[doc = " @param[out] v Returns the indexed variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_VARIABLE_NOT_FOUND"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtMaterialGetVariable was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtMaterialQueryVariable,"] + #[doc = " @ref rtMaterialGetVariableCount,"] + #[doc = " @ref rtMaterialCreate"] + #[doc = ""] + pub fn rtMaterialGetVariable( + material: RTmaterial, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new texture sampler object"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreate allocates a texture sampler object."] + #[doc = " Sets \\a *texturesampler to the handle of a newly created texture sampler within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a texturesampler is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context The context the texture sampler object will be created in"] + #[doc = " @param[out] texturesampler The return handle to the new texture sampler object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerDestroy"] + #[doc = ""] + pub fn rtTextureSamplerCreate( + context: RTcontext, + texturesampler: *mut RTtexturesampler, + ) -> RTresult; +} +#[doc = " @brief Structure describing a block of demand loaded memory."] +#[doc = ""] +#[doc = " @ingroup Buffer"] +#[doc = ""] +#[doc = " Description"] +#[doc = ""] +#[doc = " @ref \\RTmemoryblock describes a one-, two- or three-dimensional block of bytes in memory"] +#[doc = " for a \\a mipLevel that are interpreted as elements of \\a format."] +#[doc = ""] +#[doc = " The region is defined by the elements beginning at (x, y, z) and extending to"] +#[doc = " (x + width - 1, y + height - 1, z + depth - 1). The element size must be taken into account"] +#[doc = " when computing addresses into the memory block based on the size of elements. There is no"] +#[doc = " padding between elements within a row, e.g. along the x direction."] +#[doc = ""] +#[doc = " The starting address of the block is given by \\a baseAddress and data is stored at addresses"] +#[doc = " increasing from \\a baseAddress. One-dimensional blocks ignore the \\a rowPitch and"] +#[doc = " \\a planePitch members and are described entirely by the \\a baseAddress of the block. Two"] +#[doc = " dimensional blocks have contiguous bytes in every row, starting with \\a baseAddress, but"] +#[doc = " may have gaps between subsequent rows along the height dimension. The \\a rowPitch describes"] +#[doc = " the offset in bytes between subsequent rows within the two-dimensional block. Similarly,"] +#[doc = " the \\a planePitch describes the offset in bytes between subsequent planes within the depth"] +#[doc = " dimension."] +#[doc = ""] +#[doc = " History"] +#[doc = ""] +#[doc = " @ref RTmemoryblock was introduced in OptiX 6.1"] +#[doc = ""] +#[doc = " See also"] +#[doc = " @ref RTbuffercallback"] +#[doc = " @ref RTtexturesamplercallback"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RTmemoryblock { + pub format: RTformat, + pub baseAddress: *mut ::std::os::raw::c_void, + pub mipLevel: ::std::os::raw::c_uint, + pub x: ::std::os::raw::c_uint, + pub y: ::std::os::raw::c_uint, + pub z: ::std::os::raw::c_uint, + pub width: ::std::os::raw::c_uint, + pub height: ::std::os::raw::c_uint, + pub depth: ::std::os::raw::c_uint, + pub rowPitch: ::std::os::raw::c_uint, + pub planePitch: ::std::os::raw::c_uint, +} +extern "C" { + #[doc = " @brief Destroys a texture sampler object"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerDestroy removes \\a texturesampler from its context and deletes it."] + #[doc = " \\a texturesampler should be a value returned by @ref rtTextureSamplerCreate."] + #[doc = " After the call, \\a texturesampler is no longer a valid handle."] + #[doc = " Any API object that referenced \\a texturesampler will have its reference invalidated."] + #[doc = ""] + #[doc = " @param[in] texturesampler Handle of the texture sampler to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate"] + #[doc = ""] + pub fn rtTextureSamplerDestroy(texturesampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the state of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerValidate checks \\a texturesampler for completeness. If \\a texturesampler does not have buffers"] + #[doc = " attached to all of its MIP levels and array slices or if the filtering modes are incompatible with the current"] + #[doc = " MIP level and array slice configuration then returns @ref RT_ERROR_INVALID_CONTEXT."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler to be validated"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextValidate"] + #[doc = ""] + pub fn rtTextureSamplerValidate(texturesampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the context object that created this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetContext returns a handle to the context object that was used to create"] + #[doc = " \\a texturesampler. If \\a context is \\a NULL, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried for its context"] + #[doc = " @param[out] context The return handle for the context object of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtTextureSamplerGetContext( + texturesampler: RTtexturesampler, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 3.9. Use @ref rtBufferSetMipLevelCount instead."] + #[doc = ""] + pub fn rtTextureSamplerSetMipLevelCount( + texturesampler: RTtexturesampler, + mipLevelCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 3.9. Use @ref rtBufferGetMipLevelCount instead."] + #[doc = ""] + pub fn rtTextureSamplerGetMipLevelCount( + texturesampler: RTtexturesampler, + mipLevelCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 3.9. Use texture samplers with layered buffers instead. See @ref rtBufferCreate."] + #[doc = ""] + pub fn rtTextureSamplerSetArraySize( + texturesampler: RTtexturesampler, + textureCount: ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " Deprecated in OptiX 3.9. Use texture samplers with layered buffers instead. See @ref rtBufferCreate."] + #[doc = ""] + pub fn rtTextureSamplerGetArraySize( + texturesampler: RTtexturesampler, + textureCount: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the wrapping mode of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetWrapMode sets the wrapping mode of"] + #[doc = " \\a texturesampler to \\a wrapmode for the texture dimension specified"] + #[doc = " by \\a dimension. \\a wrapmode can take one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_WRAP_REPEAT"] + #[doc = " - @ref RT_WRAP_CLAMP_TO_EDGE"] + #[doc = " - @ref RT_WRAP_MIRROR"] + #[doc = " - @ref RT_WRAP_CLAMP_TO_BORDER"] + #[doc = ""] + #[doc = " The wrapping mode controls the behavior of the texture sampler as"] + #[doc = " texture coordinates wrap around the range specified by the indexing"] + #[doc = " mode. These values mirror the CUDA behavior of textures."] + #[doc = " See CUDA programming guide for details."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] dimension Dimension of the texture"] + #[doc = " @param[in] wrapmode The new wrap mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetWrapMode was introduced in OptiX 1.0."] + #[doc = " @ref RT_WRAP_MIRROR and @ref RT_WRAP_CLAMP_TO_BORDER were introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetWrapMode"] + #[doc = ""] + pub fn rtTextureSamplerSetWrapMode( + texturesampler: RTtexturesampler, + dimension: ::std::os::raw::c_uint, + wrapmode: RTwrapmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the wrap mode of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetWrapMode gets the texture wrapping mode of \\a texturesampler and stores it in \\a *wrapmode."] + #[doc = " See @ref rtTextureSamplerSetWrapMode for a list of values @ref RTwrapmode can take."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[in] dimension Dimension for the wrapping"] + #[doc = " @param[out] wrapmode The return handle for the wrap mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetWrapMode was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetWrapMode"] + #[doc = ""] + pub fn rtTextureSamplerGetWrapMode( + texturesampler: RTtexturesampler, + dimension: ::std::os::raw::c_uint, + wrapmode: *mut RTwrapmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the filtering modes of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetFilteringModes sets the minification, magnification and MIP mapping filter modes for \\a texturesampler."] + #[doc = " RTfiltermode must be one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_FILTER_NEAREST"] + #[doc = " - @ref RT_FILTER_LINEAR"] + #[doc = " - @ref RT_FILTER_NONE"] + #[doc = ""] + #[doc = " These filter modes specify how the texture sampler will interpolate"] + #[doc = " buffer data that has been attached to it. \\a minification and"] + #[doc = " \\a magnification must be one of @ref RT_FILTER_NEAREST or"] + #[doc = " @ref RT_FILTER_LINEAR. \\a mipmapping may be any of the three values but"] + #[doc = " must be @ref RT_FILTER_NONE if the texture sampler contains only a"] + #[doc = " single MIP level or one of @ref RT_FILTER_NEAREST or @ref RT_FILTER_LINEAR"] + #[doc = " if the texture sampler contains more than one MIP level."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] minification The new minification filter mode of the texture sampler"] + #[doc = " @param[in] magnification The new magnification filter mode of the texture sampler"] + #[doc = " @param[in] mipmapping The new MIP mapping filter mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetFilteringModes was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetFilteringModes"] + #[doc = ""] + pub fn rtTextureSamplerSetFilteringModes( + texturesampler: RTtexturesampler, + minification: RTfiltermode, + magnification: RTfiltermode, + mipmapping: RTfiltermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the filtering modes of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetFilteringModes gets the minification, magnification and MIP mapping filtering modes from"] + #[doc = " \\a texturesampler and stores them in \\a *minification, \\a *magnification and \\a *mipmapping, respectively. See"] + #[doc = " @ref rtTextureSamplerSetFilteringModes for the values @ref RTfiltermode may take."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] minification The return handle for the minification filtering mode of the texture sampler"] + #[doc = " @param[out] magnification The return handle for the magnification filtering mode of the texture sampler"] + #[doc = " @param[out] mipmapping The return handle for the MIP mapping filtering mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetFilteringModes was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetFilteringModes"] + #[doc = ""] + pub fn rtTextureSamplerGetFilteringModes( + texturesampler: RTtexturesampler, + minification: *mut RTfiltermode, + magnification: *mut RTfiltermode, + mipmapping: *mut RTfiltermode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the maximum anisotropy of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMaxAnisotropy sets the maximum anisotropy of \\a texturesampler to \\a value. A float"] + #[doc = " value specifies the maximum anisotropy ratio to be used when doing anisotropic filtering. This value will be clamped to the range [1,16]"] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] value The new maximum anisotropy level of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMaxAnisotropy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetMaxAnisotropy"] + #[doc = ""] + pub fn rtTextureSamplerSetMaxAnisotropy( + texturesampler: RTtexturesampler, + value: f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the maximum anisotropy level for a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMaxAnisotropy gets the maximum anisotropy level for \\a texturesampler and stores"] + #[doc = " it in \\a *value."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] value The return handle for the maximum anisotropy level of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMaxAnisotropy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetMaxAnisotropy"] + #[doc = ""] + pub fn rtTextureSamplerGetMaxAnisotropy( + texturesampler: RTtexturesampler, + value: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the minimum and the maximum MIP level access range of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMipLevelClamp sets lower end and the upper end of the MIP level range to clamp access to."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] minLevel The new minimum mipmap level of the texture sampler"] + #[doc = " @param[in] maxLevel The new maximum mipmap level of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMipLevelClamp was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetMipLevelClamp"] + #[doc = ""] + pub fn rtTextureSamplerSetMipLevelClamp( + texturesampler: RTtexturesampler, + minLevel: f32, + maxLevel: f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the minimum and the maximum MIP level access range for a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMipLevelClamp gets the minimum and the maximum MIP level access range for \\a texturesampler and stores"] + #[doc = " it in \\a *minLevel and \\a maxLevel."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] minLevel The return handle for the minimum mipmap level of the texture sampler"] + #[doc = " @param[out] maxLevel The return handle for the maximum mipmap level of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMipLevelClamp was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetMipLevelClamp"] + #[doc = ""] + pub fn rtTextureSamplerGetMipLevelClamp( + texturesampler: RTtexturesampler, + minLevel: *mut f32, + maxLevel: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the mipmap offset of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMipLevelBias sets the offset to be applied to the calculated mipmap level."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] value The new mipmap offset of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetMipLevelBias was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetMipLevelBias"] + #[doc = ""] + pub fn rtTextureSamplerSetMipLevelBias( + texturesampler: RTtexturesampler, + value: f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the mipmap offset for a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMipLevelBias gets the mipmap offset for \\a texturesampler and stores"] + #[doc = " it in \\a *value."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] value The return handle for the mipmap offset of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetMipLevelBias was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetMipLevelBias"] + #[doc = ""] + pub fn rtTextureSamplerGetMipLevelBias( + texturesampler: RTtexturesampler, + value: *mut f32, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the read mode of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetReadMode sets the data read mode of \\a texturesampler to \\a readmode."] + #[doc = " \\a readmode can take one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_TEXTURE_READ_ELEMENT_TYPE"] + #[doc = " - @ref RT_TEXTURE_READ_NORMALIZED_FLOAT"] + #[doc = " - @ref RT_TEXTURE_READ_ELEMENT_TYPE_SRGB"] + #[doc = " - @ref RT_TEXTURE_READ_NORMALIZED_FLOAT_SRGB"] + #[doc = ""] + #[doc = " @ref RT_TEXTURE_READ_ELEMENT_TYPE_SRGB and @ref RT_TEXTURE_READ_NORMALIZED_FLOAT_SRGB were introduced in OptiX 3.9"] + #[doc = " and apply sRGB to linear conversion during texture read for 8-bit integer buffer formats."] + #[doc = " \\a readmode controls the returned value of the texture sampler when it is used to sample"] + #[doc = " textures. @ref RT_TEXTURE_READ_ELEMENT_TYPE will return data of the type of the underlying"] + #[doc = " buffer objects. @ref RT_TEXTURE_READ_NORMALIZED_FLOAT will return floating point values"] + #[doc = " normalized by the range of the underlying type. If the underlying type is floating point,"] + #[doc = " @ref RT_TEXTURE_READ_NORMALIZED_FLOAT and @ref RT_TEXTURE_READ_ELEMENT_TYPE are equivalent,"] + #[doc = " always returning the unmodified floating point value."] + #[doc = ""] + #[doc = " For example, a texture sampler that samples a buffer of type @ref RT_FORMAT_UNSIGNED_BYTE with"] + #[doc = " a read mode of @ref RT_TEXTURE_READ_NORMALIZED_FLOAT will convert integral values from the"] + #[doc = " range [0,255] to floating point values in the range [0,1] automatically as the buffer is"] + #[doc = " sampled from."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] readmode The new read mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetReadMode was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetReadMode"] + #[doc = ""] + pub fn rtTextureSamplerSetReadMode( + texturesampler: RTtexturesampler, + readmode: RTtexturereadmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the read mode of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetReadMode gets the read mode of \\a texturesampler and stores it in \\a *readmode."] + #[doc = " See @ref rtTextureSamplerSetReadMode for a list of values @ref RTtexturereadmode can take."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] readmode The return handle for the read mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetReadMode was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetReadMode"] + #[doc = ""] + pub fn rtTextureSamplerGetReadMode( + texturesampler: RTtexturesampler, + readmode: *mut RTtexturereadmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets whether texture coordinates for this texture sampler are normalized"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetIndexingMode sets the indexing mode of \\a texturesampler to \\a indexmode. \\a indexmode"] + #[doc = " can take on one of the following values:"] + #[doc = ""] + #[doc = " - @ref RT_TEXTURE_INDEX_NORMALIZED_COORDINATES,"] + #[doc = " - @ref RT_TEXTURE_INDEX_ARRAY_INDEX"] + #[doc = ""] + #[doc = " These values are used to control the interpretation of texture coordinates. If the index mode is set to"] + #[doc = " @ref RT_TEXTURE_INDEX_NORMALIZED_COORDINATES, the texture is parameterized over [0,1]. If the index"] + #[doc = " mode is set to @ref RT_TEXTURE_INDEX_ARRAY_INDEX then texture coordinates are interpreted as array indices"] + #[doc = " into the contents of the underlying buffer objects."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be changed"] + #[doc = " @param[in] indexmode The new indexing mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetIndexingMode was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetIndexingMode"] + #[doc = ""] + pub fn rtTextureSamplerSetIndexingMode( + texturesampler: RTtexturesampler, + indexmode: RTtextureindexmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the indexing mode of a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetIndexingMode gets the indexing mode of \\a texturesampler and stores it in \\a *indexmode."] + #[doc = " See @ref rtTextureSamplerSetIndexingMode for the values @ref RTtextureindexmode may take."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried"] + #[doc = " @param[out] indexmode The return handle for the indexing mode of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetIndexingMode was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetIndexingMode"] + #[doc = ""] + pub fn rtTextureSamplerGetIndexingMode( + texturesampler: RTtexturesampler, + indexmode: *mut RTtextureindexmode, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Attaches a buffer object to a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetBuffer attaches \\a buffer to \\a texturesampler."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object that will contain the buffer"] + #[doc = " @param[in] deprecated0 Deprecated in OptiX 3.9, must be 0"] + #[doc = " @param[in] deprecated1 Deprecated in OptiX 3.9, must be 0"] + #[doc = " @param[in] buffer The buffer to be attached to the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerSetBuffer was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerGetBuffer"] + #[doc = ""] + pub fn rtTextureSamplerSetBuffer( + texturesampler: RTtexturesampler, + deprecated0: ::std::os::raw::c_uint, + deprecated1: ::std::os::raw::c_uint, + buffer: RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets a buffer object handle from a texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetBuffer gets a buffer object from"] + #[doc = " \\a texturesampler and"] + #[doc = " stores it in \\a *buffer."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried for the buffer"] + #[doc = " @param[in] deprecated0 Deprecated in OptiX 3.9, must be 0"] + #[doc = " @param[in] deprecated1 Deprecated in OptiX 3.9, must be 0"] + #[doc = " @param[out] buffer The return handle to the buffer attached to the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetBuffer was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerSetBuffer"] + #[doc = ""] + pub fn rtTextureSamplerGetBuffer( + texturesampler: RTtexturesampler, + deprecated0: ::std::os::raw::c_uint, + deprecated1: ::std::os::raw::c_uint, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the texture ID of this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetId returns a handle to the texture sampler"] + #[doc = " \\a texturesampler to be used in OptiX programs on the device to"] + #[doc = " reference the associated texture. The returned ID cannot be used on"] + #[doc = " the host side. If \\a textureId is \\a NULL, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] texturesampler The texture sampler object to be queried for its ID"] + #[doc = " @param[out] textureId The returned device-side texture ID of the texture sampler"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetId was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate"] + #[doc = ""] + pub fn rtTextureSamplerGetId( + texturesampler: RTtexturesampler, + textureId: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreate allocates and returns a new handle to a new buffer object in \\a *buffer associated"] + #[doc = " with \\a context. The backing storage of the buffer is managed by OptiX. A buffer is specified by a bitwise"] + #[doc = " \\a or combination of a \\a type and \\a flags in \\a bufferdesc. The supported types are:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_INPUT"] + #[doc = " - @ref RT_BUFFER_OUTPUT"] + #[doc = " - @ref RT_BUFFER_INPUT_OUTPUT"] + #[doc = " - @ref RT_BUFFER_PROGRESSIVE_STREAM"] + #[doc = ""] + #[doc = " The type values are used to specify the direction of data flow from the host to the OptiX devices."] + #[doc = " @ref RT_BUFFER_INPUT specifies that the host may only write to the buffer and the device may only read from the buffer."] + #[doc = " @ref RT_BUFFER_OUTPUT specifies the opposite, read only access on the host and write only access on the device."] + #[doc = " Devices and the host may read and write from buffers of type @ref RT_BUFFER_INPUT_OUTPUT. Reading or writing to"] + #[doc = " a buffer of the incorrect type (e.g., the host writing to a buffer of type @ref RT_BUFFER_OUTPUT) is undefined."] + #[doc = " @ref RT_BUFFER_PROGRESSIVE_STREAM is used to receive stream updates generated by progressive launches (see @ref rtContextLaunchProgressive2D)."] + #[doc = ""] + #[doc = " The supported flags are:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_GPU_LOCAL"] + #[doc = " - @ref RT_BUFFER_COPY_ON_DIRTY"] + #[doc = " - @ref RT_BUFFER_LAYERED"] + #[doc = " - @ref RT_BUFFER_CUBEMAP"] + #[doc = " - @ref RT_BUFFER_DISCARD_HOST_MEMORY"] + #[doc = ""] + #[doc = " If RT_BUFFER_LAYERED flag is set, buffer depth specifies the number of layers, not the depth of a 3D buffer."] + #[doc = " If RT_BUFFER_CUBEMAP flag is set, buffer depth specifies the number of cube faces, not the depth of a 3D buffer."] + #[doc = " See details in @ref rtBufferSetSize3D"] + #[doc = ""] + #[doc = " Flags can be used to optimize data transfers between the host and its devices. The flag @ref RT_BUFFER_GPU_LOCAL can only be"] + #[doc = " used in combination with @ref RT_BUFFER_INPUT_OUTPUT. @ref RT_BUFFER_INPUT_OUTPUT and @ref RT_BUFFER_GPU_LOCAL used together specify a buffer"] + #[doc = " that allows the host to \\a only write, and the device to read \\a and write data. The written data will never be visible"] + #[doc = " on the host side and will generally not be visible on other devices."] + #[doc = ""] + #[doc = " If @ref rtBufferGetDevicePointer has been called for a single device for a given buffer,"] + #[doc = " the user can change the buffer's content on that device through the pointer. OptiX must then synchronize the new buffer contents to all devices."] + #[doc = " These synchronization copies occur at every @ref rtContextLaunch \"rtContextLaunch\", unless the buffer is created with @ref RT_BUFFER_COPY_ON_DIRTY."] + #[doc = " In this case, @ref rtBufferMarkDirty can be used to notify OptiX that the buffer has been dirtied and must be synchronized."] + #[doc = ""] + #[doc = " The flag @ref RT_BUFFER_DISCARD_HOST_MEMORY can only be used in combination with @ref RT_BUFFER_INPUT. The data will be"] + #[doc = " synchronized to the devices as soon as the buffer is unmapped from the host using @ref rtBufferUnmap or"] + #[doc = " @ref rtBufferUnmapEx and the memory allocated on the host will be deallocated."] + #[doc = " It is preferred to map buffers created with the @ref RT_BUFFER_DISCARD_HOST_MEMORY using @ref rtBufferMapEx with the"] + #[doc = " @ref RT_BUFFER_MAP_WRITE_DISCARD option enabled. If it is mapped using @ref rtBufferMap or the @ref RT_BUFFER_MAP_WRITE"] + #[doc = " option instead, the data needs to be synchronized to the host during mapping."] + #[doc = " Note that the data that is allocated on the devices will not be deallocated until the buffer is destroyed."] + #[doc = ""] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a buffer is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " @ref RT_BUFFER_GPU_LOCAL was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromGLBO,"] + #[doc = " @ref rtBufferDestroy,"] + #[doc = " @ref rtBufferMarkDirty"] + #[doc = " @ref rtBufferBindProgressiveStream"] + #[doc = ""] + pub fn rtBufferCreate( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + buffer: *mut RTbuffer, + ) -> RTresult; +} +#[doc = " @brief Callback function used to demand load data for a buffer."] +#[doc = ""] +#[doc = " @ingroup Buffer"] +#[doc = ""] +#[doc = " Description"] +#[doc = ""] +#[doc = " @ref RTbuffercallback is implemented by the application. It is invoked by OptiX for each"] +#[doc = " \\a requestedPage of the demand loaded \\a buffer referenced by the previous launch that was not"] +#[doc = " resident in device memory. The callback should either fill the provided \\a block buffer with"] +#[doc = " the requested \\a pageDataSizeInBytes of data and return \\a true, or return \\a false. When the"] +#[doc = " callback returns \\a false, no data is transferred to the \\a buffer."] +#[doc = ""] +#[doc = " CAUTION: OptiX will invoke callback functions from multiple threads in order to satisfy"] +#[doc = " pending requests in parallel. A user provided callback function should not allow exceptions to"] +#[doc = " escape from their callback function."] +#[doc = ""] +#[doc = " @param[in] callbackData An arbitrary data pointer from the application when the callback was registered."] +#[doc = " @param[in] buffer Handle of the buffer requesting pages."] +#[doc = " @param[in] block A pointer to the @ref RTmemoryblock describing the memory to be filled with data."] +#[doc = ""] +#[doc = " Return values"] +#[doc = ""] +#[doc = " \\a non-zero The \\a block buffer was filled with \\a pageDataSizeInBytes of data."] +#[doc = " \\a zero No data was written. No data will be transferred to the \\a buffer."] +#[doc = " The same \\a block may be passed to the callback again after the next launch."] +#[doc = ""] +#[doc = " History"] +#[doc = ""] +#[doc = " @ref RTbuffercallback was introduced in OptiX 6.1"] +#[doc = ""] +#[doc = " See also"] +#[doc = " @ref RTmemoryblock"] +#[doc = " @ref rtBufferCreateFromCallback"] +pub type RTbuffercallback = ::std::option::Option< + unsafe extern "C" fn( + callbackData: *mut ::std::os::raw::c_void, + buffer: RTbuffer, + block: *mut RTmemoryblock, + ) -> ::std::os::raw::c_int, +>; +extern "C" { + #[doc = " @brief Creates a buffer whose contents are loaded on demand."] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromCallback allocates and returns a new handle to a new buffer object in \\a *buffer associated"] + #[doc = " with \\a context. The backing storage of the buffer is managed by OptiX, but is filled on demand by the application."] + #[doc = " The backing storage is allocated in multiples of pages. Each page is a uniform size as described by the"] + #[doc = " \\a RT_BUFFER_ATTRIBUTE_PAGE_SIZE attribute. The backing storage may be smaller than the total size of storage needed"] + #[doc = " for the buffer, with OptiX managing the storage in conjunction with the application supplied \\a callback. A buffer"] + #[doc = " is specified by a bitwise \\a or combination of a \\a type and \\a flags in \\a bufferdesc. The only supported type is"] + #[doc = " @ref RT_BUFFER_INPUT as only input buffers can be demand loaded."] + #[doc = ""] + #[doc = " The supported flags are:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_LAYERED"] + #[doc = " - @ref RT_BUFFER_CUBEMAP"] + #[doc = ""] + #[doc = " If RT_BUFFER_LAYERED flag is set, buffer depth specifies the number of layers, not the depth of a 3D buffer."] + #[doc = " If RT_BUFFER_CUBEMAP flag is set, buffer depth specifies the number of cube faces, not the depth of a 3D buffer."] + #[doc = " See details in @ref rtBufferSetSize3D"] + #[doc = ""] + #[doc = " It is an error to call @ref rtBufferGetDevicePointer, @ref rtBufferMap or @ref rtBufferUnmap for a demand loaded buffer."] + #[doc = ""] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if either \\a callback or \\a buffer is \\a NULL."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in."] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer."] + #[doc = " @param[in] callback The demand load callback. Most not be NULL."] + #[doc = " @param[in] callbackData An arbitrary pointer from the application that is passed to the callback. This may be \\a NULL."] + #[doc = " @param[out] buffer The return handle for the buffer object."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromCallback was introduced in OptiX 6.1"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref RTbuffercallback"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateFromCallback( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + callback: RTbuffercallback, + callbackData: *mut ::std::os::raw::c_void, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroys a buffer object"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferDestroy removes \\a buffer from its context and deletes it."] + #[doc = " \\a buffer should be a value returned by @ref rtBufferCreate."] + #[doc = " After the call, \\a buffer is no longer a valid handle."] + #[doc = " Any API object that referenced \\a buffer will have its reference invalidated."] + #[doc = ""] + #[doc = " @param[in] buffer Handle of the buffer to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferDestroy was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferCreateFromGLBO"] + #[doc = ""] + pub fn rtBufferDestroy(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Validates the state of a buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferValidate checks \\a buffer for completeness. If \\a buffer has not had its dimensionality, size or format"] + #[doc = " set, this call will return @ref RT_ERROR_INVALID_CONTEXT."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to validate"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferValidate was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferCreateFromGLBO"] + #[doc = " @ref rtContextValidate"] + #[doc = ""] + pub fn rtBufferValidate(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context object that created this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetContext returns a handle to the context that created \\a buffer in \\a *context."] + #[doc = " If \\a *context is \\a NULL, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its context"] + #[doc = " @param[out] context The return handle for the buffer's context"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetContext was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextCreate"] + #[doc = ""] + pub fn rtBufferGetContext(buffer: RTbuffer, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the format of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetFormat changes the \\a format of \\a buffer to the specified value."] + #[doc = " The data elements of the buffer will have the specified type and can either be"] + #[doc = " vector formats, or a user-defined type whose size is specified with"] + #[doc = " @ref rtBufferSetElementSize. Possible values for \\a format are:"] + #[doc = ""] + #[doc = " - @ref RT_FORMAT_HALF"] + #[doc = " - @ref RT_FORMAT_HALF2"] + #[doc = " - @ref RT_FORMAT_HALF3"] + #[doc = " - @ref RT_FORMAT_HALF4"] + #[doc = " - @ref RT_FORMAT_FLOAT"] + #[doc = " - @ref RT_FORMAT_FLOAT2"] + #[doc = " - @ref RT_FORMAT_FLOAT3"] + #[doc = " - @ref RT_FORMAT_FLOAT4"] + #[doc = " - @ref RT_FORMAT_BYTE"] + #[doc = " - @ref RT_FORMAT_BYTE2"] + #[doc = " - @ref RT_FORMAT_BYTE3"] + #[doc = " - @ref RT_FORMAT_BYTE4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BYTE"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BYTE2"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BYTE3"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BYTE4"] + #[doc = " - @ref RT_FORMAT_SHORT"] + #[doc = " - @ref RT_FORMAT_SHORT2"] + #[doc = " - @ref RT_FORMAT_SHORT3"] + #[doc = " - @ref RT_FORMAT_SHORT4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_SHORT"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_SHORT2"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_SHORT3"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_SHORT4"] + #[doc = " - @ref RT_FORMAT_INT"] + #[doc = " - @ref RT_FORMAT_INT2"] + #[doc = " - @ref RT_FORMAT_INT3"] + #[doc = " - @ref RT_FORMAT_INT4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_INT"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_INT2"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_INT3"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_INT4"] + #[doc = " - @ref RT_FORMAT_LONG_LONG"] + #[doc = " - @ref RT_FORMAT_LONG_LONG2"] + #[doc = " - @ref RT_FORMAT_LONG_LONG3"] + #[doc = " - @ref RT_FORMAT_LONG_LONG4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_LONG_LONG"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_LONG_LONG2"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_LONG_LONG3"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_LONG_LONG4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC1"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC2"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC3"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC4"] + #[doc = " - @ref RT_FORMAT_BC4"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC5"] + #[doc = " - @ref RT_FORMAT_BC5"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC6H"] + #[doc = " - @ref RT_FORMAT_BC6H"] + #[doc = " - @ref RT_FORMAT_UNSIGNED_BC7"] + #[doc = " - @ref RT_FORMAT_USER"] + #[doc = ""] + #[doc = " Buffers of block-compressed formats like @ref RT_FORMAT_BC6H must be sized"] + #[doc = " to a quarter of the uncompressed view resolution in each dimension, i.e."] + #[doc = " @code rtBufferSetSize2D( buffer, width/4, height/4 ); @endcode"] + #[doc = " The base type of the internal buffer will then correspond to @ref RT_FORMAT_UNSIGNED_INT2"] + #[doc = " for BC1 and BC4 formats and @ref RT_FORMAT_UNSIGNED_INT4 for all other BC formats."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to have its format set"] + #[doc = " @param[in] format The target format of the buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetFormat was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetFormat,"] + #[doc = " @ref rtBufferGetFormat,"] + #[doc = " @ref rtBufferGetFormat,"] + #[doc = " @ref rtBufferGetElementSize,"] + #[doc = " @ref rtBufferSetElementSize"] + #[doc = ""] + pub fn rtBufferSetFormat(buffer: RTbuffer, format: RTformat) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the format of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetFormat returns, in \\a *format, the format of \\a buffer. See @ref rtBufferSetFormat for a listing"] + #[doc = " of @ref RTbuffer values."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its format"] + #[doc = " @param[out] format The return handle for the buffer's format"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetFormat was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetFormat,"] + #[doc = " @ref rtBufferGetFormat"] + #[doc = ""] + pub fn rtBufferGetFormat(buffer: RTbuffer, format: *mut RTformat) -> RTresult; +} +extern "C" { + #[doc = " @brief Modifies the size in bytes of a buffer's individual elements"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetElementSize modifies the size in bytes of a buffer's user-formatted"] + #[doc = " elements. The target buffer is specified by \\a buffer, which should be a"] + #[doc = " value returned by @ref rtBufferCreate and should have format @ref RT_FORMAT_USER."] + #[doc = " The new size of the buffer's individual elements is specified by"] + #[doc = " \\a elementSize and should not be 0. If the buffer has"] + #[doc = " format @ref RT_FORMAT_USER, and \\a elementSize is not 0, then the buffer's individual"] + #[doc = " element size is set to \\a elemenSize and all storage associated with the buffer is reset."] + #[doc = " Otherwise, this call has no effect and returns either @ref RT_ERROR_TYPE_MISMATCH if"] + #[doc = " the buffer does not have format @ref RT_FORMAT_USER or @ref RT_ERROR_INVALID_VALUE if the"] + #[doc = " buffer has format @ref RT_FORMAT_USER but \\a elemenSize is 0."] + #[doc = ""] + #[doc = " @param[in] buffer Specifies the buffer to be modified"] + #[doc = " @param[in] elementSize Specifies the new size in bytes of the buffer's individual elements"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_TYPE_MISMATCH"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetElementSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferGetElementSize,"] + #[doc = " @ref rtBufferCreate"] + #[doc = ""] + pub fn rtBufferSetElementSize(buffer: RTbuffer, elementSize: RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the size of a buffer's individual elements"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetElementSize queries the size of a buffer's elements. The target buffer"] + #[doc = " is specified by \\a buffer, which should be a value returned by"] + #[doc = " @ref rtBufferCreate. The size, in bytes, of the buffer's"] + #[doc = " individual elements is returned in \\a *elementSize."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if given a \\a NULL pointer."] + #[doc = ""] + #[doc = " @param[in] buffer Specifies the buffer to be queried"] + #[doc = " @param[out] elementSize Returns the size of the buffer's individual elements"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_UNKNOWN"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetElementSize was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetElementSize,"] + #[doc = " @ref rtBufferCreate"] + #[doc = ""] + pub fn rtBufferGetElementSize(buffer: RTbuffer, elementSize: *mut RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the width and dimensionality of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize1D sets the dimensionality of \\a buffer to 1 and sets its width to"] + #[doc = " \\a width."] + #[doc = " Fails with @ref RT_ERROR_ALREADY_MAPPED if called on a buffer that is mapped."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be resized"] + #[doc = " @param[in] width The width of the resized buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize1D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferSetSize1D(buffer: RTbuffer, width: RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Get the width of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize1D stores the width of \\a buffer in \\a *width."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize1D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetSize1D(buffer: RTbuffer, width: *mut RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the width, height and dimensionality of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize2D sets the dimensionality of \\a buffer to 2 and sets its width"] + #[doc = " and height to \\a width and \\a height, respectively. If \\a width or \\a height is"] + #[doc = " zero, they both must be zero."] + #[doc = " Fails with @ref RT_ERROR_ALREADY_MAPPED if called on a buffer that is mapped."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be resized"] + #[doc = " @param[in] width The width of the resized buffer"] + #[doc = " @param[in] height The height of the resized buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize2D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferSetSize2D(buffer: RTbuffer, width: RTsize, height: RTsize) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the width and height of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize2D stores the width and height of \\a buffer in \\a *width and"] + #[doc = " \\a *height, respectively."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = " @param[out] height The return handle for the buffer's height"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize2D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetSize2D(buffer: RTbuffer, width: *mut RTsize, height: *mut RTsize) + -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the width, height, depth and dimensionality of a buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize3D sets the dimensionality of \\a buffer to 3 and sets its width,"] + #[doc = " height and depth to \\a width, \\a height and \\a depth, respectively. If \\a width,"] + #[doc = " \\a height or \\a depth is zero, they all must be zero."] + #[doc = ""] + #[doc = " A 1D layered mipmapped buffer is allocated if \\a height is 1 and the @ref RT_BUFFER_LAYERED flag was set at buffer creating. The number of layers is determined by the \\a depth."] + #[doc = " A 2D layered mipmapped buffer is allocated if the @ref RT_BUFFER_LAYERED flag was set at buffer creating. The number of layers is determined by the \\a depth."] + #[doc = " A cubemap mipmapped buffer is allocated if the @ref RT_BUFFER_CUBEMAP flag was set at buffer creating. \\a width must be equal to \\a height and the number of cube faces is determined by the \\a depth,"] + #[doc = " it must be six or a multiple of six, if the @ref RT_BUFFER_LAYERED flag was also set."] + #[doc = " Layered, mipmapped and cubemap buffers are supported only as texture buffers."] + #[doc = ""] + #[doc = " Fails with @ref RT_ERROR_ALREADY_MAPPED if called on a buffer that is mapped."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be resized"] + #[doc = " @param[in] width The width of the resized buffer"] + #[doc = " @param[in] height The height of the resized buffer"] + #[doc = " @param[in] depth The depth of the resized buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetSize3D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferSetSize3D( + buffer: RTbuffer, + width: RTsize, + height: RTsize, + depth: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the MIP level count of a buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetMipLevelCount sets the number of MIP levels to \\a levels. The default number of MIP levels is 1."] + #[doc = " Fails with @ref RT_ERROR_ALREADY_MAPPED if called on a buffer that is mapped."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be resized"] + #[doc = " @param[in] levels Number of mip levels"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetMipLevelCount was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferSetMipLevelCount(buffer: RTbuffer, levels: ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the width, height and depth of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize3D stores the width, height and depth of \\a buffer in \\a *width,"] + #[doc = " \\a *height and \\a *depth, respectively."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = " @param[out] height The return handle for the buffer's height"] + #[doc = " @param[out] depth The return handle for the buffer's depth"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetSize3D was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetSize3D( + buffer: RTbuffer, + width: *mut RTsize, + height: *mut RTsize, + depth: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the width of buffer specific MIP level"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize1D stores the width of \\a buffer in \\a *width."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[in] level The buffer MIP level index to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize1D was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetMipLevelSize1D( + buffer: RTbuffer, + level: ::std::os::raw::c_uint, + width: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the width, height of buffer specific MIP level"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize2D stores the width, height of \\a buffer in \\a *width and"] + #[doc = " \\a *height respectively."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[in] level The buffer MIP level index to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = " @param[out] height The return handle for the buffer's height"] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize2D was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetMipLevelSize2D( + buffer: RTbuffer, + level: ::std::os::raw::c_uint, + width: *mut RTsize, + height: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the width, height and depth of buffer specific MIP level"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize3D stores the width, height and depth of \\a buffer in \\a *width,"] + #[doc = " \\a *height and \\a *depth, respectively."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[in] level The buffer MIP level index to be queried for its dimensions"] + #[doc = " @param[out] width The return handle for the buffer's width"] + #[doc = " @param[out] height The return handle for the buffer's height"] + #[doc = " @param[out] depth The return handle for the buffer's depth"] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelSize3D was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetMipLevelSize3D( + buffer: RTbuffer, + level: ::std::os::raw::c_uint, + width: *mut RTsize, + height: *mut RTsize, + depth: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the dimensionality and dimensions of a buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetSizev sets the dimensionality of \\a buffer to \\a dimensionality and"] + #[doc = " sets the dimensions of the buffer to the values stored at *\\a dims, which must contain"] + #[doc = " a number of values equal to \\a dimensionality. If any of values of \\a dims is zero"] + #[doc = " they must all be zero."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be resized"] + #[doc = " @param[in] dimensionality The dimensionality the buffer will be resized to"] + #[doc = " @param[in] dims The array of sizes for the dimension of the resize"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetSizev was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferSetSizev( + buffer: RTbuffer, + dimensionality: ::std::os::raw::c_uint, + dims: *const RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the dimensions of this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetSizev stores the dimensions of \\a buffer in \\a *dims. The number of"] + #[doc = " dimensions returned is specified by \\a dimensionality. The storage at \\a dims must be"] + #[doc = " large enough to hold the number of requested buffer dimensions."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensions"] + #[doc = " @param[in] dimensionality The number of requested dimensions"] + #[doc = " @param[out] dims The array of dimensions to store to"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetSizev was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetMipLevelCount,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D"] + #[doc = ""] + pub fn rtBufferGetSizev( + buffer: RTbuffer, + dimensionality: ::std::os::raw::c_uint, + dims: *mut RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the dimensionality of this buffer object"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetDimensionality returns the dimensionality of \\a buffer in \\a"] + #[doc = " *dimensionality. The value returned will be one of 1, 2 or 3, corresponding to 1D, 2D"] + #[doc = " and 3D buffers, respectively."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its dimensionality"] + #[doc = " @param[out] dimensionality The return handle for the buffer's dimensionality"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetDimensionality was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " \\a rtBufferSetSize{1-2-3}D"] + #[doc = ""] + pub fn rtBufferGetDimensionality( + buffer: RTbuffer, + dimensionality: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the number of mipmap levels of this buffer object"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelCount returns the number of mipmap levels. Default number of MIP levels is 1."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its number of mipmap levels"] + #[doc = " @param[out] level The return number of mipmap levels"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetMipLevelCount was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetMipLevelCount,"] + #[doc = " @ref rtBufferSetSize1D,"] + #[doc = " @ref rtBufferSetSize2D,"] + #[doc = " @ref rtBufferSetSize3D,"] + #[doc = " @ref rtBufferSetSizev,"] + #[doc = " @ref rtBufferGetMipLevelSize1D,"] + #[doc = " @ref rtBufferGetMipLevelSize2D,"] + #[doc = " @ref rtBufferGetMipLevelSize3D,"] + #[doc = " @ref rtBufferGetSize1D,"] + #[doc = " @ref rtBufferGetSize2D,"] + #[doc = " @ref rtBufferGetSize3D,"] + #[doc = " @ref rtBufferGetSizev"] + #[doc = ""] + pub fn rtBufferGetMipLevelCount( + buffer: RTbuffer, + level: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Maps a buffer object to the host"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferMap returns a pointer, accessible by the host, in \\a *userPointer that"] + #[doc = " contains a mapped copy of the contents of \\a buffer. The memory pointed to by \\a *userPointer"] + #[doc = " can be written to or read from, depending on the type of \\a buffer. For"] + #[doc = " example, this code snippet demonstrates creating and filling an input buffer with"] + #[doc = " floats."] + #[doc = ""] + #[doc = "@code"] + #[doc = " RTbuffer buffer;"] + #[doc = " float* data;"] + #[doc = " rtBufferCreate(context, RT_BUFFER_INPUT, &buffer);"] + #[doc = " rtBufferSetFormat(buffer, RT_FORMAT_FLOAT);"] + #[doc = " rtBufferSetSize1D(buffer, 10);"] + #[doc = " rtBufferMap(buffer, (void*)&data);"] + #[doc = " for(int i = 0; i < 10; ++i)"] + #[doc = " data[i] = 4.f * i;"] + #[doc = " rtBufferUnmap(buffer);"] + #[doc = "@endcode"] + #[doc = " If \\a buffer has already been mapped, returns @ref RT_ERROR_ALREADY_MAPPED."] + #[doc = " If \\a buffer has size zero, the returned pointer is undefined."] + #[doc = ""] + #[doc = " Note that this call does not stop a progressive render if called on a stream buffer."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be mapped"] + #[doc = " @param[out] userPointer Return handle to a user pointer where the buffer will be mapped to"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferMap was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferUnmap,"] + #[doc = " @ref rtBufferMapEx,"] + #[doc = " @ref rtBufferUnmapEx"] + #[doc = ""] + pub fn rtBufferMap(buffer: RTbuffer, userPointer: *mut *mut ::std::os::raw::c_void) + -> RTresult; +} +extern "C" { + #[doc = " @brief Unmaps a buffer's storage from the host"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferUnmap unmaps a buffer from the host after a call to @ref rtBufferMap. @ref rtContextLaunch \"rtContextLaunch\" cannot be called"] + #[doc = " while buffers are still mapped to the host. A call to @ref rtBufferUnmap that does not follow a matching @ref rtBufferMap"] + #[doc = " call will return @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " Note that this call does not stop a progressive render if called with a stream buffer."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to unmap"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferUnmap was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferMap,"] + #[doc = " @ref rtBufferMapEx,"] + #[doc = " @ref rtBufferUnmapEx"] + #[doc = ""] + pub fn rtBufferUnmap(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Maps mipmap level of buffer object to the host"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferMapEx makes the buffer contents available on the host, either by returning a pointer in \\a *optixOwned, or by copying the contents"] + #[doc = " to a memory location pointed to by \\a userOwned. Calling @ref rtBufferMapEx with proper map flags can result in better performance than using @ref rtBufferMap, because"] + #[doc = " fewer synchronization copies are required in certain situations."] + #[doc = " @ref rtBufferMapEx with \\a mapFlags = @ref RT_BUFFER_MAP_READ_WRITE and \\a level = 0 is equivalent to @ref rtBufferMap."] + #[doc = ""] + #[doc = " Note that this call does not stop a progressive render if called on a stream buffer."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be mapped"] + #[doc = " @param[in] mapFlags Map flags, see below"] + #[doc = " @param[in] level The mipmap level to be mapped"] + #[doc = " @param[in] userOwned Not yet supported. Must be NULL"] + #[doc = " @param[out] optixOwned Return handle to a user pointer where the buffer will be mapped to"] + #[doc = ""] + #[doc = " The following flags are supported for mapFlags. They are mutually exclusive:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_MAP_READ"] + #[doc = " - @ref RT_BUFFER_MAP_WRITE"] + #[doc = " - @ref RT_BUFFER_MAP_READ_WRITE"] + #[doc = " - @ref RT_BUFFER_MAP_WRITE_DISCARD"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_ALREADY_MAPPED"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferMapEx was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferMap,"] + #[doc = " @ref rtBufferUnmap,"] + #[doc = " @ref rtBufferUnmapEx"] + #[doc = ""] + pub fn rtBufferMapEx( + buffer: RTbuffer, + mapFlags: ::std::os::raw::c_uint, + level: ::std::os::raw::c_uint, + userOwned: *mut ::std::os::raw::c_void, + optixOwned: *mut *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Unmaps mipmap level storage from the host"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferUnmapEx unmaps buffer level from the host after a call to @ref rtBufferMapEx. @ref rtContextLaunch \"rtContextLaunch\" cannot be called"] + #[doc = " while buffers are still mapped to the host. A call to @ref rtBufferUnmapEx that does not follow a matching @ref rtBufferMapEx"] + #[doc = " call will return @ref RT_ERROR_INVALID_VALUE. @ref rtBufferUnmap is equivalent to @ref rtBufferUnmapEx with \\a level = 0."] + #[doc = ""] + #[doc = " Note that this call does not stop a progressive render if called with a stream buffer."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to unmap"] + #[doc = " @param[in] level The mipmap level to unmap"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferUnmapEx was introduced in OptiX 3.9."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferMap,"] + #[doc = " @ref rtBufferUnmap,"] + #[doc = " @ref rtBufferMapEx"] + #[doc = ""] + pub fn rtBufferUnmapEx(buffer: RTbuffer, level: ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets an id suitable for use with buffers of buffers"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetId returns an ID for the provided buffer. The returned ID is used on"] + #[doc = " the device to reference the buffer. It needs to be copied into a buffer of type @ref"] + #[doc = " RT_FORMAT_BUFFER_ID or used in a @ref rtBufferId object.. If \\a *bufferId is \\a NULL"] + #[doc = " or the \\a buffer is not a valid RTbuffer, returns @ref"] + #[doc = " RT_ERROR_INVALID_VALUE. @ref RT_BUFFER_ID_NULL can be used as a sentinel for a"] + #[doc = " non-existent buffer, since this value will never be returned as a valid buffer id."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its id"] + #[doc = " @param[out] bufferId The returned ID of the buffer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetId was introduced in OptiX 3.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextGetBufferFromId"] + #[doc = ""] + pub fn rtBufferGetId(buffer: RTbuffer, bufferId: *mut ::std::os::raw::c_int) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets an RTbuffer corresponding to the buffer id"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextGetBufferFromId returns a handle to the buffer in \\a *buffer corresponding to"] + #[doc = " the \\a bufferId supplied. If \\a bufferId does not map to a valid buffer handle,"] + #[doc = " \\a *buffer is \\a NULL or if \\a context is invalid, returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] context The context the buffer should be originated from"] + #[doc = " @param[in] bufferId The ID of the buffer to query"] + #[doc = " @param[out] buffer The return handle for the buffer object corresponding to the bufferId"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextGetBufferFromId was introduced in OptiX 3.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferGetId"] + #[doc = ""] + pub fn rtContextGetBufferFromId( + context: RTcontext, + bufferId: ::std::os::raw::c_int, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Check whether stream buffer content has been updated by a Progressive Launch"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Returns whether or not the result of a progressive launch in \\a buffer has been updated"] + #[doc = " since the last time this function was called. A client application should use this call in its"] + #[doc = " main render/display loop to poll for frame refreshes after initiating a progressive launch. If \\a subframeCount and"] + #[doc = " \\a maxSubframes are non-null, they will be filled with the corresponding counters if and"] + #[doc = " only if \\a ready returns 1."] + #[doc = ""] + #[doc = " Note that this call does not stop a progressive render."] + #[doc = ""] + #[doc = " @param[in] buffer The stream buffer to be queried"] + #[doc = " @param[out] ready Ready flag. Will be set to 1 if an update is available, or 0 if no update is available."] + #[doc = " @param[out] subframeCount The number of subframes accumulated in the latest result"] + #[doc = " @param[out] maxSubframes The \\a maxSubframes parameter as specified in the call to @ref rtContextLaunchProgressive2D"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetProgressiveUpdateReady was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextLaunchProgressive2D"] + #[doc = ""] + pub fn rtBufferGetProgressiveUpdateReady( + buffer: RTbuffer, + ready: *mut ::std::os::raw::c_int, + subframeCount: *mut ::std::os::raw::c_uint, + maxSubframes: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Bind a stream buffer to an output buffer source"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Binds an output buffer to a progressive stream. The output buffer thereby becomes the"] + #[doc = " data source for the stream. To form a valid output/stream pair, the stream buffer must be"] + #[doc = " of format @ref RT_FORMAT_UNSIGNED_BYTE4, and the output buffer must be of format @ref RT_FORMAT_FLOAT3 or @ref RT_FORMAT_FLOAT4."] + #[doc = " The use of @ref RT_FORMAT_FLOAT4 is recommended for performance reasons, even if the fourth component is unused."] + #[doc = " The output buffer must be of type @ref RT_BUFFER_OUTPUT; it may not be of type @ref RT_BUFFER_INPUT_OUTPUT."] + #[doc = ""] + #[doc = " @param[in] stream The stream buffer for which the source is to be specified"] + #[doc = " @param[in] source The output buffer to function as the stream's source"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferBindProgressiveStream was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate"] + #[doc = " @ref rtBufferSetAttribute"] + #[doc = " @ref rtBufferGetAttribute"] + #[doc = ""] + pub fn rtBufferBindProgressiveStream(stream: RTbuffer, source: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Set a buffer attribute"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Sets a buffer attribute. Currently, all available attributes refer to stream buffers only,"] + #[doc = " and attempting to set them on a non-stream buffer will generate an error."] + #[doc = ""] + #[doc = " Each attribute can have a different size. The sizes are given in the following list:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_ATTRIBUTE_STREAM_FORMAT strlen(input_string)"] + #[doc = " - @ref RT_BUFFER_ATTRIBUTE_STREAM_BITRATE sizeof(int)"] + #[doc = " - @ref RT_BUFFER_ATTRIBUTE_STREAM_FPS sizeof(int)"] + #[doc = " - @ref RT_BUFFER_ATTRIBUTE_STREAM_GAMMA sizeof(float)"] + #[doc = ""] + #[doc = " @ref RT_BUFFER_ATTRIBUTE_STREAM_FORMAT sets the encoding format used for streams sent over the network, specified as a string."] + #[doc = " The default is \"auto\". Various other common stream and image formats are available (e.g. \"h264\", \"png\"). This"] + #[doc = " attribute has no effect if the progressive API is used locally."] + #[doc = ""] + #[doc = " @ref RT_BUFFER_ATTRIBUTE_STREAM_BITRATE sets the target bitrate for streams sent over the network, if the stream format supports"] + #[doc = " it. The data is specified as a 32-bit integer. The default is 5000000. This attribute has no"] + #[doc = " effect if the progressive API is used locally or if the stream format does not support"] + #[doc = " variable bitrates."] + #[doc = ""] + #[doc = " @ref RT_BUFFER_ATTRIBUTE_STREAM_FPS sets the target update rate per second for streams sent over the network, if the stream"] + #[doc = " format supports it. The data is specified as a 32-bit integer. The default is 30. This"] + #[doc = " attribute has no effect if the progressive API is used locally or if the stream format does"] + #[doc = " not support variable framerates."] + #[doc = ""] + #[doc = " @ref RT_BUFFER_ATTRIBUTE_STREAM_GAMMA sets the gamma value for the built-in tonemapping operator. The data is specified as a"] + #[doc = " 32-bit float, the default is 1.0. Tonemapping is executed before encoding the"] + #[doc = " accumulated output into the stream, i.e. on the server side if remote rendering is used."] + #[doc = " See the section on Buffers below for more details."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer on which to set the attribute"] + #[doc = " @param[in] attrib The attribute to set"] + #[doc = " @param[in] size The size of the attribute value, in bytes"] + #[doc = " @param[in] p Pointer to the attribute value"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetAttribute was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferGetAttribute"] + #[doc = ""] + pub fn rtBufferSetAttribute( + buffer: RTbuffer, + attrib: RTbufferattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query a buffer attribute"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetAttribute is used to query buffer attributes. For a list of available attributes that can be set, please refer to @ref rtBufferSetAttribute."] + #[doc = " The attribute \\a RT_BUFFER_ATTRIBUTE_PAGE_SIZE can only be queried and returns the page size of a demand loaded buffer in bytes. The size of the data returned"] + #[doc = " for this attribute is \\a sizeof(int)."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to query the attribute from"] + #[doc = " @param[in] attrib The attribute to query"] + #[doc = " @param[in] size The size of the attribute value, in bytes. For string attributes, this is the maximum buffer size the returned string will use (including a terminating null character)."] + #[doc = " @param[out] p Pointer to the attribute value to be filled in. Must point to valid memory of at least \\a size bytes."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetAttribute was introduced in OptiX 3.8."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferSetAttribute"] + #[doc = ""] + pub fn rtBufferGetAttribute( + buffer: RTbuffer, + attrib: RTbufferattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new post-processing stage"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageCreateBuiltin creates a new post-processing stage selected from a list of"] + #[doc = " pre-defined post-processing stages. The \\a context specifies the target context, and should be"] + #[doc = " a value returned by @ref rtContextCreate."] + #[doc = " Sets \\a *stage to the handle of a newly created stage within \\a context."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context to which the post-processing stage belongs"] + #[doc = " @param[in] builtinName The name of the built-in stage to instantiate"] + #[doc = " @param[out] stage New post-processing stage handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageCreateBuiltin was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageDestroy,"] + #[doc = " @ref rtPostProcessingStageGetContext,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariableCount"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageCreateBuiltin( + context: RTcontext, + builtinName: *const ::std::os::raw::c_char, + stage: *mut RTpostprocessingstage, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroy a post-processing stage"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageDestroy destroys a post-processing stage from its context and deletes"] + #[doc = " it. The variables built into the stage are destroyed. After the call, \\a stage is no longer a valid handle."] + #[doc = " After a post-processing stage was destroyed all command lists containing that stage are invalidated and"] + #[doc = " can no longer be used."] + #[doc = ""] + #[doc = " @param[in] stage Handle of the post-processing stage to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageDestroy was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = " @ref rtPostProcessingStageGetContext,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariableCount"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageDestroy(stage: RTpostprocessingstage) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a new named variable associated with a PostprocessingStage"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageDeclareVariable declares a new variable associated with a"] + #[doc = " postprocessing stage. \\a stage specifies the post-processing stage, and should be a value"] + #[doc = " returned by @ref rtPostProcessingStageCreateBuiltin. \\a name specifies the name of the variable, and"] + #[doc = " should be a \\a NULL-terminated string. If there is currently no variable associated with \\a"] + #[doc = " stage named \\a name, a new variable named \\a name will be created and associated with"] + #[doc = " \\a stage. After the call, \\a *v will be set to the handle of the newly-created"] + #[doc = " variable. Otherwise, \\a *v will be set to \\a NULL. After declaration, the variable can be"] + #[doc = " queried with @ref rtPostProcessingStageQueryVariable or @ref rtPostProcessingStageGetVariable. A"] + #[doc = " declared variable does not have a type until its value is set with one of the @ref rtVariableSet"] + #[doc = " functions. Once a variable is set, its type cannot be changed anymore."] + #[doc = ""] + #[doc = " @param[in] stage Specifies the associated postprocessing stage"] + #[doc = " @param[in] name The name that identifies the variable"] + #[doc = " @param[out] v Returns a handle to a newly declared variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageDeclareVariable was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref Variables,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageDeclareVariable( + stage: RTpostprocessingstage, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a post-processing stage."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetContext queries a stage for its associated context."] + #[doc = " \\a stage specifies the post-processing stage to query, and should be a value"] + #[doc = " returned by @ref rtPostProcessingStageCreateBuiltin. If both parameters are valid,"] + #[doc = " \\a *context is set to the context associated with \\a stage. Otherwise, the call"] + #[doc = " has no effect and returns @ref RT_ERROR_INVALID_VALUE."] + #[doc = ""] + #[doc = " @param[in] stage Specifies the post-processing stage to query"] + #[doc = " @param[out] context Returns the context associated with the material"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetContext was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = " @ref rtPostProcessingStageDestroy,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariableCount"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageGetContext( + stage: RTpostprocessingstage, + context: *mut RTcontext, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to a named variable of a post-processing stage"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageQueryVariable queries the handle of a post-processing stage's named"] + #[doc = " variable. \\a stage specifies the source post-processing stage, as returned by"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin. \\a name specifies the name of the variable, and should be a"] + #[doc = " \\a NULL -terminated string. If \\a name is the name of a variable attached to \\a stage, the call"] + #[doc = " returns a handle to that variable in \\a *variable, otherwise \\a NULL. Only pre-defined variables of that"] + #[doc = " built-in stage type can be queried. It is not possible to add or remove variables."] + #[doc = ""] + #[doc = " @param[in] stage The post-processing stage to query the variable from"] + #[doc = " @param[in] name The name that identifies the variable to be queried"] + #[doc = " @param[out] variable Returns the named variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageQueryVariable was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = " @ref rtPostProcessingStageDestroy,"] + #[doc = " @ref rtPostProcessingStageGetContext,"] + #[doc = " @ref rtPostProcessingStageGetVariableCount"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageQueryVariable( + stage: RTpostprocessingstage, + name: *const ::std::os::raw::c_char, + variable: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the number of variables pre-defined in a post-processing stage."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetVariableCount returns the number of variables which are pre-defined"] + #[doc = " in a post-processing stage. This can be used to iterate over the variables. Sets \\a *count to the"] + #[doc = " number."] + #[doc = ""] + #[doc = " @param[in] stage The post-processing stage to query the number of variables from"] + #[doc = " @param[out] count Returns the number of pre-defined variables"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetVariableCount was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = " @ref rtPostProcessingStageDestroy,"] + #[doc = " @ref rtPostProcessingStageGetContext,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariable"] + #[doc = ""] + pub fn rtPostProcessingStageGetVariableCount( + stage: RTpostprocessingstage, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns a handle to a variable of a post-processing stage. The variable is defined by index."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetVariable queries the handle of a post-processing stage's variable which"] + #[doc = " is identified by its index . \\a stage specifies the source post-processing stage, as returned by"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin. \\a index specifies the index of the variable, and should be a"] + #[doc = " less than the value return by @ref rtPostProcessingStageGetVariableCount. If \\a index is in the valid"] + #[doc = " range, the call returns a handle to that variable in \\a *variable, otherwise \\a NULL."] + #[doc = ""] + #[doc = " @param[in] stage The post-processing stage to query the variable from"] + #[doc = " @param[in] index The index identifying the variable to be returned"] + #[doc = " @param[out] variable Returns the variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtPostProcessingStageGetVariable was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = " @ref rtPostProcessingStageDestroy,"] + #[doc = " @ref rtPostProcessingStageGetContext,"] + #[doc = " @ref rtPostProcessingStageQueryVariable,"] + #[doc = " @ref rtPostProcessingStageGetVariableCount"] + #[doc = ""] + pub fn rtPostProcessingStageGetVariable( + stage: RTpostprocessingstage, + index: ::std::os::raw::c_uint, + variable: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new command list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListCreate creates a new command list. The \\a context specifies the target"] + #[doc = " context, and should be a value returned by @ref rtContextCreate. The call"] + #[doc = " sets \\a *list to the handle of a newly created list within \\a context."] + #[doc = " Returns @ref RT_ERROR_INVALID_VALUE if \\a list is \\a NULL."] + #[doc = ""] + #[doc = " A command list can be used to assemble a list of different types of commands and execute them"] + #[doc = " later. At this point, commands can be built-in post-processing stages or context launches. Those"] + #[doc = " are appended to the list using @ref rtCommandListAppendPostprocessingStage, and @ref"] + #[doc = " rtCommandListAppendLaunch2D, respectively. Commands will be executed in the order they have been"] + #[doc = " appended to the list. Thus later commands can use the results of earlier commands. Note that"] + #[doc = " all commands added to the created list must be associated with the same \\a context. It is"] + #[doc = " invalid to mix commands from different contexts."] + #[doc = ""] + #[doc = " @param[in] context Specifies the rendering context of the command list"] + #[doc = " @param[out] list New command list handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListCreate was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListCreate(context: RTcontext, list: *mut RTcommandlist) -> RTresult; +} +extern "C" { + #[doc = " @brief Destroy a command list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListDestroy destroys a command list from its context and deletes it. After the"] + #[doc = " call, \\a list is no longer a valid handle. Any stages associated with the command list are not destroyed."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to destroy"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListDestroy was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListDestroy(list: RTcommandlist) -> RTresult; +} +extern "C" { + #[doc = " @brief Append a post-processing stage to the command list \\a list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendPostprocessingStage appends a post-processing stage to the command list"] + #[doc = " \\a list. The command list must have been created from the same context as the the post-processing"] + #[doc = " stage."] + #[doc = " The launchWidth and launchHeight specify the launch dimensions and may be different than the"] + #[doc = " input or output buffers associated with each post-processing stage depending on the requirements"] + #[doc = " of the post-processing stage appended."] + #[doc = " It is invalid to call @ref rtCommandListAppendPostprocessingStage after calling @ref"] + #[doc = " rtCommandListFinalize."] + #[doc = ""] + #[doc = " NOTE: A post-processing stage can be added to multiple command lists or added to the same command"] + #[doc = " list multiple times. Also note that destroying a post-processing stage will invalidate all command"] + #[doc = " lists it was added to."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to append to"] + #[doc = " @param[in] stage The post-processing stage to append to the command list"] + #[doc = " @param[in] launchWidth This is a hint for the width of the launch dimensions to use for this stage."] + #[doc = " The stage can ignore this and use a suitable launch width instead."] + #[doc = " @param[in] launchHeight This is a hint for the height of the launch dimensions to use for this stage."] + #[doc = " The stage can ignore this and use a suitable launch height instead."] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendPostprocessingStage was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = " @ref rtPostProcessingStageCreateBuiltin,"] + #[doc = ""] + pub fn rtCommandListAppendPostprocessingStage( + list: RTcommandlist, + stage: RTpostprocessingstage, + launchWidth: RTsize, + launchHeight: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Append a 1D launch to the command list \\a list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch1D appends a 1D context launch to the command list \\a list. It is"] + #[doc = " invalid to call @ref rtCommandListAppendLaunch1D after calling @ref rtCommandListFinalize."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to append to"] + #[doc = " @param[in] entryPointIndex The initial entry point into the kernel"] + #[doc = " @param[in] launchWidth Width of the computation grid"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch2D was introduced in OptiX 6.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListAppendLaunch3D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListAppendLaunch1D( + list: RTcommandlist, + entryPointIndex: ::std::os::raw::c_uint, + launchWidth: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Append a 2D launch to the command list \\a list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch2D appends a 2D context launch to the command list \\a list. It is"] + #[doc = " invalid to call @ref rtCommandListAppendLaunch2D after calling @ref rtCommandListFinalize."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to append to"] + #[doc = " @param[in] entryPointIndex The initial entry point into the kernel"] + #[doc = " @param[in] launchWidth Width of the computation grid"] + #[doc = " @param[in] launchHeight Height of the computation grid"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch2D was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch1D,"] + #[doc = " @ref rtCommandListAppendLaunch3D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListAppendLaunch2D( + list: RTcommandlist, + entryPointIndex: ::std::os::raw::c_uint, + launchWidth: RTsize, + launchHeight: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Append a 3D launch to the command list \\a list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch3D appends a 3D context launch to the command list \\a list. It is"] + #[doc = " invalid to call @ref rtCommandListAppendLaunch3D after calling @ref rtCommandListFinalize."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to append to"] + #[doc = " @param[in] entryPointIndex The initial entry point into the kernel"] + #[doc = " @param[in] launchWidth Width of the computation grid"] + #[doc = " @param[in] launchHeight Height of the computation grid"] + #[doc = " @param[in] launchDepth Depth of the computation grid"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListAppendLaunch2D was introduced in OptiX 6.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch1D,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListAppendLaunch3D( + list: RTcommandlist, + entryPointIndex: ::std::os::raw::c_uint, + launchWidth: RTsize, + launchHeight: RTsize, + launchDepth: RTsize, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the devices to use for this command list."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListSetDevices specifies a list of hardware devices to use for this command list. This"] + #[doc = " must be a subset of the currently active devices, see @ref rtContextSetDevices. If not set then all the"] + #[doc = " active devices will be used."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to set devices for"] + #[doc = " @param[in] count The number of devices in the list"] + #[doc = " @param[in] devices The list of devices"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextSetDevices,"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListSetDevices( + list: RTcommandlist, + count: ::std::os::raw::c_uint, + devices: *const ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Retrieve a list of hardware devices being used by the command list."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListGetDevices retrieves a list of hardware devices used by the command list."] + #[doc = " Note that the device numbers are OptiX device ordinals, which may not be the same as CUDA device ordinals."] + #[doc = " Use @ref rtDeviceGetAttribute with @ref RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL to query the CUDA device"] + #[doc = " corresponding to a particular OptiX device."] + #[doc = ""] + #[doc = " Note that if the list of set devices is empty then all active devices will be used."] + #[doc = ""] + #[doc = " @param[in] list The command list to which the hardware list is applied"] + #[doc = " @param[out] devices Return parameter for the list of devices. The memory must be able to hold entries"] + #[doc = " numbering least the number of devices as returned by @ref rtCommandListGetDeviceCount"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListSetDevices,"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListGetDevices( + list: RTcommandlist, + devices: *mut ::std::os::raw::c_int, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Query the number of devices currently being used by the command list."] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListGetDeviceCount queries the number of devices currently being used."] + #[doc = ""] + #[doc = " @param[in] list The command list containing the devices"] + #[doc = " @param[out] count Return parameter for the device count"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListSetDevices,"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListGetDeviceCount( + list: RTcommandlist, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Finalize the command list. This must be done before executing the command list."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListFinalize finalizes the command list. This will do all work necessary to"] + #[doc = " prepare the command list for execution. Specifically it will do all work which can be shared"] + #[doc = " between subsequent calls to @ref rtCommandListExecute."] + #[doc = " It is invalid to call @ref rtCommandListExecute before calling @ref rtCommandListFinalize. It is"] + #[doc = " invalid to call @ref rtCommandListAppendPostprocessingStage or"] + #[doc = " @ref rtCommandListAppendLaunch2D after calling finalize and will result in an error. Also"] + #[doc = " @ref rtCommandListFinalize can only be called once on each command list."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to finalize"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListFinalize was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListExecute"] + #[doc = ""] + pub fn rtCommandListFinalize(list: RTcommandlist) -> RTresult; +} +extern "C" { + #[doc = " @brief Execute the command list."] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListExecute executes the command list. All added commands will be executed in the"] + #[doc = " order in which they were added. Commands can access the results of earlier executed commands."] + #[doc = " This must be called after calling @ref rtCommandListFinalize, otherwise an error will be returned"] + #[doc = " and the command list is not executed."] + #[doc = " @ref rtCommandListExecute can be called multiple times, but only one call may be active at the"] + #[doc = " same time. Overlapping calls from multiple threads will result in undefined behavior."] + #[doc = ""] + #[doc = " @param[in] list Handle of the command list to execute"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListExecute was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListCreate,"] + #[doc = " @ref rtCommandListDestroy,"] + #[doc = " @ref rtCommandListAppendPostprocessingStage,"] + #[doc = " @ref rtCommandListAppendLaunch2D,"] + #[doc = " @ref rtCommandListFinalize,"] + #[doc = ""] + pub fn rtCommandListExecute(list: RTcommandlist) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the context associated with a command list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListGetContext queries the context associated with a command list. The"] + #[doc = " target command list is specified by \\a list. The context of the command list is"] + #[doc = " returned to \\a *context if the pointer \\a context is not \\a NULL. If \\a list is"] + #[doc = " not a valid command list, \\a *context is set to \\a NULL and @ref RT_ERROR_INVALID_VALUE is"] + #[doc = " returned."] + #[doc = ""] + #[doc = " @param[in] list Specifies the command list to be queried"] + #[doc = " @param[out] context Returns the context associated with the command list"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListGetContext was introduced in OptiX 5.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtContextDeclareVariable"] + #[doc = ""] + pub fn rtCommandListGetContext(list: RTcommandlist, context: *mut RTcontext) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the attribute program on a GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetAttributeProgram sets for \\a geometrytriangles the \\a"] + #[doc = " program that performs attribute computation. RTprograms can be either generated with"] + #[doc = " @ref rtProgramCreateFromPTXFile or @ref rtProgramCreateFromPTXString. An attribute"] + #[doc = " program is optional. If no attribute program is specified, a default attribute"] + #[doc = " program will be provided. Attributes are computed after intersection and before any-"] + #[doc = " hit or closest-hit programs that require those attributes. No assumptions about the"] + #[doc = " precise invocation time should be made."] + #[doc = " The default attribute program provides the attribute rtTriangleBarycentrics of type float2."] + #[doc = ""] + #[doc = " Names are case sensitive and types must match. To use the attribute, declare the following"] + #[doc = " rtDeclareVariable( float2, barycentrics, attribute rtTriangleBarycentrics, );"] + #[doc = ""] + #[doc = " If you provide an attribute program, the following device side functions will be available:"] + #[doc = " float2 rtGetTriangleBarycentrics();"] + #[doc = " unsigned int rtGetPrimitiveIndex();"] + #[doc = " bool rtIsTriangleHit();"] + #[doc = " bool rtIsTriangleHitFrontFace();"] + #[doc = " bool rtIsTriangleHitBackFace();"] + #[doc = ""] + #[doc = " besides other semantics such as the ray time for motion blur."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles The geometrytriangles node for which to set the attribute program"] + #[doc = " @param[in] program A handle to the attribute program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesSetAttributeProgram was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetAttributeProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString,"] + #[doc = " @ref rtGetTriangleBarycentrics,"] + #[doc = ""] + pub fn rtGeometryTrianglesSetAttributeProgram( + geometrytriangles: RTgeometrytriangles, + program: RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the attribute program of a GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetAttributeProgram gets the attribute \\a program of a given"] + #[doc = " \\a geometrytriangles object. If no program has been set, 0 is returned."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles The geometrytriangles node for which to set the attribute program"] + #[doc = " @param[out] program A pointer to a handle to the attribute program"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetAttributeProgram was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesDeclareVariable,"] + #[doc = " @ref rtGeometryTrianglesSetAttributeProgram,"] + #[doc = " @ref rtProgramCreateFromPTXFile,"] + #[doc = " @ref rtProgramCreateFromPTXString"] + #[doc = ""] + pub fn rtGeometryTrianglesGetAttributeProgram( + geometrytriangles: RTgeometrytriangles, + program: *mut RTprogram, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a geometry variable for a GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesDeclareVariable declares a \\a variable attribute of a \\a geometrytriangles object with"] + #[doc = " a specified \\a name."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles A geometry node"] + #[doc = " @param[in] name The name of the variable"] + #[doc = " @param[out] v A pointer to a handle to the variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesDeclareVariable was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariableCount,"] + #[doc = " @ref rtGeometryTrianglesQueryVariable,"] + #[doc = " @ref rtGeometryTrianglesRemoveVariable"] + #[doc = ""] + pub fn rtGeometryTrianglesDeclareVariable( + geometrytriangles: RTgeometrytriangles, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Queries a variable attached to a GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesQueryVariable gets a variable with a given \\a name from"] + #[doc = " a \\a geometrytriangles object."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles A geometrytriangles object"] + #[doc = " @param[in] name Thee name of the variable"] + #[doc = " @param[out] v A pointer to a handle to the variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesQueryVariable was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesGetVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariableCount,"] + #[doc = " @ref rtGeometryTrianglesQueryVariable,"] + #[doc = " @ref rtGeometryTrianglesRemoveVariable"] + #[doc = ""] + pub fn rtGeometryTrianglesQueryVariable( + geometrytriangles: RTgeometrytriangles, + name: *const ::std::os::raw::c_char, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Removes a variable from GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesRemoveVariable removes a variable from"] + #[doc = " a \\a geometrytriangles object."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles A geometrytriangles object"] + #[doc = " @param[in] v A pointer to a handle to the variable"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesRemoveVariable was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesDeclareVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariableCount,"] + #[doc = " @ref rtGeometryTrianglesQueryVariable"] + #[doc = ""] + pub fn rtGeometryTrianglesRemoveVariable( + geometrytriangles: RTgeometrytriangles, + v: RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Get the number of variables attached to a GeometryTriangles object"] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetVariableCount returns a \\a count of the number"] + #[doc = " of variables attached to a \\a geometrytriangles object."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles A geometrytriangles node"] + #[doc = " @param[out] count A pointer to an unsigned int"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetVariableCount was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesDeclareVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariable,"] + #[doc = " @ref rtGeometryTrianglesQueryVariable,"] + #[doc = " @ref rtGeometryTrianglesRemoveVariable"] + #[doc = ""] + pub fn rtGeometryTrianglesGetVariableCount( + geometrytriangles: RTgeometrytriangles, + count: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Get a variable attached to a GeometryTriangles object at a specified index."] + #[doc = ""] + #[doc = " @ingroup GeometryTriangles"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetVariable returns the variable attached at a given"] + #[doc = " index to the specified GeometryTriangles object."] + #[doc = ""] + #[doc = " @param[in] geometrytriangles A geometry node"] + #[doc = " @param[in] index The index of the variable"] + #[doc = " @param[out] v A pointer to a variable handle"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtGeometryTrianglesGetVariable was introduced in OptiX 6.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtGeometryTrianglesDeclareVariable,"] + #[doc = " @ref rtGeometryTrianglesGetVariableCount,"] + #[doc = " @ref rtGeometryTrianglesQueryVariable,"] + #[doc = " @ref rtGeometryTrianglesRemoveVariable"] + #[doc = ""] + pub fn rtGeometryTrianglesGetVariable( + geometrytriangles: RTgeometrytriangles, + index: ::std::os::raw::c_uint, + v: *mut RTvariable, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object that will later rely on user-side CUDA allocation"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Deprecated in OptiX 4.0. Now forwards to @ref rtBufferCreate."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateForCUDA was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferSetDevicePointer,"] + #[doc = " @ref rtBufferMarkDirty,"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateForCUDA( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the pointer to the buffer's data on the given device"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetDevicePointer returns the pointer to the data of \\a buffer on device \\a optix_device_ordinal in **\\a device_pointer."] + #[doc = ""] + #[doc = " If @ref rtBufferGetDevicePointer has been called for a single device for a given buffer,"] + #[doc = " the user can change the buffer's content on that device through the pointer. OptiX must then synchronize the new buffer contents to all devices."] + #[doc = " These synchronization copies occur at every @ref rtContextLaunch \"rtContextLaunch\", unless the buffer is created with @ref RT_BUFFER_COPY_ON_DIRTY."] + #[doc = " In this case, @ref rtBufferMarkDirty can be used to notify OptiX that the buffer has been dirtied and must be synchronized."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its device pointer"] + #[doc = " @param[in] optix_device_ordinal The number assigned by OptiX to the device"] + #[doc = " @param[out] device_pointer The return handle to the buffer's device pointer"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetDevicePointer was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferMarkDirty,"] + #[doc = " @ref rtBufferSetDevicePointer"] + #[doc = ""] + pub fn rtBufferGetDevicePointer( + buffer: RTbuffer, + optix_device_ordinal: ::std::os::raw::c_int, + device_pointer: *mut *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets a buffer as dirty"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " If @ref rtBufferSetDevicePointer or @ref rtBufferGetDevicePointer have been called for a single device for a given buffer,"] + #[doc = " the user can change the buffer's content on that device through the pointer. OptiX must then synchronize the new buffer contents to all devices."] + #[doc = " These synchronization copies occur at every @ref rtContextLaunch, unless the buffer is declared with @ref RT_BUFFER_COPY_ON_DIRTY."] + #[doc = " In this case, @ref rtBufferMarkDirty can be used to notify OptiX that the buffer has been dirtied and must be synchronized."] + #[doc = ""] + #[doc = " Note that RT_BUFFER_COPY_ON_DIRTY currently only applies to CUDA interop buffers (buffers for which the application has a device pointer)."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be marked dirty"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferMarkDirty was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferGetDevicePointer,"] + #[doc = " @ref rtBufferSetDevicePointer,"] + #[doc = " @ref RT_BUFFER_COPY_ON_DIRTY"] + #[doc = ""] + pub fn rtBufferMarkDirty(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets the pointer to the buffer's data on the given device"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferSetDevicePointer sets the pointer to the data of \\a buffer on device \\a optix_device_ordinal to \\a device_pointer."] + #[doc = ""] + #[doc = " If @ref rtBufferSetDevicePointer has been called for a single device for a given buffer,"] + #[doc = " the user can change the buffer's content on that device through the pointer. OptiX must then synchronize the new buffer contents to all devices."] + #[doc = " These synchronization copies occur at every @ref rtContextLaunch \"rtContextLaunch\", unless the buffer is declared with @ref RT_BUFFER_COPY_ON_DIRTY."] + #[doc = " In this case, @ref rtBufferMarkDirty can be used to notify OptiX that the buffer has been dirtied and must be synchronized."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer for which the device pointer is to be set"] + #[doc = " @param[in] optix_device_ordinal The number assigned by OptiX to the device"] + #[doc = " @param[in] device_pointer The pointer to the data on the specified device"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferSetDevicePointer was introduced in OptiX 3.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferMarkDirty,"] + #[doc = " @ref rtBufferGetDevicePointer"] + #[doc = ""] + pub fn rtBufferSetDevicePointer( + buffer: RTbuffer, + optix_device_ordinal: ::std::os::raw::c_int, + device_pointer: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Sets a CUDA synchronization stream for the command list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListSetCudaStream sets a CUDA synchronization stream for the command list. The"] + #[doc = " command list guarantees that all work on the synchronization stream finishes before any launches"] + #[doc = " of the command list executes on the GPU. It will also have the synchronization stream wait for"] + #[doc = " those launches to complete using CUDA events. This means cuda interop, such as memory copying"] + #[doc = " or kernel execution, can be done in a safe way both before and after executing a command list."] + #[doc = " If CUDA interop is made using streams other than the synchronization stream then CUDA events"] + #[doc = " must be used to make sure that the synchronization stream waits for all work done by other"] + #[doc = " streams, and also that the other streams wait for the synchronization stream after executing"] + #[doc = " the command list."] + #[doc = ""] + #[doc = " Note that the synchronization stream can be created on any active device, there is no need to"] + #[doc = " have one per device."] + #[doc = ""] + #[doc = " @param[in] list The command list buffer for which the stream is to be set"] + #[doc = " @param[in] stream The CUDA stream to set"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListSetCudaStream was introduced in OptiX 6.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListExecute"] + #[doc = " @ref rtCommandListGetCudaStream"] + #[doc = ""] + pub fn rtCommandListSetCudaStream( + list: RTcommandlist, + stream: *mut ::std::os::raw::c_void, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the CUDA synchronization stream set for the command list"] + #[doc = ""] + #[doc = " @ingroup CommandList"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtCommandListGetCudaStream gets the CUDA synchronization stream set for the command list."] + #[doc = ""] + #[doc = " @param[in] list The command list buffer for which to get the stream"] + #[doc = " @param[out] stream Set to the CUDA stream of the command list"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtCommandListGetCudaStream was introduced in OptiX 6.1."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtCommandListSetCommandList"] + #[doc = ""] + pub fn rtCommandListGetCudaStream( + list: RTcommandlist, + stream: *mut *mut ::std::os::raw::c_void, + ) -> RTresult; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct IDirect3DDevice9 { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct IDirect3DResource9 { + _unused: [u8; 0], +} +extern "C" { + #[doc = " @brief Binds a D3D9 device to a context and enables interop"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D9Device binds \\a device to \\a context and enables D3D9 interop capabilities in \\a context. This"] + #[doc = " function must be executed once for \\a context before any call to @ref rtBufferCreateFromD3D9Resource or @ref rtTextureSamplerCreateFromD3D9Resource can"] + #[doc = " take place. A context can only be bound to one device. Once \\a device is bound to \\a context, the binding is immutable and remains upon destruction of \\a context."] + #[doc = ""] + #[doc = " @param[in] context The context to bind the device with"] + #[doc = " @param[in] device The D3D9 device to be used for interop with the associated context"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D9Device was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D9Resource,"] + #[doc = " @ref rtTextureSamplerCreateFromD3D9Resource"] + #[doc = ""] + pub fn rtContextSetD3D9Device(context: RTcontext, device: *mut IDirect3DDevice9) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the OptiX device number associated with the specified name of a D3D9 adapter"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D9Device returns in \\a device the OptiX device ID of the adapter represented by \\a pszAdapterName."] + #[doc = " \\a pszAdapterName is the DeviceName field in the \\a D3DADAPTER_IDENTIFIER9 struct. In combination with @ref rtContextSetDevices,"] + #[doc = " this function can be used to restrict OptiX to use only one device. The same device the D3D9 commands will be sent to."] + #[doc = ""] + #[doc = " This function is only supported on Windows platforms."] + #[doc = ""] + #[doc = " @param[in] device A handle to the memory location where the OptiX device ordinal associated with \\a pszAdapterName will be stored"] + #[doc = " @param[out] pszAdapterName The name of an adapter as can be found in the DeviceName field in the \\a D3DADAPTER_IDENTIFIER9 struct"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D9Device was introduced in OptiX 2.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount"] + #[doc = ""] + pub fn rtDeviceGetD3D9Device( + device: *mut ::std::os::raw::c_int, + pszAdapterName: *const ::std::os::raw::c_char, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object from a D3D9 resource"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D9Resource allocates and returns a handle to a new buffer object in \\a *buffer associated with"] + #[doc = " \\a context. If the allocated size of the D3D resource is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported D3D9 buffer types are:"] + #[doc = ""] + #[doc = " - IDirect3DVertexBuffer9"] + #[doc = " - IDirect3DIndexBuffer9"] + #[doc = ""] + #[doc = " These buffers can be used to share data with D3D9; changes of the content in \\a buffer, either done by D3D9 or OptiX,"] + #[doc = " will be reflected automatically in both APIs. If the size, or format, of a D3D9 buffer is changed, appropriate OptiX"] + #[doc = " calls have to be used to update \\a buffer accordingly. OptiX keeps only a reference to D3D9 data, when \\a buffer is"] + #[doc = " destroyed, the state of \\a resource is unaltered."] + #[doc = ""] + #[doc = " The \\a type of this buffer is specified by one of the following values in \\a bufferdesc:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_INPUT"] + #[doc = " - @ref RT_BUFFER_OUTPUT"] + #[doc = " - @ref RT_BUFFER_INPUT_OUTPUT"] + #[doc = ""] + #[doc = " The type values are used to specify the direction of data flow from the host to the OptiX devices."] + #[doc = " @ref RT_BUFFER_INPUT specifies that the host may only write to the buffer and the device may only read from the buffer."] + #[doc = " @ref RT_BUFFER_OUTPUT specifies the opposite, read only access on the host and write only access on the device."] + #[doc = " Devices and the host may read and write from buffers of type @ref RT_BUFFER_INPUT_OUTPUT. Reading or writing to"] + #[doc = " a buffer of the incorrect type (e.g., the host writing to a buffer of type @ref RT_BUFFER_OUTPUT) is undefined."] + #[doc = ""] + #[doc = " Flags can be used to optimize data transfers between the host and it's devices. Currently no \\a flags are supported for"] + #[doc = " interop buffers."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[in] resource The D3D9 resource handle for use in OptiX"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D9Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateFromD3D9Resource( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + resource: *mut IDirect3DResource9, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new texture sampler object from a D3D9 resource"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D9Resource allocates and returns a"] + #[doc = " handle to a new texture sampler object in \\a *texturesampler"] + #[doc = " associated with \\a context. If the allocated size of the D3D resource"] + #[doc = " is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported"] + #[doc = " D3D9 texture types are:"] + #[doc = ""] + #[doc = " - IDirect3DSurface9"] + #[doc = ""] + #[doc = " - (derivatives of) IDirect3DBaseTexture9"] + #[doc = ""] + #[doc = " These texture samplers can be used to share data with D3D9; changes of"] + #[doc = " the content and size of \\a texturesampler done by D3D9 will be"] + #[doc = " reflected automatically in OptiX. Currently texture sampler data are"] + #[doc = " read only in OptiX programs. OptiX keeps only a reference to"] + #[doc = " D3D9 data, when \\a texturesampler is destroyed, the state of the"] + #[doc = " \\a resource is unaltered."] + #[doc = ""] + #[doc = " The array size and number of mipmap levels can't be changed for"] + #[doc = " texture samplers that encapsulate a D3D9 resource. Furthermore no"] + #[doc = " buffer objects can be queried. Please refer to the @ref InteropTypes for a"] + #[doc = " complete list of supported texture formats."] + #[doc = ""] + #[doc = " @param[in] context The context to create the texture sampler in"] + #[doc = " @param[in] resource The D3D9 resource handle for use in OptiX"] + #[doc = " @param[out] textureSampler The return handle for the texture sampler object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D9Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate,"] + #[doc = " @ref rtTextureSamplerDestroy"] + #[doc = ""] + pub fn rtTextureSamplerCreateFromD3D9Resource( + context: RTcontext, + resource: *mut IDirect3DResource9, + textureSampler: *mut RTtexturesampler, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D9 resource associated with this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D9Resource stores the D3D9 resource pointer in \\a **resource if \\a buffer was created with"] + #[doc = " @ref rtBufferCreateFromD3D9Resource. If \\a buffer was not created from a D3D9 resource \\a **resource will be \\a 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its D3D9 resource"] + #[doc = " @param[out] resource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D9Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D9Resource"] + #[doc = ""] + pub fn rtBufferGetD3D9Resource( + buffer: RTbuffer, + resource: *mut *mut IDirect3DResource9, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D9 resource associated with this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D9Resource stores the D3D9 resource pointer in \\a **resource if \\a sampler was created with"] + #[doc = " @ref rtTextureSamplerGetD3D9Resource. If \\a sampler was not created from a D3D9 resource \\a resource will be 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned"] + #[doc = ""] + #[doc = " @param[in] textureSampler The texture sampler to be queried for its D3D9 resource"] + #[doc = " @param[out] pResource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D9Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D9Resource"] + #[doc = ""] + pub fn rtTextureSamplerGetD3D9Resource( + textureSampler: RTtexturesampler, + pResource: *mut *mut IDirect3DResource9, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D9 buffer as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in an unregistered state can be registered to OptiX again via @ref rtBufferD3D9Register. Once registered,"] + #[doc = " properties like the size of the original D3D9 resource cannot be modified anymore. Calls to the corresponding D3D9 functions"] + #[doc = " will return with an error code. However, the data of the D3D9 resource can still be read and written by the appropriate D3D9 commands."] + #[doc = " When a buffer is already in a registered state @ref rtBufferD3D9Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED. A resource"] + #[doc = " must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D9Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D9Register(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D9 buffer as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in a registered state can be unregistered via @ref rtBufferD3D9Register. Once unregistered,"] + #[doc = " properties like the size of the original D3D9 resource can be changed. As long as a resource is unregistered,"] + #[doc = " OptiX will not be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already"] + #[doc = " in an unregistered state @ref rtBufferD3D9Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D9Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D9Unregister(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D9 texture as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in an unregistered state can be registered to OptiX again via @ref rtTextureSamplerD3D9Register."] + #[doc = " Once registered, properties like the size of the original D3D9 resource cannot be modified anymore. Calls to the corresponding"] + #[doc = " D3D9 functions will return with an error code. However, the data of the D3D9 resource can still be read and written by the appropriate"] + #[doc = " D3D9 commands. When a texture sampler is already in a registered state @ref rtTextureSamplerD3D9Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED."] + #[doc = " A resource must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D9Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D9Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D9Register(textureSampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D9 texture as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in a registered state can be unregistered via @ref rtTextureSamplerD3D9Unregister. Once unregistered,"] + #[doc = " properties like the size of the original D3D9 resource can be changed. As long as a resource is unregistered, OptiX will not"] + #[doc = " be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already in an unregistered state"] + #[doc = " @ref rtBufferD3D9Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D9Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D9Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D9Unregister(textureSampler: RTtexturesampler) -> RTresult; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct IDXGIAdapter { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D10Device { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D10Resource { + _unused: [u8; 0], +} +extern "C" { + #[doc = " @brief Binds a D3D10 device to a context and enables interop"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D10Device binds \\a device to \\a context and enables D3D10 interop capabilities in \\a context. This"] + #[doc = " function must be executed once for \\a context before any call to @ref rtBufferCreateFromD3D10Resource or @ref rtTextureSamplerCreateFromD3D10Resource can"] + #[doc = " take place. A context can only be bound to one device. Once \\a device is bound to \\a context, the binding is immutable and remains upon destruction of \\a context."] + #[doc = ""] + #[doc = " @param[in] context The context to bind the device with"] + #[doc = " @param[in] device The D3D10 device to be used for interop with the associated context"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D10Device was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D10Resource,"] + #[doc = " @ref rtTextureSamplerCreateFromD3D10Resource"] + #[doc = ""] + pub fn rtContextSetD3D10Device(context: RTcontext, device: *mut ID3D10Device) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the OptiX device number associated with the pointer to a D3D10 adapter"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D10Device returns in \\a device the OptiX device ID of the adapter represented by \\a d3d10Device."] + #[doc = " \\a d3d10Device is a pointer returned from \\a D3D10CreateDeviceAndSwapChain. In combination with @ref rtContextSetDevices,"] + #[doc = " this function can be used to restrict OptiX to use only one device. The same device the D3D10 commands will be sent to."] + #[doc = ""] + #[doc = " This function is only supported on Windows platforms."] + #[doc = ""] + #[doc = " @param[in] device A handle to the memory location where the OptiX device ordinal associated with \\a d3d10Device will be stored"] + #[doc = " @param[out] pAdapter A pointer to an \\a ID3D10Device as returned from \\a D3D10CreateDeviceAndSwapChain"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D10Device was introduced in OptiX 2.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount"] + #[doc = ""] + pub fn rtDeviceGetD3D10Device( + device: *mut ::std::os::raw::c_int, + pAdapter: *mut IDXGIAdapter, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object from a D3D10 resource"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D10Resource allocates and returns a handle to a new buffer object in \\a *buffer associated with"] + #[doc = " \\a context. If the allocated size of the D3D resource is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported D3D10 buffer types are:"] + #[doc = ""] + #[doc = " - ID3D10Buffer"] + #[doc = ""] + #[doc = " These buffers can be used to share data with D3D10; changes of the content in \\a buffer, either done by D3D10 or OptiX,"] + #[doc = " will be reflected automatically in both APIs. If the size, or format, of a D3D10 buffer is changed, appropriate OptiX"] + #[doc = " calls have to be used to update \\a buffer accordingly. OptiX keeps only a reference to D3D10 data, when \\a buffer is"] + #[doc = " destroyed, the state of \\a resource is unaltered."] + #[doc = ""] + #[doc = " The \\a type of this buffer is specified by one of the following values in \\a bufferdesc:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_INPUT"] + #[doc = " - @ref RT_BUFFER_OUTPUT"] + #[doc = " - @ref RT_BUFFER_INPUT_OUTPUT"] + #[doc = ""] + #[doc = " The type values are used to specify the direction of data flow from the host to the OptiX devices."] + #[doc = " @ref RT_BUFFER_INPUT specifies that the host may only write to the buffer and the device may only read from the buffer."] + #[doc = " @ref RT_BUFFER_OUTPUT specifies the opposite, read only access on the host and write only access on the device."] + #[doc = " Devices and the host may read and write from buffers of type @ref RT_BUFFER_INPUT_OUTPUT. Reading or writing to"] + #[doc = " a buffer of the incorrect type (e.g., the host writing to a buffer of type @ref RT_BUFFER_OUTPUT) is undefined."] + #[doc = ""] + #[doc = " Flags can be used to optimize data transfers between the host and it's devices. Currently no \\a flags are supported for"] + #[doc = " interop buffers."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[in] resource The D3D10 resource handle for use in OptiX"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D10Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateFromD3D10Resource( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + resource: *mut ID3D10Resource, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new texture sampler object from a D3D10 resource"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D10Resource allocates and returns a"] + #[doc = " handle to a new texture sampler object in \\a *texturesampler"] + #[doc = " associated with \\a context. If the allocated size of the D3D resource"] + #[doc = " is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported"] + #[doc = " D3D10 texture types are:"] + #[doc = ""] + #[doc = " - ID3D10Texture1D"] + #[doc = " - ID3D10Texture2D"] + #[doc = " - ID3D10Texture3D"] + #[doc = ""] + #[doc = " These texture samplers can be used to share data with D3D10; changes of"] + #[doc = " the content and size of \\a texturesampler done by D3D10 will be"] + #[doc = " reflected automatically in OptiX. Currently texture sampler data are"] + #[doc = " read only in OptiX programs. OptiX keeps only a reference to"] + #[doc = " D3D10 data, when \\a texturesampler is destroyed, the state of the"] + #[doc = " \\a resource is unaltered."] + #[doc = ""] + #[doc = " The array size and number of mipmap levels can't be changed for"] + #[doc = " texture samplers that encapsulate a D3D10 resource. Furthermore no"] + #[doc = " buffer objects can be queried. Please refer to the @ref InteropTypes for a"] + #[doc = " complete list of supported texture formats."] + #[doc = ""] + #[doc = " @param[in] context The context to create the texture sampler in"] + #[doc = " @param[in] resource The D3D10 resource handle for use in OptiX"] + #[doc = " @param[out] textureSampler The return handle for the texture sampler object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D10Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate,"] + #[doc = " @ref rtTextureSamplerDestroy"] + #[doc = ""] + pub fn rtTextureSamplerCreateFromD3D10Resource( + context: RTcontext, + resource: *mut ID3D10Resource, + textureSampler: *mut RTtexturesampler, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D10 resource associated with this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D10Resource stores the D3D10 resource pointer in \\a **resource if \\a buffer was created with"] + #[doc = " @ref rtBufferCreateFromD3D10Resource. If \\a buffer was not created from a D3D10 resource \\a **resource will be \\a 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its D3D10 resource"] + #[doc = " @param[out] resource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D10Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D10Resource"] + #[doc = ""] + pub fn rtBufferGetD3D10Resource( + buffer: RTbuffer, + resource: *mut *mut ID3D10Resource, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D10 resource associated with this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D10Resource stores the D3D10 resource pointer in \\a **resource if \\a sampler was created with"] + #[doc = " @ref rtTextureSamplerGetD3D10Resource. If \\a sampler was not created from a D3D10 resource \\a resource will be 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned"] + #[doc = ""] + #[doc = " @param[in] textureSampler The texture sampler to be queried for its D3D10 resource"] + #[doc = " @param[out] resource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D10Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D10Resource"] + #[doc = ""] + pub fn rtTextureSamplerGetD3D10Resource( + textureSampler: RTtexturesampler, + resource: *mut *mut ID3D10Resource, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D10 buffer as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in an unregistered state can be registered to OptiX again via @ref rtBufferD3D10Register. Once registered,"] + #[doc = " properties like the size of the original D3D10 resource cannot be modified anymore. Calls to the corresponding D3D10 functions"] + #[doc = " will return with an error code. However, the data of the D3D10 resource can still be read and written by the appropriate D3D10 commands."] + #[doc = " When a buffer is already in a registered state @ref rtBufferD3D10Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED. A resource"] + #[doc = " must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D10Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D10Register(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D10 buffer as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in a registered state can be unregistered via @ref rtBufferD3D10Register. Once unregistered,"] + #[doc = " properties like the size of the original D3D10 resource can be changed. As long as a resource is unregistered,"] + #[doc = " OptiX will not be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already"] + #[doc = " in an unregistered state @ref rtBufferD3D10Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D10Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D10Unregister(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D10 texture as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in an unregistered state can be registered to OptiX again via @ref rtTextureSamplerD3D10Register."] + #[doc = " Once registered, properties like the size of the original D3D10 resource cannot be modified anymore. Calls to the corresponding"] + #[doc = " D3D10 functions will return with an error code. However, the data of the D3D10 resource can still be read and written by the appropriate"] + #[doc = " D3D10 commands. When a texture sampler is already in a registered state @ref rtTextureSamplerD3D10Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED."] + #[doc = " A resource must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D10Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D10Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D10Register(textureSampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D10 texture as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in a registered state can be unregistered via @ref rtTextureSamplerD3D10Unregister. Once unregistered,"] + #[doc = " properties like the size of the original D3D10 resource can be changed. As long as a resource is unregistered, OptiX will not"] + #[doc = " be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already in an unregistered state"] + #[doc = " @ref rtBufferD3D10Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D10Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D10Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D10Unregister(textureSampler: RTtexturesampler) -> RTresult; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Device { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Resource { + _unused: [u8; 0], +} +extern "C" { + #[doc = " @brief Binds a D3D11 device to a context and enables interop"] + #[doc = ""] + #[doc = " @ingroup Context"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D11Device binds \\a device to \\a context and enables D3D11 interop capabilities in \\a context. This"] + #[doc = " function must be executed once for \\a context before any call to @ref rtBufferCreateFromD3D11Resource or @ref rtTextureSamplerCreateFromD3D11Resource can"] + #[doc = " take place. A context can only be bound to one device. Once \\a device is bound to \\a context, the binding is immutable and remains upon destruction of \\a context."] + #[doc = ""] + #[doc = " @param[in] context The context to bind the device with"] + #[doc = " @param[in] device The D3D11 device to be used for interop with the associated context"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtContextSetD3D11Device was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource,"] + #[doc = " @ref rtTextureSamplerCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtContextSetD3D11Device(context: RTcontext, device: *mut ID3D11Device) -> RTresult; +} +extern "C" { + #[doc = " @brief Returns the OptiX device number associated with the pointer to a D3D11 adapter"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D11Device returns in \\a device the OptiX device ID of the adapter represented by \\a D3D11Device."] + #[doc = " \\a D3D11Device is a pointer returned from \\a D3D11CreateDeviceAndSwapChain. In combination with @ref rtContextSetDevices,"] + #[doc = " this function can be used to restrict OptiX to use only one device. The same device the D3D11 commands will be sent to."] + #[doc = ""] + #[doc = " This function is only supported on Windows platforms."] + #[doc = ""] + #[doc = " @param[in] device A handle to the memory location where the OptiX device ordinal associated with \\a D3D11Device will be stored"] + #[doc = " @param[in] pAdapter A pointer to an \\a ID3D11Device as returned from \\a D3D11CreateDeviceAndSwapChain"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetD3D11Device was introduced in OptiX 2.5."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount"] + #[doc = ""] + pub fn rtDeviceGetD3D11Device( + device: *mut ::std::os::raw::c_int, + pAdapter: *mut IDXGIAdapter, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object from a D3D11 resource"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D11Resource allocates and returns a handle to a new buffer object in \\a *buffer associated with"] + #[doc = " \\a context. If the allocated size of the D3D resource is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported D3D11 buffer types are:"] + #[doc = ""] + #[doc = " - ID3D11Buffer"] + #[doc = ""] + #[doc = " These buffers can be used to share data with D3D11; changes of the content in \\a buffer, either done by D3D11 or OptiX,"] + #[doc = " will be reflected automatically in both APIs. If the size, or format, of a D3D11 buffer is changed, appropriate OptiX"] + #[doc = " calls have to be used to update \\a buffer accordingly. OptiX keeps only a reference to D3D11 data, when \\a buffer is"] + #[doc = " destroyed, the state of \\a resource is unaltered."] + #[doc = ""] + #[doc = " The \\a type of this buffer is specified by one of the following values in \\a bufferdesc:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_INPUT"] + #[doc = " - @ref RT_BUFFER_OUTPUT"] + #[doc = " - @ref RT_BUFFER_INPUT_OUTPUT"] + #[doc = ""] + #[doc = " The type values are used to specify the direction of data flow from the host to the OptiX devices."] + #[doc = " @ref RT_BUFFER_INPUT specifies that the host may only write to the buffer and the device may only read from the buffer."] + #[doc = " @ref RT_BUFFER_OUTPUT specifies the opposite, read only access on the host and write only access on the device."] + #[doc = " Devices and the host may read and write from buffers of type @ref RT_BUFFER_INPUT_OUTPUT. Reading or writing to"] + #[doc = " a buffer of the incorrect type (e.g., the host writing to a buffer of type @ref RT_BUFFER_OUTPUT) is undefined."] + #[doc = ""] + #[doc = " Flags can be used to optimize data transfers between the host and it's devices. Currently no \\a flags are supported for"] + #[doc = " interop buffers."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[in] resource The D3D11 resource handle for use in OptiX"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromD3D11Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateFromD3D11Resource( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + resource: *mut ID3D11Resource, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new texture sampler object from a D3D11 resource"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D11Resource allocates and returns a"] + #[doc = " handle to a new texture sampler object in \\a *texturesampler"] + #[doc = " associated with \\a context. If the allocated size of the D3D resource"] + #[doc = " is \\a 0, @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported"] + #[doc = " D3D11 texture types are:"] + #[doc = ""] + #[doc = " - ID3D11Texture1D"] + #[doc = " - ID3D11Texture2D"] + #[doc = " - ID3D11Texture3D"] + #[doc = ""] + #[doc = " These texture samplers can be used to share data with D3D11; changes of"] + #[doc = " the content and size of \\a texturesampler done by D3D11 will be"] + #[doc = " reflected automatically in OptiX. Currently texture sampler data are"] + #[doc = " read only in OptiX programs. OptiX keeps only a reference to"] + #[doc = " D3D11 data, when \\a texturesampler is destroyed, the state of the"] + #[doc = " \\a resource is unaltered."] + #[doc = ""] + #[doc = " The array size and number of mipmap levels can't be changed for"] + #[doc = " texture samplers that encapsulate a D3D11 resource. Furthermore no"] + #[doc = " buffer objects can be queried. Please refer to the @ref InteropTypes for a"] + #[doc = " complete list of supported texture formats."] + #[doc = ""] + #[doc = " @param[in] context The context to create the texture sampler in"] + #[doc = " @param[in] resource The D3D11 resource handle for use in OptiX"] + #[doc = " @param[out] textureSampler The return handle for the texture sampler object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromD3D11Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate,"] + #[doc = " @ref rtTextureSamplerDestroy"] + #[doc = ""] + pub fn rtTextureSamplerCreateFromD3D11Resource( + context: RTcontext, + resource: *mut ID3D11Resource, + textureSampler: *mut RTtexturesampler, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D11 resource associated with this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D11Resource stores the D3D11 resource pointer in \\a **resource if \\a buffer was created with"] + #[doc = " @ref rtBufferCreateFromD3D11Resource. If \\a buffer was not created from a D3D11 resource \\a **resource will be \\a 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its D3D11 resource"] + #[doc = " @param[out] resource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetD3D11Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferGetD3D11Resource( + buffer: RTbuffer, + resource: *mut *mut ID3D11Resource, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the D3D11 resource associated with this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D11Resource stores the D3D11 resource pointer in \\a **resource if \\a sampler was created with"] + #[doc = " @ref rtTextureSamplerGetD3D11Resource. If \\a sampler was not created from a D3D11 resource \\a resource will be 0 after"] + #[doc = " the call and @ref RT_ERROR_INVALID_VALUE is returned"] + #[doc = ""] + #[doc = " @param[in] textureSampler The texture sampler to be queried for its D3D11 resource"] + #[doc = " @param[out] resource The return handle for the resource"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetD3D11Resource was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtTextureSamplerGetD3D11Resource( + textureSampler: RTtexturesampler, + resource: *mut *mut ID3D11Resource, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D11 buffer as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in an unregistered state can be registered to OptiX again via @ref rtBufferD3D11Register. Once registered,"] + #[doc = " properties like the size of the original D3D11 resource cannot be modified anymore. Calls to the corresponding D3D11 functions"] + #[doc = " will return with an error code. However, the data of the D3D11 resource can still be read and written by the appropriate D3D11 commands."] + #[doc = " When a buffer is already in a registered state @ref rtBufferD3D11Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED. A resource"] + #[doc = " must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D11Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D11Register(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D11 buffer as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX buffer in a registered state can be unregistered via @ref rtBufferD3D11Register. Once unregistered,"] + #[doc = " properties like the size of the original D3D11 resource can be changed. As long as a resource is unregistered,"] + #[doc = " OptiX will not be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already"] + #[doc = " in an unregistered state @ref rtBufferD3D11Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferD3D11Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtBufferD3D11Unregister(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D11 texture as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in an unregistered state can be registered to OptiX again via @ref rtTextureSamplerD3D11Register."] + #[doc = " Once registered, properties like the size of the original D3D11 resource cannot be modified anymore. Calls to the corresponding"] + #[doc = " D3D11 functions will return with an error code. However, the data of the D3D11 resource can still be read and written by the appropriate"] + #[doc = " D3D11 commands. When a texture sampler is already in a registered state @ref rtTextureSamplerD3D11Register will return @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED."] + #[doc = " A resource must be registered in order to be used by OptiX. If a resource is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D11Register was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D11Register(textureSampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares a D3D11 texture as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " An OptiX texture sampler in a registered state can be unregistered via @ref rtTextureSamplerD3D11Unregister. Once unregistered,"] + #[doc = " properties like the size of the original D3D11 resource can be changed. As long as a resource is unregistered, OptiX will not"] + #[doc = " be able to access the data and will fail with @ref RT_ERROR_INVALID_VALUE. When a buffer is already in an unregistered state"] + #[doc = " @ref rtBufferD3D11Unregister will return @ref RT_ERROR_RESOURCE_NOT_REGISTERED."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerD3D11Unregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromD3D11Resource"] + #[doc = ""] + pub fn rtTextureSamplerD3D11Unregister(textureSampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new buffer object from an OpenGL buffer object"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromGLBO allocates and returns a handle to a new buffer object in *\\a buffer associated with"] + #[doc = " \\a context. Supported OpenGL buffer types are:"] + #[doc = ""] + #[doc = " - Pixel Buffer Objects"] + #[doc = ""] + #[doc = " - Vertex Buffer Objects"] + #[doc = ""] + #[doc = " These buffers can be used to share data with OpenGL; changes of the content in \\a buffer, either done by OpenGL or OptiX,"] + #[doc = " will be reflected automatically in both APIs. If the size, or format, of an OpenGL buffer is changed, appropriate OptiX"] + #[doc = " calls have to be used to update \\a buffer accordingly. OptiX keeps only a reference to OpenGL data, when \\a buffer is"] + #[doc = " destroyed, the state of the \\a gl_id object is unaltered."] + #[doc = ""] + #[doc = " The \\a type of this buffer is specified by one of the following values in \\a bufferdesc:"] + #[doc = ""] + #[doc = " - @ref RT_BUFFER_INPUT"] + #[doc = " - @ref RT_BUFFER_OUTPUT"] + #[doc = " - @ref RT_BUFFER_INPUT_OUTPUT"] + #[doc = ""] + #[doc = " The type values are used to specify the direction of data flow from the host to the OptiX devices."] + #[doc = " @ref RT_BUFFER_INPUT specifies that the host may only write to the buffer and the device may only read from the buffer."] + #[doc = " @ref RT_BUFFER_OUTPUT specifies the opposite, read only access on the host and write only access on the device."] + #[doc = " Devices and the host may read and write from buffers of type @ref RT_BUFFER_INPUT_OUTPUT. Reading or writing to"] + #[doc = " a buffer of the incorrect type (e.g., the host writing to a buffer of type @ref RT_BUFFER_OUTPUT) is undefined."] + #[doc = ""] + #[doc = " Flags can be used to optimize data transfers between the host and it's devices. Currently no \\a flags are supported for"] + #[doc = " interop buffers."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] bufferdesc Bitwise \\a or combination of the \\a type and \\a flags of the new buffer"] + #[doc = " @param[in] glId The OpenGL image object resource handle for use in OptiX"] + #[doc = " @param[out] buffer The return handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferCreateFromGLBO was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreate,"] + #[doc = " @ref rtBufferDestroy"] + #[doc = ""] + pub fn rtBufferCreateFromGLBO( + context: RTcontext, + bufferdesc: ::std::os::raw::c_uint, + glId: ::std::os::raw::c_uint, + buffer: *mut RTbuffer, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Creates a new texture sampler object from an OpenGL image"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromGLImage allocates and returns a handle to"] + #[doc = " a new texture sampler object in * \\a texturesampler associated with"] + #[doc = " \\a context. If the allocated size of the GL texture is 0,"] + #[doc = " @ref RT_ERROR_MEMORY_ALLOCATION_FAILED will be returned. Supported OpenGL"] + #[doc = " image types are:"] + #[doc = ""] + #[doc = " Renderbuffers"] + #[doc = ""] + #[doc = " - GL_TEXTURE_2D"] + #[doc = ""] + #[doc = " - GL_TEXTURE_2D_RECT"] + #[doc = ""] + #[doc = " - GL_TEXTURE_3D"] + #[doc = ""] + #[doc = ""] + #[doc = " These types are reflected by \\a target:"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_RENDER_BUFFER"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_1D"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_2D"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_RECTANGLE"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_3D"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_1D_ARRAY"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_2D_ARRAY"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_CUBE_MAP"] + #[doc = ""] + #[doc = " - @ref RT_TARGET_GL_TEXTURE_CUBE_MAP_ARRAY"] + #[doc = ""] + #[doc = " Supported attachment points for renderbuffers are:"] + #[doc = ""] + #[doc = " - GL_COLOR_ATTACHMENT"] + #[doc = ""] + #[doc = ""] + #[doc = " These texture samplers can be used to share data with OpenGL; changes"] + #[doc = " of the content and size of \\a texturesampler done by OpenGL will be"] + #[doc = " reflected automatically in OptiX. Currently texture sampler data are"] + #[doc = " read only in OptiX programs. OptiX keeps only a reference to"] + #[doc = " OpenGL data, when \\a texturesampler is destroyed, the state of the"] + #[doc = " \\a gl_id image is unaltered."] + #[doc = ""] + #[doc = " The array size and number of mipmap levels can't be changed for"] + #[doc = " texture samplers that encapsulate a GL image. Furthermore no buffer"] + #[doc = " objects can be queried."] + #[doc = ""] + #[doc = " Currently OptiX supports only a limited number of internal OpenGL"] + #[doc = " texture formats. Texture formats with an internal type of float,"] + #[doc = " e.g. \\a GL_RGBA32F, and many integer formats are supported. Depth formats"] + #[doc = " as well as multisample buffers are also currently not supported."] + #[doc = " Please refer to the @ref InteropTypes section for a complete list of supported"] + #[doc = " texture formats."] + #[doc = ""] + #[doc = " @param[in] context The context to create the buffer in"] + #[doc = " @param[in] glId The OpenGL image object resoure handle for use in OptiX"] + #[doc = " @param[in] target The OpenGL target"] + #[doc = " @param[out] textureSampler The return handle for the texture sampler object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerCreateFromGLImage was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreate,"] + #[doc = " @ref rtTextureSamplerDestroy"] + #[doc = ""] + pub fn rtTextureSamplerCreateFromGLImage( + context: RTcontext, + glId: ::std::os::raw::c_uint, + target: RTgltarget, + textureSampler: *mut RTtexturesampler, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the OpenGL Buffer Object ID associated with this buffer"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtBufferGetGLBOId stores the OpenGL buffer object id in \\a gl_id if"] + #[doc = " \\a buffer was created with @ref rtBufferCreateFromGLBO. If \\a buffer was"] + #[doc = " not created from an OpenGL Buffer Object \\a gl_id will be set to 0."] + #[doc = ""] + #[doc = " @param[in] buffer The buffer to be queried for its OpenGL buffer object id"] + #[doc = " @param[in] glId The return handle for the id"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGetGLBOId was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromGLBO"] + #[doc = ""] + pub fn rtBufferGetGLBOId(buffer: RTbuffer, glId: *mut ::std::os::raw::c_uint) -> RTresult; +} +extern "C" { + #[doc = " @brief Gets the OpenGL image object id associated with this texture sampler"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetGLImageId stores the OpenGL image object id in"] + #[doc = " \\a gl_id if \\a textureSampler was created with @ref rtTextureSamplerCreateFromGLImage."] + #[doc = " If \\a textureSampler was not created from an OpenGL image object \\a gl_id"] + #[doc = " will be set to 0."] + #[doc = ""] + #[doc = " @param[in] textureSampler The texture sampler to be queried for its OpenGL buffer object id"] + #[doc = " @param[in] glId The return handle for the id"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_MEMORY_ALLOCATION_FAILED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGetGLImageId was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromGLImage"] + #[doc = ""] + pub fn rtTextureSamplerGetGLImageId( + textureSampler: RTtexturesampler, + glId: *mut ::std::os::raw::c_uint, + ) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares an OpenGL buffer as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Once registered, properties like the size of the original GL buffer cannot be modified anymore."] + #[doc = " Calls to the corresponding GL functions will return with an error code."] + #[doc = " However, the buffer data of the GL buffer can still be read and written by the appropriate GL commands."] + #[doc = " Returns \\a RT_ERROR_RESOURCE_ALREADY_REGISTERED if \\a buffer is already registered."] + #[doc = " A buffer object must be registered in order to be used by OptiX."] + #[doc = " If a buffer object is not registered @ref RT_ERROR_INVALID_VALUE will be returned."] + #[doc = " An OptiX buffer in a registered state can be unregistered via @ref rtBufferGLRegister."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGLRegister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromGLBO,"] + #[doc = " @ref rtBufferGLUnregister"] + #[doc = ""] + pub fn rtBufferGLRegister(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares an OpenGL buffer as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup Buffer"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Once unregistered, properties like the size of the original GL buffer can be changed."] + #[doc = " As long as a buffer object is unregistered, OptiX will not be able to access the data and calls will fail with @ref RT_ERROR_INVALID_VALUE."] + #[doc = " Returns \\a RT_ERROR_RESOURCE_NOT_REGISTERED if \\a buffer is already unregistered."] + #[doc = " An OptiX buffer in an unregistered state can be registered to OptiX again via @ref rtBufferGLRegister."] + #[doc = ""] + #[doc = " @param[in] buffer The handle for the buffer object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtBufferGLUnregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtBufferCreateFromGLBO,"] + #[doc = " @ref rtBufferGLRegister"] + #[doc = ""] + pub fn rtBufferGLUnregister(buffer: RTbuffer) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares an OpenGL texture as immutable and accessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Registers an OpenGL texture as accessible by OptiX. Once registered, properties like the size of the original GL texture cannot be modified anymore."] + #[doc = " Calls to the corresponding GL functions will return with an error code. However, the pixel data of the GL texture can still be read and written by the appropriate GL commands."] + #[doc = " Returns @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED if \\a textureSampler is already registered."] + #[doc = " A texture sampler must be registered in order to be used by OptiX. Otherwise, @ref RT_ERROR_INVALID_VALUE is returned."] + #[doc = " An OptiX texture sampler in a registered state can be unregistered via @ref rtTextureSamplerGLUnregister."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_RESOURCE_ALREADY_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGLRegister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromGLImage,"] + #[doc = " @ref rtTextureSamplerGLUnregister"] + #[doc = ""] + pub fn rtTextureSamplerGLRegister(textureSampler: RTtexturesampler) -> RTresult; +} +extern "C" { + #[doc = " @brief Declares an OpenGL texture as mutable and inaccessible by OptiX"] + #[doc = ""] + #[doc = " @ingroup TextureSampler"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " Once unregistered, properties like the size of the original GL texture can be changed."] + #[doc = " As long as a texture is unregistered, OptiX will not be able to access the pixel data and calls will fail with @ref RT_ERROR_INVALID_VALUE."] + #[doc = " Returns \\a RT_ERROR_RESOURCE_NOT_REGISTERED if \\a textureSampler is already unregistered."] + #[doc = " An OptiX texture sampler in an unregistered state can be registered to OptiX again via @ref rtTextureSamplerGLRegister."] + #[doc = ""] + #[doc = " @param[in] textureSampler The handle for the texture object"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_CONTEXT"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = " - @ref RT_ERROR_RESOURCE_NOT_REGISTERED"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtTextureSamplerGLUnregister was introduced in OptiX 2.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtTextureSamplerCreateFromGLImage,"] + #[doc = " @ref rtTextureSamplerGLRegister"] + #[doc = ""] + pub fn rtTextureSamplerGLUnregister(textureSampler: RTtexturesampler) -> RTresult; +} +pub type HGPUNV = *mut ::std::os::raw::c_void; +extern "C" { + #[doc = " @brief returns the OptiX device number associated with the specified GPU"] + #[doc = ""] + #[doc = " @ingroup ContextFreeFunctions"] + #[doc = ""] + #[doc = " Description"] + #[doc = ""] + #[doc = " @ref rtDeviceGetWGLDevice returns in \\a device the OptiX device ID of the GPU represented by \\a gpu."] + #[doc = " \\a gpu is returned from \\a WGL_NV_gpu_affinity, an OpenGL extension. This enables OptiX to create a context"] + #[doc = " on the same GPU that OpenGL commands will be sent to, improving OpenGL interoperation efficiency."] + #[doc = ""] + #[doc = " @param[out] device A handle to the memory location where the OptiX device ordinal associated with \\a gpu will be stored"] + #[doc = " @param[in] gpu A handle to a GPU as returned from the \\a WGL_NV_gpu_affinity OpenGL extension"] + #[doc = ""] + #[doc = " Return values"] + #[doc = ""] + #[doc = " Relevant return values:"] + #[doc = " - @ref RT_SUCCESS"] + #[doc = " - @ref RT_ERROR_INVALID_VALUE"] + #[doc = ""] + #[doc = " History"] + #[doc = ""] + #[doc = " @ref rtDeviceGetWGLDevice was introduced in OptiX 1.0."] + #[doc = ""] + #[doc = " See also"] + #[doc = " @ref rtDeviceGetDeviceCount,"] + #[doc = " \\a WGL_NV_gpu_affinity"] + #[doc = ""] + pub fn rtDeviceGetWGLDevice(device: *mut ::std::os::raw::c_int, gpu: HGPUNV) -> RTresult; +} diff --git a/optix_dump/Cargo.toml b/optix_dump/Cargo.toml new file mode 100644 index 0000000..741d3cd --- /dev/null +++ b/optix_dump/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "optix_dump" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "optix_dump" +crate-type = ["cdylib"] + +[dependencies] +cuda_types = { path = "../cuda_types" } +optix_base = { path = "../optix_base" } +wmi = "0.9" +winapi = { version = "0.3", features = ["libloaderapi", "std"] } +lazy_static = "1.4.0" +paste = "1.0.7" +sha2 = "0.10.2" +generic-array = "0.14.5" +typenum = "1.15.0" + +[package.metadata.zluda] +debug_only = true +windows_only = true +broken = true diff --git a/optix_dump/README b/optix_dump/README new file mode 100644 index 0000000..991557a --- /dev/null +++ b/optix_dump/README @@ -0,0 +1 @@ +bindgen include/wrapper.hpp -o src/optix.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --whitelist-type="Optix.*" --whitelist-function "optix.*" --whitelist-var "OPTIX.*" -- -I"F:\dev\OptiX SDK 7.4.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.5\include diff --git a/optix_dump/include/wrapper.hpp b/optix_dump/include/wrapper.hpp new file mode 100644 index 0000000..0cbf13b --- /dev/null +++ b/optix_dump/include/wrapper.hpp @@ -0,0 +1,2 @@ +#include +#include diff --git a/optix_dump/src/eptx.rs b/optix_dump/src/eptx.rs new file mode 100644 index 0000000..d1d47d7 --- /dev/null +++ b/optix_dump/src/eptx.rs @@ -0,0 +1,170 @@ +use generic_array::arr; +use generic_array::GenericArray; +use sha2::Digest; +use sha2::Sha256; +use std::convert::TryInto; +use std::io::Write; +use std::mem; +use std::u8; +use typenum::{U16, U2, U32}; + +const OPTIX_KEY: &'static [u8] = + b"-3343556356fgfgfdessss-(--9355-489795-2333354:[]}}{[]523552%GWEf"; + +const REMAINDER_KEY: [u8; 7] = [164, 195, 147, 255, 203, 161, 184]; + +pub(crate) fn decode_ptx<'a>( + content: &'a mut [u8], + optix_salt: &[u8], + vendor_salt: &[u8], + vendor_key: &[u8], +) -> &'a mut [u8] { + let content = normalize(content); + let concatenated_key = [&vendor_key[..], &OPTIX_KEY[..]].concat(); + let hashed_key = sha256(&concatenated_key[..]); + let hexed_key = to_hex_string(hashed_key); + let session_key_input = [&optix_salt[..], &hexed_key[..], &vendor_salt[..]].concat(); + let mut hashed_session_key = sha256(&session_key_input[..]); + let reduced_key = reduce_key(&mut hashed_session_key); + decode(content, &*reduced_key); + decode_remainder(content); + content +} + +pub(crate) fn encode_ptx<'a>( + content: &'a mut [u8], + optix_salt: &[u8], + vendor_salt: &[u8], + vendor_key: &[u8], +) -> Vec { + let concatenated_key = [&vendor_key[..], &OPTIX_KEY[..]].concat(); + let hashed_key = sha256(&concatenated_key[..]); + let hexed_key = to_hex_string(hashed_key); + let session_key_input = [&optix_salt[..], &hexed_key[..], &vendor_salt[..]].concat(); + let mut hashed_session_key = sha256(&session_key_input[..]); + let reduced_key = reduce_key(&mut hashed_session_key); + encode(content, &*reduced_key); + decode_remainder(content); + escape(content) +} + +fn escape(content: &[u8]) -> Vec { + let mut result = Vec::with_capacity(content.len()); + result.extend_from_slice("eptx0001".as_bytes()); + for c in content.iter().copied() { + if c == 0 || c == 1 { + result.push(1); + result.push(c + 1); + } else { + result.push(c); + } + } + result +} + +fn decode(content: &mut [u8], reduced_key: &GenericArray) { + for i in 0..content.len() / 8 { + let block = &mut content[i * 8..i * 8 + 8]; + unsafe { decrypt_block(block.try_into().unwrap(), reduced_key) }; + } +} + +fn decode_remainder(content: &mut [u8]) { + let remainer_start = (content.len() / 8) * 8; + for i in 0..content.len() % 8 { + content[remainer_start + i] = content[remainer_start + i] ^ REMAINDER_KEY[i]; + } +} + +fn sha256(content: &[u8]) -> GenericArray { + let mut hasher = Sha256::new(); + hasher.update(content); + hasher.finalize() +} + +fn to_hex_string(hash: GenericArray) -> [u8; 64] { + let mut result = [0u8; 64]; + for (idx, c) in hash.into_iter().enumerate() { + write!(&mut result[idx * 2..idx * 2 + 2], "{:02x}", c).unwrap(); + } + result +} + +fn reduce_key<'a>(content: &'a mut GenericArray) -> &'a mut GenericArray { + for i in 0usize..16 { + content[i] = content[i].wrapping_add(content[i + 16]); + } + GenericArray::from_mut_slice(&mut content.as_mut_slice()[..16]) +} + +unsafe fn decrypt_block(block: &mut [u8; 8], key: &GenericArray) { + let delta: u32 = 0x9E3779B9; + let mut sum: u32 = 0xE3779B90; + let v = mem::transmute::<[u8; 8], [u32; 2]>(*block); + let mut v0 = v[0]; + let mut v1 = v[1]; + let key = key.as_ptr() as *const u32; + let k0 = *key.offset(0); + let k1 = *key.offset(1); + let k2 = *key.offset(2); + let k3 = *key.offset(3); + for _ in 0..16 { + v1 = v1.wrapping_sub( + ((v0 << 4).wrapping_add(k2)) ^ (v0.wrapping_add(sum)) ^ ((v0 >> 5).wrapping_add(k3)), + ); + v0 = v0.wrapping_sub( + ((v1 << 4).wrapping_add(k0)) ^ (v1.wrapping_add(sum)) ^ ((v1 >> 5).wrapping_add(k1)), + ); + sum = sum.wrapping_sub(delta); + } + *block = std::mem::transmute::, [u8; 8]>(arr![u32; v0, v1]); +} + +fn encode(content: &mut [u8], reduced_key: &GenericArray) { + for i in 0..content.len() / 8 { + let block = &mut content[i * 8..i * 8 + 8]; + unsafe { encrypt_block(block.try_into().unwrap(), reduced_key) }; + } +} + +unsafe fn encrypt_block(block: &mut [u8; 8], key: &GenericArray) { + let delta: u32 = 0x9E3779B9; + let mut sum: u32 = 0; + let v = mem::transmute::<[u8; 8], [u32; 2]>(*block); + let mut v0 = v[0]; + let mut v1 = v[1]; + let key = key.as_ptr() as *const u32; + let k0 = *key.offset(0); + let k1 = *key.offset(1); + let k2 = *key.offset(2); + let k3 = *key.offset(3); + for _ in 0..16 { + sum = sum.wrapping_add(delta); + v0 = v0.wrapping_add( + ((v1 << 4).wrapping_add(k0)) ^ (v1.wrapping_add(sum)) ^ ((v1 >> 5).wrapping_add(k1)), + ); + v1 = v1.wrapping_add( + ((v0 << 4).wrapping_add(k2)) ^ (v0.wrapping_add(sum)) ^ ((v0 >> 5).wrapping_add(k3)), + ); + } + *block = std::mem::transmute::, [u8; 8]>(arr![u32; v0, v1]); +} + +fn normalize<'a>(content: &'a mut [u8]) -> &'a mut [u8] { + let mut to = 0; + let mut from = 8; + loop { + if from >= content.len() { + break; + } + let mut c = content[from]; + if c == 1 { + from += 1; + c = content[from] - 1; + } + content[to] = c; + from += 1; + to += 1; + } + &mut content[0..to] +} diff --git a/optix_dump/src/lib.rs b/optix_dump/src/lib.rs new file mode 100644 index 0000000..d1bcf12 --- /dev/null +++ b/optix_dump/src/lib.rs @@ -0,0 +1,425 @@ +#[macro_use] +extern crate lazy_static; + +use cuda_types::*; +use paste::paste; +use std::io::Write; +use std::{ + ffi::{c_void, CStr}, + fs::File, + mem, ptr, + sync::{atomic::AtomicUsize, Mutex}, +}; +use winapi::{ + shared::{ + minwindef::{HINSTANCE, HMODULE}, + ntdef::LPCWSTR, + }, + um::libloaderapi::{GetModuleHandleA, GetProcAddress, LoadLibraryW}, +}; + +mod eptx; + +optix_base::optix_type_declarations!(); +optix_base::optix6_type_declarations!(); + +macro_rules! optix_fn_table { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + trait OptixFunctionTableTrait { + $( + unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + let mut global = match GLOBAL_STATE.lock() { + Ok(global) => global, + Err(_) => return <$ret_type as DefaultError>::error(), + }; + let global = global.as_mut().unwrap(); + panic!() + //(global.fn_table).$fn_name.unwrap() ( $( $arg_id),* ) + } + )* + } + + struct DumpOptixFunctionTable; + + impl OptixFunctionTableTrait for DumpOptixFunctionTable { + + } + + fn get_table() -> OptixFunctionTable { + OptixFunctionTable { + $( + $fn_name: Some(T::$fn_name), + )* + } + } + }; +} + +optix_base::optix_function_declarations!(optix_fn_table); + +macro_rules! optix6_fn { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + $( + #[no_mangle] + unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + let fn_ptr = GlobalState::with_state(|global| { + writeln!(&mut global.log_file, stringify!($fn_name)); + GetProcAddress(global.optix6_handle, concat!(stringify!($fn_name), "\0").as_ptr() as _ ) + }); + let fn_ptr = match fn_ptr { + Some(f) if f == ptr::null_mut() => panic!(stringify!($fn_name)), + Some(f) => f, + None => panic!(stringify!($fn_name)) + }; + let fn_ptr = mem::transmute::<_, unsafe extern $abi fn ( $( $arg_type),* ) -> $ret_type>(fn_ptr); + (fn_ptr)( $( $arg_id ),* ) + } + )* + }; +} + +macro_rules! optix6_fn_override { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + $( + #[no_mangle] + unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + let fn_ptr = GlobalState::with_state(|global| { + writeln!(&mut global.log_file, stringify!($fn_name)).unwrap(); + GetProcAddress(global.optix6_handle, concat!(stringify!($fn_name), "\0").as_ptr() as _ ) + }); + let fn_ptr = match fn_ptr { + Some(f) if f == ptr::null_mut() => panic!(stringify!($fn_name)), + Some(f) => f, + None => panic!(stringify!($fn_name)) + }; + let fn_ptr = mem::transmute::<_, unsafe extern $abi fn ( $( $arg_type),* ) -> $ret_type>(fn_ptr); + let result = (fn_ptr)( $( $arg_id ),* ); + (paste! { [<$fn_name _Post >] }) ( $( $arg_id ),* ); + result + } + )* + }; +} + +optix_base::optix6_function_declarations!( + optix6_fn, + optix6_fn_override, + [ + rtContextGetAttribute, + rtContextSetAttribute, + rtContextLaunch2D, + rtGeometryTrianglesSetFlagsPerMaterial, + rtProgramCreateFromPTXString, + rtGeometryInstanceSetMaterialCount, + rtBufferSetFormat + ] +); + +trait DefaultError { + fn error() -> Self; +} + +impl DefaultError for OptixResult { + fn error() -> Self { + OptixResult::OPTIX_ERROR_INTERNAL_ERROR + } +} + +impl DefaultError for RTresult { + fn error() -> Self { + RTresult::RT_ERROR_UNKNOWN + } +} + +impl DefaultError for *const i8 { + fn error() -> Self { + ptr::null() + } +} + +impl DefaultError for () { + fn error() -> Self { + () + } +} + +#[allow(non_snake_case)] +struct GlobalState { + log_file: File, + optix6_handle: HINSTANCE, + optix_salt: Vec, + vendor_salt: Vec, + vendor_key: Vec, + /* + fn_table: OptixFunctionTable, + optixQueryFunctionTable: fn( + abi_id: c_int, + num_options: c_uint, + option_keys: *const c_void, + option_values: *mut *const c_void, + function_table: *mut OptixFunctionTable, + size_of_table: usize, + ) -> OptixResult, + */ +} + +impl GlobalState { + unsafe fn with_state(f: impl FnOnce(&mut GlobalState) -> T) -> Option { + let mut global = match GLOBAL_STATE.lock() { + Ok(global) => global, + Err(_) => return None, + }; + let global = match &mut *global { + Some(global) => global, + None => { + let redirect_handle = GetModuleHandleA(b"zluda_redirect\0".as_ptr() as _); + let load_library: unsafe extern "system" fn(LPCWSTR) -> HMODULE = + if redirect_handle == ptr::null_mut() { + LoadLibraryW + } else { + mem::transmute(GetProcAddress( + redirect_handle, + b"ZludaLoadLibraryW_NoRedirect\0".as_ptr() as _, + )) + }; + //let optix_handle = + // load_library(OPTIX_PATH.encode_utf16().collect::>().as_ptr()); + let optix6_handle = + load_library(OPTIX6_PATH.encode_utf16().collect::>().as_ptr()); + if optix6_handle == std::ptr::null_mut() { + return None; + } + /* + let optixQueryFunctionTable = + GetProcAddress(optix_handle, "optixQueryFunctionTable\0".as_ptr() as _); + if optixQueryFunctionTable == ptr::null_mut() { + return None; + } + let optixQueryFunctionTable = mem::transmute::< + _, + fn( + abi_id: c_int, + num_options: c_uint, + option_keys: *const c_void, + option_values: *mut *const c_void, + function_table: *mut OptixFunctionTable, + size_of_table: usize, + ) -> OptixResult, + >(optixQueryFunctionTable); + let mut fn_table = mem::zeroed::(); + let error = optixQueryFunctionTable( + 55, + 0, + ptr::null(), + ptr::null_mut(), + &mut fn_table, + mem::size_of::(), + ); + if error != OptixResult::OPTIX_SUCCESS { + return None; + } + global.insert(GlobalState { + optix6_handle, + fn_table, + optixQueryFunctionTable, + }) + */ + let log_file = std::fs::File::create(OPTIX_LOG).unwrap(); + //let log_file = std::io::stdout(); + global.insert(GlobalState { + log_file, + optix6_handle, + optix_salt: Vec::new(), + vendor_salt: Vec::new(), + vendor_key: Vec::new(), + //fn_table: mem::zeroed(), + //optixQueryFunctionTable: mem::transmute(ptr::null_mut::<()>()), + }) + } + }; + Some(f(global)) + } +} + +unsafe impl Send for GlobalState {} + +lazy_static! { + static ref GLOBAL_STATE: Mutex> = Mutex::new(None); +} + +const OPTIX_PATH: &'static str = "C:\\Windows\\System32\\DriverStore\\FileRepository\\nvmdui.inf_amd64_0085e40375a3f44a\\nvoptix.dll\0"; +const OPTIX6_PATH: &'static str = "C:\\dev\\OptiX SDK 6.5.0\\bin64\\optix.6.5.0.dll\0"; +//"C:\\ProgramData\\Autodesk\\ApplicationPlugins\\MAXtoA_2022\\optix.6.6.0.dll\0"; +const OPTIX_LOG: &'static str = r#"C:\temp\optix.log"#; + +/* +#[no_mangle] +unsafe extern "C" fn optixQueryFunctionTable( + abi_id: c_int, + num_options: c_uint, + option_keys: *const c_void, + option_values: *mut *const c_void, + function_table: *mut OptixFunctionTable, + size_of_table: usize, +) -> OptixResult { + //file_append(OPTIX_LOG, "optixQueryFunctionTable"); + if GlobalState::with_state(|global| {}).is_none() { + return DefaultError::error(); + } + *function_table = get_table::(); + OptixResult::OPTIX_SUCCESS +} + */ + +static mut PROGRAM_COUNTER: AtomicUsize = AtomicUsize::new(1); + +pub(crate) unsafe extern "C" fn rtProgramCreateFromPTXString_Post( + _context: RTcontext, + ptx: *const ::std::os::raw::c_char, + programName: *const ::std::os::raw::c_char, + _program: *mut RTprogram, +) { + GlobalState::with_state(|global| { + writeln!(&mut global.log_file, "{:?}", CStr::from_ptr(programName)).unwrap(); + let program_number = PROGRAM_COUNTER.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + let text = CStr::from_ptr(ptx).to_bytes(); + if text.starts_with(b"eptx0001") { + let mut encoded_content = text.to_vec(); + let encoded_file = format!("C:\\temp\\optix_dump\\module_{}.eptx", program_number); + std::fs::write(encoded_file, &encoded_content).unwrap(); + let decoded_content = eptx::decode_ptx( + &mut encoded_content[..], + &global.optix_salt[..], + &global.vendor_salt[..], + &global.vendor_key[..], + ); + let decoded_file = format!("C:\\temp\\optix_dump\\module_{}.ptx", program_number); + std::fs::write(&decoded_file, decoded_content).unwrap(); + // INJECTING CUSTOM PTX + //if &*CStr::from_ptr(programName).to_string_lossy() == "exception" { + // let fn_ptr = GetProcAddress( + // global.optix6_handle, + // "rtProgramCreateFromPTXString\0".as_ptr() as _, + // ); + // let fn_ptr = mem::transmute::< + // _, + // unsafe extern "C" fn( + // RTcontext, + // *const ::std::os::raw::c_char, + // *const ::std::os::raw::c_char, + // *mut RTprogram, + // ) -> OptixResult, + // >(fn_ptr); + // let mut encoded = std::fs::read("C:\\dev\\module_1.ptx").unwrap(); + // encoded = eptx::encode_ptx( + // &mut encoded, + // &global.optix_salt[..], + // &global.vendor_salt[..], + // &global.vendor_key[..], + // ); + // encoded.push(0); + // let result = fn_ptr(_context, encoded.as_ptr() as _, programName, _program); + // if result != OptixResult::OPTIX_SUCCESS { + // panic!("{:?}", result); + // } + //} + } else { + let file = format!("C:\\temp\\optix_dump\\module_{}.eptx", program_number); + std::fs::write(file, text).unwrap(); + } + }); +} + +pub(crate) unsafe extern "C" fn rtContextGetAttribute_Post( + context: RTcontext, + attrib: RTcontextattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, +) { + let fn_ptr = GlobalState::with_state(|global| { + save_attribute(global, attrib, size, p); + }); +} + +pub(crate) unsafe extern "C" fn rtContextSetAttribute_Post( + context: RTcontext, + attrib: RTcontextattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, +) { + let fn_ptr = GlobalState::with_state(|global| { + save_attribute(global, attrib, size, p); + }); +} + +pub(crate) unsafe extern "C" fn rtContextLaunch2D_Post( + context: RTcontext, + entry_point_index: ::std::os::raw::c_uint, + width: u64, + height: u64, +) { + let fn_ptr = GlobalState::with_state(|global| { + writeln!(&mut global.log_file, "({}, {})", width, height).unwrap(); + }); +} + +pub(crate) unsafe extern "C" fn rtGeometryTrianglesSetFlagsPerMaterial_Post( + geometrytriangles: RTgeometrytriangles, + materialIndex: ::std::os::raw::c_uint, + flags: RTgeometryflags, +) { + GlobalState::with_state(|global| { + writeln!(&mut global.log_file, "{}", flags.0).unwrap(); + }); +} + +unsafe fn save_attribute( + global: &mut GlobalState, + attrib: RTcontextattribute, + size: RTsize, + p: *const c_void, +) { + let (attrib_name, vec) = match attrib { + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_OPTIX_SALT => { + ("RT_CONTEXT_ATTRIBUTE_OPTIX_SALT", &mut global.optix_salt) + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_VENDOR_SALT => { + ("RT_CONTEXT_ATTRIBUTE_VENDOR_SALT", &mut global.vendor_salt) + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY => ( + "RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY", + &mut global.vendor_key, + ), + _ => return, + }; + let size = size as usize; + let mut value = vec![0u8; size]; + value.copy_from_slice(std::slice::from_raw_parts(p as *const u8, size)); + writeln!(&mut global.log_file, "{}: {:?}", attrib_name, value).unwrap(); + *vec = value; +} + +pub(crate) unsafe extern "C" fn rtGeometryInstanceSetMaterialCount_Post( + geometryinstance: RTgeometryinstance, + count: ::std::os::raw::c_uint, +) { + GlobalState::with_state(|global| { + writeln!(&mut global.log_file, "{}", count).unwrap(); + }); +} + +pub(crate) unsafe extern "C" fn rtBufferSetFormat_Post(_buffer: RTbuffer, format: RTformat) { + GlobalState::with_state(|global| { + writeln!(&mut global.log_file, "{:?}", format).unwrap(); + }); +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn tabe_size() { + assert_eq!(std::mem::size_of::(), 0x158); + } +} diff --git a/optix_types/Cargo.toml b/optix_types/Cargo.toml new file mode 100644 index 0000000..1efbe04 --- /dev/null +++ b/optix_types/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "optix_types" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] + +[dependencies] +cuda_types = { path = "../cuda_types" } +optix_base = { path = "../optix_base" } diff --git a/optix_types/src/lib.rs b/optix_types/src/lib.rs new file mode 100644 index 0000000..314686c --- /dev/null +++ b/optix_types/src/lib.rs @@ -0,0 +1,2 @@ + +optix_base::optix6_type_declarations!(RTformat, RTresult); \ No newline at end of file diff --git a/process_address_table/Cargo.toml b/process_address_table/Cargo.toml new file mode 100644 index 0000000..2de38f1 --- /dev/null +++ b/process_address_table/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "process_address_table" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[dependencies] +detours-sys = { path = "../detours-sys" } +libloading = "0.8" + +[dependencies.windows] +version = "0.48" +features = [ + "Win32_Foundation", + "Win32_System_Diagnostics_Debug", + "Win32_System_LibraryLoader", +] + +[package.metadata.zluda] +debug_only = true diff --git a/process_address_table/src/main.rs b/process_address_table/src/main.rs new file mode 100644 index 0000000..a2dbc38 --- /dev/null +++ b/process_address_table/src/main.rs @@ -0,0 +1,230 @@ +use libloading::Library; +use std::collections::BTreeSet; +use std::collections::HashMap; +use std::ptr; + +// Version history taken from here: https://developer.nvidia.com/cuda-toolkit-archive +static CUDA_VERSIONS: &[&'static str] = &[ + "12.2.0", "12.1.1", "12.1.0", "12.0.1", "12.0.0", "11.8.0", "11.7.1", "11.7.0", "11.6.2", + "11.6.1", "11.6.0", "11.5.2", "11.5.1", "11.5.0", "11.4.4", "11.4.3", "11.4.2", "11.4.1", + "11.4.0", "11.3.1", "11.3.0", "11.2.2", "11.2.1", "11.2.0", "11.1.1", "11.1.0", "11.0.3", + "11.0.2", "11.0.1", "11.0", "10.2", "10.1", "10.1", "10.1", "10.0", "9.2", "9.1", "9.0", "8.0", + "7.5", "7.0", "6.5", "6.0", "5.5", "5.0", "4.2", "4.1", "4.0", "3.2", "3.1", "3.0", "2.3", + "2.2", "2.1", "2.0", "1.1", "1.0", +]; + +struct FnVersionTable<'a> { + fn_: &'a str, + flag: u64, + versions: Vec<(u32, &'a str)>, +} + +impl<'a> FnVersionTable<'a> { + fn new(fn_: &'a str, flag: u64) -> Self { + Self { + fn_, + flag, + versions: Vec::new(), + } + } + + fn push(&mut self, ver: u32, name: &'a str) { + if Some(name) == self.versions.last().map(|(_, n)| *n) { + return; + } + self.versions.push((ver, name)); + } + + fn print(&self) { + if self.versions.len() == 0 { + return; + } + println!(" (b\"{}\", {}) => {{", &self.fn_, self.flag); + for (version, name) in self.versions.iter().rev() { + println!(" if version >= {version} {{"); + println!(" return {name} as _;"); + println!(" }}"); + } + println!(" usize::MAX as _"); + println!(" }}"); + } +} + +fn main() { + unsafe { main_impl() } +} + +unsafe fn main_impl() { + let all_exports = os::get_nvcuda_exports(); + let mut cuda_versions = CUDA_VERSIONS + .iter() + .map(cuda_version_to_integer) + .collect::>(); + cuda_versions.sort_unstable(); + let cuda = Library::new(os::CUDA_PATH).unwrap(); + let mut cu_get_proc_address = cuda + .get:: u32>(b"cuGetProcAddress\0") + .unwrap() + .into_raw(); + let cuda_impl = if cfg!(windows) { + // Done purely to force load of nvcuda64.dll on Windows + cu_get_proc_address("cuInit\0".as_ptr() as _, &mut ptr::null_mut(), 0, 0); + let nvcuda64 = Library::new(os::CUDA_IMPL_LIB).unwrap(); + cu_get_proc_address = nvcuda64 + .get:: u32>(b"cuGetProcAddress\0") + .unwrap() + .into_raw(); + nvcuda64 + } else { + Library::new(os::CUDA_IMPL_LIB).unwrap() + }; + let (nvcuda_exports, cuda_impl_exports) = get_impl_fns(&cuda_impl, all_exports); + println!("// GENERATED AUTOMATICALLY BY process_address_table, DON'T CHANGE MANUALLY"); + println!("match (name, flag) {{"); + for export in nvcuda_exports.iter() { + for flag in [0, 1, 2] { + let mut ver_table = FnVersionTable::new(export, flag); + for ver in cuda_versions.iter().copied() { + let mut fnptr = ptr::null_mut(); + let error = cu_get_proc_address(export.as_ptr() as _, &mut fnptr, ver as i32, flag); + if error == 500 { + continue; + } + assert_eq!(0, error); + let fn_name = &cuda_impl_exports[&fnptr]; + ver_table.push(ver, fn_name); + } + ver_table.print(); + } + } + println!(" _ => std::ptr::null_mut()"); + println!("}}"); +} + +fn cuda_version_to_integer(ver: &&str) -> u32 { + let parts = ver + .split('.') + .map(|x| x.parse::().unwrap()) + .collect::>(); + let version_parts = if parts.len() == 2 { + [parts[0], parts[1], 0] + } else { + [parts[0], parts[1], parts[2]] + }; + (1000 * version_parts[0]) + (10 * version_parts[1]) + version_parts[2] +} + +unsafe fn get_impl_fns( + cuda_impl: &Library, + all_exports: BTreeSet, +) -> (BTreeSet, HashMap<*mut std::ffi::c_void, String>) { + let mut unversioned_symbols = BTreeSet::new(); + let mut addressed = HashMap::with_capacity(all_exports.len()); + for mut symbol in all_exports { + if symbol.starts_with("cuD3D") + || symbol.starts_with("cuGraphicsD3D") + || symbol.starts_with("cuGraphicsVDPAU") + || symbol.starts_with("cudbg") + || symbol.starts_with("cuVDPAU") + || symbol.starts_with("cuWGL") + || symbol.starts_with("cuEGL") + || symbol.starts_with("cuGraphicsEGL") + || symbol.contains("NvSci") + || symbol.ends_with("EglFrame") + { + continue; + } + symbol.push('\0'); + let fn_ptr = cuda_impl + .get::<*mut std::ffi::c_void>(symbol.as_bytes()) + .unwrap(); + symbol.truncate(symbol.len() - 1); + addressed.insert(*fn_ptr, symbol.clone()); + if let Some(version_suffix_idx) = symbol.find("_") { + assert!( + symbol.as_bytes()[version_suffix_idx + 2].is_ascii_digit() + || symbol.ends_with("_ptsz") + || symbol.ends_with("_ptds") + ); + symbol.truncate(version_suffix_idx); + } + unversioned_symbols.insert(symbol); + } + (unversioned_symbols, addressed) +} + +#[cfg(windows)] +mod os { + use detours_sys::*; + use std::collections::BTreeSet; + use std::ffi::CStr; + use windows::{core::PCSTR, imp::LoadLibraryA}; + + pub const CUDA_PATH: &'static str = "C:\\Windows\\System32\\nvcuda.dll"; + pub const CUDA_IMPL_LIB: &'static str = "nvcuda64"; + + pub fn get_nvcuda_exports() -> BTreeSet { + let nvcuda = unsafe { LoadLibraryA(PCSTR("C:\\Windows\\System32\\nvcuda.dll\0".as_ptr())) }; + let mut nvcuda_exports = BTreeSet::new(); + assert_eq!(1, unsafe { + DetourEnumerateExports( + nvcuda as _, + &mut nvcuda_exports as *mut BTreeSet<_> as _, + Some(get_unversioned_export), + ) + }); + nvcuda_exports + } + + unsafe extern "stdcall" fn get_unversioned_export( + context: PVOID, + _ordinal: ULONG, + name: LPCSTR, + _code: PVOID, + ) -> i32 { + let exports = context as *mut BTreeSet; + let name = CStr::from_ptr(name).to_str().unwrap().to_string(); + (&mut *exports).insert(name); + 1 + } +} + +#[cfg(unix)] +mod os { + use std::collections::BTreeSet; + use std::io::BufRead; + use std::process::Command; + + pub const CUDA_PATH: &'static str = "/usr/lib/x86_64-linux-gnu/libcuda.so"; + pub const CUDA_IMPL_LIB: &'static str = "libcuda.so"; + + pub fn get_nvcuda_exports() -> BTreeSet { + let export_list = Command::new("nm") + .args([ + "nm", + "-D", + "-g", + "--defined-only", + "--format=just-symbols", + CUDA_PATH, + ]) + .output() + .unwrap(); + export_list + .stdout + .lines() + .into_iter() + .collect::>() + .unwrap() + } +} diff --git a/process_address_table/table.rs b/process_address_table/table.rs new file mode 100644 index 0000000..deba1d2 --- /dev/null +++ b/process_address_table/table.rs @@ -0,0 +1,7963 @@ +// GENERATED AUTOMATICALLY BY process_address_table, DON'T CHANGE MANUALLY +match (name, flag) { + (b"cuArray3DCreate", 0) => { + if version >= 3020 { + return cuArray3DCreate_v2 as _; + } + if version >= 2000 { + return cuArray3DCreate as _; + } + usize::MAX as _ + } + (b"cuArray3DCreate", 1) => { + if version >= 3020 { + return cuArray3DCreate_v2 as _; + } + if version >= 2000 { + return cuArray3DCreate as _; + } + usize::MAX as _ + } + (b"cuArray3DCreate", 2) => { + if version >= 3020 { + return cuArray3DCreate_v2 as _; + } + if version >= 2000 { + return cuArray3DCreate as _; + } + usize::MAX as _ + } + (b"cuArray3DGetDescriptor", 0) => { + if version >= 3020 { + return cuArray3DGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArray3DGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArray3DGetDescriptor", 1) => { + if version >= 3020 { + return cuArray3DGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArray3DGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArray3DGetDescriptor", 2) => { + if version >= 3020 { + return cuArray3DGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArray3DGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArrayCreate", 0) => { + if version >= 3020 { + return cuArrayCreate_v2 as _; + } + if version >= 2000 { + return cuArrayCreate as _; + } + usize::MAX as _ + } + (b"cuArrayCreate", 1) => { + if version >= 3020 { + return cuArrayCreate_v2 as _; + } + if version >= 2000 { + return cuArrayCreate as _; + } + usize::MAX as _ + } + (b"cuArrayCreate", 2) => { + if version >= 3020 { + return cuArrayCreate_v2 as _; + } + if version >= 2000 { + return cuArrayCreate as _; + } + usize::MAX as _ + } + (b"cuArrayDestroy", 0) => { + if version >= 2000 { + return cuArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuArrayDestroy", 1) => { + if version >= 2000 { + return cuArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuArrayDestroy", 2) => { + if version >= 2000 { + return cuArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuArrayGetDescriptor", 0) => { + if version >= 3020 { + return cuArrayGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArrayGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArrayGetDescriptor", 1) => { + if version >= 3020 { + return cuArrayGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArrayGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArrayGetDescriptor", 2) => { + if version >= 3020 { + return cuArrayGetDescriptor_v2 as _; + } + if version >= 2000 { + return cuArrayGetDescriptor as _; + } + usize::MAX as _ + } + (b"cuArrayGetMemoryRequirements", 0) => { + if version >= 11060 { + return cuArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuArrayGetMemoryRequirements", 1) => { + if version >= 11060 { + return cuArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuArrayGetMemoryRequirements", 2) => { + if version >= 11060 { + return cuArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuArrayGetPlane", 0) => { + if version >= 11020 { + return cuArrayGetPlane as _; + } + usize::MAX as _ + } + (b"cuArrayGetPlane", 1) => { + if version >= 11020 { + return cuArrayGetPlane as _; + } + usize::MAX as _ + } + (b"cuArrayGetPlane", 2) => { + if version >= 11020 { + return cuArrayGetPlane as _; + } + usize::MAX as _ + } + (b"cuArrayGetSparseProperties", 0) => { + if version >= 11010 { + return cuArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuArrayGetSparseProperties", 1) => { + if version >= 11010 { + return cuArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuArrayGetSparseProperties", 2) => { + if version >= 11010 { + return cuArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttribute", 0) => { + if version >= 12010 { + return cuCoredumpGetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttribute", 1) => { + if version >= 12010 { + return cuCoredumpGetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttribute", 2) => { + if version >= 12010 { + return cuCoredumpGetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttributeGlobal", 0) => { + if version >= 12010 { + return cuCoredumpGetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttributeGlobal", 1) => { + if version >= 12010 { + return cuCoredumpGetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCoredumpGetAttributeGlobal", 2) => { + if version >= 12010 { + return cuCoredumpGetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttribute", 0) => { + if version >= 12010 { + return cuCoredumpSetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttribute", 1) => { + if version >= 12010 { + return cuCoredumpSetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttribute", 2) => { + if version >= 12010 { + return cuCoredumpSetAttribute as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttributeGlobal", 0) => { + if version >= 12010 { + return cuCoredumpSetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttributeGlobal", 1) => { + if version >= 12010 { + return cuCoredumpSetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCoredumpSetAttributeGlobal", 2) => { + if version >= 12010 { + return cuCoredumpSetAttributeGlobal as _; + } + usize::MAX as _ + } + (b"cuCtxAttach", 0) => { + if version >= 2000 { + return cuCtxAttach as _; + } + usize::MAX as _ + } + (b"cuCtxAttach", 1) => { + if version >= 2000 { + return cuCtxAttach as _; + } + usize::MAX as _ + } + (b"cuCtxAttach", 2) => { + if version >= 2000 { + return cuCtxAttach as _; + } + usize::MAX as _ + } + (b"cuCtxCreate", 0) => { + if version >= 11040 { + return cuCtxCreate_v3 as _; + } + if version >= 3020 { + return cuCtxCreate_v2 as _; + } + if version >= 2000 { + return cuCtxCreate as _; + } + usize::MAX as _ + } + (b"cuCtxCreate", 1) => { + if version >= 11040 { + return cuCtxCreate_v3 as _; + } + if version >= 3020 { + return cuCtxCreate_v2 as _; + } + if version >= 2000 { + return cuCtxCreate as _; + } + usize::MAX as _ + } + (b"cuCtxCreate", 2) => { + if version >= 11040 { + return cuCtxCreate_v3 as _; + } + if version >= 3020 { + return cuCtxCreate_v2 as _; + } + if version >= 2000 { + return cuCtxCreate as _; + } + usize::MAX as _ + } + (b"cuCtxDestroy", 0) => { + if version >= 4000 { + return cuCtxDestroy_v2 as _; + } + if version >= 2000 { + return cuCtxDestroy as _; + } + usize::MAX as _ + } + (b"cuCtxDestroy", 1) => { + if version >= 4000 { + return cuCtxDestroy_v2 as _; + } + if version >= 2000 { + return cuCtxDestroy as _; + } + usize::MAX as _ + } + (b"cuCtxDestroy", 2) => { + if version >= 4000 { + return cuCtxDestroy_v2 as _; + } + if version >= 2000 { + return cuCtxDestroy as _; + } + usize::MAX as _ + } + (b"cuCtxDetach", 0) => { + if version >= 2000 { + return cuCtxDetach as _; + } + usize::MAX as _ + } + (b"cuCtxDetach", 1) => { + if version >= 2000 { + return cuCtxDetach as _; + } + usize::MAX as _ + } + (b"cuCtxDetach", 2) => { + if version >= 2000 { + return cuCtxDetach as _; + } + usize::MAX as _ + } + (b"cuCtxDisablePeerAccess", 0) => { + if version >= 4000 { + return cuCtxDisablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxDisablePeerAccess", 1) => { + if version >= 4000 { + return cuCtxDisablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxDisablePeerAccess", 2) => { + if version >= 4000 { + return cuCtxDisablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxEnablePeerAccess", 0) => { + if version >= 4000 { + return cuCtxEnablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxEnablePeerAccess", 1) => { + if version >= 4000 { + return cuCtxEnablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxEnablePeerAccess", 2) => { + if version >= 4000 { + return cuCtxEnablePeerAccess as _; + } + usize::MAX as _ + } + (b"cuCtxGetApiVersion", 0) => { + if version >= 3020 { + return cuCtxGetApiVersion as _; + } + usize::MAX as _ + } + (b"cuCtxGetApiVersion", 1) => { + if version >= 3020 { + return cuCtxGetApiVersion as _; + } + usize::MAX as _ + } + (b"cuCtxGetApiVersion", 2) => { + if version >= 3020 { + return cuCtxGetApiVersion as _; + } + usize::MAX as _ + } + (b"cuCtxGetCacheConfig", 0) => { + if version >= 3020 { + return cuCtxGetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetCacheConfig", 1) => { + if version >= 3020 { + return cuCtxGetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetCacheConfig", 2) => { + if version >= 3020 { + return cuCtxGetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetCurrent", 0) => { + if version >= 4000 { + return cuCtxGetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxGetCurrent", 1) => { + if version >= 4000 { + return cuCtxGetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxGetCurrent", 2) => { + if version >= 4000 { + return cuCtxGetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxGetDevice", 0) => { + if version >= 2000 { + return cuCtxGetDevice as _; + } + usize::MAX as _ + } + (b"cuCtxGetDevice", 1) => { + if version >= 2000 { + return cuCtxGetDevice as _; + } + usize::MAX as _ + } + (b"cuCtxGetDevice", 2) => { + if version >= 2000 { + return cuCtxGetDevice as _; + } + usize::MAX as _ + } + (b"cuCtxGetExecAffinity", 0) => { + if version >= 11040 { + return cuCtxGetExecAffinity as _; + } + usize::MAX as _ + } + (b"cuCtxGetExecAffinity", 1) => { + if version >= 11040 { + return cuCtxGetExecAffinity as _; + } + usize::MAX as _ + } + (b"cuCtxGetExecAffinity", 2) => { + if version >= 11040 { + return cuCtxGetExecAffinity as _; + } + usize::MAX as _ + } + (b"cuCtxGetFlags", 0) => { + if version >= 7000 { + return cuCtxGetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxGetFlags", 1) => { + if version >= 7000 { + return cuCtxGetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxGetFlags", 2) => { + if version >= 7000 { + return cuCtxGetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxGetId", 0) => { + if version >= 12000 { + return cuCtxGetId as _; + } + usize::MAX as _ + } + (b"cuCtxGetId", 1) => { + if version >= 12000 { + return cuCtxGetId as _; + } + usize::MAX as _ + } + (b"cuCtxGetId", 2) => { + if version >= 12000 { + return cuCtxGetId as _; + } + usize::MAX as _ + } + (b"cuCtxGetLimit", 0) => { + if version >= 3010 { + return cuCtxGetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxGetLimit", 1) => { + if version >= 3010 { + return cuCtxGetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxGetLimit", 2) => { + if version >= 3010 { + return cuCtxGetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxGetSharedMemConfig", 0) => { + if version >= 4020 { + return cuCtxGetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetSharedMemConfig", 1) => { + if version >= 4020 { + return cuCtxGetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetSharedMemConfig", 2) => { + if version >= 4020 { + return cuCtxGetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxGetStreamPriorityRange", 0) => { + if version >= 5050 { + return cuCtxGetStreamPriorityRange as _; + } + usize::MAX as _ + } + (b"cuCtxGetStreamPriorityRange", 1) => { + if version >= 5050 { + return cuCtxGetStreamPriorityRange as _; + } + usize::MAX as _ + } + (b"cuCtxGetStreamPriorityRange", 2) => { + if version >= 5050 { + return cuCtxGetStreamPriorityRange as _; + } + usize::MAX as _ + } + (b"cuCtxPopCurrent", 0) => { + if version >= 4000 { + return cuCtxPopCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPopCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxPopCurrent", 1) => { + if version >= 4000 { + return cuCtxPopCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPopCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxPopCurrent", 2) => { + if version >= 4000 { + return cuCtxPopCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPopCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxPushCurrent", 0) => { + if version >= 4000 { + return cuCtxPushCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPushCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxPushCurrent", 1) => { + if version >= 4000 { + return cuCtxPushCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPushCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxPushCurrent", 2) => { + if version >= 4000 { + return cuCtxPushCurrent_v2 as _; + } + if version >= 2000 { + return cuCtxPushCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxResetPersistingL2Cache", 0) => { + if version >= 11000 { + return cuCtxResetPersistingL2Cache as _; + } + usize::MAX as _ + } + (b"cuCtxResetPersistingL2Cache", 1) => { + if version >= 11000 { + return cuCtxResetPersistingL2Cache as _; + } + usize::MAX as _ + } + (b"cuCtxResetPersistingL2Cache", 2) => { + if version >= 11000 { + return cuCtxResetPersistingL2Cache as _; + } + usize::MAX as _ + } + (b"cuCtxSetCacheConfig", 0) => { + if version >= 3020 { + return cuCtxSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSetCacheConfig", 1) => { + if version >= 3020 { + return cuCtxSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSetCacheConfig", 2) => { + if version >= 3020 { + return cuCtxSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSetCurrent", 0) => { + if version >= 4000 { + return cuCtxSetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxSetCurrent", 1) => { + if version >= 4000 { + return cuCtxSetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxSetCurrent", 2) => { + if version >= 4000 { + return cuCtxSetCurrent as _; + } + usize::MAX as _ + } + (b"cuCtxSetFlags", 0) => { + if version >= 12010 { + return cuCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxSetFlags", 1) => { + if version >= 12010 { + return cuCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxSetFlags", 2) => { + if version >= 12010 { + return cuCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuCtxSetLimit", 0) => { + if version >= 3010 { + return cuCtxSetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxSetLimit", 1) => { + if version >= 3010 { + return cuCtxSetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxSetLimit", 2) => { + if version >= 3010 { + return cuCtxSetLimit as _; + } + usize::MAX as _ + } + (b"cuCtxSetSharedMemConfig", 0) => { + if version >= 4020 { + return cuCtxSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSetSharedMemConfig", 1) => { + if version >= 4020 { + return cuCtxSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSetSharedMemConfig", 2) => { + if version >= 4020 { + return cuCtxSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuCtxSynchronize", 0) => { + if version >= 2000 { + return cuCtxSynchronize as _; + } + usize::MAX as _ + } + (b"cuCtxSynchronize", 1) => { + if version >= 2000 { + return cuCtxSynchronize as _; + } + usize::MAX as _ + } + (b"cuCtxSynchronize", 2) => { + if version >= 2000 { + return cuCtxSynchronize as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalMemory", 0) => { + if version >= 10000 { + return cuDestroyExternalMemory as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalMemory", 1) => { + if version >= 10000 { + return cuDestroyExternalMemory as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalMemory", 2) => { + if version >= 10000 { + return cuDestroyExternalMemory as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalSemaphore", 0) => { + if version >= 10000 { + return cuDestroyExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalSemaphore", 1) => { + if version >= 10000 { + return cuDestroyExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuDestroyExternalSemaphore", 2) => { + if version >= 10000 { + return cuDestroyExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuDeviceCanAccessPeer", 0) => { + if version >= 4000 { + return cuDeviceCanAccessPeer as _; + } + usize::MAX as _ + } + (b"cuDeviceCanAccessPeer", 1) => { + if version >= 4000 { + return cuDeviceCanAccessPeer as _; + } + usize::MAX as _ + } + (b"cuDeviceCanAccessPeer", 2) => { + if version >= 4000 { + return cuDeviceCanAccessPeer as _; + } + usize::MAX as _ + } + (b"cuDeviceComputeCapability", 0) => { + if version >= 2000 { + return cuDeviceComputeCapability as _; + } + usize::MAX as _ + } + (b"cuDeviceComputeCapability", 1) => { + if version >= 2000 { + return cuDeviceComputeCapability as _; + } + usize::MAX as _ + } + (b"cuDeviceComputeCapability", 2) => { + if version >= 2000 { + return cuDeviceComputeCapability as _; + } + usize::MAX as _ + } + (b"cuDeviceGet", 0) => { + if version >= 2000 { + return cuDeviceGet as _; + } + usize::MAX as _ + } + (b"cuDeviceGet", 1) => { + if version >= 2000 { + return cuDeviceGet as _; + } + usize::MAX as _ + } + (b"cuDeviceGet", 2) => { + if version >= 2000 { + return cuDeviceGet as _; + } + usize::MAX as _ + } + (b"cuDeviceGetAttribute", 0) => { + if version >= 2000 { + return cuDeviceGetAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetAttribute", 1) => { + if version >= 2000 { + return cuDeviceGetAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetAttribute", 2) => { + if version >= 2000 { + return cuDeviceGetAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetByPCIBusId", 0) => { + if version >= 4010 { + return cuDeviceGetByPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetByPCIBusId", 1) => { + if version >= 4010 { + return cuDeviceGetByPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetByPCIBusId", 2) => { + if version >= 4010 { + return cuDeviceGetByPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetCount", 0) => { + if version >= 2000 { + return cuDeviceGetCount as _; + } + usize::MAX as _ + } + (b"cuDeviceGetCount", 1) => { + if version >= 2000 { + return cuDeviceGetCount as _; + } + usize::MAX as _ + } + (b"cuDeviceGetCount", 2) => { + if version >= 2000 { + return cuDeviceGetCount as _; + } + usize::MAX as _ + } + (b"cuDeviceGetDefaultMemPool", 0) => { + if version >= 11020 { + return cuDeviceGetDefaultMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetDefaultMemPool", 1) => { + if version >= 11020 { + return cuDeviceGetDefaultMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetDefaultMemPool", 2) => { + if version >= 11020 { + return cuDeviceGetDefaultMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetExecAffinitySupport", 0) => { + if version >= 11040 { + return cuDeviceGetExecAffinitySupport as _; + } + usize::MAX as _ + } + (b"cuDeviceGetExecAffinitySupport", 1) => { + if version >= 11040 { + return cuDeviceGetExecAffinitySupport as _; + } + usize::MAX as _ + } + (b"cuDeviceGetExecAffinitySupport", 2) => { + if version >= 11040 { + return cuDeviceGetExecAffinitySupport as _; + } + usize::MAX as _ + } + (b"cuDeviceGetGraphMemAttribute", 0) => { + if version >= 11040 { + return cuDeviceGetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetGraphMemAttribute", 1) => { + if version >= 11040 { + return cuDeviceGetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetGraphMemAttribute", 2) => { + if version >= 11040 { + return cuDeviceGetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetLuid", 0) => { + if version >= 10000 { + return cuDeviceGetLuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGetLuid", 1) => { + if version >= 10000 { + return cuDeviceGetLuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGetLuid", 2) => { + if version >= 10000 { + return cuDeviceGetLuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGetMemPool", 0) => { + if version >= 11020 { + return cuDeviceGetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetMemPool", 1) => { + if version >= 11020 { + return cuDeviceGetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetMemPool", 2) => { + if version >= 11020 { + return cuDeviceGetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceGetName", 0) => { + if version >= 2000 { + return cuDeviceGetName as _; + } + usize::MAX as _ + } + (b"cuDeviceGetName", 1) => { + if version >= 2000 { + return cuDeviceGetName as _; + } + usize::MAX as _ + } + (b"cuDeviceGetName", 2) => { + if version >= 2000 { + return cuDeviceGetName as _; + } + usize::MAX as _ + } + (b"cuDeviceGetP2PAttribute", 0) => { + if version >= 8000 { + return cuDeviceGetP2PAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetP2PAttribute", 1) => { + if version >= 8000 { + return cuDeviceGetP2PAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetP2PAttribute", 2) => { + if version >= 8000 { + return cuDeviceGetP2PAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceGetPCIBusId", 0) => { + if version >= 4010 { + return cuDeviceGetPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetPCIBusId", 1) => { + if version >= 4010 { + return cuDeviceGetPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetPCIBusId", 2) => { + if version >= 4010 { + return cuDeviceGetPCIBusId as _; + } + usize::MAX as _ + } + (b"cuDeviceGetProperties", 0) => { + if version >= 2000 { + return cuDeviceGetProperties as _; + } + usize::MAX as _ + } + (b"cuDeviceGetProperties", 1) => { + if version >= 2000 { + return cuDeviceGetProperties as _; + } + usize::MAX as _ + } + (b"cuDeviceGetProperties", 2) => { + if version >= 2000 { + return cuDeviceGetProperties as _; + } + usize::MAX as _ + } + (b"cuDeviceGetTexture1DLinearMaxWidth", 0) => { + if version >= 11010 { + return cuDeviceGetTexture1DLinearMaxWidth as _; + } + usize::MAX as _ + } + (b"cuDeviceGetTexture1DLinearMaxWidth", 1) => { + if version >= 11010 { + return cuDeviceGetTexture1DLinearMaxWidth as _; + } + usize::MAX as _ + } + (b"cuDeviceGetTexture1DLinearMaxWidth", 2) => { + if version >= 11010 { + return cuDeviceGetTexture1DLinearMaxWidth as _; + } + usize::MAX as _ + } + (b"cuDeviceGetUuid", 0) => { + if version >= 11040 { + return cuDeviceGetUuid_v2 as _; + } + if version >= 9020 { + return cuDeviceGetUuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGetUuid", 1) => { + if version >= 11040 { + return cuDeviceGetUuid_v2 as _; + } + if version >= 9020 { + return cuDeviceGetUuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGetUuid", 2) => { + if version >= 11040 { + return cuDeviceGetUuid_v2 as _; + } + if version >= 9020 { + return cuDeviceGetUuid as _; + } + usize::MAX as _ + } + (b"cuDeviceGraphMemTrim", 0) => { + if version >= 11040 { + return cuDeviceGraphMemTrim as _; + } + usize::MAX as _ + } + (b"cuDeviceGraphMemTrim", 1) => { + if version >= 11040 { + return cuDeviceGraphMemTrim as _; + } + usize::MAX as _ + } + (b"cuDeviceGraphMemTrim", 2) => { + if version >= 11040 { + return cuDeviceGraphMemTrim as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxGetState", 0) => { + if version >= 7000 { + return cuDevicePrimaryCtxGetState as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxGetState", 1) => { + if version >= 7000 { + return cuDevicePrimaryCtxGetState as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxGetState", 2) => { + if version >= 7000 { + return cuDevicePrimaryCtxGetState as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRelease", 0) => { + if version >= 11000 { + return cuDevicePrimaryCtxRelease_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxRelease as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRelease", 1) => { + if version >= 11000 { + return cuDevicePrimaryCtxRelease_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxRelease as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRelease", 2) => { + if version >= 11000 { + return cuDevicePrimaryCtxRelease_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxRelease as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxReset", 0) => { + if version >= 11000 { + return cuDevicePrimaryCtxReset_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxReset as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxReset", 1) => { + if version >= 11000 { + return cuDevicePrimaryCtxReset_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxReset as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxReset", 2) => { + if version >= 11000 { + return cuDevicePrimaryCtxReset_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxReset as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRetain", 0) => { + if version >= 7000 { + return cuDevicePrimaryCtxRetain as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRetain", 1) => { + if version >= 7000 { + return cuDevicePrimaryCtxRetain as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxRetain", 2) => { + if version >= 7000 { + return cuDevicePrimaryCtxRetain as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxSetFlags", 0) => { + if version >= 11000 { + return cuDevicePrimaryCtxSetFlags_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxSetFlags", 1) => { + if version >= 11000 { + return cuDevicePrimaryCtxSetFlags_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuDevicePrimaryCtxSetFlags", 2) => { + if version >= 11000 { + return cuDevicePrimaryCtxSetFlags_v2 as _; + } + if version >= 7000 { + return cuDevicePrimaryCtxSetFlags as _; + } + usize::MAX as _ + } + (b"cuDeviceSetGraphMemAttribute", 0) => { + if version >= 11040 { + return cuDeviceSetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceSetGraphMemAttribute", 1) => { + if version >= 11040 { + return cuDeviceSetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceSetGraphMemAttribute", 2) => { + if version >= 11040 { + return cuDeviceSetGraphMemAttribute as _; + } + usize::MAX as _ + } + (b"cuDeviceSetMemPool", 0) => { + if version >= 11020 { + return cuDeviceSetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceSetMemPool", 1) => { + if version >= 11020 { + return cuDeviceSetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceSetMemPool", 2) => { + if version >= 11020 { + return cuDeviceSetMemPool as _; + } + usize::MAX as _ + } + (b"cuDeviceTotalMem", 0) => { + if version >= 3020 { + return cuDeviceTotalMem_v2 as _; + } + if version >= 2000 { + return cuDeviceTotalMem as _; + } + usize::MAX as _ + } + (b"cuDeviceTotalMem", 1) => { + if version >= 3020 { + return cuDeviceTotalMem_v2 as _; + } + if version >= 2000 { + return cuDeviceTotalMem as _; + } + usize::MAX as _ + } + (b"cuDeviceTotalMem", 2) => { + if version >= 3020 { + return cuDeviceTotalMem_v2 as _; + } + if version >= 2000 { + return cuDeviceTotalMem as _; + } + usize::MAX as _ + } + (b"cuDriverGetVersion", 0) => { + if version >= 2020 { + return cuDriverGetVersion as _; + } + usize::MAX as _ + } + (b"cuDriverGetVersion", 1) => { + if version >= 2020 { + return cuDriverGetVersion as _; + } + usize::MAX as _ + } + (b"cuDriverGetVersion", 2) => { + if version >= 2020 { + return cuDriverGetVersion as _; + } + usize::MAX as _ + } + (b"cuEventCreate", 0) => { + if version >= 2000 { + return cuEventCreate as _; + } + usize::MAX as _ + } + (b"cuEventCreate", 1) => { + if version >= 2000 { + return cuEventCreate as _; + } + usize::MAX as _ + } + (b"cuEventCreate", 2) => { + if version >= 2000 { + return cuEventCreate as _; + } + usize::MAX as _ + } + (b"cuEventDestroy", 0) => { + if version >= 4000 { + return cuEventDestroy_v2 as _; + } + if version >= 2000 { + return cuEventDestroy as _; + } + usize::MAX as _ + } + (b"cuEventDestroy", 1) => { + if version >= 4000 { + return cuEventDestroy_v2 as _; + } + if version >= 2000 { + return cuEventDestroy as _; + } + usize::MAX as _ + } + (b"cuEventDestroy", 2) => { + if version >= 4000 { + return cuEventDestroy_v2 as _; + } + if version >= 2000 { + return cuEventDestroy as _; + } + usize::MAX as _ + } + (b"cuEventElapsedTime", 0) => { + if version >= 2000 { + return cuEventElapsedTime as _; + } + usize::MAX as _ + } + (b"cuEventElapsedTime", 1) => { + if version >= 2000 { + return cuEventElapsedTime as _; + } + usize::MAX as _ + } + (b"cuEventElapsedTime", 2) => { + if version >= 2000 { + return cuEventElapsedTime as _; + } + usize::MAX as _ + } + (b"cuEventQuery", 0) => { + if version >= 2000 { + return cuEventQuery as _; + } + usize::MAX as _ + } + (b"cuEventQuery", 1) => { + if version >= 2000 { + return cuEventQuery as _; + } + usize::MAX as _ + } + (b"cuEventQuery", 2) => { + if version >= 2000 { + return cuEventQuery as _; + } + usize::MAX as _ + } + (b"cuEventRecord", 0) => { + if version >= 2000 { + return cuEventRecord as _; + } + usize::MAX as _ + } + (b"cuEventRecord", 1) => { + if version >= 2000 { + return cuEventRecord as _; + } + usize::MAX as _ + } + (b"cuEventRecord", 2) => { + if version >= 7000 { + return cuEventRecord_ptsz as _; + } + usize::MAX as _ + } + (b"cuEventRecordWithFlags", 0) => { + if version >= 11010 { + return cuEventRecordWithFlags as _; + } + usize::MAX as _ + } + (b"cuEventRecordWithFlags", 1) => { + if version >= 11010 { + return cuEventRecordWithFlags as _; + } + usize::MAX as _ + } + (b"cuEventRecordWithFlags", 2) => { + if version >= 11010 { + return cuEventRecordWithFlags_ptsz as _; + } + usize::MAX as _ + } + (b"cuEventSynchronize", 0) => { + if version >= 2000 { + return cuEventSynchronize as _; + } + usize::MAX as _ + } + (b"cuEventSynchronize", 1) => { + if version >= 2000 { + return cuEventSynchronize as _; + } + usize::MAX as _ + } + (b"cuEventSynchronize", 2) => { + if version >= 2000 { + return cuEventSynchronize as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedBuffer", 0) => { + if version >= 10000 { + return cuExternalMemoryGetMappedBuffer as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedBuffer", 1) => { + if version >= 10000 { + return cuExternalMemoryGetMappedBuffer as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedBuffer", 2) => { + if version >= 10000 { + return cuExternalMemoryGetMappedBuffer as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedMipmappedArray", 0) => { + if version >= 10000 { + return cuExternalMemoryGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedMipmappedArray", 1) => { + if version >= 10000 { + return cuExternalMemoryGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuExternalMemoryGetMappedMipmappedArray", 2) => { + if version >= 10000 { + return cuExternalMemoryGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuFlushGPUDirectRDMAWrites", 0) => { + if version >= 11030 { + return cuFlushGPUDirectRDMAWrites as _; + } + usize::MAX as _ + } + (b"cuFlushGPUDirectRDMAWrites", 1) => { + if version >= 11030 { + return cuFlushGPUDirectRDMAWrites as _; + } + usize::MAX as _ + } + (b"cuFlushGPUDirectRDMAWrites", 2) => { + if version >= 11030 { + return cuFlushGPUDirectRDMAWrites as _; + } + usize::MAX as _ + } + (b"cuFuncGetAttribute", 0) => { + if version >= 2020 { + return cuFuncGetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncGetAttribute", 1) => { + if version >= 2020 { + return cuFuncGetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncGetAttribute", 2) => { + if version >= 2020 { + return cuFuncGetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncGetModule", 0) => { + if version >= 11000 { + return cuFuncGetModule as _; + } + usize::MAX as _ + } + (b"cuFuncGetModule", 1) => { + if version >= 11000 { + return cuFuncGetModule as _; + } + usize::MAX as _ + } + (b"cuFuncGetModule", 2) => { + if version >= 11000 { + return cuFuncGetModule as _; + } + usize::MAX as _ + } + (b"cuFuncSetAttribute", 0) => { + if version >= 9000 { + return cuFuncSetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncSetAttribute", 1) => { + if version >= 9000 { + return cuFuncSetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncSetAttribute", 2) => { + if version >= 9000 { + return cuFuncSetAttribute as _; + } + usize::MAX as _ + } + (b"cuFuncSetBlockShape", 0) => { + if version >= 2000 { + return cuFuncSetBlockShape as _; + } + usize::MAX as _ + } + (b"cuFuncSetBlockShape", 1) => { + if version >= 2000 { + return cuFuncSetBlockShape as _; + } + usize::MAX as _ + } + (b"cuFuncSetBlockShape", 2) => { + if version >= 2000 { + return cuFuncSetBlockShape as _; + } + usize::MAX as _ + } + (b"cuFuncSetCacheConfig", 0) => { + if version >= 3000 { + return cuFuncSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetCacheConfig", 1) => { + if version >= 3000 { + return cuFuncSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetCacheConfig", 2) => { + if version >= 3000 { + return cuFuncSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedMemConfig", 0) => { + if version >= 4020 { + return cuFuncSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedMemConfig", 1) => { + if version >= 4020 { + return cuFuncSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedMemConfig", 2) => { + if version >= 4020 { + return cuFuncSetSharedMemConfig as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedSize", 0) => { + if version >= 2000 { + return cuFuncSetSharedSize as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedSize", 1) => { + if version >= 2000 { + return cuFuncSetSharedSize as _; + } + usize::MAX as _ + } + (b"cuFuncSetSharedSize", 2) => { + if version >= 2000 { + return cuFuncSetSharedSize as _; + } + usize::MAX as _ + } + (b"cuGLCtxCreate", 0) => { + if version >= 3020 { + return cuGLCtxCreate_v2 as _; + } + if version >= 2000 { + return cuGLCtxCreate as _; + } + usize::MAX as _ + } + (b"cuGLCtxCreate", 1) => { + if version >= 3020 { + return cuGLCtxCreate_v2 as _; + } + if version >= 2000 { + return cuGLCtxCreate as _; + } + usize::MAX as _ + } + (b"cuGLCtxCreate", 2) => { + if version >= 3020 { + return cuGLCtxCreate_v2 as _; + } + if version >= 2000 { + return cuGLCtxCreate as _; + } + usize::MAX as _ + } + (b"cuGLGetDevices", 0) => { + if version >= 6050 { + return cuGLGetDevices_v2 as _; + } + if version >= 4010 { + return cuGLGetDevices as _; + } + usize::MAX as _ + } + (b"cuGLGetDevices", 1) => { + if version >= 6050 { + return cuGLGetDevices_v2 as _; + } + if version >= 4010 { + return cuGLGetDevices as _; + } + usize::MAX as _ + } + (b"cuGLGetDevices", 2) => { + if version >= 6050 { + return cuGLGetDevices_v2 as _; + } + if version >= 4010 { + return cuGLGetDevices as _; + } + usize::MAX as _ + } + (b"cuGLInit", 0) => { + if version >= 2000 { + return cuGLInit as _; + } + usize::MAX as _ + } + (b"cuGLInit", 1) => { + if version >= 2000 { + return cuGLInit as _; + } + usize::MAX as _ + } + (b"cuGLInit", 2) => { + if version >= 2000 { + return cuGLInit as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObject", 0) => { + if version >= 3020 { + return cuGLMapBufferObject_v2 as _; + } + if version >= 2000 { + return cuGLMapBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObject", 1) => { + if version >= 3020 { + return cuGLMapBufferObject_v2 as _; + } + if version >= 2000 { + return cuGLMapBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObject", 2) => { + if version >= 7000 { + return cuGLMapBufferObject_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObjectAsync", 0) => { + if version >= 3020 { + return cuGLMapBufferObjectAsync_v2 as _; + } + if version >= 2030 { + return cuGLMapBufferObjectAsync as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObjectAsync", 1) => { + if version >= 3020 { + return cuGLMapBufferObjectAsync_v2 as _; + } + if version >= 2030 { + return cuGLMapBufferObjectAsync as _; + } + usize::MAX as _ + } + (b"cuGLMapBufferObjectAsync", 2) => { + if version >= 7000 { + return cuGLMapBufferObjectAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuGLRegisterBufferObject", 0) => { + if version >= 2000 { + return cuGLRegisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLRegisterBufferObject", 1) => { + if version >= 2000 { + return cuGLRegisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLRegisterBufferObject", 2) => { + if version >= 2000 { + return cuGLRegisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLSetBufferObjectMapFlags", 0) => { + if version >= 2030 { + return cuGLSetBufferObjectMapFlags as _; + } + usize::MAX as _ + } + (b"cuGLSetBufferObjectMapFlags", 1) => { + if version >= 2030 { + return cuGLSetBufferObjectMapFlags as _; + } + usize::MAX as _ + } + (b"cuGLSetBufferObjectMapFlags", 2) => { + if version >= 2030 { + return cuGLSetBufferObjectMapFlags as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObject", 0) => { + if version >= 2000 { + return cuGLUnmapBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObject", 1) => { + if version >= 2000 { + return cuGLUnmapBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObject", 2) => { + if version >= 2000 { + return cuGLUnmapBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObjectAsync", 0) => { + if version >= 2030 { + return cuGLUnmapBufferObjectAsync as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObjectAsync", 1) => { + if version >= 2030 { + return cuGLUnmapBufferObjectAsync as _; + } + usize::MAX as _ + } + (b"cuGLUnmapBufferObjectAsync", 2) => { + if version >= 2030 { + return cuGLUnmapBufferObjectAsync as _; + } + usize::MAX as _ + } + (b"cuGLUnregisterBufferObject", 0) => { + if version >= 2000 { + return cuGLUnregisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLUnregisterBufferObject", 1) => { + if version >= 2000 { + return cuGLUnregisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGLUnregisterBufferObject", 2) => { + if version >= 2000 { + return cuGLUnregisterBufferObject as _; + } + usize::MAX as _ + } + (b"cuGetErrorName", 0) => { + if version >= 6000 { + return cuGetErrorName as _; + } + usize::MAX as _ + } + (b"cuGetErrorName", 1) => { + if version >= 6000 { + return cuGetErrorName as _; + } + usize::MAX as _ + } + (b"cuGetErrorName", 2) => { + if version >= 6000 { + return cuGetErrorName as _; + } + usize::MAX as _ + } + (b"cuGetErrorString", 0) => { + if version >= 6000 { + return cuGetErrorString as _; + } + usize::MAX as _ + } + (b"cuGetErrorString", 1) => { + if version >= 6000 { + return cuGetErrorString as _; + } + usize::MAX as _ + } + (b"cuGetErrorString", 2) => { + if version >= 6000 { + return cuGetErrorString as _; + } + usize::MAX as _ + } + (b"cuGetExportTable", 0) => { + if version >= 3000 { + return cuGetExportTable as _; + } + usize::MAX as _ + } + (b"cuGetExportTable", 1) => { + if version >= 3000 { + return cuGetExportTable as _; + } + usize::MAX as _ + } + (b"cuGetExportTable", 2) => { + if version >= 3000 { + return cuGetExportTable as _; + } + usize::MAX as _ + } + (b"cuGetProcAddress", 0) => { + if version >= 12000 { + return cuGetProcAddress_v2 as _; + } + if version >= 11030 { + return cuGetProcAddress as _; + } + usize::MAX as _ + } + (b"cuGetProcAddress", 1) => { + if version >= 12000 { + return cuGetProcAddress_v2 as _; + } + if version >= 11030 { + return cuGetProcAddress as _; + } + usize::MAX as _ + } + (b"cuGetProcAddress", 2) => { + if version >= 12000 { + return cuGetProcAddress_v2 as _; + } + if version >= 11030 { + return cuGetProcAddress as _; + } + usize::MAX as _ + } + (b"cuGraphAddBatchMemOpNode", 0) => { + if version >= 11070 { + return cuGraphAddBatchMemOpNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddBatchMemOpNode", 1) => { + if version >= 11070 { + return cuGraphAddBatchMemOpNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddBatchMemOpNode", 2) => { + if version >= 11070 { + return cuGraphAddBatchMemOpNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddChildGraphNode", 0) => { + if version >= 10000 { + return cuGraphAddChildGraphNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddChildGraphNode", 1) => { + if version >= 10000 { + return cuGraphAddChildGraphNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddChildGraphNode", 2) => { + if version >= 10000 { + return cuGraphAddChildGraphNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddDependencies", 0) => { + if version >= 10000 { + return cuGraphAddDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphAddDependencies", 1) => { + if version >= 10000 { + return cuGraphAddDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphAddDependencies", 2) => { + if version >= 10000 { + return cuGraphAddDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphAddEmptyNode", 0) => { + if version >= 10000 { + return cuGraphAddEmptyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEmptyNode", 1) => { + if version >= 10000 { + return cuGraphAddEmptyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEmptyNode", 2) => { + if version >= 10000 { + return cuGraphAddEmptyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventRecordNode", 0) => { + if version >= 11010 { + return cuGraphAddEventRecordNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventRecordNode", 1) => { + if version >= 11010 { + return cuGraphAddEventRecordNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventRecordNode", 2) => { + if version >= 11010 { + return cuGraphAddEventRecordNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventWaitNode", 0) => { + if version >= 11010 { + return cuGraphAddEventWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventWaitNode", 1) => { + if version >= 11010 { + return cuGraphAddEventWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddEventWaitNode", 2) => { + if version >= 11010 { + return cuGraphAddEventWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresSignalNode", 0) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresSignalNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresSignalNode", 1) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresSignalNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresSignalNode", 2) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresSignalNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresWaitNode", 0) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresWaitNode", 1) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddExternalSemaphoresWaitNode", 2) => { + if version >= 11020 { + return cuGraphAddExternalSemaphoresWaitNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddHostNode", 0) => { + if version >= 10000 { + return cuGraphAddHostNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddHostNode", 1) => { + if version >= 10000 { + return cuGraphAddHostNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddHostNode", 2) => { + if version >= 10000 { + return cuGraphAddHostNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddKernelNode", 0) => { + if version >= 12000 { + return cuGraphAddKernelNode_v2 as _; + } + if version >= 10000 { + return cuGraphAddKernelNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddKernelNode", 1) => { + if version >= 12000 { + return cuGraphAddKernelNode_v2 as _; + } + if version >= 10000 { + return cuGraphAddKernelNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddKernelNode", 2) => { + if version >= 12000 { + return cuGraphAddKernelNode_v2 as _; + } + if version >= 10000 { + return cuGraphAddKernelNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemAllocNode", 0) => { + if version >= 11040 { + return cuGraphAddMemAllocNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemAllocNode", 1) => { + if version >= 11040 { + return cuGraphAddMemAllocNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemAllocNode", 2) => { + if version >= 11040 { + return cuGraphAddMemAllocNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemFreeNode", 0) => { + if version >= 11040 { + return cuGraphAddMemFreeNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemFreeNode", 1) => { + if version >= 11040 { + return cuGraphAddMemFreeNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemFreeNode", 2) => { + if version >= 11040 { + return cuGraphAddMemFreeNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemcpyNode", 0) => { + if version >= 10000 { + return cuGraphAddMemcpyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemcpyNode", 1) => { + if version >= 10000 { + return cuGraphAddMemcpyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemcpyNode", 2) => { + if version >= 10000 { + return cuGraphAddMemcpyNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemsetNode", 0) => { + if version >= 10000 { + return cuGraphAddMemsetNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemsetNode", 1) => { + if version >= 10000 { + return cuGraphAddMemsetNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddMemsetNode", 2) => { + if version >= 10000 { + return cuGraphAddMemsetNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddNode", 0) => { + if version >= 12020 { + return cuGraphAddNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddNode", 1) => { + if version >= 12020 { + return cuGraphAddNode as _; + } + usize::MAX as _ + } + (b"cuGraphAddNode", 2) => { + if version >= 12020 { + return cuGraphAddNode as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeGetParams", 0) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeGetParams", 1) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeGetParams", 2) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeSetParams", 0) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeSetParams", 1) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphBatchMemOpNodeSetParams", 2) => { + if version >= 11070 { + return cuGraphBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphChildGraphNodeGetGraph", 0) => { + if version >= 10000 { + return cuGraphChildGraphNodeGetGraph as _; + } + usize::MAX as _ + } + (b"cuGraphChildGraphNodeGetGraph", 1) => { + if version >= 10000 { + return cuGraphChildGraphNodeGetGraph as _; + } + usize::MAX as _ + } + (b"cuGraphChildGraphNodeGetGraph", 2) => { + if version >= 10000 { + return cuGraphChildGraphNodeGetGraph as _; + } + usize::MAX as _ + } + (b"cuGraphClone", 0) => { + if version >= 10000 { + return cuGraphClone as _; + } + usize::MAX as _ + } + (b"cuGraphClone", 1) => { + if version >= 10000 { + return cuGraphClone as _; + } + usize::MAX as _ + } + (b"cuGraphClone", 2) => { + if version >= 10000 { + return cuGraphClone as _; + } + usize::MAX as _ + } + (b"cuGraphCreate", 0) => { + if version >= 10000 { + return cuGraphCreate as _; + } + usize::MAX as _ + } + (b"cuGraphCreate", 1) => { + if version >= 10000 { + return cuGraphCreate as _; + } + usize::MAX as _ + } + (b"cuGraphCreate", 2) => { + if version >= 10000 { + return cuGraphCreate as _; + } + usize::MAX as _ + } + (b"cuGraphDebugDotPrint", 0) => { + if version >= 11030 { + return cuGraphDebugDotPrint as _; + } + usize::MAX as _ + } + (b"cuGraphDebugDotPrint", 1) => { + if version >= 11030 { + return cuGraphDebugDotPrint as _; + } + usize::MAX as _ + } + (b"cuGraphDebugDotPrint", 2) => { + if version >= 11030 { + return cuGraphDebugDotPrint as _; + } + usize::MAX as _ + } + (b"cuGraphDestroy", 0) => { + if version >= 10000 { + return cuGraphDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphDestroy", 1) => { + if version >= 10000 { + return cuGraphDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphDestroy", 2) => { + if version >= 10000 { + return cuGraphDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphDestroyNode", 0) => { + if version >= 10000 { + return cuGraphDestroyNode as _; + } + usize::MAX as _ + } + (b"cuGraphDestroyNode", 1) => { + if version >= 10000 { + return cuGraphDestroyNode as _; + } + usize::MAX as _ + } + (b"cuGraphDestroyNode", 2) => { + if version >= 10000 { + return cuGraphDestroyNode as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeGetEvent", 0) => { + if version >= 11010 { + return cuGraphEventRecordNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeGetEvent", 1) => { + if version >= 11010 { + return cuGraphEventRecordNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeGetEvent", 2) => { + if version >= 11010 { + return cuGraphEventRecordNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeSetEvent", 0) => { + if version >= 11010 { + return cuGraphEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeSetEvent", 1) => { + if version >= 11010 { + return cuGraphEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventRecordNodeSetEvent", 2) => { + if version >= 11010 { + return cuGraphEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeGetEvent", 0) => { + if version >= 11010 { + return cuGraphEventWaitNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeGetEvent", 1) => { + if version >= 11010 { + return cuGraphEventWaitNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeGetEvent", 2) => { + if version >= 11010 { + return cuGraphEventWaitNodeGetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeSetEvent", 0) => { + if version >= 11010 { + return cuGraphEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeSetEvent", 1) => { + if version >= 11010 { + return cuGraphEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphEventWaitNodeSetEvent", 2) => { + if version >= 11010 { + return cuGraphEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecBatchMemOpNodeSetParams", 0) => { + if version >= 11070 { + return cuGraphExecBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecBatchMemOpNodeSetParams", 1) => { + if version >= 11070 { + return cuGraphExecBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecBatchMemOpNodeSetParams", 2) => { + if version >= 11070 { + return cuGraphExecBatchMemOpNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecChildGraphNodeSetParams", 0) => { + if version >= 11010 { + return cuGraphExecChildGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecChildGraphNodeSetParams", 1) => { + if version >= 11010 { + return cuGraphExecChildGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecChildGraphNodeSetParams", 2) => { + if version >= 11010 { + return cuGraphExecChildGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecDestroy", 0) => { + if version >= 10000 { + return cuGraphExecDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphExecDestroy", 1) => { + if version >= 10000 { + return cuGraphExecDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphExecDestroy", 2) => { + if version >= 10000 { + return cuGraphExecDestroy as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventRecordNodeSetEvent", 0) => { + if version >= 11010 { + return cuGraphExecEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventRecordNodeSetEvent", 1) => { + if version >= 11010 { + return cuGraphExecEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventRecordNodeSetEvent", 2) => { + if version >= 11010 { + return cuGraphExecEventRecordNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventWaitNodeSetEvent", 0) => { + if version >= 11010 { + return cuGraphExecEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventWaitNodeSetEvent", 1) => { + if version >= 11010 { + return cuGraphExecEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecEventWaitNodeSetEvent", 2) => { + if version >= 11010 { + return cuGraphExecEventWaitNodeSetEvent as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresSignalNodeSetParams", 0) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresSignalNodeSetParams", 1) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresSignalNodeSetParams", 2) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresWaitNodeSetParams", 0) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresWaitNodeSetParams", 1) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecExternalSemaphoresWaitNodeSetParams", 2) => { + if version >= 11020 { + return cuGraphExecExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecGetFlags", 0) => { + if version >= 12000 { + return cuGraphExecGetFlags as _; + } + usize::MAX as _ + } + (b"cuGraphExecGetFlags", 1) => { + if version >= 12000 { + return cuGraphExecGetFlags as _; + } + usize::MAX as _ + } + (b"cuGraphExecGetFlags", 2) => { + if version >= 12000 { + return cuGraphExecGetFlags as _; + } + usize::MAX as _ + } + (b"cuGraphExecHostNodeSetParams", 0) => { + if version >= 10020 { + return cuGraphExecHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecHostNodeSetParams", 1) => { + if version >= 10020 { + return cuGraphExecHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecHostNodeSetParams", 2) => { + if version >= 10020 { + return cuGraphExecHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecKernelNodeSetParams", 0) => { + if version >= 12000 { + return cuGraphExecKernelNodeSetParams_v2 as _; + } + if version >= 10010 { + return cuGraphExecKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecKernelNodeSetParams", 1) => { + if version >= 12000 { + return cuGraphExecKernelNodeSetParams_v2 as _; + } + if version >= 10010 { + return cuGraphExecKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecKernelNodeSetParams", 2) => { + if version >= 12000 { + return cuGraphExecKernelNodeSetParams_v2 as _; + } + if version >= 10010 { + return cuGraphExecKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemcpyNodeSetParams", 0) => { + if version >= 10020 { + return cuGraphExecMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemcpyNodeSetParams", 1) => { + if version >= 10020 { + return cuGraphExecMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemcpyNodeSetParams", 2) => { + if version >= 10020 { + return cuGraphExecMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemsetNodeSetParams", 0) => { + if version >= 10020 { + return cuGraphExecMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemsetNodeSetParams", 1) => { + if version >= 10020 { + return cuGraphExecMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecMemsetNodeSetParams", 2) => { + if version >= 10020 { + return cuGraphExecMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecNodeSetParams", 0) => { + if version >= 12020 { + return cuGraphExecNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecNodeSetParams", 1) => { + if version >= 12020 { + return cuGraphExecNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecNodeSetParams", 2) => { + if version >= 12020 { + return cuGraphExecNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExecUpdate", 0) => { + if version >= 12000 { + return cuGraphExecUpdate_v2 as _; + } + if version >= 10020 { + return cuGraphExecUpdate as _; + } + usize::MAX as _ + } + (b"cuGraphExecUpdate", 1) => { + if version >= 12000 { + return cuGraphExecUpdate_v2 as _; + } + if version >= 10020 { + return cuGraphExecUpdate as _; + } + usize::MAX as _ + } + (b"cuGraphExecUpdate", 2) => { + if version >= 12000 { + return cuGraphExecUpdate_v2 as _; + } + if version >= 10020 { + return cuGraphExecUpdate as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeGetParams", 0) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeGetParams", 1) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeGetParams", 2) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeSetParams", 0) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeSetParams", 1) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresSignalNodeSetParams", 2) => { + if version >= 11020 { + return cuGraphExternalSemaphoresSignalNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeGetParams", 0) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeGetParams", 1) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeGetParams", 2) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeSetParams", 0) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeSetParams", 1) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphExternalSemaphoresWaitNodeSetParams", 2) => { + if version >= 11020 { + return cuGraphExternalSemaphoresWaitNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphGetEdges", 0) => { + if version >= 10000 { + return cuGraphGetEdges as _; + } + usize::MAX as _ + } + (b"cuGraphGetEdges", 1) => { + if version >= 10000 { + return cuGraphGetEdges as _; + } + usize::MAX as _ + } + (b"cuGraphGetEdges", 2) => { + if version >= 10000 { + return cuGraphGetEdges as _; + } + usize::MAX as _ + } + (b"cuGraphGetNodes", 0) => { + if version >= 10000 { + return cuGraphGetNodes as _; + } + usize::MAX as _ + } + (b"cuGraphGetNodes", 1) => { + if version >= 10000 { + return cuGraphGetNodes as _; + } + usize::MAX as _ + } + (b"cuGraphGetNodes", 2) => { + if version >= 10000 { + return cuGraphGetNodes as _; + } + usize::MAX as _ + } + (b"cuGraphGetRootNodes", 0) => { + if version >= 10000 { + return cuGraphGetRootNodes as _; + } + usize::MAX as _ + } + (b"cuGraphGetRootNodes", 1) => { + if version >= 10000 { + return cuGraphGetRootNodes as _; + } + usize::MAX as _ + } + (b"cuGraphGetRootNodes", 2) => { + if version >= 10000 { + return cuGraphGetRootNodes as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeGetParams", 0) => { + if version >= 10000 { + return cuGraphHostNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeGetParams", 1) => { + if version >= 10000 { + return cuGraphHostNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeGetParams", 2) => { + if version >= 10000 { + return cuGraphHostNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeSetParams", 0) => { + if version >= 10000 { + return cuGraphHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeSetParams", 1) => { + if version >= 10000 { + return cuGraphHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphHostNodeSetParams", 2) => { + if version >= 10000 { + return cuGraphHostNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiate", 0) => { + if version >= 11000 { + return cuGraphInstantiate_v2 as _; + } + if version >= 10000 { + return cuGraphInstantiate as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiate", 1) => { + if version >= 11000 { + return cuGraphInstantiate_v2 as _; + } + if version >= 10000 { + return cuGraphInstantiate as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiate", 2) => { + if version >= 11000 { + return cuGraphInstantiate_v2 as _; + } + if version >= 10000 { + return cuGraphInstantiate as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithFlags", 0) => { + if version >= 11040 { + return cuGraphInstantiateWithFlags as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithFlags", 1) => { + if version >= 11040 { + return cuGraphInstantiateWithFlags as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithFlags", 2) => { + if version >= 11040 { + return cuGraphInstantiateWithFlags as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithParams", 0) => { + if version >= 12000 { + return cuGraphInstantiateWithParams as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithParams", 1) => { + if version >= 12000 { + return cuGraphInstantiateWithParams as _; + } + usize::MAX as _ + } + (b"cuGraphInstantiateWithParams", 2) => { + if version >= 12000 { + return cuGraphInstantiateWithParams_ptsz as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeCopyAttributes", 0) => { + if version >= 11000 { + return cuGraphKernelNodeCopyAttributes as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeCopyAttributes", 1) => { + if version >= 11000 { + return cuGraphKernelNodeCopyAttributes as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeCopyAttributes", 2) => { + if version >= 11000 { + return cuGraphKernelNodeCopyAttributes as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetAttribute", 0) => { + if version >= 11000 { + return cuGraphKernelNodeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetAttribute", 1) => { + if version >= 11000 { + return cuGraphKernelNodeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetAttribute", 2) => { + if version >= 11000 { + return cuGraphKernelNodeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetParams", 0) => { + if version >= 12000 { + return cuGraphKernelNodeGetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetParams", 1) => { + if version >= 12000 { + return cuGraphKernelNodeGetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeGetParams", 2) => { + if version >= 12000 { + return cuGraphKernelNodeGetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetAttribute", 0) => { + if version >= 11000 { + return cuGraphKernelNodeSetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetAttribute", 1) => { + if version >= 11000 { + return cuGraphKernelNodeSetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetAttribute", 2) => { + if version >= 11000 { + return cuGraphKernelNodeSetAttribute as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetParams", 0) => { + if version >= 12000 { + return cuGraphKernelNodeSetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetParams", 1) => { + if version >= 12000 { + return cuGraphKernelNodeSetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphKernelNodeSetParams", 2) => { + if version >= 12000 { + return cuGraphKernelNodeSetParams_v2 as _; + } + if version >= 10000 { + return cuGraphKernelNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphLaunch", 0) => { + if version >= 10000 { + return cuGraphLaunch as _; + } + usize::MAX as _ + } + (b"cuGraphLaunch", 1) => { + if version >= 10000 { + return cuGraphLaunch as _; + } + usize::MAX as _ + } + (b"cuGraphLaunch", 2) => { + if version >= 10000 { + return cuGraphLaunch_ptsz as _; + } + usize::MAX as _ + } + (b"cuGraphMemAllocNodeGetParams", 0) => { + if version >= 11040 { + return cuGraphMemAllocNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemAllocNodeGetParams", 1) => { + if version >= 11040 { + return cuGraphMemAllocNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemAllocNodeGetParams", 2) => { + if version >= 11040 { + return cuGraphMemAllocNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemFreeNodeGetParams", 0) => { + if version >= 11040 { + return cuGraphMemFreeNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemFreeNodeGetParams", 1) => { + if version >= 11040 { + return cuGraphMemFreeNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemFreeNodeGetParams", 2) => { + if version >= 11040 { + return cuGraphMemFreeNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeGetParams", 0) => { + if version >= 10000 { + return cuGraphMemcpyNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeGetParams", 1) => { + if version >= 10000 { + return cuGraphMemcpyNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeGetParams", 2) => { + if version >= 10000 { + return cuGraphMemcpyNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeSetParams", 0) => { + if version >= 10000 { + return cuGraphMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeSetParams", 1) => { + if version >= 10000 { + return cuGraphMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemcpyNodeSetParams", 2) => { + if version >= 10000 { + return cuGraphMemcpyNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeGetParams", 0) => { + if version >= 10000 { + return cuGraphMemsetNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeGetParams", 1) => { + if version >= 10000 { + return cuGraphMemsetNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeGetParams", 2) => { + if version >= 10000 { + return cuGraphMemsetNodeGetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeSetParams", 0) => { + if version >= 10000 { + return cuGraphMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeSetParams", 1) => { + if version >= 10000 { + return cuGraphMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphMemsetNodeSetParams", 2) => { + if version >= 10000 { + return cuGraphMemsetNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphNodeFindInClone", 0) => { + if version >= 10000 { + return cuGraphNodeFindInClone as _; + } + usize::MAX as _ + } + (b"cuGraphNodeFindInClone", 1) => { + if version >= 10000 { + return cuGraphNodeFindInClone as _; + } + usize::MAX as _ + } + (b"cuGraphNodeFindInClone", 2) => { + if version >= 10000 { + return cuGraphNodeFindInClone as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependencies", 0) => { + if version >= 10000 { + return cuGraphNodeGetDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependencies", 1) => { + if version >= 10000 { + return cuGraphNodeGetDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependencies", 2) => { + if version >= 10000 { + return cuGraphNodeGetDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependentNodes", 0) => { + if version >= 10000 { + return cuGraphNodeGetDependentNodes as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependentNodes", 1) => { + if version >= 10000 { + return cuGraphNodeGetDependentNodes as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetDependentNodes", 2) => { + if version >= 10000 { + return cuGraphNodeGetDependentNodes as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetEnabled", 0) => { + if version >= 11060 { + return cuGraphNodeGetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetEnabled", 1) => { + if version >= 11060 { + return cuGraphNodeGetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetEnabled", 2) => { + if version >= 11060 { + return cuGraphNodeGetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetType", 0) => { + if version >= 10000 { + return cuGraphNodeGetType as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetType", 1) => { + if version >= 10000 { + return cuGraphNodeGetType as _; + } + usize::MAX as _ + } + (b"cuGraphNodeGetType", 2) => { + if version >= 10000 { + return cuGraphNodeGetType as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetEnabled", 0) => { + if version >= 11060 { + return cuGraphNodeSetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetEnabled", 1) => { + if version >= 11060 { + return cuGraphNodeSetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetEnabled", 2) => { + if version >= 11060 { + return cuGraphNodeSetEnabled as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetParams", 0) => { + if version >= 12020 { + return cuGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetParams", 1) => { + if version >= 12020 { + return cuGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphNodeSetParams", 2) => { + if version >= 12020 { + return cuGraphNodeSetParams as _; + } + usize::MAX as _ + } + (b"cuGraphReleaseUserObject", 0) => { + if version >= 11030 { + return cuGraphReleaseUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphReleaseUserObject", 1) => { + if version >= 11030 { + return cuGraphReleaseUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphReleaseUserObject", 2) => { + if version >= 11030 { + return cuGraphReleaseUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphRemoveDependencies", 0) => { + if version >= 10000 { + return cuGraphRemoveDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphRemoveDependencies", 1) => { + if version >= 10000 { + return cuGraphRemoveDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphRemoveDependencies", 2) => { + if version >= 10000 { + return cuGraphRemoveDependencies as _; + } + usize::MAX as _ + } + (b"cuGraphRetainUserObject", 0) => { + if version >= 11030 { + return cuGraphRetainUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphRetainUserObject", 1) => { + if version >= 11030 { + return cuGraphRetainUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphRetainUserObject", 2) => { + if version >= 11030 { + return cuGraphRetainUserObject as _; + } + usize::MAX as _ + } + (b"cuGraphUpload", 0) => { + if version >= 11010 { + return cuGraphUpload as _; + } + usize::MAX as _ + } + (b"cuGraphUpload", 1) => { + if version >= 11010 { + return cuGraphUpload as _; + } + usize::MAX as _ + } + (b"cuGraphUpload", 2) => { + if version >= 11010 { + return cuGraphUpload_ptsz as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterBuffer", 0) => { + if version >= 3000 { + return cuGraphicsGLRegisterBuffer as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterBuffer", 1) => { + if version >= 3000 { + return cuGraphicsGLRegisterBuffer as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterBuffer", 2) => { + if version >= 3000 { + return cuGraphicsGLRegisterBuffer as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterImage", 0) => { + if version >= 3000 { + return cuGraphicsGLRegisterImage as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterImage", 1) => { + if version >= 3000 { + return cuGraphicsGLRegisterImage as _; + } + usize::MAX as _ + } + (b"cuGraphicsGLRegisterImage", 2) => { + if version >= 3000 { + return cuGraphicsGLRegisterImage as _; + } + usize::MAX as _ + } + (b"cuGraphicsMapResources", 0) => { + if version >= 3000 { + return cuGraphicsMapResources as _; + } + usize::MAX as _ + } + (b"cuGraphicsMapResources", 1) => { + if version >= 3000 { + return cuGraphicsMapResources as _; + } + usize::MAX as _ + } + (b"cuGraphicsMapResources", 2) => { + if version >= 7000 { + return cuGraphicsMapResources_ptsz as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedMipmappedArray", 0) => { + if version >= 5000 { + return cuGraphicsResourceGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedMipmappedArray", 1) => { + if version >= 5000 { + return cuGraphicsResourceGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedMipmappedArray", 2) => { + if version >= 5000 { + return cuGraphicsResourceGetMappedMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedPointer", 0) => { + if version >= 3020 { + return cuGraphicsResourceGetMappedPointer_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceGetMappedPointer as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedPointer", 1) => { + if version >= 3020 { + return cuGraphicsResourceGetMappedPointer_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceGetMappedPointer as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceGetMappedPointer", 2) => { + if version >= 3020 { + return cuGraphicsResourceGetMappedPointer_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceGetMappedPointer as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceSetMapFlags", 0) => { + if version >= 6050 { + return cuGraphicsResourceSetMapFlags_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceSetMapFlags as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceSetMapFlags", 1) => { + if version >= 6050 { + return cuGraphicsResourceSetMapFlags_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceSetMapFlags as _; + } + usize::MAX as _ + } + (b"cuGraphicsResourceSetMapFlags", 2) => { + if version >= 6050 { + return cuGraphicsResourceSetMapFlags_v2 as _; + } + if version >= 3000 { + return cuGraphicsResourceSetMapFlags as _; + } + usize::MAX as _ + } + (b"cuGraphicsSubResourceGetMappedArray", 0) => { + if version >= 3000 { + return cuGraphicsSubResourceGetMappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsSubResourceGetMappedArray", 1) => { + if version >= 3000 { + return cuGraphicsSubResourceGetMappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsSubResourceGetMappedArray", 2) => { + if version >= 3000 { + return cuGraphicsSubResourceGetMappedArray as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnmapResources", 0) => { + if version >= 3000 { + return cuGraphicsUnmapResources as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnmapResources", 1) => { + if version >= 3000 { + return cuGraphicsUnmapResources as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnmapResources", 2) => { + if version >= 7000 { + return cuGraphicsUnmapResources_ptsz as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnregisterResource", 0) => { + if version >= 3000 { + return cuGraphicsUnregisterResource as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnregisterResource", 1) => { + if version >= 3000 { + return cuGraphicsUnregisterResource as _; + } + usize::MAX as _ + } + (b"cuGraphicsUnregisterResource", 2) => { + if version >= 3000 { + return cuGraphicsUnregisterResource as _; + } + usize::MAX as _ + } + (b"cuImportExternalMemory", 0) => { + if version >= 10000 { + return cuImportExternalMemory as _; + } + usize::MAX as _ + } + (b"cuImportExternalMemory", 1) => { + if version >= 10000 { + return cuImportExternalMemory as _; + } + usize::MAX as _ + } + (b"cuImportExternalMemory", 2) => { + if version >= 10000 { + return cuImportExternalMemory as _; + } + usize::MAX as _ + } + (b"cuImportExternalSemaphore", 0) => { + if version >= 10000 { + return cuImportExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuImportExternalSemaphore", 1) => { + if version >= 10000 { + return cuImportExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuImportExternalSemaphore", 2) => { + if version >= 10000 { + return cuImportExternalSemaphore as _; + } + usize::MAX as _ + } + (b"cuInit", 0) => { + if version >= 2000 { + return cuInit as _; + } + usize::MAX as _ + } + (b"cuInit", 1) => { + if version >= 2000 { + return cuInit as _; + } + usize::MAX as _ + } + (b"cuInit", 2) => { + if version >= 2000 { + return cuInit as _; + } + usize::MAX as _ + } + (b"cuIpcCloseMemHandle", 0) => { + if version >= 4010 { + return cuIpcCloseMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcCloseMemHandle", 1) => { + if version >= 4010 { + return cuIpcCloseMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcCloseMemHandle", 2) => { + if version >= 4010 { + return cuIpcCloseMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetEventHandle", 0) => { + if version >= 4010 { + return cuIpcGetEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetEventHandle", 1) => { + if version >= 4010 { + return cuIpcGetEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetEventHandle", 2) => { + if version >= 4010 { + return cuIpcGetEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetMemHandle", 0) => { + if version >= 4010 { + return cuIpcGetMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetMemHandle", 1) => { + if version >= 4010 { + return cuIpcGetMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcGetMemHandle", 2) => { + if version >= 4010 { + return cuIpcGetMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenEventHandle", 0) => { + if version >= 4010 { + return cuIpcOpenEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenEventHandle", 1) => { + if version >= 4010 { + return cuIpcOpenEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenEventHandle", 2) => { + if version >= 4010 { + return cuIpcOpenEventHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenMemHandle", 0) => { + if version >= 11000 { + return cuIpcOpenMemHandle_v2 as _; + } + if version >= 4010 { + return cuIpcOpenMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenMemHandle", 1) => { + if version >= 11000 { + return cuIpcOpenMemHandle_v2 as _; + } + if version >= 4010 { + return cuIpcOpenMemHandle as _; + } + usize::MAX as _ + } + (b"cuIpcOpenMemHandle", 2) => { + if version >= 11000 { + return cuIpcOpenMemHandle_v2 as _; + } + if version >= 4010 { + return cuIpcOpenMemHandle as _; + } + usize::MAX as _ + } + (b"cuKernelGetAttribute", 0) => { + if version >= 12000 { + return cuKernelGetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelGetAttribute", 1) => { + if version >= 12000 { + return cuKernelGetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelGetAttribute", 2) => { + if version >= 12000 { + return cuKernelGetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelGetFunction", 0) => { + if version >= 12000 { + return cuKernelGetFunction as _; + } + usize::MAX as _ + } + (b"cuKernelGetFunction", 1) => { + if version >= 12000 { + return cuKernelGetFunction as _; + } + usize::MAX as _ + } + (b"cuKernelGetFunction", 2) => { + if version >= 12000 { + return cuKernelGetFunction as _; + } + usize::MAX as _ + } + (b"cuKernelSetAttribute", 0) => { + if version >= 12000 { + return cuKernelSetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelSetAttribute", 1) => { + if version >= 12000 { + return cuKernelSetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelSetAttribute", 2) => { + if version >= 12000 { + return cuKernelSetAttribute as _; + } + usize::MAX as _ + } + (b"cuKernelSetCacheConfig", 0) => { + if version >= 12000 { + return cuKernelSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuKernelSetCacheConfig", 1) => { + if version >= 12000 { + return cuKernelSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuKernelSetCacheConfig", 2) => { + if version >= 12000 { + return cuKernelSetCacheConfig as _; + } + usize::MAX as _ + } + (b"cuLaunch", 0) => { + if version >= 2000 { + return cuLaunch as _; + } + usize::MAX as _ + } + (b"cuLaunch", 1) => { + if version >= 2000 { + return cuLaunch as _; + } + usize::MAX as _ + } + (b"cuLaunch", 2) => { + if version >= 2000 { + return cuLaunch as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernel", 0) => { + if version >= 9000 { + return cuLaunchCooperativeKernel as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernel", 1) => { + if version >= 9000 { + return cuLaunchCooperativeKernel as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernel", 2) => { + if version >= 9000 { + return cuLaunchCooperativeKernel_ptsz as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernelMultiDevice", 0) => { + if version >= 9000 { + return cuLaunchCooperativeKernelMultiDevice as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernelMultiDevice", 1) => { + if version >= 9000 { + return cuLaunchCooperativeKernelMultiDevice as _; + } + usize::MAX as _ + } + (b"cuLaunchCooperativeKernelMultiDevice", 2) => { + if version >= 9000 { + return cuLaunchCooperativeKernelMultiDevice as _; + } + usize::MAX as _ + } + (b"cuLaunchGrid", 0) => { + if version >= 2000 { + return cuLaunchGrid as _; + } + usize::MAX as _ + } + (b"cuLaunchGrid", 1) => { + if version >= 2000 { + return cuLaunchGrid as _; + } + usize::MAX as _ + } + (b"cuLaunchGrid", 2) => { + if version >= 2000 { + return cuLaunchGrid as _; + } + usize::MAX as _ + } + (b"cuLaunchGridAsync", 0) => { + if version >= 2000 { + return cuLaunchGridAsync as _; + } + usize::MAX as _ + } + (b"cuLaunchGridAsync", 1) => { + if version >= 2000 { + return cuLaunchGridAsync as _; + } + usize::MAX as _ + } + (b"cuLaunchGridAsync", 2) => { + if version >= 2000 { + return cuLaunchGridAsync as _; + } + usize::MAX as _ + } + (b"cuLaunchHostFunc", 0) => { + if version >= 10000 { + return cuLaunchHostFunc as _; + } + usize::MAX as _ + } + (b"cuLaunchHostFunc", 1) => { + if version >= 10000 { + return cuLaunchHostFunc as _; + } + usize::MAX as _ + } + (b"cuLaunchHostFunc", 2) => { + if version >= 10000 { + return cuLaunchHostFunc_ptsz as _; + } + usize::MAX as _ + } + (b"cuLaunchKernel", 0) => { + if version >= 4000 { + return cuLaunchKernel as _; + } + usize::MAX as _ + } + (b"cuLaunchKernel", 1) => { + if version >= 4000 { + return cuLaunchKernel as _; + } + usize::MAX as _ + } + (b"cuLaunchKernel", 2) => { + if version >= 7000 { + return cuLaunchKernel_ptsz as _; + } + usize::MAX as _ + } + (b"cuLaunchKernelEx", 0) => { + if version >= 11060 { + return cuLaunchKernelEx as _; + } + usize::MAX as _ + } + (b"cuLaunchKernelEx", 1) => { + if version >= 11060 { + return cuLaunchKernelEx as _; + } + usize::MAX as _ + } + (b"cuLaunchKernelEx", 2) => { + if version >= 11060 { + return cuLaunchKernelEx_ptsz as _; + } + usize::MAX as _ + } + (b"cuLibraryGetGlobal", 0) => { + if version >= 12000 { + return cuLibraryGetGlobal as _; + } + usize::MAX as _ + } + (b"cuLibraryGetGlobal", 1) => { + if version >= 12000 { + return cuLibraryGetGlobal as _; + } + usize::MAX as _ + } + (b"cuLibraryGetGlobal", 2) => { + if version >= 12000 { + return cuLibraryGetGlobal as _; + } + usize::MAX as _ + } + (b"cuLibraryGetKernel", 0) => { + if version >= 12000 { + return cuLibraryGetKernel as _; + } + usize::MAX as _ + } + (b"cuLibraryGetKernel", 1) => { + if version >= 12000 { + return cuLibraryGetKernel as _; + } + usize::MAX as _ + } + (b"cuLibraryGetKernel", 2) => { + if version >= 12000 { + return cuLibraryGetKernel as _; + } + usize::MAX as _ + } + (b"cuLibraryGetManaged", 0) => { + if version >= 12000 { + return cuLibraryGetManaged as _; + } + usize::MAX as _ + } + (b"cuLibraryGetManaged", 1) => { + if version >= 12000 { + return cuLibraryGetManaged as _; + } + usize::MAX as _ + } + (b"cuLibraryGetManaged", 2) => { + if version >= 12000 { + return cuLibraryGetManaged as _; + } + usize::MAX as _ + } + (b"cuLibraryGetModule", 0) => { + if version >= 12000 { + return cuLibraryGetModule as _; + } + usize::MAX as _ + } + (b"cuLibraryGetModule", 1) => { + if version >= 12000 { + return cuLibraryGetModule as _; + } + usize::MAX as _ + } + (b"cuLibraryGetModule", 2) => { + if version >= 12000 { + return cuLibraryGetModule as _; + } + usize::MAX as _ + } + (b"cuLibraryGetUnifiedFunction", 0) => { + if version >= 12000 { + return cuLibraryGetUnifiedFunction as _; + } + usize::MAX as _ + } + (b"cuLibraryGetUnifiedFunction", 1) => { + if version >= 12000 { + return cuLibraryGetUnifiedFunction as _; + } + usize::MAX as _ + } + (b"cuLibraryGetUnifiedFunction", 2) => { + if version >= 12000 { + return cuLibraryGetUnifiedFunction as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadData", 0) => { + if version >= 12000 { + return cuLibraryLoadData as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadData", 1) => { + if version >= 12000 { + return cuLibraryLoadData as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadData", 2) => { + if version >= 12000 { + return cuLibraryLoadData as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadFromFile", 0) => { + if version >= 12000 { + return cuLibraryLoadFromFile as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadFromFile", 1) => { + if version >= 12000 { + return cuLibraryLoadFromFile as _; + } + usize::MAX as _ + } + (b"cuLibraryLoadFromFile", 2) => { + if version >= 12000 { + return cuLibraryLoadFromFile as _; + } + usize::MAX as _ + } + (b"cuLibraryUnload", 0) => { + if version >= 12000 { + return cuLibraryUnload as _; + } + usize::MAX as _ + } + (b"cuLibraryUnload", 1) => { + if version >= 12000 { + return cuLibraryUnload as _; + } + usize::MAX as _ + } + (b"cuLibraryUnload", 2) => { + if version >= 12000 { + return cuLibraryUnload as _; + } + usize::MAX as _ + } + (b"cuLinkAddData", 0) => { + if version >= 6050 { + return cuLinkAddData_v2 as _; + } + if version >= 5050 { + return cuLinkAddData as _; + } + usize::MAX as _ + } + (b"cuLinkAddData", 1) => { + if version >= 6050 { + return cuLinkAddData_v2 as _; + } + if version >= 5050 { + return cuLinkAddData as _; + } + usize::MAX as _ + } + (b"cuLinkAddData", 2) => { + if version >= 6050 { + return cuLinkAddData_v2 as _; + } + if version >= 5050 { + return cuLinkAddData as _; + } + usize::MAX as _ + } + (b"cuLinkAddFile", 0) => { + if version >= 6050 { + return cuLinkAddFile_v2 as _; + } + if version >= 5050 { + return cuLinkAddFile as _; + } + usize::MAX as _ + } + (b"cuLinkAddFile", 1) => { + if version >= 6050 { + return cuLinkAddFile_v2 as _; + } + if version >= 5050 { + return cuLinkAddFile as _; + } + usize::MAX as _ + } + (b"cuLinkAddFile", 2) => { + if version >= 6050 { + return cuLinkAddFile_v2 as _; + } + if version >= 5050 { + return cuLinkAddFile as _; + } + usize::MAX as _ + } + (b"cuLinkComplete", 0) => { + if version >= 5050 { + return cuLinkComplete as _; + } + usize::MAX as _ + } + (b"cuLinkComplete", 1) => { + if version >= 5050 { + return cuLinkComplete as _; + } + usize::MAX as _ + } + (b"cuLinkComplete", 2) => { + if version >= 5050 { + return cuLinkComplete as _; + } + usize::MAX as _ + } + (b"cuLinkCreate", 0) => { + if version >= 6050 { + return cuLinkCreate_v2 as _; + } + if version >= 5050 { + return cuLinkCreate as _; + } + usize::MAX as _ + } + (b"cuLinkCreate", 1) => { + if version >= 6050 { + return cuLinkCreate_v2 as _; + } + if version >= 5050 { + return cuLinkCreate as _; + } + usize::MAX as _ + } + (b"cuLinkCreate", 2) => { + if version >= 6050 { + return cuLinkCreate_v2 as _; + } + if version >= 5050 { + return cuLinkCreate as _; + } + usize::MAX as _ + } + (b"cuLinkDestroy", 0) => { + if version >= 5050 { + return cuLinkDestroy as _; + } + usize::MAX as _ + } + (b"cuLinkDestroy", 1) => { + if version >= 5050 { + return cuLinkDestroy as _; + } + usize::MAX as _ + } + (b"cuLinkDestroy", 2) => { + if version >= 5050 { + return cuLinkDestroy as _; + } + usize::MAX as _ + } + (b"cuMemAddressFree", 0) => { + if version >= 10020 { + return cuMemAddressFree as _; + } + usize::MAX as _ + } + (b"cuMemAddressFree", 1) => { + if version >= 10020 { + return cuMemAddressFree as _; + } + usize::MAX as _ + } + (b"cuMemAddressFree", 2) => { + if version >= 10020 { + return cuMemAddressFree as _; + } + usize::MAX as _ + } + (b"cuMemAddressReserve", 0) => { + if version >= 10020 { + return cuMemAddressReserve as _; + } + usize::MAX as _ + } + (b"cuMemAddressReserve", 1) => { + if version >= 10020 { + return cuMemAddressReserve as _; + } + usize::MAX as _ + } + (b"cuMemAddressReserve", 2) => { + if version >= 10020 { + return cuMemAddressReserve as _; + } + usize::MAX as _ + } + (b"cuMemAdvise", 0) => { + if version >= 12020 { + return cuMemAdvise_v2 as _; + } + if version >= 8000 { + return cuMemAdvise as _; + } + usize::MAX as _ + } + (b"cuMemAdvise", 1) => { + if version >= 12020 { + return cuMemAdvise_v2 as _; + } + if version >= 8000 { + return cuMemAdvise as _; + } + usize::MAX as _ + } + (b"cuMemAdvise", 2) => { + if version >= 12020 { + return cuMemAdvise_v2 as _; + } + if version >= 8000 { + return cuMemAdvise as _; + } + usize::MAX as _ + } + (b"cuMemAlloc", 0) => { + if version >= 3020 { + return cuMemAlloc_v2 as _; + } + if version >= 2000 { + return cuMemAlloc as _; + } + usize::MAX as _ + } + (b"cuMemAlloc", 1) => { + if version >= 3020 { + return cuMemAlloc_v2 as _; + } + if version >= 2000 { + return cuMemAlloc as _; + } + usize::MAX as _ + } + (b"cuMemAlloc", 2) => { + if version >= 3020 { + return cuMemAlloc_v2 as _; + } + if version >= 2000 { + return cuMemAlloc as _; + } + usize::MAX as _ + } + (b"cuMemAllocAsync", 0) => { + if version >= 11020 { + return cuMemAllocAsync as _; + } + usize::MAX as _ + } + (b"cuMemAllocAsync", 1) => { + if version >= 11020 { + return cuMemAllocAsync as _; + } + usize::MAX as _ + } + (b"cuMemAllocAsync", 2) => { + if version >= 11020 { + return cuMemAllocAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemAllocFromPoolAsync", 0) => { + if version >= 11020 { + return cuMemAllocFromPoolAsync as _; + } + usize::MAX as _ + } + (b"cuMemAllocFromPoolAsync", 1) => { + if version >= 11020 { + return cuMemAllocFromPoolAsync as _; + } + usize::MAX as _ + } + (b"cuMemAllocFromPoolAsync", 2) => { + if version >= 11020 { + return cuMemAllocFromPoolAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemAllocHost", 0) => { + if version >= 3020 { + return cuMemAllocHost_v2 as _; + } + if version >= 2000 { + return cuMemAllocHost as _; + } + usize::MAX as _ + } + (b"cuMemAllocHost", 1) => { + if version >= 3020 { + return cuMemAllocHost_v2 as _; + } + if version >= 2000 { + return cuMemAllocHost as _; + } + usize::MAX as _ + } + (b"cuMemAllocHost", 2) => { + if version >= 3020 { + return cuMemAllocHost_v2 as _; + } + if version >= 2000 { + return cuMemAllocHost as _; + } + usize::MAX as _ + } + (b"cuMemAllocManaged", 0) => { + if version >= 6000 { + return cuMemAllocManaged as _; + } + usize::MAX as _ + } + (b"cuMemAllocManaged", 1) => { + if version >= 6000 { + return cuMemAllocManaged as _; + } + usize::MAX as _ + } + (b"cuMemAllocManaged", 2) => { + if version >= 6000 { + return cuMemAllocManaged as _; + } + usize::MAX as _ + } + (b"cuMemAllocPitch", 0) => { + if version >= 3020 { + return cuMemAllocPitch_v2 as _; + } + if version >= 2000 { + return cuMemAllocPitch as _; + } + usize::MAX as _ + } + (b"cuMemAllocPitch", 1) => { + if version >= 3020 { + return cuMemAllocPitch_v2 as _; + } + if version >= 2000 { + return cuMemAllocPitch as _; + } + usize::MAX as _ + } + (b"cuMemAllocPitch", 2) => { + if version >= 3020 { + return cuMemAllocPitch_v2 as _; + } + if version >= 2000 { + return cuMemAllocPitch as _; + } + usize::MAX as _ + } + (b"cuMemCreate", 0) => { + if version >= 10020 { + return cuMemCreate as _; + } + usize::MAX as _ + } + (b"cuMemCreate", 1) => { + if version >= 10020 { + return cuMemCreate as _; + } + usize::MAX as _ + } + (b"cuMemCreate", 2) => { + if version >= 10020 { + return cuMemCreate as _; + } + usize::MAX as _ + } + (b"cuMemExportToShareableHandle", 0) => { + if version >= 10020 { + return cuMemExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemExportToShareableHandle", 1) => { + if version >= 10020 { + return cuMemExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemExportToShareableHandle", 2) => { + if version >= 10020 { + return cuMemExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemFree", 0) => { + if version >= 3020 { + return cuMemFree_v2 as _; + } + if version >= 2000 { + return cuMemFree as _; + } + usize::MAX as _ + } + (b"cuMemFree", 1) => { + if version >= 3020 { + return cuMemFree_v2 as _; + } + if version >= 2000 { + return cuMemFree as _; + } + usize::MAX as _ + } + (b"cuMemFree", 2) => { + if version >= 3020 { + return cuMemFree_v2 as _; + } + if version >= 2000 { + return cuMemFree as _; + } + usize::MAX as _ + } + (b"cuMemFreeAsync", 0) => { + if version >= 11020 { + return cuMemFreeAsync as _; + } + usize::MAX as _ + } + (b"cuMemFreeAsync", 1) => { + if version >= 11020 { + return cuMemFreeAsync as _; + } + usize::MAX as _ + } + (b"cuMemFreeAsync", 2) => { + if version >= 11020 { + return cuMemFreeAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemFreeHost", 0) => { + if version >= 2000 { + return cuMemFreeHost as _; + } + usize::MAX as _ + } + (b"cuMemFreeHost", 1) => { + if version >= 2000 { + return cuMemFreeHost as _; + } + usize::MAX as _ + } + (b"cuMemFreeHost", 2) => { + if version >= 2000 { + return cuMemFreeHost as _; + } + usize::MAX as _ + } + (b"cuMemGetAccess", 0) => { + if version >= 10020 { + return cuMemGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemGetAccess", 1) => { + if version >= 10020 { + return cuMemGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemGetAccess", 2) => { + if version >= 10020 { + return cuMemGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemGetAddressRange", 0) => { + if version >= 3020 { + return cuMemGetAddressRange_v2 as _; + } + if version >= 2000 { + return cuMemGetAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetAddressRange", 1) => { + if version >= 3020 { + return cuMemGetAddressRange_v2 as _; + } + if version >= 2000 { + return cuMemGetAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetAddressRange", 2) => { + if version >= 3020 { + return cuMemGetAddressRange_v2 as _; + } + if version >= 2000 { + return cuMemGetAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationGranularity", 0) => { + if version >= 10020 { + return cuMemGetAllocationGranularity as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationGranularity", 1) => { + if version >= 10020 { + return cuMemGetAllocationGranularity as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationGranularity", 2) => { + if version >= 10020 { + return cuMemGetAllocationGranularity as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationPropertiesFromHandle", 0) => { + if version >= 10020 { + return cuMemGetAllocationPropertiesFromHandle as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationPropertiesFromHandle", 1) => { + if version >= 10020 { + return cuMemGetAllocationPropertiesFromHandle as _; + } + usize::MAX as _ + } + (b"cuMemGetAllocationPropertiesFromHandle", 2) => { + if version >= 10020 { + return cuMemGetAllocationPropertiesFromHandle as _; + } + usize::MAX as _ + } + (b"cuMemGetHandleForAddressRange", 0) => { + if version >= 11070 { + return cuMemGetHandleForAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetHandleForAddressRange", 1) => { + if version >= 11070 { + return cuMemGetHandleForAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetHandleForAddressRange", 2) => { + if version >= 11070 { + return cuMemGetHandleForAddressRange as _; + } + usize::MAX as _ + } + (b"cuMemGetInfo", 0) => { + if version >= 3020 { + return cuMemGetInfo_v2 as _; + } + if version >= 2000 { + return cuMemGetInfo as _; + } + usize::MAX as _ + } + (b"cuMemGetInfo", 1) => { + if version >= 3020 { + return cuMemGetInfo_v2 as _; + } + if version >= 2000 { + return cuMemGetInfo as _; + } + usize::MAX as _ + } + (b"cuMemGetInfo", 2) => { + if version >= 3020 { + return cuMemGetInfo_v2 as _; + } + if version >= 2000 { + return cuMemGetInfo as _; + } + usize::MAX as _ + } + (b"cuMemHostAlloc", 0) => { + if version >= 2020 { + return cuMemHostAlloc as _; + } + usize::MAX as _ + } + (b"cuMemHostAlloc", 1) => { + if version >= 2020 { + return cuMemHostAlloc as _; + } + usize::MAX as _ + } + (b"cuMemHostAlloc", 2) => { + if version >= 2020 { + return cuMemHostAlloc as _; + } + usize::MAX as _ + } + (b"cuMemHostGetDevicePointer", 0) => { + if version >= 3020 { + return cuMemHostGetDevicePointer_v2 as _; + } + if version >= 2020 { + return cuMemHostGetDevicePointer as _; + } + usize::MAX as _ + } + (b"cuMemHostGetDevicePointer", 1) => { + if version >= 3020 { + return cuMemHostGetDevicePointer_v2 as _; + } + if version >= 2020 { + return cuMemHostGetDevicePointer as _; + } + usize::MAX as _ + } + (b"cuMemHostGetDevicePointer", 2) => { + if version >= 3020 { + return cuMemHostGetDevicePointer_v2 as _; + } + if version >= 2020 { + return cuMemHostGetDevicePointer as _; + } + usize::MAX as _ + } + (b"cuMemHostGetFlags", 0) => { + if version >= 2030 { + return cuMemHostGetFlags as _; + } + usize::MAX as _ + } + (b"cuMemHostGetFlags", 1) => { + if version >= 2030 { + return cuMemHostGetFlags as _; + } + usize::MAX as _ + } + (b"cuMemHostGetFlags", 2) => { + if version >= 2030 { + return cuMemHostGetFlags as _; + } + usize::MAX as _ + } + (b"cuMemHostRegister", 0) => { + if version >= 6050 { + return cuMemHostRegister_v2 as _; + } + if version >= 4000 { + return cuMemHostRegister as _; + } + usize::MAX as _ + } + (b"cuMemHostRegister", 1) => { + if version >= 6050 { + return cuMemHostRegister_v2 as _; + } + if version >= 4000 { + return cuMemHostRegister as _; + } + usize::MAX as _ + } + (b"cuMemHostRegister", 2) => { + if version >= 6050 { + return cuMemHostRegister_v2 as _; + } + if version >= 4000 { + return cuMemHostRegister as _; + } + usize::MAX as _ + } + (b"cuMemHostUnregister", 0) => { + if version >= 4000 { + return cuMemHostUnregister as _; + } + usize::MAX as _ + } + (b"cuMemHostUnregister", 1) => { + if version >= 4000 { + return cuMemHostUnregister as _; + } + usize::MAX as _ + } + (b"cuMemHostUnregister", 2) => { + if version >= 4000 { + return cuMemHostUnregister as _; + } + usize::MAX as _ + } + (b"cuMemImportFromShareableHandle", 0) => { + if version >= 10020 { + return cuMemImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemImportFromShareableHandle", 1) => { + if version >= 10020 { + return cuMemImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemImportFromShareableHandle", 2) => { + if version >= 10020 { + return cuMemImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemMap", 0) => { + if version >= 10020 { + return cuMemMap as _; + } + usize::MAX as _ + } + (b"cuMemMap", 1) => { + if version >= 10020 { + return cuMemMap as _; + } + usize::MAX as _ + } + (b"cuMemMap", 2) => { + if version >= 10020 { + return cuMemMap as _; + } + usize::MAX as _ + } + (b"cuMemMapArrayAsync", 0) => { + if version >= 11010 { + return cuMemMapArrayAsync as _; + } + usize::MAX as _ + } + (b"cuMemMapArrayAsync", 1) => { + if version >= 11010 { + return cuMemMapArrayAsync as _; + } + usize::MAX as _ + } + (b"cuMemMapArrayAsync", 2) => { + if version >= 11010 { + return cuMemMapArrayAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemPoolCreate", 0) => { + if version >= 11020 { + return cuMemPoolCreate as _; + } + usize::MAX as _ + } + (b"cuMemPoolCreate", 1) => { + if version >= 11020 { + return cuMemPoolCreate as _; + } + usize::MAX as _ + } + (b"cuMemPoolCreate", 2) => { + if version >= 11020 { + return cuMemPoolCreate as _; + } + usize::MAX as _ + } + (b"cuMemPoolDestroy", 0) => { + if version >= 11020 { + return cuMemPoolDestroy as _; + } + usize::MAX as _ + } + (b"cuMemPoolDestroy", 1) => { + if version >= 11020 { + return cuMemPoolDestroy as _; + } + usize::MAX as _ + } + (b"cuMemPoolDestroy", 2) => { + if version >= 11020 { + return cuMemPoolDestroy as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportPointer", 0) => { + if version >= 11020 { + return cuMemPoolExportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportPointer", 1) => { + if version >= 11020 { + return cuMemPoolExportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportPointer", 2) => { + if version >= 11020 { + return cuMemPoolExportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportToShareableHandle", 0) => { + if version >= 11020 { + return cuMemPoolExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportToShareableHandle", 1) => { + if version >= 11020 { + return cuMemPoolExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolExportToShareableHandle", 2) => { + if version >= 11020 { + return cuMemPoolExportToShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAccess", 0) => { + if version >= 11020 { + return cuMemPoolGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAccess", 1) => { + if version >= 11020 { + return cuMemPoolGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAccess", 2) => { + if version >= 11020 { + return cuMemPoolGetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAttribute", 0) => { + if version >= 11020 { + return cuMemPoolGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAttribute", 1) => { + if version >= 11020 { + return cuMemPoolGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolGetAttribute", 2) => { + if version >= 11020 { + return cuMemPoolGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportFromShareableHandle", 0) => { + if version >= 11020 { + return cuMemPoolImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportFromShareableHandle", 1) => { + if version >= 11020 { + return cuMemPoolImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportFromShareableHandle", 2) => { + if version >= 11020 { + return cuMemPoolImportFromShareableHandle as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportPointer", 0) => { + if version >= 11020 { + return cuMemPoolImportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportPointer", 1) => { + if version >= 11020 { + return cuMemPoolImportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolImportPointer", 2) => { + if version >= 11020 { + return cuMemPoolImportPointer as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAccess", 0) => { + if version >= 11020 { + return cuMemPoolSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAccess", 1) => { + if version >= 11020 { + return cuMemPoolSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAccess", 2) => { + if version >= 11020 { + return cuMemPoolSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAttribute", 0) => { + if version >= 11020 { + return cuMemPoolSetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAttribute", 1) => { + if version >= 11020 { + return cuMemPoolSetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolSetAttribute", 2) => { + if version >= 11020 { + return cuMemPoolSetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemPoolTrimTo", 0) => { + if version >= 11020 { + return cuMemPoolTrimTo as _; + } + usize::MAX as _ + } + (b"cuMemPoolTrimTo", 1) => { + if version >= 11020 { + return cuMemPoolTrimTo as _; + } + usize::MAX as _ + } + (b"cuMemPoolTrimTo", 2) => { + if version >= 11020 { + return cuMemPoolTrimTo as _; + } + usize::MAX as _ + } + (b"cuMemPrefetchAsync", 0) => { + if version >= 12020 { + return cuMemPrefetchAsync_v2 as _; + } + if version >= 8000 { + return cuMemPrefetchAsync as _; + } + usize::MAX as _ + } + (b"cuMemPrefetchAsync", 1) => { + if version >= 12020 { + return cuMemPrefetchAsync_v2 as _; + } + if version >= 8000 { + return cuMemPrefetchAsync as _; + } + usize::MAX as _ + } + (b"cuMemPrefetchAsync", 2) => { + if version >= 12020 { + return cuMemPrefetchAsync_v2_ptsz as _; + } + if version >= 8000 { + return cuMemPrefetchAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttribute", 0) => { + if version >= 8000 { + return cuMemRangeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttribute", 1) => { + if version >= 8000 { + return cuMemRangeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttribute", 2) => { + if version >= 8000 { + return cuMemRangeGetAttribute as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttributes", 0) => { + if version >= 8000 { + return cuMemRangeGetAttributes as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttributes", 1) => { + if version >= 8000 { + return cuMemRangeGetAttributes as _; + } + usize::MAX as _ + } + (b"cuMemRangeGetAttributes", 2) => { + if version >= 8000 { + return cuMemRangeGetAttributes as _; + } + usize::MAX as _ + } + (b"cuMemRelease", 0) => { + if version >= 10020 { + return cuMemRelease as _; + } + usize::MAX as _ + } + (b"cuMemRelease", 1) => { + if version >= 10020 { + return cuMemRelease as _; + } + usize::MAX as _ + } + (b"cuMemRelease", 2) => { + if version >= 10020 { + return cuMemRelease as _; + } + usize::MAX as _ + } + (b"cuMemRetainAllocationHandle", 0) => { + if version >= 11000 { + return cuMemRetainAllocationHandle as _; + } + usize::MAX as _ + } + (b"cuMemRetainAllocationHandle", 1) => { + if version >= 11000 { + return cuMemRetainAllocationHandle as _; + } + usize::MAX as _ + } + (b"cuMemRetainAllocationHandle", 2) => { + if version >= 11000 { + return cuMemRetainAllocationHandle as _; + } + usize::MAX as _ + } + (b"cuMemSetAccess", 0) => { + if version >= 10020 { + return cuMemSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemSetAccess", 1) => { + if version >= 10020 { + return cuMemSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemSetAccess", 2) => { + if version >= 10020 { + return cuMemSetAccess as _; + } + usize::MAX as _ + } + (b"cuMemUnmap", 0) => { + if version >= 10020 { + return cuMemUnmap as _; + } + usize::MAX as _ + } + (b"cuMemUnmap", 1) => { + if version >= 10020 { + return cuMemUnmap as _; + } + usize::MAX as _ + } + (b"cuMemUnmap", 2) => { + if version >= 10020 { + return cuMemUnmap as _; + } + usize::MAX as _ + } + (b"cuMemcpy", 0) => { + if version >= 4000 { + return cuMemcpy as _; + } + usize::MAX as _ + } + (b"cuMemcpy", 1) => { + if version >= 4000 { + return cuMemcpy as _; + } + usize::MAX as _ + } + (b"cuMemcpy", 2) => { + if version >= 7000 { + return cuMemcpy_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpy2D", 0) => { + if version >= 3020 { + return cuMemcpy2D_v2 as _; + } + if version >= 2000 { + return cuMemcpy2D as _; + } + usize::MAX as _ + } + (b"cuMemcpy2D", 1) => { + if version >= 3020 { + return cuMemcpy2D_v2 as _; + } + if version >= 2000 { + return cuMemcpy2D as _; + } + usize::MAX as _ + } + (b"cuMemcpy2D", 2) => { + if version >= 7000 { + return cuMemcpy2D_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DAsync", 0) => { + if version >= 3020 { + return cuMemcpy2DAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpy2DAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DAsync", 1) => { + if version >= 3020 { + return cuMemcpy2DAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpy2DAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DAsync", 2) => { + if version >= 7000 { + return cuMemcpy2DAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DUnaligned", 0) => { + if version >= 3020 { + return cuMemcpy2DUnaligned_v2 as _; + } + if version >= 2000 { + return cuMemcpy2DUnaligned as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DUnaligned", 1) => { + if version >= 3020 { + return cuMemcpy2DUnaligned_v2 as _; + } + if version >= 2000 { + return cuMemcpy2DUnaligned as _; + } + usize::MAX as _ + } + (b"cuMemcpy2DUnaligned", 2) => { + if version >= 7000 { + return cuMemcpy2DUnaligned_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpy3D", 0) => { + if version >= 3020 { + return cuMemcpy3D_v2 as _; + } + if version >= 2000 { + return cuMemcpy3D as _; + } + usize::MAX as _ + } + (b"cuMemcpy3D", 1) => { + if version >= 3020 { + return cuMemcpy3D_v2 as _; + } + if version >= 2000 { + return cuMemcpy3D as _; + } + usize::MAX as _ + } + (b"cuMemcpy3D", 2) => { + if version >= 7000 { + return cuMemcpy3D_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DAsync", 0) => { + if version >= 3020 { + return cuMemcpy3DAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpy3DAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DAsync", 1) => { + if version >= 3020 { + return cuMemcpy3DAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpy3DAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DAsync", 2) => { + if version >= 7000 { + return cuMemcpy3DAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeer", 0) => { + if version >= 4000 { + return cuMemcpy3DPeer as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeer", 1) => { + if version >= 4000 { + return cuMemcpy3DPeer as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeer", 2) => { + if version >= 7000 { + return cuMemcpy3DPeer_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeerAsync", 0) => { + if version >= 4000 { + return cuMemcpy3DPeerAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeerAsync", 1) => { + if version >= 4000 { + return cuMemcpy3DPeerAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpy3DPeerAsync", 2) => { + if version >= 7000 { + return cuMemcpy3DPeerAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyAsync", 0) => { + if version >= 4000 { + return cuMemcpyAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyAsync", 1) => { + if version >= 4000 { + return cuMemcpyAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyAsync", 2) => { + if version >= 7000 { + return cuMemcpyAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoA", 0) => { + if version >= 3020 { + return cuMemcpyAtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoA", 1) => { + if version >= 3020 { + return cuMemcpyAtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoA", 2) => { + if version >= 7000 { + return cuMemcpyAtoA_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoD", 0) => { + if version >= 3020 { + return cuMemcpyAtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoD", 1) => { + if version >= 3020 { + return cuMemcpyAtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoD", 2) => { + if version >= 7000 { + return cuMemcpyAtoD_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoH", 0) => { + if version >= 3020 { + return cuMemcpyAtoH_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoH as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoH", 1) => { + if version >= 3020 { + return cuMemcpyAtoH_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoH as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoH", 2) => { + if version >= 7000 { + return cuMemcpyAtoH_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoHAsync", 0) => { + if version >= 3020 { + return cuMemcpyAtoHAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoHAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoHAsync", 1) => { + if version >= 3020 { + return cuMemcpyAtoHAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyAtoHAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyAtoHAsync", 2) => { + if version >= 7000 { + return cuMemcpyAtoHAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoA", 0) => { + if version >= 3020 { + return cuMemcpyDtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoA", 1) => { + if version >= 3020 { + return cuMemcpyDtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoA", 2) => { + if version >= 7000 { + return cuMemcpyDtoA_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoD", 0) => { + if version >= 3020 { + return cuMemcpyDtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoD", 1) => { + if version >= 3020 { + return cuMemcpyDtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoD", 2) => { + if version >= 7000 { + return cuMemcpyDtoD_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoDAsync", 0) => { + if version >= 3020 { + return cuMemcpyDtoDAsync_v2 as _; + } + if version >= 3000 { + return cuMemcpyDtoDAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoDAsync", 1) => { + if version >= 3020 { + return cuMemcpyDtoDAsync_v2 as _; + } + if version >= 3000 { + return cuMemcpyDtoDAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoDAsync", 2) => { + if version >= 7000 { + return cuMemcpyDtoDAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoH", 0) => { + if version >= 3020 { + return cuMemcpyDtoH_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoH as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoH", 1) => { + if version >= 3020 { + return cuMemcpyDtoH_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoH as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoH", 2) => { + if version >= 7000 { + return cuMemcpyDtoH_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoHAsync", 0) => { + if version >= 3020 { + return cuMemcpyDtoHAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoHAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoHAsync", 1) => { + if version >= 3020 { + return cuMemcpyDtoHAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyDtoHAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyDtoHAsync", 2) => { + if version >= 7000 { + return cuMemcpyDtoHAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoA", 0) => { + if version >= 3020 { + return cuMemcpyHtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoA", 1) => { + if version >= 3020 { + return cuMemcpyHtoA_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoA as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoA", 2) => { + if version >= 7000 { + return cuMemcpyHtoA_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoAAsync", 0) => { + if version >= 3020 { + return cuMemcpyHtoAAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoAAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoAAsync", 1) => { + if version >= 3020 { + return cuMemcpyHtoAAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoAAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoAAsync", 2) => { + if version >= 7000 { + return cuMemcpyHtoAAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoD", 0) => { + if version >= 3020 { + return cuMemcpyHtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoD", 1) => { + if version >= 3020 { + return cuMemcpyHtoD_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoD as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoD", 2) => { + if version >= 7000 { + return cuMemcpyHtoD_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoDAsync", 0) => { + if version >= 3020 { + return cuMemcpyHtoDAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoDAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoDAsync", 1) => { + if version >= 3020 { + return cuMemcpyHtoDAsync_v2 as _; + } + if version >= 2000 { + return cuMemcpyHtoDAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyHtoDAsync", 2) => { + if version >= 7000 { + return cuMemcpyHtoDAsync_v2_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeer", 0) => { + if version >= 4000 { + return cuMemcpyPeer as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeer", 1) => { + if version >= 4000 { + return cuMemcpyPeer as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeer", 2) => { + if version >= 7000 { + return cuMemcpyPeer_ptds as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeerAsync", 0) => { + if version >= 4000 { + return cuMemcpyPeerAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeerAsync", 1) => { + if version >= 4000 { + return cuMemcpyPeerAsync as _; + } + usize::MAX as _ + } + (b"cuMemcpyPeerAsync", 2) => { + if version >= 7000 { + return cuMemcpyPeerAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD16", 0) => { + if version >= 3020 { + return cuMemsetD16_v2 as _; + } + if version >= 2000 { + return cuMemsetD16 as _; + } + usize::MAX as _ + } + (b"cuMemsetD16", 1) => { + if version >= 3020 { + return cuMemsetD16_v2 as _; + } + if version >= 2000 { + return cuMemsetD16 as _; + } + usize::MAX as _ + } + (b"cuMemsetD16", 2) => { + if version >= 7000 { + return cuMemsetD16_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD16Async", 0) => { + if version >= 3020 { + return cuMemsetD16Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD16Async", 1) => { + if version >= 3020 { + return cuMemsetD16Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD16Async", 2) => { + if version >= 7000 { + return cuMemsetD16Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16", 0) => { + if version >= 3020 { + return cuMemsetD2D16_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D16 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16", 1) => { + if version >= 3020 { + return cuMemsetD2D16_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D16 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16", 2) => { + if version >= 7000 { + return cuMemsetD2D16_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16Async", 0) => { + if version >= 3020 { + return cuMemsetD2D16Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16Async", 1) => { + if version >= 3020 { + return cuMemsetD2D16Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D16Async", 2) => { + if version >= 7000 { + return cuMemsetD2D16Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32", 0) => { + if version >= 3020 { + return cuMemsetD2D32_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D32 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32", 1) => { + if version >= 3020 { + return cuMemsetD2D32_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D32 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32", 2) => { + if version >= 7000 { + return cuMemsetD2D32_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32Async", 0) => { + if version >= 3020 { + return cuMemsetD2D32Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32Async", 1) => { + if version >= 3020 { + return cuMemsetD2D32Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D32Async", 2) => { + if version >= 7000 { + return cuMemsetD2D32Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8", 0) => { + if version >= 3020 { + return cuMemsetD2D8_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D8 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8", 1) => { + if version >= 3020 { + return cuMemsetD2D8_v2 as _; + } + if version >= 2000 { + return cuMemsetD2D8 as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8", 2) => { + if version >= 7000 { + return cuMemsetD2D8_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8Async", 0) => { + if version >= 3020 { + return cuMemsetD2D8Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8Async", 1) => { + if version >= 3020 { + return cuMemsetD2D8Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD2D8Async", 2) => { + if version >= 7000 { + return cuMemsetD2D8Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD32", 0) => { + if version >= 3020 { + return cuMemsetD32_v2 as _; + } + if version >= 2000 { + return cuMemsetD32 as _; + } + usize::MAX as _ + } + (b"cuMemsetD32", 1) => { + if version >= 3020 { + return cuMemsetD32_v2 as _; + } + if version >= 2000 { + return cuMemsetD32 as _; + } + usize::MAX as _ + } + (b"cuMemsetD32", 2) => { + if version >= 7000 { + return cuMemsetD32_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD32Async", 0) => { + if version >= 3020 { + return cuMemsetD32Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD32Async", 1) => { + if version >= 3020 { + return cuMemsetD32Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD32Async", 2) => { + if version >= 7000 { + return cuMemsetD32Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMemsetD8", 0) => { + if version >= 3020 { + return cuMemsetD8_v2 as _; + } + if version >= 2000 { + return cuMemsetD8 as _; + } + usize::MAX as _ + } + (b"cuMemsetD8", 1) => { + if version >= 3020 { + return cuMemsetD8_v2 as _; + } + if version >= 2000 { + return cuMemsetD8 as _; + } + usize::MAX as _ + } + (b"cuMemsetD8", 2) => { + if version >= 7000 { + return cuMemsetD8_v2_ptds as _; + } + usize::MAX as _ + } + (b"cuMemsetD8Async", 0) => { + if version >= 3020 { + return cuMemsetD8Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD8Async", 1) => { + if version >= 3020 { + return cuMemsetD8Async as _; + } + usize::MAX as _ + } + (b"cuMemsetD8Async", 2) => { + if version >= 7000 { + return cuMemsetD8Async_ptsz as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayCreate", 0) => { + if version >= 5000 { + return cuMipmappedArrayCreate as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayCreate", 1) => { + if version >= 5000 { + return cuMipmappedArrayCreate as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayCreate", 2) => { + if version >= 5000 { + return cuMipmappedArrayCreate as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayDestroy", 0) => { + if version >= 5000 { + return cuMipmappedArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayDestroy", 1) => { + if version >= 5000 { + return cuMipmappedArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayDestroy", 2) => { + if version >= 5000 { + return cuMipmappedArrayDestroy as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetLevel", 0) => { + if version >= 5000 { + return cuMipmappedArrayGetLevel as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetLevel", 1) => { + if version >= 5000 { + return cuMipmappedArrayGetLevel as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetLevel", 2) => { + if version >= 5000 { + return cuMipmappedArrayGetLevel as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetMemoryRequirements", 0) => { + if version >= 11060 { + return cuMipmappedArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetMemoryRequirements", 1) => { + if version >= 11060 { + return cuMipmappedArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetMemoryRequirements", 2) => { + if version >= 11060 { + return cuMipmappedArrayGetMemoryRequirements as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetSparseProperties", 0) => { + if version >= 11010 { + return cuMipmappedArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetSparseProperties", 1) => { + if version >= 11010 { + return cuMipmappedArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuMipmappedArrayGetSparseProperties", 2) => { + if version >= 11010 { + return cuMipmappedArrayGetSparseProperties as _; + } + usize::MAX as _ + } + (b"cuModuleGetFunction", 0) => { + if version >= 2000 { + return cuModuleGetFunction as _; + } + usize::MAX as _ + } + (b"cuModuleGetFunction", 1) => { + if version >= 2000 { + return cuModuleGetFunction as _; + } + usize::MAX as _ + } + (b"cuModuleGetFunction", 2) => { + if version >= 2000 { + return cuModuleGetFunction as _; + } + usize::MAX as _ + } + (b"cuModuleGetGlobal", 0) => { + if version >= 3020 { + return cuModuleGetGlobal_v2 as _; + } + if version >= 2000 { + return cuModuleGetGlobal as _; + } + usize::MAX as _ + } + (b"cuModuleGetGlobal", 1) => { + if version >= 3020 { + return cuModuleGetGlobal_v2 as _; + } + if version >= 2000 { + return cuModuleGetGlobal as _; + } + usize::MAX as _ + } + (b"cuModuleGetGlobal", 2) => { + if version >= 3020 { + return cuModuleGetGlobal_v2 as _; + } + if version >= 2000 { + return cuModuleGetGlobal as _; + } + usize::MAX as _ + } + (b"cuModuleGetLoadingMode", 0) => { + if version >= 11070 { + return cuModuleGetLoadingMode as _; + } + usize::MAX as _ + } + (b"cuModuleGetLoadingMode", 1) => { + if version >= 11070 { + return cuModuleGetLoadingMode as _; + } + usize::MAX as _ + } + (b"cuModuleGetLoadingMode", 2) => { + if version >= 11070 { + return cuModuleGetLoadingMode as _; + } + usize::MAX as _ + } + (b"cuModuleGetSurfRef", 0) => { + if version >= 3000 { + return cuModuleGetSurfRef as _; + } + usize::MAX as _ + } + (b"cuModuleGetSurfRef", 1) => { + if version >= 3000 { + return cuModuleGetSurfRef as _; + } + usize::MAX as _ + } + (b"cuModuleGetSurfRef", 2) => { + if version >= 3000 { + return cuModuleGetSurfRef as _; + } + usize::MAX as _ + } + (b"cuModuleGetTexRef", 0) => { + if version >= 2000 { + return cuModuleGetTexRef as _; + } + usize::MAX as _ + } + (b"cuModuleGetTexRef", 1) => { + if version >= 2000 { + return cuModuleGetTexRef as _; + } + usize::MAX as _ + } + (b"cuModuleGetTexRef", 2) => { + if version >= 2000 { + return cuModuleGetTexRef as _; + } + usize::MAX as _ + } + (b"cuModuleLoad", 0) => { + if version >= 2000 { + return cuModuleLoad as _; + } + usize::MAX as _ + } + (b"cuModuleLoad", 1) => { + if version >= 2000 { + return cuModuleLoad as _; + } + usize::MAX as _ + } + (b"cuModuleLoad", 2) => { + if version >= 2000 { + return cuModuleLoad as _; + } + usize::MAX as _ + } + (b"cuModuleLoadData", 0) => { + if version >= 2000 { + return cuModuleLoadData as _; + } + usize::MAX as _ + } + (b"cuModuleLoadData", 1) => { + if version >= 2000 { + return cuModuleLoadData as _; + } + usize::MAX as _ + } + (b"cuModuleLoadData", 2) => { + if version >= 2000 { + return cuModuleLoadData as _; + } + usize::MAX as _ + } + (b"cuModuleLoadDataEx", 0) => { + if version >= 2010 { + return cuModuleLoadDataEx as _; + } + usize::MAX as _ + } + (b"cuModuleLoadDataEx", 1) => { + if version >= 2010 { + return cuModuleLoadDataEx as _; + } + usize::MAX as _ + } + (b"cuModuleLoadDataEx", 2) => { + if version >= 2010 { + return cuModuleLoadDataEx as _; + } + usize::MAX as _ + } + (b"cuModuleLoadFatBinary", 0) => { + if version >= 2000 { + return cuModuleLoadFatBinary as _; + } + usize::MAX as _ + } + (b"cuModuleLoadFatBinary", 1) => { + if version >= 2000 { + return cuModuleLoadFatBinary as _; + } + usize::MAX as _ + } + (b"cuModuleLoadFatBinary", 2) => { + if version >= 2000 { + return cuModuleLoadFatBinary as _; + } + usize::MAX as _ + } + (b"cuModuleUnload", 0) => { + if version >= 2000 { + return cuModuleUnload as _; + } + usize::MAX as _ + } + (b"cuModuleUnload", 1) => { + if version >= 2000 { + return cuModuleUnload as _; + } + usize::MAX as _ + } + (b"cuModuleUnload", 2) => { + if version >= 2000 { + return cuModuleUnload as _; + } + usize::MAX as _ + } + (b"cuMulticastAddDevice", 0) => { + if version >= 12010 { + return cuMulticastAddDevice as _; + } + usize::MAX as _ + } + (b"cuMulticastAddDevice", 1) => { + if version >= 12010 { + return cuMulticastAddDevice as _; + } + usize::MAX as _ + } + (b"cuMulticastAddDevice", 2) => { + if version >= 12010 { + return cuMulticastAddDevice as _; + } + usize::MAX as _ + } + (b"cuMulticastBindAddr", 0) => { + if version >= 12010 { + return cuMulticastBindAddr as _; + } + usize::MAX as _ + } + (b"cuMulticastBindAddr", 1) => { + if version >= 12010 { + return cuMulticastBindAddr as _; + } + usize::MAX as _ + } + (b"cuMulticastBindAddr", 2) => { + if version >= 12010 { + return cuMulticastBindAddr as _; + } + usize::MAX as _ + } + (b"cuMulticastBindMem", 0) => { + if version >= 12010 { + return cuMulticastBindMem as _; + } + usize::MAX as _ + } + (b"cuMulticastBindMem", 1) => { + if version >= 12010 { + return cuMulticastBindMem as _; + } + usize::MAX as _ + } + (b"cuMulticastBindMem", 2) => { + if version >= 12010 { + return cuMulticastBindMem as _; + } + usize::MAX as _ + } + (b"cuMulticastCreate", 0) => { + if version >= 12010 { + return cuMulticastCreate as _; + } + usize::MAX as _ + } + (b"cuMulticastCreate", 1) => { + if version >= 12010 { + return cuMulticastCreate as _; + } + usize::MAX as _ + } + (b"cuMulticastCreate", 2) => { + if version >= 12010 { + return cuMulticastCreate as _; + } + usize::MAX as _ + } + (b"cuMulticastGetGranularity", 0) => { + if version >= 12010 { + return cuMulticastGetGranularity as _; + } + usize::MAX as _ + } + (b"cuMulticastGetGranularity", 1) => { + if version >= 12010 { + return cuMulticastGetGranularity as _; + } + usize::MAX as _ + } + (b"cuMulticastGetGranularity", 2) => { + if version >= 12010 { + return cuMulticastGetGranularity as _; + } + usize::MAX as _ + } + (b"cuMulticastUnbind", 0) => { + if version >= 12010 { + return cuMulticastUnbind as _; + } + usize::MAX as _ + } + (b"cuMulticastUnbind", 1) => { + if version >= 12010 { + return cuMulticastUnbind as _; + } + usize::MAX as _ + } + (b"cuMulticastUnbind", 2) => { + if version >= 12010 { + return cuMulticastUnbind as _; + } + usize::MAX as _ + } + (b"cuOccupancyAvailableDynamicSMemPerBlock", 0) => { + if version >= 10020 { + return cuOccupancyAvailableDynamicSMemPerBlock as _; + } + usize::MAX as _ + } + (b"cuOccupancyAvailableDynamicSMemPerBlock", 1) => { + if version >= 10020 { + return cuOccupancyAvailableDynamicSMemPerBlock as _; + } + usize::MAX as _ + } + (b"cuOccupancyAvailableDynamicSMemPerBlock", 2) => { + if version >= 10020 { + return cuOccupancyAvailableDynamicSMemPerBlock as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessor", 0) => { + if version >= 6050 { + return cuOccupancyMaxActiveBlocksPerMultiprocessor as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessor", 1) => { + if version >= 6050 { + return cuOccupancyMaxActiveBlocksPerMultiprocessor as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessor", 2) => { + if version >= 6050 { + return cuOccupancyMaxActiveBlocksPerMultiprocessor as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags", 0) => { + if version >= 7000 { + return cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags", 1) => { + if version >= 7000 { + return cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags", 2) => { + if version >= 7000 { + return cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveClusters", 0) => { + if version >= 11070 { + return cuOccupancyMaxActiveClusters as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveClusters", 1) => { + if version >= 11070 { + return cuOccupancyMaxActiveClusters as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxActiveClusters", 2) => { + if version >= 11070 { + return cuOccupancyMaxActiveClusters as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSize", 0) => { + if version >= 6050 { + return cuOccupancyMaxPotentialBlockSize as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSize", 1) => { + if version >= 6050 { + return cuOccupancyMaxPotentialBlockSize as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSize", 2) => { + if version >= 6050 { + return cuOccupancyMaxPotentialBlockSize as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSizeWithFlags", 0) => { + if version >= 7000 { + return cuOccupancyMaxPotentialBlockSizeWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSizeWithFlags", 1) => { + if version >= 7000 { + return cuOccupancyMaxPotentialBlockSizeWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialBlockSizeWithFlags", 2) => { + if version >= 7000 { + return cuOccupancyMaxPotentialBlockSizeWithFlags as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialClusterSize", 0) => { + if version >= 11070 { + return cuOccupancyMaxPotentialClusterSize as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialClusterSize", 1) => { + if version >= 11070 { + return cuOccupancyMaxPotentialClusterSize as _; + } + usize::MAX as _ + } + (b"cuOccupancyMaxPotentialClusterSize", 2) => { + if version >= 11070 { + return cuOccupancyMaxPotentialClusterSize as _; + } + usize::MAX as _ + } + (b"cuParamSetSize", 0) => { + if version >= 2000 { + return cuParamSetSize as _; + } + usize::MAX as _ + } + (b"cuParamSetSize", 1) => { + if version >= 2000 { + return cuParamSetSize as _; + } + usize::MAX as _ + } + (b"cuParamSetSize", 2) => { + if version >= 2000 { + return cuParamSetSize as _; + } + usize::MAX as _ + } + (b"cuParamSetTexRef", 0) => { + if version >= 2000 { + return cuParamSetTexRef as _; + } + usize::MAX as _ + } + (b"cuParamSetTexRef", 1) => { + if version >= 2000 { + return cuParamSetTexRef as _; + } + usize::MAX as _ + } + (b"cuParamSetTexRef", 2) => { + if version >= 2000 { + return cuParamSetTexRef as _; + } + usize::MAX as _ + } + (b"cuParamSetf", 0) => { + if version >= 2000 { + return cuParamSetf as _; + } + usize::MAX as _ + } + (b"cuParamSetf", 1) => { + if version >= 2000 { + return cuParamSetf as _; + } + usize::MAX as _ + } + (b"cuParamSetf", 2) => { + if version >= 2000 { + return cuParamSetf as _; + } + usize::MAX as _ + } + (b"cuParamSeti", 0) => { + if version >= 2000 { + return cuParamSeti as _; + } + usize::MAX as _ + } + (b"cuParamSeti", 1) => { + if version >= 2000 { + return cuParamSeti as _; + } + usize::MAX as _ + } + (b"cuParamSeti", 2) => { + if version >= 2000 { + return cuParamSeti as _; + } + usize::MAX as _ + } + (b"cuParamSetv", 0) => { + if version >= 2000 { + return cuParamSetv as _; + } + usize::MAX as _ + } + (b"cuParamSetv", 1) => { + if version >= 2000 { + return cuParamSetv as _; + } + usize::MAX as _ + } + (b"cuParamSetv", 2) => { + if version >= 2000 { + return cuParamSetv as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttribute", 0) => { + if version >= 4000 { + return cuPointerGetAttribute as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttribute", 1) => { + if version >= 4000 { + return cuPointerGetAttribute as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttribute", 2) => { + if version >= 4000 { + return cuPointerGetAttribute as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttributes", 0) => { + if version >= 7000 { + return cuPointerGetAttributes as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttributes", 1) => { + if version >= 7000 { + return cuPointerGetAttributes as _; + } + usize::MAX as _ + } + (b"cuPointerGetAttributes", 2) => { + if version >= 7000 { + return cuPointerGetAttributes as _; + } + usize::MAX as _ + } + (b"cuPointerSetAttribute", 0) => { + if version >= 6000 { + return cuPointerSetAttribute as _; + } + usize::MAX as _ + } + (b"cuPointerSetAttribute", 1) => { + if version >= 6000 { + return cuPointerSetAttribute as _; + } + usize::MAX as _ + } + (b"cuPointerSetAttribute", 2) => { + if version >= 6000 { + return cuPointerSetAttribute as _; + } + usize::MAX as _ + } + (b"cuProfilerInitialize", 0) => { + if version >= 4000 { + return cuProfilerInitialize as _; + } + usize::MAX as _ + } + (b"cuProfilerInitialize", 1) => { + if version >= 4000 { + return cuProfilerInitialize as _; + } + usize::MAX as _ + } + (b"cuProfilerInitialize", 2) => { + if version >= 4000 { + return cuProfilerInitialize as _; + } + usize::MAX as _ + } + (b"cuProfilerStart", 0) => { + if version >= 4000 { + return cuProfilerStart as _; + } + usize::MAX as _ + } + (b"cuProfilerStart", 1) => { + if version >= 4000 { + return cuProfilerStart as _; + } + usize::MAX as _ + } + (b"cuProfilerStart", 2) => { + if version >= 4000 { + return cuProfilerStart as _; + } + usize::MAX as _ + } + (b"cuProfilerStop", 0) => { + if version >= 4000 { + return cuProfilerStop as _; + } + usize::MAX as _ + } + (b"cuProfilerStop", 1) => { + if version >= 4000 { + return cuProfilerStop as _; + } + usize::MAX as _ + } + (b"cuProfilerStop", 2) => { + if version >= 4000 { + return cuProfilerStop as _; + } + usize::MAX as _ + } + (b"cuSignalExternalSemaphoresAsync", 0) => { + if version >= 10000 { + return cuSignalExternalSemaphoresAsync as _; + } + usize::MAX as _ + } + (b"cuSignalExternalSemaphoresAsync", 1) => { + if version >= 10000 { + return cuSignalExternalSemaphoresAsync as _; + } + usize::MAX as _ + } + (b"cuSignalExternalSemaphoresAsync", 2) => { + if version >= 10000 { + return cuSignalExternalSemaphoresAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamAddCallback", 0) => { + if version >= 5000 { + return cuStreamAddCallback as _; + } + usize::MAX as _ + } + (b"cuStreamAddCallback", 1) => { + if version >= 5000 { + return cuStreamAddCallback as _; + } + usize::MAX as _ + } + (b"cuStreamAddCallback", 2) => { + if version >= 7000 { + return cuStreamAddCallback_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamAttachMemAsync", 0) => { + if version >= 6000 { + return cuStreamAttachMemAsync as _; + } + usize::MAX as _ + } + (b"cuStreamAttachMemAsync", 1) => { + if version >= 6000 { + return cuStreamAttachMemAsync as _; + } + usize::MAX as _ + } + (b"cuStreamAttachMemAsync", 2) => { + if version >= 7000 { + return cuStreamAttachMemAsync_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamBatchMemOp", 0) => { + if version >= 11070 { + return cuStreamBatchMemOp_v2 as _; + } + if version >= 8000 { + return cuStreamBatchMemOp as _; + } + usize::MAX as _ + } + (b"cuStreamBatchMemOp", 1) => { + if version >= 11070 { + return cuStreamBatchMemOp_v2 as _; + } + if version >= 8000 { + return cuStreamBatchMemOp as _; + } + usize::MAX as _ + } + (b"cuStreamBatchMemOp", 2) => { + if version >= 11070 { + return cuStreamBatchMemOp_v2_ptsz as _; + } + if version >= 8000 { + return cuStreamBatchMemOp_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamBeginCapture", 0) => { + if version >= 10010 { + return cuStreamBeginCapture_v2 as _; + } + if version >= 10000 { + return cuStreamBeginCapture as _; + } + usize::MAX as _ + } + (b"cuStreamBeginCapture", 1) => { + if version >= 10010 { + return cuStreamBeginCapture_v2 as _; + } + if version >= 10000 { + return cuStreamBeginCapture as _; + } + usize::MAX as _ + } + (b"cuStreamBeginCapture", 2) => { + if version >= 10010 { + return cuStreamBeginCapture_v2_ptsz as _; + } + if version >= 10000 { + return cuStreamBeginCapture_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamCopyAttributes", 0) => { + if version >= 11000 { + return cuStreamCopyAttributes as _; + } + usize::MAX as _ + } + (b"cuStreamCopyAttributes", 1) => { + if version >= 11000 { + return cuStreamCopyAttributes as _; + } + usize::MAX as _ + } + (b"cuStreamCopyAttributes", 2) => { + if version >= 11000 { + return cuStreamCopyAttributes_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamCreate", 0) => { + if version >= 2000 { + return cuStreamCreate as _; + } + usize::MAX as _ + } + (b"cuStreamCreate", 1) => { + if version >= 2000 { + return cuStreamCreate as _; + } + usize::MAX as _ + } + (b"cuStreamCreate", 2) => { + if version >= 2000 { + return cuStreamCreate as _; + } + usize::MAX as _ + } + (b"cuStreamCreateWithPriority", 0) => { + if version >= 5050 { + return cuStreamCreateWithPriority as _; + } + usize::MAX as _ + } + (b"cuStreamCreateWithPriority", 1) => { + if version >= 5050 { + return cuStreamCreateWithPriority as _; + } + usize::MAX as _ + } + (b"cuStreamCreateWithPriority", 2) => { + if version >= 5050 { + return cuStreamCreateWithPriority as _; + } + usize::MAX as _ + } + (b"cuStreamDestroy", 0) => { + if version >= 4000 { + return cuStreamDestroy_v2 as _; + } + if version >= 2000 { + return cuStreamDestroy as _; + } + usize::MAX as _ + } + (b"cuStreamDestroy", 1) => { + if version >= 4000 { + return cuStreamDestroy_v2 as _; + } + if version >= 2000 { + return cuStreamDestroy as _; + } + usize::MAX as _ + } + (b"cuStreamDestroy", 2) => { + if version >= 4000 { + return cuStreamDestroy_v2 as _; + } + if version >= 2000 { + return cuStreamDestroy as _; + } + usize::MAX as _ + } + (b"cuStreamEndCapture", 0) => { + if version >= 10000 { + return cuStreamEndCapture as _; + } + usize::MAX as _ + } + (b"cuStreamEndCapture", 1) => { + if version >= 10000 { + return cuStreamEndCapture as _; + } + usize::MAX as _ + } + (b"cuStreamEndCapture", 2) => { + if version >= 10000 { + return cuStreamEndCapture_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetAttribute", 0) => { + if version >= 11000 { + return cuStreamGetAttribute as _; + } + usize::MAX as _ + } + (b"cuStreamGetAttribute", 1) => { + if version >= 11000 { + return cuStreamGetAttribute as _; + } + usize::MAX as _ + } + (b"cuStreamGetAttribute", 2) => { + if version >= 11000 { + return cuStreamGetAttribute_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetCaptureInfo", 0) => { + if version >= 11030 { + return cuStreamGetCaptureInfo_v2 as _; + } + if version >= 10010 { + return cuStreamGetCaptureInfo as _; + } + usize::MAX as _ + } + (b"cuStreamGetCaptureInfo", 1) => { + if version >= 11030 { + return cuStreamGetCaptureInfo_v2 as _; + } + if version >= 10010 { + return cuStreamGetCaptureInfo as _; + } + usize::MAX as _ + } + (b"cuStreamGetCaptureInfo", 2) => { + if version >= 11030 { + return cuStreamGetCaptureInfo_v2_ptsz as _; + } + if version >= 10010 { + return cuStreamGetCaptureInfo_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetCtx", 0) => { + if version >= 9020 { + return cuStreamGetCtx as _; + } + usize::MAX as _ + } + (b"cuStreamGetCtx", 1) => { + if version >= 9020 { + return cuStreamGetCtx as _; + } + usize::MAX as _ + } + (b"cuStreamGetCtx", 2) => { + if version >= 9020 { + return cuStreamGetCtx_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetFlags", 0) => { + if version >= 5050 { + return cuStreamGetFlags as _; + } + usize::MAX as _ + } + (b"cuStreamGetFlags", 1) => { + if version >= 5050 { + return cuStreamGetFlags as _; + } + usize::MAX as _ + } + (b"cuStreamGetFlags", 2) => { + if version >= 7000 { + return cuStreamGetFlags_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetId", 0) => { + if version >= 12000 { + return cuStreamGetId as _; + } + usize::MAX as _ + } + (b"cuStreamGetId", 1) => { + if version >= 12000 { + return cuStreamGetId as _; + } + usize::MAX as _ + } + (b"cuStreamGetId", 2) => { + if version >= 12000 { + return cuStreamGetId_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamGetPriority", 0) => { + if version >= 5050 { + return cuStreamGetPriority as _; + } + usize::MAX as _ + } + (b"cuStreamGetPriority", 1) => { + if version >= 5050 { + return cuStreamGetPriority as _; + } + usize::MAX as _ + } + (b"cuStreamGetPriority", 2) => { + if version >= 7000 { + return cuStreamGetPriority_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamIsCapturing", 0) => { + if version >= 10000 { + return cuStreamIsCapturing as _; + } + usize::MAX as _ + } + (b"cuStreamIsCapturing", 1) => { + if version >= 10000 { + return cuStreamIsCapturing as _; + } + usize::MAX as _ + } + (b"cuStreamIsCapturing", 2) => { + if version >= 10000 { + return cuStreamIsCapturing_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamQuery", 0) => { + if version >= 2000 { + return cuStreamQuery as _; + } + usize::MAX as _ + } + (b"cuStreamQuery", 1) => { + if version >= 2000 { + return cuStreamQuery as _; + } + usize::MAX as _ + } + (b"cuStreamQuery", 2) => { + if version >= 7000 { + return cuStreamQuery_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamSetAttribute", 0) => { + if version >= 11000 { + return cuStreamSetAttribute as _; + } + usize::MAX as _ + } + (b"cuStreamSetAttribute", 1) => { + if version >= 11000 { + return cuStreamSetAttribute as _; + } + usize::MAX as _ + } + (b"cuStreamSetAttribute", 2) => { + if version >= 11000 { + return cuStreamSetAttribute_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamSynchronize", 0) => { + if version >= 2000 { + return cuStreamSynchronize as _; + } + usize::MAX as _ + } + (b"cuStreamSynchronize", 1) => { + if version >= 2000 { + return cuStreamSynchronize as _; + } + usize::MAX as _ + } + (b"cuStreamSynchronize", 2) => { + if version >= 7000 { + return cuStreamSynchronize_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamUpdateCaptureDependencies", 0) => { + if version >= 11030 { + return cuStreamUpdateCaptureDependencies as _; + } + usize::MAX as _ + } + (b"cuStreamUpdateCaptureDependencies", 1) => { + if version >= 11030 { + return cuStreamUpdateCaptureDependencies as _; + } + usize::MAX as _ + } + (b"cuStreamUpdateCaptureDependencies", 2) => { + if version >= 11030 { + return cuStreamUpdateCaptureDependencies_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamWaitEvent", 0) => { + if version >= 3020 { + return cuStreamWaitEvent as _; + } + usize::MAX as _ + } + (b"cuStreamWaitEvent", 1) => { + if version >= 3020 { + return cuStreamWaitEvent as _; + } + usize::MAX as _ + } + (b"cuStreamWaitEvent", 2) => { + if version >= 7000 { + return cuStreamWaitEvent_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue32", 0) => { + if version >= 11070 { + return cuStreamWaitValue32_v2 as _; + } + if version >= 8000 { + return cuStreamWaitValue32 as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue32", 1) => { + if version >= 11070 { + return cuStreamWaitValue32_v2 as _; + } + if version >= 8000 { + return cuStreamWaitValue32 as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue32", 2) => { + if version >= 11070 { + return cuStreamWaitValue32_v2_ptsz as _; + } + if version >= 8000 { + return cuStreamWaitValue32_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue64", 0) => { + if version >= 11070 { + return cuStreamWaitValue64_v2 as _; + } + if version >= 9000 { + return cuStreamWaitValue64 as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue64", 1) => { + if version >= 11070 { + return cuStreamWaitValue64_v2 as _; + } + if version >= 9000 { + return cuStreamWaitValue64 as _; + } + usize::MAX as _ + } + (b"cuStreamWaitValue64", 2) => { + if version >= 11070 { + return cuStreamWaitValue64_v2_ptsz as _; + } + if version >= 9000 { + return cuStreamWaitValue64_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue32", 0) => { + if version >= 11070 { + return cuStreamWriteValue32_v2 as _; + } + if version >= 8000 { + return cuStreamWriteValue32 as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue32", 1) => { + if version >= 11070 { + return cuStreamWriteValue32_v2 as _; + } + if version >= 8000 { + return cuStreamWriteValue32 as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue32", 2) => { + if version >= 11070 { + return cuStreamWriteValue32_v2_ptsz as _; + } + if version >= 8000 { + return cuStreamWriteValue32_ptsz as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue64", 0) => { + if version >= 11070 { + return cuStreamWriteValue64_v2 as _; + } + if version >= 9000 { + return cuStreamWriteValue64 as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue64", 1) => { + if version >= 11070 { + return cuStreamWriteValue64_v2 as _; + } + if version >= 9000 { + return cuStreamWriteValue64 as _; + } + usize::MAX as _ + } + (b"cuStreamWriteValue64", 2) => { + if version >= 11070 { + return cuStreamWriteValue64_v2_ptsz as _; + } + if version >= 9000 { + return cuStreamWriteValue64_ptsz as _; + } + usize::MAX as _ + } + (b"cuSurfObjectCreate", 0) => { + if version >= 5000 { + return cuSurfObjectCreate as _; + } + usize::MAX as _ + } + (b"cuSurfObjectCreate", 1) => { + if version >= 5000 { + return cuSurfObjectCreate as _; + } + usize::MAX as _ + } + (b"cuSurfObjectCreate", 2) => { + if version >= 5000 { + return cuSurfObjectCreate as _; + } + usize::MAX as _ + } + (b"cuSurfObjectDestroy", 0) => { + if version >= 5000 { + return cuSurfObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuSurfObjectDestroy", 1) => { + if version >= 5000 { + return cuSurfObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuSurfObjectDestroy", 2) => { + if version >= 5000 { + return cuSurfObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuSurfObjectGetResourceDesc", 0) => { + if version >= 5000 { + return cuSurfObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuSurfObjectGetResourceDesc", 1) => { + if version >= 5000 { + return cuSurfObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuSurfObjectGetResourceDesc", 2) => { + if version >= 5000 { + return cuSurfObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuSurfRefGetArray", 0) => { + if version >= 3000 { + return cuSurfRefGetArray as _; + } + usize::MAX as _ + } + (b"cuSurfRefGetArray", 1) => { + if version >= 3000 { + return cuSurfRefGetArray as _; + } + usize::MAX as _ + } + (b"cuSurfRefGetArray", 2) => { + if version >= 3000 { + return cuSurfRefGetArray as _; + } + usize::MAX as _ + } + (b"cuSurfRefSetArray", 0) => { + if version >= 3000 { + return cuSurfRefSetArray as _; + } + usize::MAX as _ + } + (b"cuSurfRefSetArray", 1) => { + if version >= 3000 { + return cuSurfRefSetArray as _; + } + usize::MAX as _ + } + (b"cuSurfRefSetArray", 2) => { + if version >= 3000 { + return cuSurfRefSetArray as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeIm2col", 0) => { + if version >= 12000 { + return cuTensorMapEncodeIm2col as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeIm2col", 1) => { + if version >= 12000 { + return cuTensorMapEncodeIm2col as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeIm2col", 2) => { + if version >= 12000 { + return cuTensorMapEncodeIm2col as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeTiled", 0) => { + if version >= 12000 { + return cuTensorMapEncodeTiled as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeTiled", 1) => { + if version >= 12000 { + return cuTensorMapEncodeTiled as _; + } + usize::MAX as _ + } + (b"cuTensorMapEncodeTiled", 2) => { + if version >= 12000 { + return cuTensorMapEncodeTiled as _; + } + usize::MAX as _ + } + (b"cuTensorMapReplaceAddress", 0) => { + if version >= 12000 { + return cuTensorMapReplaceAddress as _; + } + usize::MAX as _ + } + (b"cuTensorMapReplaceAddress", 1) => { + if version >= 12000 { + return cuTensorMapReplaceAddress as _; + } + usize::MAX as _ + } + (b"cuTensorMapReplaceAddress", 2) => { + if version >= 12000 { + return cuTensorMapReplaceAddress as _; + } + usize::MAX as _ + } + (b"cuTexObjectCreate", 0) => { + if version >= 5000 { + return cuTexObjectCreate as _; + } + usize::MAX as _ + } + (b"cuTexObjectCreate", 1) => { + if version >= 5000 { + return cuTexObjectCreate as _; + } + usize::MAX as _ + } + (b"cuTexObjectCreate", 2) => { + if version >= 5000 { + return cuTexObjectCreate as _; + } + usize::MAX as _ + } + (b"cuTexObjectDestroy", 0) => { + if version >= 5000 { + return cuTexObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuTexObjectDestroy", 1) => { + if version >= 5000 { + return cuTexObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuTexObjectDestroy", 2) => { + if version >= 5000 { + return cuTexObjectDestroy as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceDesc", 0) => { + if version >= 5000 { + return cuTexObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceDesc", 1) => { + if version >= 5000 { + return cuTexObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceDesc", 2) => { + if version >= 5000 { + return cuTexObjectGetResourceDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceViewDesc", 0) => { + if version >= 5000 { + return cuTexObjectGetResourceViewDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceViewDesc", 1) => { + if version >= 5000 { + return cuTexObjectGetResourceViewDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetResourceViewDesc", 2) => { + if version >= 5000 { + return cuTexObjectGetResourceViewDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetTextureDesc", 0) => { + if version >= 5000 { + return cuTexObjectGetTextureDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetTextureDesc", 1) => { + if version >= 5000 { + return cuTexObjectGetTextureDesc as _; + } + usize::MAX as _ + } + (b"cuTexObjectGetTextureDesc", 2) => { + if version >= 5000 { + return cuTexObjectGetTextureDesc as _; + } + usize::MAX as _ + } + (b"cuTexRefCreate", 0) => { + if version >= 2000 { + return cuTexRefCreate as _; + } + usize::MAX as _ + } + (b"cuTexRefCreate", 1) => { + if version >= 2000 { + return cuTexRefCreate as _; + } + usize::MAX as _ + } + (b"cuTexRefCreate", 2) => { + if version >= 2000 { + return cuTexRefCreate as _; + } + usize::MAX as _ + } + (b"cuTexRefDestroy", 0) => { + if version >= 2000 { + return cuTexRefDestroy as _; + } + usize::MAX as _ + } + (b"cuTexRefDestroy", 1) => { + if version >= 2000 { + return cuTexRefDestroy as _; + } + usize::MAX as _ + } + (b"cuTexRefDestroy", 2) => { + if version >= 2000 { + return cuTexRefDestroy as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddress", 0) => { + if version >= 3020 { + return cuTexRefGetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefGetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddress", 1) => { + if version >= 3020 { + return cuTexRefGetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefGetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddress", 2) => { + if version >= 3020 { + return cuTexRefGetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefGetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddressMode", 0) => { + if version >= 2000 { + return cuTexRefGetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddressMode", 1) => { + if version >= 2000 { + return cuTexRefGetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetAddressMode", 2) => { + if version >= 2000 { + return cuTexRefGetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetArray", 0) => { + if version >= 2000 { + return cuTexRefGetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefGetArray", 1) => { + if version >= 2000 { + return cuTexRefGetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefGetArray", 2) => { + if version >= 2000 { + return cuTexRefGetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefGetBorderColor", 0) => { + if version >= 8000 { + return cuTexRefGetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefGetBorderColor", 1) => { + if version >= 8000 { + return cuTexRefGetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefGetBorderColor", 2) => { + if version >= 8000 { + return cuTexRefGetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFilterMode", 0) => { + if version >= 2000 { + return cuTexRefGetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFilterMode", 1) => { + if version >= 2000 { + return cuTexRefGetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFilterMode", 2) => { + if version >= 2000 { + return cuTexRefGetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFlags", 0) => { + if version >= 2000 { + return cuTexRefGetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFlags", 1) => { + if version >= 2000 { + return cuTexRefGetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFlags", 2) => { + if version >= 2000 { + return cuTexRefGetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFormat", 0) => { + if version >= 2000 { + return cuTexRefGetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFormat", 1) => { + if version >= 2000 { + return cuTexRefGetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefGetFormat", 2) => { + if version >= 2000 { + return cuTexRefGetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMaxAnisotropy", 0) => { + if version >= 5000 { + return cuTexRefGetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMaxAnisotropy", 1) => { + if version >= 5000 { + return cuTexRefGetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMaxAnisotropy", 2) => { + if version >= 5000 { + return cuTexRefGetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapFilterMode", 0) => { + if version >= 5000 { + return cuTexRefGetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapFilterMode", 1) => { + if version >= 5000 { + return cuTexRefGetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapFilterMode", 2) => { + if version >= 5000 { + return cuTexRefGetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelBias", 0) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelBias", 1) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelBias", 2) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelClamp", 0) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelClamp", 1) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmapLevelClamp", 2) => { + if version >= 5000 { + return cuTexRefGetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmappedArray", 0) => { + if version >= 5000 { + return cuTexRefGetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmappedArray", 1) => { + if version >= 5000 { + return cuTexRefGetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuTexRefGetMipmappedArray", 2) => { + if version >= 5000 { + return cuTexRefGetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress", 0) => { + if version >= 3020 { + return cuTexRefSetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefSetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress", 1) => { + if version >= 3020 { + return cuTexRefSetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefSetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress", 2) => { + if version >= 3020 { + return cuTexRefSetAddress_v2 as _; + } + if version >= 2000 { + return cuTexRefSetAddress as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress2D", 0) => { + if version >= 4010 { + return cuTexRefSetAddress2D_v3 as _; + } + if version >= 3020 { + return cuTexRefSetAddress2D_v2 as _; + } + if version >= 2020 { + return cuTexRefSetAddress2D as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress2D", 1) => { + if version >= 4010 { + return cuTexRefSetAddress2D_v3 as _; + } + if version >= 3020 { + return cuTexRefSetAddress2D_v2 as _; + } + if version >= 2020 { + return cuTexRefSetAddress2D as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddress2D", 2) => { + if version >= 4010 { + return cuTexRefSetAddress2D_v3 as _; + } + if version >= 3020 { + return cuTexRefSetAddress2D_v2 as _; + } + if version >= 2020 { + return cuTexRefSetAddress2D as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddressMode", 0) => { + if version >= 2000 { + return cuTexRefSetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddressMode", 1) => { + if version >= 2000 { + return cuTexRefSetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetAddressMode", 2) => { + if version >= 2000 { + return cuTexRefSetAddressMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetArray", 0) => { + if version >= 2000 { + return cuTexRefSetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetArray", 1) => { + if version >= 2000 { + return cuTexRefSetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetArray", 2) => { + if version >= 2000 { + return cuTexRefSetArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetBorderColor", 0) => { + if version >= 8000 { + return cuTexRefSetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefSetBorderColor", 1) => { + if version >= 8000 { + return cuTexRefSetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefSetBorderColor", 2) => { + if version >= 8000 { + return cuTexRefSetBorderColor as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFilterMode", 0) => { + if version >= 2000 { + return cuTexRefSetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFilterMode", 1) => { + if version >= 2000 { + return cuTexRefSetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFilterMode", 2) => { + if version >= 2000 { + return cuTexRefSetFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFlags", 0) => { + if version >= 2000 { + return cuTexRefSetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFlags", 1) => { + if version >= 2000 { + return cuTexRefSetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFlags", 2) => { + if version >= 2000 { + return cuTexRefSetFlags as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFormat", 0) => { + if version >= 2000 { + return cuTexRefSetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFormat", 1) => { + if version >= 2000 { + return cuTexRefSetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefSetFormat", 2) => { + if version >= 2000 { + return cuTexRefSetFormat as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMaxAnisotropy", 0) => { + if version >= 5000 { + return cuTexRefSetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMaxAnisotropy", 1) => { + if version >= 5000 { + return cuTexRefSetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMaxAnisotropy", 2) => { + if version >= 5000 { + return cuTexRefSetMaxAnisotropy as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapFilterMode", 0) => { + if version >= 5000 { + return cuTexRefSetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapFilterMode", 1) => { + if version >= 5000 { + return cuTexRefSetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapFilterMode", 2) => { + if version >= 5000 { + return cuTexRefSetMipmapFilterMode as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelBias", 0) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelBias", 1) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelBias", 2) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelBias as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelClamp", 0) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelClamp", 1) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmapLevelClamp", 2) => { + if version >= 5000 { + return cuTexRefSetMipmapLevelClamp as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmappedArray", 0) => { + if version >= 5000 { + return cuTexRefSetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmappedArray", 1) => { + if version >= 5000 { + return cuTexRefSetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuTexRefSetMipmappedArray", 2) => { + if version >= 5000 { + return cuTexRefSetMipmappedArray as _; + } + usize::MAX as _ + } + (b"cuThreadExchangeStreamCaptureMode", 0) => { + if version >= 10010 { + return cuThreadExchangeStreamCaptureMode as _; + } + usize::MAX as _ + } + (b"cuThreadExchangeStreamCaptureMode", 1) => { + if version >= 10010 { + return cuThreadExchangeStreamCaptureMode as _; + } + usize::MAX as _ + } + (b"cuThreadExchangeStreamCaptureMode", 2) => { + if version >= 10010 { + return cuThreadExchangeStreamCaptureMode as _; + } + usize::MAX as _ + } + (b"cuUserObjectCreate", 0) => { + if version >= 11030 { + return cuUserObjectCreate as _; + } + usize::MAX as _ + } + (b"cuUserObjectCreate", 1) => { + if version >= 11030 { + return cuUserObjectCreate as _; + } + usize::MAX as _ + } + (b"cuUserObjectCreate", 2) => { + if version >= 11030 { + return cuUserObjectCreate as _; + } + usize::MAX as _ + } + (b"cuUserObjectRelease", 0) => { + if version >= 11030 { + return cuUserObjectRelease as _; + } + usize::MAX as _ + } + (b"cuUserObjectRelease", 1) => { + if version >= 11030 { + return cuUserObjectRelease as _; + } + usize::MAX as _ + } + (b"cuUserObjectRelease", 2) => { + if version >= 11030 { + return cuUserObjectRelease as _; + } + usize::MAX as _ + } + (b"cuUserObjectRetain", 0) => { + if version >= 11030 { + return cuUserObjectRetain as _; + } + usize::MAX as _ + } + (b"cuUserObjectRetain", 1) => { + if version >= 11030 { + return cuUserObjectRetain as _; + } + usize::MAX as _ + } + (b"cuUserObjectRetain", 2) => { + if version >= 11030 { + return cuUserObjectRetain as _; + } + usize::MAX as _ + } + (b"cuWaitExternalSemaphoresAsync", 0) => { + if version >= 10000 { + return cuWaitExternalSemaphoresAsync as _; + } + usize::MAX as _ + } + (b"cuWaitExternalSemaphoresAsync", 1) => { + if version >= 10000 { + return cuWaitExternalSemaphoresAsync as _; + } + usize::MAX as _ + } + (b"cuWaitExternalSemaphoresAsync", 2) => { + if version >= 10000 { + return cuWaitExternalSemaphoresAsync_ptsz as _; + } + usize::MAX as _ + } + _ => std::ptr::null_mut() +} diff --git a/ptx/Cargo.toml b/ptx/Cargo.toml index 409cd1f..fbf5dd2 100644 --- a/ptx/Cargo.toml +++ b/ptx/Cargo.toml @@ -7,21 +7,32 @@ edition = "2018" [lib] [dependencies] -lalrpop-util = "0.19" +hip_common = { path = "../hip_common" } +zluda_llvm = { path = "../zluda_llvm" } +lalrpop-util = "0.20" regex = "1" -rspirv = "0.6" -spirv_headers = "~1.4.2" -quick-error = "1.2" -bit-vec = "0.6" -half ="1.6" -bitflags = "1.2" +thiserror = "1.0" +num-traits = "0.2" +rustc-hash = "1.1" +cpp_demangle = "0.3.5" +paste = "1.0" +bit-vec = "0.6.3" +either = "1.9" -[build-dependencies.lalrpop] -version = "0.19" -features = ["lexer"] +[dependencies.half] +version = "1.8" +features = ["num-traits"] [dev-dependencies] -level_zero-sys = { path = "../level_zero-sys" } -level_zero = { path = "../level_zero" } -spirv_tools-sys = { path = "../spirv_tools-sys" } -paste = "1.0" +cuda_base = { path = "../cuda_base" } +cuda_types = { path = "../cuda_types" } +hip_runtime-sys = { path = "../hip_runtime-sys" } +hiprt-sys = { path = "../hiprt-sys" } +comgr = { path = "../comgr" } +tempfile = "3" +libloading = "0.8" +lazy_static = "1.4.0" + +[build-dependencies.lalrpop] +version = "0.20" +features = ["lexer"] diff --git a/ptx/build.rs b/ptx/build.rs index 42c5d59..23c7d3f 100644 --- a/ptx/build.rs +++ b/ptx/build.rs @@ -2,4 +2,4 @@ extern crate lalrpop; fn main() { lalrpop::process_root().unwrap(); -} \ No newline at end of file +} diff --git a/ptx/lib/.gitattributes b/ptx/lib/.gitattributes new file mode 100644 index 0000000..008ba9f --- /dev/null +++ b/ptx/lib/.gitattributes @@ -0,0 +1,2 @@ +*.cpp diff +*.hpp diff diff --git a/ptx/lib/cvt.h b/ptx/lib/cvt.h new file mode 100644 index 0000000..9b9c4e5 --- /dev/null +++ b/ptx/lib/cvt.h @@ -0,0 +1,413 @@ +// GENERATED AUTOMATICALLY BY cvt.py, DON'T CHANGE MANUALLY +extern "C" +{ +typedef __fp16 half; +half convert_half_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_f32)(float x) { auto temp = __float2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_f32)(float x) { auto temp = __float2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_f32)(float x) { auto temp = __float2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_f32)(float x) { auto temp = __float2half_ru(x); return *reinterpret_cast(&temp); } +half convert_half_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_f64)(double x) { return convert_half_rte(x); } +half convert_half_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_f64)(double x) { return convert_half_rtz(x); } +half convert_half_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_f64)(double x) { return convert_half_rtn(x); } +half convert_half_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_f64)(double x) { return convert_half_rtp(x); } +float convert_float_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_f64)(double x) { return __double2float_rn(x); } +float convert_float_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_f64)(double x) { return __double2float_rz(x); } +float convert_float_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_f64)(double x) { return __double2float_rd(x); } +float convert_float_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_f64)(double x) { return __double2float_ru(x); } +half convert_half_rte(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_s8)(char x) { return convert_half_rte(x); } +half convert_half_rtz(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_s8)(char x) { return convert_half_rtz(x); } +half convert_half_rtn(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_s8)(char x) { return convert_half_rtn(x); } +half convert_half_rtp(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_s8)(char x) { return convert_half_rtp(x); } +float convert_float_rte(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_s8)(char x) { return convert_float_rte(x); } +float convert_float_rtz(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_s8)(char x) { return convert_float_rtz(x); } +float convert_float_rtn(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_s8)(char x) { return convert_float_rtn(x); } +float convert_float_rtp(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_s8)(char x) { return convert_float_rtp(x); } +double convert_double_rte(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_s8)(char x) { return convert_double_rte(x); } +double convert_double_rtz(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_s8)(char x) { return convert_double_rtz(x); } +double convert_double_rtn(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_s8)(char x) { return convert_double_rtn(x); } +double convert_double_rtp(char) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_s8)(char x) { return convert_double_rtp(x); } +half convert_half_rte(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_s16)(short x) { auto temp = __short2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_s16)(short x) { auto temp = __short2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_s16)(short x) { auto temp = __short2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_s16)(short x) { auto temp = __short2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_s16)(short x) { return convert_float_rte(x); } +float convert_float_rtz(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_s16)(short x) { return convert_float_rtz(x); } +float convert_float_rtn(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_s16)(short x) { return convert_float_rtn(x); } +float convert_float_rtp(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_s16)(short x) { return convert_float_rtp(x); } +double convert_double_rte(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_s16)(short x) { return convert_double_rte(x); } +double convert_double_rtz(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_s16)(short x) { return convert_double_rtz(x); } +double convert_double_rtn(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_s16)(short x) { return convert_double_rtn(x); } +double convert_double_rtp(short) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_s16)(short x) { return convert_double_rtp(x); } +half convert_half_rte(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_s32)(int x) { auto temp = __int2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_s32)(int x) { auto temp = __int2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_s32)(int x) { auto temp = __int2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_s32)(int x) { auto temp = __int2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_s32)(int x) { return __int2float_rn(x); } +float convert_float_rtz(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_s32)(int x) { return __int2float_rz(x); } +float convert_float_rtn(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_s32)(int x) { return __int2float_rd(x); } +float convert_float_rtp(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_s32)(int x) { return __int2float_ru(x); } +double convert_double_rte(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_s32)(int x) { return __int2double_rn(x); } +double convert_double_rtz(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_s32)(int x) { return convert_double_rtz(x); } +double convert_double_rtn(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_s32)(int x) { return convert_double_rtn(x); } +double convert_double_rtp(int) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_s32)(int x) { return convert_double_rtp(x); } +half convert_half_rte(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_s64)(long x) { auto temp = __ll2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_s64)(long x) { auto temp = __ll2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_s64)(long x) { auto temp = __ll2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_s64)(long x) { auto temp = __ll2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_s64)(long x) { return __ll2float_rn(x); } +float convert_float_rtz(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_s64)(long x) { return __ll2float_rz(x); } +float convert_float_rtn(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_s64)(long x) { return __ll2float_rd(x); } +float convert_float_rtp(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_s64)(long x) { return __ll2float_ru(x); } +double convert_double_rte(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_s64)(long x) { return __ll2double_rn(x); } +double convert_double_rtz(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_s64)(long x) { return __ll2double_rz(x); } +double convert_double_rtn(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_s64)(long x) { return __ll2double_rd(x); } +double convert_double_rtp(long) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_s64)(long x) { return __ll2double_ru(x); } +half convert_half_rte(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_u8)(uchar x) { return convert_half_rte(x); } +half convert_half_rtz(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_u8)(uchar x) { return convert_half_rtz(x); } +half convert_half_rtn(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_u8)(uchar x) { return convert_half_rtn(x); } +half convert_half_rtp(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_u8)(uchar x) { return convert_half_rtp(x); } +float convert_float_rte(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_u8)(uchar x) { return convert_float_rte(x); } +float convert_float_rtz(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_u8)(uchar x) { return convert_float_rtz(x); } +float convert_float_rtn(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_u8)(uchar x) { return convert_float_rtn(x); } +float convert_float_rtp(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_u8)(uchar x) { return convert_float_rtp(x); } +double convert_double_rte(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_u8)(uchar x) { return convert_double_rte(x); } +double convert_double_rtz(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_u8)(uchar x) { return convert_double_rtz(x); } +double convert_double_rtn(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_u8)(uchar x) { return convert_double_rtn(x); } +double convert_double_rtp(uchar) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_u8)(uchar x) { return convert_double_rtp(x); } +half convert_half_rte(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_u16)(ushort x) { auto temp = __ushort2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_u16)(ushort x) { auto temp = __ushort2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_u16)(ushort x) { auto temp = __ushort2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_u16)(ushort x) { auto temp = __ushort2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_u16)(ushort x) { return convert_float_rte(x); } +float convert_float_rtz(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_u16)(ushort x) { return convert_float_rtz(x); } +float convert_float_rtn(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_u16)(ushort x) { return convert_float_rtn(x); } +float convert_float_rtp(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_u16)(ushort x) { return convert_float_rtp(x); } +double convert_double_rte(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_u16)(ushort x) { return convert_double_rte(x); } +double convert_double_rtz(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_u16)(ushort x) { return convert_double_rtz(x); } +double convert_double_rtn(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_u16)(ushort x) { return convert_double_rtn(x); } +double convert_double_rtp(ushort) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_u16)(ushort x) { return convert_double_rtp(x); } +half convert_half_rte(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_u32)(uint x) { auto temp = __uint2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_u32)(uint x) { auto temp = __uint2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_u32)(uint x) { auto temp = __uint2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_u32)(uint x) { auto temp = __uint2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_u32)(uint x) { return __uint2float_rn(x); } +float convert_float_rtz(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_u32)(uint x) { return __uint2float_rz(x); } +float convert_float_rtn(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_u32)(uint x) { return __uint2float_rd(x); } +float convert_float_rtp(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_u32)(uint x) { return __uint2float_ru(x); } +double convert_double_rte(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_u32)(uint x) { return convert_double_rte(x); } +double convert_double_rtz(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_u32)(uint x) { return convert_double_rtz(x); } +double convert_double_rtn(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_u32)(uint x) { return convert_double_rtn(x); } +double convert_double_rtp(uint) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_u32)(uint x) { return convert_double_rtp(x); } +half convert_half_rte(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rn_f16_u64)(ulong x) { auto temp = __ull2half_rn(x); return *reinterpret_cast(&temp); } +half convert_half_rtz(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rz_f16_u64)(ulong x) { auto temp = __ull2half_rz(x); return *reinterpret_cast(&temp); } +half convert_half_rtn(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rm_f16_u64)(ulong x) { auto temp = __ull2half_rd(x); return *reinterpret_cast(&temp); } +half convert_half_rtp(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) half FUNC(cvt_rp_f16_u64)(ulong x) { auto temp = __ull2half_ru(x); return *reinterpret_cast(&temp); } +float convert_float_rte(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rn_f32_u64)(ulong x) { return __ull2float_rn(x); } +float convert_float_rtz(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rz_f32_u64)(ulong x) { return __ull2float_rz(x); } +float convert_float_rtn(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rm_f32_u64)(ulong x) { return __ull2float_rd(x); } +float convert_float_rtp(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) float FUNC(cvt_rp_f32_u64)(ulong x) { return __ull2float_ru(x); } +double convert_double_rte(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rn_f64_u64)(ulong x) { return __ull2double_rn(x); } +double convert_double_rtz(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rz_f64_u64)(ulong x) { return __ull2double_rz(x); } +double convert_double_rtn(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rm_f64_u64)(ulong x) { return __ull2double_rd(x); } +double convert_double_rtp(ulong) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) double FUNC(cvt_rp_f64_u64)(ulong x) { return __ull2double_ru(x); } +char convert_char_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rn_s8_f16)(half x) { return convert_char_rte(x); } +char convert_char_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rz_s8_f16)(half x) { return convert_char_rtz(x); } +char convert_char_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rm_s8_f16)(half x) { return convert_char_rtn(x); } +char convert_char_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rp_s8_f16)(half x) { return convert_char_rtp(x); } +short convert_short_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rn_s16_f16)(half x) { return __half2short_rn(reinterpret_cast(x)); } +short convert_short_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rz_s16_f16)(half x) { return __half2short_rz(reinterpret_cast(x)); } +short convert_short_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rm_s16_f16)(half x) { return __half2short_rd(reinterpret_cast(x)); } +short convert_short_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rp_s16_f16)(half x) { return __half2short_ru(reinterpret_cast(x)); } +int convert_int_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rn_s32_f16)(half x) { return __half2int_rn(reinterpret_cast(x)); } +int convert_int_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rz_s32_f16)(half x) { return __half2int_rz(reinterpret_cast(x)); } +int convert_int_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rm_s32_f16)(half x) { return __half2int_rd(reinterpret_cast(x)); } +int convert_int_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rp_s32_f16)(half x) { return __half2int_ru(reinterpret_cast(x)); } +long convert_long_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rn_s64_f16)(half x) { return __half2ll_rn(reinterpret_cast(x)); } +long convert_long_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rz_s64_f16)(half x) { return __half2ll_rz(reinterpret_cast(x)); } +long convert_long_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rm_s64_f16)(half x) { return __half2ll_rd(reinterpret_cast(x)); } +long convert_long_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rp_s64_f16)(half x) { return __half2ll_ru(reinterpret_cast(x)); } +char convert_char_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rn_s8_f32)(float x) { return convert_char_rte(x); } +char convert_char_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rz_s8_f32)(float x) { return convert_char_rtz(x); } +char convert_char_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rm_s8_f32)(float x) { return convert_char_rtn(x); } +char convert_char_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rp_s8_f32)(float x) { return convert_char_rtp(x); } +short convert_short_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rn_s16_f32)(float x) { return convert_short_rte(x); } +short convert_short_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rz_s16_f32)(float x) { return convert_short_rtz(x); } +short convert_short_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rm_s16_f32)(float x) { return convert_short_rtn(x); } +short convert_short_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rp_s16_f32)(float x) { return convert_short_rtp(x); } +int convert_int_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rn_s32_f32)(float x) { return __float2int_rn(x); } +int convert_int_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rz_s32_f32)(float x) { return __float2int_rz(x); } +int convert_int_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rm_s32_f32)(float x) { return __float2int_rd(x); } +int convert_int_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rp_s32_f32)(float x) { return __float2int_ru(x); } +long convert_long_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rn_s64_f32)(float x) { return __float2ll_rn(x); } +long convert_long_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rz_s64_f32)(float x) { return __float2ll_rz(x); } +long convert_long_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rm_s64_f32)(float x) { return __float2ll_rd(x); } +long convert_long_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rp_s64_f32)(float x) { return __float2ll_ru(x); } +char convert_char_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rn_s8_f64)(double x) { return convert_char_rte(x); } +char convert_char_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rz_s8_f64)(double x) { return convert_char_rtz(x); } +char convert_char_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rm_s8_f64)(double x) { return convert_char_rtn(x); } +char convert_char_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) char FUNC(cvt_rp_s8_f64)(double x) { return convert_char_rtp(x); } +short convert_short_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rn_s16_f64)(double x) { return convert_short_rte(x); } +short convert_short_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rz_s16_f64)(double x) { return convert_short_rtz(x); } +short convert_short_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rm_s16_f64)(double x) { return convert_short_rtn(x); } +short convert_short_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) short FUNC(cvt_rp_s16_f64)(double x) { return convert_short_rtp(x); } +int convert_int_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rn_s32_f64)(double x) { return __double2int_rn(x); } +int convert_int_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rz_s32_f64)(double x) { return __double2int_rz(x); } +int convert_int_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rm_s32_f64)(double x) { return __double2int_rd(x); } +int convert_int_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) int FUNC(cvt_rp_s32_f64)(double x) { return __double2int_ru(x); } +long convert_long_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rn_s64_f64)(double x) { return __double2ll_rn(x); } +long convert_long_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rz_s64_f64)(double x) { return __double2ll_rz(x); } +long convert_long_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rm_s64_f64)(double x) { return __double2ll_rd(x); } +long convert_long_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) long FUNC(cvt_rp_s64_f64)(double x) { return __double2ll_ru(x); } +uchar convert_uchar_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rn_u8_f16)(half x) { return convert_uchar_rte(x); } +uchar convert_uchar_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rz_u8_f16)(half x) { return convert_uchar_rtz(x); } +uchar convert_uchar_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rm_u8_f16)(half x) { return convert_uchar_rtn(x); } +uchar convert_uchar_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rp_u8_f16)(half x) { return convert_uchar_rtp(x); } +ushort convert_ushort_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rn_u16_f16)(half x) { return __half2ushort_rn(reinterpret_cast(x)); } +ushort convert_ushort_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rz_u16_f16)(half x) { return __half2ushort_rz(reinterpret_cast(x)); } +ushort convert_ushort_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rm_u16_f16)(half x) { return __half2ushort_rd(reinterpret_cast(x)); } +ushort convert_ushort_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rp_u16_f16)(half x) { return __half2ushort_ru(reinterpret_cast(x)); } +uint convert_uint_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rn_u32_f16)(half x) { return __half2uint_rn(reinterpret_cast(x)); } +uint convert_uint_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rz_u32_f16)(half x) { return __half2uint_rz(reinterpret_cast(x)); } +uint convert_uint_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rm_u32_f16)(half x) { return __half2uint_rd(reinterpret_cast(x)); } +uint convert_uint_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rp_u32_f16)(half x) { return __half2uint_ru(reinterpret_cast(x)); } +ulong convert_ulong_rte(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rn_u64_f16)(half x) { return __half2ull_rn(reinterpret_cast(x)); } +ulong convert_ulong_rtz(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rz_u64_f16)(half x) { return __half2ull_rz(reinterpret_cast(x)); } +ulong convert_ulong_rtn(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rm_u64_f16)(half x) { return __half2ull_rd(reinterpret_cast(x)); } +ulong convert_ulong_rtp(half) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rp_u64_f16)(half x) { return __half2ull_ru(reinterpret_cast(x)); } +uchar convert_uchar_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rn_u8_f32)(float x) { return convert_uchar_rte(x); } +uchar convert_uchar_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rz_u8_f32)(float x) { return convert_uchar_rtz(x); } +uchar convert_uchar_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rm_u8_f32)(float x) { return convert_uchar_rtn(x); } +uchar convert_uchar_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rp_u8_f32)(float x) { return convert_uchar_rtp(x); } +ushort convert_ushort_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rn_u16_f32)(float x) { return convert_ushort_rte(x); } +ushort convert_ushort_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rz_u16_f32)(float x) { return convert_ushort_rtz(x); } +ushort convert_ushort_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rm_u16_f32)(float x) { return convert_ushort_rtn(x); } +ushort convert_ushort_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rp_u16_f32)(float x) { return convert_ushort_rtp(x); } +uint convert_uint_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rn_u32_f32)(float x) { return __float2uint_rn(x); } +uint convert_uint_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rz_u32_f32)(float x) { return __float2uint_rz(x); } +uint convert_uint_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rm_u32_f32)(float x) { return __float2uint_rd(x); } +uint convert_uint_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rp_u32_f32)(float x) { return __float2uint_ru(x); } +ulong convert_ulong_rte(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rn_u64_f32)(float x) { return __float2ull_rn(x); } +ulong convert_ulong_rtz(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rz_u64_f32)(float x) { return __float2ull_rz(x); } +ulong convert_ulong_rtn(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rm_u64_f32)(float x) { return __float2ull_rd(x); } +ulong convert_ulong_rtp(float) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rp_u64_f32)(float x) { return __float2ull_ru(x); } +uchar convert_uchar_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rn_u8_f64)(double x) { return convert_uchar_rte(x); } +uchar convert_uchar_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rz_u8_f64)(double x) { return convert_uchar_rtz(x); } +uchar convert_uchar_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rm_u8_f64)(double x) { return convert_uchar_rtn(x); } +uchar convert_uchar_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uchar FUNC(cvt_rp_u8_f64)(double x) { return convert_uchar_rtp(x); } +ushort convert_ushort_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rn_u16_f64)(double x) { return convert_ushort_rte(x); } +ushort convert_ushort_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rz_u16_f64)(double x) { return convert_ushort_rtz(x); } +ushort convert_ushort_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rm_u16_f64)(double x) { return convert_ushort_rtn(x); } +ushort convert_ushort_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ushort FUNC(cvt_rp_u16_f64)(double x) { return convert_ushort_rtp(x); } +uint convert_uint_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rn_u32_f64)(double x) { return __double2uint_rn(x); } +uint convert_uint_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rz_u32_f64)(double x) { return __double2uint_rz(x); } +uint convert_uint_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rm_u32_f64)(double x) { return __double2uint_rd(x); } +uint convert_uint_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) uint FUNC(cvt_rp_u32_f64)(double x) { return __double2uint_ru(x); } +ulong convert_ulong_rte(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rn_u64_f64)(double x) { return __double2ull_rn(x); } +ulong convert_ulong_rtz(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rz_u64_f64)(double x) { return __double2ull_rz(x); } +ulong convert_ulong_rtn(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rm_u64_f64)(double x) { return __double2ull_rd(x); } +ulong convert_ulong_rtp(double) __attribute__((overloadable)) __attribute__((device)) __attribute__((const)); +__attribute__((always_inline)) ulong FUNC(cvt_rp_u64_f64)(double x) { return __double2ull_ru(x); } +} diff --git a/ptx/lib/cvt.py b/ptx/lib/cvt.py new file mode 100644 index 0000000..1b66034 --- /dev/null +++ b/ptx/lib/cvt.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python3 + +import os +import itertools +from itertools import chain, islice + + +# rg __[a-z]+2[a-z]+_r[nduz] -o -N --no-filename | sort | uniq | sed -e 's/\(^.*$\)/ \"\1\",/' +HIP_CONV = [ + "__double2float_rd", + "__double2float_rn", + "__double2float_ru", + "__double2float_rz", + "__double2int_rd", + "__double2int_rn", + "__double2int_ru", + "__double2int_rz", + "__double2ll_rd", + "__double2ll_rn", + "__double2ll_ru", + "__double2ll_rz", + "__double2uint_rd", + "__double2uint_rn", + "__double2uint_ru", + "__double2uint_rz", + "__double2ull_rd", + "__double2ull_rn", + "__double2ull_ru", + "__double2ull_rz", + "__float2half_rd", + "__float2half_rd", + "__float2half_rd", + "__float2half_rn", + "__float2half_rn", + "__float2half_rn", + "__float2half_rn", + "__float2half_ru", + "__float2half_ru", + "__float2half_ru", + "__float2half_rz", + "__float2half_rz", + "__float2half_rz", + "__float2int_rd", + "__float2int_rn", + "__float2int_ru", + "__float2int_rz", + "__float2ll_rd", + "__float2ll_rn", + "__float2ll_ru", + "__float2ll_rz", + "__float2uint_rd", + "__float2uint_rn", + "__float2uint_ru", + "__float2uint_rz", + "__float2ull_rd", + "__float2ull_rn", + "__float2ull_ru", + "__float2ull_rz", + "__half2int_rd", + "__half2int_rn", + "__half2int_ru", + "__half2int_rz", + "__half2ll_rd", + "__half2ll_rn", + "__half2ll_ru", + "__half2ll_rz", + "__half2short_rd", + "__half2short_rn", + "__half2short_ru", + "__half2short_rz", + "__half2uint_rd", + "__half2uint_rn", + "__half2uint_ru", + "__half2uint_rz", + "__half2ull_rd", + "__half2ull_rn", + "__half2ull_ru", + "__half2ull_rz", + "__half2ushort_rd", + "__half2ushort_rn", + "__half2ushort_ru", + "__half2ushort_rz", + "__int2double_rn", + "__int2float_rd", + "__int2float_rn", + "__int2float_ru", + "__int2float_rz", + "__int2half_rd", + "__int2half_rn", + "__int2half_ru", + "__int2half_rz", + "__ll2double_rd", + "__ll2double_rn", + "__ll2double_ru", + "__ll2double_rz", + "__ll2float_rd", + "__ll2float_rn", + "__ll2float_ru", + "__ll2float_rz", + "__ll2half_rd", + "__ll2half_rn", + "__ll2half_ru", + "__ll2half_rz", + "__short2half_rd", + "__short2half_rn", + "__short2half_ru", + "__short2half_rz", + # broken in ROCm 5.6 + #"__uint2double_rn", + "__uint2float_rd", + "__uint2float_rn", + "__uint2float_ru", + "__uint2float_rz", + "__uint2half_rd", + "__uint2half_rn", + "__uint2half_ru", + "__uint2half_rz", + "__ull2double_rd", + "__ull2double_rn", + "__ull2double_ru", + "__ull2double_rz", + "__ull2float_rd", + "__ull2float_rn", + "__ull2float_ru", + "__ull2float_rz", + "__ull2half_rd", + "__ull2half_rn", + "__ull2half_ru", + "__ull2half_rz", + "__ushort2half_rd", + "__ushort2half_rn", + "__ushort2half_ru", + "__ushort2half_rz" +] + +# rg __ocml_cvtrt[eznp]_[^_]+_[^\(]+ -o -N --no-filename | sort | uniq | sed -e 's/\(^.*$\)/ \"\1\",/' +OCML_CONV = [ + "__ocml_cvtrtn_f16_f32", + "__ocml_cvtrtn_f32_f64", + "__ocml_cvtrtn_f32_s32", + "__ocml_cvtrtn_f32_s64", + "__ocml_cvtrtn_f32_u32", + "__ocml_cvtrtn_f32_u64", + "__ocml_cvtrtn_f64_s64", + "__ocml_cvtrtn_f64_u64", + "__ocml_cvtrtp_f16_f32", + "__ocml_cvtrtp_f32_f64", + "__ocml_cvtrtp_f32_s32", + "__ocml_cvtrtp_f32_s64", + "__ocml_cvtrtp_f32_u32", + "__ocml_cvtrtp_f32_u64", + "__ocml_cvtrtp_f64_s64", + "__ocml_cvtrtp_f64_u64", + "__ocml_cvtrtz_f16_f32", + "__ocml_cvtrtz_f32_f64", + "__ocml_cvtrtz_f32_s32", + "__ocml_cvtrtz_f32_s64", + "__ocml_cvtrtz_f32_u32", + "__ocml_cvtrtz_f32_u64", + "__ocml_cvtrtz_f64_s64", + "__ocml_cvtrtz_f64_u64", +] + + +class Rounding: + def __init__(self, ptx, hip, opencl): + self.ptx = ptx + self.hip = hip + self.opencl = opencl + + +ROUNDING = [ + Rounding("rn", "rn", "rte"), + Rounding("rz", "rz", "rtz"), + Rounding("rm", "rd", "rtn"), + Rounding("rp", "ru", "rtp") +] + +class Type: + def __init__(self, ptx, hip, opencl = None): + self.ptx = ptx + self.hip = hip + if opencl is not None: + self.opencl = opencl + else: + self.opencl = hip + + +SIGNED_TYPES = [ + Type("s8", "char", "char"), + Type("s16", "short", "short"), + Type("s32", "int", "int"), + Type("s64", "ll", "long") +] + + +UNSIGNED_TYPES = [ + Type("u8", "uchar", "uchar"), + Type("u16", "ushort", "ushort"), + Type("u32", "uint", "uint"), + Type("u64", "ull", "ulong") +] + + +FLOAT_TYPES = [ + Type("f16", "half"), + Type("f32", "float"), + Type("f64", "double") +] + + +def hip_func(from_, to, rnd): + return f"__{from_.hip}2{to.hip}_{rnd.hip}" + + +def ocml_func(from_, to, rnd): + return f"__ocml_cvt{rnd.hip}_{to.ptx}_{from_.ptx}" + + +def convert_func(from_, to, rnd): + return f"convert_{to.opencl}_{rnd.opencl}" + + +def convert_func_decl(from_, to, rnd): + return f"{to.opencl} convert_{to.opencl}_{rnd.opencl}({from_.opencl}) __attribute__((overloadable)) __attribute__((device)) __attribute__((const));" + + +def identity_iterator(x, _): + return x + + +def emit_cvt(hip_convs, ocml_convs, from_types, to_types, iter_func): + for idx, from_ in enumerate(from_types): + for to in iter_func(to_types, idx): + for rnd in ROUNDING: + print(convert_func_decl(from_, to, rnd)) + hip = hip_func(from_, to, rnd) + if hip in hip_convs: + if from_.ptx == "f16": + print(f"__attribute__((always_inline)) {to.opencl} FUNC(cvt_{rnd.ptx}_{to.ptx}_{from_.ptx})({from_.opencl} x) {{ return {hip}(reinterpret_cast<{from_.opencl}&>(x)); }}") + elif to.ptx == "f16": + print(f"__attribute__((always_inline)) {to.opencl} FUNC(cvt_{rnd.ptx}_{to.ptx}_{from_.ptx})({from_.opencl} x) {{ auto temp = {hip}(x); return *reinterpret_cast<{to.opencl}*>(&temp); }}") + else: + print(f"__attribute__((always_inline)) {to.opencl} FUNC(cvt_{rnd.ptx}_{to.ptx}_{from_.ptx})({from_.opencl} x) {{ return {hip}(x); }}") + else: + ocml = ocml_func(from_, to, rnd) + if ocml in ocml_convs: + print(f"__attribute__((always_inline)) {to.opencl} FUNC(cvt_{rnd.ptx}_{to.ptx}_{from_.ptx})({from_.opencl} x) {{ return {ocml}(x); }}") + else: + print(f"__attribute__((always_inline)) {to.opencl} FUNC(cvt_{rnd.ptx}_{to.ptx}_{from_.ptx})({from_.opencl} x) {{ return {convert_func(from_, to, rnd)}(x); }}") + + +def main(): + hip_convs = set(HIP_CONV) + ocml_convs = set(OCML_CONV) + signed_types_ptx = ["s8", "s16", "s32", "s64"] + signed_types_opencl = ["char", "short", "int", "long"] + unsigned_types_ptx = ["u8", "u16", "u32", "u64"] + unsigned_types_opencl = ["uchar", "ushort", "uint", "ulong"] + float_types_ptx = ["f16", "f32", "f64"] + float_types_opencl = ["half", "float", "double"] + # somehow in LLVM `half` codegens to i16 and _Float codegens to half + float_types_hip = ["half", "float", "double"] + print(f"// GENERATED AUTOMATICALLY BY {os.path.basename(__file__)}, DON'T CHANGE MANUALLY") + print("extern \"C\"") + print("{") + print("typedef __fp16 half;") + # float from float truncation + emit_cvt(hip_convs, ocml_convs, FLOAT_TYPES, FLOAT_TYPES, islice) + # float from int, "Floating-point rounding is required for float-to-float conversions that result in loss of precision, and for integer-to-float conversions" + emit_cvt(hip_convs, ocml_convs, SIGNED_TYPES, FLOAT_TYPES, identity_iterator) + emit_cvt(hip_convs, ocml_convs, UNSIGNED_TYPES, FLOAT_TYPES, identity_iterator) + # int from float, "Integer rounding is required for float-to-integer conversions" + emit_cvt(hip_convs, ocml_convs, FLOAT_TYPES, SIGNED_TYPES, identity_iterator) + emit_cvt(hip_convs, ocml_convs, FLOAT_TYPES, UNSIGNED_TYPES, identity_iterator) + print("}") + +if __name__ == "__main__": + main() diff --git a/ptx/lib/raytracing.cpp b/ptx/lib/raytracing.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8a57624a9db985728be0817dd0cba6849075ee3 GIT binary patch literal 3263 zcmeHKZExa65bozl`43Z0O3l@EIC582v^j|jT#Akm1SG2ZWwqD~tT1b9y$1VU{`<}P zb?sAh>9Ib4iKWH}$+j9o8*N`4^ROIou2U@)VK9~n6^mw-=W;qIP|^Z3EwyAKsl7Bq$VV)8g#jZ4?u zSV|@o!AuzFjUP}2rA+Zd+ie|Viz%cjYI#qxcpT#wuE~^{X+^oFGIh}-$z6l$Bc2x} z8U6}HAP>}!3~`zE+v)wg;k1nHNF}FhpOLj6xcl$IsY0XcSUneyl_R1J`jYeK=i2>U z7tvE?Lr5NoR3uah;fK&CLNcB3OFfK=$z--trrhkKdVFD#Mj>tV@IP$5dg79e z0G7B62U8$g(dzNi^r1pFqAy3Z?l&48!0L2hko`a>dewW=(e0>(`qKs+`)_hU4XNfk z4h$UF30#BPNk+YimpF;R)dHpsU|P)pZMK4Hwrmn*WbiWoGU5j(fuFx;M_Z_rQ&Tx@ zC_iEQM2~DE103{N8rQIu+{+CYUTBvzQDs60Tj%BP>BDG97AtGH8s2>9I$UsN6*;mY ze@JaGt=Ls<8P{J~KjyIz5~ae;(;Qj#{M5O-yyP3O68P~Ndhq!(r26Tq->p5nywo_! zR4hfq03JYrcEYN|O!H zvoo^3mDrGW9giwnzR9~P${nk+1ajH?PW1r7$D- zVngdntQiYx^I&u)bQX&wyuF53z5Z*R!m1hdag>_vBx>~vXgxb+xwSG$|B|#-aTKdW z8FY0d?Yw=dE3|mTKlwYX*vU^GNUC;B!VVh~C~R=G({m8VfL^?)???EE^O*^TNaj@t z8*oLbn1*+w+xY`br;m4lHHn)m_4!8@0Wwr7;4#;yNP`9<2bRHs>6I=*4eT65rWIc# z7~QAX$Z2E)bG8oT7UnVt=@uOsmP=9uCyqAUAWTjFsqnxH1{I;M0+_MW`(NHhOg-|5 zuer}vYUQ`kBlTl87>wA4Vx!gKGM{;S8w^t}_H@gd>XRb!LRcyri+l6hsqV(It=k=5 zOnQT$UJmivs`Q7e)nfAQ0oQ4R=~+u2TF5Hmg~v8rFzl4<-wqn90BgeCqetgwrO?H5 MQ!EK3pxO^#0chFA$p8QV literal 0 HcmV?d00001 diff --git a/ptx/lib/raytracing.hpp b/ptx/lib/raytracing.hpp new file mode 100644 index 0000000..8573264 --- /dev/null +++ b/ptx/lib/raytracing.hpp @@ -0,0 +1,1007 @@ +#ifndef SKIP_RAYTRACING_GLOBALS + #include "raytracing_defines.hpp" + + #ifndef FUNCTION_NAME + #error FUNCTION_NAME required + #endif + #ifndef EXPORTED_FUNCTION + #error EXPORTED_FUNCTION required + #endif + #ifndef EXPORTED_ATTRIBUTE_FUNCTION + #error EXPORTED_ATTRIBUTE_FUNCTION required + #endif + #ifndef EXPORTED_KERNEL + #error EXPORTED_KERNEL required + #endif + + #define FUNC(NAME) __attribute__((device)) __zluda_rt_ptx_impl__##NAME + + #define GLOBAL_SPACE __attribute__((address_space(1))) + #define SHARED_SPACE __attribute__((address_space(3))) + #define CONSTANT_SPACE __attribute__((address_space(4))) + #define PRIVATE_SPACE __attribute__((address_space(5))) + + #define EXPORTED(X) X ## EXPORT_SUFFIX + + constexpr float INFINITY = __builtin_inff(); + + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; +#endif + +#define ZLUDA_RT(NAME) __zluda_rt_ptx_impl__##NAME +// This function is for argument passing for compatibility with LLVM +// We still use float3 in fields because sizeof(zluda_float3) == 16 +typedef float zluda_float3 __attribute__((ext_vector_type(3))); +#define ZLUDA_NAN __int_as_float(0x7fffffff) + +struct OptixBuffer { + uint8_t *ptr; + uint64_t x; + uint64_t y; +}; + +struct OptixTransform { + float transform_matrix[16]; + float inverse_transform_matrix[16]; +}; + +struct OptixRay { + // We don't use zluda_float3 below because sizeof(zluda_float3) == 16 + float3 origin; + float3 direction; + unsigned int ray_type; + float tmin; + float tmax; +}; +static_assert((sizeof(OptixRay) == 36), ""); + +typedef uint32_t (*raytracing_fn)( + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state, + uint32_t prim_idx, + uint2::Native_vec_ launch_idx, + uint2::Native_vec_ launch_dim, + OptixRay PRIVATE_SPACE* current_ray, + float current_time, + uint8_t PRIVATE_SPACE* payload, + float current_distance, + float2::Native_vec_ barycentric, // in case it is an attribute function + zluda_float3 normals, // in case it is an attribute function + uint8_t GLOBAL_SPACE* variable_block, + uint8_t GLOBAL_SPACE* attribute_block, + uint8_t GLOBAL_SPACE* transform_block +); + +typedef uint32_t (*attribute_fn)( + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state, + uint32_t prim_idx, + uint2::Native_vec_ launch_idx, + uint2::Native_vec_ launch_dim, + OptixRay PRIVATE_SPACE* current_ray, + float current_time, + uint8_t PRIVATE_SPACE* payload, + float current_distance, + float2::Native_vec_ barycentric, + zluda_float3 normals, + uint8_t GLOBAL_SPACE* variable_block, + uint8_t GLOBAL_SPACE* attribute_block, + uint8_t GLOBAL_SPACE* transform_block, + /* vvv EXTRA INJECTED vvv */ + uint64_t any_hit_fn +); + +typedef void(*bounding_box_fn)( + uint32_t prim_idx, + float GLOBAL_SPACE* result, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state, + uint8_t GLOBAL_SPACE* variable_block +); + +/* + uint32_t variable uint32_t uint32_t variable variable +┌┬─────────────────┬┬────────────────────┬┬──────────────────┬──────────────────┬─────┬┬──────────────────────┬──────────────────────┬─────┬┐ +││ materials_start ││var_block_intersect ││ offset_mat0_ray0 │ offset_mat0_ray1 │ ... ││ prog_block_mat0_ray0 │ prog_block_mat0_ray1 │ ... ││ +└┴────────┬────────┴┴────────────────────┘▲─────────┬────────┴────────┬─────────┴─────┘▲──────────────────────▲──────────────────────┴─────┴┘ + │ │ │ │ │ │ + └───────────────────────────────┘ │ └────────────────┼──────────────────────┘ + │ │ + └──────────────────────────────────┘ + */ +struct IntersectionInput { + uint8_t GLOBAL_SPACE* transform_block; + uint32_t materials_start; +}; + +struct IntersectionPayload { + uint32_t result; + uint32_t ray_type; + float tmin; + float tmax; + float time; + uint8_t SHARED_SPACE* global_state; + uint8_t PRIVATE_SPACE* payload; + float closest_distance; + uint32_t material; + uint8_t GLOBAL_SPACE* attribute_block; +}; + +template +__device__ static inline T get_program_block_inner( + void GLOBAL_SPACE *offset_block, + uint32_t prim_idx +) { + uint32_t byte_offset = reinterpret_cast(offset_block)[prim_idx]; + if (byte_offset == ~uint32_t(0)) + return nullptr; + uint8_t GLOBAL_SPACE *program_block = reinterpret_cast(offset_block) + byte_offset; + return (T)(program_block); +} + +template +__device__ static inline T get_program_block_outer( + void GLOBAL_SPACE *offset_block, + uint32_t id, + uint32_t subid +) { + uint32_t byte_offset = reinterpret_cast(offset_block)[id]; + if (byte_offset == ~uint32_t(0)) + return nullptr; + if (byte_offset & 1U) { // is bottom bit set? + byte_offset &= ~(1U); // clear bottom bit + uint8_t GLOBAL_SPACE* inner_chain = reinterpret_cast(offset_block) + byte_offset; + return get_program_block_inner( + inner_chain, + subid + ); + } else { + uint8_t GLOBAL_SPACE* program_block = reinterpret_cast(offset_block) + byte_offset; + return (T)(program_block); + } +} +__device__ static inline uint32_t call_raytracing_fn_inner( + uint8_t SHARED_SPACE* global_state, + void GLOBAL_SPACE* offset_block, + uint32_t prim_idx, + uint2::Native_vec_ launch_idx, + uint2::Native_vec_ launch_dim, + OptixRay PRIVATE_SPACE* current_ray, + float current_time, + uint8_t PRIVATE_SPACE* payload, + float current_distance, + float2::Native_vec_ barycentric, + zluda_float3 normals, + uint8_t GLOBAL_SPACE* attribute_block, + uint8_t GLOBAL_SPACE* transform_block +) { + uint32_t byte_offset = reinterpret_cast(offset_block)[prim_idx]; + if (byte_offset == ~uint32_t(0)) + return 0; + uint8_t GLOBAL_SPACE* program_block = reinterpret_cast(offset_block) + byte_offset; + raytracing_fn GLOBAL_SPACE* fn = reinterpret_cast(program_block); + return (*fn)( + global_state, + prim_idx, + launch_idx, + launch_dim, + current_ray, + current_time, + payload, + current_distance, + barycentric, + normals, + program_block, + attribute_block, + transform_block + ); +} + +template +__device__ void GLOBAL_SPACE* byte_offset(T GLOBAL_SPACE* ptr, uint32_t offset) { + uint8_t GLOBAL_SPACE* byte_ptr = reinterpret_cast(ptr); + return reinterpret_cast(byte_ptr + offset); +} + +// https://stackoverflow.com/a/9194117 +__device__ static inline int ZLUDA_RT(round_up)(int number, int multiple) +{ + return (number + multiple - 1) & -multiple; +} + +struct BvhDetails; + +struct GlobalState { + BvhDetails CONSTANT_SPACE* scenes; + void CONSTANT_SPACE* miss_programs; + OptixBuffer CONSTANT_SPACE* buffers; + uint32_t GLOBAL_SPACE* callable_programs; + hipTextureObject_t CONSTANT_SPACE* textures; + uint32_t ray_type_count; + uint32_t uv_attribute_offset; + uint32_t width; + uint32_t height; + uint16_t attribute_block_size; // in DWORDs + uint16_t attribute_block_align; // in DWORDs + uint16_t thread_global_stack_size; + uint16_t _padding; +}; +static_assert((sizeof(GlobalState) == 64), ""); + +// We are executing with 256 VGPRs/per wavefront (due to virtual calls), consequently +// * Dual CU has four SIMDs +// * One SIMD has 1024 VGPRs +// * At maximum 16 wavefronts / dual CU +// * Dual CU has 128kB LDS +// * At minimum 8kBs LDS per wavefront +// * At minimum 2048 dwords LDS per wavefront +// * At minimum 64 dwords per thread +// We might raise LDS/thread in the future +struct OptixStack { + constexpr static auto LOCAL_STACK_SIZE = 61; + constexpr static auto LOCAL_STACK_BITS = 6; + constexpr static auto LOCAL_STACK_MASK = 63; + + GlobalState globals; + // Bottom 6 bits are for LDS, stack, top 10 bits are for global stack + // Both are in dwords + uint32_t stack_pointers[32]; + uint32_t stacks[32 * LOCAL_STACK_SIZE]; + uint32_t GLOBAL_SPACE* global_stack; + + __device__ uint32_t& stack_pointer(void) { + return this->stack_pointers[__lane_id()]; + } + + // does not change the value of stack offset + __device__ uint32_t soft_push_attribute_block(uint8_t GLOBAL_SPACE** stack_pointer) { + uint32_t size = this->globals.attribute_block_size; + uint32_t align = this->globals.attribute_block_align; + uint32_t original_stack_pointer = this->stack_pointer(); + uint32_t global_stack_offset = original_stack_pointer >> LOCAL_STACK_BITS; + uint32_t aligned_start_in_dwords = uint32_t(ZLUDA_RT(round_up)(int32_t(global_stack_offset), int32_t(align))); + uint32_t aligned_start = this->globals.thread_global_stack_size * uint32_t(__lane_id()) + aligned_start_in_dwords; + *stack_pointer = (uint8_t GLOBAL_SPACE*)&this->global_stack[aligned_start]; + return (original_stack_pointer & LOCAL_STACK_MASK) | ((aligned_start_in_dwords + size) << LOCAL_STACK_BITS); + } + + __device__ void init( + uint32_t local_x, + uint32_t local_y, + uint32_t wavefront_id, + GlobalState globals_, + void GLOBAL_SPACE* global_stack_space + ) { + if (local_x == 0 && local_y == 0) { + this->globals = globals_; + } + if (__lane_id() == 0) + { + uint32_t wavefront_stack_offset = globals_.thread_global_stack_size * 32 * wavefront_id; + this->global_stack = &((uint32_t GLOBAL_SPACE*)global_stack_space)[wavefront_stack_offset]; + } + this->stack_pointers[__lane_id()] = 0; + } +}; +static_assert((sizeof(OptixStack) <= 8192), ""); + +static __shared__ OptixStack ZLUDA_RT(STACK); +static __shared__ GlobalState ZLUDA_RT(BB_GLOBALS); + +#ifndef SKIP_RAYTRACING_GLOBALS +/* + uint32_t uint32_t uint32_t uint32_t variable variable uint32_t variable +┌┬───────────────┬┬───────────────────┬┬─────────┬┬───────────┬───────────┬─────┬┬─────────────────┬─────────────────┬─────┬┬──────────────┬─────┬┬─────────────────┬─────┬┐ +││ any_hit_start ││ closest_hit_start ││ padding ││ any_hit_0 │ any_hit_1 │ ... ││ prog_block_ah_0 │ prog_block_ah_1 │ ... ││ closet_hit_0 │ ... ││ prog_block_ch_0 │ ... ││ +└┴────┬──────────┴┴────────┬──────────┴┴─────────┘▲────────┬──┴────────┬──┴─────┘▲─────────────────▲─────────────────┴─────┘►──────┬───────┴─────┘▲─────────────────┴─────┴┘ + │ │ │ │ │ │ │ │ │ │ + │ │ │ │ └─────────┼─────────────────┘ │ └──────────────┘ + │ │ │ │ │ │ + └────────────────────┼──────────────────────┘ └─────────────────────┘ │ + │ │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + */ +// Due to alignment there might be padding between those two variables and the chain proper +struct HitProgramChain { + uint32_t any_hit_start; + uint32_t closest_hit_start; +}; + +struct BvhDetails { + hiprtScene scene; + hiprtCustomFuncTable func_set; + void CONSTANT_SPACE* attribute_programs; + uint8_t GLOBAL_SPACE* GLOBAL_SPACE* transform_blocks; + HitProgramChain GLOBAL_SPACE* GLOBAL_SPACE* hit_chains; +}; + +template +__device__ T GLOBAL_SPACE* global_space_cast(T CONSTANT_SPACE* ptr) { + return (T GLOBAL_SPACE*)(ptr); +} + +extern "C" { + struct ZLUDA_RT(TraversalStack) { + __device__ int pop() { + OptixStack SHARED_SPACE* stack = (OptixStack SHARED_SPACE*)0; + if (global_offset > (bottom_pointer >> OptixStack::LOCAL_STACK_BITS)) { + return thread_global_stack[--global_offset]; + } else { + auto pos = (__lane_id() * OptixStack::LOCAL_STACK_SIZE) + --shared_offset; + return stack->stacks[pos]; + } + } + __device__ void push( int val ) { + OptixStack SHARED_SPACE* stack = (OptixStack SHARED_SPACE*)0; + if (shared_offset != OptixStack::LOCAL_STACK_SIZE) { + auto pos = (__lane_id() * OptixStack::LOCAL_STACK_SIZE) + shared_offset++; + stack->stacks[pos] = val; + } else { + thread_global_stack[global_offset++] = val; + } + } + __device__ bool empty() const { + return (global_offset == (bottom_pointer >> OptixStack::LOCAL_STACK_BITS)) + && (shared_offset == (bottom_pointer & OptixStack::LOCAL_STACK_MASK)); + } + __device__ int vacancy() const { + int32_t global_vacancy = int32_t(global_stack_size) - int32_t(global_offset); + int32_t local_vacancy = int32_t(OptixStack::LOCAL_STACK_SIZE) - int32_t(shared_offset); + int32_t vacancy = global_vacancy + local_vacancy; + return vacancy; + } + __device__ void reset() { + global_offset = (bottom_pointer >> OptixStack::LOCAL_STACK_BITS); + shared_offset = (bottom_pointer & OptixStack::LOCAL_STACK_MASK); + } + + __device__ ZLUDA_RT(TraversalStack)(uint32_t stack_pointer) : bottom_pointer(stack_pointer) { + OptixStack SHARED_SPACE* stack = (OptixStack SHARED_SPACE*)0; + global_stack_size = stack->globals.thread_global_stack_size; + thread_global_stack = &stack->global_stack[global_stack_size * __lane_id()]; + reset(); + } + + uint32_t GLOBAL_SPACE* thread_global_stack; + const uint32_t bottom_pointer; + uint32_t global_stack_size; + uint32_t global_offset; + uint16_t shared_offset; + }; + + /* + uint32_t uint32_t variable variable + ┌┬────────┬────────┬─────┬┬───────────────────┬───────────────────┬─────┬┐ + ││ miss_0 │ miss_1 │ ... ││ prog_block_miss_0 │ prog_block_miss_1 │ ... ││ + └┴───┬────┴───┬────┴─────┘▲───────────────────▲───────────────────┴─────┴┘ + │ │ │ │ + │ └───────────┼───────────────────┘ + │ │ + └────────────────────┘ + */ +// HACK START +} + +using BoxNode = hiprt::BoxNode; +using Ray = hiprt::Ray; +using InstanceNode = hiprt::InstanceNode; +using CustomNode = hiprt::CustomNode; +using TriangleNode = hiprt::TriangleNode; +using GeomHeader = hiprt::GeomHeader; +using Frame = hiprt::Frame; +using SceneHeader = hiprt::SceneHeader; +using Transform = hiprt::Transform; +template +using TraversalBase = hiprt::TraversalBase; +template +using PrivateStack = hiprt::PrivateStack; + +struct IntersectResult { + bool hit; + float t; + float2 uv; + float3 normal; +}; + +struct hiprtHit2 { + uint32_t instanceID; + uint32_t primID; + float2 uv; + float3 normal; + float t; + float3 origin; + float3 direction; + + HIPRT_DEVICE bool hasHit() const { return primID != hiprtInvalidValue; } +}; + +typedef IntersectResult ( *hiprtIntersectFunc2 )(hiprtRay ray, u32 primIdx, const void* data, void* payload ); + +template +class SceneTraversal2 : public TraversalBase +{ +public: + HIPRT_DEVICE SceneTraversal2( hiprtScene scene, const hiprtRay& ray, hiprtRayMask mask, Stack& stack ); + + HIPRT_DEVICE SceneTraversal2( + hiprtScene scene, const hiprtRay& ray, hiprtRayMask mask, hiprtCustomFuncTable funcTable, Stack& stack, void* payload = nullptr ); + + HIPRT_DEVICE void transformRay( Ray& ray, float3& invD, float3& oxInvD, const InstanceNode& node ) const; + + HIPRT_DEVICE void restoreRay( Ray& ray, float3& invD, float3& oxInvD ) const; + + HIPRT_DEVICE void set_ray_maxT(float x) + { + m_ray.maxT = x; + } + + HIPRT_DEVICE bool testLeafNode( + const Ray& ray, + const float3& invD, + int leafIndex, + int shapeId, + int& hitIndex, + float2& hitUv, + float3& hitNormal, + float& hitT ); + + HIPRT_DEVICE hiprtHit2 getNextHit2(); + HIPRT_DEVICE hiprtHit getNextHit() { + abort(); + return hiprtHit {}; + } + +protected: + using TraversalBase::m_ray; + using TraversalBase::m_state; + using TraversalBase::m_stack; + using TraversalBase::m_payload; +#if defined( __USE_HWI__ ) + using TraversalBase::m_descriptor; +#endif + + int m_nodeIndex; + int m_instanceIndex; + BoxNode* m_boxNodes; + InstanceNode* m_instanceNodes; + GeomHeader** m_geoms; + Frame* m_frames; + hiprtRayMask m_mask; + hiprtCustomFuncTable m_funcTable; +}; + +template +HIPRT_DEVICE SceneTraversal2::SceneTraversal2( hiprtScene scene, const hiprtRay& ray, hiprtRayMask mask, Stack& stack ) + : TraversalBase( ray, stack, nullptr ), m_funcTable( nullptr ), m_mask( mask ), m_instanceIndex( hiprtInvalidValue ), m_nodeIndex( hiprt::RootIndex ) +{ + SceneHeader* data = (SceneHeader*)scene; + m_boxNodes = data->m_boxNodes; + m_instanceNodes = data->m_primNodes; + m_geoms = data->m_geoms; + m_frames = data->m_frames; + m_stack.reset(); +} + +template +HIPRT_DEVICE SceneTraversal2::SceneTraversal2( + hiprtScene scene, const hiprtRay& ray, hiprtRayMask mask, hiprtCustomFuncTable funcTable, Stack& stack, void* payload ) + : TraversalBase( ray, stack, payload ), m_funcTable( funcTable ), m_mask( mask ), m_instanceIndex( hiprtInvalidValue ), + m_nodeIndex( hiprt::RootIndex ) +{ + SceneHeader* data = (SceneHeader*)scene; + m_boxNodes = data->m_boxNodes; + m_instanceNodes = data->m_primNodes; + m_geoms = data->m_geoms; + m_frames = data->m_frames; + m_stack.reset(); +} + +__device__ static inline float3 invTransform2(Frame& frame, const float3& p ) +{ + float3 result = p; + result = result - frame.m_translation; + result = hiprt::qtInvRotate( hiprt::qtFromAxisAngle( frame.m_rotation ), result ); + result = result / frame.m_scale; + return result; +} + +__device__ static inline Ray transformRay2(Transform& transform, Ray& ray) +{ + Frame frame = transform.interpolateFrames( ray.m_time ); + if ( frame.m_translation.x != 0.0f || frame.m_translation.y != 0.0f || frame.m_translation.z != 0.0f + || frame.m_rotation.w != 0.0f + || frame.m_scale.x != 1.0f || frame.m_scale.y != 1.0f || frame.m_scale.z != 1.0f ) + { + Ray outRay; + outRay.m_origin = invTransform2(frame, ray.m_origin ); + outRay.m_direction = invTransform2(frame, ray.m_origin + ray.m_direction ); + outRay.m_direction = outRay.m_direction - outRay.m_origin; + outRay.m_time = ray.m_time; + outRay.m_maxT = ray.m_maxT; + return outRay; + } + else + { + return ray; + } +} + +template +HIPRT_DEVICE void SceneTraversal2::transformRay( + Ray& ray, float3& invD, float3& oxInvD, const InstanceNode& node ) const +{ + Transform tr( m_frames + node.m_frameIndex, node.m_frameCount ); + ray = transformRay2( tr, ray ); + invD = hiprt::safeInv( ray.m_direction ); + oxInvD = -ray.m_origin * invD; +} + +template +HIPRT_DEVICE void +SceneTraversal2::restoreRay( Ray& ray, float3& invD, float3& oxInvD ) const +{ + ray.m_origin = m_ray.origin; + ray.m_direction = m_ray.direction; + invD = hiprt::safeInv( m_ray.direction ); + oxInvD = -m_ray.origin * invD; +} + +template +HIPRT_DEVICE bool SceneTraversal2::testLeafNode( + const Ray& ray, + const float3& invD, + int leafIndex, + int instanceId, + int& hitIndex, + float2& hitUv, + float3& hitNormal, + float& hitT ) +{ + bool hit = false; + const GeomHeader* geom = m_geoms[instanceId]; + int type = geom->m_customType; + if ( type == hiprtInvalidValue ) + { + TriangleNode node = ( (TriangleNode*)geom->m_primNodes )[hiprt::getNodeAddr( leafIndex )]; +#if !defined( __USE_HWI__ ) + hit = node.m_triangle.intersect( ray, hitUv, hitT ); + if ( hit ) + { + hitIndex = node.m_primIndex; + hitNormal = node.m_triangle.normal(); + } +#else + auto result = __builtin_amdgcn_image_bvh_intersect_ray_l( + hiprt::encodeBaseAddr( geom->m_primNodes, leafIndex ), + ray.m_maxT, + make_float4( ray.m_origin.x, ray.m_origin.y, ray.m_origin.z, ray.m_origin.z ).data, + make_float4( ray.m_direction.x, ray.m_direction.y, ray.m_direction.z, ray.m_direction.z ).data, + make_float4( invD.x, invD.y, invD.z, invD.z ).data, + m_descriptor.data ); + float invDenom = __ocml_native_recip_f32( __int_as_float( result[1] ) ); + float t = __int_as_float( result[0] ) * invDenom; + hit = t <= ray.m_maxT; + if ( hit ) + { + hitT = t; + hitUv.x = __int_as_float( result[2] ) * invDenom; + hitUv.y = __int_as_float( result[3] ) * invDenom; + hitIndex = node.m_primIndex; + hitNormal = node.m_triangle.normal(); + } +#endif + } + else + { + CustomNode node = ( (CustomNode*)geom->m_primNodes )[hiprt::getNodeAddr( leafIndex )]; + hiprtCustomFuncSet* funcTable = (hiprtCustomFuncSet*)m_funcTable; + IntersectResult result = ((hiprtIntersectFunc2)(funcTable[type].intersectFunc))( + reinterpret_cast(ray), + node.m_primIndex, + funcTable[type].intersectFuncData, + m_payload ); + if ( result.hit ) { + hitIndex = node.m_primIndex; + hit = true; + hitT = result.t; + hitUv = result.uv; + hitNormal = result.normal; + } + } + return hit; +} + + +template +HIPRT_DEVICE hiprtHit2 SceneTraversal2::getNextHit2() +{ + int instanceId = hiprtInvalidValue; + int nodeIndex = m_nodeIndex; + int instanceIndex = m_instanceIndex; + + Ray ray = *(Ray*)&m_ray; + float3 invD, oxInvD; + if ( instanceIndex == hiprtInvalidValue ) + { + restoreRay( ray, invD, oxInvD ); + } + else + { + InstanceNode node = m_instanceNodes[hiprt::getNodeAddr( instanceIndex )]; + instanceId = node.m_primIndex; + transformRay( ray, invD, oxInvD, node ); + } + + int hitInstanceId = hiprtInvalidValue; + int hitInstanceIndex = hiprtInvalidValue; + int hitPrimIndex = hiprtInvalidValue; + float hitT = 0.0f; + float2 hitUv = make_float2( 0.0f, 0.0f ); + float3 hitNormal; + + if ( m_stack.empty() ) m_stack.push( hiprtInvalidValue ); + + while ( nodeIndex != hiprtInvalidValue && m_state != hiprtTraversalStateStackOverflow ) + { + if ( hiprt::isInternalNode( nodeIndex ) ) + { + BoxNode* nodes = ( instanceId == hiprtInvalidValue ) ? m_boxNodes : m_geoms[instanceId]->m_boxNodes; + if ( this->testInternalNode( ray, invD, oxInvD, nodes, nodeIndex ) ) + continue; + } + else + { + if ( instanceId != hiprtInvalidValue ) + { + if ( testLeafNode( ray, invD, nodeIndex, instanceId, hitPrimIndex, hitUv, hitNormal, hitT ) ) + { + if constexpr ( TraversalType == hiprtTraversalTerminateAtAnyHit ) + { + m_nodeIndex = m_stack.pop(); + m_instanceIndex = instanceIndex; + m_state = hiprtTraversalStateHit; + if ( m_nodeIndex == hiprtInvalidValue && !m_stack.empty() ) + { + m_instanceIndex = hiprtInvalidValue; + m_nodeIndex = m_stack.pop(); + } + InstanceNode& node = m_instanceNodes[hiprt::getNodeAddr( instanceIndex )]; + Transform tr( m_frames + node.m_frameIndex, node.m_frameCount ); + hitNormal = tr.transformNormal( hitNormal, ray.m_time ); + return hiprtHit2 + { + (u32)instanceId, + (u32)hitPrimIndex, + hitUv, + hitNormal, + hitT, + ray.m_origin, + ray.m_direction + }; + } + else + { + hitInstanceId = instanceId; + hitInstanceIndex = instanceIndex; + ray.m_maxT = hitT; + } + } + } + else + { + InstanceNode node = m_instanceNodes[hiprt::getNodeAddr( nodeIndex )]; + if ( node.m_mask & m_mask ) + { + if ( instanceId != node.m_primIndex ) + { + if ( m_stack.vacancy() < 1 ) + { + m_state = hiprtTraversalStateStackOverflow; + continue; + } + m_stack.push( hiprtInvalidValue ); + } + instanceIndex = nodeIndex; + nodeIndex = hiprt::RootIndex; + instanceId = node.m_primIndex; + transformRay( ray, invD, oxInvD, node ); + continue; + } + } + } + nodeIndex = m_stack.pop(); + if ( nodeIndex == hiprtInvalidValue && !m_stack.empty() ) + { + instanceIndex = hiprtInvalidValue; + instanceId = hiprtInvalidValue; + nodeIndex = m_stack.pop(); + restoreRay( ray, invD, oxInvD ); + } + } + + hiprtHit2 result{ hiprtInvalidValue, hiprtInvalidValue, { 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, -1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }; + if ( hitInstanceId != hiprtInvalidValue ) + { + InstanceNode node = m_instanceNodes[hiprt::getNodeAddr( hitInstanceIndex )]; + Transform tr( m_frames + node.m_frameIndex, node.m_frameCount ); + result.t = hitT; + result.instanceID = hitInstanceId; + result.primID = hitPrimIndex; + result.uv = hitUv; + result.normal = tr.transformNormal( hitNormal, ray.m_time ); + result.origin = ray.m_origin; + result.direction = ray.m_direction; + } + if ( m_state != hiprtTraversalStateStackOverflow ) + m_state = hiprtTraversalStateFinished; + return result; +} + +__device__ static inline void ZLUDA_RT(set_attr_barycentrics)( + uint8_t GLOBAL_SPACE* attr_block, + float2 value +) { + OptixStack SHARED_SPACE* stack = (OptixStack SHARED_SPACE*)0; + if (stack->globals.uv_attribute_offset != ~uint32_t(0)) { + *(float2*)(attr_block + stack->globals.uv_attribute_offset) = value; + } +} + +extern "C" { +// HACK END + __device__ uint32_t FUNC(_rt_trace_time_mask_flags_64) ( + uint32_t bvh_index, + float ray_origin_x, + float ray_origin_y, + float ray_origin_z, + float ray_direction_x, + float ray_direction_y, + float ray_direction_z, + uint32_t ray_type, + float tmin, + float tmax, + float time, + uint32_t mask, + uint32_t flags, + uint64_t payload_ptr, + uint32_t payload_size, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + OptixStack SHARED_SPACE* stack = (OptixStack SHARED_SPACE*)global_state; + uint32_t launch_x = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t launch_y = blockIdx.y * blockDim.y + threadIdx.y; + uint2::Native_vec_ launch_idx = uint2(launch_x, launch_y).data; + uint32_t size_x = stack->globals.width; + uint32_t size_y = stack->globals.height; + uint2::Native_vec_ launch_dim = uint2(size_x, size_y).data; + hiprtRay ray { + make_float3(ray_origin_x, ray_origin_y, ray_origin_z), + time, + make_float3(ray_direction_x, ray_direction_y, ray_direction_z), + tmax + }; + OptixRay optix_ray { + make_float3(ray_origin_x, ray_origin_y, ray_origin_z), + make_float3(ray_direction_x, ray_direction_y, ray_direction_z), + ray_type, + tmin, + tmax + }; + PRIVATE_SPACE uint8_t* payload = reinterpret_cast(payload_ptr); + uint32_t ray_type_count = stack->globals.ray_type_count; + BvhDetails CONSTANT_SPACE* bvh = &stack->globals.scenes[bvh_index]; + HitProgramChain GLOBAL_SPACE* programs_chain = bvh->hit_chains[ray_type]; + IntersectionPayload intersection_payload { + 0, + ray_type, + tmin, + tmax, + time, + global_state, + payload, + tmax, + ~uint32_t(0) + }; + uint32_t old_stack_bottom = ((OptixStack*)stack)->stack_pointer(); + uint32_t new_stack_bottom = ((OptixStack*)stack)->soft_push_attribute_block(&intersection_payload.attribute_block); + ZLUDA_RT(TraversalStack) rt_stack(new_stack_bottom); + if (rt_stack.vacancy() < 1) { + abort(); + } + SceneTraversal2 tr { bvh->scene, ray, mask, bvh->func_set, rt_stack, &intersection_payload }; + unsigned int closest_instance_id = hiprtInvalidValue; + unsigned int closest_subinstance_id = 0; + attribute_fn* closest_attr_fn = nullptr; + float2 closest_uv {}; + float3 closest_normals(ZLUDA_NAN, ZLUDA_NAN, ZLUDA_NAN); + while (true) { + intersection_payload.result = 0; + intersection_payload.material = ~uint32_t(0); + hiprtHit2 hit = tr.getNextHit2(); + if (tr.getCurrentState() == hiprtTraversalStateStackOverflow) { + abort(); + } + if (!hit.hasHit()) + break; + if (hit.t < tmin) + continue; + tr.set_ray_maxT(hit.t); + // Successful custom intersection hit + if (intersection_payload.material != ~uint32_t(0)) { + if (intersection_payload.result != 1) { + closest_attr_fn = nullptr; + closest_normals = {ZLUDA_NAN, ZLUDA_NAN, ZLUDA_NAN}; + closest_instance_id = hit.instanceID; + closest_subinstance_id = intersection_payload.material; + intersection_payload.closest_distance = hit.t; + } + if (intersection_payload.result == 2) + break; + continue; + } + attribute_fn* attr_fn = get_program_block_inner( + global_space_cast(bvh->attribute_programs), + hit.instanceID + ); + raytracing_fn* anyhit_fn = get_program_block_outer( + byte_offset(programs_chain, programs_chain->any_hit_start), + hit.instanceID, + hit.primID + ); + uint32_t intersection_result = 0; + if (attr_fn != nullptr) { + OptixRay transformed_ray { + { hit.origin.x, hit.origin.y, hit.origin.z }, + { hit.direction.x, hit.direction.y, hit.direction.z }, + ray_type, + tmin, + tmax + }; + intersection_result = (*attr_fn)( + global_state, + hit.primID, + launch_idx, + launch_dim, + (OptixRay PRIVATE_SPACE*)(&transformed_ray), + time, + payload, + hit.t, + hit.uv.data, + zluda_float3{hit.normal.x, hit.normal.y, hit.normal.z}, + (uint8_t GLOBAL_SPACE *)(attr_fn), + intersection_payload.attribute_block, + bvh->transform_blocks[hit.instanceID], + reinterpret_cast(anyhit_fn) + ); + } else { + ZLUDA_RT(set_attr_barycentrics)(intersection_payload.attribute_block, hit.uv); + if (anyhit_fn != nullptr) { + OptixRay transformed_ray { + { hit.origin.x, hit.origin.y, hit.origin.z }, + { hit.direction.x, hit.direction.y, hit.direction.z }, + ray_type, + tmin, + tmax + }; + intersection_result = (*anyhit_fn)( + global_state, + hit.primID, + launch_idx, + launch_dim, + (OptixRay PRIVATE_SPACE*)(&transformed_ray), + time, + payload, + hit.t, + hit.uv.data, + zluda_float3{hit.normal.x, hit.normal.y, hit.normal.z}, + (uint8_t GLOBAL_SPACE *)(anyhit_fn), + intersection_payload.attribute_block, + bvh->transform_blocks[hit.instanceID] + ); + } + } + if (intersection_result >= 1024) { + return intersection_result; + } + if (intersection_result != 1) { + closest_attr_fn = attr_fn; + closest_uv = hit.uv; + closest_normals = hit.normal; + closest_instance_id = hit.instanceID; + closest_subinstance_id = hit.primID; + intersection_payload.closest_distance = hit.t; + } + if (intersection_result == 2) + break; + } + if (closest_instance_id != hiprtInvalidValue) { + raytracing_fn* closest_hit_fn = get_program_block_outer( + byte_offset(programs_chain, programs_chain->closest_hit_start), + closest_instance_id, + closest_subinstance_id + ); + if (closest_hit_fn != nullptr) { + ((OptixStack*)stack)->stack_pointer() = new_stack_bottom; + uint32_t result = 0; + if (closest_attr_fn != nullptr) { + result = (*closest_attr_fn)( + global_state, + closest_subinstance_id, + launch_idx, + launch_dim, + (OptixRay PRIVATE_SPACE*)(&optix_ray), + time, + payload, + intersection_payload.closest_distance, + closest_uv.data, + zluda_float3{closest_normals.x, closest_normals.y, closest_normals.z}, + (uint8_t GLOBAL_SPACE *)(closest_attr_fn), + intersection_payload.attribute_block, + bvh->transform_blocks[closest_instance_id], + reinterpret_cast(closest_hit_fn) + ); + } else { + result = (*closest_hit_fn)( + global_state, + closest_subinstance_id, + launch_idx, + launch_dim, + (OptixRay PRIVATE_SPACE*)(&optix_ray), + time, + payload, + intersection_payload.closest_distance, + float2(0.0, 0.0).data, + zluda_float3{closest_normals.x, closest_normals.y, closest_normals.z}, + (uint8_t GLOBAL_SPACE *)(closest_hit_fn), + intersection_payload.attribute_block, + bvh->transform_blocks[closest_instance_id] + ); + } + if (result >= 1024) { + return result; + } + ((OptixStack*)stack)->stack_pointer() = old_stack_bottom; + } + return 0; + } else { + return call_raytracing_fn_inner( + global_state, + global_space_cast(stack->globals.miss_programs), + ray_type, + launch_idx, + launch_dim, + (OptixRay PRIVATE_SPACE*)(&optix_ray), + 0.0, + payload, + 0.0, + float2(0.0, 0.0).data, + zluda_float3{0.0, 0.0, 0.0}, + nullptr, + nullptr + ); + } + } + + __global__ void ZLUDA_RT(generate_bounding_box)( + GlobalState globals, + bounding_box_fn bb_func, + uint32_t primitive_count, + float GLOBAL_SPACE* output, + uint8_t GLOBAL_SPACE* variable_block + ) { + asm ("" : : : "s105"); + asm ("" : : : "v255"); + if (threadIdx.x == 0) + ZLUDA_RT(BB_GLOBALS) = globals; + __syncthreads(); + + uint32_t x = blockIdx.x * blockDim.x + threadIdx.x; + if (x >= primitive_count) + return; + bb_func(x, &output[x*8], (uint8_t SHARED_SPACE*)&ZLUDA_RT(BB_GLOBALS), variable_block); + } +} +#endif + \ No newline at end of file diff --git a/ptx/lib/raytracing_bounding_box.cpp b/ptx/lib/raytracing_bounding_box.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f101c3df257eb02395e50be34ccaba319705e223 GIT binary patch literal 938 zcma)*T}#6-6o$PX>_3FCHY^QuP*Q=$lw|tKmTS{)JXcW#z)ILv@11Lu^|aHJI(5{js|0Gbz8qDvxdX;! zzsfm@-bTam)O7PX8V{m=6Xj+;HZU5#eklH%&^}vEf7jS?@Qa%r3)?A(Ma~oRZg4CL vJmYBVrn<}EFNef1*(h`qn3;Ej$`?j*Ezp9{rO9l!svs3S(@;o-%x?$Z@f04j literal 0 HcmV?d00001 diff --git a/ptx/lib/raytracing_callable.cpp b/ptx/lib/raytracing_callable.cpp new file mode 100644 index 0000000..4a127df --- /dev/null +++ b/ptx/lib/raytracing_callable.cpp @@ -0,0 +1,10 @@ +#include "raytracing.hpp" + +extern "C" { + __device__ void FUNCTION_NAME(); + __device__ void* EXPORTED_FUNCTION = (void*)FUNCTION_NAME; + static __global__ void EXPORTED_KERNEL() { } +} + +#define extern auto hack = +#define constexpr ; diff --git a/ptx/lib/raytracing_intersect.cpp b/ptx/lib/raytracing_intersect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6036b5ddf05a37e5292b8e3b1ee905b58d4aeb9e GIT binary patch literal 4526 zcmcgwTW{Mo6y9qB$-26(aD9K_0r-tvG;gM8}@iI+MPmWKH#nuU<;PmDczMLEbK8(d; zEhE7gthJ2c-Jkb2&(nu{c7OfHq?gkWT_%ja)GqZ->>{`2g1IHB9e+o7_B4 zZvD&PygDb|pOE$AhwG=wE&KR*eKQ%rBGEIRFzdJzHDN@2ad~;qom>mH77>GlXDV8@ zly=a?dzJ;wk5AK2*UyunI?9X@$}x;kP4hg_+(9^Va@97Ad}v8Z`3||_gHmFN{;8-- z()+uIU$5_iNo#H-pCy9L5*>Z6$qOzt$+>ez&NBCJ=@AIZ&b3+X$XCX5x4lUgw&Y?io|2VGn%ym)jvDL8Vx^nWIt65b#-XKb}71nw35PIn0m4R`O+96yqRMT3Z_eCL` zncJlT$OI!Ijb4~6a`2EkxqafheHOQp>OYW|u*<{fIfJiKDPdrasY)LsY-EzaOrS$nIJ#z3B@I?atfV@#h_xg`C1f=j z5q{qj=te$qki0I^pz+e80+i?L@pin$Z1LH9D_8jP0|wU!9{VG#8pI!-wwzsE&aN(J*O0R-t51-G zWo5eJ3ye3alNK}Cic8S=x)2%`MrY{|+y=kmD`L`DdpiWdqhv=)iiq)dRt3W(^*p^FtoE|iFefMp+r#d1DJY09-q+qfAC6#tCY;r&`Phm62^ zAQ7-ZC3B;Z9ZfcFObR^=&`=|Yw6uUnkw}n?N=b%ii0eHaO`B00P$3$_GfDOSQ6B5e z6hW|K_%MBhr)Mykvi@MMAVp|nPrz(&%RLp9!`v*g6?%?Bo|l+!9L>cBH>!M!adt2Z zfsGgR{N(_ZiGoFIsxZN!*=fB+)Z3W!r*EP64VHedmJQU;0+#5r&ij}T5AB&Ev%)ZH zNG(;}1*2@uiS6iWBV)IG zk(`pUB*zN6Sh^N{=v$#l(!ka(85C6fd901ZENvB^a2QK$ht!rj&MQYzjPIW>5>dze z1_9qT@BC}aEzHSJMT;<^*1X7CJbQf!%;0b;QjH%a{?K~NS_?|&^Mu&XLZ#IRxqbgB z+AX%L*^W9J<=+qRrfFGue|0UzJchUPx@CAiD?0en_UO>oKpxR^poP#;75+NTx+07= zUi6AxU^@&gV%HycbR93*Gvvq|V%a7Nh_WBXjw#1>o2RDkq z((76+`e*gkpd>AU*xW4oXQf_*|Nd$b_|K{^hpnOs^mcKSbEqOziH7eH^m|hYX{i+C z`weDChiNc^H?5rc+B9UQbpp~dO2=*yWCEO>b&AKciGm6=17f^;KlsdrcD^%l+crmYHF{eSX_?LxexEd^R>qE+u<8bK5 MX0c5TAlrBU097>xIsgCw literal 0 HcmV?d00001 diff --git a/ptx/lib/zluda_ptx_impl.bc b/ptx/lib/zluda_ptx_impl.bc new file mode 100644 index 0000000000000000000000000000000000000000..48ea22b8902095dd36ce79adfedb42c3358515e1 GIT binary patch literal 144764 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 literal 0 HcmV?d00001 diff --git a/ptx/lib/zluda_ptx_impl.cl b/ptx/lib/zluda_ptx_impl.cl deleted file mode 100644 index 94d02ec..0000000 --- a/ptx/lib/zluda_ptx_impl.cl +++ /dev/null @@ -1,146 +0,0 @@ -// 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.cpp b/ptx/lib/zluda_ptx_impl.cpp new file mode 100644 index 0000000..420ce65 --- /dev/null +++ b/ptx/lib/zluda_ptx_impl.cpp @@ -0,0 +1,1490 @@ +// Compile and disassemble: +// python3 ./cvt.py > cvt.h && /opt/rocm/llvm/bin/clang -std=c++17 -Xclang -no-opaque-pointers -Wall -Wextra -Wsign-compare -Wconversion -x hip zluda_ptx_impl.cpp -S -emit-llvm --cuda-device-only -nogpulib -O3 -Xclang -fallow-half-arguments-and-returns -o - | sed -e 's/define/define linkonce_odr/g' | sed -e '/@llvm.used/d' | sed -e 's/\"target-cpu\"=\"[^\"]*\"//g' | sed -e 's/\"target-features\"=\"[^\"]*\"//g' | sed -e 's/\"denormal-fp-math-f32\"=\"[^\"]*\"//g' | sed -e 's/!llvm.module.flags = !{!0, !1, !2, !3, !4}/!llvm.module.flags = !{ }/g' | sed -e 's/memory(none)/readnone/g' | sed -e 's/memory(argmem: readwrite, inaccessiblemem: readwrite)/inaccessiblemem_or_argmemonly/g' | sed -e 's/memory(read)/readonly/g' | sed -e 's/memory(argmem: readwrite)/argmemonly/g' | llvm-as-13 -o zluda_ptx_impl.bc && /opt/rocm/llvm/bin/llvm-dis zluda_ptx_impl.bc +// Compile to binary: +// /opt/rocm/llvm/bin/clang -x ir -target amdgcn-amd-amdhsa -Xlinker --no-undefined zluda_ptx_impl.bc -mno-wavefrontsize64 -mcpu=gfx1030 +// Decompile: +// /opt/rocm/llvm/bin/llvm-objdump -d a.out --triple amdgcn-amd-amdhsa +// List of builtins: +// https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/BuiltinsAMDGPU.def +// https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAMDGPU.td +// Extra information: +// https://llvm.org/docs/AMDGPUUsage.html + +#include +#include +#define HIP_NO_HALF +#include +#undef HIP_NO_HALF +#include +#include + +enum class CompilationMode : uint8_t +{ + /* + warp[0] warp[1] + ┌─┬─────┬──┬┬──┬─────┬──┐ + CUDA │0│ ... │31││32│ ... │63│ + └─┴──┬──┴──┴┴──┴──┬──┴──┘ + │ │ + │ │ + ┌─┬──▼──┬──┬┬──┬──▼──┬──┐ + AMDGPU │0│ ... │31││32│ ... │63│ + └─┴─────┴──┴┴──┴─────┴──┘ + wfront[0] wfront[1] + */ + Wave32 = 1, + /* + warp[0] warp[1] + ┌─┬─────┬──┬┬──┬─────┬──┐ + CUDA │0│ ... │31││32│ ... │63│ + └─┴──┬──┴──┴┴──┴──┬──┴──┘ + │ │ + │ └─────┐ + │ │ + ┌─┬──▼────────┬──┬┬──┬──▼────────┬───┐ + AMDGPU │0│ ... ¦ │63││64│ ... ¦ │127│ + └─┴───────────┴──┴┴──┴───────────┴───┘ + wfront[0] wfront[1] + */ + Wave32OnWave64 = 2, + /* + warp[0] warp[1] + ┌─┬─────┬──┬┬──┬─────┬──┐ + CUDA │0│ ... │31││32│ ... │63│ + └─┴──┬──┴──┴┴──┴──┬──┴──┘ + │ │ + │ ┌──────┘ + │ │ + ┌─┬──▼─────▼──┬──┐ + AMDGPU │0│ ... ¦ ... │63│ + └─┴───────────┴──┘ + wfront[0] + */ + DoubleWave32OnWave64 = 3 +}; + +#define FUNC(NAME) __attribute__((device)) __attribute__((retain)) __zluda_ptx_impl__##NAME +#define STRUCT(NAME) struct __zluda_ptx_impl__##NAME +#define FUNC_CALL(NAME) __zluda_ptx_impl__##NAME + +// The depths of madness of conversions with rounding modes: +// * AMD GPUs do not have HW support for conversions with rounding modes +// * Not a problem, LLVM supports it. Haha, no: +// * `llvm.experimental.constrained.fptrunc` is exactly the same as `fptrunc`on AMDGPU +// * `llvm.fptrunc.round` looks fine, but it's LLVM 14+ so avoiding it for now +// * Nothing for float->int and int->flot +// * Not a problem, HIP supports it. Haha, no. This is HIP implementation right now: +// __device__ static inline float __double2float_rz(double x) { return (double)x; } +// * Not a problem, ROCm-Device-Libs supports it. Haha, Somewhat: +// * Only when building for OpenCL (that's why we pass opencl.bc and related explictly). There's no non-deprecated way to convince comgr to link it +// * To top it all, by default, OpenCL `half` type gets mangled differently than HIP `half` or Clang `_Float16` +// * There's __fp16, but by default it can't be passed as an argument. Thankfully there's a hidden flag to fix this +#include "cvt.h" + +#define GENERIC_SPACE __attribute__((address_space(0))) +#define GLOBAL_SPACE __attribute__((address_space(1))) +#define SHARED_SPACE __attribute__((address_space(3))) +#define CONSTANT_SPACE __attribute__((address_space(4))) +#define PRIVATE_SPACE __attribute__((address_space(5))) + +typedef half half4 __attribute__((ext_vector_type(4))); + +extern "C" __device__ const CONSTANT_SPACE CompilationMode FUNC_CALL(COMPILATION_MODE); +extern "C" __device__ const CONSTANT_SPACE bool FUNC_CALL(IS_WINDOWS); + +template < + typename T, + typename std::enable_if::value && sizeof(T) / sizeof(typename T::value_type) == 1 && sizeof(typename T::value_type) <= sizeof(float)>::type * = nullptr> +static __device__ float4::Native_vec_ __pack_to_float4(const T &t) +{ + union result_element + { + float float_; + typename T::value_type value; + }; + float4::Native_vec_ result; + result_element x = {0}; + x.value = t.x; + result.x = x.float_; + return result; +} + +template < + typename T, + typename std::enable_if::value && sizeof(T) / sizeof(typename T::value_type) == 2 && sizeof(typename T::value_type) <= sizeof(float)>::type * = nullptr> +static __device__ float4::Native_vec_ __pack_to_float4(const T &t) +{ + union result_element + { + float float_; + typename T::value_type value; + }; + float4::Native_vec_ result; + result_element x = {0}; + x.value = t.x; + result.x = x.float_; + result_element y = {0}; + y.value = t.y; + result.y = y.float_; + return result; +} + +template < + typename T, + typename std::enable_if::value && sizeof(T) / sizeof(typename T::value_type) == 4 && sizeof(typename T::value_type) <= sizeof(float)>::type * = nullptr> +static __device__ float4::Native_vec_ __pack_to_float4(const T &t) +{ + union result_element + { + float float_; + typename T::value_type value; + }; + float4::Native_vec_ result; + result_element x = {0}; + x.value = t.x; + result.x = x.float_; + result_element y = {0}; + y.value = t.y; + result.y = y.float_; + result_element z = {0}; + z.value = t.z; + result.z = z.float_; + result_element w = {0}; + w.value = t.w; + result.w = w.float_; + return result; +} + +extern "C" +{ +#define atomic_inc(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \ + uint32_t FUNC(NAME)(SPACE uint32_t * ptr, uint32_t threshold) \ + { \ + uint32_t expected = *ptr; \ + uint32_t desired; \ + do \ + { \ + desired = (expected >= threshold) ? 0 : expected + 1; \ + } while (!__hip_atomic_compare_exchange_strong((volatile SPACE uint32_t *)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \ + return expected; \ + } + +#define atomic_dec(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \ + uint32_t FUNC(NAME)(SPACE uint32_t * ptr, uint32_t threshold) \ + { \ + uint32_t expected = *ptr; \ + uint32_t desired; \ + do \ + { \ + desired = (expected == 0 || expected > threshold) ? threshold : expected - 1; \ + } while (!__hip_atomic_compare_exchange_strong((volatile SPACE uint32_t *)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \ + return expected; \ + } + + // atom.inc + atomic_inc(atom_relaxed_cta_generic_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_inc(atom_acquire_cta_generic_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_inc(atom_release_cta_generic_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_inc(atom_acq_rel_cta_generic_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + + atomic_inc(atom_relaxed_gpu_generic_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_inc(atom_acquire_gpu_generic_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_inc(atom_release_gpu_generic_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_inc(atom_acq_rel_gpu_generic_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + + atomic_inc(atom_relaxed_sys_generic_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_inc(atom_acquire_sys_generic_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_inc(atom_release_sys_generic_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_inc(atom_acq_rel_sys_generic_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + + atomic_inc(atom_relaxed_cta_global_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_inc(atom_acquire_cta_global_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_inc(atom_release_cta_global_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_inc(atom_acq_rel_cta_global_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + + atomic_inc(atom_relaxed_gpu_global_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_inc(atom_acquire_gpu_global_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_inc(atom_release_gpu_global_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_inc(atom_acq_rel_gpu_global_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + + atomic_inc(atom_relaxed_sys_global_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_inc(atom_acquire_sys_global_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_inc(atom_release_sys_global_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_inc(atom_acq_rel_sys_global_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + + atomic_inc(atom_relaxed_cta_shared_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_inc(atom_acquire_cta_shared_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_inc(atom_release_cta_shared_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_inc(atom_acq_rel_cta_shared_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + + atomic_inc(atom_relaxed_gpu_shared_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_inc(atom_acquire_gpu_shared_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_inc(atom_release_gpu_shared_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_inc(atom_acq_rel_gpu_shared_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + + atomic_inc(atom_relaxed_sys_shared_inc, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_inc(atom_acquire_sys_shared_inc, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_inc(atom_release_sys_shared_inc, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_inc(atom_acq_rel_sys_shared_inc, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + + // atom.dec + atomic_dec(atom_relaxed_cta_generic_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_dec(atom_acquire_cta_generic_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_dec(atom_release_cta_generic_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + atomic_dec(atom_acq_rel_cta_generic_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GENERIC_SPACE); + + atomic_dec(atom_relaxed_gpu_generic_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_dec(atom_acquire_gpu_generic_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_dec(atom_release_gpu_generic_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + atomic_dec(atom_acq_rel_gpu_generic_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GENERIC_SPACE); + + atomic_dec(atom_relaxed_sys_generic_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_dec(atom_acquire_sys_generic_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_dec(atom_release_sys_generic_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + atomic_dec(atom_acq_rel_sys_generic_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GENERIC_SPACE); + + atomic_dec(atom_relaxed_cta_global_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_dec(atom_acquire_cta_global_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_dec(atom_release_cta_global_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + atomic_dec(atom_acq_rel_cta_global_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, GLOBAL_SPACE); + + atomic_dec(atom_relaxed_gpu_global_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_dec(atom_acquire_gpu_global_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_dec(atom_release_gpu_global_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + atomic_dec(atom_acq_rel_gpu_global_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, GLOBAL_SPACE); + + atomic_dec(atom_relaxed_sys_global_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_dec(atom_acquire_sys_global_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_dec(atom_release_sys_global_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + atomic_dec(atom_acq_rel_sys_global_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, GLOBAL_SPACE); + + atomic_dec(atom_relaxed_cta_shared_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_dec(atom_acquire_cta_shared_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_dec(atom_release_cta_shared_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + atomic_dec(atom_acq_rel_cta_shared_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_WORKGROUP, SHARED_SPACE); + + atomic_dec(atom_relaxed_gpu_shared_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_dec(atom_acquire_gpu_shared_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_dec(atom_release_gpu_shared_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + atomic_dec(atom_acq_rel_gpu_shared_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_AGENT, SHARED_SPACE); + + atomic_dec(atom_relaxed_sys_shared_dec, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_dec(atom_acquire_sys_shared_dec, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_dec(atom_release_sys_shared_dec, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + atomic_dec(atom_acq_rel_sys_shared_dec, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SYSTEM, SHARED_SPACE); + +#define tex_1d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE, TEX_FN) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return TEX_FN(textureObject, x.x).data; \ + } \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_indirect_1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return TEX_FN(textureObject, x.x).data; \ + } + + __device__ half4 __ockl_image_sampleh_1D(unsigned int CONSTANT_SPACE *i, unsigned int CONSTANT_SPACE *s, float c); + __device__ half4 static inline FUNC_CALL(tex1D_f16)(hipTextureObject_t textureObject, float x) + { + TEXTURE_OBJECT_PARAMETERS_INIT; + return __ockl_image_sampleh_1D(i, s, x); + } + + __device__ half4 __ockl_image_loadh_1Db(unsigned int CONSTANT_SPACE *i, int c); + __device__ half4 static inline FUNC_CALL(tex1Dfetch_f16)(hipTextureObject_t textureObject, int x) + { + TEXTURE_OBJECT_PARAMETERS_INIT; + (void)s; + return __ockl_image_loadh_1Db(i, x); + } + +#define tex_1d_f16(COORD_TYPE, HIP_COORD_TYPE, TEX_FN) \ + half4 FUNC(tex_1d_v4_f16_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return FUNC_CALL(TEX_FN)(textureObject, x.x); \ + } \ + half4 FUNC(tex_indirect_1d_v4_f16_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return FUNC_CALL(TEX_FN)(textureObject, x.x); \ + } + + tex_1d(u32, uint, s32, int, tex1Dfetch); + tex_1d(u32, uint, f32, float, tex1D); + tex_1d(s32, int, s32, int, tex1Dfetch); + tex_1d(s32, int, f32, float, tex1D); + tex_1d(f32, float, s32, int, tex1Dfetch); + tex_1d(f32, float, f32, float, tex1D); + tex_1d_f16(s32, int, tex1Dfetch_f16); + tex_1d_f16(f32, float, tex1D_f16); + +#define tex_2d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return tex2D(textureObject, float(coord.x), float(coord.y)).data; \ + } \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_indirect_2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return tex2D(textureObject, float(coord.x), float(coord.y)).data; \ + } + + __device__ half4 __ockl_image_sampleh_2D(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float2::Native_vec_ c); +#define tex_2d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_2d_v4_f16_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2D(i, s, (float2){float(coord.x), float(coord.y)}.data); \ + } \ + half4 FUNC(tex_indirect_2d_v4_f16_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2D(i, s, (float2){float(coord.x), float(coord.y)}.data); \ + } + + tex_2d(u32, uint, s32, int); + tex_2d(u32, uint, f32, float); + tex_2d(s32, int, s32, int); + tex_2d(s32, int, f32, float); + tex_2d(f32, float, s32, int); + tex_2d(f32, float, f32, float); + tex_2d_f16(s32, int); + tex_2d_f16(f32, float); + +#define tex_3d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_3d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return tex3D(textureObject, float(coord.x), float(coord.y), float(coord.z)).data; \ + } \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_indirect_3d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return tex3D(textureObject, float(coord.x), float(coord.y), float(coord.z)).data; \ + } + + __device__ half4 __ockl_image_sampleh_3D(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float4::Native_vec_ c); +#define tex_3d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_3d_v4_f16_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_3D(i, s, (float4){float(coord.x), float(coord.y), float(coord.z), float(coord.w)}.data); \ + } \ + half4 FUNC(tex_indirect_3d_v4_f16_##COORD_TYPE)(uint64_t texobj, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_3D(i, s, (float4){float(coord.x), float(coord.y), float(coord.z), float(coord.w)}.data); \ + } + + tex_3d(u32, uint, s32, int); + tex_3d(u32, uint, f32, float); + tex_3d(s32, int, s32, int); + tex_3d(s32, int, f32, float); + tex_3d(f32, float, s32, int); + tex_3d(f32, float, f32, float); + tex_3d_f16(s32, int); + tex_3d_f16(f32, float); + +#define tex_a1d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_a1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return tex1DLayered(textureObject, float(x), int(layer)).data; \ + } \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_indirect_a1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(uint64_t texobj, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return tex1DLayered(textureObject, float(x), int(layer)).data; \ + } + + __device__ half4 __ockl_image_sampleh_1Da(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float2::Native_vec_ c); +#define tex_a1d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_a1d_v4_f16_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_1Da(i, s, (float2){float(x), float(layer)}.data); \ + } \ + half4 FUNC(tex_indirect_a1d_v4_f16_##COORD_TYPE)(uint64_t texobj, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_1Da(i, s, (float2){float(x), float(layer)}.data); \ + } + + tex_a1d(u32, uint, s32, int); + tex_a1d(u32, uint, f32, float); + tex_a1d(s32, int, s32, int); + tex_a1d(s32, int, f32, float); + tex_a1d(f32, float, s32, int); + tex_a1d(f32, float, f32, float); + tex_a1d_f16(s32, int); + tex_a1d_f16(f32, float); + +#define tex_a2d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_a2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + return tex2DLayered(textureObject, float(x), float(y), int(layer)).data; \ + } \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_indirect_a2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(uint64_t texobj, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + return tex2DLayered(textureObject, float(x), float(y), int(layer)).data; \ + } + + __device__ half4 __ockl_image_sampleh_2Da(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float4::Native_vec_ c); +#define tex_a2d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_a2d_v4_f16_##COORD_TYPE)(struct textureReference GLOBAL_SPACE * ptr, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2Da(i, s, (float4){float(x), float(y), float(layer), 0.0}.data); \ + } \ + half4 FUNC(tex_indirect_a2d_v4_f16_##COORD_TYPE)(uint64_t texobj, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = (hipTextureObject_t)texobj; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2Da(i, s, (float4){float(x), float(y), float(layer), 0.0}.data); \ + } + + tex_a2d(u32, uint, s32, int); + tex_a2d(u32, uint, f32, float); + tex_a2d(s32, int, s32, int); + tex_a2d(s32, int, f32, float); + tex_a2d(f32, float, s32, int); + tex_a2d(f32, float, f32, float); + tex_a2d_f16(s32, int); + tex_a2d_f16(f32, float); + +#define suld_b_1d_vec(VEC, TYPE, HIP_TYPE) \ + HIP_TYPE::Native_vec_ FUNC(suld_b_1d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int1::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(x.x, __ockl_image_channel_data_type_1D(i), __ockl_image_channel_order_1D(i)); \ + return __hipMapFrom(__ockl_image_load_1D(i, byte_coord)).data; \ + } \ + \ + HIP_TYPE::Native_vec_ FUNC(suld_b_indirect_1d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int1::Native_vec_ x) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + HIP_TYPE result; \ + surf1Dread(&result, surfObj, x.x, hipBoundaryModeTrap); \ + return result.data; \ + } + + suld_b_1d_vec(, b8, uchar1); + suld_b_1d_vec(, b16, ushort1); + suld_b_1d_vec(, b32, uint1); + // suld_b_1d_vec(, b64, ulong1); + suld_b_1d_vec(_v2, b8, uchar2); + suld_b_1d_vec(_v2, b16, ushort2); + suld_b_1d_vec(_v2, b32, uint2); + // suld_b_1d_vec(_v2, b64, ulong2); + suld_b_1d_vec(_v4, b8, uchar4); + suld_b_1d_vec(_v4, b16, ushort4); + suld_b_1d_vec(_v4, b32, uint4); + // suld_b_1d_vec(_v4, b64, ulong4); + +#define suld_b_2d_vec(VEC, TYPE, HIP_TYPE) \ + HIP_TYPE::Native_vec_ FUNC(suld_b_2d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int2::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_2D(i), __ockl_image_channel_order_2D(i)); \ + return __hipMapFrom(__ockl_image_load_2D(i, int2(byte_coord, coord.y).data)).data; \ + } \ + \ + HIP_TYPE::Native_vec_ FUNC(suld_b_indirect_2d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int2::Native_vec_ x) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + HIP_TYPE result; \ + surf2Dread(&result, surfObj, x.x, x.y); \ + return result.data; \ + } + + suld_b_2d_vec(, b8, uchar1); + suld_b_2d_vec(, b16, ushort1); + suld_b_2d_vec(, b32, uint1); + // suld_b_2d_vec(, b64, ulong1); + suld_b_2d_vec(_v2, b8, uchar2); + suld_b_2d_vec(_v2, b16, ushort2); + suld_b_2d_vec(_v2, b32, uint2); + // suld_b_2d_vec(_v2, b64, ulong2); + suld_b_2d_vec(_v4, b8, uchar4); + suld_b_2d_vec(_v4, b16, ushort4); + suld_b_2d_vec(_v4, b32, uint4); + // suld_b_2d_vec(_v4, b64, ulong4); + +#define suld_b_3d_vec(VEC, TYPE, HIP_TYPE) \ + HIP_TYPE::Native_vec_ FUNC(suld_b_3d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int4::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_3D(i), __ockl_image_channel_order_3D(i)); \ + return __hipMapFrom(__ockl_image_load_3D(i, int4(byte_coord, coord.y, coord.z, 0).data)).data; \ + } \ + \ + HIP_TYPE::Native_vec_ FUNC(suld_b_indirect_3d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int4::Native_vec_ x) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + HIP_TYPE result; \ + surf3Dread(&result, surfObj, x.x, x.y, x.z); \ + return result.data; \ + } + + suld_b_3d_vec(, b8, uchar1); + suld_b_3d_vec(, b16, ushort1); + suld_b_3d_vec(, b32, uint1); + // suld_b_3d_vec(, b64, ulong1); + suld_b_3d_vec(_v2, b8, uchar2); + suld_b_3d_vec(_v2, b16, ushort2); + suld_b_3d_vec(_v2, b32, uint2); + // suld_b_3d_vec(_v2, b64, ulong2); + suld_b_3d_vec(_v4, b8, uchar4); + suld_b_3d_vec(_v4, b16, ushort4); + suld_b_3d_vec(_v4, b32, uint4); + // suld_b_3d_vec(_v4, b64, ulong4); + +#define suld_b_a1d_vec(VEC, TYPE, HIP_TYPE) \ + HIP_TYPE::Native_vec_ FUNC(suld_b_a1d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, uint layer, int x) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_1Da(i), __ockl_image_channel_order_1Da(i)); \ + return __hipMapFrom(__ockl_image_load_1Da(i, int2(byte_coord, int(layer)).data)).data; \ + } \ + \ + HIP_TYPE::Native_vec_ FUNC(suld_b_indirect_a1d##VEC##_##TYPE##_trap)(uint64_t serf_arg, uint layer, int x) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + __HIP_SURFACE_OBJECT_PARAMETERS_INIT \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_1Da(i), __ockl_image_channel_order_1Da(i)); \ + return __hipMapFrom(__ockl_image_load_1Da(i, int2(byte_coord, int(layer)).data)).data; \ + } + + suld_b_a1d_vec(, b8, uchar1); + suld_b_a1d_vec(, b16, ushort1); + suld_b_a1d_vec(, b32, uint1); + // suld_b_a1d_vec(, b64, ulong1); + suld_b_a1d_vec(_v2, b8, uchar2); + suld_b_a1d_vec(_v2, b16, ushort2); + suld_b_a1d_vec(_v2, b32, uint2); + // suld_b_a1d_vec(_v2, b64, ulong2); + suld_b_a1d_vec(_v4, b8, uchar4); + suld_b_a1d_vec(_v4, b16, ushort4); + suld_b_a1d_vec(_v4, b32, uint4); + // suld_b_a1d_vec(_v4, b64, ulong4); + +#define suld_b_a2d_vec(VEC, TYPE, HIP_TYPE) \ + HIP_TYPE::Native_vec_ FUNC(suld_b_a2d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, uint layer, int x, int y) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_2Da(i), __ockl_image_channel_order_2Da(i)); \ + return __hipMapFrom(__ockl_image_load_2Da(i, int4(byte_coord, y, int(layer), 0).data)).data; \ + } \ + \ + HIP_TYPE::Native_vec_ FUNC(suld_b_indirect_a2d##VEC##_##TYPE##_trap)(uint64_t serf_arg, uint layer, int x, int y) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + __HIP_SURFACE_OBJECT_PARAMETERS_INIT \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_2Da(i), __ockl_image_channel_order_2Da(i)); \ + return __hipMapFrom(__ockl_image_load_2Da(i, int4(byte_coord, y, int(layer), 0).data)).data; \ + } + + suld_b_a2d_vec(, b8, uchar1); + suld_b_a2d_vec(, b16, ushort1); + suld_b_a2d_vec(, b32, uint1); + // suld_b_a2d_vec(, b64, ulong1); + suld_b_a2d_vec(_v2, b8, uchar2); + suld_b_a2d_vec(_v2, b16, ushort2); + suld_b_a2d_vec(_v2, b32, uint2); + // suld_b_a2d_vec(_v2, b64, ulong2); + suld_b_a2d_vec(_v4, b8, uchar4); + suld_b_a2d_vec(_v4, b16, ushort4); + suld_b_a2d_vec(_v4, b32, uint4); + // suld_b_a2d_vec(_v4, b64, ulong4); + +#define sust_b_1d_vec(VEC, TYPE, HIP_TYPE) \ + void FUNC(sust_b_1d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int1::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_1D(i), __ockl_image_channel_order_1D(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_1D(i, byte_coord, tmp); \ + } \ + void FUNC(sust_b_indirect_1d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int1::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + surf1Dwrite(hip_data, surfObj, coord.x); \ + } + + sust_b_1d_vec(, b8, uchar1); + sust_b_1d_vec(, b16, ushort1); + sust_b_1d_vec(, b32, uint1); + // sust_b_1d_vec(, b64, ulong1); + sust_b_1d_vec(_v2, b8, uchar2); + sust_b_1d_vec(_v2, b16, ushort2); + sust_b_1d_vec(_v2, b32, uint2); + // sust_b_1d_vec(_v2, b64, ulong2); + sust_b_1d_vec(_v4, b8, uchar4); + sust_b_1d_vec(_v4, b16, ushort4); + sust_b_1d_vec(_v4, b32, uint4); + // sust_b_1d_vec(_v4, b64, ulong4); + +#define sust_b_2d_vec(VEC, TYPE, HIP_TYPE) \ + void FUNC(sust_b_2d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int2::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_2D(i), __ockl_image_channel_order_2D(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_2D(i, int2(byte_coord, coord.y).data, tmp); \ + } \ + void FUNC(sust_b_indirect_2d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int2::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + surf2Dwrite(hip_data, surfObj, coord.x, coord.y); \ + } + + sust_b_2d_vec(, b8, uchar1); + sust_b_2d_vec(, b16, ushort1); + sust_b_2d_vec(, b32, uint1); + // sust_b_2d_vec(, b64, ulong1); + sust_b_2d_vec(_v2, b8, uchar2); + sust_b_2d_vec(_v2, b16, ushort2); + sust_b_2d_vec(_v2, b32, uint2); + // sust_b_2d_vec(_v2, b64, ulong2); + sust_b_2d_vec(_v4, b8, uchar4); + sust_b_2d_vec(_v4, b16, ushort4); + sust_b_2d_vec(_v4, b32, uint4); + // sust_b_2d_vec(_v4, b64, ulong4); + +#define sust_b_3d_vec(VEC, TYPE, HIP_TYPE) \ + void FUNC(sust_b_3d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, int4::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_3D(i), __ockl_image_channel_order_3D(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_3D(i, int4(byte_coord, coord.y, coord.z, 0).data, tmp); \ + } \ + void FUNC(sust_b_indirect_3d##VEC##_##TYPE##_trap)(uint64_t serf_arg, int4::Native_vec_ coord, HIP_TYPE::Native_vec_ data) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + __HIP_SURFACE_OBJECT_PARAMETERS_INIT; \ + int byte_coord = __hipGetPixelAddr(coord.x, __ockl_image_channel_data_type_3D(i), __ockl_image_channel_order_3D(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_3D(i, int4(byte_coord, coord.y, coord.z, 0).data, tmp); \ + } + + sust_b_3d_vec(, b8, uchar1); + sust_b_3d_vec(, b16, ushort1); + sust_b_3d_vec(, b32, uint1); + // sust_b_3d_vec(, b64, ulong1); + sust_b_3d_vec(_v2, b8, uchar2); + sust_b_3d_vec(_v2, b16, ushort2); + sust_b_3d_vec(_v2, b32, uint2); + // sust_b_3d_vec(_v2, b64, ulong2); + sust_b_3d_vec(_v4, b8, uchar4); + sust_b_3d_vec(_v4, b16, ushort4); + sust_b_3d_vec(_v4, b32, uint4); + // sust_b_3d_vec(_v4, b64, ulong4); + +#define sust_b_a1d_vec(VEC, TYPE, HIP_TYPE) \ + void FUNC(sust_b_a1d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, uint layer, int x, HIP_TYPE::Native_vec_ data) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_1Da(i), __ockl_image_channel_order_1Da(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_1Da(i, int2(byte_coord, int(layer)).data, tmp); \ + } \ + void FUNC(sust_b_indirect_a1d##VEC##_##TYPE##_trap)(uint64_t serf_arg, uint layer, int x, HIP_TYPE::Native_vec_ data) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + __HIP_SURFACE_OBJECT_PARAMETERS_INIT; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_1Da(i), __ockl_image_channel_order_1Da(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_1Da(i, int2(byte_coord, int(layer)).data, tmp); \ + } + + sust_b_a1d_vec(, b8, uchar1); + sust_b_a1d_vec(, b16, ushort1); + sust_b_a1d_vec(, b32, uint1); + // sust_b_a1d_vec(, b64, ulong1); + sust_b_a1d_vec(_v2, b8, uchar2); + sust_b_a1d_vec(_v2, b16, ushort2); + sust_b_a1d_vec(_v2, b32, uint2); + // sust_b_a1d_vec(_v2, b64, ulong2); + sust_b_a1d_vec(_v4, b8, uchar4); + sust_b_a1d_vec(_v4, b16, ushort4); + sust_b_a1d_vec(_v4, b32, uint4); + // sust_b_a1d_vec(_v4, b64, ulong4); + +#define sust_b_a2d_vec(VEC, TYPE, HIP_TYPE) \ + void FUNC(sust_b_a2d##VEC##_##TYPE##_trap)(struct textureReference GLOBAL_SPACE * ptr, uint layer, int x, int y, HIP_TYPE::Native_vec_ data) \ + { \ + hipTextureObject_t textureObject = ptr->textureObject; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_2Da(i), __ockl_image_channel_order_2Da(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_2Da(i, int4(byte_coord, y, int(layer), 0).data, tmp); \ + } \ + void FUNC(sust_b_indirect_a2d##VEC##_##TYPE##_trap)(uint64_t serf_arg, uint layer, int x, int y, HIP_TYPE::Native_vec_ data) \ + { \ + hipSurfaceObject_t surfObj = (hipSurfaceObject_t)serf_arg; \ + __HIP_SURFACE_OBJECT_PARAMETERS_INIT; \ + int byte_coord = __hipGetPixelAddr(x, __ockl_image_channel_data_type_2Da(i), __ockl_image_channel_order_2Da(i)); \ + HIP_TYPE hip_data; \ + hip_data.data = data; \ + auto tmp = __pack_to_float4(hip_data); \ + __ockl_image_store_2Da(i, int4(byte_coord, y, int(layer), 0).data, tmp); \ + } + + sust_b_a2d_vec(, b8, uchar1); + sust_b_a2d_vec(, b16, ushort1); + sust_b_a2d_vec(, b32, uint1); + // sust_b_a2d_vec(, b64, ulong1); + sust_b_a2d_vec(_v2, b8, uchar2); + sust_b_a2d_vec(_v2, b16, ushort2); + sust_b_a2d_vec(_v2, b32, uint2); + // sust_b_a2d_vec(_v2, b64, ulong2); + sust_b_a2d_vec(_v4, b8, uchar4); + sust_b_a2d_vec(_v4, b16, ushort4); + sust_b_a2d_vec(_v4, b32, uint4); + // sust_b_a2d_vec(_v4, b64, ulong4); + + __device__ static inline bool is_upper_warp() + { + return FUNC_CALL(COMPILATION_MODE) == CompilationMode::DoubleWave32OnWave64 && __lane_id() >= 32; + } + + uint32_t FUNC(sreg_laneid)() + { + switch (FUNC_CALL(COMPILATION_MODE)) + { + case CompilationMode::Wave32: + { + return __builtin_amdgcn_mbcnt_lo(~0U, 0); + } + case CompilationMode::Wave32OnWave64: + { + uint32_t lane_id = __lane_id(); + return lane_id; + } + case CompilationMode::DoubleWave32OnWave64: + { + uint32_t lane_id = __lane_id(); + return lane_id & 31U; + } + default: + { + __builtin_unreachable(); + return 0; + } + } + } + +#define shfl(NAME, EXPR) \ + uint32_t FUNC(shfl_##NAME##_b32_slow)(uint32_t a, uint32_t b, uint32_t c) \ + { \ + __builtin_amdgcn_wave_barrier(); \ + int32_t lane = (int32_t)FUNC_CALL(sreg_laneid()); \ + int32_t bval = b & 31U; \ + int32_t cval = c & 31U; \ + int32_t mask = (c >> 8) & 31U; \ + int32_t max_lane = (lane & mask) | (cval & ~mask); \ + int32_t min_lane __attribute__((unused)) = (lane & mask); \ + int32_t j, pval; \ + EXPR; \ + if (!pval) \ + j = lane; \ + if (is_upper_warp()) \ + j += 32; \ + int32_t shfl_width = (FUNC_CALL(COMPILATION_MODE) == CompilationMode::DoubleWave32OnWave64) ? 64 : 32; \ + return __shfl(a, j, shfl_width); \ + } \ + \ + uint2::Native_vec_ FUNC(shfl_##NAME##_b32_pred_slow)(uint32_t a, uint32_t b, uint32_t c) \ + { \ + __builtin_amdgcn_wave_barrier(); \ + int32_t lane = (int32_t)FUNC_CALL(sreg_laneid()); \ + int32_t bval = b & 31U; \ + int32_t cval = c & 31U; \ + int32_t mask = (c >> 8) & 31U; \ + int32_t max_lane = (lane & mask) | (cval & ~mask); \ + int32_t min_lane __attribute__((unused)) = (lane & mask); \ + int32_t j, pval; \ + EXPR; \ + if (!pval) \ + j = lane; \ + if (is_upper_warp()) \ + j += 32; \ + int32_t shfl_width = (FUNC_CALL(COMPILATION_MODE) == CompilationMode::DoubleWave32OnWave64) ? 64 : 32; \ + return uint2(__shfl(a, j, shfl_width), pval).data; \ + } + + shfl(up, j = lane - bval; pval = (j >= max_lane)); + shfl(down, j = lane + bval; pval = (j <= max_lane)); + shfl(bfly, j = lane ^ bval; pval = (j <= max_lane)); + shfl(idx, j = min_lane | (bval & ~mask); pval = (j <= max_lane)); + + void FUNC(__assertfail)(uint64_t message, + uint64_t file, + uint32_t line, + uint64_t function, + __attribute__((unused)) uint64_t char_size) + { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-attributes" + [[clang::always_inline]] __assert_fail((const char *)message, (const char *)file, line, (const char *)function); +#pragma clang diagnostic pop + } + + uint64_t FUNC(malloc)(uint64_t size) + { + return reinterpret_cast(malloc(size)); + } + + void FUNC(free)(uint64_t ptr) + { + return free(reinterpret_cast(ptr)); + } + + __device__ static inline uint32_t match_any_sync_b32_32(int32_t a, uint32_t membermask) + { + int32_t result = 0; + for (int i = 0; i < 32; i++) + { + int32_t current = __builtin_amdgcn_readlane(a, i); + result |= ((a == current) << i); + } + return ((uint32_t)result) & membermask; + } + + __device__ static inline uint32_t match_any_sync_b32_double32(int32_t a, uint32_t membermask) + { + int32_t result = 0; + int start = is_upper_warp() ? 32 : 0; + for (int i = start; i < start + 32; i++) + { + int32_t current = __shfl(a, i, 64); + result |= ((a == current) << (i % 32)); + } + return ((uint32_t)result) & membermask; + } + + uint32_t FUNC(match_any_sync_b32)(int32_t a, uint32_t membermask) + { + if (FUNC_CALL(COMPILATION_MODE) == CompilationMode::DoubleWave32OnWave64) + return match_any_sync_b32_double32(a, membermask); + else + return match_any_sync_b32_32(a, membermask); + } + + // https://cplusplus.com/reference/cstdio/printf/ + __device__ static uint8_t parse_printf_length(const char *s, uint8_t &len) + { + switch (*s) + { + case 'h': + switch (s[1]) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + len = 2; + break; + case 'n': + len = 8; + break; + default: + return 0; + } + case 'l': + switch (s[1]) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + len = FUNC_CALL(IS_WINDOWS) ? 4 : 8; + break; + case 'c': + len = FUNC_CALL(IS_WINDOWS) ? 2 : 4; + break; + case 's': + case 'n': + len = 8; + break; + case 'l': + switch (s[2]) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + case 'n': + len = 8; + return 2; + default: + return 0; + } + default: + return 0; + } + default: + return 0; + } + return 1; + } + + __device__ static bool parse_printf_specifier(const char *s, uint8_t &len) + { + switch (*s) + { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + case 'c': + len = 4; + break; + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + case 'a': + case 'A': + case 's': + case 'p': + case 'n': + len = 8; + break; + default: + return false; + } + return true; + } + + __device__ static uint32_t round_up(uint32_t numToRound, uint32_t multiple_2) + { + return (numToRound + multiple_2 - uint32_t(1)) & -multiple_2; + } + + __device__ static uint64_t read_valist(const char *valist_ptr, uint32_t &offset, uint8_t len) + { + // add padding + offset = round_up(offset, len); + uint64_t result; + switch (len) + { + case 1: + result = uint64_t(*(const uint8_t *)(valist_ptr + offset)); + break; + case 2: + result = uint64_t(*(const uint16_t *)(valist_ptr + offset)); + break; + case 4: + result = uint64_t(*(const uint32_t *)(valist_ptr + offset)); + break; + case 8: + result = uint64_t(*(const uint64_t *)(valist_ptr + offset)); + break; + default: + __builtin_unreachable(); + } + offset += len; + return result; + } + + __device__ uint64_t __ockl_printf_begin(uint64_t version); + __device__ uint64_t __ockl_printf_append_string_n(uint64_t msg_desc, const char *data, uint64_t length, uint32_t is_last); + __device__ uint64_t __ockl_printf_append_args(uint64_t msg_desc, uint32_t num_args, uint64_t value0, uint64_t value1, uint64_t value2, uint64_t value3, uint64_t value4, uint64_t value5, uint64_t value6, uint32_t is_last); + + __device__ static uint32_t strlen_plus_one(const char *s) + { + const char *c = s; + while ((*(c++)) != 0) + { + } + return uint32_t(c - s); + } + + uint32_t FUNC(vprintf)(uint64_t format, uint64_t valist) + { + uint64_t handle = __ockl_printf_begin(0); + const char *msg = (const char *)format; + const char *valist_ptr = (const char *)valist; + const char *s = msg; + uint32_t valist_offset = 0; + uint32_t len = strlen_plus_one(msg); + handle = __ockl_printf_append_string_n(handle, msg, len, 0); + + while (true) + { + char c = *(s++); + if (c == 0) + break; + if (c == '%') + { + uint8_t len = 0; + if (parse_printf_specifier(s, len)) + { + s++; + } + else + { + uint8_t specifier_with_length = parse_printf_length(s, len); + if (specifier_with_length) + { + s += specifier_with_length; + } + if (len > 0) + { + uint64_t value = read_valist(valist_ptr, valist_offset, len); + handle = __ockl_printf_append_args(handle, 1, value, 0, 0, 0, 0, 0, 0, 0); + } + } + } + } + return (uint32_t)__ockl_printf_append_args(handle, 0, 0, 0, 0, 0, 0, 0, 0, 1); + return 1; + } + + int64_t __ockl_mul_hi_i64(int64_t x, int64_t y) __attribute__((device)); + int64_t FUNC(mul_hi_s64)(int64_t x, int64_t y) + { + return __ockl_mul_hi_i64(x, y); + } + + int64_t FUNC(mad_hi_s64)(int64_t a, int64_t b, int64_t c) + { + int64_t temp = FUNC_CALL(mul_hi_s64)(a, b); + return temp + c; + } + + uint64_t __ockl_mul_hi_u64(uint64_t x, uint64_t y) __attribute__((device)); + uint64_t FUNC(mul_hi_u64)(uint64_t x, uint64_t y) + { + return __ockl_mul_hi_u64(x, y); + } + + uint64_t FUNC(mad_hi_u64)(uint64_t a, uint64_t b, uint64_t c) + { + uint64_t temp = FUNC_CALL(mul_hi_u64)(a, b); + return temp + c; + } + + uint32_t __ockl_bfe_u32(uint32_t, uint32_t, uint32_t) __attribute__((device)); + uint32_t FUNC(bfe_u32)(uint32_t base, uint32_t pos, uint32_t len) + { + return __ockl_bfe_u32(base, pos, len); + } + + uint64_t FUNC(bfe_u64)(uint64_t base, uint32_t pos, uint32_t len) + { + // No V_BFE_U64 + return (base >> pos) & ((1U << len) - 1U); + } + + int32_t __ockl_bfe_i32(int32_t, uint32_t, uint32_t) __attribute__((device)); + int32_t FUNC(bfe_s32)(int32_t base, uint32_t pos, uint32_t len) + { + return __ockl_bfe_i32(base, pos, len); + } + + int64_t FUNC(bfe_s64)(int64_t base, uint32_t pos, uint32_t len) + { + // No V_BFE_I64 + return (base << (64U - pos - len)) >> (64U - len); + } + + uint32_t __ockl_bfm_u32(uint32_t count, uint32_t offset) __attribute__((device)) __attribute__((const)); + + uint32_t FUNC(bfi_b32)(uint32_t insert, uint32_t base, uint32_t offset, uint32_t count) + { + offset = offset & 0xffU; + if (offset > 31U) + { + return base; + } + count = count & 0xffU; + uint32_t mask; + if (count > 31U) + { + mask = UINT32_MAX << offset; + } + else + { + mask = __ockl_bfm_u32(count, offset); + } + return (~mask & base) | (mask & (insert << offset)); + } + + // NVIDIA docs are incorrect. + // In bfi, operands c and d are restricted to 0..255 _only_ in b32 mode + uint64_t FUNC(bfi_b64)(uint64_t insert, uint64_t base, uint32_t offset, uint32_t count) + { + if (offset > 63U) + { + return base; + } + uint64_t mask; + if (count > 63U) + { + mask = UINT64_MAX << offset; + } + else + { + mask = ((1UL << count) - 1UL) << (offset); + } + return (~mask & base) | (mask & (insert << offset)); + } + + uint32_t FUNC(activemask)(void) + { + if (FUNC_CALL(COMPILATION_MODE) == CompilationMode::DoubleWave32OnWave64) + { + uint64_t exec = __builtin_amdgcn_read_exec(); + if (is_upper_warp()) + { + return (uint32_t)(exec >> 32); + } + else + { + return (uint32_t)exec; + } + } + return __builtin_amdgcn_read_exec_lo(); + } + + // Taken from __ballot definition in hipamd/include/hip/amd_detail/amd_device_functions.h + // They return active threads, which I think is incorrect + uint32_t FUNC(sreg_lanemask_lt)(void) + { + uint32_t lane_idx = FUNC_CALL(sreg_laneid)(); + uint32_t mask = (1U << lane_idx) - 1U; + return mask; + } + + uint32_t FUNC(sreg_lanemask_ge)(void) + { + uint32_t lane_idx = FUNC_CALL(sreg_laneid)(); + uint32_t mask = (~0U) << lane_idx; + return mask; + } + + uint32_t FUNC(sreg_lanemask_le)(void) + { + uint32_t lane_idx = FUNC_CALL(sreg_laneid)(); + uint32_t mask = 1U << lane_idx; + return mask | (mask - 1); + } + + size_t __ockl_get_local_linear_id() __device__; + size_t __ockl_get_local_id(uint32_t) __device__; + size_t __ockl_get_local_size(uint32_t) __device__; + uint32_t FUNC(sreg_tid)(uchar dim) + { + if (FUNC_CALL(COMPILATION_MODE) == CompilationMode::Wave32OnWave64) + { + uint32_t linear_id_hip = (uint32_t)__ockl_get_local_linear_id(); + uint32_t wavefront_id = linear_id_hip / 64U; + uint32_t laneid = linear_id_hip % 64U; + uint32_t linear_id_cuda = (wavefront_id * 32) + laneid; + if (dim == 0) + return linear_id_cuda % __ockl_get_local_size(0); + if (dim == 1) + return (linear_id_cuda / __ockl_get_local_size(0)) % __ockl_get_local_size(1); + if (dim == 2) + return (linear_id_cuda / (__ockl_get_local_size(0) * __ockl_get_local_size(1))) % (__ockl_get_local_size(2) / 2); + return 0; + } + else + { + return (uint32_t)__ockl_get_local_id(dim); + } + } + + uint32_t FUNC(sreg_ntid)(uchar dim) + { + uint32_t local_size = (uint32_t)__ockl_get_local_size(dim); + if (FUNC_CALL(COMPILATION_MODE) == CompilationMode::Wave32OnWave64 && dim == 2) + { + local_size /= 2U; + } + return local_size; + } + + size_t __ockl_get_group_id(uint32_t) __device__; + uint32_t FUNC(sreg_ctaid)(uchar dim) + { + return (uint32_t)__ockl_get_group_id(dim); + } + + size_t __ockl_get_num_groups(uint32_t) __device__; + uint32_t FUNC(sreg_nctaid)(uchar dim) + { + return (uint32_t)__ockl_get_num_groups(dim); + } + + uint64_t __ockl_cyclectr_u64(void) __device__; + __attribute__((always_inline)) uint32_t FUNC(sreg_clock)(void) + { + return (uint32_t)__ockl_cyclectr_u64(); + } + + __attribute__((always_inline)) uint64_t FUNC(sreg_clock64)() + { + return __ockl_cyclectr_u64(); + } + + void FUNC(barrier_sync)(uint32_t) + { + // I'm not 100% how should a barrier be defined: + // * In NVIDIA world barrier.sync == __syncthreads() + // * Majority of internet sources claim that __syncthreads() is + // equivalent to OpenCL barrier(CLK_LOCAL_MEM_FENCE), but this + // can't be true. Both docs for __syncthreads(...) and barrier + // imply that it syncs global scope memory too + // * AMDGPU has two barrier definitions, one in HIP + // (https://github.com/ROCm-Developer-Tools/hipamd/blob/312dff7b794337aa040be0691acc78e9f968a8d2/include/hip/amd_detail/amd_device_functions.h#L867), + // where the sequence is fence(release), s_barrier, fence(acquire) no matter the fence flags. + // Another is in ROCm-Device-Libs + // (https://github.com/RadeonOpenCompute/ROCm-Device-Libs/blob/amd-stg-open/opencl/src/workgroup/wgbarrier.cl#L21) + // where the sequence is fence(seq_cst), s_barrier, fence(seq_cst) + // * __builtin_amdgcn_fence(..., "workgroup") produce s_waitcnt on everything and L1 flush if it's seq_cst + // I don't see much point in emitting the fence twice. It's not like there were any memory loads or writes + // in-between those fense to wait on + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "workgroup"); + __builtin_amdgcn_s_barrier(); + } + + half __ockl_median3_f16(half, half, half) __attribute__((device)); + half FUNC(cvt_sat_f16_f16)(half x) + { + return __ockl_median3_f16(x, 0, 1); + } + + float __ockl_median3_f32(float, float, float) __attribute__((device)); + float FUNC(cvt_sat_f32_f32)(float x) + { + return __ockl_median3_f32(x, 0.0f, 1.0f); + } + + double FUNC(cvt_sat_f64_f64)(double x) + { + return fmin(fmax(x, 0.0), 1.0); + } + + __device__ uint32_t __llvm_fshl_i32(uint32_t a, uint32_t b, uint32_t c) __asm("llvm.fshl.i32"); + uint32_t FUNC(shf_l_clamp_b32)(uint32_t a, uint32_t b, uint32_t c) + { + if (c >= 32) + return a; + return __llvm_fshl_i32(b, a, c); + } + + __device__ uint32_t __llvm_fshr_i32(uint32_t a, uint32_t b, uint32_t c) __asm("llvm.fshr.i32"); + uint32_t FUNC(shf_r_clamp_b32)(uint32_t a, uint32_t b, uint32_t c) + { + if (c >= 32) + return b; + return __llvm_fshr_i32(b, a, c); + } + + uint32_t __ockl_udot4(uint32_t, uint32_t, uint32_t, bool) __attribute__((device)); + uint32_t FUNC(dp4a_u32_u32)(uint32_t a, uint32_t b, uint32_t c) + { + return __ockl_udot4(a, b, c, false); + } + + int32_t __ockl_sdot4(int32_t, int32_t, int32_t, bool) __attribute__((device)); + int32_t FUNC(dp4a_s32_s32)(int32_t a, int32_t b, int32_t c) + { + return __ockl_sdot4(a, b, c, false); + } +} +__device__ uint32_t __llvm_amdgcn_ballot_i32(bool) __asm("llvm.amdgcn.ballot.i32"); +__device__ uint64_t __llvm_amdgcn_ballot_i64(bool) __asm("llvm.amdgcn.ballot.i64"); + +template +__device__ static inline uint32_t vote_sync_pred(bool value, uint32_t membermask, bool negate) +{ + __builtin_amdgcn_wave_barrier(); + if constexpr (compilation_mode == CompilationMode::DoubleWave32OnWave64) + { + uint64_t vote = __llvm_amdgcn_ballot_i64(negate ? !value : value); + if (is_upper_warp()) + { + return ((uint32_t)(vote >> 32)) & membermask; + } + else + { + return ((uint32_t)vote) & membermask; + } + } + else if constexpr (compilation_mode == CompilationMode::Wave32) + { + return __llvm_amdgcn_ballot_i32(negate ? !value : value) & membermask; + } + else if constexpr (compilation_mode == CompilationMode::Wave32OnWave64) + { + return ((uint32_t)__llvm_amdgcn_ballot_i64(negate ? !value : value)) & membermask; + } + else + { + __builtin_unreachable(); + return 0; + } +} + +extern "C" +{ + +#define GENERATE_VOTE_SYNC(SUFFIX, MODE) \ + bool FUNC(vote_sync_any_pred_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, false) != 0; \ + } \ + \ + bool FUNC(vote_sync_any_pred_negate_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, true) != 0; \ + } \ + \ + bool FUNC(vote_sync_all_pred_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, false) == membermask; \ + } \ + \ + bool FUNC(vote_sync_all_pred_negate_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, true) == membermask; \ + } \ + \ + uint32_t FUNC(vote_sync_ballot_b32_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, false); \ + } \ + \ + uint32_t FUNC(vote_sync_ballot_b32_negate_##SUFFIX)(bool value, uint32_t membermask) \ + { \ + return vote_sync_pred(value, membermask, true); \ + } + + GENERATE_VOTE_SYNC(32, CompilationMode::Wave32); + GENERATE_VOTE_SYNC(32on64, CompilationMode::Wave32OnWave64); + GENERATE_VOTE_SYNC(double32on64, CompilationMode::DoubleWave32OnWave64); + + // From NVIDIA PTX documentation: + // "Instruction barrier{.cta} has optional .aligned modifier. When specified, + // it indicates that all threads in CTA will execute the same barrier{.cta} instruction. + // In conditionally executed code, an aligned barrier{.cta} instruction should + // only be used if it is known that all threads in CTA evaluate the condition identically, + // otherwise behavior is undefined." + // This would imply that unaligned bar.red makes sense, but not sure how much sense does it make? + // Maybe with non-zero barriers? + int32_t __ockl_wgred_and_i32(int32_t) __attribute__((device)); + bool FUNC(bar_red_and_pred)(__attribute__((unused)) uint32_t barrier, bool predicate) + { + return __ockl_wgred_and_i32(predicate); + } + + int32_t __ockl_wgred_or_i32(int32_t) __attribute__((device)); + bool FUNC(bar_red_or_pred)(__attribute__((unused)) uint32_t barrier, bool predicate) + { + return __ockl_wgred_or_i32(predicate); + } + + int32_t __ockl_wgred_add_i32(int32_t) __attribute__((device)); + uint32_t FUNC(bar_red_popc_u32)(__attribute__((unused)) uint32_t barrier, bool predicate) + { + return (uint32_t)__ockl_wgred_add_i32(predicate); + } + + void FUNC(nanosleep_u32)(uint32_t ns) + { + // There's no good conversion here, we should read base clock from the environment + // and use it here, but that's a lot of work for very little gain + // So instead I'm assuming here: + // * 2000 MHz if it's wave32 because that's the game clock on my RX 6800 XT, + // meaning 0.5ns for a clock cycle + // * 1000 MHz if it's wave64 because that's the base clock for MI300, + // meaning 1ns for a clock cycle + // Expected sleep time for S_SLEEP x is (x*64)-32 clocks + // We change that 32 offset to 31/63 to avoid small sleep values resulting in s_sleep 0 + uint32_t sleep_amount; + if (FUNC_CALL(COMPILATION_MODE) == CompilationMode::Wave32) + { + sleep_amount = (ns + 31U) / 32U; + } + else + { + sleep_amount = (ns + 63U) / 64U; + } + // We do this garbage because argument to __builtin_amdgcn_s_sleep must be a constant + for (uint32_t i = 0; i < (sleep_amount >> 4U); i++) + __builtin_amdgcn_s_sleep(16); + if (sleep_amount & 8U) + __builtin_amdgcn_s_sleep(8); + if (sleep_amount & 4U) + __builtin_amdgcn_s_sleep(4); + if (sleep_amount & 2U) + __builtin_amdgcn_s_sleep(2); + if (sleep_amount & 1U) + __builtin_amdgcn_s_sleep(1); + } +} diff --git a/ptx/lib/zluda_ptx_impl.spv b/ptx/lib/zluda_ptx_impl.spv deleted file mode 100644 index 731966e2aa649dfd179822a634c86aaa5dfecb0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49500 zcmb821%RK`@pcz?cXxMpcXyW%AcR2BB)Ge~ySux)ySuwqC{Uotch2@c+e!ahvfr?j?> zQK6$_jh*}KxXh}v4;Z+02la-bN=N5ffok7Sdsckwu0&LSg^rQP>*$z?)obIq=IpoQ zz&`zZ4cKy%Q=(xr0jX zs2!jF&)ihj?b@f;Rs(zY z>f3*(EqnLxwRNAZy6!e+$9BAw|G)G7cC6>$8>Z*y`|Q|f*M3|5=K|h;A@0)C{_T9% z1w4N=AouY6fNgv4+Gp$kwCCN7*>MR_|NouuYTtSO;-1aF@6Lm|pZ`len}0b!c>mS; zh0=rjcb@NV{^$2>{`Gv<1)Sd>J)6JhyPf~2J>#dG?`q#U{|S25f54stx}X2TJ$wJ< z{NVlX>)HG}&v!TfVS4ud>-nw=IR63v^ZUhMzy3Yn?feJ!Z2skZSNqQS_ZuSry>{g< z0{`>-&v`?9{{KEdc>nQ-IRF2g?{5BnEB*6dKmX@^*9DyaqeJAc>wLHKe`ARJ{rCB< z_MP*8w`cS3{Po-2_y6I0*1wz|y#HZ6n}6r|?&kku&*opxcU{2wFEm8{JLl*5Zs)(` z5c&V_^Ih#b=f76Z-hbz>-|ptWW6$Pa&JW)I$DYl<^L%&npRZ@X{_6Rz3poF4dp3X1 zcRT+pdN%)ZzN>xb{8#;R{`ub1r}uzA`T6INKY#vi&JW)Imp{M%VCTD=|Jr}fe|P7* zF5vvH_;dd1`EKWb-=Fi>&H1kOo%4U7XY()LKL-E#^P8T{znmYu|8{@Qf9_wue{@~I z`Q6d8`PcJZ7x4U~f6jmH-|hUT?-@V#Z|A$(cg}y_p1uFhU%%ab|5>+Z@4uWMy#HH0 zn}6r|?)aayXYaqB@4A5VKcQ#y_k6eWKdxupI`<{Er$UfB${Ht9|GE59`_d%lD72 zU;drv@95e5%lX0k&pkx`JMUk=e{@~I`5o4?`PcJZ7x4T?J)6JhyPf}cJ)3_y-_^cz ze!ui={++*myZin#WzYJT^Mm)lsAu!sU{)K4SgK8lQX5$y%AUHETcC8LXRF&$7N`4ad8ginSPP zBi10+iL7f`PqIE`4Fx}wu@+`+z#7Opk#!yGY1S94;b44f))K5uS$nchW8KVpf%PqG zWacmfYgtxr)_$zBS$D9;<98{!a>tY`Kl&qLm(<~-KP}dnpIKVIzrV>yy8PMQzi{VLTy|-4*&fT&8+t^*1rFKwh=o% z!Ew*HYijnQXX44d$9$~$scS9!_;Dr+@ZZL~Uo@|?OH;06LEeIA?dR|L`f+aN8}s+D zb9U6CM?>eVJ^a0CKeg`|_&Gaf(PN==)*k+zwV&E|9Q>Rex9IWEIcs148tcb*Xuj`o zqNd%SnDrA=m;}2B)0rAO4a;ZW2jBNPeT#JrHB6^=hKs?E=VxG9Pi=g0X61R~iT#Y4 z6yHADoShMEZt||vQMbE!g5i4K)m0{QDjK&RO#- zC;nczpUTO?_+e}jv^^KahLdH`m6K)hjdjpVT{&3}-+Im_oS17oF=xFPzJ0WLw&l_0 zCNG?rI9U~KES#){b}n*~WqtGH#9VX2$?DB_Kb)+AHXcs&o!`{BW`(+MYXM!^v*w%E|8d#^gk8 zuiS4BwDt0?<-}a$i8PU_q>~&=pW5GhGh-4 zHIHq+@zgvOU2BGu(}=qlPI6WoPEJS5iS^C5u6>Tf+E*J+&OqBIoSca^7EaDWI~V&| z(`9}03D>x30ODW9_RACpV() z6HabI8w)2lqc33D&+jQN>zgMh=9&{uZfU;z;pA4d@o=K={H|bmA8nrdHgtXNaB_Q# z%Zb`|=U;csubkY0@27HdCw@4&3vJK4vEk$)bmin>d}DH=wpZ@=2-X#0edr_sj3$unr@V!ysDIkCQZa$>GI;pExoyB|)TLmLk#`p)k` zmiN)-xt~YZ=ME*ICw3Tl0)Pi{tbMiNoTzC+cuwe&xi!m&#A& zWLRS1WH_`vhsTB!e_y^rvD?&9a8tn$tAjcxujqt~JBSti;_5CpoJPC$pjD#QNr2 z*FMu??W+wZv!m@3PUb)x3nz1;os0eYvgE}2=E;e<=7f{En(ux%nHz09oaj5h=~&)J zo9CVfU7tIg%-iB}q7EnKS5EwUqx@7(<|h_T7C_r`L2Nkj|6i+|EQxPSPSll?rSPqn zcP%I88c)nwFNAL&ZJupuw7JO(C(96X&%4Qq{=%$9Sk_QmbJ6A-Pt9e~wPrY3j<|c_ zBxkkZWO=llSl@i>+GjDWeYN3a1+;y_$%<%W;bbMWbFtrnEIF~hd2(W|IpJjG=DQzG zRzVvNC;HBBahCVd=DAlz*XIr=tF^eCsKbf*m6J8`{j7nNjn%PhHSPOZ8*R^Zu;FB5 zbme3dd}DH=uAFR&Z@s*0IWgCGV$OP9eEVqgY@4CYO+yNVI2BIrBgYb>Xjk&9m)}HaB_UW)EWS zc{jPy--)#|%NlBH?$UhYsktY*)(kg$5qB@# z+UFRoeYN4_G_=nh|8%r{!_66JW8vmZv}a_dFH37b^W?@{bHdG8&38ZCoQ*afZuFh! zu`KVW%^c1_*Exinb6Z?))Zxbb%FTKBekwQT6AL#NpzV1fHr!l+uH0OSZ%l5~m7A;Z zt(SK%H|82o%-LUrZy#-*?P|2S$qP5v5OdGF$&LQStV>wdP+RlT<{MAVYtgl4xVetF zd*LQ$wc+M^wA@(VeCyihGOT^I;p7Ii&mI3pw0*_6Z9LrQJI~8m-cOr3+=i}m2sgL4xZJ42jroP+;pQE5<>p;{V{)Ue+`NZxy}Wz5G1quv&i*xg`)KoQ@1xC4Uby*y zn0ww$ZuDPgy}`1E+L~`R-*{?%h^{rm%}2!D3pY8d4L2X7eV^7h-@5jB3u|9(IQaza zbI1P_ZQpS78QNI5`5f&T`}@7dWk2)e#$0p4%@@sgKiqtYHXd&Do#)#u@2AZizCzbI zgqyEhTyE6i#{A07H~4-kH{TKqH-ACf^RL)&^CP-)^G|$Za-*)?{Dg14ynDGZ*LY&i z{%^*b&9nVX%-rOKn_q~z=iTH+|L?5tSk_Qm^B>JOo|^wc*P7wxSK{u4o1E2#o8QoK zV}0|jYoG72_SJ@y-_bsI{6En44L78B7z;N;;d{pZeOYp2Kl9|qTyw(B&}e=4!_6>g z_^72k2cRX4%%G4I?sliaS6ER-Q-4p6xOILYpAU`TJw#k z=6L8@Gu(_%+`VvuH4LuZ#}oejk(4XbN18X*hiaZn+3SB<^0g$ysfPn$U`h^})8 zHw(46+^EBi`IQ_0>;ONNn?;C)n?=#~Tnrm-mPJ=?mcutDH|omG^7z(sJKUISJTYg# zIF5a^dA1eM=JM5fHr%X8z&-EgeDs%KEy=Qm+L}u>-*{@SgswHi&C0~x3pY8d4L7Tx zeV^7h-@5i$8f#x|I9V0#bH`r|ZQpRSI@(ycSp)4E`{(By`*D*V+^k0|+^mnb=LXntvpKqQ(+l62 z+^8!zTi{#I?QmnR@x+|{hB)@o=Gl6q&E>1}Y`EEyfP3CeZuB=|ZOpQU+M1g*-*{?n zg|0Qj&DO--3pY8d4L5zza$|k-t!tl6vG&!5lWovGcl^F+`-Yos(Z<3}KeT7;-OB#!;QJd6La>v;@C%z@nV#CcT=*rEh_{QW$UAZ|8-+FF`8*_~(=IoEd zv5z*-b~@TzzBk#Bu5$=C7q__FsKbrIX2u}hpyaQk8ezF z)RmhX@U7=|xG~pwV$S{w9Q$bVY&W9K<*V~-xVeddd)`fM^si)H#j=LlnpZd9cxv8^ zt~JBWEyUdmH#w^fH@BjFpVl|uy7svSYhP_Rxee`e$G;tI-*9sW+E}=`6YZJ&Y@@ZG zd2(Z}IpOB6=DQzm?nWCAH~P-=T9)_IW)AnD>m0((y)7;`>TqLz<>o$oKb4#NiG`a7 z(Dr-~8*ZLJS8krfHzqgg%FR>w)^j`Dm}@*SXa5k6eYAPDr_tu})p<7DJVU^}2Uv2W z|1j$jmNnGYe6;z-Q}bDLtr>2fBko?f$ysf^W6_OucD2I8-3^bILrHKGl$pEbq?X?^%j>K zb+|FVa`OhhpUTaf#KO&6XnVem4L2X5D>onG8nK7>$x3n%r%~vvwsK2KH5Cn zr)YEe>O326J|p0scat0acUkYTtf98%`^`6=nxCU<&2aMtareSa&T7NWmuR`MzWLU* z&j(ohYQxD_XrDX&*J%5On{Uv@!p*m6&&W%DzOkQqa$~MJ;pQ*RcR$?x6>U7+=sV93 zS>8{ZIs6S>=MZlG-r{nj4majkZob3!Q@QyEv2gP}+MYjP!_BYg%FS>1#^gp_x%nO6 zdTxgsbB!nF?0>|uk2cTt2ijb|I?sk1#@OMWcat0af1-bKk*&7o&&@ZUnp| z;_ii;oYjV#Vc3@&>zi*~`}~5nuQr?v%f8PYe>i-fCEN^;Z!Fx5fcA|2?cuVYd2(Z} zIpJo+=DQzmMnW48H~P-=Uo7vZ%^XH%ug*5yjMCzAqYgLbS8n{XC;e1zMk5w(Mn~Io z3~adZ&%LPJOn`69!K*7b6XIKsD|g2I{bF;CC+6(O#J7(&&o&X-+~kFuiHW)A-Q-4p zEY{d8YpAU`PV z9d698+)R(}r*bm`v2ZgZ+MY9E!;ODdO66uQd}DH>uH4LxZ@s*GxiQyxV$ObMeEVqg zZ1bSaOXpOVa>|2hT595HQ#t@&WElw!_EA}-3vE4s|_~`pykH;=3Cc3 zvt#Y64JQkteeU=Rq3s)P7DgKjH;bS>WB zmiNuH0;cZ@s*GxiQyxV$ObZeEVqgY<OGW+HkWyT5hawzIE-hCDy*$aMB;`bI0ESZQpRSBidNF*$M3# z``g21Kl9|qTyw(B&dql}-0Xrj9&YrV=Te&uE$zMsm? zAY$QWH?%!>$A+8z(3PA0@r}uix^i;>zV-6%<;Gm&i8=c{@a?0`vmJ;wH+kXaAY$%$ zH@VT@leHJi8ft6q-F)Mzc`&-x3^#`mcQ4%JtTx;niuQe4-+b%ZXCJJ6wc+G2w9g&? zaI}5H%@Js0;pRxRXY8M!Z|rBD+?Z=lxH+o%?uVPB(Z<7#zVqCd<^8mo!!hVOhj4Rj zi_48V+?ZdvIS$`X<>q)|;pPOiJx|1jn={arn=|o^$&I>la~8h!^6urvT;qv3`;+kP zqs_COjW#!V;pQA-?s+%4(Lb4W3d6UT(}ao|v=02H!r~Jlm~kbCVZtZX@QNcat0aYgyN^tf98%_02b)nzy5C&2V!E zareSa&T7NWooKnSzWLU*&kb1nYQxE0XrDX&-DvxUn|sj4!p*&C&)7dd-`LMQxiQzA zaC2Yt-48eSqm73fedl>2%lm0FhX>Gg4&mm(7MB}!xG}$S^ANtD`p?-tOf1|yg0|3C#=1JHWt?2L_1r*H#rNJ_05wtbIr-z-fF)4VeM_S@vx@v zJ9viWeYAP*chL2@!`izoE^F$rW`1SuJ$yfvwfBjIwGYtt{16+~zC>5nzQQ*qYwF6{ z*Z9^8FS2H?@x+||0{)g*E+8SRb>jp-qjyplgk=_E+NW`Fygb zZ;ek`)=+z|&zf&MHUEaLHN)E9iMtopa#kDGzC+v7`sQ2LKA&Uls|{=aK-(v*eUCO4 z)_y=c+x!frwZ3_>X0ADz+mFq6Kdk)|Z9J^$`wqTfc^_?_`zLgL?y&ZAi_4liteIa~ z`vu=mW$jD%;=RzsT_BNMMR!rCar-ShcmP2U&_ZqtS##3`tbgdcIMkDTC zSj$;$SQ{N}PwSg+UHc4!wXZg;je)jLSQ`^P0d&5pOIpIWzByNj-Sff1jNGHglKzCgbiy` zp(|@s;~SGTwKDgc2FH5gMb^wUo|v4>=(*7PT3O~SH$Ucv#c-9ZbpcKH5C@oap-8 zVQsD!mo+tCovfK(S@X}l_fuJ$hgevf7j4h^uwl(V1H7`fIKDAiQ!8`7C2*`4US!Q& z{N}n0sL@XSHE%d9*#PZ@zWyvk2C{+OW0)+CE`zMYOT7wi4Re+Rs_I ztZ$yInQKnwwsP~`4{NKSjfXXT-@&3R@1xCguc~I{xx?COEiP+nzB*Ymzp}Qv8+1Mv z?_fig_tECLw?)_I4r~2dT-MZlb+TrDWoF>7Qrv0iwQHFJ$8=B$sxw~sbw zPeGfTyv*!WV(x`C{bN{1v#g;_jnmMzMp!$YxO+aItm#|hSe7-^-s`yL8&AzM(6we* zJCnG3VJ&C1VeKrmJ*{uPb?tLJ*1p=Xb~f5RVeK5Wv9NY7+S%GKKd)KeJXtf>oXqXK z=DQ!(&PN*$Yx=%}6Ik9yo9Dg&U7tIwUD)EXrsk`YHS;TL7rDWwvUV}CuyzUBo|j_7 z+O_D)+I9HGWKFHi{jSHcUU-o;bB!nFtS`g2k2Ys-K%1Mq%09GUmNnGg>#F7(Pt9AB?GCiDuy!Zf+1k%pxU6rUteI<0=5|-}-4APbqm73(ec!<~EbpVubKirm z&mGq8ZE;ys^VP|k`IWW%+~8ALyPsHCdjM_E2eD!8NpxlHDSTtHrdH;DPvclGyvUll z#uIba58>NKo3qcL%}rir_AD{?!kYdgtcO|F(5A+7=vpJJJx|;{pHJ5Gt??+!8fx$L zSo4ji<_qXrGpxNx+`X`tv)Zus655{DH{ZJUc^qqBZCHC5ZJ)6A3ffp$dll_$?U$d| ztZ$yInQKnw_FD7Z4{NWZjfXXT-@y|s@1xCgzk#mL9oF7#aamLI)ybOqm9@9r;8R(9 zn^;(T2W`)Hv0?2~bY<-`d}FevR_1=6<5(}e$eOvv6LZ$@;oC=>vtOXiO4Kf4UKP1 z*3_2F{f5D}UU-o;bB!nFtbb{Jv^hI0Ip!uWGaHVWdtpugSI+&b)zGHK@a)wZVQmEB z?)iMOrf-ekS`D@L`n~zaQ**@ssu|WsBJN&T%UNw$8<~B3THk!@+UF0fbJm8nQP}tH zVQo~jv9LB8+S%GKKd)KeJXtf>oXlj&vA%_wQ)K}$tbMg%Z3eWni$5dUzF}`Bw6U-^GuktL ze{(i2`04tRmNnGgYu)A>PtDEIwPx7sMcloxm$TZiw*}gs);Hg}_E`^WUu{_HjdphN zw?x}F>}`cM7WTGAdq(E^vb6RyPxj0;Cv)u6eD}lNHfZBvPv3X4KFj-QGl#zDI)|{g zZHvpEI_#NW+3Sbzr?R&lv9Py2+MfNfVQ(P1vNs6dnCz)5d%NLVFZ{@!xyBQ7_B-I) zN1JEc9c^y%GP6C1xfk~IcVg|xvW7M__C(hjVQ(+u?)iMOr*Dm&S=LZ{uU(pNJT>=5 z*P3B(AL8zXy`0sCy?xR4w7&V)wa>0t`)b45erRVGe}A-n!`=aCV`1+=v}a^4KkwPk zJlQkXoXqi{=DQ#E4n`Xfd-}eU0W9yQ%^VIv*Exi}Lt9+-)M3y3%HCo4ekyy16AODs zpzV1iHtd~omA#Yktrvb|&s^h)Is2pV?W4`Joq{$ud70U%#M}#e`p2-2 zW?4g<8mFOajj(q*arb;a+0(biu`Fw-z1MNgH=dejpli*rcP4T7!d}j5!`@kFds^Ro z>)PjdtbMg%?QFEOi+>K{`a?A=D(y|925Vn!Si1x5?Bd^vwr|+G z3vDdy-HrB){r%qOvY&afXRbM!<2}uHKkVI$HXio$eJ9tlyq`96xDQ?D5cckGaoJOc zJ@YGj58(T$>^(><>^+3G=fl{r_cXe)_YA%<*;7~cp2fFb_>nzxjVI>pAHlbeHqZ7P z+T7%2X3rCIFYM_*#(I=x4Q*KFQ!MYN%^coF*Exi}cUoNb)M3y3%HF&9ekyzK5es|oqwVomA$Xi8}|N=wx{*Yx2}CY z!`fFH*1khKyZHY=+c)fek2V(een5N1{`q;&e&)%Zx#nb!KQ`a}u=h{2@vx`wJNcaD z{j{0GPv|;_u=jI|%bq&ynP1ua1>a9)?_b2i-mhqT{)P>E!wo+;d&A=!lRb51Zv=en zg&*1LJWo6^Xa9Taqs_C8NRGM5%gjb1=3dy-?_mAWYG_kqWa70(*c*kodp@7+>04tc zmd~s9UPCwEcxsM{t~JBnXvEzMdpWBOd!wW6X?^ppYoB4T_SJ^9G0@H~{+Rgo4SQpu zjfK6j(VnrtvvJwaJlQkXoXl~Y=DQ#E#zh+sd-}eUVX@v%n>mb!u5$=`1Yz?_?^L_tRz$bEE4V!rnYBE_>>*XMSaGUVJ~5z4?fRz4_7hTmT#P zmOxkbmc%zEd+N&GQux*jKeA`8@x+|{g825)=Gm4;o147MY#Czig+2X+SqrhOp-qit z(X~d{TaLJUKA-IATVoNHHPqf~(dHXZ&E?UxX4qSSxO-tQXSHE(MYKJwZ@zWyvl!OC z+OW0~+S$cl8ExONw+h-=*jp9t8T;qwJ^Ps_d*+&xIj+`x_ru=mXyai|-*>V&%lm0F zhc(c34qg&)~7 z*LY&iem#8qX!C5n(B>vDGuwigdtpz11J?R1YiLuWH@emcds`BB&*zgpeQRvUvWD7w zZPa|@sks%p)(m@F6L&A{<*YXB^+DUy`sQ2LJ{x20s|{=0pq*X(zG(Y~y=~FP!d^eL zXY8M!_v~k$?3rs$=D1z+-4A=)qm73>ec#C@Ebphy9Qvc{9KzlXEiQZNuxEZ{Z%2GT z^`DF0iCEa%8Ewy9uwidcbY*WZd}FewuI%lNZ@us%d*&KX%-QdXZy#-*Z6CC`$;-_4 zCFWk((;vthz_NxmHTFZ-8ewmL;_mr;vZrs2K`d*iz1MEdH=ddYpli*rcOY^1!d}j5 z!`?w?ds^Ro>)K~`tbMg%?O?RCi+_lk74{BA8w-1fp*`bYZ=H?He&)%Zx#nb!hd1B- zuy+L7c-YhTo$SH#e%j38NOYY;*gLAlWltUU%&+Vnjqj(jcMP$xcP!eT$6>?XY3Rz{ z>G;NEPhHtN1K)b#NA}D$o|v;g9^XFNJlmOQbCZ{uokh&Ou%~|_>jaiHw5f46y4DDL z=MZ<#=aW5sYn;TghT40b+1Yz@8ndL_tRz$m!az% z!rtXAE_>>*XMSbx3Vc76y(@`@y{pjnyc!$!Zbn!3ZoxMud+N&Gt@zdpKeA`8@x+|{ zHTd??=GksTo147M>~>=Ag+2Z2Sl6l=du5$=`AGWycsl%T6mA#Mf{Z#foCKmQSLEH0FY}or2UD^8!zA@QT zSN8sjZ@us%d*&KX%-Mg2Zy#-*?Qdvvlb4zOotS%JPyY+n=PYYzQ{y{ytr7PALEJr` zPxkb!@g>U|YVY+`^NpwG_vl(P?EOI8y|9Gul|#`vvV8`#T$#{mhd+bIr*d|J8i=!``oG<6%$Vck&I(`)Mxg}n*Tp0U5*`&{-j zPxj0;Cv%*z`R<3kiO|Nwp1$v7B$oHnW)2gh>m0(vBrPs`>ab^iWp7e^Kb5`7h=sk$ z(e|7I8}?>E^VP-Pj5x+*PhHuY3Ez6*NA}D$o|vdM~o_|^+QvS+UG#GL(N`1aA}*;YWCo4m|yMPlxSJ^dwEi?ghuO^ub%wMN)mnYepC zpX}*dV@Z}Z)ZS~U<{MAVRnWC&*jtsjdtonUwP9~Hv^}kFzIE-hG}gY_u(mqd*~MQ2 zZQroBCfZooTMO+O`{(C9`^H`@ zk2cS?HQLHAK$V0k}n=CBL8&LQmW+TyaO4twTT_6Felsq76T7WM|A z?YSE^?CpoQ zd+M-fer4}kd_R@F>xhND>(TbS0UP%2K=akb-kmtcWKUh$y9?iX;Yaq&HJ+HWzY*U) z+C1CcXmgX7ncYLoy|AZ$GwUXnHMFU5FS^zUd-oA{&*zgpeQVspvWD7w-P(NPsd+!T z)(m?O5O*)^<*YXBJ&3la_06}geQv|rR~yzILOZ+o52NiH_8vhS3ww{EJ!Aj;yk|f2 zWY1i4GRMc7?|#^O9Bn-8>HAJ@XL&zu=I{i%&LQkQ+2XRN4twTT_MXD`;~zB{-kv5F z{Y=r%qV4}2b|L7KiRaPQ_Kdma_|E|wPoELle*xdmNGxj`dy!cByj1kdX#2c^wU4>4 zqDO9L%r(b8#?#09yoT?mKF{mK(&vq$-$dKzEo`3WZS?4z_l&vb*vEMKc%OIh{nY1q zmst9|SM>X6`+R`S^L&UNoAaJA*Btv8PoIy_pR)XXg0=R?*w2doyy>aQ`J%+XEcz?7 O{lCWk)-hCP{r?AZm)24M diff --git a/ptx/lib/zluda_rt_ptx_impl.bc b/ptx/lib/zluda_rt_ptx_impl.bc new file mode 100644 index 0000000000000000000000000000000000000000..a927fe4df980717656427da0c022dd512a045b6d GIT binary patch literal 18996 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 literal 0 HcmV?d00001 diff --git a/ptx/lib/zluda_rt_ptx_impl.cpp b/ptx/lib/zluda_rt_ptx_impl.cpp new file mode 100644 index 0000000..398c7f0 --- /dev/null +++ b/ptx/lib/zluda_rt_ptx_impl.cpp @@ -0,0 +1,572 @@ +// Compile and disassemble: +// /opt/rocm/llvm/bin/clang -Xclang -no-opaque-pointers -Wall -Wextra -Wsign-compare -Wconversion -x hip zluda_rt_ptx_impl.cpp -S -emit-llvm --cuda-device-only -nogpulib -O3 -mno-wavefrontsize64 -Xclang -fallow-half-arguments-and-returns -o - | sed -e 's/define/define linkonce_odr/g' | sed -e '/@llvm.used/d' | sed -e 's/\"target-cpu\"=\"[^\"]*\"//g' | sed -e 's/\"target-features\"=\"[^\"]*\"//g' | sed -e 's/\"denormal-fp-math-f32\"=\"[^\"]*\"//g' | sed -e 's/!0, !1, !2//g' | llvm-as-13 -o zluda_rt_ptx_impl.bc && /opt/rocm/llvm/bin/llvm-dis zluda_rt_ptx_impl.bc +// Compile to binary: +// /opt/rocm/llvm/bin/clang -x ir -target amdgcn-amd-amdhsa -Xlinker --no-undefined zluda_rt_ptx_impl.bc -mno-wavefrontsize64 -mcpu=gfx1030 +// Decompile: +// /opt/rocm/llvm/bin/llvm-objdump -d a.out --triple amdgcn-amd-amdhsa +// List of builtins: +// https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/BuiltinsAMDGPU.def +// https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAMDGPU.td +// Extra information: +// https://llvm.org/docs/AMDGPUUsage.html + +#include +#include +#include +#include + +#define FUNC(NAME) __attribute__((device)) __attribute__((retain)) __zluda_rt_ptx_impl__##NAME + +#define GENERIC_SPACE __attribute__((address_space(0))) +#define GLOBAL_SPACE __attribute__((address_space(1))) +#define SHARED_SPACE __attribute__((address_space(3))) +#define CONSTANT_SPACE __attribute__((address_space(4))) +#define PRIVATE_SPACE __attribute__((address_space(5))) + +typedef __fp16 half; +typedef half half4 __attribute__((ext_vector_type(4))); + +#define SKIP_RAYTRACING_GLOBALS +#include "raytracing.hpp" + +extern "C" +{ + // This could be emitted directly during raytracing passes, but we keep it + // here in case we ever wanted to change the layout of variable blocks + __attribute__((always_inline)) GLOBAL_SPACE uint8_t *FUNC(get_variable_pointer_global)( + GLOBAL_SPACE uint8_t *variable_block_ptr, + uint32_t variable_offset) + { + return variable_block_ptr + variable_offset; + } + + __attribute__((always_inline)) PRIVATE_SPACE uint8_t *FUNC(get_variable_pointer_local)( + PRIVATE_SPACE uint8_t *variable_block_ptr, + uint32_t variable_offset) + { + return variable_block_ptr + variable_offset; + } + + __device__ uint32_t ZLUDA_RT(_rt_trace_time_mask_flags_64) ( + uint32_t bvh_index, + float ray_origin_x, + float ray_origin_y, + float ray_origin_z, + float ray_direction_x, + float ray_direction_y, + float ray_direction_z, + uint32_t ray_type, + float tmin, + float tmax, + float time, + uint32_t mask, + uint32_t flags, + uint64_t payload_ptr, + uint32_t payload_size, + uint8_t SHARED_SPACE* global_state + ); + + __device__ uint32_t FUNC(_rt_trace_mask_flags_64) ( + uint32_t bvh_index, + float ray_origin_x, + float ray_origin_y, + float ray_origin_z, + float ray_direction_x, + float ray_direction_y, + float ray_direction_z, + uint32_t ray_type, + float tmin, + float tmax, + uint32_t mask, + uint32_t flags, + uint64_t payload_ptr, + uint32_t payload_size, + uint8_t SHARED_SPACE* global_state + ) { + return ZLUDA_RT(_rt_trace_time_mask_flags_64)( + bvh_index, + ray_origin_x, + ray_origin_y, + ray_origin_z, + ray_direction_x, + ray_direction_y, + ray_direction_z, + ray_type, + tmin, + tmax, + 0.0, + mask, + flags, + payload_ptr, + payload_size, + global_state + ); + } + + __attribute__((always_inline)) uint64_t FUNC(_rt_buffer_get_64)( + uint64_t untyped_ptr, + uint32_t dimensions, + uint32_t element_size, + uint64_t x, + uint64_t y, + uint64_t z, + uint64_t w __attribute__((unused)) + ) { + OptixBuffer *buffer_ptr = reinterpret_cast(untyped_ptr); + switch (dimensions) + { + case 1: + return reinterpret_cast(buffer_ptr->ptr + (element_size * x)); + case 2: + return reinterpret_cast(buffer_ptr->ptr + (element_size * ((buffer_ptr->x * y) + x))); + case 3: + return reinterpret_cast(buffer_ptr->ptr + (element_size * ((buffer_ptr->y * buffer_ptr->x * z) + (buffer_ptr->x * y) + x))); + default: + __builtin_unreachable(); + } + } + + __attribute__((always_inline)) uint64_t FUNC(_rt_buffer_get_id_64)( + uint32_t buffer_id, + uint32_t dimensions, + uint32_t element_size, + uint64_t x, + uint64_t y, + uint64_t z, + uint64_t w, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + uint64_t untyped_ptr = reinterpret_cast(&globals->buffers[buffer_id]); + return ZLUDA_RT(_rt_buffer_get_64)(untyped_ptr, dimensions, element_size, x, y, z, w); + } + + struct buffer_size_result + { + uint64_t x, y, z, w; + }; + __attribute__((always_inline)) buffer_size_result FUNC(_rt_buffer_get_size_64)(uint64_t untyped_ptr, uint32_t dimensions __attribute__((unused)), uint32_t element_size __attribute__((unused))) + { + OptixBuffer *buffer_ptr = reinterpret_cast(untyped_ptr); + return buffer_size_result{buffer_ptr->x, buffer_ptr->y, 0, 0}; + } + + __attribute__((always_inline)) buffer_size_result FUNC(_rt_buffer_get_id_size_64)( + uint32_t buffer_id, + uint32_t dimensions, + uint32_t element_size, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + uint64_t untyped_ptr = reinterpret_cast(&globals->buffers[buffer_id]); + return ZLUDA_RT(_rt_buffer_get_size_64)(untyped_ptr, dimensions, element_size); + } + + uint32_t FUNC(_rt_print_active)(void) + { + return 0; + } + + void FUNC(_rt_throw)(uint32_t) + { + abort(); + } + + // TODO: implement + struct float4_struct + { + float x, y, z, w; + }; + float4_struct FUNC(_rt_transform_tuple)( + uint32_t, + float x, + float y, + float z, + float w) + { + return float4_struct{x, y, z, w}; + } + + uint32_t FUNC(_rt_potential_intersection)( + float distance, + /* vvv INJECTED vvv */ + uint8_t(PRIVATE_SPACE *current_ray)[36], + float current_distance, + float PRIVATE_SPACE *potential_distance) + { + OptixRay PRIVATE_SPACE *optix_ray = reinterpret_cast(current_ray); + if (distance > optix_ray->tmin && distance < current_distance) + { + *potential_distance = distance; + return 1; + } + else + { + return 0; + } + } + + uint32_t FUNC(_rt_report_intersection)( + uint32_t material, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state, + uint2::Native_vec_ launch_idx, + uint2::Native_vec_ dim_idx, + uint8_t(PRIVATE_SPACE *current_ray)[36], + float current_time, + uint8_t PRIVATE_SPACE *payload, + uint8_t GLOBAL_SPACE *variable_block, + uint8_t GLOBAL_SPACE *attribute_block, + uint8_t GLOBAL_SPACE *transform_block, + float PRIVATE_SPACE *new_distance, + uint32_t PRIVATE_SPACE *intersection_result, + uint32_t PRIVATE_SPACE *material_result, + float PRIVATE_SPACE *potential_distance) + { + OptixRay PRIVATE_SPACE *ray_ptr = reinterpret_cast(current_ray); + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + uint32_t ray_type_count = globals->ray_type_count; + uint32_t entry_index = (ray_type_count * material) + ray_ptr->ray_type; + IntersectionInput GLOBAL_SPACE* intersect_input = reinterpret_cast(variable_block); + uint8_t GLOBAL_SPACE* offsets_start = reinterpret_cast(byte_offset(intersect_input, intersect_input->materials_start)); + uint32_t anyhit_result = call_raytracing_fn_inner( + global_state, + offsets_start, + entry_index, + launch_idx, + dim_idx, + ray_ptr, + current_time, + payload, + // TODO: double check + *potential_distance, + make_float2(0.0, 0.0).data, + zluda_float3(ZLUDA_NAN), + attribute_block, + transform_block + ); + *intersection_result = anyhit_result + 1; + if (anyhit_result != 1) { + *new_distance = *potential_distance; + *material_result = material; + } + return anyhit_result != 1; + } + + __attribute__((always_inline)) uint64_t FUNC(_rt_callable_program_from_id_64)( + uint32_t program, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + uint32_t program_offset = globals->callable_programs[program - 1]; + return reinterpret_cast(reinterpret_cast(globals->callable_programs) + program_offset); + } + + __attribute__((always_inline)) uint64_t FUNC(_rt_callable_program_from_id_v2_64)( + uint32_t program, + uint64_t unused __attribute__((unused)), + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + return ZLUDA_RT(_rt_callable_program_from_id_64)(program, global_state); + } + + float4_struct FUNC(_rt_texture_get_f_id)( + unsigned int tex, + unsigned int dim, + float x, + float y, + float z, + float w __attribute__((unused)), + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + hipTextureObject_t tex_object = globals->textures[tex - 1]; + float4 result; + switch (dim) + { + case 1: + result = tex1D(tex_object, x); + break; + case 2: + result = tex2D(tex_object, x, y); + break; + case 3: + result = tex3D(tex_object, x, y, z); + break; + default: + __builtin_unreachable(); + } + return float4_struct{result.x, result.y, result.z, result.w}; + } + + uint32_t FUNC(_rt_is_triangle_hit)(zluda_float3 normals) + { + return !__builtin_isnan(normals[0]); + } + + __device__ static inline float ZLUDA_RT(dot3)(float3 p0, zluda_float3 p1) + { + return __builtin_fmaf(p0.z, p1[2], __builtin_fmaf(p0.y, p1[1], p0.x*p1[0])); + } + + uint32_t FUNC(_rt_is_triangle_hit_front_face)(uint8_t (PRIVATE_SPACE* current_ray)[36], zluda_float3 normals) + { + OptixRay* optix_ray = (OptixRay*)reinterpret_cast(current_ray); + return !__builtin_isnan(normals[0]) && ZLUDA_RT(dot3)(optix_ray->direction, normals) < 0.0f; + } + + uint32_t FUNC(_rt_is_triangle_hit_back_face)(uint8_t (PRIVATE_SPACE* current_ray)[36], zluda_float3 normals) + { + OptixRay* optix_ray = (OptixRay*)reinterpret_cast(current_ray); + return !__builtin_isnan(normals[0]) && ZLUDA_RT(dot3)(optix_ray->direction, normals) > 0.0f; + } + + struct transform_result + { + float x0, x1, x2, x3, + x4, x5, x6, x7, + x8, x9, x10, x11, + x12, x13, x14, x15; + }; + transform_result FUNC(_rt_get_transform)(uint32_t kind, uint8_t GLOBAL_SPACE* transform_block) + { + if (transform_block == nullptr) + { + return transform_result + { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + } + OptixTransform GLOBAL_SPACE* optix_transform = reinterpret_cast(transform_block); + if(kind == 3841) + { + float GLOBAL_SPACE* m = optix_transform->transform_matrix; + return transform_result{ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15] }; + } + else if (kind == 3840) + { + float GLOBAL_SPACE* m = optix_transform->inverse_transform_matrix; + return transform_result{ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15] }; + } + else + { + transform_result result = {}; + return result; + } + } + + float4_struct FUNC(_rt_texture_grad_load_or_request_f_id)( + unsigned int tex, + unsigned int dim, + float x, + float y, + float z, + float w __attribute__((unused)), + float dPdx_x, + float dPdx_y, + float dPdx_z, + float dPdy_x, + float dPdy_y, + float dPdy_z, + uint64_t isResident, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + hipTextureObject_t tex_object = globals->textures[tex - 1]; + float4 result; + switch (dim) + { + case 1: + result = tex1DGrad(tex_object, x, dPdx_x, dPdy_x); + break; + case 2: + result = tex2DGrad(tex_object, x, y, float2(dPdx_x, dPdx_y), float2(dPdy_x, dPdy_y)); + break; + case 3: + result = tex3DGrad(tex_object, x, y, z, float4(dPdx_x, dPdx_y, dPdx_z, 0.0), float4(dPdy_x, dPdy_y, dPdy_z, 0.0)); + break; + default: + __builtin_unreachable(); + } + *((uint8_t*)isResident) = 1; + return float4_struct{result.x, result.y, result.z, result.w}; + } + + float4_struct FUNC(_rt_texture_lod_load_or_request_f_id)( + unsigned int tex, + unsigned int dim, + float x, + float y, + float z, + float w __attribute__((unused)), + float level __attribute__((unused)), // TODO: respect lod argument when HIP fixes mipmapped arrays + uint64_t isResident, + /* vvv INJECTED vvv */ + uint8_t SHARED_SPACE* global_state + ) { + GlobalState SHARED_SPACE* globals = (GlobalState SHARED_SPACE*)global_state; + hipTextureObject_t tex_object = globals->textures[tex - 1]; + float4 result; + switch (dim) + { + case 1: + result = tex1D(tex_object, x); + break; + case 2: + result = tex2D(tex_object, x, y); + break; + case 3: + result = tex3D(tex_object, x, y, z); + break; + default: + __builtin_unreachable(); + } + *((uint8_t*)isResident) = 1; + return float4_struct{result.x, result.y, result.z, result.w}; + } + + // _ _ _ ___ _ __ _ _ ___ ___ _____ + // | || | /_\ / __| |/ / /_\ | | | __| _ \_ _| + // | __ |/ _ \ (__| ' < / _ \| |__| _|| / | | + // |_||_/_/ \_\___|_|\_\ /_/ \_\____|___|_|_\ |_| + // + // Normal ZLUDA tex functions operate on texturereferences, we do a special + // override here to operate on textureobjects. + // This is temporary until we fix ZLUDA tex functions to also use + // textureobjects + +#define tex_1d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + return tex1Dfetch(textureObject, int(x.x)).data; \ + } + + __device__ half4 __ockl_image_loadh_1Db(unsigned int CONSTANT_SPACE *i, int c); +#define tex_1d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_1d_v4_f16_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##1 ::Native_vec_ x) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + (void)s; \ + return __ockl_image_loadh_1Db(i, int(x.x)); \ + } + + tex_1d(u32, uint, s32, int); + tex_1d(u32, uint, f32, float); + tex_1d(s32, int, s32, int); + tex_1d(s32, int, f32, float); + tex_1d(f32, float, s32, int); + tex_1d(f32, float, f32, float); + tex_1d_f16(s32, int); + tex_1d_f16(f32, float); + +#define tex_2d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + return tex2D(textureObject, float(coord.x), float(coord.y)).data; \ + } + + __device__ half4 __ockl_image_sampleh_2D(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float2::Native_vec_ c); +#define tex_2d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_2d_v4_f16_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##2 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2D(i, s, (float2){float(coord.x), float(coord.y)}.data); \ + } + + tex_2d(u32, uint, s32, int); + tex_2d(u32, uint, f32, float); + tex_2d(s32, int, s32, int); + tex_2d(s32, int, f32, float); + tex_2d(f32, float, s32, int); + tex_2d(f32, float, f32, float); + tex_2d_f16(s32, int); + tex_2d_f16(f32, float); + +#define tex_3d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_3d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + return tex3D(textureObject, float(coord.x), float(coord.y), float(coord.z)).data; \ + } + + __device__ half4 __ockl_image_sampleh_3D(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float4::Native_vec_ c); +#define tex_3d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_3d_v4_f16_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, HIP_COORD_TYPE##4 ::Native_vec_ coord) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_3D(i, s, (float4){float(coord.x), float(coord.y), float(coord.z), float(coord.w)}.data); \ + } + + tex_3d(u32, uint, s32, int); + tex_3d(u32, uint, f32, float); + tex_3d(s32, int, s32, int); + tex_3d(s32, int, f32, float); + tex_3d(f32, float, s32, int); + tex_3d(f32, float, f32, float); + tex_3d_f16(s32, int); + tex_3d_f16(f32, float); + +#define tex_a1d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_a1d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + return tex1DLayered(textureObject, float(x), int(layer)).data; \ + } + + __device__ half4 __ockl_image_sampleh_1Da(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float2::Native_vec_ c); +#define tex_a1d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_a1d_v4_f16_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, uint32_t layer, HIP_COORD_TYPE x) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_1Da(i, s, (float2){float(x), float(layer)}.data); \ + } + + tex_a1d(u32, uint, s32, int); + tex_a1d(u32, uint, f32, float); + tex_a1d(s32, int, s32, int); + tex_a1d(s32, int, f32, float); + tex_a1d(f32, float, s32, int); + tex_a1d(f32, float, f32, float); + tex_a1d_f16(s32, int); + tex_a1d_f16(f32, float); + +#define tex_a2d(CHANNEL_TYPE, HIP_CHANNEL_TYPE, COORD_TYPE, HIP_COORD_TYPE) \ + HIP_CHANNEL_TYPE##4 ::Native_vec_ FUNC(tex_a2d_v4_##CHANNEL_TYPE##_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + return tex2DLayered(textureObject, float(x), float(y), int(layer)).data; \ + } + + __device__ half4 __ockl_image_sampleh_2Da(unsigned int CONSTANT_SPACE *i, unsigned int ADDRESS_SPACE_CONSTANT *s, float4::Native_vec_ c); +#define tex_a2d_f16(COORD_TYPE, HIP_COORD_TYPE) \ + half4 FUNC(tex_a2d_v4_f16_##COORD_TYPE)(hipTextureObject_t GLOBAL_SPACE * texture_ptr, uint32_t layer, HIP_COORD_TYPE x, HIP_COORD_TYPE y) \ + { \ + hipTextureObject_t textureObject = *texture_ptr; \ + TEXTURE_OBJECT_PARAMETERS_INIT; \ + return __ockl_image_sampleh_2Da(i, s, (float4){float(x), float(y), float(layer), 0.0}.data); \ + } + + tex_a2d(u32, uint, s32, int); + tex_a2d(u32, uint, f32, float); + tex_a2d(s32, int, s32, int); + tex_a2d(s32, int, f32, float); + tex_a2d(f32, float, s32, int); + tex_a2d(f32, float, f32, float); + tex_a2d_f16(s32, int); + tex_a2d_f16(f32, float); +} diff --git a/ptx/src/ast.rs b/ptx/src/ast.rs index d81cd66..0281961 100644 --- a/ptx/src/ast.rs +++ b/ptx/src/ast.rs @@ -1,1406 +1,1438 @@ -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 { - 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 { - 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; - -sub_type! { - VariableLocalType { - Scalar(SizedScalarType), - Vector(SizedScalarType, u8), - Array(SizedScalarType, VecU32), - } -} - -impl TryFrom for VariableLocalType { - type Error = PtxError; - - fn try_from(value: VariableGlobalType) -> Result { - 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 { - fn unwrap_with(self, errs: &mut Vec) -> To; -} - -impl, EInto> UnwrapWithVec - for Result -{ - fn unwrap_with(self, errs: &mut Vec) -> R { - self.unwrap_or_else(|e| { - errs.push(e.into()); - R::default() - }) - } -} - -impl< - R1: Default, - EFrom1: std::convert::Into, - R2: Default, - EFrom2: std::convert::Into, - EInto, - > UnwrapWithVec for (Result, Result) -{ - fn unwrap_with(self, errs: &mut Vec) -> (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>>, -} - -pub enum Directive<'a, P: ArgParams> { - Variable(Variable), - Method(Function<'a, &'a str, Statement

>), -} - -pub enum MethodDecl<'a, ID> { - Func(Vec>, ID, Vec>), - Kernel { - name: &'a str, - in_args: Vec>, - }, -} - -pub type FnArgument = Variable; -pub type KernelArgument = Variable; - -pub struct Function<'a, ID, S> { - pub func_directive: MethodDecl<'a, ID>, - pub body: Option>, -} - -pub type ParsedFunction<'a> = Function<'a, &'a str, Statement>>; - -#[derive(PartialEq, Eq, Clone)] -pub enum FnArgumentType { - Reg(VariableRegType), - Param(VariableParamType), - Shared, -} -#[derive(PartialEq, Eq, Clone)] -pub enum KernelArgumentType { - Normal(VariableParamType), - Shared, -} - -impl From for Type { - fn from(this: KernelArgumentType) -> Self { - match this { - KernelArgumentType::Normal(typ) => typ.into(), - KernelArgumentType::Shared => { - Type::Pointer(PointerType::Scalar(ScalarType::B8), LdStateSpace::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), - Pointer(PointerType, LdStateSpace), -} - -#[derive(PartialEq, Eq, Clone)] -pub enum PointerType { - Scalar(ScalarType), - Vector(ScalarType, u8), - Array(ScalarType, VecU32), - Pointer(ScalarType, LdStateSpace), -} - -impl From for PointerType { - fn from(t: SizedScalarType) -> Self { - PointerType::Scalar(t.into()) - } -} - -impl TryFrom for SizedScalarType { - type Error = (); - - fn try_from(value: PointerType) -> Result { - 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 { - Label(P::Id), - Variable(MultiVariable), - Instruction(Option>, Instruction

), - Block(Vec>), -} - -pub struct MultiVariable { - pub var: Variable, - pub count: Option, -} - -#[derive(Clone)] -pub struct Variable { - pub align: Option, - pub v_type: T, - pub name: ID, - pub array_init: Vec, -} - -#[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 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 { - pub not: bool, - pub label: ID, -} - -pub enum Instruction { - Ld(LdDetails, Arg2Ld

), - Mov(MovDetails, Arg2Mov

), - Mul(MulDetails, Arg3

), - Add(ArithDetails, Arg3

), - Setp(SetpData, Arg4Setp

), - SetpBool(SetpBoolData, Arg5Setp

), - Not(BooleanType, Arg2

), - Bra(BraData, Arg1

), - Cvt(CvtDetails, Arg2

), - Cvta(CvtaDetails, Arg2

), - Shl(ShlType, Arg3

), - Shr(ShrType, Arg3

), - St(StData, Arg2St

), - Ret(RetData), - Call(CallInst

), - Abs(AbsDetails, Arg2

), - Mad(MulDetails, Arg4

), - Or(BooleanType, Arg3

), - Sub(ArithDetails, Arg3

), - Min(MinMaxDetails, Arg3

), - Max(MinMaxDetails, Arg3

), - Rcp(RcpDetails, Arg2

), - And(BooleanType, Arg3

), - Selp(SelpType, Arg4

), - Bar(BarDetails, Arg1Bar

), - Atom(AtomDetails, Arg3

), - AtomCas(AtomCasDetails, Arg4

), - Div(DivDetails, Arg3

), - Sqrt(SqrtDetails, Arg2

), - Rsqrt(RsqrtDetails, Arg2

), - Neg(NegDetails, Arg2

), - Sin { flush_to_zero: bool, arg: Arg2

}, - Cos { flush_to_zero: bool, arg: Arg2

}, - Lg2 { flush_to_zero: bool, arg: Arg2

}, - Ex2 { flush_to_zero: bool, arg: Arg2

}, - Clz { typ: BitType, arg: Arg2

}, - Brev { typ: BitType, arg: Arg2

}, - Popc { typ: BitType, arg: Arg2

}, - Xor { typ: BooleanType, arg: Arg3

}, - Bfe { typ: IntType, arg: Arg4

}, - Rem { typ: IntType, arg: Arg3

}, -} - -#[derive(Copy, Clone)] -pub struct MadFloatDesc {} - -#[derive(Copy, Clone)] -pub struct AbsDetails { - pub flush_to_zero: Option, - pub typ: ScalarType, -} -#[derive(Copy, Clone)] -pub struct RcpDetails { - pub rounding: Option, - pub flush_to_zero: Option, - pub is_f64: bool, -} - -pub struct CallInst { - pub uniform: bool, - pub ret_params: Vec, - pub func: P::Id, - pub param_list: Vec, -} - -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 { - pub src: P::Id, // it is a jump destination, but in terms of operands it is a source operand -} - -pub struct Arg1Bar { - pub src: P::Operand, -} - -pub struct Arg2 { - pub dst: P::Operand, - pub src: P::Operand, -} -pub struct Arg2Ld { - pub dst: P::Operand, - pub src: P::Operand, -} - -pub struct Arg2St { - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg2Mov { - pub dst: P::Operand, - pub src: P::Operand, -} - -pub struct Arg3 { - pub dst: P::Operand, - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg4 { - pub dst: P::Operand, - pub src1: P::Operand, - pub src2: P::Operand, - pub src3: P::Operand, -} - -pub struct Arg4Setp { - pub dst1: P::Id, - pub dst2: Option, - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg5Setp { - pub dst1: P::Id, - pub dst2: Option, - 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 { - Reg(Id), - RegOffset(Id, i32), - Imm(ImmediateValue), - VecMember(Id, u8), - VecPack(Vec), -} - -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 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, - 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, - pub cmp_op: SetpCompareOp, - pub bool_op: SetpBoolPostOp, -} - -pub struct BraData { - pub uniform: bool, -} - -pub enum CvtDetails { - IntFromInt(CvtIntToIntDesc), - FloatFromFloat(CvtDesc), - IntFromFloat(CvtDesc), - FloatFromInt(CvtDesc), -} - -pub struct CvtIntToIntDesc { - pub dst: IntType, - pub src: IntType, - pub saturate: bool, -} - -pub struct CvtDesc { - pub rounding: Option, - pub flush_to_zero: Option, - 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, - ) -> 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, - ) -> 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, - ) -> 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, - pub flush_to_zero: Option, - 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, - 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, - 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>), -} - -#[derive(Copy, Clone)] -pub struct SqrtDetails { - pub typ: FloatType, - pub flush_to_zero: Option, - 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, -} - -impl<'a> NumsOrArrays<'a> { - pub fn to_vec(self, typ: SizedScalarType, dimensions: &mut [u32]) -> Result, 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::(idx, str_val, radix, output)?; - } - SizedScalarType::B16 | SizedScalarType::U16 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::B32 | SizedScalarType::U32 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::B64 | SizedScalarType::U64 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::S8 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::S16 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::S32 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::S64 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::F16 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::F16x2 => todo!(), - SizedScalarType::F32 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - SizedScalarType::F64 => { - Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; - } - } - Ok(()) - } - - fn parse_and_copy_single_t( - idx: usize, - str_val: &str, - _radix: u32, // TODO: use this to properly support hex literals - output: &mut [u8], - ) -> Result<(), PtxError> - where - T::Err: Into, - { - let typed_output = unsafe { - std::slice::from_raw_parts_mut::( - output.as_mut_ptr() as *mut _, - output.len() / mem::size_of::(), - ) - }; - typed_output[idx] = str_val.parse::().map_err(|e| e.into())?; - Ok(()) - } -} - -pub enum ArrayOrPointer { - Array { dimensions: Vec, init: Vec }, - 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()); - } -} +use half::f16; +use lalrpop_util::{lexer::Token, ParseError}; +use std::alloc::Layout; +use std::{convert::From, mem, num::ParseFloatError, str::FromStr}; +use std::{marker::PhantomData, num::ParseIntError}; + +#[derive(Debug, thiserror::Error)] +pub enum PtxError { + #[error("{source}")] + ParseInt { + #[from] + source: ParseIntError, + }, + #[error("{source}")] + ParseFloat { + #[from] + source: ParseFloatError, + }, + #[error("")] + SyntaxError, + #[error("")] + NonF32Ftz, + #[error("")] + WrongArrayType, + #[error("")] + WrongVectorElement, + #[error("")] + MultiArrayVariable, + #[error("")] + ZeroDimensionArray, + #[error("")] + ArrayInitializer, + #[error("")] + ScalarInitalizer, + #[error("")] + NonScalarArray, + #[error("")] + InvalidStateSpace, + #[error("")] + BlankVariableName, + #[error("")] + NonRegPredVariable, + #[error("")] + InitializerTypeMismatch, + #[error("")] + NonExternPointer, + #[error("{start}:{end}")] + UnrecognizedStatement { start: usize, end: usize }, + #[error("{start}:{end}")] + UnrecognizedDirective { start: usize, end: usize }, + #[error("")] + NoSmVersion, + #[error("")] + UnexpectedMultivariable, + #[error("")] + ExternDefinition, +} + +// 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[] + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum BarDetails { + SyncAligned, +} + +#[derive(Eq, PartialEq, Clone, Copy)] +pub enum ReductionOp { + And, + Or, + Popc, +} + +pub trait UnwrapWithVec { + fn unwrap_with(self, errs: &mut Vec) -> To; +} + +impl, EInto> UnwrapWithVec + for Result +{ + fn unwrap_with(self, errs: &mut Vec) -> R { + self.unwrap_or_else(|e| { + errs.push(e.into()); + R::default() + }) + } +} + +impl< + R1: Default, + EFrom1: std::convert::Into, + R2: Default, + EFrom2: std::convert::Into, + EInto, + > UnwrapWithVec for (Result, Result) +{ + fn unwrap_with(self, errs: &mut Vec) -> (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 sm_version: u32, + pub directives: Vec>>, +} + +pub enum Directive<'a, P: ArgParams> { + Variable(LinkingDirective, MultiVariableDefinition), + Method(LinkingDirective, Function<'a, &'a str, Statement

>), +} + +#[derive(Hash, PartialEq, Eq, Copy, Clone)] +pub enum MethodName<'input, ID> { + Kernel(&'input str), + Func(ID), +} + +impl<'input, ID> MethodName<'input, ID> { + pub fn is_kernel(&self) -> bool { + match self { + MethodName::Kernel(..) => true, + MethodName::Func(..) => false, + } + } +} + +#[derive(Clone)] +pub struct MethodDeclaration<'input, ID> { + pub return_arguments: Vec>, + pub name: MethodName<'input, ID>, + pub input_arguments: Vec>, +} + +pub struct Function<'a, ID, S> { + pub func_directive: MethodDeclaration<'a, ID>, + pub tuning: Vec, + pub body: Option>, +} + +#[derive(PartialEq, Eq, Clone, Hash)] +pub enum Type { + // .param.b32 foo; + // -> OpTypeInt + Scalar(ScalarType), + // .param.v2.b32 foo; + // -> OpTypeVector + Vector(ScalarType, u8), + // .param.b32 foo[4]; + // -> OpTypeArray + Array(ScalarType, Vec), + /* + Variables of this type almost never exist in the original .ptx and are + usually artificially created. Some examples below: + - extern pointers to the .shared memory in the form: + .extern .shared .b32 shared_mem[]; + which we first parse as + .extern .shared .b32 shared_mem; + and then convert to an additional function parameter: + .param .ptr<.b32.shared> shared_mem; + and do a load at the start of the function (and renames inside fn): + .reg .ptr<.b32.shared> temp; + ld.param.ptr<.b32.shared> temp, [shared_mem]; + note, we don't support non-.shared extern pointers, because there's + zero use for them in the ptxas + - artifical pointers created by stateful conversion, which work + similiarly to the above + - function parameters: + foobar(.param .align 4 .b8 numbers[]) + which get parsed to + foobar(.param .align 4 .b8 numbers) + and then converted to + foobar(.reg .align 4 .ptr<.b8.param> numbers) + - ld/st with offset: + .reg.b32 x; + .param.b64 arg0; + st.param.b32 [arg0+4], x; + Yes, this code is legal and actually emitted by the NV compiler! + We convert the st to: + .reg ptr<.b64.param> temp = ptr_offset(arg0, 4); + st.param.b32 [temp], x; + */ + // .reg ptr<.b64.param> + // -> OpTypePointer Function + Pointer(ScalarType, StateSpace), + Texref, + Surfref, + // Structs exist only to support certain internal, compiler-generated patterns + Struct(Vec), +} + +#[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, +} + +impl ScalarType { + pub(crate) fn to_ptx_name(self) -> &'static str { + match self { + ScalarType::B8 => "b8", + ScalarType::B16 => "b16", + ScalarType::B32 => "b32", + ScalarType::B64 => "b64", + ScalarType::U8 => "u8", + ScalarType::U16 => "u16", + ScalarType::U32 => "u32", + ScalarType::U64 => "u64", + ScalarType::S8 => "s8", + ScalarType::S16 => "s16", + ScalarType::S32 => "s32", + ScalarType::S64 => "s64", + ScalarType::F16 => "f16", + ScalarType::F32 => "f32", + ScalarType::F64 => "f64", + ScalarType::F16x2 => "f16x2", + ScalarType::Pred => "pred", + } + } +} + +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 + } +} + +#[derive(PartialEq, Eq, Hash, Clone, Copy)] +pub enum StructField { + Scalar(ScalarType), + Vector(ScalarType, u8), +} + +impl StructField { + pub fn to_type(self) -> Type { + match self { + Self::Scalar(type_) => Type::Scalar(type_), + Self::Vector(type_, size) => Type::Vector(type_, size), + } + } +} + +pub enum Statement { + Label(P::Id), + Callprototype(Callprototype), + Variable(Vec>), + Instruction(Option>, Instruction

), + Block(Vec>), +} + +#[derive(Clone)] +pub struct Callprototype { + pub name: ID, + pub return_arguments: Vec<(Type, StateSpace)>, + pub input_arguments: Vec<(Type, StateSpace)>, +} + +#[derive(Clone)] +pub struct VariableDeclaration { + pub align: Option, + pub type_: Type, + pub state_space: StateSpace, + pub name: ID, +} + +impl VariableDeclaration { + pub fn layout(&self) -> Layout { + let layout = self.type_.layout(); + match self.align.map(|a| layout.align_to(a as usize)) { + Some(Ok(aligned_layout)) => aligned_layout, + _ => layout, + } + } +} + +#[derive(Clone)] +pub struct MultiVariableDefinition { + pub variable: VariableDeclaration, + pub suffix: Option>, +} + +#[derive(Clone)] +pub enum DeclarationSuffix { + Count(u32), + Initializer(Initializer), +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub enum StateSpace { + Reg, + Const, + Global, + Local, + Shared, + Param, + Generic, + Sreg, +} + +pub struct PredAt { + pub not: bool, + pub label: ID, +} + +pub struct BfindDetails { + pub shift: bool, + pub type_: ScalarType, +} + +pub enum Instruction { + Ld(LdDetails, Arg2Ld

), + Mov(MovDetails, Arg2Mov

), + Mul(MulDetails, Arg3

), + Add(ArithDetails, Arg3

), + AddC(CarryInDetails, Arg3

), + AddCC(ScalarType, Arg3

), + Setp(SetpData, Arg4Setp

), + SetpBool(SetpBoolData, Arg5Setp

), + Not(ScalarType, Arg2

), + Bra(BraData, Arg1

), + Cvt(CvtDetails, Arg2

), + Cvta(CvtaDetails, Arg2

), + Shl(ScalarType, Arg3

), + Shr(ScalarType, Arg3

), + St(StData, Arg2St

), + Ret(RetData), + Call(CallInst

), + Abs(AbsDetails, Arg2

), + Mad(MulDetails, Arg4

), + MadC { + type_: ScalarType, + carry_out: bool, + is_hi: bool, + arg: Arg4

, + }, + MadCC { + type_: ScalarType, + arg: Arg4

, + }, + Fma(ArithFloat, Arg4

), + Or(ScalarType, Arg3

), + Sub(ArithDetails, Arg3

), + SubC(CarryInDetails, Arg3

), + SubCC(ScalarType, Arg3

), + Min(MinMaxDetails, Arg3

), + Max(MinMaxDetails, Arg3

), + Rcp(RcpSqrtDetails, Arg2

), + Sqrt(RcpSqrtDetails, Arg2

), + And(ScalarType, Arg3

), + Selp(ScalarType, Arg4

), + Bar(BarDetails, Arg1Bar

), + BarWarp(BarDetails, Arg1Bar

), + BarRed(ReductionOp, Arg3

), + Atom(AtomDetails, Arg3

), + AtomCas(AtomCasDetails, Arg4

), + Div(DivDetails, Arg3

), + Rsqrt(RsqrtDetails, Arg2

), + Neg(NegDetails, Arg2

), + Sin { + flush_to_zero: bool, + arg: Arg2

, + }, + Cos { + flush_to_zero: bool, + arg: Arg2

, + }, + Lg2 { + flush_to_zero: bool, + arg: Arg2

, + }, + Ex2 { + flush_to_zero: bool, + arg: Arg2

, + }, + Clz { + typ: ScalarType, + arg: Arg2

, + }, + Brev { + typ: ScalarType, + arg: Arg2

, + }, + Popc { + typ: ScalarType, + arg: Arg2

, + }, + Xor { + typ: ScalarType, + arg: Arg3

, + }, + Bfe { + typ: ScalarType, + arg: Arg4

, + }, + Bfi { + typ: ScalarType, + arg: Arg5

, + }, + Rem { + typ: ScalarType, + arg: Arg3

, + }, + Prmt { + control: u16, + arg: Arg3

, + }, + PrmtSlow { + control: P::Id, + arg: Arg3

, + }, + Activemask { + arg: Arg1

, + }, + Membar { + level: MemScope, + }, + Tex(TexDetails, Arg4Tex

), + Suld(SurfaceDetails, Arg4Tex

), + Sust(SurfaceDetails, Arg4Sust

), + Shfl(ShflMode, Arg5Shfl

), + Shf(FunnelShift, Arg4

), + Vote(VoteDetails, Arg3

), + Exit, + Trap, + Brkpt, + Vshr(Arg4

), + Bfind(BfindDetails, Arg2

), + Set(SetData, Arg3

), + Dp4a(ScalarType, Arg4

), + MatchAny(Arg3

), + Red(AtomDetails, Arg2St

), + Nanosleep(Arg1

), +} + +#[derive(Copy, Clone)] + +pub struct CarryInDetails { + pub type_: ScalarType, + pub carry_out: bool, +} + +#[derive(Copy, Clone)] +pub enum ShflMode { + Up, + Down, + Bfly, + Idx, +} + +#[derive(Copy, Clone)] +pub struct VoteDetails { + pub mode: VoteMode, + pub negate_pred: bool, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum VoteMode { + Ballot, + All, + Any, + Uni, +} + +#[derive(Copy, Clone)] +pub struct MadFloatDesc {} + +#[derive(Copy, Clone)] +pub struct AbsDetails { + pub flush_to_zero: Option, + pub typ: ScalarType, +} + +#[derive(Copy, Clone)] +pub struct RcpSqrtDetails { + pub kind: RcpSqrtKind, + pub flush_to_zero: Option, + pub type_: ScalarType, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum RcpSqrtKind { + Approx, + Rounding(RoundingMode), +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct FunnelShift { + pub direction: FunnelDirection, + pub mode: ShiftNormalization, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum FunnelDirection { + Left, + Right, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum ShiftNormalization { + Wrap, + Clamp, +} + +pub struct CallInst { + pub uniform: bool, + pub ret_params: Vec, + pub func: P::Id, + pub param_list: Vec, + pub prototype: Option, +} + +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 { + pub src: P::Id, // it is a jump destination, but in terms of operands it is a source operand +} + +pub struct Arg1Bar { + pub src: P::Operand, +} + +pub struct Arg2 { + pub dst: P::Operand, + pub src: P::Operand, +} +pub struct Arg2Ld { + pub dst: P::Operand, + pub src: P::Operand, +} + +pub struct Arg2St { + pub src1: P::Operand, + pub src2: P::Operand, +} + +pub struct Arg2Mov { + pub dst: P::Operand, + pub src: P::Operand, +} + +pub struct Arg3 { + pub dst: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, +} + +pub struct Arg4 { + pub dst: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, + pub src3: P::Operand, +} + +pub struct Arg4Setp { + pub dst1: P::Id, + pub dst2: Option, + pub src1: P::Operand, + pub src2: P::Operand, +} + +pub struct Arg4Tex { + pub dst: P::Operand, + pub image: P::Operand, + pub layer: Option, + pub coordinates: P::Operand, +} + +pub struct Arg4Sust { + pub image: P::Operand, + pub coordinates: P::Operand, + pub layer: Option, + pub value: P::Operand, +} + +pub struct Arg5 { + pub dst: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, + pub src3: P::Operand, + pub src4: P::Operand, +} + +pub struct Arg5Setp { + pub dst1: P::Id, + pub dst2: Option, + pub src1: P::Operand, + pub src2: P::Operand, + pub src3: P::Operand, +} + +pub struct Arg5Shfl { + pub dst1: P::Id, + pub dst2: Option, + 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), +} + +impl ImmediateValue { + pub fn to_bytes(self) -> Vec { + match self { + ImmediateValue::U64(x) => x.to_ne_bytes().to_vec(), + ImmediateValue::S64(x) => x.to_ne_bytes().to_vec(), + ImmediateValue::F32(x) => x.to_ne_bytes().to_vec(), + ImmediateValue::F64(x) => x.to_ne_bytes().to_vec(), + } + } + + pub fn as_u8(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as u8), + ImmediateValue::S64(x) => Some(x as u8), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_i8(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as i8), + ImmediateValue::S64(x) => Some(x as i8), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_u16(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as u16), + ImmediateValue::S64(x) => Some(x as u16), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_i16(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as i16), + ImmediateValue::S64(x) => Some(x as i16), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_u32(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as u32), + ImmediateValue::S64(x) => Some(x as u32), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_i32(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as i32), + ImmediateValue::S64(x) => Some(x as i32), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_u64(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x), + ImmediateValue::S64(x) => Some(x as u64), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_i64(self) -> Option { + match self { + ImmediateValue::U64(x) => Some(x as i64), + ImmediateValue::S64(x) => Some(x), + ImmediateValue::F32(_) | ImmediateValue::F64(_) => None, + } + } + + pub fn as_f32(self) -> Option { + match self { + ImmediateValue::F32(x) => Some(x), + ImmediateValue::F64(_) | ImmediateValue::U64(_) | ImmediateValue::S64(_) => None, + } + } + + pub fn as_f64(self) -> Option { + match self { + ImmediateValue::F32(x) => Some(x as f64), + ImmediateValue::F64(x) => Some(x), + ImmediateValue::U64(_) | ImmediateValue::S64(_) => None, + } + } +} + +#[derive(Clone)] +pub enum Operand { + Reg(Id), + RegOffset(Id, i64), + Imm(ImmediateValue), + VecMember(Id, u8), + VecPack(Vec>), +} + +#[derive(Clone)] +pub enum RegOrImmediate { + Reg(Id), + Imm(ImmediateValue), +} + +pub struct LdDetails { + pub qualifier: LdStQualifier, + pub state_space: StateSpace, + pub caching: LdCacheOperator, + pub typ: Type, + pub non_coherent: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum LdStQualifier { + Weak, + Volatile, + Relaxed(MemScope), + Acquire(MemScope), + Release(MemScope), +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum MemScope { + Cta, + Gpu, + Sys, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum LdCacheOperator { + Cached, + L2Only, + Streaming, + LastUse, + Uncached, +} + +#[derive(Clone)] +pub struct MovDetails { + pub typ: Type, + // 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, + dst_width: 0, + src_width: 0, + relaxed_src2_conv: false, + } + } +} + +#[derive(Copy, Clone)] +pub struct MulIntDesc { + pub typ: ScalarType, + 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: ScalarType, + pub saturate: bool, +} + +pub struct SetpData { + pub typ: ScalarType, + pub flush_to_zero: Option, + pub cmp_op: SetpCompareOp, +} + +pub struct SetData { + pub dst_type: ScalarType, + pub src_type: ScalarType, + pub flush_to_zero: 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, + IsAnyNan, +} + +pub struct SetpBoolData { + pub base: SetpData, + pub bool_op: SetpBoolPostOp, + pub negate_src3: bool, +} + +#[derive(Clone, Copy)] +pub enum SetpBoolPostOp { + And, + Or, + Xor, +} + +pub struct BraData { + pub uniform: bool, +} + +pub enum CvtDetails { + IntFromInt(CvtIntToIntDesc), + FloatFromFloat(CvtDesc), + IntFromFloat(CvtDesc), + FloatFromInt(CvtDesc), +} + +pub struct CvtIntToIntDesc { + pub dst: ScalarType, + pub src: ScalarType, + pub saturate: bool, +} + +#[derive(Clone)] +pub struct CvtDesc { + pub rounding: Option, + pub flush_to_zero: Option, + pub saturate: bool, + pub dst: ScalarType, + pub src: ScalarType, +} + +impl CvtDetails { + pub fn new_int_from_int_checked<'err, 'input>( + saturate: bool, + dst: ScalarType, + src: ScalarType, + err: &'err mut Vec, PtxError>>, + ) -> Self { + if saturate { + if src.kind() == ScalarKind::Signed { + if dst.kind() == ScalarKind::Signed && dst.size_of() >= src.size_of() { + err.push(ParseError::from(PtxError::SyntaxError)); + } + } else { + if dst == src || dst.size_of() >= src.size_of() { + err.push(ParseError::from(PtxError::SyntaxError)); + } + } + } + CvtDetails::IntFromInt(CvtIntToIntDesc { dst, src, saturate }) + } + + pub fn new_float_from_int_checked<'err, 'input>( + rounding: RoundingMode, + flush_to_zero: bool, + saturate: bool, + dst: ScalarType, + src: ScalarType, + err: &'err mut Vec, PtxError>>, + ) -> Self { + if flush_to_zero && dst != ScalarType::F32 { + err.push(ParseError::from(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<'err, 'input>( + rounding: RoundingMode, + flush_to_zero: bool, + saturate: bool, + dst: ScalarType, + src: ScalarType, + err: &'err mut Vec, PtxError>>, + ) -> Self { + if flush_to_zero && src != ScalarType::F32 { + err.push(ParseError::from(PtxError::NonF32Ftz)); + } + CvtDetails::IntFromFloat(CvtDesc { + dst, + src, + saturate, + flush_to_zero: Some(flush_to_zero), + rounding: Some(rounding), + }) + } +} + +pub struct CvtaDetails { + pub to: StateSpace, + pub from: StateSpace, + pub size: CvtaSize, +} + +#[derive(Clone, Copy)] +pub enum CvtaSize { + U32, + U64, +} + +pub struct StData { + pub qualifier: LdStQualifier, + pub state_space: StateSpace, + pub caching: StCacheOperator, + pub typ: Type, +} + +#[derive(PartialEq, Eq)] +pub enum StCacheOperator { + Writeback, + L2Only, + Streaming, + Writethrough, +} + +#[derive(Copy, Clone)] +pub struct RetData { + pub uniform: bool, +} + +#[derive(Copy, Clone)] +pub enum MulDetails { + Unsigned(MulInt), + Signed(MulInt), + Float(ArithFloat), +} + +#[derive(Copy, Clone)] +pub struct MulInt { + pub typ: ScalarType, + pub control: MulIntControl, +} + +#[derive(Copy, Clone)] +pub enum ArithDetails { + Unsigned(ScalarType), + Signed(ArithSInt), + Float(ArithFloat), +} + +#[derive(Copy, Clone)] +pub struct ArithSInt { + pub typ: ScalarType, + pub saturate: bool, +} + +#[derive(Copy, Clone)] +pub struct ArithFloat { + pub typ: ScalarType, + pub rounding: Option, + pub flush_to_zero: Option, + pub saturate: bool, +} + +#[derive(Copy, Clone)] +pub enum MinMaxDetails { + Signed(ScalarType), + Unsigned(ScalarType), + Float(MinMaxFloat), +} + +#[derive(Copy, Clone)] +pub struct MinMaxFloat { + pub flush_to_zero: Option, + pub nan: bool, + pub typ: ScalarType, +} + +#[derive(Copy, Clone)] +pub struct AtomDetails { + pub semantics: AtomSemantics, + pub scope: MemScope, + pub space: StateSpace, + pub inner: AtomInnerDetails, +} + +#[derive(Copy, Clone)] +pub enum AtomSemantics { + Relaxed, + Acquire, + Release, + AcquireRelease, +} + +#[derive(Copy, Clone)] +pub enum AtomInnerDetails { + Bit { op: AtomBitOp, typ: ScalarType }, + Unsigned { op: AtomUIntOp, typ: ScalarType }, + Signed { op: AtomSIntOp, typ: ScalarType }, + Float { op: AtomFloatOp, typ: ScalarType }, +} + +#[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: StateSpace, + pub typ: ScalarType, +} + +#[derive(Copy, Clone)] +pub enum DivDetails { + Unsigned(ScalarType), + Signed(ScalarType), + Float(DivFloatDetails), +} + +#[derive(Copy, Clone)] +pub struct DivFloatDetails { + pub typ: ScalarType, + pub flush_to_zero: Option, + 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>), +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct RsqrtDetails { + pub typ: ScalarType, + pub flush_to_zero: bool, +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct NegDetails { + pub typ: ScalarType, + pub flush_to_zero: Option, +} + +impl<'a> NumsOrArrays<'a> { + pub fn to_vec(self, typ: ScalarType, dimensions: &mut [u32]) -> Result, 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: ScalarType, + 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: ScalarType, + idx: usize, + str_val: &str, + radix: u32, + output: &mut [u8], + ) -> Result<(), PtxError> { + match t { + ScalarType::B8 | ScalarType::U8 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::B16 | ScalarType::U16 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::B32 | ScalarType::U32 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::B64 | ScalarType::U64 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::S8 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::S16 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::S32 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::S64 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::F16 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::F16x2 => todo!(), + ScalarType::F32 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::F64 => { + Self::parse_and_copy_single_t::(idx, str_val, radix, output)?; + } + ScalarType::Pred => todo!(), + } + Ok(()) + } + + fn parse_and_copy_single_t( + idx: usize, + str_val: &str, + _radix: u32, // TODO: use this to properly support hex literals + output: &mut [u8], + ) -> Result<(), PtxError> + where + T::Err: Into, + { + let typed_output = unsafe { + std::slice::from_raw_parts_mut::( + output.as_mut_ptr() as *mut _, + output.len() / mem::size_of::(), + ) + }; + typed_output[idx] = str_val.parse::().map_err(|e| e.into())?; + Ok(()) + } +} + +pub enum ArrayOrPointer { + Array { dimensions: Vec, init: Vec }, + Pointer, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum LinkingDirective { + None, + Extern, + Visible, + Weak, + Common, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum TuningDirective { + MaxNReg(u32), + MaxNtid(u32, u32, u32), + ReqNtid(u32, u32, u32), + MinNCtaPerSm(u32), +} + +#[repr(u8)] +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum ScalarKind { + Bit, + Unsigned, + Signed, + Float, + Float2, + Pred, +} + +impl ScalarType { + pub fn kind(self) -> ScalarKind { + match self { + ScalarType::U8 => ScalarKind::Unsigned, + ScalarType::U16 => ScalarKind::Unsigned, + ScalarType::U32 => ScalarKind::Unsigned, + ScalarType::U64 => ScalarKind::Unsigned, + ScalarType::S8 => ScalarKind::Signed, + ScalarType::S16 => ScalarKind::Signed, + ScalarType::S32 => ScalarKind::Signed, + ScalarType::S64 => ScalarKind::Signed, + ScalarType::B8 => ScalarKind::Bit, + ScalarType::B16 => ScalarKind::Bit, + ScalarType::B32 => ScalarKind::Bit, + ScalarType::B64 => ScalarKind::Bit, + ScalarType::F16 => ScalarKind::Float, + ScalarType::F32 => ScalarKind::Float, + ScalarType::F64 => ScalarKind::Float, + ScalarType::F16x2 => ScalarKind::Float2, + ScalarType::Pred => ScalarKind::Pred, + } + } +} + +pub struct TexDetails { + pub geometry: TextureGeometry, + pub channel_type: ScalarType, + pub coordinate_type: ScalarType, + // direct = takes .texref, indirect = takes .u64 + pub direct: bool, +} + +pub struct SurfaceDetails { + pub geometry: TextureGeometry, + pub vector: Option, + pub type_: ScalarType, + // direct = takes .texref, indirect = takes .u64 + pub direct: bool, +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum TextureGeometry { + OneD, + TwoD, + ThreeD, + Array1D, + Array2D, +} + +#[derive(Clone)] +pub enum Initializer { + Constant(ImmediateValue), + Global(ID, Type), + GenericGlobal(ID, Type), + Add(Box<(Initializer, Initializer)>), + Array(Vec>), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn array_fails_multiple_0_dmiensions() { + let inp = NumsOrArrays::Nums(Vec::new()); + assert!(inp.to_vec(ScalarType::B8, &mut vec![0, 0]).is_err()); + } + + #[test] + fn array_fails_on_empty() { + let inp = NumsOrArrays::Nums(Vec::new()); + assert!(inp.to_vec(ScalarType::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(ScalarType::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(ScalarType::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(ScalarType::B8, &mut dimensions).is_err()); + } +} diff --git a/ptx/src/emit.rs b/ptx/src/emit.rs new file mode 100644 index 0000000..89fce11 --- /dev/null +++ b/ptx/src/emit.rs @@ -0,0 +1,3868 @@ +use hip_common::CompilationMode; +use rustc_hash::FxHashMap; +use std::borrow::Cow; +use std::collections::HashMap; +use std::convert::TryInto; +use std::ffi::CStr; +use std::fmt::Display; +use std::io::Write; +use std::ptr::null_mut; +use std::{convert, iter, mem, ptr}; +use zluda_llvm::core::*; +use zluda_llvm::prelude::*; +use zluda_llvm::zluda::*; +use zluda_llvm::*; + +use crate::translate::{ + self, Arg4CarryOut, ConstType, ConversionKind, DenormSummary, ExpandedArgParams, FPDenormMode, + MadCCDetails, MadCDetails, TranslationModule, TypeKind, TypeParts, +}; +use crate::translate::{Id, IdGenerator}; +use crate::{ + ast::{self, LinkingDirective}, + llvm, + translate::Directive, + TranslateError, +}; + +const LLVM_UNNAMED: *const i8 = b"\0".as_ptr() as *const i8; +const TEXREF_UNDERLYING: *const i8 = b"struct.textureReference\0".as_ptr() as *const i8; + +struct EmitContext<'a> { + context: &'a llvm::Context, + module: &'a llvm::Module, + builder: llvm::Builder, + texref_underlying_type: LLVMTypeRef, + constants: Constants, + names: NamedIdGenerator, + denorm_statistics: FxHashMap, + compilation_mode: CompilationMode, +} + +impl<'a> EmitContext<'a> { + fn new<'input>( + context: &'a llvm::Context, + module: &'a llvm::Module, + id_gen: IdGenerator, + id_defs: &FxHashMap>, + directive: &[Directive<'input>], + denorm_statistics: FxHashMap, + compilation_mode: CompilationMode, + ) -> Self { + let builder = unsafe { llvm::Builder::create(context.get()) }; + let texref_underlying_type = + unsafe { LLVMStructCreateNamed(context.get(), TEXREF_UNDERLYING) }; + EmitContext { + context, + module, + builder, + texref_underlying_type, + constants: Constants::amdgpu(), + names: NamedIdGenerator::new(id_gen, id_defs, directive), + denorm_statistics, + compilation_mode, + } + } +} + +struct NamedIdGenerator { + id_gen: IdGenerator, + names: Vec, + name_override: HashMap>, + value_refs: Vec, +} + +impl NamedIdGenerator { + fn new<'input>( + id_gen: IdGenerator, + id_defs: &FxHashMap>, + directives: &[Directive<'input>], + ) -> Self { + let mut names = Vec::new(); + for id in 1..(id_gen.next.get()) { + write!(names, "{}\0", id).unwrap(); + } + let name_override = + id_defs + .iter() + .map(|(func_id, func_name)| (*func_id, clone_and_append_trailing_nul(&func_name))) + .chain(directives.iter().filter_map(|directive| match directive { + Directive::Method(method) => method.source_name.as_ref().map(|source_name| { + (method.name, clone_and_append_trailing_nul(&*source_name)) + }), + translate::TranslationDirective::Variable(_, Some(compiled_name), var) => { + Some((var.name, clone_and_append_trailing_nul(compiled_name))) + } + _ => None, + })) + .collect(); + let value_refs = vec![ptr::null_mut(); (id_gen.next.get() - 1) as usize]; + Self { + names, + id_gen, + name_override, + value_refs, + } + } + + fn name_ptr(&self, id: Id) -> *const i8 { + self.name(id).as_ptr() + } + + fn name<'a>(&'a self, id: Id) -> &'a [i8] { + if let Some(name) = self.name_override.get(&id) { + // Skip trailing NUL + return &name[..name.len() - 1]; + } + let id = id.get(); + let digits_lower = (id as f64).log10() as usize; + let length_of_digits_below = 10usize.pow(digits_lower as u32) * digits_lower + - ((10usize.pow(digits_lower as u32) + 1) / 9); + let length_of_digits_above = + (digits_lower + 1) * (id as usize - 10usize.pow(digits_lower as u32)); + let offset = length_of_digits_below + length_of_digits_above + id as usize - 1; + unsafe { + std::slice::from_raw_parts(self.names.as_ptr().add(offset) as _, digits_lower + 1) + } + } + + fn next(&mut self) -> Id { + let result = self.id_gen.next(); + write!(self.names, "{}\0", result.get()).unwrap(); + self.value_refs.push(ptr::null_mut()); + result + } + + fn register(&mut self, id: Id, val: LLVMValueRef) { + self.value_refs[(id.get() - 1) as usize] = val; + } + + fn register_result( + &mut self, + id: Id, + func: impl FnOnce(*const i8) -> LLVMValueRef, + ) -> LLVMValueRef { + let name = self.name_ptr(id); + let result = func(name); + self.register(id, result); + result + } + + fn register_result_option( + &mut self, + id: Option, + func: impl FnOnce(*const i8) -> LLVMValueRef, + ) -> LLVMValueRef { + if let Some(id) = id { + self.register_result(id, func) + } else { + func(b"\0".as_ptr() as _) + } + } + + fn value(&self, id: Id) -> Result { + self.try_value(id).ok_or_else(TranslateError::unreachable) + } + + fn try_value(&self, id: Id) -> Option { + let ptr = self.value_refs[(id.get() - 1) as usize]; + if ptr == null_mut() { + None + } else { + Some(ptr) + } + } +} + +fn clone_and_append_trailing_nul(s: &str) -> Vec { + let mut string = s.as_bytes().to_owned(); + string.push(b'\0'); + let ptr = string.as_mut_ptr() as _; + let len = string.len(); + let capacity = string.capacity(); + mem::forget(string); + unsafe { Vec::from_raw_parts(ptr, len, capacity) } +} + +struct Constants { + data_layout: &'static [u8], + target_triple: &'static [u8], + generic_space: u32, + global_space: u32, + shared_space: u32, + constant_space: u32, + private_space: u32, + kernel_callconv: LLVMCallConv, + function_callconv: LLVMCallConv, +} + +impl Constants { + // https://llvm.org/docs/AMDGPUUsage.html + fn amdgpu() -> Self { + Self { + data_layout: b"e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7\0", + target_triple: b"amdgcn-amd-amdhsa\0", + generic_space: 0, + global_space: 1, + shared_space: 3, + constant_space: 4, + private_space: 5, + kernel_callconv: LLVMCallConv::LLVMAMDGPUKERNELCallConv, + function_callconv: LLVMCallConv::LLVMCCallConv + } + } +} + +pub(crate) unsafe fn emit_llvm_bitcode_and_linker_module<'input>( + module: TranslationModule<'input, ExpandedArgParams>, + denorm_statistics: FxHashMap, +) -> Result<(llvm::Context, llvm::Module), TranslateError> { + let context = llvm::Context::create(); + LLVMContextSetOpaquePointers(context.get(), 1); + let llvm_module = llvm::Module::create(b"\0".as_ptr() as _, context.get()); + { + let mut emit_ctx = EmitContext::new( + &context, + &llvm_module, + module.id_defs.id_gen, + &module.id_defs.globals.reverse_variables, + &module.directives, + denorm_statistics, + module.compilation_mode, + ); + emit_prelude(&mut emit_ctx); + for d in module.directives { + emit_directive(&mut emit_ctx, d)?; + } + } + if cfg!(debug_assertions) { + if let Some(error_msg) = llvm_module.verify() { + LLVMDumpModule(llvm_module.get()); + return Err(TranslateError::l_l_v_m(error_msg)); + } + } + Ok((context, llvm_module)) +} + +pub(crate) fn emit_section(section_name: &str, metadata: &[u8], text_buffer: &mut Vec) { + writeln!(text_buffer, ".section {}", section_name).ok(); + writeln!(text_buffer, ".p2align 3").ok(); + let mut chunks = metadata.chunks_exact(std::mem::size_of::()); + { + if let Some(qword) = chunks.next() { + let qword = u64::from_le_bytes(qword.try_into().unwrap()); + write!(text_buffer, ".quad {:#x}", qword).ok(); + for qword in &mut chunks { + let qword = u64::from_le_bytes(qword.try_into().unwrap()); + write!(text_buffer, ",{:#x}", qword).ok(); + } + writeln!(text_buffer, "").ok(); + } + } + let mut remainder = chunks.remainder().iter().copied(); + if let Some(byte) = remainder.next() { + write!(text_buffer, ".byte {:#x}", byte).ok(); + for byte in remainder { + write!(text_buffer, ",{:#x}", byte).ok(); + } + writeln!(text_buffer, "").ok(); + } +} + +unsafe fn emit_prelude(ctx: &mut EmitContext) { + LLVMSetDataLayout(ctx.module.get(), ctx.constants.data_layout.as_ptr() as _); + LLVMSetTarget(ctx.module.get(), ctx.constants.target_triple.as_ptr() as _); +} + +unsafe fn emit_directive<'a, 'input>( + ctx: &mut EmitContext<'a>, + d: Directive<'input>, +) -> Result<(), TranslateError> { + Ok(match d { + Directive::Variable(linking, compiled_name, variable) => { + emit_global_variable(ctx, linking, variable, compiled_name.is_some())? + } + Directive::Method(m) => emit_method(ctx, m)?, + }) +} + +unsafe fn emit_global_variable( + ctx: &mut EmitContext, + linking: LinkingDirective, + variable: translate::Variable, + globally_visible: bool, +) -> Result<(), TranslateError> { + let module = ctx.module.get(); + let llvm_type = get_llvm_type(ctx, &variable.type_)?; + let address_space = get_llvm_address_space(&ctx.constants, variable.state_space)?; + let value = match ctx.names.try_value(variable.name) { + Some(value) => { + if linking == ast::LinkingDirective::Extern { + return Ok(()); + } + value + } + None => ctx.names.register_result(variable.name, |mut name| { + // HACK ALERT + // For whatever reason if there's a global variable named __unnamed_1 AMDGPU falls on its face + if CStr::from_ptr(name) + .to_string_lossy() + .starts_with("__unnamed_") + { + name = LLVM_UNNAMED; + } + // HACK ALERT + // Autogenerated globals that hold string content, done to avoid name clash during linking + if CStr::from_ptr(name).to_string_lossy().starts_with("$str") { + name = LLVM_UNNAMED; + } + LLVMAddGlobalInAddressSpace(module, llvm_type, name, address_space) + }), + }; + emit_linkage_for_variable(variable.state_space, value, globally_visible)?; + emit_init( + ctx, + value, + linking, + &variable.type_, + variable.state_space, + variable.initializer, + )?; + emit_alignment(value, variable.align); + match variable.state_space { + ast::StateSpace::Const | ast::StateSpace::Global | ast::StateSpace::Generic => { + LLVMSetExternallyInitialized(value, 1); + } + ast::StateSpace::Reg + | ast::StateSpace::Local + | ast::StateSpace::Shared + | ast::StateSpace::Param + | ast::StateSpace::Sreg => {} + } + if variable.type_ == ast::Type::Texref || variable.type_ == ast::Type::Surfref { + LLVMSetExternallyInitialized(value, 1); + LLVMSetAlignment(value, mem::size_of::() as u32); + } + Ok(()) +} + +fn emit_alignment(value: LLVMValueRef, align: Option) { + if let Some(align) = align { + unsafe { LLVMSetAlignment(value, align) }; + } +} + +unsafe fn emit_init( + ctx: &mut EmitContext, + value_ref: LLVMValueRef, + linking: ast::LinkingDirective, + type_: &ast::Type, + space: ast::StateSpace, + initializer: Option>, +) -> Result<(), TranslateError> { + // .shared can't be const-initialized + let const_value = if space == ast::StateSpace::Shared { + if linking == ast::LinkingDirective::Extern { + return Ok(()); + } else { + LLVMGetUndef(get_llvm_type(ctx, type_)?) + } + } else { + get_llvm_const(ctx, ConstType::Type(type_), initializer)? + }; + LLVMSetInitializer(value_ref, const_value); + Ok(()) +} + +unsafe fn get_llvm_const( + ctx: &mut EmitContext, + type_: ConstType, + initalizer: Option>, +) -> Result { + let const_value = match (type_, initalizer) { + (ConstType::Type(type_), None) => LLVMConstNull(get_llvm_type(ctx, type_)?), + (ConstType::ArraySubtype(type_, dimensions), None) => LLVMConstNull(get_llvm_array_type( + get_llvm_type(ctx, &ast::Type::Scalar(type_))?, + dimensions, + )), + (ConstType::Type(ast::Type::Scalar(scalar_type)), Some(ast::Initializer::Constant(x))) => { + get_llvm_const_scalar(ctx, *scalar_type, x)? + } + ( + ConstType::Type(ast::Type::Array(scalar_type, dimensions)), + Some(ast::Initializer::Array(array)), + ) => get_llvm_const_array(ctx, *scalar_type, &dimensions, array)?, + ( + ConstType::ArraySubtype(scalar_type, dimensions), + Some(ast::Initializer::Array(array)), + ) => get_llvm_const_array(ctx, scalar_type, dimensions, array)?, + (type_, Some(ast::Initializer::Add(add))) => { + let (init1, init2) = *add; + let const1 = get_llvm_const(ctx, type_, Some(init1))?; + let const2 = get_llvm_const(ctx, type_, Some(init2))?; + LLVMConstAdd(const1, const2) + } + (_, Some(ast::Initializer::Global(id, type_))) => { + let name = ctx.names.value(id)?; + let b64 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B64))?; + let mut zero = LLVMConstInt(b64, 0, 0); + let src_type = get_llvm_type(ctx, &type_)?; + let global_ptr = LLVMConstInBoundsGEP2(src_type, name, &mut zero, 1); + LLVMConstPtrToInt(global_ptr, b64) + } + (_, Some(ast::Initializer::GenericGlobal(id, type_))) => { + let name = ctx.names.value(id)?; + let b64 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B64))?; + let mut zero = LLVMConstInt(b64, 0, 0); + let src_type = get_llvm_type(ctx, &type_)?; + let global_ptr = LLVMConstInBoundsGEP2(src_type, name, &mut zero, 1); + // void pointers are illegal in LLVM IR + let b8 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B8))?; + let b8_generic_ptr = LLVMPointerType( + b8, + get_llvm_address_space(&ctx.constants, ast::StateSpace::Generic)?, + ); + let generic_ptr = LLVMConstAddrSpaceCast(global_ptr, b8_generic_ptr); + LLVMConstPtrToInt(generic_ptr, b64) + } + _ => return Err(TranslateError::todo()), + }; + Ok(const_value) +} + +unsafe fn get_llvm_const_scalar( + ctx: &mut EmitContext, + scalar_type: ast::ScalarType, + constant: ast::ImmediateValue, +) -> Result { + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(scalar_type))?; + Ok(match scalar_type.kind() { + ast::ScalarKind::Pred + | ast::ScalarKind::Bit + | ast::ScalarKind::Unsigned + | ast::ScalarKind::Signed => LLVMConstInt( + llvm_type, + constant + .as_u64() + .ok_or_else(TranslateError::mismatched_type)?, + 0, + ), + ast::ScalarKind::Float => LLVMConstReal( + llvm_type, + constant + .as_f64() + .ok_or_else(TranslateError::mismatched_type)?, + ), + ast::ScalarKind::Float2 => return Err(TranslateError::todo()), + }) +} + +unsafe fn get_llvm_const_array( + ctx: &mut EmitContext, + scalar_type: ast::ScalarType, + dimensions: &[u32], + initializer: Vec>, +) -> Result { + let llvm_type: *mut LLVMType = get_llvm_type(ctx, &ast::Type::Scalar(scalar_type))?; + Ok(match dimensions { + [] => return Err(TranslateError::unreachable()), + [dim, rest @ ..] => { + let inner_array_type = if rest.len() == 0 { + llvm_type + } else { + get_llvm_array_type(llvm_type, rest) + }; + if initializer.len() != *dim as usize { + return Err(TranslateError::unreachable()); + } + let mut subinits = initializer + .into_iter() + .map(|inner_initalizer| { + if rest.len() == 0 { + get_llvm_const( + ctx, + ConstType::Type(&ast::Type::Scalar(scalar_type)), + Some(inner_initalizer), + ) + } else { + get_llvm_const( + ctx, + ConstType::ArraySubtype(scalar_type, rest), + Some(inner_initalizer), + ) + } + }) + .collect::, _>>()?; + LLVMConstArray(inner_array_type, subinits.as_mut_ptr(), *dim) + } + }) +} + +fn emit_function_variable( + ctx: &mut EmitContext, + variable: translate::Variable, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let llvm_type = get_llvm_type(ctx, &variable.type_)?; + let addr_space = get_llvm_address_space(&ctx.constants, variable.state_space)?; + let value = ctx.names.register_result(variable.name, |name| unsafe { + LLVMZludaBuildAlloca(builder, llvm_type, addr_space, name) + }); + match variable.initializer { + None => {} + Some(init) => { + let constant = + unsafe { get_llvm_const(ctx, ConstType::Type(&variable.type_), Some(init))? }; + unsafe { LLVMBuildStore(builder, constant, value) }; + } + } + // TODO: it shuld be possible to skip alignment of .param/.reg variables and get + // minimally better assembly. See if this doesn't crash anything and measure impact + emit_alignment(value, variable.align); + Ok(()) +} + +fn emit_method<'a, 'input>( + ctx: &mut EmitContext<'a>, + method: crate::translate::Function<'input>, +) -> Result<(), TranslateError> { + let is_kernel = method.is_kernel; + let llvm_method = emit_method_declaration(ctx, &method)?; + emit_linkage_for_method(&method, is_kernel, llvm_method); + emit_tuning(ctx, llvm_method, &method.tuning); + for statement in method.body.iter().flat_map(convert::identity) { + register_basic_blocks(ctx, llvm_method, statement); + } + for statement in method.body.into_iter().flatten() { + emit_statement(ctx, is_kernel, statement)?; + } + Ok(()) +} + +fn emit_tuning<'a>( + ctx: &mut EmitContext<'a>, + llvm_method: *mut LLVMValue, + tunings: &[ast::TuningDirective], +) { + for tuning in tunings { + emit_tuning_single(ctx, llvm_method, *tuning); + } +} + +fn emit_tuning_single<'a>( + ctx: &mut EmitContext<'a>, + llvm_method: *mut LLVMValue, + tuning: ast::TuningDirective, +) { + match tuning { + // TODO: measure + ast::TuningDirective::MaxNReg(_) | ast::TuningDirective::MinNCtaPerSm(_) => {} + ast::TuningDirective::MaxNtid(x, y, z) => { + let size = x as u64 * y as u64 * z as u64; + emit_llvm_string_attribute( + ctx, + llvm_method, + b"amdgpu-flat-work-group-size", + format!("1,{0}", size).as_bytes(), + ); + } + ast::TuningDirective::ReqNtid(x, y, z) => { + let size = x as u64 * y as u64 * z as u64; + emit_llvm_string_attribute( + ctx, + llvm_method, + b"amdgpu-flat-work-group-size", + format!("{0},{0}", size).as_bytes(), + ); + } + } +} + +fn register_basic_blocks( + ctx: &mut EmitContext, + llvm_method: LLVMValueRef, + statement: &crate::translate::ExpandedStatement, +) { + match statement { + crate::translate::Statement::Label(label) => { + let context = ctx.context.get(); + ctx.names.register_result(*label, |label_name| unsafe { + LLVMBasicBlockAsValue(LLVMAppendBasicBlockInContext( + context, + llvm_method, + label_name, + )) + }); + } + _ => {} + } +} + +fn emit_statement( + ctx: &mut EmitContext, + is_kernel: bool, + statement: crate::translate::ExpandedStatement, +) -> Result<(), TranslateError> { + start_synthetic_basic_block_if_needed(ctx, &statement); + Ok(match statement { + crate::translate::Statement::Label(label) => emit_label(ctx, label)?, + crate::translate::Statement::Variable(var) => emit_function_variable(ctx, var)?, + crate::translate::Statement::Instruction(inst) => emit_instruction(ctx, is_kernel, &inst)?, + crate::translate::Statement::Conditional(cond) => emit_conditional(ctx, &cond)?, + crate::translate::Statement::Call(call) => emit_call(ctx, &call)?, + crate::translate::Statement::LoadVar(load) => emit_load_var(ctx, &load)?, + crate::translate::Statement::StoreVar(store) => emit_store_var(ctx, &store)?, + crate::translate::Statement::Conversion(conv) => emit_implicit_conversion(ctx, &conv)?, + crate::translate::Statement::Constant(constant) => emit_constant(ctx, &constant)?, + crate::translate::Statement::RetValue(ret, ids) => emit_ret_value(ctx, &ret, &ids)?, + crate::translate::Statement::PtrAccess(ptr_access) => emit_ptr_access(ctx, &ptr_access)?, + crate::translate::Statement::RepackVector(repack) => emit_repack_vector(ctx, &repack)?, + crate::translate::Statement::FunctionPointer(fnptr) => emit_function_pointer(ctx, &fnptr)?, + crate::translate::Statement::MadC(MadCDetails { type_, is_hi, arg }) => { + emit_inst_madc(ctx, type_, is_hi, &arg)? + } + crate::translate::Statement::MadCC(MadCCDetails { type_, arg }) => { + emit_inst_madcc(ctx, type_, &arg)? + } + crate::translate::Statement::AddC(type_, arg) => emit_inst_add_c(ctx, type_, &arg)?, + crate::translate::Statement::AddCC(type_, arg) => { + emit_inst_addsub_cc(ctx, "add", type_, &arg)? + } + crate::translate::Statement::SubC(type_, arg) => emit_inst_sub_c(ctx, type_, &arg)?, + crate::translate::Statement::SubCC(type_, arg) => { + emit_inst_addsub_cc(ctx, "sub", type_, &arg)? + } + crate::translate::Statement::AsmVolatile { asm, constraints } => unsafe { + emit_asm_volatile(ctx, asm, constraints)? + }, + }) +} + +unsafe fn emit_asm_volatile( + ctx: &mut EmitContext, + asm: &str, + constraints: &str, +) -> Result<(), TranslateError> { + let func_type = get_llvm_function_type(ctx, llvm::void_type(ctx.context), iter::empty())?; + let asm_call = LLVMGetInlineAsm( + func_type, + asm.as_ptr() as *mut _, + asm.len(), + constraints.as_ptr().cast::() as _, + constraints.len(), + 1, + 0, + LLVMInlineAsmDialect::LLVMInlineAsmDialectATT, + 0, + ); + LLVMBuildCall2( + ctx.builder.get(), + func_type, + asm_call, + ptr::null_mut(), + 0, + LLVM_UNNAMED, + ); + Ok(()) +} + +fn emit_conditional( + ctx: &mut EmitContext, + cond: &crate::translate::BrachCondition, +) -> Result<(), TranslateError> { + let predicate = ctx.names.value(cond.predicate)?; + let if_true = unsafe { LLVMValueAsBasicBlock(ctx.names.value(cond.if_true)?) }; + let if_false = unsafe { LLVMValueAsBasicBlock(ctx.names.value(cond.if_false)?) }; + unsafe { LLVMBuildCondBr(ctx.builder.get(), predicate, if_true, if_false) }; + Ok(()) +} + +fn emit_repack_vector( + ctx: &mut EmitContext, + repack: &crate::translate::RepackVectorDetails, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let llvm_i32 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + if repack.is_extract { + let src = ctx.names.value(repack.packed)?; + for (index, dst_id) in repack.unpacked.iter().enumerate() { + let index_llvm = unsafe { LLVMConstInt(llvm_i32, index as _, 0) }; + ctx.names.register_result(*dst_id, |dst_name| unsafe { + LLVMBuildExtractElement(builder, src, index_llvm, dst_name) + }); + } + } else { + let vector_type = get_llvm_type( + ctx, + &ast::Type::Vector(repack.typ, repack.unpacked.len() as u8), + )?; + let mut temp_vec = unsafe { LLVMGetUndef(vector_type) }; + for (index, src_id) in repack.unpacked.iter().enumerate() { + let dst = if index == repack.unpacked.len() - 1 { + Some(repack.packed) + } else { + None + }; + let src = ctx.names.value(*src_id)?; + let index_llvm = unsafe { LLVMConstInt(llvm_i32, index as _, 0) }; + temp_vec = ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildInsertElement(builder, temp_vec, src, index_llvm, dst_name) + }); + } + } + Ok(()) +} + +fn emit_function_pointer( + ctx: &mut EmitContext, + fnptr: &crate::translate::FunctionPointerDetails, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src = ctx.names.value(fnptr.src)?; + let type_ = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B64))?; + ctx.names.register_result(fnptr.dst, |dst| unsafe { + LLVMBuildPtrToInt(builder, src, type_, dst) + }); + Ok(()) +} + +fn emit_ret_value( + ctx: &mut EmitContext, + _ret: &ast::RetData, + ids: &[(Id, ast::Type)], +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + if ids.len() == 1 { + let ret_value = ctx.names.value(ids[0].0)?; + unsafe { LLVMBuildRet(builder, ret_value) }; + return Ok(()); + } + let ret_type = get_llvm_type_struct(ctx, ids.iter().map(|(_, type_)| Cow::Borrowed(type_)))?; + let mut ret_value = unsafe { LLVMGetUndef(ret_type) }; + for (idx, (id, _)) in ids.iter().enumerate() { + let id = ctx.names.value(*id)?; + ret_value = + unsafe { LLVMBuildInsertValue(builder, ret_value, id, idx as u32, LLVM_UNNAMED) }; + } + unsafe { LLVMBuildRet(builder, ret_value) }; + Ok(()) +} + +fn start_synthetic_basic_block_if_needed( + ctx: &mut EmitContext, + statement: &crate::translate::ExpandedStatement, +) { + let current_block = unsafe { LLVMGetInsertBlock(ctx.builder.get()) }; + if current_block == ptr::null_mut() { + return; + } + let terminator = unsafe { LLVMGetBasicBlockTerminator(current_block) }; + if terminator == ptr::null_mut() { + return; + } + if let crate::translate::Statement::Label(..) = statement { + return; + } + let new_block = + unsafe { LLVMCreateBasicBlockInContext(ctx.context.get(), b"\0".as_ptr() as _) }; + unsafe { LLVMInsertExistingBasicBlockAfterInsertBlock(ctx.builder.get(), new_block) }; + unsafe { LLVMPositionBuilderAtEnd(ctx.builder.get(), new_block) }; +} + +fn emit_ptr_access( + ctx: &mut EmitContext, + ptr_access: &crate::translate::PtrAccess, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let ptr_id = ctx.names.value(ptr_access.ptr_src)?; + let temp1_id = ctx.names.next(); + let llvm_ptr_u8_type = get_llvm_pointer_type( + ctx, + &ast::Type::Scalar(ast::ScalarType::B8), + ptr_access.state_space, + )?; + let llvm_u8_type = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B8))?; + let underlying_ptr_llvm_type = + get_llvm_pointer_type(ctx, &ptr_access.underlying_type, ptr_access.state_space)?; + let temp1_value = ctx.names.register_result(temp1_id, |temp1_name| unsafe { + LLVMBuildPointerCast(builder, ptr_id, llvm_ptr_u8_type, temp1_name) + }); + let mut ptr_offset_id = ctx.names.value(ptr_access.offset_src)?; + let temp2_id = ctx.names.next(); + let temp2_value = ctx.names.register_result(temp2_id, |temp2_name| unsafe { + LLVMBuildInBoundsGEP2( + builder, + llvm_u8_type, + temp1_value, + &mut ptr_offset_id, + 1, + temp2_name, + ) + }); + ctx.names + .register_result(ptr_access.dst, |dst_name| unsafe { + LLVMBuildPointerCast(builder, temp2_value, underlying_ptr_llvm_type, dst_name) + }); + Ok(()) +} + +fn emit_call( + ctx: &mut EmitContext, + call: &crate::translate::ResolvedCall, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let mut args = call + .input_arguments + .iter() + .map(|(id, _, _)| ctx.names.value(*id)) + .collect::, _>>()?; + let (ret_value_name, return_type) = match &*call.return_arguments { + [] => (LLVM_UNNAMED, llvm::void_type(&ctx.context)), + [(single_return_id, type_, _)] => ( + ctx.names.name_ptr(*single_return_id), + get_llvm_type(ctx, type_)?, + ), + [..] => ( + LLVM_UNNAMED, + get_llvm_type_struct( + ctx, + call.return_arguments + .iter() + .map(|(_, type_, _)| Cow::Borrowed(type_)), + )?, + ), + }; + let function_type = get_llvm_function_type( + ctx, + return_type, + call.input_arguments + .iter() + .map(|(_, type_, state_space)| (type_, *state_space)), + )?; + let mut llvm_fn = ctx.names.value(call.name)?; + if call.is_indirect { + llvm_fn = unsafe { + LLVMBuildIntToPtr( + builder, + llvm_fn, + LLVMPointerType(function_type, ctx.constants.generic_space), + LLVM_UNNAMED, + ) + }; + } + let call_result = unsafe { + LLVMBuildCall2( + builder, + function_type, + llvm_fn, + args.as_mut_ptr(), + args.len() as u32, + ret_value_name, + ) + }; + match &*call.return_arguments { + [] => {} + [(single_return_id, _, _)] => ctx.names.register(*single_return_id, call_result), + many_return_args => { + for (idx, (id, _, _)) in many_return_args.iter().enumerate() { + ctx.names.register_result(*id, |id| unsafe { + LLVMBuildExtractValue(builder, call_result, idx as u32, id) + }); + } + } + } + Ok(()) +} + +fn emit_constant( + ctx: &mut EmitContext, + constant: &crate::translate::ConstantDefinition, +) -> Result<(), TranslateError> { + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(constant.typ))?; + let dst_value = unsafe { emit_constant_value(llvm_type, constant.value) }; + ctx.names.register(constant.dst, dst_value); + Ok(()) +} + +unsafe fn emit_constant_value(llvm_type: LLVMTypeRef, value: ast::ImmediateValue) -> LLVMValueRef { + match value { + ast::ImmediateValue::U64(x) => LLVMConstInt(llvm_type, x, 0), + ast::ImmediateValue::S64(x) => LLVMConstInt(llvm_type, x as _, 0), + ast::ImmediateValue::F32(x) => LLVMConstReal(llvm_type, x as f64), + ast::ImmediateValue::F64(x) => LLVMConstReal(llvm_type, x), + } +} + +fn emit_implicit_conversion( + ctx: &mut EmitContext, + cv: &crate::translate::ImplicitConversion, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let from_parts = cv.from_type.to_parts(); + let to_parts = cv.to_type.to_parts(); + Ok(match (from_parts.kind, to_parts.kind, &cv.kind) { + (_, _, &ConversionKind::BitToPtr) => { + let dst_type = get_llvm_pointer_type(ctx, &cv.to_type, cv.to_space)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildIntToPtr(builder, src, dst_type, dst) + }); + } + (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::Default) => { + if from_parts.width == to_parts.width { + if from_parts.scalar_kind == to_parts.scalar_kind { + // It is noop, but another instruction expects result of this conversion + emit_value_copy(ctx, &cv.to_type, ctx.names.value(cv.src)?, cv.dst)?; + } else { + let dst_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildBitCast(builder, src, dst_type, dst) + }); + } + } else { + // This block is safe because it's illegal to implictly convert between floating point values + let same_width_bit_type = get_llvm_type( + ctx, + &ast::Type::from_parts(TypeParts { + scalar_kind: ast::ScalarKind::Bit, + ..from_parts + }), + )?; + let src = ctx.names.value(cv.src)?; + let temp_id = ctx.names.next(); + let same_width_bit_value = + ctx.names.register_result(temp_id, |temp_value| unsafe { + LLVMBuildBitCast(builder, src, same_width_bit_type, temp_value) + }); + let wide_bit_type = ast::Type::from_parts(TypeParts { + scalar_kind: ast::ScalarKind::Bit, + ..to_parts + }); + let wide_bit_type_llvm = get_llvm_type(ctx, &wide_bit_type)?; + if to_parts.scalar_kind == ast::ScalarKind::Unsigned + || to_parts.scalar_kind == ast::ScalarKind::Bit + { + let conversion_fn = if to_parts.width > from_parts.width { + LLVMBuildZExt + } else { + LLVMBuildTruncOrBitCast + }; + ctx.names.register_result(cv.dst, |dst| unsafe { + conversion_fn(builder, same_width_bit_value, wide_bit_type_llvm, dst) + }); + } else { + let conversion_fn = if to_parts.width > from_parts.width { + if from_parts.scalar_kind == ast::ScalarKind::Signed + && to_parts.scalar_kind == ast::ScalarKind::Signed + { + LLVMBuildSExt + } else { + LLVMBuildZExt + } + } else { + LLVMBuildTruncOrBitCast + }; + let wide_bit_id = ctx.names.next(); + ctx.names.register_result(wide_bit_id, |dst| unsafe { + conversion_fn(builder, same_width_bit_value, wide_bit_type_llvm, dst) + }); + emit_implicit_conversion( + ctx, + &crate::translate::ImplicitConversion { + src: wide_bit_id, + dst: cv.dst, + from_type: wide_bit_type, + from_space: cv.from_space, + to_type: cv.to_type.clone(), + to_space: cv.to_space, + kind: ConversionKind::Default, + }, + )?; + } + } + } + (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::SignExtend) => { + let result_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildSExtOrBitCast(builder, src, result_type, dst) + }); + } + (TypeKind::Vector, TypeKind::Scalar, &ConversionKind::Default) + | (TypeKind::Scalar, TypeKind::Vector, &ConversionKind::Default) + | (TypeKind::Scalar, TypeKind::Array, &ConversionKind::Default) + | (TypeKind::Array, TypeKind::Scalar, &ConversionKind::Default) => { + let result_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildBitCast(builder, src, result_type, dst) + }); + } + (_, _, &ConversionKind::PtrToPtr) => { + let result_type = get_llvm_pointer_type(ctx, &cv.to_type, cv.to_space)?; + if cv.to_space == ast::StateSpace::Generic && cv.from_space != ast::StateSpace::Generic + { + let src = if cv.from_type != cv.to_type { + let pointer_from_type = get_llvm_pointer_type(ctx, &cv.to_type, cv.from_space)?; + let src = ctx.names.value(cv.src)?; + let temp_id = ctx.names.next(); + ctx.names.register_result(temp_id, |dst| unsafe { + LLVMBuildBitCast(builder, src, pointer_from_type, dst) + }) + } else { + ctx.names.value(cv.src)? + }; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildAddrSpaceCast(builder, src, result_type, dst) + }); + } else if cv.from_space == ast::StateSpace::Generic + && cv.to_space != ast::StateSpace::Generic + { + let src = if cv.from_type != cv.to_type { + let temp_type = get_llvm_pointer_type(ctx, &cv.to_type, cv.from_space)?; + let src = ctx.names.value(cv.src)?; + let temp_id = ctx.names.next(); + ctx.names.register_result(temp_id, |dst| unsafe { + LLVMBuildBitCast(builder, src, temp_type, dst) + }) + } else { + ctx.names.value(cv.src)? + }; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildAddrSpaceCast(builder, src, result_type, dst) + }); + } else { + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildBitCast(builder, src, result_type, dst) + }); + } + } + (_, _, &ConversionKind::AddressOf) => { + let dst_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildPtrToInt(builder, src, dst_type, dst) + }); + } + (TypeKind::Pointer, TypeKind::Scalar, &ConversionKind::Default) => { + let result_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildPtrToInt(builder, src, result_type, dst) + }); + } + (TypeKind::Scalar, TypeKind::Pointer, &ConversionKind::Default) => { + let result_type = get_llvm_type(ctx, &cv.to_type)?; + let src = ctx.names.value(cv.src)?; + ctx.names.register_result(cv.dst, |dst| unsafe { + LLVMBuildIntToPtr(builder, src, result_type, dst) + }); + } + _ => unreachable!(), + }) +} + +fn emit_value_copy( + ctx: &mut EmitContext, + type_: &ast::Type, + src: LLVMValueRef, + dst: Id, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let type_ = get_llvm_type(ctx, type_)?; + let temp_value = unsafe { LLVMBuildAlloca(builder, type_, LLVM_UNNAMED) }; + unsafe { LLVMBuildStore(builder, src, temp_value) }; + ctx.names.register_result(dst, |dst| unsafe { + LLVMBuildLoad2(builder, type_, temp_value, dst) + }); + Ok(()) +} + +fn emit_instruction( + ctx: &mut EmitContext, + is_kernel: bool, + inst: &ast::Instruction, +) -> Result<(), TranslateError> { + Ok(match inst { + ast::Instruction::Ld(details, args) => emit_inst_ld(ctx, details, args)?, + ast::Instruction::Mov(details, args) => emit_inst_mov(ctx, details, args)?, + ast::Instruction::Mul(details, args) => emit_inst_mul(ctx, details, args)?, + ast::Instruction::Add(details, args) => emit_inst_add(ctx, details, args)?, + ast::Instruction::Setp(details, args) => emit_inst_setp(ctx, details, args, None)?, + ast::Instruction::SetpBool(details, args) => emit_inst_setp_bool(ctx, details, args)?, + ast::Instruction::Not(type_, args) => emit_inst_not(ctx, *type_, args)?, + ast::Instruction::Bra(_, args) => emit_inst_bra(ctx, args)?, + ast::Instruction::Cvt(details, args) => emit_inst_cvt(ctx, details, args)?, + ast::Instruction::Cvta(details, args) => emit_inst_cvta(ctx, details, args)?, + ast::Instruction::Shl(type_, args) => emit_inst_shl(ctx, *type_, args)?, + ast::Instruction::Shr(type_, args) => emit_inst_shr(ctx, *type_, args)?, + ast::Instruction::St(details, args) => emit_inst_st(ctx, details, args)?, + ast::Instruction::Exit => emit_inst_exit(ctx, is_kernel)?, + ast::Instruction::Ret(_) => emit_inst_ret(ctx), + ast::Instruction::Abs(details, args) => emit_inst_abs(ctx, details, args)?, + ast::Instruction::Mad(details, args) => emit_inst_mad(ctx, details, args)?, + ast::Instruction::Fma(details, args) => emit_inst_fma(ctx, details, args)?, + ast::Instruction::Or(_, args) => emit_inst_or(ctx, args)?, + ast::Instruction::Sub(details, args) => emit_inst_sub(ctx, details, args)?, + ast::Instruction::Min(details, args) => emit_inst_min(ctx, details, args)?, + ast::Instruction::Max(details, args) => emit_inst_max(ctx, details, args)?, + ast::Instruction::Rcp(details, args) => emit_inst_rcp(ctx, details, args)?, + ast::Instruction::And(_, args) => emit_inst_and(ctx, args)?, + ast::Instruction::Selp(_, args) => emit_inst_selp(ctx, args)?, + ast::Instruction::Atom(details, args) => emit_inst_atom(ctx, details, args)?, + ast::Instruction::AtomCas(details, args) => emit_inst_atom_cas(ctx, details, args)?, + ast::Instruction::Div(details, args) => emit_inst_div(ctx, details, args)?, + ast::Instruction::Sqrt(details, args) => emit_inst_sqrt(ctx, details, args)?, + ast::Instruction::Rsqrt(details, args) => emit_inst_rsqrt(ctx, details, args)?, + ast::Instruction::Neg(details, args) => emit_inst_neg(ctx, details, args)?, + ast::Instruction::Sin { arg, .. } => emit_inst_sin(ctx, arg)?, + ast::Instruction::Cos { arg, .. } => emit_inst_cos(ctx, arg)?, + ast::Instruction::Lg2 { arg, .. } => emit_inst_lg2(ctx, arg)?, + ast::Instruction::Ex2 { arg, .. } => emit_inst_ex2(ctx, arg)?, + ast::Instruction::Clz { typ, arg } => emit_inst_clz(ctx, *typ, arg)?, + ast::Instruction::Bfind(details, arg) => emit_inst_bfind(ctx, details, arg)?, + ast::Instruction::Brev { typ, arg } => emit_inst_brev(ctx, *typ, arg)?, + ast::Instruction::Popc { typ, arg } => emit_inst_popc(ctx, *typ, arg)?, + ast::Instruction::Xor { arg, .. } => emit_inst_xor(ctx, arg)?, + ast::Instruction::Rem { typ, arg } => emit_inst_rem(ctx, *typ, arg)?, + ast::Instruction::Prmt { control, arg } => emit_inst_prmt(ctx, *control, arg)?, + ast::Instruction::PrmtSlow { .. } => return Err(TranslateError::unexpected_pattern()), + ast::Instruction::Membar { level } => emit_inst_membar(ctx, *level), + ast::Instruction::Shf(details, args) => emit_inst_shf(ctx, details, args)?, + ast::Instruction::Trap => emit_int_trap(ctx)?, + ast::Instruction::Brkpt => emit_int_brkpt(ctx)?, + ast::Instruction::BarWarp(..) => emit_inst_bar_warp(ctx)?, + ast::Instruction::Vshr(arg) => emit_inst_vshr(ctx, arg)?, + ast::Instruction::Set(details, arg) => emit_inst_set(ctx, details, arg)?, + ast::Instruction::Red(details, arg) => emit_inst_red(ctx, details, arg)?, + // replaced by function calls or Statement variants + ast::Instruction::Activemask { .. } + | ast::Instruction::Bar(..) + | ast::Instruction::BarRed(..) + | ast::Instruction::Bfe { .. } + | ast::Instruction::Bfi { .. } + | ast::Instruction::MadC { .. } + | ast::Instruction::MadCC { .. } + | ast::Instruction::AddC { .. } + | ast::Instruction::AddCC { .. } + | ast::Instruction::SubC { .. } + | ast::Instruction::SubCC { .. } + | ast::Instruction::Tex(..) + | ast::Instruction::Suld(..) + | ast::Instruction::Sust(..) + | ast::Instruction::Call(_) + | ast::Instruction::Vote { .. } + | ast::Instruction::Shfl(..) + | ast::Instruction::Dp4a(..) + | ast::Instruction::Nanosleep(..) + | ast::Instruction::MatchAny(..) => return Err(TranslateError::unreachable()), + }) +} + +fn emit_inst_red( + ctx: &mut EmitContext, + details: &ast::AtomDetails, + arg: &ast::Arg2St, +) -> Result<(), TranslateError> { + emit_inst_atom_impl(ctx, details, None, arg.src1, arg.src2) +} + +fn emit_inst_set( + ctx: &mut EmitContext, + details: &ast::SetData, + arg: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let temp_result = emit_inst_setp_float(ctx, details.cmp_op, None, arg.src1, arg.src2)?; + if details.src_type != ast::ScalarType::F16x2 || details.dst_type == ast::ScalarType::F16x2 { + return Err(TranslateError::todo()); + } + let b16vec2_type = get_llvm_type(ctx, &ast::Type::Vector(ast::ScalarType::B16, 2))?; + let b16vec2_result = unsafe { LLVMBuildSExt(builder, temp_result, b16vec2_type, LLVM_UNNAMED) }; + let u32_type = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + ctx.names.register_result(arg.dst, |dst_name| unsafe { + LLVMBuildBitCast(builder, b16vec2_result, u32_type, dst_name) + }); + Ok(()) +} + +fn emit_inst_bfind( + ctx: &mut EmitContext, + details: &ast::BfindDetails, + arg: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src = arg.src.get_llvm_value(&mut ctx.names)?; + let llvm_dst_type = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + let const_0 = unsafe { LLVMConstInt(llvm_dst_type, 0, 0) }; + let const_int_max = unsafe { LLVMConstInt(llvm_dst_type, u64::MAX, 0) }; + let is_zero = unsafe { + LLVMBuildICmp( + builder, + LLVMIntPredicate::LLVMIntEQ, + src, + const_0, + LLVM_UNNAMED, + ) + }; + let mut clz_result = emit_inst_clz_impl(ctx, ast::ScalarType::U32, None, arg.src, true)?; + if !details.shift { + let bits = unsafe { + LLVMConstInt( + llvm_dst_type, + (details.type_.size_of() as u32 * u8::BITS) as u64 - 1, + 0, + ) + }; + clz_result = unsafe { LLVMBuildSub(builder, bits, clz_result, LLVM_UNNAMED) }; + } + ctx.names.register_result(arg.dst, |dst_name| unsafe { + LLVMBuildSelect(builder, is_zero, const_int_max, clz_result, dst_name) + }); + Ok(()) +} + +fn emit_inst_vshr( + ctx: &mut EmitContext, + arg: &ast::Arg4, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let shift_result = emit_inst_shift_impl( + ctx, + ast::ScalarType::U32, + None, + arg.src1, + arg.src2, + LLVMBuildLShr, + 0, + )?; + let src3 = arg.src3.get_llvm_value(&mut ctx.names)?; + ctx.names.register_result(arg.dst, |name| unsafe { + LLVMBuildAdd(builder, shift_result, src3, name) + }); + Ok(()) +} + +fn emit_int_brkpt(ctx: &mut EmitContext) -> Result<(), TranslateError> { + emit_intrinsic_arg0(ctx, b"llvm.debugtrap\0")?; + Ok(()) +} + +fn emit_inst_bar_warp(ctx: &mut EmitContext) -> Result<(), TranslateError> { + emit_intrinsic_arg0(ctx, b"llvm.amdgcn.wave.barrier\0")?; + Ok(()) +} + +fn emit_int_trap(ctx: &mut EmitContext) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let function_type = get_llvm_function_type(ctx, llvm::void_type(&ctx.context), iter::empty())?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), "llvm.trap\0".as_ptr().cast()) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + "llvm.trap\0".as_ptr().cast(), + function_type, + ) + }; + } + unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + ptr::null_mut(), + 0, + LLVM_UNNAMED, + ); + // llvm.trap is not a terminator, + // LLVM might fail with an unterminated basic block if we don't insert unreachable + LLVMBuildUnreachable(builder); + } + Ok(()) +} + +fn emit_inst_exit(ctx: &mut EmitContext, is_kernel: bool) -> Result<(), TranslateError> { + if !is_kernel { + return Err(TranslateError::todo()); + } + Ok(emit_inst_ret(ctx)) +} + +fn emit_inst_shf( + ctx: &mut EmitContext, + details: &ast::FunnelShift, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + match details.mode { + ast::ShiftNormalization::Clamp => return Err(TranslateError::unreachable()), + ast::ShiftNormalization::Wrap => {} + } + let op_name = match details.direction { + ast::FunnelDirection::Left => "fshl", + ast::FunnelDirection::Right => "fshr", + }; + let intrinsic_name = format!("llvm.{}.i32\0", op_name); + let builder = ctx.builder.get(); + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B32))?; + let function_type = get_llvm_function_type( + ctx, + llvm_type, + [ + ( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ), + ( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ), + ( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ), + ] + .iter() + .copied(), + )?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), intrinsic_name.as_ptr() as _) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + intrinsic_name.as_ptr() as _, + function_type, + ) + }; + } + let src1 = args.src1.get_llvm_value(&mut ctx.names)?; + let src2 = args.src2.get_llvm_value(&mut ctx.names)?; + let src3 = args.src3.get_llvm_value(&mut ctx.names)?; + let mut llvm_args = [src2, src1, src3]; + ctx.names + .register_result_option(Some(args.dst), |dst_name| unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + llvm_args.as_mut_ptr(), + 3, + dst_name, + ) + }); + Ok(()) +} + +fn emit_inst_setp_bool( + ctx: &mut EmitContext, + details: &ast::SetpBoolData, + args: &ast::Arg5Setp, +) -> Result<(), TranslateError> { + let base_args = ast::Arg4Setp { + dst1: args.dst1, + dst2: args.dst2, + src1: args.src1, + src2: args.src2, + }; + emit_inst_setp( + ctx, + &details.base, + &base_args, + Some((details.negate_src3, args.src3, details.bool_op)), + ) +} + +fn emit_inst_abs( + ctx: &mut EmitContext, + details: &ast::AbsDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + if details.typ.kind() == ast::ScalarKind::Float { + let intrinsic_name = format!("llvm.fabs.{}\0", details.typ.llvm_display()); + emit_intrinsic_arg2( + ctx, + (details.typ, Some(args.dst)), + (details.typ, args.src), + intrinsic_name.as_bytes(), + )?; + } else { + let intrinsic_name = format!("llvm.abs.{}\0", details.typ.llvm_display()); + let const_0 = unsafe { + LLVMConstInt( + get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::Pred))?, + 0, + 0, + ) + }; + emit_intrinsic_arg3( + ctx, + ( + get_llvm_type(ctx, &ast::Type::Scalar(details.typ))?, + Some(args.dst), + ), + (details.typ, args.src), + (ast::ScalarType::Pred, const_0), + intrinsic_name.as_bytes(), + )?; + } + Ok(()) +} + +fn emit_inst_xor( + ctx: &mut EmitContext, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildXor(builder, src1, src2, dst_name) + }); + Ok(()) +} + +fn emit_inst_shl( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + emit_inst_shift_impl( + ctx, + type_, + Some(args.dst), + args.src1, + args.src2, + LLVMBuildShl, + 0u64, + )?; + Ok(()) +} + +fn emit_inst_shr( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let (shift_fn, zero) = if type_.kind() == ast::ScalarKind::Signed { + ( + LLVMBuildAShr + as unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, + u64::MAX, + ) + } else { + ( + LLVMBuildLShr + as unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, + 0u64, + ) + }; + emit_inst_shift_impl( + ctx, + type_, + Some(args.dst), + args.src1, + args.src2, + shift_fn, + zero, + )?; + Ok(()) +} + +// I would do it as as function in zluda_ptx_impl, but C++ hates 16 bit shifts +fn emit_inst_shift_impl( + ctx: &mut EmitContext, + type_: ast::ScalarType, + dst: Option, + src1: Id, + src2: Id, + shift_fn: unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, + zero: u64, +) -> Result { + let builder = ctx.builder.get(); + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(type_))?; + let src = ctx.names.value(src1)?; + let mut shift_amount = ctx.names.value(src2)?; + if type_.size_of() == 8 { + shift_amount = unsafe { LLVMBuildZExt(builder, shift_amount, llvm_type, LLVM_UNNAMED) }; + } else if type_.size_of() == 2 { + shift_amount = unsafe { LLVMBuildTrunc(builder, shift_amount, llvm_type, LLVM_UNNAMED) }; + }; + let max_shift_const: *mut LLVMValue = + unsafe { LLVMConstInt(llvm_type, (type_.size_of() as u64 * 8) - 1, 0) }; + let is_over_max_shift = unsafe { + LLVMBuildICmp( + builder, + LLVMIntPredicate::LLVMIntUGT, + shift_amount, + max_shift_const, + LLVM_UNNAMED, + ) + }; + let const_0 = unsafe { LLVMConstInt(llvm_type, zero, 0) }; + let shift_result = unsafe { shift_fn(builder, src, shift_amount, LLVM_UNNAMED) }; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildSelect(builder, is_over_max_shift, const_0, shift_result, dst_name) + })) +} + +fn emit_inst_selp( + ctx: &mut EmitContext, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + let src3 = ctx.names.value(args.src3)?; + ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildSelect(builder, src3, src1, src2, dst_name) + }); + Ok(()) +} + +fn emit_inst_rsqrt( + ctx: &mut EmitContext, + details: &ast::RsqrtDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let type_llvm = get_llvm_type(ctx, &ast::Type::Scalar(details.typ))?; + let const_1 = unsafe { LLVMConstReal(type_llvm, 1.0) }; + let intrinsic_fn = match details.typ { + ast::ScalarType::F32 => &b"llvm.sqrt.f32\0"[..], + ast::ScalarType::F64 => b"llvm.sqrt.f64\0", + _ => return Err(TranslateError::unreachable()), + }; + let sqrt_result = emit_intrinsic_arg2( + ctx, + (details.typ, None), + (details.typ, args.src), + intrinsic_fn, + )?; + unsafe { LLVMZludaSetFastMathFlags(sqrt_result, FastMathFlags::ApproxFunc) }; + let result = ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildFDiv(builder, const_1, sqrt_result, dst_name) + }); + unsafe { + LLVMZludaSetFastMathFlags( + result, + FastMathFlags::ApproxFunc | FastMathFlags::AllowReciprocal, + ) + }; + Ok(()) +} + +fn emit_inst_rem( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let build_fn = if type_.kind() == ast::ScalarKind::Signed { + LLVMBuildSRem + } else { + LLVMBuildURem + }; + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + ctx.names.register_result(args.dst, |dst_name| unsafe { + build_fn(builder, src1, src2, dst_name) + }); + Ok(()) +} + +fn emit_inst_sqrt( + ctx: &mut EmitContext, + details: &ast::RcpSqrtDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let (intrinsic_fn, fast_math) = match (details.type_, details.kind) { + (ast::ScalarType::F32, ast::RcpSqrtKind::Approx) => { + (&b"llvm.sqrt.f32\0"[..], FastMathFlags::ApproxFunc) + } + (ast::ScalarType::F64, ast::RcpSqrtKind::Approx) => { + (&b"llvm.sqrt.f64\0"[..], FastMathFlags::ApproxFunc) + } + // TODO: Go back to llvm.sqrt.f64 when this commit lands: + // https://github.com/RadeonOpenCompute/llvm-project/commit/e3fd8f83a801b1918508c7c0a71cc31bc95ad4d2 + // It's not yet present as of ROCm 5.7.1 + // TODO: support correct rounding + (ast::ScalarType::F32, _) => (&b"__ocml_sqrt_f32\0"[..], FastMathFlags::empty()), + (ast::ScalarType::F64, _) => (&b"__ocml_sqrt_f64\0"[..], FastMathFlags::empty()), + _ => return Err(TranslateError::unreachable()), + }; + let sqrt_result = emit_intrinsic_arg2( + ctx, + (details.type_, Some(args.dst)), + (details.type_, args.src), + intrinsic_fn, + )?; + unsafe { LLVMZludaSetFastMathFlags(sqrt_result, fast_math) }; + Ok(()) +} + +fn emit_inst_rcp( + ctx: &mut EmitContext, + details: &ast::RcpSqrtDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let type_llvm = get_llvm_type(ctx, &ast::Type::Scalar(details.type_))?; + let const_1 = unsafe { LLVMConstReal(type_llvm, 1.0) }; + let src = ctx.names.value(args.src)?; + let value = ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildFDiv(builder, const_1, src, dst_name) + }); + let fast_math = match details.kind { + ast::RcpSqrtKind::Approx => FastMathFlags::AllowReciprocal | FastMathFlags::ApproxFunc, + ast::RcpSqrtKind::Rounding(ast::RoundingMode::NearestEven) => { + FastMathFlags::AllowReciprocal + } + // TODO: implement this correctly + ast::RcpSqrtKind::Rounding(ast::RoundingMode::PositiveInf) => { + FastMathFlags::AllowReciprocal + } + // TODO: fix this + ast::RcpSqrtKind::Rounding(_) => FastMathFlags::AllowReciprocal, + }; + unsafe { LLVMZludaSetFastMathFlags(value, fast_math) }; + Ok(()) +} + +fn emit_inst_prmt( + ctx: &mut EmitContext, + control: u16, + arg: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let components = [ + ((control >> 0) & 0b1111) as u32, + ((control >> 4) & 0b1111) as u32, + ((control >> 8) & 0b1111) as u32, + ((control >> 12) & 0b1111) as u32, + ]; + if components.iter().any(|&c| c > 7) { + return Err(TranslateError::todo()); + } + let llvm_i32 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + let llvm_vec4_i8 = get_llvm_type(ctx, &ast::Type::Vector(ast::ScalarType::U8, 4))?; + let src1 = ctx.names.value(arg.src1)?; + let src2 = ctx.names.value(arg.src2)?; + let src1_vector = unsafe { LLVMBuildBitCast(builder, src1, llvm_vec4_i8, LLVM_UNNAMED) }; + let src2_vector = unsafe { LLVMBuildBitCast(builder, src2, llvm_vec4_i8, LLVM_UNNAMED) }; + let mut components_llvm = [ + unsafe { LLVMConstInt(llvm_i32, components[0] as _, 0) }, + unsafe { LLVMConstInt(llvm_i32, components[1] as _, 0) }, + unsafe { LLVMConstInt(llvm_i32, components[2] as _, 0) }, + unsafe { LLVMConstInt(llvm_i32, components[3] as _, 0) }, + ]; + let mask = unsafe { LLVMConstVector(components_llvm.as_mut_ptr(), 4) }; + let shuffle_result = + unsafe { LLVMBuildShuffleVector(builder, src1_vector, src2_vector, mask, LLVM_UNNAMED) }; + ctx.names.register_result(arg.dst, |dst_name| unsafe { + LLVMBuildBitCast(builder, shuffle_result, llvm_i32, dst_name) + }); + Ok(()) +} + +fn emit_inst_setp( + ctx: &mut EmitContext, + setp: &ast::SetpData, + args: &ast::Arg4Setp, + bool_postprocess: Option<(bool, Id, ast::SetpBoolPostOp)>, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let cmp_op_dst1 = if bool_postprocess.is_none() { + Some(args.dst1) + } else { + None + }; + let cmp_result1 = match setp.typ.kind() { + ast::ScalarKind::Signed | ast::ScalarKind::Unsigned | ast::ScalarKind::Bit => { + emit_inst_setp_int(ctx, setp, cmp_op_dst1, args.src1, args.src2)? + } + ast::ScalarKind::Float => { + emit_inst_setp_float(ctx, setp.cmp_op, cmp_op_dst1, args.src1, args.src2)? + } + _ => return Err(TranslateError::unreachable()), + }; + let cmp_result2 = match args.dst2 { + Some(dst2) => { + let cmp_op_dst2 = if bool_postprocess.is_none() { + Some(dst2) + } else { + None + }; + Some(( + dst2, + emit_inst_not_impl(ctx, ast::ScalarType::Pred, cmp_op_dst2, cmp_result1)?, + )) + } + None => None, + }; + if let Some((negate_src3, src3, bool_op)) = bool_postprocess { + let mut src3 = ctx.names.value(src3)?; + if negate_src3 { + src3 = emit_inst_not_impl(ctx, ast::ScalarType::Pred, None, src3)?; + } + let llvm_fn = match bool_op { + ast::SetpBoolPostOp::And => LLVMBuildAnd, + ast::SetpBoolPostOp::Or => LLVMBuildOr, + ast::SetpBoolPostOp::Xor => LLVMBuildXor, + }; + ctx.names.register_result(args.dst1, |dst_name| unsafe { + llvm_fn(builder, cmp_result1, src3, dst_name) + }); + if let Some((dst2, llvm_result2)) = cmp_result2 { + ctx.names.register_result(dst2, |dst_name| unsafe { + llvm_fn(builder, llvm_result2, src3, dst_name) + }); + } + } + Ok(()) +} + +fn emit_inst_setp_int( + ctx: &mut EmitContext, + setp: &ast::SetpData, + dst: Option, + src1: Id, + src2: Id, +) -> Result { + let builder = ctx.builder.get(); + let is_signed = setp.typ.kind() == ast::ScalarKind::Signed; + let comparer_op = match (setp.cmp_op, is_signed) { + (ast::SetpCompareOp::Eq, _) => LLVMIntPredicate::LLVMIntEQ, + (ast::SetpCompareOp::NotEq, _) => LLVMIntPredicate::LLVMIntNE, + (ast::SetpCompareOp::Less, false) => LLVMIntPredicate::LLVMIntULT, + (ast::SetpCompareOp::Less, true) => LLVMIntPredicate::LLVMIntSLT, + (ast::SetpCompareOp::LessOrEq, false) => LLVMIntPredicate::LLVMIntULE, + (ast::SetpCompareOp::LessOrEq, true) => LLVMIntPredicate::LLVMIntSLE, + (ast::SetpCompareOp::Greater, false) => LLVMIntPredicate::LLVMIntUGT, + (ast::SetpCompareOp::Greater, true) => LLVMIntPredicate::LLVMIntSGT, + (ast::SetpCompareOp::GreaterOrEq, false) => LLVMIntPredicate::LLVMIntUGE, + (ast::SetpCompareOp::GreaterOrEq, true) => LLVMIntPredicate::LLVMIntSGE, + (ast::SetpCompareOp::NanEq, _) + | (ast::SetpCompareOp::NanNotEq, _) + | (ast::SetpCompareOp::NanLess, _) + | (ast::SetpCompareOp::NanLessOrEq, _) + | (ast::SetpCompareOp::NanGreater, _) + | (ast::SetpCompareOp::NanGreaterOrEq, _) + | (ast::SetpCompareOp::IsNotNan, _) + | (ast::SetpCompareOp::IsAnyNan, _) => return Err(TranslateError::unreachable()), + }; + let src1 = ctx.names.value(src1)?; + let src2 = ctx.names.value(src2)?; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildICmp(builder, comparer_op, src1, src2, dst_name) + })) +} + +fn emit_inst_setp_float( + ctx: &mut EmitContext, + cmp_op: ast::SetpCompareOp, + dst: Option, + src1: Id, + src2: Id, +) -> Result { + let builder = ctx.builder.get(); + let comparer_op = match cmp_op { + ast::SetpCompareOp::Eq => LLVMRealPredicate::LLVMRealOEQ, + ast::SetpCompareOp::NotEq => LLVMRealPredicate::LLVMRealONE, + ast::SetpCompareOp::Less => LLVMRealPredicate::LLVMRealOLT, + ast::SetpCompareOp::LessOrEq => LLVMRealPredicate::LLVMRealOLE, + ast::SetpCompareOp::Greater => LLVMRealPredicate::LLVMRealOGT, + ast::SetpCompareOp::GreaterOrEq => LLVMRealPredicate::LLVMRealOGE, + ast::SetpCompareOp::NanEq => LLVMRealPredicate::LLVMRealUEQ, + ast::SetpCompareOp::NanNotEq => LLVMRealPredicate::LLVMRealUNE, + ast::SetpCompareOp::NanLess => LLVMRealPredicate::LLVMRealULT, + ast::SetpCompareOp::NanLessOrEq => LLVMRealPredicate::LLVMRealULE, + ast::SetpCompareOp::NanGreater => LLVMRealPredicate::LLVMRealUGT, + ast::SetpCompareOp::NanGreaterOrEq => LLVMRealPredicate::LLVMRealUGE, + ast::SetpCompareOp::IsNotNan => LLVMRealPredicate::LLVMRealORD, + ast::SetpCompareOp::IsAnyNan => LLVMRealPredicate::LLVMRealUNO, + }; + let src1 = ctx.names.value(src1)?; + let src2 = ctx.names.value(src2)?; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildFCmp(builder, comparer_op, src1, src2, dst_name) + })) +} + +fn emit_inst_sub( + ctx: &mut EmitContext, + details: &ast::ArithDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + emit_inst_sub_impl(ctx, details.get_type(), args.dst, args.src1, args.src2) +} + +fn emit_inst_sub_impl( + ctx: &mut EmitContext, + details: ast::ScalarType, + dst: Id, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let function = match details.kind() { + ast::ScalarKind::Float | ast::ScalarKind::Float2 => LLVMBuildFSub, + ast::ScalarKind::Unsigned | ast::ScalarKind::Signed => LLVMBuildSub, + _ => return Err(TranslateError::unreachable()), + }; + let src1 = src1.get_llvm_value(&mut ctx.names)?; + let src2 = src2.get_llvm_value(&mut ctx.names)?; + ctx.names.register_result(dst, |dst_name| unsafe { + function(builder, src1, src2, dst_name) + }); + Ok(()) +} + +fn emit_inst_neg( + ctx: &mut EmitContext, + details: &ast::NegDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let zero = if details.typ.kind() == ast::ScalarKind::Float { + ast::ImmediateValue::F64(0.0) + } else { + ast::ImmediateValue::S64(0) + }; + let zero = unsafe { get_llvm_const_scalar(ctx, details.typ, zero)? }; + emit_inst_sub_impl(ctx, details.typ, args.dst, zero, args.src) +} + +fn emit_inst_not( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + emit_inst_not_impl(ctx, type_, Some(args.dst), args.src)?; + Ok(()) +} + +fn emit_inst_not_impl( + ctx: &mut EmitContext, + type_: ast::ScalarType, + dst: Option, + src: impl GetLLVMValue, +) -> Result { + let builder = ctx.builder.get(); + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(type_))?; + let constant = unsafe { LLVMConstInt(llvm_type, u64::MAX, 0) }; + let src = src.get_llvm_value(&mut ctx.names)?; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildXor(builder, src, constant, dst_name) + })) +} + +// Looking at the docs (https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#memory-fence-functions): +// * __threadfence_block() compiles to membar.cta +// * __threadfence_system() compiles to membar.sys +// Additionally, they are dfined as: +// "also ensures that no writes to *all* memory made by the calling thread after the call to ..." +fn emit_inst_membar(ctx: &mut EmitContext, level: ast::MemScope) { + let scope = get_llvm_scope_for_membar(level); + let ordering = LLVMAtomicOrdering::LLVMAtomicOrderingSequentiallyConsistent; + unsafe { + LLVMZludaBuildFence( + ctx.builder.get(), + ordering, + scope.as_ptr() as _, + b"\0".as_ptr() as _, + ) + }; +} + +fn emit_inst_max( + ctx: &mut EmitContext, + details: &ast::MinMaxDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let function_name = match details { + ast::MinMaxDetails::Signed(ast::ScalarType::S16) => &b"llvm.smax.i16\0"[..], + ast::MinMaxDetails::Signed(ast::ScalarType::S32) => b"llvm.smax.i32\0", + ast::MinMaxDetails::Signed(ast::ScalarType::S64) => b"llvm.smax.i64\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U16) => b"llvm.umax.i16\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U32) => b"llvm.umax.i32\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U64) => b"llvm.umax.i64\0", + ast::MinMaxDetails::Float(desc) => { + if desc.nan { + return Err(TranslateError::todo()); + } + match desc.typ { + ast::ScalarType::F16 => b"llvm.maxnum.f16\0", + ast::ScalarType::F32 => b"llvm.maxnum.f32\0", + ast::ScalarType::F64 => b"llvm.maxnum.f64\0", + _ => return Err(TranslateError::unreachable()), + } + } + _ => return Err(TranslateError::unreachable()), + }; + let type_ = details.get_type(); + emit_intrinsic_arg3( + ctx, + ( + get_llvm_type(ctx, &ast::Type::Scalar(type_))?, + Some(args.dst), + ), + (type_, args.src1), + (type_, args.src2), + function_name, + )?; + Ok(()) +} + +fn emit_inst_min( + ctx: &mut EmitContext, + details: &ast::MinMaxDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let function_name = match details { + ast::MinMaxDetails::Signed(ast::ScalarType::S16) => &b"llvm.smin.i16\0"[..], + ast::MinMaxDetails::Signed(ast::ScalarType::S32) => b"llvm.smin.i32\0", + ast::MinMaxDetails::Signed(ast::ScalarType::S64) => b"llvm.smin.i64\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U16) => b"llvm.umin.i16\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U32) => b"llvm.umin.i32\0", + ast::MinMaxDetails::Unsigned(ast::ScalarType::U64) => b"llvm.umin.i64\0", + ast::MinMaxDetails::Float(desc) => { + if desc.nan { + return Err(TranslateError::todo()); + } + match desc.typ { + ast::ScalarType::F16 => b"llvm.minnum.f16\0", + ast::ScalarType::F32 => b"llvm.minnum.f32\0", + ast::ScalarType::F64 => b"llvm.minnum.f64\0", + _ => return Err(TranslateError::unreachable()), + } + } + _ => return Err(TranslateError::unreachable()), + }; + let type_ = details.get_type(); + emit_intrinsic_arg3( + ctx, + ( + get_llvm_type(ctx, &ast::Type::Scalar(type_))?, + Some(args.dst), + ), + (type_, args.src1), + (type_, args.src2), + function_name, + )?; + Ok(()) +} + +fn emit_inst_mad( + ctx: &mut EmitContext, + details: &ast::MulDetails, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + match details { + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::Low, + typ, + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::Low, + typ, + }) => emit_inst_mad_lo(ctx, *typ, args), + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }) => emit_inst_mad_hi(ctx, *typ, args), + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::Wide, + typ, + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::Wide, + typ, + }) => emit_inst_mad_wide(ctx, *typ, args), + ast::MulDetails::Float(arith) => return emit_inst_fma(ctx, arith, args), + } +} + +fn emit_inst_mad_wide( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + let result = emit_inst_mul_wide(ctx, type_, None, args.src1, args.src2)?; + let wide_type = type_.widen()?; + emit_inst_add_impl( + ctx, + &ast::ArithDetails::Unsigned(wide_type), + args.dst, + result, + args.src3, + ) +} + +fn emit_inst_mad_hi( + ctx: &mut EmitContext, + typ: ast::ScalarType, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + let temp_dst = emit_inst_mul_hi_impl(ctx, typ, None, args.src1, args.src2)?; + emit_inst_add_impl( + ctx, + &ast::ArithDetails::Unsigned(typ), + args.dst, + temp_dst, + args.src3, + ) +} + +fn emit_inst_mad_lo( + ctx: &mut EmitContext, + typ: ast::ScalarType, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + let mul_result = emit_inst_mul_low_impl(ctx, None, args.src1, args.src2, LLVMBuildMul)?; + emit_inst_add_impl( + ctx, + &ast::ArithDetails::Unsigned(typ), + args.dst, + mul_result, + args.src3, + ) +} + +// TODO: support mad.hi.cc +fn emit_inst_madcc( + ctx: &mut EmitContext, + type_: ast::ScalarType, + arg: &Arg4CarryOut, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(arg.src1)?; + let src2 = ctx.names.value(arg.src2)?; + let mul_result = unsafe { LLVMBuildMul(builder, src1, src2, LLVM_UNNAMED) }; + emit_inst_addsub_cc_impl( + ctx, + "add", + type_, + arg.dst, + arg.carry_out, + mul_result, + arg.src3, + ) +} + +fn get_llvm_type_struct<'a>( + ctx: &EmitContext, + types: impl ExactSizeIterator>, +) -> Result { + use std::fmt::Write; + let element_count = types.len() as u32; + let mut name_suffix = "struct.".to_string(); + let mut llvm_types = Vec::new(); + let mut is_anonymous = false; + for type_ in types { + llvm_types.push(get_llvm_type(ctx, &type_)?); + match &*type_ { + ast::Type::Scalar(type_) => { + write!(name_suffix, "{}", type_.llvm_display()) + .map_err(|_| TranslateError::unreachable())?; + } + _ => is_anonymous = true, + } + } + name_suffix.push('\0'); + if is_anonymous { + unsafe { + Ok(LLVMStructTypeInContext( + ctx.context.get(), + llvm_types.as_mut_ptr(), + element_count, + 0, + )) + } + } else { + // We emit named type for structs, because unnamed LLVM structs are not subject + // to unification during linking, e.g. if we have a func decl: + // declare protected { float, float } @foobar(i32, i32) + // that is used like this: + // %0 = call { float, float } @foobar(i32 %"arg1", i32 %"arg2") + // and definition in another module, like this: + // %struct.float2_struct = type { float, float } + // define linkonce_odr hidden %struct.float2_struct @foobar(i32 %0, i32 %1) { + // ... + // } + // then llvm-link emits our original call as a cast: + // %0 = call { float, float } bitcast (%struct.float2_struct (i32, i32)* @foobar to { float, float } (i32, i32)*)(i32 %"arg1", i32 %"arg2") + // which makes certain amount of sense, but prevents inlining + let mut struct_type = + unsafe { LLVMGetTypeByName2(ctx.context.get(), name_suffix.as_ptr() as _) }; + if struct_type == ptr::null_mut() { + struct_type = + unsafe { LLVMStructCreateNamed(ctx.context.get(), name_suffix.as_ptr() as _) }; + unsafe { LLVMStructSetBody(struct_type, llvm_types.as_mut_ptr(), element_count, 0) }; + } + Ok(struct_type) + } +} + +fn emit_inst_madc( + ctx: &mut EmitContext, + type_: ast::ScalarType, + is_hi: bool, + args: &translate::Arg4CarryIn, +) -> Result<(), TranslateError> { + let mul_result = if is_hi { + emit_inst_mul_hi_impl(ctx, type_, None, args.src1, args.src2)? + } else { + emit_inst_mul_low_impl(ctx, None, args.src1, args.src2, LLVMBuildMul)? + }; + emit_inst_addsub_c_impl( + ctx, + "add", + LLVMBuildAdd, + type_, + args.dst, + args.carry_out, + args.carry_in, + mul_result, + args.src3, + ) + /* + let src3 = ctx.names.value(args.src3)?; + let add_no_carry = unsafe { LLVMBuildAdd(builder, mul_result, src3, LLVM_UNNAMED) }; + let carry_flag = ctx.names.value(args.carry_in)?; + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(type_))?; + let carry_flag = unsafe { LLVMBuildZExt(builder, carry_flag, llvm_type, LLVM_UNNAMED) }; + if let Some(carry_out) = args.carry_out { + emit_inst_addsub_cc_impl( + ctx, + "add", + type_, + args.dst, + carry_out, + add_no_carry, + carry_flag, + )?; + } else { + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildAdd(builder, add_no_carry, carry_flag, dst) + }); + } + Ok(()) + */ +} + +fn emit_inst_add_c( + ctx: &mut EmitContext, + type_: ast::ScalarType, + arg: &translate::Arg3CarryIn, +) -> Result<(), TranslateError> { + emit_inst_addsub_c_impl( + ctx, + "add", + LLVMBuildAdd, + type_, + arg.dst, + arg.carry_out, + arg.carry_in, + arg.src1, + arg.src2, + ) +} + +fn emit_inst_sub_c( + ctx: &mut EmitContext<'_>, + type_: ast::ScalarType, + arg: &translate::Arg3CarryIn, +) -> Result<(), TranslateError> { + emit_inst_addsub_c_impl( + ctx, + "sub", + LLVMBuildSub, + type_, + arg.dst, + arg.carry_out, + arg.carry_in, + arg.src1, + arg.src2, + ) +} + +fn emit_inst_addsub_c_impl( + ctx: &mut EmitContext, + op: &str, + llvm_fn: unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, + type_: ast::ScalarType, + dst: Id, + carry_out: Option, + carry_in: Id, + src1: impl GetLLVMValue, + src2: Id, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let carry_in = ctx.names.value(carry_in)?; + let carry_in = unsafe { + LLVMBuildZExt( + builder, + carry_in, + get_llvm_type(ctx, &ast::Type::Scalar(type_))?, + LLVM_UNNAMED, + ) + }; + if let Some(carry_out) = carry_out { + let fn_name = format!("llvm.u{}.with.overflow.{}\0", op, type_.llvm_display()); + let dst_type = get_anonymous_struct_type(ctx, [type_, ast::ScalarType::Pred])?; + let temp_result1 = emit_intrinsic_arg3( + ctx, + (dst_type, None), + (type_, src1), + (type_, src2), + fn_name.as_bytes(), + )?; + let temp_value = unsafe { LLVMBuildExtractValue(builder, temp_result1, 0, LLVM_UNNAMED) }; + let intermediate_flag1 = + unsafe { LLVMBuildExtractValue(builder, temp_result1, 1, LLVM_UNNAMED) }; + let temp_result2 = emit_intrinsic_arg3( + ctx, + (dst_type, None), + (type_, temp_value), + (type_, carry_in), + fn_name.as_bytes(), + )?; + ctx.names.register_result(dst, |dst: *const i8| unsafe { + LLVMBuildExtractValue(builder, temp_result2, 0, dst) + }); + let intermediate_flag2 = + unsafe { LLVMBuildExtractValue(builder, temp_result2, 1, LLVM_UNNAMED) }; + ctx.names + .register_result(carry_out, |dst: *const i8| unsafe { + LLVMBuildXor(builder, intermediate_flag1, intermediate_flag2, dst) + }); + } else { + let src2 = ctx.names.value(src2)?; + let temp = unsafe { + llvm_fn( + builder, + src1.get_llvm_value(&mut ctx.names)?, + src2, + LLVM_UNNAMED, + ) + }; + ctx.names + .register_result(dst, |dst| unsafe { llvm_fn(builder, temp, carry_in, dst) }); + } + Ok(()) +} + +fn emit_inst_addsub_cc( + ctx: &mut EmitContext, + op: &str, + type_: ast::ScalarType, + arg: &translate::Arg3CarryOut, +) -> Result<(), TranslateError> { + emit_inst_addsub_cc_impl(ctx, op, type_, arg.dst, arg.carry_flag, arg.src1, arg.src2) +} + +fn emit_inst_addsub_cc_impl( + ctx: &mut EmitContext, + op: &str, + type_: ast::ScalarType, + dst: Id, + carry_flag: Id, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let dst_type = get_anonymous_struct_type(ctx, [type_, ast::ScalarType::Pred])?; + let fn_name = format!("llvm.u{}.with.overflow.{}\0", op, type_.llvm_display()); + let result = emit_intrinsic_arg3( + ctx, + (dst_type, None), + (type_, src1), + (type_, src2), + fn_name.as_bytes(), + )?; + ctx.names.register_result(dst, |dst: *const i8| unsafe { + LLVMBuildExtractValue(builder, result, 0, dst) + }); + ctx.names.register_result(carry_flag, |dst| unsafe { + LLVMBuildExtractValue(builder, result, 1, dst) + }); + Ok(()) +} + +fn emit_inst_fma( + ctx: &mut EmitContext, + details: &ast::ArithFloat, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + if details.saturate + //|| !(details.rounding == None || details.rounding == Some(ast::RoundingMode::NearestEven)) + { + return Err(TranslateError::todo()); + } + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + let src3 = ctx.names.value(args.src3)?; + let intrinsic_name = match details.typ { + ast::ScalarType::F16 => &b"llvm.fma.f16\0"[..], + ast::ScalarType::F16x2 => b"llvm.fma.v2f16\0", + ast::ScalarType::F32 => b"llvm.fma.f32\0", + ast::ScalarType::F64 => b"llvm.fma.f64\0", + _ => return Err(TranslateError::unreachable()), + }; + let llvm_type = get_llvm_type(ctx, &ast::Type::Scalar(details.typ))?; + let function_type = get_llvm_function_type( + ctx, + llvm_type, + iter::repeat((&ast::Type::Scalar(details.typ), ast::StateSpace::Reg)).take(3), + )?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), intrinsic_name.as_ptr() as _) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + intrinsic_name.as_ptr() as _, + function_type, + ) + }; + } + let mut fn_args = [src1, src2, src3]; + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + fn_args.as_mut_ptr(), + 3, + dst, + ) + }); + Ok(()) +} + +fn emit_inst_div( + ctx: &mut EmitContext, + details: &ast::DivDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + let (llvm_fn, approx) = match details { + ast::DivDetails::Unsigned(_) => ( + LLVMBuildUDiv as unsafe extern "C" fn(_, _, _, _) -> _, + false, + ), + ast::DivDetails::Signed(_) => ( + LLVMBuildSDiv as unsafe extern "C" fn(_, _, _, _) -> _, + false, + ), + ast::DivDetails::Float(ast::DivFloatDetails { kind, .. }) => match kind { + ast::DivFloatKind::Approx => { + (LLVMBuildFDiv as unsafe extern "C" fn(_, _, _, _) -> _, true) + } + ast::DivFloatKind::Full + | ast::DivFloatKind::Rounding(ast::RoundingMode::NearestEven) => ( + LLVMBuildFDiv as unsafe extern "C" fn(_, _, _, _) -> _, + false, + ), + // TODO: Fix this + ast::DivFloatKind::Rounding(_) => ( + LLVMBuildFDiv as unsafe extern "C" fn(_, _, _, _) -> _, + false, + ), + }, + }; + let value = ctx.names.register_result(args.dst, |dst_name| unsafe { + llvm_fn(builder, src1, src2, dst_name) + }); + if approx { + unsafe { + LLVMZludaSetFastMathFlags( + value, + FastMathFlags::AllowReciprocal | FastMathFlags::ApproxFunc, + ) + }; + } + Ok(()) +} + +fn emit_inst_cvt( + ctx: &mut EmitContext, + details: &ast::CvtDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + Ok(match details { + ast::CvtDetails::FloatFromFloat(desc) => { + if desc.saturate { + return Err(TranslateError::todo()); + } + let type_ = desc.dst; + if desc.dst == desc.src { + match desc.rounding { + Some(ast::RoundingMode::NearestEven) => { + let intrinsic_fn = match type_ { + ast::ScalarType::F16 => &b"llvm.rint.f16\0"[..], + ast::ScalarType::F32 => &b"llvm.rint.f32\0"[..], + ast::ScalarType::F64 => &b"llvm.rint.f64\0"[..], + _ => return Err(TranslateError::unreachable()), + }; + emit_intrinsic_arg2( + ctx, + (type_, Some(args.dst)), + (type_, args.src), + intrinsic_fn, + )?; + } + Some(ast::RoundingMode::Zero) => { + let intrinsic_fn = match type_ { + ast::ScalarType::F16 => &b"llvm.trunc.f16\0"[..], + ast::ScalarType::F32 => &b"llvm.trunc.f32\0"[..], + ast::ScalarType::F64 => &b"llvm.trunc.f64\0"[..], + _ => return Err(TranslateError::unreachable()), + }; + emit_intrinsic_arg2( + ctx, + (type_, Some(args.dst)), + (type_, args.src), + intrinsic_fn, + )?; + } + Some(ast::RoundingMode::NegativeInf) => { + let intrinsic_fn = match type_ { + ast::ScalarType::F16 => &b"llvm.floor.f16\0"[..], + ast::ScalarType::F32 => &b"llvm.floor.f32\0"[..], + ast::ScalarType::F64 => &b"llvm.floor.f64\0"[..], + _ => return Err(TranslateError::unreachable()), + }; + emit_intrinsic_arg2( + ctx, + (type_, Some(args.dst)), + (type_, args.src), + intrinsic_fn, + )?; + } + Some(ast::RoundingMode::PositiveInf) => { + let intrinsic_fn = match type_ { + ast::ScalarType::F16 => &b"llvm.ceil.f16\0"[..], + ast::ScalarType::F32 => &b"llvm.ceil.f32\0"[..], + ast::ScalarType::F64 => &b"llvm.ceil.f64\0"[..], + _ => return Err(TranslateError::unreachable()), + }; + emit_intrinsic_arg2( + ctx, + (type_, Some(args.dst)), + (type_, args.src), + intrinsic_fn, + )?; + } + None => { + let src = ctx.names.value(args.src)?; + emit_value_copy(ctx, &ast::Type::Scalar(type_), src, args.dst)?; + } + } + } else if desc.dst.size_of() > desc.src.size_of() { + let src = ctx.names.value(args.src)?; + let type_ = get_llvm_type(ctx, &ast::Type::Scalar(desc.dst))?; + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildFPExt(builder, src, type_, dst) + }); + } else { + // Replaced by a function call + return Err(TranslateError::unreachable()); + } + } + ast::CvtDetails::FloatFromInt(_) => { + // Replaced by a function call + return Err(TranslateError::unreachable()); + } + ast::CvtDetails::IntFromFloat(_) => { + // Replaced by a function call + return Err(TranslateError::unreachable()); + } + ast::CvtDetails::IntFromInt(desc) => emit_inst_cvt_int_from_int(ctx, desc, args)?, + }) +} + +fn emit_inst_cvt_int_from_int( + ctx: &mut EmitContext, + desc: &ast::CvtIntToIntDesc, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src = if desc.saturate { + match emit_int_saturate_if_needed(ctx, desc, args) { + Ok(Some(src)) => src, + Ok(None) => ctx.names.value(args.src)?, + Err(err) => return Err(err), + } + } else { + ctx.names.value(args.src)? + }; + // The value is now clamped, do bit conversions + let llvm_op = if desc.dst.size_of() > desc.src.size_of() { + if desc.src.kind() == ast::ScalarKind::Signed { + LLVMBuildSExt + } else { + LLVMBuildZExt + } + } else if desc.dst.size_of() < desc.src.size_of() { + LLVMBuildTrunc + } else { + return emit_value_copy(ctx, &ast::Type::Scalar(desc.dst), src, args.dst); + }; + let type_ = get_llvm_type(ctx, &ast::Type::Scalar(desc.dst))?; + ctx.names + .register_result(args.dst, |dst| unsafe { llvm_op(builder, src, type_, dst) }); + Ok(()) +} + +fn emit_int_saturate_if_needed( + ctx: &mut EmitContext, + desc: &ast::CvtIntToIntDesc, + args: &ast::Arg2, +) -> Result, TranslateError> { + let (src_min, src_max) = get_min_max(desc.src)?; + let (dst_min, dst_max) = get_min_max(desc.dst)?; + let src_type = get_llvm_type(ctx, &ast::Type::Scalar(desc.src))?; + let mut result = None; + if src_max > dst_max { + let intrinsic_name = match desc.src.kind() { + ast::ScalarKind::Signed => format!("llvm.smin.{}\0", desc.src.llvm_display()), + ast::ScalarKind::Bit | ast::ScalarKind::Unsigned => { + format!("llvm.umin.{}\0", desc.src.llvm_display()) + } + ast::ScalarKind::Float | ast::ScalarKind::Float2 | ast::ScalarKind::Pred => { + return Err(TranslateError::unreachable()) + } + }; + let dst_max_llvm = unsafe { LLVMConstInt(src_type, dst_max as _, 0) }; + result = Some(emit_intrinsic_arg3( + ctx, + (get_llvm_type(ctx, &ast::Type::Scalar(desc.src))?, None), + (desc.src, args.src), + (desc.src, dst_max_llvm), + intrinsic_name.as_bytes(), + )?); + } + if src_min < dst_min { + let intrinsic_name = match desc.src.kind() { + ast::ScalarKind::Signed => format!("llvm.smax.{}\0", desc.src.llvm_display()), + ast::ScalarKind::Bit | ast::ScalarKind::Unsigned => { + format!("llvm.umax.{}\0", desc.src.llvm_display()) + } + ast::ScalarKind::Float | ast::ScalarKind::Float2 | ast::ScalarKind::Pred => { + return Err(TranslateError::unreachable()) + } + }; + let dst_min_llvm = unsafe { LLVMConstInt(src_type, dst_min as _, 0) }; + result = Some(emit_intrinsic_arg3( + ctx, + (get_llvm_type(ctx, &ast::Type::Scalar(desc.src))?, None), + (desc.src, args.src), + (desc.src, dst_min_llvm), + intrinsic_name.as_bytes(), + )?); + } + Ok(result) +} + +fn get_min_max(type_: ast::ScalarType) -> Result<(i128, i128), TranslateError> { + Ok(match type_ { + ast::ScalarType::B8 | ast::ScalarType::U8 => (u8::MIN as _, u8::MAX as _), + ast::ScalarType::B16 | ast::ScalarType::U16 => (u16::MIN as _, u16::MAX as _), + ast::ScalarType::B32 | ast::ScalarType::U32 => (u32::MIN as _, u32::MAX as _), + ast::ScalarType::B64 | ast::ScalarType::U64 => (u64::MIN as _, u64::MAX as _), + ast::ScalarType::S8 => (i8::MIN as _, i8::MAX as _), + ast::ScalarType::S16 => (i16::MIN as _, i16::MAX as _), + ast::ScalarType::S32 => (i32::MIN as _, i32::MAX as _), + ast::ScalarType::S64 => (i64::MIN as _, i64::MAX as _), + ast::ScalarType::F16 + | ast::ScalarType::F32 + | ast::ScalarType::F64 + | ast::ScalarType::F16x2 + | ast::ScalarType::Pred => return Err(TranslateError::unreachable()), + }) +} + +fn emit_inst_cvta( + ctx: &mut EmitContext, + details: &ast::CvtaDetails, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src = ctx.names.value(args.src)?; + let from_ptr_type = + get_llvm_pointer_type(ctx, &ast::Type::Scalar(ast::ScalarType::B8), details.from)?; + let src_ptr = unsafe { LLVMBuildIntToPtr(builder, src, from_ptr_type, b"\0".as_ptr() as _) }; + let to_ptr_type = + get_llvm_pointer_type(ctx, &ast::Type::Scalar(ast::ScalarType::B8), details.to)?; + let cast_result = + unsafe { LLVMBuildAddrSpaceCast(builder, src_ptr, to_ptr_type, b"\0".as_ptr() as _) }; + let scalar_type = match details.size { + ast::CvtaSize::U32 => ast::ScalarType::U32, + ast::CvtaSize::U64 => ast::ScalarType::U64, + }; + let type_ = get_llvm_type(ctx, &ast::Type::Scalar(scalar_type))?; + ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildPtrToInt(builder, cast_result, type_, dst_name) + }); + Ok(()) +} + +fn emit_inst_cos( + ctx: &mut EmitContext, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let function_name = b"llvm.cos.f32\0"; + let cos_value = emit_intrinsic_arg2( + ctx, + (ast::ScalarType::F32, Some(args.dst)), + (ast::ScalarType::F32, args.src), + function_name, + )?; + unsafe { LLVMZludaSetFastMathFlags(cos_value, FastMathFlags::ApproxFunc) }; + Ok(()) +} + +fn emit_inst_sin( + ctx: &mut EmitContext, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let function_name = b"llvm.sin.f32\0"; + let cos_value = emit_intrinsic_arg2( + ctx, + (ast::ScalarType::F32, Some(args.dst)), + (ast::ScalarType::F32, args.src), + function_name, + )?; + unsafe { LLVMZludaSetFastMathFlags(cos_value, FastMathFlags::ApproxFunc) }; + Ok(()) +} + +fn emit_inst_mul( + ctx: &mut EmitContext, + details: &ast::MulDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + match details { + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::Wide, + typ, + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::Wide, + typ, + }) => { + emit_inst_mul_wide(ctx, *typ, Some(args.dst), args.src1, args.src2)?; + Ok(()) + } + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::Low, + .. + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::Low, + .. + }) => emit_inst_mul_lo(ctx, args, LLVMBuildMul), + ast::MulDetails::Float(ast::ArithFloat { .. }) => { + emit_inst_mul_lo(ctx, args, LLVMBuildFMul) + } + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }) + | ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }) => { + emit_inst_mul_hi(ctx, *typ, args)?; + Ok(()) + } + } +} + +fn emit_inst_mul_hi( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + emit_inst_mul_hi_impl(ctx, type_, Some(args.dst), args.src1, args.src2)?; + Ok(()) +} + +fn emit_inst_mul_hi_impl( + ctx: &mut EmitContext, + type_: ast::ScalarType, + dst: Option, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, +) -> Result { + let temp_dst = emit_inst_mul_wide(ctx, type_, None, src1, src2)?; + emit_get_high_bits(ctx, type_, temp_dst, dst) +} + +fn emit_get_high_bits( + ctx: &mut EmitContext, + narrow_type: ast::ScalarType, + input: LLVMValueRef, + dst: Option, +) -> Result { + let builder: *mut LLVMBuilder = ctx.builder.get(); + let llvm_narrow_type = get_llvm_type(ctx, &ast::Type::Scalar(narrow_type))?; + let llvm_wide_type = get_llvm_type(ctx, &ast::Type::Scalar(narrow_type.widen()?))?; + let shift_constant = + unsafe { LLVMConstInt(llvm_wide_type, narrow_type.size_of() as u64 * 8u64, 0) }; + let shift_result = unsafe { LLVMBuildLShr(builder, input, shift_constant, LLVM_UNNAMED) }; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildTrunc(builder, shift_result, llvm_narrow_type, dst_name) + })) +} + +fn emit_inst_mul_wide( + ctx: &mut EmitContext, + type_: ast::ScalarType, + dst: Option, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, +) -> Result { + let builder = ctx.builder.get(); + let (extend_fn, build_fn) = if type_.kind() == ast::ScalarKind::Signed { + ( + LLVMBuildSExt as unsafe extern "C" fn(_, _, _, _) -> _, + LLVMBuildNSWMul as unsafe extern "C" fn(_, _, _, _) -> _, + ) + } else { + ( + LLVMBuildZExt as unsafe extern "C" fn(_, _, _, _) -> _, + LLVMBuildNUWMul as unsafe extern "C" fn(_, _, _, _) -> _, + ) + }; + let widened_type = get_llvm_type(ctx, &ast::Type::Scalar(type_.widen()?))?; + let src1 = src1.get_llvm_value(&mut ctx.names)?; + let src2 = src2.get_llvm_value(&mut ctx.names)?; + let src1_temp = unsafe { extend_fn(builder, src1, widened_type, b"\0".as_ptr() as _) }; + let src2_temp = unsafe { extend_fn(builder, src2, widened_type, b"\0".as_ptr() as _) }; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + build_fn(builder, src1_temp, src2_temp, dst_name) + })) +} + +fn emit_inst_mul_lo( + ctx: &mut EmitContext, + args: &ast::Arg3, + llvm_fn: unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, +) -> Result<(), TranslateError> { + emit_inst_mul_low_impl(ctx, Some(args.dst), args.src1, args.src2, llvm_fn)?; + Ok(()) +} + +fn emit_inst_mul_low_impl( + ctx: &mut EmitContext, + dst: Option, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, + llvm_fn: unsafe extern "C" fn( + LLVMBuilderRef, + LLVMValueRef, + LLVMValueRef, + *const i8, + ) -> LLVMValueRef, +) -> Result { + let builder = ctx.builder.get(); + let src1 = src1.get_llvm_value(&mut ctx.names)?; + let src2 = src2.get_llvm_value(&mut ctx.names)?; + Ok(ctx + .names + .register_result_option(dst, |dst| unsafe { llvm_fn(builder, src1, src2, dst) })) +} + +fn emit_inst_clz( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + emit_inst_clz_impl(ctx, type_, Some(args.dst), args.src, false)?; + Ok(()) +} + +fn emit_inst_clz_impl( + ctx: &mut EmitContext, + type_: ast::ScalarType, + dst: Option, + src: Id, + is_zero_poison: bool, +) -> Result { + let builder = ctx.builder.get(); + let intrinsic_name = match type_.size_of() { + 4 => &b"llvm.ctlz.i32\0"[..], + 8 => b"llvm.ctlz.i64\0", + _ => return Err(TranslateError::unreachable()), + }; + let const_0 = unsafe { + LLVMConstInt( + get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::Pred))?, + is_zero_poison as _, + 0, + ) + }; + let temp_result = emit_intrinsic_arg3( + ctx, + (get_llvm_type(ctx, &ast::Type::Scalar(type_))?, None), + (type_, src), + (ast::ScalarType::Pred, const_0), + intrinsic_name, + )?; + let b32_type = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::B32))?; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildTrunc(builder, temp_result, b32_type, dst_name) + })) +} + +fn emit_inst_brev( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let function_name = match type_.size_of() { + 4 => &b"llvm.bitreverse.i32\0"[..], + 8 => b"llvm.bitreverse.i64\0", + _ => return Err(TranslateError::unreachable()), + }; + emit_intrinsic_arg2( + ctx, + (type_, Some(args.dst)), + (type_, args.src), + function_name, + )?; + Ok(()) +} + +fn emit_inst_popc( + ctx: &mut EmitContext, + type_: ast::ScalarType, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let (function_name, shorten) = match type_.size_of() { + 4 => (&b"llvm.ctpop.i32\0"[..], false), + 8 => (&b"llvm.ctpop.i64\0"[..], true), + _ => return Err(TranslateError::unreachable()), + }; + let popc_dst = if shorten { None } else { Some(args.dst) }; + let popc_result = + emit_intrinsic_arg2(ctx, (type_, popc_dst), (type_, args.src), function_name)?; + if shorten { + let llvm_i32 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildTrunc(builder, popc_result, llvm_i32, dst_name) + }); + } + Ok(()) +} + +fn emit_inst_ex2( + ctx: &mut EmitContext, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let function_name = b"llvm.exp2.f32\0"; + let llvm_value = emit_intrinsic_arg2( + ctx, + (ast::ScalarType::F32, Some(args.dst)), + (ast::ScalarType::F32, args.src), + function_name, + )?; + unsafe { LLVMZludaSetFastMathFlags(llvm_value, FastMathFlags::ApproxFunc) }; + Ok(()) +} + +fn emit_inst_lg2( + ctx: &mut EmitContext, + args: &ast::Arg2, +) -> Result<(), TranslateError> { + let function_name = b"llvm.log2.f32\0"; + let llvm_value = emit_intrinsic_arg2( + ctx, + (ast::ScalarType::F32, Some(args.dst)), + (ast::ScalarType::F32, args.src), + function_name, + )?; + unsafe { LLVMZludaSetFastMathFlags(llvm_value, FastMathFlags::ApproxFunc) }; + Ok(()) +} + +fn emit_intrinsic_arg0( + ctx: &mut EmitContext, + intrinsic_name: &[u8], +) -> Result { + let builder = ctx.builder.get(); + let function_type = get_llvm_function_type(ctx, llvm::void_type(ctx.context), iter::empty())?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), intrinsic_name.as_ptr() as _) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + intrinsic_name.as_ptr() as _, + function_type, + ) + }; + } + Ok(unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + ptr::null_mut(), + 0, + LLVM_UNNAMED, + ) + }) +} + +fn emit_intrinsic_arg2( + ctx: &mut EmitContext, + (dst_type, dst): (ast::ScalarType, Option), + (src_type, src): (ast::ScalarType, Id), + intrinsic_name: &[u8], +) -> Result { + let builder = ctx.builder.get(); + let mut llvm_src = ctx.names.value(src)?; + let dst_type = get_llvm_type(ctx, &ast::Type::Scalar(dst_type))?; + let function_type = get_llvm_function_type( + ctx, + dst_type, + iter::once((&ast::Type::Scalar(src_type), ast::StateSpace::Reg)), + )?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), intrinsic_name.as_ptr() as _) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + intrinsic_name.as_ptr() as _, + function_type, + ) + }; + } + Ok(ctx.names.register_result_option(dst, |dst| unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + &mut llvm_src, + 1, + dst, + ) + })) +} + +fn emit_intrinsic_arg3( + ctx: &mut EmitContext, + (dst_type, dst): (LLVMTypeRef, Option), + (src1_type, src1): (ast::ScalarType, impl GetLLVMValue), + (src2_type, src2): (ast::ScalarType, impl GetLLVMValue), + intrinsic_name: &[u8], +) -> Result { + let builder = ctx.builder.get(); + let function_type = get_llvm_function_type( + ctx, + dst_type, + [ + (&ast::Type::Scalar(src1_type), ast::StateSpace::Reg), + (&ast::Type::Scalar(src2_type), ast::StateSpace::Reg), + ] + .iter() + .copied(), + )?; + let mut function_value = + unsafe { LLVMGetNamedFunction(ctx.module.get(), intrinsic_name.as_ptr() as _) }; + if function_value == ptr::null_mut() { + function_value = unsafe { + LLVMAddFunction( + ctx.module.get(), + intrinsic_name.as_ptr() as _, + function_type, + ) + }; + } + let src1 = src1.get_llvm_value(&mut ctx.names)?; + let src2 = src2.get_llvm_value(&mut ctx.names)?; + let mut args = [src1, src2]; + Ok(ctx.names.register_result_option(dst, |dst_name| unsafe { + LLVMBuildCall2( + builder, + function_type, + function_value, + args.as_mut_ptr(), + 2, + dst_name, + ) + })) +} + +fn emit_inst_bra( + ctx: &mut EmitContext, + args: &ast::Arg1, +) -> Result<(), TranslateError> { + let label = ctx.names.value(args.src)?; + unsafe { LLVMBuildBr(ctx.builder.get(), LLVMValueAsBasicBlock(label)) }; + Ok(()) +} + +fn emit_inst_atom_cas( + ctx: &mut EmitContext, + details: &ast::AtomCasDetails, + args: &ast::Arg4, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let ptr = ctx.names.value(args.src1)?; + let cmp = ctx.names.value(args.src2)?; + let new = ctx.names.value(args.src3)?; + let success_ordering = get_llvm_ordering(details.semantics); + // https://llvm.org/docs/LangRef.html#cmpxchg-instruction + // "the failure ordering cannot be either release or acq_rel" + let failure_ordering = match success_ordering { + LLVMAtomicOrdering::LLVMAtomicOrderingRelease + | LLVMAtomicOrdering::LLVMAtomicOrderingAcquireRelease => { + LLVMAtomicOrdering::LLVMAtomicOrderingAcquire + } + o => o, + }; + let scope = get_llvm_scope(details.scope); + let aggregate_value = unsafe { + LLVMZludaBuildAtomicCmpXchg( + builder, + ptr, + cmp, + new, + scope.as_ptr() as _, + success_ordering, + failure_ordering, + details.typ.size_of() as u32, + ) + }; + // cmpxchg yields a struct { ty, i1 }, we still need to extract the result + ctx.names.register_result(args.dst, |dst_name| unsafe { + LLVMBuildExtractValue(builder, aggregate_value, 0, dst_name) + }); + Ok(()) +} + +fn emit_inst_atom( + ctx: &mut EmitContext, + details: &ast::AtomDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + emit_inst_atom_impl(ctx, details, Some(args.dst), args.src1, args.src2) +} + +fn emit_inst_atom_impl( + ctx: &mut EmitContext, + details: &ast::AtomDetails, + dst: Option, + src1: Id, + src2: Id, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let (atomic_op, type_) = match details.inner { + ast::AtomInnerDetails::Bit { + op: ast::AtomBitOp::And, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpAnd, typ), + ast::AtomInnerDetails::Bit { + op: ast::AtomBitOp::Exchange, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpXchg, typ), + ast::AtomInnerDetails::Bit { + op: ast::AtomBitOp::Or, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpOr, typ), + ast::AtomInnerDetails::Bit { + op: ast::AtomBitOp::Xor, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpXor, typ), + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Add, + typ, + } + | ast::AtomInnerDetails::Signed { + op: ast::AtomSIntOp::Add, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpAdd, typ), + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Max, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpUMax, typ), + ast::AtomInnerDetails::Signed { + op: ast::AtomSIntOp::Max, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpMax, typ), + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Min, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpUMin, typ), + ast::AtomInnerDetails::Signed { + op: ast::AtomSIntOp::Min, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpMin, typ), + ast::AtomInnerDetails::Float { + op: ast::AtomFloatOp::Add, + typ, + } => (LLVMAtomicRMWBinOp::LLVMAtomicRMWBinOpFAdd, typ), + // Converted to a function call in a compiler pass + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Dec, + .. + } + | ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Inc, + .. + } => return Err(TranslateError::unreachable()), + }; + let ordering = get_llvm_ordering(details.semantics); + let scope = get_llvm_scope(details.scope); + let ptr = ctx.names.value(src1)?; + let val = ctx.names.value(src2)?; + let value = unsafe { + LLVMZludaBuildAtomicRMW( + builder, + atomic_op, + ptr, + val, + scope.as_ptr() as _, + ordering, + type_.size_of() as u32, + ) + }; + if let Some(dst) = dst { + ctx.names.register(dst, value); + let name = ctx.names.name(dst); + unsafe { LLVMSetValueName2(value, name.as_ptr(), name.len()) }; + } + Ok(()) +} + +// https://llvm.org/docs/AMDGPUUsage.html#memory-scopes +fn get_llvm_scope(scope: ast::MemScope) -> &'static [u8] { + match scope { + ast::MemScope::Cta => &b"workgroup-one-as\0"[..], + ast::MemScope::Gpu => b"agent-one-as\0", + ast::MemScope::Sys => b"one-as\0", + } +} +// https://llvm.org/docs/AMDGPUUsage.html#memory-scopes +fn get_llvm_scope_for_membar(scope: ast::MemScope) -> &'static [u8] { + match scope { + // HACK ALERT: for reasons that I don't understand emitting workgroup fence for membar.cta + // lead to HIP hand or X11 crashes when running XGBoost tests as of ROCm 5.7.1 + // Probably related to those two: + // https://gitlab.freedesktop.org/drm/amd/-/issues/2145 + // https://projects.blender.org/blender/blender/issues/100353 + // TODO: change it back to "workgroup" when HIP, amdgpu or whoever is responsible for + // the underlying issue fixes it + ast::MemScope::Cta => &b"agent\0"[..], + ast::MemScope::Gpu => b"agent\0", + ast::MemScope::Sys => b"\0", + } +} + +fn get_llvm_ordering(semantics: ast::AtomSemantics) -> LLVMAtomicOrdering { + match semantics { + ast::AtomSemantics::Relaxed => LLVMAtomicOrdering::LLVMAtomicOrderingMonotonic, + ast::AtomSemantics::Acquire => LLVMAtomicOrdering::LLVMAtomicOrderingAcquire, + ast::AtomSemantics::Release => LLVMAtomicOrdering::LLVMAtomicOrderingRelease, + ast::AtomSemantics::AcquireRelease => LLVMAtomicOrdering::LLVMAtomicOrderingAcquireRelease, + } +} + +fn emit_inst_mov( + ctx: &mut EmitContext, + details: &ast::MovDetails, + args: &ast::Arg2Mov, +) -> Result<(), TranslateError> { + emit_value_copy(ctx, &details.typ, ctx.names.value(args.src)?, args.dst) +} + +fn emit_inst_ret(ctx: &mut EmitContext) { + unsafe { LLVMBuildRetVoid(ctx.builder.get()) }; +} + +fn emit_inst_st( + ctx: &mut EmitContext, + details: &ast::StData, + args: &ast::Arg2St, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let val = ctx.names.value(args.src2)?; + let ptr = ctx.names.value(args.src1)?; + if !matches!( + details.qualifier, + ast::LdStQualifier::Weak | ast::LdStQualifier::Volatile + ) { + if let ast::Type::Vector(..) = details.typ { + let integer_layout = details.typ.layout(); + let integer_type = unsafe { + LLVMIntTypeInContext(ctx.context.get(), integer_layout.size() as u32 * u8::BITS) + }; + let pointer_type = unsafe { + LLVMPointerType( + integer_type, + get_llvm_address_space(&ctx.constants, details.state_space)?, + ) + }; + let integer_value = + unsafe { LLVMBuildBitCast(builder, val, integer_type, LLVM_UNNAMED) }; + let pointer_cast_value = + unsafe { LLVMBuildPointerCast(builder, ptr, pointer_type, LLVM_UNNAMED) }; + let result = unsafe { LLVMBuildStore(builder, integer_value, pointer_cast_value) }; + unsafe { apply_qualifier(ctx.context.get(), result, details.qualifier) }; + // Weirdly, for i128 we get default alignment 8 + unsafe { LLVMSetAlignment(result, integer_layout.align() as u32) }; + return Ok(()); + } + } + let result = unsafe { LLVMBuildStore(builder, val, ptr) }; + unsafe { apply_qualifier(ctx.context.get(), result, details.qualifier) }; + Ok(()) +} + +unsafe fn apply_qualifier(ctx: LLVMContextRef, value: LLVMValueRef, qualifier: ast::LdStQualifier) { + unsafe fn apply_qualifier_atomic( + ctx: LLVMContextRef, + value: LLVMValueRef, + ordering: LLVMAtomicOrdering, + scope: ast::MemScope, + ) { + let scope = get_llvm_scope(scope); + LLVMZludaSetAtomic(ctx, value, ordering, scope.as_ptr().cast()); + } + match qualifier { + ast::LdStQualifier::Weak => {} + ast::LdStQualifier::Volatile => LLVMSetVolatile(value, 1), + ast::LdStQualifier::Relaxed(scope) => apply_qualifier_atomic( + ctx, + value, + LLVMAtomicOrdering::LLVMAtomicOrderingMonotonic, + scope, + ), + ast::LdStQualifier::Acquire(scope) => apply_qualifier_atomic( + ctx, + value, + LLVMAtomicOrdering::LLVMAtomicOrderingAcquire, + scope, + ), + ast::LdStQualifier::Release(scope) => apply_qualifier_atomic( + ctx, + value, + LLVMAtomicOrdering::LLVMAtomicOrderingRelease, + scope, + ), + } +} + +fn emit_inst_add( + ctx: &mut EmitContext, + details: &ast::ArithDetails, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + emit_inst_add_impl(ctx, details, args.dst, args.src1, args.src2) +} + +fn emit_inst_add_impl( + ctx: &mut EmitContext, + details: &ast::ArithDetails, + dst: Id, + src1: impl GetLLVMValue, + src2: impl GetLLVMValue, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let function = match details { + ast::ArithDetails::Unsigned(..) | ast::ArithDetails::Signed(..) => LLVMBuildAdd, + ast::ArithDetails::Float(..) => LLVMBuildFAdd, + }; + let src1 = src1.get_llvm_value(&mut ctx.names)?; + let src2 = src2.get_llvm_value(&mut ctx.names)?; + ctx.names.register_result(dst, |dst_name| unsafe { + function(builder, src1, src2, dst_name) + }); + Ok(()) +} + +fn emit_inst_or( + ctx: &mut EmitContext, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildOr(builder, src1, src2, dst) + }); + Ok(()) +} + +fn emit_inst_and( + ctx: &mut EmitContext, + args: &ast::Arg3, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let src1 = ctx.names.value(args.src1)?; + let src2 = ctx.names.value(args.src2)?; + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildAnd(builder, src1, src2, dst) + }); + Ok(()) +} + +fn emit_inst_ld( + ctx: &mut EmitContext, + details: &ast::LdDetails, + args: &ast::Arg2Ld, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let ptr = ctx.names.value(args.src)?; + let vector_type = get_llvm_type(ctx, &details.typ)?; + if !matches!( + details.qualifier, + ast::LdStQualifier::Weak | ast::LdStQualifier::Volatile + ) { + if let ast::Type::Vector(..) = details.typ { + let integer_layout = details.typ.layout(); + let integer_type = unsafe { + LLVMIntTypeInContext(ctx.context.get(), integer_layout.size() as u32 * u8::BITS) + }; + let pointer_type = unsafe { + LLVMPointerType( + integer_type, + get_llvm_address_space(&ctx.constants, details.state_space)?, + ) + }; + let pointer_cast_value = + unsafe { LLVMBuildPointerCast(builder, ptr, pointer_type, LLVM_UNNAMED) }; + let integer_result = + unsafe { LLVMBuildLoad2(builder, integer_type, pointer_cast_value, LLVM_UNNAMED) }; + unsafe { apply_qualifier(ctx.context.get(), integer_result, details.qualifier) }; + // Weirdly, for i128 we get default alignment 8 + unsafe { LLVMSetAlignment(integer_result, integer_layout.align() as u32) }; + ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildBitCast(builder, integer_result, vector_type, dst) + }); + return Ok(()); + } + } + let result = ctx.names.register_result(args.dst, |dst| unsafe { + LLVMBuildLoad2(builder, vector_type, ptr, dst) + }); + unsafe { apply_qualifier(ctx.context.get(), result, details.qualifier) }; + Ok(()) +} + +fn emit_load_var( + ctx: &mut EmitContext, + load: &crate::translate::LoadVarDetails, +) -> Result<(), TranslateError> { + let builder = ctx.builder.get(); + let mut src = ctx.names.value(load.arg.src)?; + if let Some((idx, width)) = load.member_index { + // TODO: improve + let vector_type = match load.typ { + ast::Type::Scalar(scalar_t) => ast::Type::Vector(scalar_t, width), + _ => return Err(TranslateError::mismatched_type()), + }; + let llvm_type = get_llvm_type(ctx, &vector_type)?; + let llvm_i32 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + let zero_llvm = unsafe { LLVMConstInt(llvm_i32, 0, 0) }; + let index_llvm = unsafe { LLVMConstInt(llvm_i32, idx as _, 0) }; + let indices = [zero_llvm, index_llvm]; + src = unsafe { + LLVMBuildInBoundsGEP2( + builder, + llvm_type, + src, + indices.as_ptr() as _, + 2, + LLVM_UNNAMED, + ) + }; + } + let llvm_type = get_llvm_type(ctx, &load.typ)?; + ctx.names.register_result(load.arg.dst, |dst| unsafe { + LLVMBuildLoad2(builder, llvm_type, src, dst) + }); + Ok(()) +} + +fn emit_store_var( + ctx: &mut EmitContext, + store: &crate::translate::StoreVarDetails, +) -> Result<(), TranslateError> { + let mut ptr = ctx.names.value(store.arg.src1)?; + if let Some(index) = store.member_index { + let llvm_i32 = get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::U32))?; + let zero_llvm = unsafe { LLVMConstInt(llvm_i32, 0, 0) }; + let index_llvm = unsafe { LLVMConstInt(llvm_i32, index as _, 0) }; + let indices = [zero_llvm, index_llvm]; + let gep_type = get_llvm_type(ctx, &store.type_)?; + ptr = unsafe { + LLVMBuildInBoundsGEP2( + ctx.builder.get(), + gep_type, + ptr, + indices.as_ptr() as _, + 2, + LLVM_UNNAMED, + ) + }; + }; + let val = ctx.names.value(store.arg.src2)?; + unsafe { LLVMBuildStore(ctx.builder.get(), val, ptr) }; + Ok(()) +} + +fn emit_label(ctx: &mut EmitContext, label: Id) -> Result<(), TranslateError> { + let new_block = unsafe { LLVMValueAsBasicBlock(ctx.names.value(label)?) }; + terminate_current_block_if_needed(ctx, new_block); + unsafe { LLVMPositionBuilderAtEnd(ctx.builder.get(), new_block) }; + Ok(()) +} + +fn terminate_current_block_if_needed(ctx: &mut EmitContext, new_block: LLVMBasicBlockRef) { + let current_block = unsafe { LLVMGetInsertBlock(ctx.builder.get()) }; + if current_block == ptr::null_mut() { + return; + } + let terminator = unsafe { LLVMGetBasicBlockTerminator(current_block) }; + if terminator != ptr::null_mut() { + return; + } + unsafe { LLVMBuildBr(ctx.builder.get(), new_block) }; +} + +fn emit_method_declaration<'input>( + ctx: &mut EmitContext, + method: &crate::translate::Function<'input>, +) -> Result { + if let Some(llvm_decl) = ctx.names.try_value(method.name) { + // We rename function args if the function was already declared, because fn + // declaration and definition have different ids in arguments + if method.body.is_some() { + for (idx, input_arg) in method.input_arguments.iter().enumerate() { + let llvm_param = unsafe { LLVMGetParam(llvm_decl, idx as u32) }; + ctx.names.register(input_arg.name, llvm_param); + let name = ctx.names.name(input_arg.name); + unsafe { + LLVMSetValueName2(llvm_param, name.as_ptr(), name.len()); + } + } + } + return Ok(llvm_decl); + } + let name_ptr = ctx.names.name_ptr(method.name); + let call_conv = if method.is_kernel { + ctx.constants.kernel_callconv + } else { + ctx.constants.function_callconv + }; + let input_types = method + .input_arguments + .iter() + .map(|var| (&var.type_, var.state_space)); + let return_type = match &*method.return_arguments { + [] => llvm::void_type(&ctx.context), + [var] => get_llvm_type(ctx, &var.type_)?, + [..] => get_llvm_type_struct( + ctx, + method + .return_arguments + .iter() + .map(|var| Cow::Borrowed(&var.type_)), + )?, + }; + let fn_type = get_llvm_function_type(ctx, return_type, input_types)?; + let llvm_func = unsafe { LLVMAddFunction(ctx.module.get(), name_ptr, fn_type) }; + ctx.names.register(method.name, llvm_func); + unsafe { LLVMSetFunctionCallConv(llvm_func, call_conv as u32) }; + emit_denorm(ctx, method.name, llvm_func); + emit_llvm_string_attribute(ctx, llvm_func, b"amdgpu-unsafe-fp-atomics", b"true"); + emit_llvm_string_attribute(ctx, llvm_func, b"no-trapping-math", b"true"); + emit_llvm_string_attribute(ctx, llvm_func, b"uniform-work-group-size", b"true"); + // TODO: split this into a kernel/app-profile + if ctx.compilation_mode != CompilationMode::Wave32 { + if let Some(ref name) = method.source_name { + if name.contains("IN9LAMMPS_NS") { + emit_llvm_string_attribute( + ctx, + llvm_func, + b"amdgpu-flat-work-group-size", + b"1,512", + ); + } + } + } + for (idx, input_arg) in method.input_arguments.iter().enumerate() { + let llvm_param = unsafe { LLVMGetParam(llvm_func, idx as u32) }; + ctx.names.register(input_arg.name, llvm_param); + let name = ctx.names.name(input_arg.name); + unsafe { + LLVMSetValueName2(llvm_param, name.as_ptr(), name.len()); + } + let llvm_param = unsafe { LLVMGetParam(llvm_func, idx as u32) }; + if method.is_kernel { + unsafe { + if let Some(align) = input_arg.align { + LLVMSetParamAlignment(llvm_param, align); + } + let attr_kind = + LLVMGetEnumAttributeKindForName(b"byref".as_ptr().cast(), b"byref".len()); + if attr_kind == 0 { + panic!(); + } + let attr = LLVMCreateTypeAttribute( + ctx.context.get(), + attr_kind, + get_llvm_type(ctx, &input_arg.type_)?, + ); + LLVMAddAttributeAtIndex(llvm_func, idx as u32 + 1, attr); + } + } + } + Ok(llvm_func) +} + +fn emit_denorm(ctx: &mut EmitContext, method_name: Id, llvm_func: *mut LLVMValue) { + let maybe_denorm_summary = ctx.denorm_statistics.get(&method_name).copied(); + if let Some(denorm_summary) = maybe_denorm_summary { + emit_denorm_attribute(ctx, llvm_func, b"denormal-fp-math", denorm_summary.f16f64); + emit_denorm_attribute(ctx, llvm_func, b"denormal-fp-math-f32", denorm_summary.f32); + } +} + +fn emit_denorm_attribute( + ctx: &mut EmitContext, + new_llvm_func: LLVMValueRef, + denorm_key: &'static [u8], + denorm_value: FPDenormMode, +) { + let denorm_mode_value = match denorm_value { + FPDenormMode::FlushToZero => &b"preserve-sign,preserve-sign"[..], + FPDenormMode::Preserve => b"ieee,ieee", + }; + emit_llvm_string_attribute(ctx, new_llvm_func, denorm_key, denorm_mode_value); +} + +fn emit_llvm_string_attribute( + ctx: &mut EmitContext, + llvm_func: LLVMValueRef, + key: &[u8], + value: &[u8], +) { + let denorm_attr = unsafe { + LLVMCreateStringAttribute( + ctx.context.get(), + key.as_ptr() as _, + key.len() as u32, + value.as_ptr() as _, + value.len() as u32, + ) + }; + unsafe { LLVMAddAttributeAtIndex(llvm_func, LLVMAttributeFunctionIndex, denorm_attr) }; +} + +fn get_llvm_type(ctx: &EmitContext, type_: &ast::Type) -> Result { + unsafe { + Ok(match type_ { + ast::Type::Scalar(scalar) => match scalar { + ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => { + LLVMInt8TypeInContext(ctx.context.get()) + } + ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => { + LLVMInt16TypeInContext(ctx.context.get()) + } + ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => { + LLVMInt32TypeInContext(ctx.context.get()) + } + ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => { + LLVMInt64TypeInContext(ctx.context.get()) + } + ast::ScalarType::F16 => LLVMHalfTypeInContext(ctx.context.get()), + ast::ScalarType::F32 => LLVMFloatTypeInContext(ctx.context.get()), + ast::ScalarType::F64 => LLVMDoubleTypeInContext(ctx.context.get()), + ast::ScalarType::F16x2 => LLVMVectorType( + get_llvm_type(ctx, &ast::Type::Scalar(ast::ScalarType::F16))?, + 2, + ), + ast::ScalarType::Pred => LLVMInt1TypeInContext(ctx.context.get()), + }, + ast::Type::Vector(scalar_type, count) => LLVMVectorType( + get_llvm_type(ctx, &ast::Type::Scalar(*scalar_type))?, + *count as u32, + ), + ast::Type::Array(scalar_type, dims) => { + let llvm_type_scalar = get_llvm_type(ctx, &ast::Type::Scalar(*scalar_type))?; + get_llvm_array_type(llvm_type_scalar, &*dims) + } + ast::Type::Pointer(scalar_type, state_space) => { + get_llvm_pointer_type(ctx, &ast::Type::Scalar(*scalar_type), *state_space)? + } + ast::Type::Texref | ast::Type::Surfref => ctx.texref_underlying_type, + ast::Type::Struct(fields) => get_llvm_type_struct( + ctx, + fields + .iter() + .map(|struct_field| Cow::Owned(struct_field.to_type())), + )?, + }) + } +} + +fn get_anonymous_struct_type( + ctx: &EmitContext, + fields: [ast::ScalarType; N], +) -> Result { + let mut fields = IntoIterator::into_iter(fields) + .map(|scalar| get_llvm_type(ctx, &ast::Type::Scalar(scalar))) + .collect::, _>>()?; + Ok(unsafe { + LLVMStructTypeInContext( + ctx.context.get(), + fields.as_mut_ptr(), + fields.len() as u32, + 0, + ) + }) +} + +fn get_llvm_pointer_type( + ctx: &EmitContext, + type_: &ast::Type, + state_space: ast::StateSpace, +) -> Result { + let underlying_dst_type = get_llvm_type(ctx, type_)?; + let address_space = get_llvm_address_space(&ctx.constants, state_space)?; + Ok(unsafe { LLVMPointerType(underlying_dst_type, address_space) }) +} + +fn get_llvm_function_type<'a>( + ctx: &mut EmitContext, + return_type: LLVMTypeRef, + param_types: impl Iterator, +) -> Result { + let mut llvm_types = param_types + .map(|(type_, space)| get_method_input_type(ctx, type_, space)) + .collect::, _>>()?; + unsafe { + Ok(LLVMFunctionType( + return_type, + llvm_types.as_mut_ptr(), + llvm_types.len() as u32, + 0, + )) + } +} + +fn get_method_input_type( + ctx: &mut EmitContext, + type_: &ast::Type, + state_space: ast::StateSpace, +) -> Result { + if state_space != ast::StateSpace::Reg { + get_llvm_pointer_type(ctx, type_, state_space) + } else { + get_llvm_type(ctx, type_) + } +} + +fn get_llvm_address_space( + constants: &Constants, + state_space: ast::StateSpace, +) -> Result { + Ok(match state_space { + ast::StateSpace::Reg => constants.private_space, + ast::StateSpace::Const => constants.constant_space, + ast::StateSpace::Global => constants.global_space, + ast::StateSpace::Local => constants.private_space, + ast::StateSpace::Shared => constants.shared_space, + // Should be removed by deparamize passes during translation + ast::StateSpace::Param => return Err(TranslateError::unreachable()), + ast::StateSpace::Generic => constants.generic_space, + ast::StateSpace::Sreg => constants.private_space, + }) +} + +unsafe fn get_llvm_array_type(inner_type: LLVMTypeRef, dims: &[u32]) -> LLVMTypeRef { + match dims.split_last() { + Some((dim, dims)) => { + let current_array_type = LLVMArrayType(inner_type, *dim); + if dims.len() > 0 { + get_llvm_array_type(current_array_type, dims) + } else { + current_array_type + } + } + None => LLVMArrayType(inner_type, 0), + } +} + +// That is not spelled explicitly in LLVM LangRef, but the difference between linkage and visibility: +// * Linkage applies during LLVM linking step, is visible in the single LLVM IR module +// * Visibility appplies post-LLVM linking, is visible in the resulting ELF binary +// So e.g. difference between private linkage and hidden visibility is: +// * With private linkage, symbol is removed during LLVM linking phase and just not present from that point on +// * With hidden visibility, symbol survives LLVM linking, but is emitted into ELF with HIDDEN visibility +fn emit_linkage_for_variable( + space: ast::StateSpace, + value: LLVMValueRef, + globally_visible: bool, +) -> Result<(), TranslateError> { + let (visibility, linking) = if globally_visible { + ( + if space == ast::StateSpace::Shared { + LLVMVisibility::LLVMHiddenVisibility + } else { + LLVMVisibility::LLVMProtectedVisibility + }, + LLVMLinkage::LLVMExternalLinkage, + ) + } else { + ( + // Local (private or internal linkage) requires default visibility + LLVMVisibility::LLVMDefaultVisibility, + LLVMLinkage::LLVMPrivateLinkage, + ) + }; + unsafe { LLVMSetLinkage(value, linking) }; + unsafe { LLVMSetVisibility(value, visibility) }; + Ok(()) +} + +fn emit_linkage_for_method<'input>( + method: &crate::translate::Function<'input>, + is_kernel: bool, + value: LLVMValueRef, +) { + // There's a little bit of mismatch between ZLUDA and LLVM view of the world. + // ZLUDA can have a function declared multiple times (and defined once) whereas + // in LLVM a function can be either defined or declared (and only once). Additionally, + // LLVM declarations are always global and external. Which are defaults when creating + // LLVM function objects + // For this reason we don't emit linkage&visibility for pure declarations + if method.body.is_none() { + return; + } + let (visibility, linking) = + if method.special_raytracing_linking || (is_kernel && method.source_name.is_some()) { + ( + LLVMVisibility::LLVMProtectedVisibility, + LLVMLinkage::LLVMExternalLinkage, + ) + } else { + ( + // Local (private or internal linkage) requires default visibility + LLVMVisibility::LLVMDefaultVisibility, + LLVMLinkage::LLVMPrivateLinkage, + ) + }; + unsafe { LLVMSetLinkage(value, linking) }; + unsafe { LLVMSetVisibility(value, visibility) }; +} + +trait GetLLVMValue { + fn get_llvm_value(self, names: &mut NamedIdGenerator) -> Result; +} + +impl GetLLVMValue for LLVMValueRef { + fn get_llvm_value(self, _names: &mut NamedIdGenerator) -> Result { + Ok(self) + } +} + +impl GetLLVMValue for Id { + fn get_llvm_value(self, names: &mut NamedIdGenerator) -> Result { + names.value(self) + } +} + +impl ast::ScalarType { + fn llvm_display(self) -> ScalarTypeLLVMDisplay { + ScalarTypeLLVMDisplay(self) + } +} + +struct ScalarTypeLLVMDisplay(ast::ScalarType); + +impl Display for ScalarTypeLLVMDisplay { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.0 { + ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => write!(f, "i8"), + ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => write!(f, "i16"), + ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => write!(f, "i32"), + ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => write!(f, "i64"), + ast::ScalarType::F16 => write!(f, "f16"), + ast::ScalarType::F32 => write!(f, "f32"), + ast::ScalarType::F64 => write!(f, "f64"), + ast::ScalarType::F16x2 => write!(f, "v2f16"), + ast::ScalarType::Pred => write!(f, "i1"), + } + } +} + +#[cfg(test)] +mod tests { + use super::NamedIdGenerator; + use crate::translate::IdGenerator; + use rustc_hash::FxHashMap; + use std::{mem, slice}; + + #[test] + fn name_cache_returns_correct_result_for_first_10002_ids() { + let mut id_gen = IdGenerator::new(); + let ids = id_gen.reserve(10002); + let names = NamedIdGenerator::new(id_gen, &FxHashMap::default(), &[]); + for id in ids { + let mut reference = id.get().to_string(); + reference.push('\0'); + let ptr = names.name_ptr(id) as *const u8; + let computed = unsafe { slice::from_raw_parts(ptr as _, reference.len()) }; + assert_eq!(reference.as_bytes(), computed); + let computed_slice = names.name(id); + assert_eq!(reference.as_bytes().split_last().unwrap().1, unsafe { + mem::transmute::<_, &[u8]>(computed_slice) + }); + } + } +} diff --git a/ptx/src/lib.rs b/ptx/src/lib.rs index 591428f..ea30a5a 100644 --- a/ptx/src/lib.rs +++ b/ptx/src/lib.rs @@ -2,56 +2,497 @@ 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; +extern crate hip_runtime_sys as hip; -#[cfg(test)] -extern crate spirv_tools_sys as spirv_tools; - -#[macro_use] -extern crate bitflags; - -lalrpop_mod!( - #[allow(warnings)] - ptx -); +lalrpop_mod!(ptx); pub mod ast; +mod emit; +pub mod llvm; +pub mod raytracing; #[cfg(test)] mod test; -mod translate; +pub mod translate; pub use crate::ptx::ModuleParser; +use ast::PtxError; 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; +use std::fmt; +pub use translate::to_llvm_module; +pub use translate::to_llvm_module_for_raytracing; +pub use translate::Module; pub use translate::TranslateError; -pub(crate) fn without_none(x: Vec>) -> Vec { - x.into_iter().filter_map(|x| x).collect() +pub trait ModuleParserExt { + fn parse_checked<'input>( + txt: &'input str, + ) -> Result, Vec, ast::PtxError>>>; + + // Returned AST might be malformed. Some users, like logger, want to look at + // malformed AST to record information - list of kernels or such + fn parse_unchecked<'input>( + txt: &'input str, + ) -> ( + ast::Module<'input>, + Vec, ast::PtxError>>, + ); } -pub(crate) fn vector_index<'input>( - inp: &'input str, -) -> Result, 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, - }), +impl ModuleParserExt for ModuleParser { + fn parse_checked<'input>( + txt: &'input str, + ) -> Result, Vec, ast::PtxError>>> { + let mut errors = Vec::new(); + let maybe_ast = ptx::ModuleParser::new().parse(&mut errors, txt); + match (&*errors, maybe_ast) { + (&[], Ok(ast)) => Ok(ast), + (_, Err(unrecoverable)) => { + errors.push(unrecoverable); + Err(errors) + } + (_, Ok(_)) => Err(errors), + } + } + + fn parse_unchecked<'input>( + txt: &'input str, + ) -> ( + ast::Module<'input>, + Vec, ast::PtxError>>, + ) { + let mut errors = Vec::new(); + let maybe_ast = ptx::ModuleParser::new().parse(&mut errors, txt); + let ast = match maybe_ast { + Ok(ast) => ast, + Err(unrecoverable_err) => { + errors.push(unrecoverable_err); + ast::Module { + sm_version: 0, + directives: Vec::new(), + } + } + }; + (ast, errors) + } +} + +pub struct DisplayParseError<'a, Loc, Tok, Err>(&'a str, &'a ParseError); + +impl<'a, Loc: fmt::Display + Into + Copy, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { + // unsafe because there's no guarantee that the input str is the one that this error was created from + pub unsafe fn new(error: &'a ParseError, text: &'a str) -> Self { + Self(text, error) + } +} + +impl<'a, Loc, Tok> fmt::Display for DisplayParseError<'a, Loc, Tok, PtxError> +where + Loc: fmt::Display, + Tok: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.1 { + ParseError::User { + error: PtxError::UnrecognizedStatement { start, end }, + } => self.fmt_unrecognized(f, *start, *end, "statement"), + ParseError::User { + error: PtxError::UnrecognizedDirective { start, end }, + } => self.fmt_unrecognized(f, *start, *end, "directive"), + _ => self.1.fmt(f), + } + } +} + +impl<'a, Loc, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { + fn fmt_unrecognized( + &self, + f: &mut fmt::Formatter, + start: usize, + end: usize, + kind: &'static str, + ) -> fmt::Result { + let full_substring = unsafe { self.0.get_unchecked(start..end) }; + write!( + f, + "Unrecognized {} `{}` found at {}:{}", + kind, full_substring, start, end + ) + } +} + +pub(crate) mod lalrpop { + use crate::ast; + use lalrpop_util::{lexer::Token, ParseError}; + + enum ConstTypeMut<'a> { + Type(&'a mut ast::Type), + ArraySubtype(ast::ScalarType, &'a mut [u32]), + } + + pub(crate) fn validate_variable_declaration2<'input>( + variable: &mut ast::MultiVariableDefinition<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) { + if variable.variable.name == "_" { + errors.push(ParseError::User { + error: ast::PtxError::BlankVariableName, + }); + } + if let Some(suffix) = &mut variable.suffix { + type_check_suffix(&mut variable.variable.type_, suffix, errors); + } + match variable.variable.type_ { + ast::Type::Array(_, ref dims) => { + if dims.len() > 1 && dims.contains(&0) { + errors.push(ParseError::User { + error: ast::PtxError::ZeroDimensionArray, + }); + } + } + _ => {} + } + } + + fn type_check_suffix<'input>( + type_: &mut ast::Type, + suffix: &mut ast::DeclarationSuffix<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) { + match suffix { + ast::DeclarationSuffix::Count(_) => { + if matches!(type_, ast::Type::Array(..)) { + errors.push(ParseError::User { + error: ast::PtxError::MultiArrayVariable, + }); + } + } + ast::DeclarationSuffix::Initializer(initializer) => { + type_check_initializer(ConstTypeMut::Type(type_), initializer, errors); + } + } + } + + fn type_check_initializer<'input>( + type_: ConstTypeMut, + initializer: &mut ast::Initializer<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) { + match (initializer, type_) { + // Constant + ( + ast::Initializer::Constant(immediate), + ConstTypeMut::Type(ast::Type::Scalar(scalar)), + ) => { + if !immediate_is_type_compatible(immediate, *scalar) { + errors.push(ParseError::User { + error: ast::PtxError::InitializerTypeMismatch, + }); + } + } + // Array + ( + ast::Initializer::Array(sub_inits), + ConstTypeMut::Type(ast::Type::Array(ref mut scalar, dims)), + ) => { + type_check_pad_array(*scalar, sub_inits, dims, false, errors); + } + ( + ast::Initializer::Array(sub_inits), + ConstTypeMut::ArraySubtype(ref mut scalar, dims), + ) => { + type_check_pad_array(*scalar, sub_inits, dims, true, errors); + } + (ast::Initializer::Array(..), _) + | (_, ConstTypeMut::Type(ast::Type::Array(..))) + | (_, ConstTypeMut::ArraySubtype(..)) => { + errors.push(ParseError::User { + error: ast::PtxError::ArrayInitializer, + }); + } + // Global + (ast::Initializer::Global(..), ConstTypeMut::Type(ast::Type::Scalar(scalar))) + | ( + ast::Initializer::GenericGlobal(..), + ConstTypeMut::Type(ast::Type::Scalar(scalar)), + ) => check_global_type(*scalar, errors), + // Add + (ast::Initializer::Add(add), ConstTypeMut::Type(type_ @ ast::Type::Scalar(_))) => { + type_check_initializer(ConstTypeMut::Type(type_), &mut add.0, errors); + type_check_initializer(ConstTypeMut::Type(type_), &mut add.1, errors); + } + _ => { + errors.push(ParseError::User { + error: ast::PtxError::InitializerTypeMismatch, + }); + } + } + } + + fn immediate_is_type_compatible( + immediate: &mut ast::ImmediateValue, + scalar: ast::ScalarType, + ) -> bool { + let type_kind = scalar.kind(); + match immediate { + ast::ImmediateValue::U64(_) | ast::ImmediateValue::S64(_) => { + matches!( + type_kind, + ast::ScalarKind::Bit + | ast::ScalarKind::Signed + | ast::ScalarKind::Unsigned + | ast::ScalarKind::Pred + ) + } + ast::ImmediateValue::F32(_) | ast::ImmediateValue::F64(_) => { + matches!(type_kind, ast::ScalarKind::Float) + } + } + } + + fn type_check_pad_array<'input>( + scalar: ast::ScalarType, + initializers: &mut Vec>, + dims: &mut [u32], + subarray: bool, + errors: &mut Vec, ast::PtxError>>, + ) { + match dims.first_mut() { + Some(x) => { + if *x == 0 { + if subarray { + errors.push(ParseError::User { + error: ast::PtxError::ZeroDimensionArray, + }); + } else { + *x = initializers.len() as u32; + } + } + } + None => { + errors.push(ParseError::User { + error: ast::PtxError::SyntaxError, + }); + return; + } + } + zero_pad_initializers(scalar, initializers, dims, errors); + for initializer in initializers { + if dims.len() == 1 { + type_check_initializer( + ConstTypeMut::Type(&mut ast::Type::Scalar(scalar)), + initializer, + errors, + ); + } else { + type_check_initializer( + ConstTypeMut::ArraySubtype(scalar, &mut dims[1..]), + initializer, + errors, + ); + } + } + } + + fn zero_pad_initializers<'input>( + scalar: ast::ScalarType, + initializers: &mut Vec>, + dims: &[u32], + errors: &mut Vec, ast::PtxError>>, + ) { + let expected_len = dims[0] as usize; + if expected_len == initializers.len() { + return; + } else if expected_len > initializers.len() { + if dims.len() > 1 { + initializers.resize_with(expected_len, || ast::Initializer::Array(Vec::new())); + } else { + initializers.resize_with(expected_len, || default_initializer_for(scalar)); + } + } else { + errors.push(ParseError::User { + error: ast::PtxError::InitializerTypeMismatch, + }); + } + } + + fn default_initializer_for<'input>(scalar: ast::ScalarType) -> ast::Initializer<&'input str> { + ast::Initializer::Constant(match scalar { + ast::ScalarType::B8 + | ast::ScalarType::B16 + | ast::ScalarType::B32 + | ast::ScalarType::B64 + | ast::ScalarType::U8 + | ast::ScalarType::U16 + | ast::ScalarType::U32 + | ast::ScalarType::U64 + | ast::ScalarType::S8 + | ast::ScalarType::S16 + | ast::ScalarType::S32 + | ast::ScalarType::S64 + | ast::ScalarType::Pred => ast::ImmediateValue::U64(0), + ast::ScalarType::F16 + | ast::ScalarType::F32 + | ast::ScalarType::F64 + | ast::ScalarType::F16x2 => ast::ImmediateValue::F64(0.0), + }) + } + + fn check_global_type<'input>( + scalar: ast::ScalarType, + errors: &mut Vec, ast::PtxError>>, + ) { + if scalar != ast::ScalarType::B64 + && scalar != ast::ScalarType::U64 + && scalar != ast::ScalarType::B64 + && scalar != ast::ScalarType::U64 + { + errors.push(ParseError::User { + error: ast::PtxError::InitializerTypeMismatch, + }); + } + } + + pub(crate) fn make_array_type<'input>( + type_: ast::Type, + array_dimensions: Option>, + errors: &mut Vec, ast::PtxError>>, + ) -> ast::Type { + match array_dimensions { + Some(dimensions) => match type_ { + ast::Type::Scalar(type_) => ast::Type::Array(type_, dimensions), + _ => { + errors.push(ParseError::User { + error: ast::PtxError::NonScalarArray, + }); + type_ + } + }, + None => type_, + } + } + + pub(crate) fn validate_variable_declaration_func<'input>( + variable: ast::VariableDeclaration<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) -> ast::VariableDeclaration<&'input str> { + validate_variable_declaration_impl( + variable, + errors, + &[ast::StateSpace::Reg, ast::StateSpace::Param], + false, + ) + } + + pub(crate) fn validate_variable_declaration_entry<'input>( + variable: ast::VariableDeclaration<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) -> ast::VariableDeclaration<&'input str> { + validate_variable_declaration_impl(variable, errors, &[ast::StateSpace::Param], false) + } + + pub(crate) fn validate_variable_declaration_proto<'input>( + variable: ast::VariableDeclaration<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) -> ast::VariableDeclaration<&'input str> { + validate_variable_declaration_impl( + variable, + errors, + &[ast::StateSpace::Reg, ast::StateSpace::Param], + true, + ) + } + + pub(crate) fn validate_variable_declaration_impl<'input>( + variable: ast::VariableDeclaration<&'input str>, + errors: &mut Vec, ast::PtxError>>, + allowed: &[ast::StateSpace], + allow_blank_name: bool, + ) -> ast::VariableDeclaration<&'input str> { + if !allowed.contains(&variable.state_space) { + errors.push(ParseError::User { + error: ast::PtxError::InvalidStateSpace, + }); + } + if !allow_blank_name && variable.name == "_" { + errors.push(ParseError::User { + error: ast::PtxError::BlankVariableName, + }); + } + variable + } + + pub(crate) fn report_incorrect_variable<'input>( + variable: &ast::VariableDeclaration<&'input str>, + errors: &mut Vec, ast::PtxError>>, + ) { + // Not mentioned in the docs + if variable.state_space != ast::StateSpace::Reg + && variable.type_ == ast::Type::Scalar(ast::ScalarType::Pred) + { + errors.push(ParseError::User { + error: ast::PtxError::NonRegPredVariable, + }); + } + // "Vectors must be based on a fundamental type, and they may reside in the register space" + // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#variable-declarations + if variable.state_space != ast::StateSpace::Reg + && matches!(variable.type_, ast::Type::Vector(..)) + { + errors.push(ParseError::User { + error: ast::PtxError::NonRegPredVariable, + }); + } + } + + pub(crate) fn without_none(x: Vec>) -> Vec { + x.into_iter().filter_map(|x| x).collect() + } + + pub(crate) fn vector_index<'input>( + inp: &'input str, + ) -> Result, 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, + }), + } + } +} + +#[cfg(test)] +mod tests { + use crate::{DisplayParseError, ModuleParser, ModuleParserExt}; + + #[test] + fn error_report_unknown_instructions() { + let module = r#" + .version 6.5 + .target sm_30 + .address_size 64 + + .visible .entry add( + .param .u64 input, + ) + { + .reg .u64 x; + does_not_exist.u64 x, x; + ret; + }"#; + let errors = match ModuleParser::parse_checked(module) { + Err(e) => e, + Ok(_) => panic!(), + }; + assert_eq!(errors.len(), 1); + let reporter = DisplayParseError(module, &errors[0]); + let build_log_string = format!("{}", reporter); + assert!(build_log_string.contains("does_not_exist")); } } diff --git a/ptx/src/llvm.rs b/ptx/src/llvm.rs new file mode 100644 index 0000000..98a17fd --- /dev/null +++ b/ptx/src/llvm.rs @@ -0,0 +1,181 @@ +/* + * This is a minimal home-made LLVM wrapper, we don't use: + * Inkwell: it's too strongly-typed (splitting Value into variants) and does not + * expose underlying raw LLVM value + * LLVM-ir: can't emit code + * rustc_codegen_llvm: the best of the bunch, but too much work to split it out + */ + +use std::error::Error; +use std::ffi::CStr; +use std::fmt::{self, Debug, Display}; +use std::mem; +use std::ptr; + +use zluda_llvm::analysis::*; +use zluda_llvm::core::*; +use zluda_llvm::prelude::*; + +macro_rules! llvm_wrapper { + ($([ + $rust_name:ident, + $llvm_name:path, + $ctor:ident( $($arg_name:ident : $arg_type: ty),* ), + $dtor:path + ]),+) => { + $( + pub struct $rust_name($llvm_name); + + impl Drop for $rust_name { + fn drop(&mut self) { + unsafe { $dtor(self.0) } + } + } + + impl $rust_name { + #[allow(non_snake_case, dead_code)] + pub(crate) unsafe fn create( $($arg_name : $arg_type),* ) -> $rust_name { + $rust_name($ctor( $($arg_name),* )) + } + + #[allow(non_snake_case, dead_code)] + pub(crate) unsafe fn from_ffi(x: $llvm_name) -> $rust_name { + $rust_name(x) + } + + #[allow(dead_code)] + pub(crate) fn get(&self) -> $llvm_name { + self.0 + } + } + )+ + }; +} + +llvm_wrapper!( + [ + Context, + LLVMContextRef, + LLVMContextCreate(), + LLVMContextDispose + ], + [ + Module, + LLVMModuleRef, + LLVMModuleCreateWithNameInContext(ModuleID: *const i8, C: LLVMContextRef), + LLVMDisposeModule + ], + [ + Builder, + LLVMBuilderRef, + LLVMCreateBuilderInContext(C: LLVMContextRef), + LLVMDisposeBuilder + ], + [ + MemoryBuffer, + LLVMMemoryBufferRef, + LLVMCreateMemoryBufferWithMemoryRangeCopy( + InputData: *const std::os::raw::c_char, + InputDataLength: usize, + BufferName: *const std::os::raw::c_char + ), + LLVMDisposeMemoryBuffer + ] +); + +impl Module { + pub(crate) fn verify(&self) -> Option { + let mut msg = ptr::null_mut(); + let is_broken = unsafe { + LLVMVerifyModule( + self.get(), + LLVMVerifierFailureAction::LLVMReturnStatusAction, + &mut msg, + ) + }; + if is_broken != 0 { + Some(Message::from_ffi(msg)) + } else { + None + } + } +} + +impl MemoryBuffer { + pub unsafe fn create_no_copy(input: &[T], requires_null_terminator: bool) -> Self { + let mut len = input.len(); + if requires_null_terminator { + len -= 1; + } + MemoryBuffer(LLVMCreateMemoryBufferWithMemoryRange( + input.as_ptr() as _, + len * mem::size_of::(), + ptr::null_mut(), + if requires_null_terminator { 1 } else { 0 }, + )) + } + + pub fn as_slice<'a>(&'a self) -> &'a [u8] { + let len = unsafe { LLVMGetBufferSize(self.get()) }; + let start = unsafe { LLVMGetBufferStart(self.get()) }; + unsafe { std::slice::from_raw_parts(start as _, len) } + } +} + +impl AsRef<[u8]> for MemoryBuffer { + fn as_ref(&self) -> &[u8] { + self.as_slice() + } +} + +#[cfg(test)] +pub(crate) unsafe fn parse_ir_in_context( + context: &Context, + mem_buf: MemoryBuffer, +) -> Result { + use zluda_llvm::ir_reader::*; + let mut module = ptr::null_mut(); + let mut message = ptr::null_mut(); + let result = LLVMParseIRInContext(context.get(), mem_buf.get(), &mut module, &mut message); + mem::forget(mem_buf); + if result == 0 { + Ok(Module::from_ffi(module)) + } else { + Err(Message(message)) + } +} +pub struct Message(*mut i8); + +impl Error for Message {} + +impl Debug for Message { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { + Display::fmt(self, f) + } +} + +impl Display for Message { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_cstr().to_str().map_err(|_| fmt::Error)?) + } +} + +impl Message { + pub(crate) fn as_cstr<'a>(&'a self) -> &'a CStr { + unsafe { CStr::from_ptr(self.0) } + } + + pub(crate) fn from_ffi(msg: *mut i8) -> Self { + Self(msg) + } +} + +impl Drop for Message { + fn drop(&mut self) { + unsafe { LLVMDisposeMessage(self.0) }; + } +} + +pub(crate) fn void_type(llvm_ctx: &Context) -> LLVMTypeRef { + unsafe { LLVMVoidTypeInContext(llvm_ctx.get()) } +} diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index fd2a3f1..88c3699 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -1,2004 +1,2772 @@ -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); - -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) = { - => { - if s.ends_with('U') { - (&s[2..s.len() - 1], 16, true) - } else { - (&s[2..], 16, false) - } - }, - => { - 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 = { - =>? { - 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 = { - =>? { - 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 = { - =>? { - 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 = { - =>? { - 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 = { - =>? { - 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> = { - Target => { - ast::Module { version: v, directives: without_none(d) } - } -}; - -Version: (u8, u8) = { - ".version" => { - let dot = v.find('.').unwrap(); - let major = v[..dot].parse::(); - let minor = v[dot+1..].parse::(); - (major,minor).unwrap_with(errors) - } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target -Target = { - ".target" Comma -}; - -TargetSpecifier = { - ShaderModel, - "texmode_unified", - "texmode_independent", - "debug", - "map_f64_to_f32" -}; - -Directive: Option>> = { - AddressSize => None, - => Some(ast::Directive::Method(f)), - File => None, - Section => None, - ";" => Some(ast::Directive::Variable(v)), -}; - -AddressSize = { - ".address_size" U8Num -}; - -Function: ast::Function<'input, &'input str, ast::Statement>> = { - LinkingDirectives - - => ast::Function{<>} -}; - -LinkingDirective: ast::LinkingDirective = { - ".extern" => ast::LinkingDirective::EXTERN, - ".visible" => ast::LinkingDirective::VISIBLE, - ".weak" => ast::LinkingDirective::WEAK, -}; - -LinkingDirectives: ast::LinkingDirective = { - => { - ldirs.into_iter().fold(ast::LinkingDirective::NONE, |x, y| x | y) - } -} - -MethodDecl: ast::MethodDecl<'input, &'input str> = { - ".entry" => - ast::MethodDecl::Kernel{ name, in_args }, - ".func" => { - ast::MethodDecl::Func(ret_vals.unwrap_or_else(|| Vec::new()), name, params) - } -}; - -KernelArguments: Vec> = { - "(" > ")" => args -}; - -FnArguments: Vec> = { - "(" > ")" => args -}; - -KernelInput: ast::Variable = { - => { - let (align, v_type, name) = v; - ast::Variable { - align, - v_type: ast::KernelArgumentType::Normal(v_type), - name, - array_init: Vec::new() - } - } -} - -FnInput: ast::Variable = { - => { - let (align, v_type, name) = v; - let v_type = ast::FnArgumentType::Reg(v_type); - ast::Variable{ align, v_type, name, array_init: Vec::new() } - }, - => { - 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>>> = { - "{" "}" => { 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>> = { - => Some(ast::Statement::Label(l)), - DebugDirective => None, - ";" => Some(ast::Statement::Variable(v)), - ";" => Some(ast::Statement::Instruction(p, i)), - PragmaStatement => None, - "{" "}" => 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 -}; - -Align: u32 = { - ".align" => x -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameterized-variable-names -MultiVariable: ast::MultiVariable<&'input str> = { - => ast::MultiVariable{<>} -} - -VariableParam: u32 = { - "<" ">" => n -} - -Variable: ast::Variable = { - => { - 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, - => { - 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, ast::VariableRegType, &'input str) = { - ".reg" > => { - let (align, t, name) = var; - let v_type = ast::VariableRegType::Scalar(t); - (align, v_type, name) - }, - ".reg" > => { - let (align, v_len, t, name) = var; - let v_type = ast::VariableRegType::Vector(t, v_len); - (align, v_type, name) - } -} - -LocalVariable: ast::Variable = { - ".local" > => { - 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" > => { - 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" > =>? { - 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 = { - ".shared" > => { - 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" > => { - 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" > =>? { - 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 = { - LinkingDirectives ".global" => { - let (align, v_type, name, array_init) = def; - ast::Variable { align, v_type: ast::VariableType::Global(v_type), name, array_init } - }, - LinkingDirectives ".shared" => { - let (align, v_type, name, array_init) = def; - ast::Variable { align, v_type: ast::VariableType::Shared(v_type), name, array_init: Vec::new() } - }, - > > =>? { - 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, Vec, ast::VariableParamType, &'input str) = { - ".param" > => { - let (align, t, name) = var; - let v_type = ast::VariableParamType::Scalar(t); - (align, Vec::new(), v_type, name) - }, - ".param" > => { - 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, ast::VariableParamType, &'input str) = { - =>? { - 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, ast::VariableGlobalType, &'input str, Vec) = { - > => { - let (align, t, name) = scalar; - let v_type = ast::VariableGlobalType::Scalar(t); - (align, v_type, name, Vec::new()) - }, - > => { - 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> = { - 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> = { - "ld" "," => { - 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 = { - => ast::LdStType::Vector(t, v), - => ast::LdStType::Scalar(t), -} - -LdStQualifier: ast::LdStQualifier = { - ".weak" => ast::LdStQualifier::Weak, - ".volatile" => ast::LdStQualifier::Volatile, - ".relaxed" => ast::LdStQualifier::Relaxed(s), - ".acquire" => 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> = { - "mov" "," => { - 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> = { - "mul" => ast::Instruction::Mul(d, a) -}; - -MulDetails: ast::MulDetails = { - => ast::MulDetails::Unsigned(ast::MulUInt{ - typ: t, - control: ctr - }), - => ast::MulDetails::Signed(ast::MulSInt{ - typ: t, - control: ctr - }), - => 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> = { - "add" => 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> = { - "setp" => ast::Instruction::Setp(d, a), - "setp" => ast::Instruction::SetpBool(d, a), -}; - -SetpMode: ast::SetpData = { - => ast::SetpData { - typ: t, - flush_to_zero: None, - cmp_op: cmp_op, - }, - ".f32" => ast::SetpData { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - cmp_op: cmp_op, - } - -}; - -SetpBoolMode: ast::SetpBoolData = { - => ast::SetpBoolData { - typ: t, - flush_to_zero: None, - cmp_op: cmp_op, - bool_op: bool_op, - }, - ".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> = { - "not" => 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> = { - "@" => ast::PredAt { not: false, label:label }, - "@" "!" => ast::PredAt { not: true, label:label } -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra -InstBra: ast::Instruction> = { - "bra" => 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> = { - "cvt" => { - ast::Instruction::Cvt(ast::CvtDetails::new_int_from_int_checked( - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" => { - ast::Instruction::Cvt(ast::CvtDetails::new_float_from_int_checked( - r, - f.is_some(), - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" => { - ast::Instruction::Cvt(ast::CvtDetails::new_int_from_float_checked( - r, - f.is_some(), - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" ".f16" ".f16" => { - 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" ".f32" ".f16" => { - 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" ".f64" ".f16" => { - 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" ".f16" ".f32" => { - 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" ".f32" ".f32" => { - 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" ".f64" ".f32" => { - 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" ".f16" ".f64" => { - 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" ".f32" ".f64" => { - 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" ".f64" ".f64" => { - 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> = { - "shl" => 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> = { - "shr" => 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> = { - "st" "," => { - 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 -} - -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> = { - "ret" => 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> = { - "cvta" => { - ast::Instruction::Cvta(ast::CvtaDetails { - to: ast::CvtaStateSpace::Generic, - from, - size: s - }, - a) - }, - "cvta" ".to" => { - 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> = { - "call" => { - 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> = { - "abs" => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: t }, a) - }, - "abs" ".f32" => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F32 }, a) - }, - "abs" ".f64" => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: ast::ScalarType::F64 }, a) - }, - "abs" ".f16" => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16 }, a) - }, - "abs" ".f16x2" => { - 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> = { - "mad" => ast::Instruction::Mad(d, a), - "mad" ".hi" ".sat" ".s32" => todo!(), - "fma" => 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> = { - "or" => ast::Instruction::Or(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-and -InstAnd: ast::Instruction> = { - "and" => ast::Instruction::And(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rcp -InstRcp: ast::Instruction> = { - "rcp" ".f32" => { - let details = ast::RcpDetails { - rounding, - flush_to_zero: Some(ftz.is_some()), - is_f64: false, - }; - ast::Instruction::Rcp(details, a) - }, - "rcp" ".f64" => { - let details = ast::RcpDetails { - rounding: Some(rn), - flush_to_zero: None, - is_f64: true, - }; - ast::Instruction::Rcp(details, a) - } -}; - -RcpRoundingMode: Option = { - ".approx" => None, - => 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> = { - "sub" => 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> = { - "min" => 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> = { - "max" => ast::Instruction::Max(d, a), -}; - -MinMaxDetails: ast::MinMaxDetails = { - => ast::MinMaxDetails::Unsigned(t), - => ast::MinMaxDetails::Signed(t), - ".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 } - ), - ".f16" => ast::MinMaxDetails::Float( - ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::FloatType::F16 } - ), - ".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> = { - "selp" => 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> = { - "barrier" ".sync" ".aligned" => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), - "bar" ".sync" => 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> = { - "atom" => { - 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" ".inc" ".u32" => { - 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" ".dec" ".u32" => { - 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" ".add" => { - 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" => { - 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" => { - 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> = { - "atom" ".cas" => { - 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> = { - "div" => ast::Instruction::Div(ast::DivDetails::Unsigned(t), a), - "div" => ast::Instruction::Div(ast::DivDetails::Signed(t), a), - "div" ".f32" => { - 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" ".f64" => { - 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, - => ast::DivFloatKind::Rounding(rnd), -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sqrt -InstSqrt: ast::Instruction> = { - "sqrt" ".approx" ".f32" => { - 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" ".f32" => { - 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" ".f64" => { - 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> = { - "rsqrt" ".approx" ".f32" => { - let details = ast::RsqrtDetails { - typ: ast::FloatType::F32, - flush_to_zero: ftz.is_some(), - }; - ast::Instruction::Rsqrt(details, a) - }, - "rsqrt" ".approx" ".f64" => { - 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> = { - "neg" => { - let details = ast::NegDetails { - typ, - flush_to_zero: Some(ftz.is_some()), - }; - ast::Instruction::Neg(details, a) - }, - "neg" => { - 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> = { - "sin" ".approx" ".f32" => { - 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> = { - "cos" ".approx" ".f32" => { - 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> = { - "lg2" ".approx" ".f32" => { - 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> = { - "ex2" ".approx" ".f32" => { - 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> = { - "clz" => ast::Instruction::Clz{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-brev -InstBrev: ast::Instruction> = { - "brev" => ast::Instruction::Brev{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-popc -InstPopc: ast::Instruction> = { - "popc" => ast::Instruction::Popc{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-xor -InstXor: ast::Instruction> = { - "xor" => ast::Instruction::Xor{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfe -InstBfe: ast::Instruction> = { - "bfe" => ast::Instruction::Bfe{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-rem -InstRem: ast::Instruction> = { - "rem" => 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 = { - => ast::ArithDetails::Unsigned(t), - => ast::ArithDetails::Signed(ast::ArithSInt { - typ: t, - saturate: false, - }), - ".sat" ".s32" => ast::ArithDetails::Signed(ast::ArithSInt { - typ: ast::SIntType::S32, - saturate: true, - }), - => ast::ArithDetails::Float(f) -} - -ArithFloat: ast::ArithFloat = { - ".f32" => ast::ArithFloat { - typ: ast::FloatType::F32, - rounding: rn, - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - ".f64" => ast::ArithFloat { - typ: ast::FloatType::F64, - rounding: rn, - flush_to_zero: None, - saturate: false, - }, - ".f16" => ast::ArithFloat { - typ: ast::FloatType::F16, - rounding: rn.map(|_| ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - ".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 = { - ".f32" => ast::ArithFloat { - typ: ast::FloatType::F32, - rounding: Some(rn), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - ".f64" => ast::ArithFloat { - typ: ast::FloatType::F64, - rounding: Some(rn), - flush_to_zero: None, - saturate: false, - }, - ".rn" ".f16" => ast::ArithFloat { - typ: ast::FloatType::F16, - rounding: Some(ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - ".rn" ".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> = { - => ast::Operand::Reg(r), - "+" => ast::Operand::RegOffset(r, offset), - => ast::Operand::Imm(x) -}; - -CallOperand: ast::Operand<&'input str> = { - => ast::Operand::Reg(r), - => 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 - =>? { - 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) }) - } - } - } - } - }, - => { - ast::ImmediateValue::F32(f) - }, - => { - ast::ImmediateValue::F64(f) - } -} - -Arg1: ast::Arg1> = { - => ast::Arg1{<>} -}; - -Arg1Bar: ast::Arg1Bar> = { - => ast::Arg1Bar{<>} -}; - -Arg2: ast::Arg2> = { - "," => ast::Arg2{<>} -}; - -MemberOperand: (&'input str, u8) = { - "." =>? { - let suf_idx = vector_index(suf)?; - Ok((pref, suf_idx)) - }, - =>? { - let suf_idx = vector_index(&suf[1..])?; - Ok((pref, suf_idx)) - } -}; - -VectorExtract: Vec<&'input str> = { - "{" "," "}" => { - vec![r1, r2] - }, - "{" "," "," "," "}" => { - vec![r1, r2, r3, r4] - }, -}; - -Arg3: ast::Arg3> = { - "," "," => ast::Arg3{<>} -}; - -Arg3Atom: ast::Arg3> = { - "," "[" "]" "," => ast::Arg3{<>} -}; - -Arg4: ast::Arg4> = { - "," "," "," => ast::Arg4{<>} -}; - -Arg4Atom: ast::Arg4> = { - "," "[" "]" "," "," => ast::Arg4{<>} -}; - -Arg4Setp: ast::Arg4Setp> = { - "," "," => ast::Arg4Setp{<>} -}; - -// TODO: pass src3 negation somewhere -Arg5Setp: ast::Arg5Setp> = { - "," "," "," "!"? => ast::Arg5Setp{<>} -}; - -ArgCall: (Vec<&'input str>, &'input str, Vec>) = { - "(" > ")" "," "," "(" > ")" => { - (ret_params, func, param_list) - }, - "," "(" > ")" => (Vec::new(), func, param_list), - => (Vec::new(), func, Vec::>::new()), -}; - -OptionalDst: &'input str = { - "|" => dst2 -} - -SrcOperand: ast::Operand<&'input str> = { - => ast::Operand::Reg(r), - "+" => ast::Operand::RegOffset(r, offset), - => ast::Operand::Imm(x), - => { - let (reg, idx) = mem_op; - ast::Operand::VecMember(reg, idx) - } -} - -SrcOperandVec: ast::Operand<&'input str> = { - => normal, - => ast::Operand::VecPack(vec), -} - -DstOperand: ast::Operand<&'input str> = { - => ast::Operand::Reg(r), - => { - let (reg, idx) = mem_op; - ast::Operand::VecMember(reg, idx) - } -} - -DstOperandVec: ast::Operand<&'input str> = { - => normal, - => 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, - ".b32" SectionLabel, - ".b64" SectionLabel, - ".b32" SectionLabel "+" U32Num, - ".b64" SectionLabel "+" U32Num, -}; - -SectionLabel = { - ID, - DotID -}; - -AnyBitType = { - ".b8", ".b16", ".b32", ".b64" -}; - -VariableScalar: (Option, T, &'input str) = { - => { - (align, v_type, name) - } -} - -VariableVector: (Option, u8, T, &'input str) = { - => { - (align, v_len, v_type, name) - } -} - -// empty dimensions [0] means it's a pointer -VariableArrayOrPointer: (Option, T, &'input str, ast::ArrayOrPointer) = { - =>? { - 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 = { - ArrayEmptyDimension => vec![0u32], - ArrayEmptyDimension => { - let mut dims = dims; - let mut result = vec![0u32]; - result.append(&mut dims); - result - }, - => dims -} - -ArrayEmptyDimension = { - "[" "]" -} - -ArrayDimension: u32 = { - "[" "]" => n, -} - -ArrayInitializer: ast::NumsOrArrays<'input> = { - "=" => nums -} - -NumsOrArraysBracket: ast::NumsOrArrays<'input> = { - "{" "}" => nums -} - -NumsOrArrays: ast::NumsOrArrays<'input> = { - > => ast::NumsOrArrays::Arrays(n), - > => ast::NumsOrArrays::Nums(n.into_iter().map(|(x,radix,_)| (x, radix)).collect()), -} - -Comma: Vec = { - ",")*> => match e { - None => v, - Some(e) => { - let mut v = v; - v.push(e); - v - } - } -}; - -CommaNonEmpty: Vec = { - ",")*> => { - let mut v = v; - v.push(e); - v - } -}; - -#[inline] -Or: T1 = { - T1, - T2 -} \ No newline at end of file +use crate::ast; +use crate::lalrpop::*; + +use either::Either; +use lalrpop_util::ParseError; + +grammar<'err>(errors: &'err 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, + "!", + "(", ")", + "+", + "-", + "_", + ",", + ".", + ":", + ";", + "@", + "[", "]", + "{", "}", + "<", ">", + "|", + "=", + ".1d", + ".2d", + ".3d", + ".a1d", + ".a2d", + ".acq_rel", + ".acquire", + ".add", + ".address_size", + ".align", + ".aligned", + ".all", + ".and", + ".any", + ".approx", + ".b", + ".b16", + ".b32", + ".b64", + ".b8", + ".ballot", + ".bfly", + ".ca", + ".callprototype", + ".cas", + ".cc", + ".cg", + ".clamp", + ".common", + ".const", + ".cs", + ".cta", + ".cv", + ".dec", + ".down", + ".entry", + ".eq", + ".equ", + ".exch", + ".extern", + ".f16", + ".f16x2", + ".f32", + ".f64", + ".file", + ".ftz", + ".full", + ".func", + ".ge", + ".geu", + ".gl", + ".global", + ".gpu", + ".gt", + ".gtu", + ".hi", + ".hs", + ".idx", + ".inc", + ".l", + ".le", + ".leu", + ".lo", + ".loc", + ".local", + ".ls", + ".lt", + ".ltu", + ".lu", + ".m8n8", + ".max", + ".maxnreg", + ".maxntid", + ".minnctapersm", + ".min", + ".nan", + ".NaN", + ".nc", + ".ne", + ".neu", + ".noftz", + ".num", + ".or", + ".param", + ".popc", + ".pragma", + ".pred", + ".r", + ".red", + ".reg", + ".relaxed", + ".release", + ".reqntid", + ".rm", + ".rmi", + ".rn", + ".rni", + ".rp", + ".rpi", + ".rz", + ".rzi", + ".s16", + ".s32", + ".s64", + ".s8" , + ".sat", + ".section", + ".shared", + ".shiftamt", + ".surfref", + ".sync", + ".sys", + ".target", + ".texref", + ".to", + ".trap", + ".u16", + ".u32", + ".u64", + ".u8" , + ".uni", + ".up", + ".v2", + ".v4", + ".version", + ".visible", + ".volatile", + ".warp", + ".wb", + ".weak", + ".wide", + ".wrap", + ".wt", + ".x4", + ".xor", + ".zero", +} else { + // IF YOU ARE ADDING A NEW TOKEN HERE ALSO ADD IT BELOW TO ExtendedID + "abs", + "activemask", + "add", + "addc", + "and", + "atom", + "bar", + "barrier", + "bfe", + "bfi", + "bfind", + "bra", + "brev", + "brkpt", + "call", + "clz", + "cos", + "cvt", + "cvta", + "debug", + "div", + "dp4a", + "ex2", + "exit", + "fma", + "function_name", + "generic", + "inlined_at", + "ld", + "ldmatrix", + "lg2", + "mad", + "madc", + "map_f64_to_f32", + "match", + "max", + "membar", + "min", + "mov", + "mul", + "nanosleep", + "neg", + "not", + "or", + "popc", + "prmt", + "rcp", + "red", + "rem", + "ret", + "rsqrt", + "selp", + "set", + "setp", + "shf", + "shfl", + "shl", + "shr", + "sin", + r"sm_[0-9]+" => ShaderModel, + "sqrt", + "st", + "sub", + "subc", + "suld", + "sust", + "tex", + "texmode_independent", + "texmode_unified", + "trap", + "vote", + "vshr", + "xor", +} else { + "WARP_SZ", + // 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", + "activemask", + "add", + "addc", + "and", + "atom", + "bar", + "barrier", + "bfe", + "bfi", + "bfind", + "bra", + "brev", + "brkpt", + "call", + "clz", + "cos", + "cvt", + "cvta", + "debug", + "div", + "dp4a", + "ex2", + "exit", + "fma", + "function_name", + "generic", + "inlined_at", + "ld", + "ldmatrix", + "lg2", + "mad", + "madc", + "map_f64_to_f32", + "match", + "max", + "membar", + "min", + "mov", + "mul", + "nanosleep", + "neg", + "not", + "or", + "popc", + "prmt", + "rcp", + "red", + "rem", + "ret", + "rsqrt", + "selp", + "set", + "setp", + "shf", + "shfl", + "shl", + "shr", + "sin", + ShaderModel, + "sqrt", + "st", + "sub", + "subc", + "suld", + "sust", + "tex", + "texmode_independent", + "texmode_unified", + "trap", + "vote", + "vshr", + "xor", + ID +} + +ExtendedIDOrBlank = { + ExtendedID, + "_" +} + +NumToken: (&'input str, u32, bool) = { + => { + if s.ends_with('U') { + (&s[2..s.len() - 1], 16, true) + } else { + (&s[2..], 16, false) + } + }, + => { + 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) + } + }, + "WARP_SZ" => { + ("32", 10, false) + } +} + +F32Num: f32 = { + => { + match u32::from_str_radix(&s[2..], 16) { + Ok(x) => unsafe { std::mem::transmute::<_, f32>(x) }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0.0 + } + } + + } +} + +F64Num: f64 = { + => { + match u64::from_str_radix(&s[2..], 16) { + Ok(x) => unsafe { std::mem::transmute::<_, f64>(x) }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0.0 + } + } + } +} + +U8Num: u8 = { + => { + let (text, radix, _) = x; + match u8::from_str_radix(text, radix) { + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } + } + } +} + +U16Num: u16 = { + => { + let (text, radix, _) = x; + match u16::from_str_radix(text, radix) { + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } + } + } +} + +U32Num: u32 = { + => { + let (text, radix, _) = x; + match u32::from_str_radix(text, radix) { + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } + } + } +} + +// TODO: handle negative number properly +S64Num: i64 = { + => { + let (text, radix, _) = x; + match i64::from_str_radix(text, radix) { + Ok(x) => if sign.is_some() { -x } else { x }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } + } + } +} + +pub Module: ast::Module<'input> = { + PtxVersion => { + ast::Module { sm_version, directives: without_none(d) } + } +}; + +PtxVersion = { + ".version" VersionNumber +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target +Target: u32 = { + ".target" > => { + let max_sm_version = specifiers.iter().copied().fold(None, |acc, current| { + match (acc, current) { + (None, x) => x, + (Some(x), None) => Some(x), + (Some(x), Some(y)) => Some(u32::max(x, y)), + } + }); + max_sm_version.unwrap_or_else(|| { + errors.push(ParseError::User { error: ast::PtxError::NoSmVersion }); + 0 + }) + } +}; + +TargetSpecifier: Option = { + => { + let sm_version = sm[sm.find('_').unwrap() + 1 ..].parse::().unwrap_or_else(|err| { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + }); + Some(sm_version) + }, + "texmode_unified" => None, + "texmode_independent" => None, + "debug" => None, + "map_f64_to_f32" => None +}; + +Directive: Option>> = { + AddressSize => None, + => { + let (linking, func) = f; + if linking == ast::LinkingDirective::Extern && func.body.is_some() { + errors.push(ParseError::User { error: ast::PtxError::ExternDefinition }); + } + Some(ast::Directive::Method(linking, func)) + }, + File => None, + Section => None, + ";" => { + if var.len() != 1 { + errors.push(ParseError::User { error: ast::PtxError::UnexpectedMultivariable }); + } + if linking == ast::LinkingDirective::Extern && matches!(var[0].suffix, Some(ast::DeclarationSuffix::Initializer(_))) { + errors.push(ParseError::User { error: ast::PtxError::ExternDefinition }); + } + if linking != ast::LinkingDirective::Extern && var[0].variable.type_.layout().size() == 0 { + errors.push(ParseError::User { error: ast::PtxError::ExternDefinition }); + } + Some(ast::Directive::Variable(linking, var.into_iter().next().unwrap())) + }, + @L ! @R => { + let (start, _, end)= (<>); + errors.push(ParseError::User { error: + ast::PtxError::UnrecognizedDirective { start, end } + }); + None + } +}; + +AddressSize = { + ".address_size" U8Num +}; + +Function: (ast::LinkingDirective, ast::Function<'input, &'input str, ast::Statement>>) = { + + + + => { + (linking, ast::Function{func_directive, tuning, body}) + } +}; + +LinkingDirective: ast::LinkingDirective = { + ".extern" => ast::LinkingDirective::Extern, + ".visible" => ast::LinkingDirective::Visible, + ".weak" => ast::LinkingDirective::Weak, + ".common" => ast::LinkingDirective::Common, + => ast::LinkingDirective::None, +}; + +TuningDirective: ast::TuningDirective = { + ".maxnreg" => ast::TuningDirective::MaxNReg(ncta), + ".maxntid" => ast::TuningDirective::MaxNtid(nx, 1, 1), + ".maxntid" "," => ast::TuningDirective::MaxNtid(nx, ny, 1), + ".maxntid" "," "," => ast::TuningDirective::MaxNtid(nx, ny, nz), + ".reqntid" => ast::TuningDirective::ReqNtid(nx, 1, 1), + ".reqntid" "," => ast::TuningDirective::ReqNtid(nx, ny, 1), + ".reqntid" "," "," => ast::TuningDirective::ReqNtid(nx, ny, nz), + ".minnctapersm" => ast::TuningDirective::MinNCtaPerSm(ncta), +}; + +MethodDeclaration: ast::MethodDeclaration<'input, &'input str> = { + ".entry" => { + let return_arguments = Vec::new(); + let name = ast::MethodName::Kernel(name); + ast::MethodDeclaration{ return_arguments, name, input_arguments } + }, + ".func" => { + let return_arguments = return_arguments.unwrap_or_else(|| Vec::new()); + let name = ast::MethodName::Func(name); + ast::MethodDeclaration{ return_arguments, name, input_arguments } + } +}; + +KernelArguments: Vec> = { + "(" > ")" => args +}; + +FnArguments: Vec> = { + "(" > ")" => args +}; + +ProtoArguments: Vec> = { + "(" > ")" => args +}; + +FunctionBody: Option>>> = { + "{" "}" => 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>> = { + => Some(ast::Statement::Label(l)), + ";" => Some(ast::Statement::Callprototype(c)), + DebugDirective => None, + ";" => Some(ast::Statement::Variable(v)), + ";" => Some(ast::Statement::Instruction(p, i)), + PragmaStatement => None, + "{" "}" => Some(ast::Statement::Block(without_none(s))), + @L ! ";" @R => { + let (start, _, _, end) = (<>); + errors.push(ParseError::User { error: + ast::PtxError::UnrecognizedStatement { start, end } + }); + None + } +}; + +PragmaStatement: () = { + ".pragma" String ";" +} + +DebugDirective: () = { + DebugLocation +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc +DebugLocation: () = { + ".loc" U32Num U32Num U32Num => {}, + ".loc" U32Num U32Num U32Num "," "function_name" ExtendedID "," "inlined_at" U32Num U32Num U32Num => {}, + ".loc" U32Num U32Num U32Num "," "function_name" ExtendedID "+" U32Num "," "inlined_at" U32Num U32Num U32Num => {} +}; + +Label: &'input str = { + ":" => id +}; + +Align: u32 = { + ".align" => x +}; + +Initializer: ast::Initializer<&'input str> = { + "+" => ast::Initializer::Add(Box::new((init1, init2))), + InitializerNoAdd +} + +InitializerNoAdd: ast::Initializer<&'input str> = { + => ast::Initializer::Constant(val), + => ast::Initializer::Global(id, ast::Type::Struct(Vec::new())), + "generic" "(" ")" => ast::Initializer::GenericGlobal(id, ast::Type::Struct(Vec::new())), + "{" > "}" => ast::Initializer::Array(array_init) +} + +VariableDeclarationFunc: ast::VariableDeclaration<&'input str> = { + => + validate_variable_declaration_func(var, errors) +} + +VariableDeclarationEntry: ast::VariableDeclaration<&'input str> = { + => + validate_variable_declaration_entry(var, errors) +} + +VariableDeclarationProto: ast::VariableDeclaration<&'input str> = { + => + validate_variable_declaration_proto(var, errors) +} + +VariableDeclarationBase: ast::VariableDeclaration<&'input str> = { + => { + let mut variable = variable.clone(); + variable.name = name; + variable.type_ = make_array_type(variable.type_, dims, errors); + report_incorrect_variable(&variable, errors); + variable + } +} + +MultiVariableDefinition: Vec> = { + > => { + defs.into_iter().map(|(name, def_suffix, initializer)| { + let mut variable = variable.clone(); + variable.name = name; + let suffix = if let Some(Either::Left(count)) = def_suffix { + Some(ast::DeclarationSuffix::Count(count)) + } else if let Some(initializer) = initializer { + Some(ast::DeclarationSuffix::Initializer(initializer)) + } else { + None + }; + if let Some(Either::Right(dims)) = def_suffix { + variable.type_ = make_array_type(variable.type_, Some(dims), errors); + } + let mut definition = ast::MultiVariableDefinition { variable, suffix }; + report_incorrect_variable(&definition.variable, errors); + validate_variable_declaration2(&mut definition, errors); + definition + }).collect::>() + } +} + +VariableDeclarationBegin: ast::VariableDeclaration<&'input str> = { + => { + ast::VariableDeclaration { + align, + type_, + state_space, + name: "" + } + } +} + +VariableDefinitionOnce: (&'input str, Option>>, Option>) = { + => (name, suffix, init) +} + +VariableDefinitionSuffix: Either> = { + // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameterized-variable-names + "<" ">" => either::Left(n), + => either::Right(dims), +} + +VariableDefinitionInitializer: ast::Initializer<&'input str> = { + "=" => init +} + +AnyType: ast::Type = { + ".texref" => ast::Type::Texref, + ".surfref" => ast::Type::Surfref, + => ast::Type::Vector(type_, v_len), + => ast::Type::Scalar(type_), +} + +#[inline] +SizedScalarType: ast::ScalarType = { + ".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, + ".f16" => ast::ScalarType::F16, + ".f16x2" => ast::ScalarType::F16x2, + ".f32" => ast::ScalarType::F32, + ".f64" => ast::ScalarType::F64, +} + +#[inline] +LdStScalarType: ast::ScalarType = { + ".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, + ".f16" => ast::ScalarType::F16, + ".f32" => ast::ScalarType::F32, + ".f64" => ast::ScalarType::F64, +} + +Instruction: ast::Instruction> = { + InstLd, + InstMov, + InstMul, + InstAdd, + InstAddC, + InstAddCC, + InstSetp, + InstNot, + InstBra, + InstCvt, + InstShl, + InstShr, + InstSt, + InstRet, + InstCvta, + InstCall, + InstAbs, + InstMad, + InstMadC, + InstMadCC, + InstFma, + InstOr, + InstAnd, + InstSub, + InstSubC, + InstSubCC, + InstMin, + InstMax, + InstRcp, + InstSelp, + InstBar, + InstAtom, + InstAtomCas, + InstDiv, + InstSqrt, + InstRsqrt, + InstNeg, + InstSin, + InstCos, + InstLg2, + InstEx2, + InstClz, + InstBrev, + InstPopc, + InstXor, + InstRem, + InstBfe, + InstBfi, + InstPrmt, + InstActivemask, + InstMembar, + InstTex, + InstSuld, + InstSust, + InstShfl, + InstShf, + InstVote, + InstExit, + InstBarRed, + InstTrap, + InstBrkpt, + InstVshr, + InstBfind, + InstSet, + InstDp4a, + InstMatch, + InstRed, + InstNanosleep, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld +InstLd: ast::Instruction> = { + "ld" "," => { + ast::Instruction::Ld( + ast::LdDetails { + qualifier: q.unwrap_or(ast::LdStQualifier::Weak), + state_space: ss.unwrap_or(ast::StateSpace::Generic), + caching: cop.unwrap_or(ast::LdCacheOperator::Cached), + typ: t, + non_coherent: false + }, + ast::Arg2Ld { dst:dst, src:src } + ) + }, + "ld" ".global" "," => { + ast::Instruction::Ld( + ast::LdDetails { + qualifier: q.unwrap_or(ast::LdStQualifier::Weak), + state_space: ast::StateSpace::Global, + caching: cop.unwrap_or(ast::LdCacheOperator::Cached), + typ: t, + non_coherent: false + }, + ast::Arg2Ld { dst:dst, src:src } + ) + }, + "ld" ".global" ".nc" "," => { + ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Global, + caching: cop.unwrap_or(ast::LdCacheOperator::Cached), + typ: t, + non_coherent: true + }, + ast::Arg2Ld { dst:dst, src:src } + ) + } +}; + +LdStType: ast::Type = { + => ast::Type::Vector(t, v), + => ast::Type::Scalar(t), +} + +LdStQualifier: ast::LdStQualifier = { + ".weak" => ast::LdStQualifier::Weak, + ".volatile" => ast::LdStQualifier::Volatile, + ".relaxed" => ast::LdStQualifier::Relaxed(s), + ".acquire" => ast::LdStQualifier::Acquire(s), + ".release" => ast::LdStQualifier::Release(s), +}; + +MemScope: ast::MemScope = { + ".cta" => ast::MemScope::Cta, + ".gpu" => ast::MemScope::Gpu, + ".sys" => ast::MemScope::Sys +}; + +MembarLevel: ast::MemScope = { + ".cta" => ast::MemScope::Cta, + ".gl" => ast::MemScope::Gpu, + ".sys" => ast::MemScope::Sys +}; + +LdNonGlobalStateSpace: ast::StateSpace = { + ".const" => ast::StateSpace::Const, + ".local" => ast::StateSpace::Local, + ".param" => ast::StateSpace::Param, + ".shared" => ast::StateSpace::Shared, +}; + +LdCacheOperator: ast::LdCacheOperator = { + ".ca" => ast::LdCacheOperator::Cached, + ".cg" => ast::LdCacheOperator::L2Only, + ".cs" => ast::LdCacheOperator::Streaming, + ".lu" => ast::LdCacheOperator::LastUse, + ".cv" => ast::LdCacheOperator::Uncached, +}; + +LdNcCacheOperator: ast::LdCacheOperator = { + ".ca" => ast::LdCacheOperator::Cached, + ".cg" => ast::LdCacheOperator::L2Only, + ".cs" => ast::LdCacheOperator::Streaming, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov +InstMov: ast::Instruction> = { + "mov" "," => { + let motype_ = match pref { + Some(vec_width) => ast::Type::Vector(t, vec_width), + None => ast::Type::Scalar(t) + }; + let details = ast::MovDetails::new(motype_); + 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> = { + "mul" => ast::Instruction::Mul(d, a) +}; + +MulDetails: ast::MulDetails = { + => ast::MulDetails::Unsigned(ast::MulInt{ + typ: t, + control: ctr + }), + => ast::MulDetails::Signed(ast::MulInt{ + typ: t, + control: ctr + }), + => 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::ScalarType = { + ".u16" => ast::ScalarType::U16, + ".u32" => ast::ScalarType::U32, + ".u64" => ast::ScalarType::U64, + ".s16" => ast::ScalarType::S16, + ".s32" => ast::ScalarType::S32, + ".s64" => ast::ScalarType::S64, +}; + +IntType3264: ast::ScalarType = { + ".u32" => ast::ScalarType::U32, + ".u64" => ast::ScalarType::U64, + ".s32" => ast::ScalarType::S32, + ".s64" => ast::ScalarType::S64, +} + +UIntType: ast::ScalarType = { + ".u16" => ast::ScalarType::U16, + ".u32" => ast::ScalarType::U32, + ".u64" => ast::ScalarType::U64, +}; + +SIntType: ast::ScalarType = { + ".s16" => ast::ScalarType::S16, + ".s32" => ast::ScalarType::S32, + ".s64" => ast::ScalarType::S64, +}; + +FloatType: ast::ScalarType = { + ".f16" => ast::ScalarType::F16, + ".f16x2" => ast::ScalarType::F16x2, + ".f32" => ast::ScalarType::F32, + ".f64" => ast::ScalarType::F64, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-directives-callprototype +Callprototype: ast::Callprototype<&'input str> = { + ":" ".callprototype" "_" => { + let return_arguments = return_arguments + .map(|args| { + args.into_iter() + .map(|var| (var.type_, var.state_space)) + .collect() + }) + .unwrap_or(Vec::new()); + let input_arguments = input_arguments + .into_iter() + .map(|var| (var.type_, var.state_space)) + .collect(); + ast::Callprototype { + name, + return_arguments, + input_arguments + } + } +}; + +// 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> = { + "add" => ast::Instruction::Add(d, a) +}; + +InstAddC: ast::Instruction> = { + "addc" => { + let details = ast::CarryInDetails { + carry_out: carry_out.is_some(), + type_ + }; + ast::Instruction::AddC(details, a) + } +}; + +InstAddCC: ast::Instruction> = { + "add" ".cc" => ast::Instruction::AddCC(type_, 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> = { + "setp" => ast::Instruction::Setp(d, a), + "setp" "," "," "," => { + let args = ast::Arg5Setp{ + dst1, + dst2, + src1, + src2, + src3 + }; + let mut details = d; + details.negate_src3 = neg_src3.is_some(); + ast::Instruction::SetpBool(details, args) + } +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-comparison-instructions-set +InstSet: ast::Instruction> = { + "set" ".u32" ".f16x2" => { + let data = ast::SetData { + dst_type: ast::ScalarType::U32, + src_type: ast::ScalarType::F16x2, + flush_to_zero: ftz.is_some(), + cmp_op: cmp_op, + }; + ast::Instruction::Set(data, arg) + } +} + +SetpMode: ast::SetpData = { + => ast::SetpData { + typ: t, + flush_to_zero: None, + cmp_op: cmp_op, + }, + ".f32" => ast::SetpData { + typ: ast::ScalarType::F32, + flush_to_zero: Some(ftz.is_some()), + cmp_op: cmp_op, + } + +}; + +SetpBoolMode: ast::SetpBoolData = { + => ast::SetpBoolData { + base: ast::SetpData { + typ: t, + flush_to_zero: None, + cmp_op: cmp_op, + }, + bool_op: bool_op, + negate_src3: false, + }, + ".f32" => ast::SetpBoolData { + base: ast::SetpData { + typ: ast::ScalarType::F32, + flush_to_zero: Some(ftz.is_some()), + cmp_op: cmp_op, + }, + bool_op: bool_op, + negate_src3: false, + } +}; + +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::IsAnyNan, +}; + +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, + // PTX docs lie, f16 is allowed + ".f16" => ast::ScalarType::F16, + ".f64" => ast::ScalarType::F64, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not +InstNot: ast::Instruction> = { + "not" => ast::Instruction::Not(t, a) +}; + +BooleanType: ast::ScalarType = { + ".pred" => ast::ScalarType::Pred, + ".b16" => ast::ScalarType::B16, + ".b32" => ast::ScalarType::B32, + ".b64" => ast::ScalarType::B64, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at +PredAt: ast::PredAt<&'input str> = { + "@" => ast::PredAt { not: false, label:label }, + "@" "!" => ast::PredAt { not: true, label:label } +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra +InstBra: ast::Instruction> = { + "bra" => 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> = { + "cvt" => { + ast::Instruction::Cvt(ast::CvtDetails::new_int_from_int_checked( + s.is_some(), + dst_t, + src_t, + errors + ), + a) + }, + "cvt" => { + ast::Instruction::Cvt(ast::CvtDetails::new_float_from_int_checked( + r, + f.is_some(), + s.is_some(), + dst_t, + src_t, + errors + ), + a) + }, + "cvt" => { + ast::Instruction::Cvt(ast::CvtDetails::new_int_from_float_checked( + r, + f.is_some(), + s.is_some(), + dst_t, + src_t, + errors + ), + a) + }, + "cvt" ".f16" ".f16" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: r, + flush_to_zero: None, + saturate: s.is_some(), + dst: ast::ScalarType::F16, + src: ast::ScalarType::F16 + } + ), a) + }, + "cvt" ".f32" ".f16" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: None, + flush_to_zero: Some(f.is_some()), + saturate: s.is_some(), + dst: ast::ScalarType::F32, + src: ast::ScalarType::F16 + } + ), a) + }, + "cvt" ".f64" ".f16" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: None, + flush_to_zero: None, + saturate: s.is_some(), + dst: ast::ScalarType::F64, + src: ast::ScalarType::F16 + } + ), a) + }, + "cvt" ".f16" ".f32" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: Some(r), + flush_to_zero: Some(f.is_some()), + saturate: s.is_some(), + dst: ast::ScalarType::F16, + src: ast::ScalarType::F32 + } + ), a) + }, + "cvt" ".f32" ".f32" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: r, + flush_to_zero: Some(f.is_some()), + saturate: s.is_some(), + dst: ast::ScalarType::F32, + src: ast::ScalarType::F32 + } + ), a) + }, + "cvt" ".f64" ".f32" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: None, + flush_to_zero: Some(f.is_some()), + saturate: s.is_some(), + dst: ast::ScalarType::F64, + src: ast::ScalarType::F32 + } + ), a) + }, + "cvt" ".f16" ".f64" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: Some(r), + flush_to_zero: None, + saturate: s.is_some(), + dst: ast::ScalarType::F16, + src: ast::ScalarType::F64 + } + ), a) + }, + "cvt" ".f32" ".f64" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: Some(r), + flush_to_zero: Some(s.is_some()), + saturate: s.is_some(), + dst: ast::ScalarType::F32, + src: ast::ScalarType::F64 + } + ), a) + }, + "cvt" ".f64" ".f64" => { + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( + ast::CvtDesc { + rounding: r, + flush_to_zero: None, + saturate: s.is_some(), + dst: ast::ScalarType::F64, + src: ast::ScalarType::F64 + } + ), a) + }, +}; + +CvtTypeInt: ast::ScalarType = { + ".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, +}; + +CvtTypeFloat: ast::ScalarType = { + ".f16" => ast::ScalarType::F16, + ".f32" => ast::ScalarType::F32, + ".f64" => ast::ScalarType::F64, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl +InstShl: ast::Instruction> = { + "shl" => ast::Instruction::Shl(t, a) +}; + +ShlType: ast::ScalarType = { + ".b16" => ast::ScalarType::B16, + ".b32" => ast::ScalarType::B32, + ".b64" => ast::ScalarType::B64, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shr +InstShr: ast::Instruction> = { + "shr" => ast::Instruction::Shr(t, a) +}; + +ShrType: 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, +}; + +// 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> = { + "st" "," => { + ast::Instruction::St( + ast::StData { + qualifier: q.unwrap_or(ast::LdStQualifier::Weak), + state_space: ss.unwrap_or(ast::StateSpace::Generic), + caching: cop.unwrap_or(ast::StCacheOperator::Writeback), + typ: t + }, + ast::Arg2St { src1:src1, src2:src2 } + ) + }, + // Wrong order, used by QUDA + "st" "," => { + ast::Instruction::St( + ast::StData { + qualifier: ast::LdStQualifier::Weak, + state_space, + caching, + 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 +} + +StStateSpace: ast::StateSpace = { + ".global" => ast::StateSpace::Global, + ".local" => ast::StateSpace::Local, + ".param" => ast::StateSpace::Param, + ".shared" => ast::StateSpace::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> = { + "ret" => 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> = { + "cvta" => { + ast::Instruction::Cvta(ast::CvtaDetails { + to: ast::StateSpace::Generic, + from, + size: s + }, + a) + }, + "cvta" ".to" => { + ast::Instruction::Cvta(ast::CvtaDetails { + to, + from: ast::StateSpace::Generic, + size: s + }, + a) + } +} + +CvtaStateSpace: ast::StateSpace = { + ".const" => ast::StateSpace::Const, + ".global" => ast::StateSpace::Global, + ".local" => ast::StateSpace::Local, + ".shared" => ast::StateSpace::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> = { + "call" => { + let (ret_params, func, param_list, prototype) = args; + ast::Instruction::Call(ast::CallInst { uniform: u.is_some(), ret_params, func, param_list, prototype }) + } +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-abs +InstAbs: ast::Instruction> = { + "abs" => { + ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: t }, a) + }, + "abs" ".f32" => { + ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F32 }, a) + }, + "abs" ".f64" => { + ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: ast::ScalarType::F64 }, a) + }, + "abs" ".f16" => { + ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16 }, a) + }, + "abs" ".f16x2" => { + 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> = { + "mad" => ast::Instruction::Mad(d, a), + "mad" ".hi" ".sat" ".s32" => todo!(), +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#extended-precision-arithmetic-instructions-mad-cc +InstMadCC: ast::Instruction> = { + "mad" ".lo" ".cc" => ast::Instruction::MadCC{<>}, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#extended-precision-arithmetic-instructions-madc +InstMadC: ast::Instruction> = { + "madc" ".lo" => { + ast::Instruction::MadC { type_, arg, is_hi: false, carry_out: carry_out.is_some() } + }, + "madc" ".hi" => { + ast::Instruction::MadC { type_, arg, is_hi: true, carry_out: carry_out.is_some() } + }, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-fma +InstFma: ast::Instruction> = { + "fma" => ast::Instruction::Fma(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> = { + "or" => ast::Instruction::Or(d, a), +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-and +InstAnd: ast::Instruction> = { + "and" => ast::Instruction::And(d, a), +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rcp +InstRcp: ast::Instruction> = { + "rcp" ".approx" ".f32" => { + let details = ast::RcpSqrtDetails { + kind: ast::RcpSqrtKind::Approx, + flush_to_zero: Some(ftz.is_some()), + type_: ast::ScalarType::F32, + }; + ast::Instruction::Rcp(details, a) + }, + // PyTorch + "rcp" ".approx" ".f32" ".ftz" => { + let details = ast::RcpSqrtDetails { + kind: ast::RcpSqrtKind::Approx, + flush_to_zero: Some(true), + type_: ast::ScalarType::F32, + }; + ast::Instruction::Rcp(details, a) + }, + // Undocumented, but supported. Used in some Thrust code from waifu2x + "rcp" ".approx" ".f64" => { + let details = ast::RcpSqrtDetails { + kind: ast::RcpSqrtKind::Approx, + flush_to_zero: Some(ftz.is_some()), + type_: ast::ScalarType::F64, + }; + ast::Instruction::Rcp(details, a) + }, + "rcp" ".f32" => { + let details = ast::RcpSqrtDetails { + kind, + flush_to_zero: Some(ftz.is_some()), + type_: ast::ScalarType::F32, + }; + ast::Instruction::Rcp(details, a) + }, + "rcp" ".f64" => { + let details = ast::RcpSqrtDetails { + kind, + flush_to_zero: None, + type_: ast::ScalarType::F64, + }; + ast::Instruction::Rcp(details, a) + } +}; + +RcpSqrtRounding: ast::RcpSqrtKind = { + => ast::RcpSqrtKind::Rounding(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> = { + "sub" => ast::Instruction::Sub(d, a), +}; + +InstSubC: ast::Instruction> = { + "subc" => { + let details = ast::CarryInDetails { + carry_out: carry_out.is_some(), + type_ + }; + ast::Instruction::SubC(details, a) + } +}; + +InstSubCC: ast::Instruction> = { + "sub" ".cc" => ast::Instruction::SubCC(type_, 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> = { + "min" => 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> = { + "max" => ast::Instruction::Max(d, a), +}; + +MinMaxDetails: ast::MinMaxDetails = { + => ast::MinMaxDetails::Unsigned(t), + => ast::MinMaxDetails::Signed(t), + ".f32" => ast::MinMaxDetails::Float( + ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F32 } + ), + ".f64" => ast::MinMaxDetails::Float( + ast::MinMaxFloat{ flush_to_zero: None, nan: false, typ: ast::ScalarType::F64 } + ), + ".f16" => ast::MinMaxDetails::Float( + ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F16 } + ), + ".f16x2" => ast::MinMaxDetails::Float( + ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F16x2 } + ) +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-selp +InstSelp: ast::Instruction> = { + "selp" => ast::Instruction::Selp(t, a), +}; + +SelpType: 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, +}; + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar +InstBar: ast::Instruction> = { + "bar" ".sync" => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), + "bar" ".warp" ".sync" => ast::Instruction::BarWarp(ast::BarDetails::SyncAligned, a), + "barrier" ".sync" => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), + "barrier" ".sync" ".aligned" => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar +InstBarRed: ast::Instruction> = { + "bar" ".red" ".and" ".pred" => { + let reduction = ast::ReductionOp::And; + ast::Instruction::BarRed(reduction, a) + }, + "bar" ".red" ".or" ".pred" => { + let reduction = ast::ReductionOp::Or; + ast::Instruction::BarRed(reduction, a) + }, + "bar" ".red" ".popc" ".u32" => { + let reduction = ast::ReductionOp::Popc; + ast::Instruction::BarRed(reduction, 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> = { + "atom" => { + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Bit { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + // Wrong order, used by QUDA + "atom" => { + let details = ast::AtomDetails { + semantics: ast::AtomSemantics::Relaxed, + scope, + space: ast::StateSpace::Generic, + inner: ast::AtomInnerDetails::Bit { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + // Wrong order, used by QUDA + "atom" => { + let details = ast::AtomDetails { + semantics: ast::AtomSemantics::Relaxed, + scope, + space: ast::StateSpace::Generic, + inner: ast::AtomInnerDetails::Unsigned { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + "atom" ".inc" ".u32" => { + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Inc, + typ: ast::ScalarType::U32 + } + }; + ast::Instruction::Atom(details,a) + }, + "atom" ".dec" ".u32" => { + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Dec, + typ: ast::ScalarType::U32 + } + }; + ast::Instruction::Atom(details,a) + }, + "atom" ".add" => { + 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::StateSpace::Generic), + inner: ast::AtomInnerDetails::Float { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + // TODO: propagate .noftz + "atom" ".add" ".noftz" ".f16" => { + let op = ast::AtomFloatOp::Add; + let typ = ast::ScalarType::F16; + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Float { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + "atom" => { + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Unsigned { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + // Wrong order, used by PETSc + "atom" => { + let details = ast::AtomDetails { + semantics, + scope, + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Unsigned { op, typ } + }; + ast::Instruction::Atom(details,a) + }, + "atom" => { + let details = ast::AtomDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::Generic), + inner: ast::AtomInnerDetails::Signed { op, typ } + }; + ast::Instruction::Atom(details,a) + } +} + +InstAtomCas: ast::Instruction> = { + "atom" ".cas" => { + let details = ast::AtomCasDetails { + semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), + scope: scope.unwrap_or(ast::MemScope::Gpu), + space: space.unwrap_or(ast::StateSpace::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::StateSpace = { + ".global" => ast::StateSpace::Global, + ".shared" => ast::StateSpace::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::ScalarType = { + ".b32" => ast::ScalarType::B32, + ".b64" => ast::ScalarType::B64, +} + +UIntType3264: ast::ScalarType = { + ".u32" => ast::ScalarType::U32, + ".u64" => ast::ScalarType::U64, +} + +SIntType3264: ast::ScalarType = { + ".s32" => ast::ScalarType::S32, + ".s64" => ast::ScalarType::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> = { + "div" => ast::Instruction::Div(ast::DivDetails::Unsigned(t), a), + "div" => ast::Instruction::Div(ast::DivDetails::Signed(t), a), + "div" ".f32" => { + let inner = ast::DivFloatDetails { + typ: ast::ScalarType::F32, + flush_to_zero: Some(ftz.is_some()), + kind + }; + ast::Instruction::Div(ast::DivDetails::Float(inner), a) + }, + "div" ".f64" => { + let inner = ast::DivFloatDetails { + typ: ast::ScalarType::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, + => ast::DivFloatKind::Rounding(rnd), +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sqrt +InstSqrt: ast::Instruction> = { + "sqrt" ".approx" ".f32" => { + let details = ast::RcpSqrtDetails { + kind: ast::RcpSqrtKind::Approx, + flush_to_zero: Some(ftz.is_some()), + type_: ast::ScalarType::F32, + }; + ast::Instruction::Sqrt(details, a) + }, + "sqrt" ".f32" => { + let details = ast::RcpSqrtDetails { + kind, + flush_to_zero: Some(ftz.is_some()), + type_: ast::ScalarType::F32, + }; + ast::Instruction::Sqrt(details, a) + }, + "sqrt" ".f64" => { + let details = ast::RcpSqrtDetails { + kind, + flush_to_zero: None, + type_: ast::ScalarType::F64, + }; + 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> = { + "rsqrt" ".approx" ".f32" => { + let details = ast::RsqrtDetails { + typ: ast::ScalarType::F32, + flush_to_zero: ftz.is_some(), + }; + ast::Instruction::Rsqrt(details, a) + }, + // PyTorch + "rsqrt" ".approx" ".f32" ".ftz" => { + let details = ast::RsqrtDetails { + typ: ast::ScalarType::F32, + flush_to_zero: true, + }; + ast::Instruction::Rsqrt(details, a) + }, + "rsqrt" ".approx" ".f64" => { + let details = ast::RsqrtDetails { + typ: ast::ScalarType::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> = { + "neg" => { + let details = ast::NegDetails { + typ, + flush_to_zero: Some(ftz.is_some()), + }; + ast::Instruction::Neg(details, a) + }, + "neg" => { + 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> = { + "sin" ".approx" ".f32" => { + 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> = { + "cos" ".approx" ".f32" => { + 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> = { + "lg2" ".approx" ".f32" => { + ast::Instruction::Lg2{ flush_to_zero: ftz.is_some(), arg } + }, + // PyTorch + "lg2" ".approx" ".f32" ".ftz" => { + ast::Instruction::Lg2{ flush_to_zero: true, arg } + }, +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-ex2 +InstEx2: ast::Instruction> = { + "ex2" ".approx" ".f32" => { + ast::Instruction::Ex2{ flush_to_zero: ftz.is_some(), arg } + }, + // PyTorch + "ex2" ".approx" ".f32" ".ftz" => { + ast::Instruction::Ex2{ flush_to_zero: true, arg } + }, +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-clz +InstClz: ast::Instruction> = { + "clz" => ast::Instruction::Clz{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-brev +InstBrev: ast::Instruction> = { + "brev" => ast::Instruction::Brev{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-popc +InstPopc: ast::Instruction> = { + "popc" => ast::Instruction::Popc{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-xor +InstXor: ast::Instruction> = { + "xor" => ast::Instruction::Xor{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfe +InstBfe: ast::Instruction> = { + "bfe" => ast::Instruction::Bfe{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfi +InstBfi: ast::Instruction> = { + "bfi" => ast::Instruction::Bfi{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-prmt +InstPrmt: ast::Instruction> = { + "prmt" ".b32" "," => ast::Instruction::Prmt{ <> }, + "prmt" ".b32" "," => ast::Instruction::PrmtSlow{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-rem +InstRem: ast::Instruction> = { + "rem" => ast::Instruction::Rem{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask +InstActivemask: ast::Instruction> = { + "activemask" ".b32" => ast::Instruction::Activemask{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar +InstMembar: ast::Instruction> = { + "membar" => ast::Instruction::Membar{ <> } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#texture-instructions-tex +InstTex: ast::Instruction> = { + "tex" ".v4" "," "[" "," "]" => { + let args = ast::Arg4Tex { + dst, + image, + coordinates, + layer: None + }; + let details = ast::TexDetails { geometry, channel_type, coordinate_type, direct: false }; + ast::Instruction::Tex(details, args) + }, + // We give a1d and a2d image operations distinctive treatment, because its + // coordintate argument is a fake vector. If you try to pass a vector to + // a1d/a2d image instructions on NVIDIA's compiler, it ICEs + "tex" ".a1d" ".v4" + "," "[" "," "{" "," "}" "]" => { + let geometry = ast::TextureGeometry::Array1D; + let args = ast::Arg4Tex { + dst, + image, + coordinates: ast::Operand::VecPack(vec![x]), + layer: Some(layer) + }; + let details = ast::TexDetails { geometry, channel_type, coordinate_type, direct: false }; + ast::Instruction::Tex(details, args) + }, + "tex" ".a2d" ".v4" + "," "[" "," "{" "," "," "," RegOrImmediate "}" "]" => { + let geometry = ast::TextureGeometry::Array2D; + let args = ast::Arg4Tex { + dst, + image, + coordinates: ast::Operand::VecPack(vec![x, y]), + layer: Some(layer) + }; + let details = ast::TexDetails { geometry, channel_type, coordinate_type, direct: false }; + ast::Instruction::Tex(details, args) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#surface-instructions-suld +InstSuld: ast::Instruction> = { + "suld" ".b" ".trap" "," "[" "," "]" => { + let args = ast::Arg4Tex { + dst, + image, + coordinates, + layer: None, + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Suld(details, args) + }, + "suld" ".b" ".a1d" ".trap" "," "[" "," "{" "," "}" "]" => { + let geometry = ast::TextureGeometry::Array1D; + let args = ast::Arg4Tex { + dst, + image, + coordinates: ast::Operand::VecPack(vec![x]), + layer: Some(layer), + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Suld(details, args) + }, + "suld" ".b" ".a2d" ".trap" "," "[" "," "{" "," "," "," RegOrImmediate "}" "]" => { + let geometry = ast::TextureGeometry::Array2D; + let args = ast::Arg4Tex { + dst, + image, + coordinates: ast::Operand::VecPack(vec![x, y]), + layer: Some(layer), + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Suld(details, args) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#surface-instructions-sust +InstSust: ast::Instruction> = { + "sust" ".b" SustClamp "[" "," "]" "," => { + let args = ast::Arg4Sust { + image, + coordinates, + layer: None, + value, + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Sust(details, args) + }, + "sust" ".b" ".a1d" SustClamp "[" "," "{" "," "}" "]" "," => { + let geometry = ast::TextureGeometry::Array1D; + let args = ast::Arg4Sust { + image, + coordinates: ast::Operand::VecPack(vec![x]), + layer: Some(layer), + value, + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Sust(details, args) + }, + "sust" ".b" ".a2d" SustClamp "[" "," "{" "," "," "," RegOrImmediate "}" "]" "," => { + let geometry = ast::TextureGeometry::Array2D; + let args = ast::Arg4Sust { + image, + coordinates: ast::Operand::VecPack(vec![x, y]), + layer: Some(layer), + value, + }; + let details = ast::SurfaceDetails { geometry, vector, type_, direct: false, }; + ast::Instruction::Sust(details, args) + } +} + +SustClamp = { + ".trap", + ".clamp", + ".zero" +} + +UnlayeredTextureGeometry: ast::TextureGeometry = { + ".1d" => ast::TextureGeometry::OneD, + ".2d" => ast::TextureGeometry::TwoD, + ".3d" => ast::TextureGeometry::ThreeD, +} + +TextureChannelType: ast::ScalarType = { + ".u32" => ast::ScalarType::U32, + ".s32" => ast::ScalarType::S32, + ".f16" => ast::ScalarType::F16, + ".f32" => ast::ScalarType::F32, +} + +TextureCoordinateType: ast::ScalarType = { + ".s32" => ast::ScalarType::S32, + ".f32" => ast::ScalarType::F32, +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-shfl +InstShfl: ast::Instruction> = { + "shfl" ".b32" => { + ast::Instruction::Shfl(shuffle_mode, args) + }, + "shfl" ".sync" ".b32" "," Operand => { + ast::Instruction::Shfl(shuffle_mode, args) + } +} + +Arg5Shfl: ast::Arg5Shfl> = { + "," "," "," => { + ast::Arg5Shfl { + dst1, + dst2, + src1, + src2, + src3 + } + } + +} + +ShflMode: ast::ShflMode = { + ".up" => ast::ShflMode::Up, + ".down" => ast::ShflMode::Down, + ".bfly" => ast::ShflMode::Bfly, + ".idx" => ast::ShflMode::Idx +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shf +InstShf: ast::Instruction> = { + "shf" ".b32" => { + ast::Instruction::Shf(ast::FunnelShift{direction, mode}, args) + } +} + +FunnelDirection: ast::FunnelDirection = { + ".l" => ast::FunnelDirection::Left, + ".r" => ast::FunnelDirection::Right +} + +ShiftNormalization: ast::ShiftNormalization = { + ".wrap" => ast::ShiftNormalization::Wrap, + ".clamp" => ast::ShiftNormalization::Clamp +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-vote-sync +InstVote: ast::Instruction> = { + "vote" ".ballot" ".sync" ".b32" "," "," => { + let mode = ast::VoteMode::Ballot; + let negate_pred = negate.is_some(); + let args = ast::Arg3 {dst, src1, src2}; + ast::Instruction::Vote(ast::VoteDetails{mode, negate_pred}, args) + }, + "vote" ".sync" ".ballot" ".b32" "," "," => { + let mode = ast::VoteMode::Ballot; + let negate_pred = negate.is_some(); + let args = ast::Arg3 {dst, src1, src2}; + ast::Instruction::Vote(ast::VoteDetails{mode, negate_pred}, args) + }, + "vote" ".sync" ".any" ".pred" "," "," => { + let mode = ast::VoteMode::Any; + let negate_pred = negate.is_some(); + let args = ast::Arg3 {dst, src1, src2}; + ast::Instruction::Vote(ast::VoteDetails{mode, negate_pred}, args) + }, + "vote" ".sync" ".all" ".pred" "," "," => { + let mode = ast::VoteMode::All; + let negate_pred = negate.is_some(); + let args = ast::Arg3 {dst, src1, src2}; + ast::Instruction::Vote(ast::VoteDetails{mode, negate_pred}, args) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-exit +InstExit: ast::Instruction> = { + "exit" => { + ast::Instruction::Exit + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#miscellaneous-instructions-trap +InstTrap: ast::Instruction> = { + "trap" => { + ast::Instruction::Trap + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#miscellaneous-instructions-brkpt +InstBrkpt: ast::Instruction> = { + "brkpt" => { + ast::Instruction::Brkpt + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#scalar-video-instructions-vshl-vshr +InstVshr: ast::Instruction> = { + "vshr" ".u32" ".u32" ".u32" ".clamp" ".add" => { + ast::Instruction::Vshr(arg) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfind +InstBfind: ast::Instruction> = { + "bfind" ".u32" => { + let details = ast::BfindDetails { shift: false, type_: ast::ScalarType::U32 }; + ast::Instruction::Bfind(details, arg) + }, + "bfind" ".u64" => { + let details = ast::BfindDetails { shift: false, type_: ast::ScalarType::U64 }; + ast::Instruction::Bfind(details, arg) + }, + "bfind" ".shiftamt" ".u32" => { + let details = ast::BfindDetails { shift: true, type_: ast::ScalarType::U32 }; + ast::Instruction::Bfind(details, arg) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-dp4a +InstDp4a: ast::Instruction> = { + "dp4a" ".s32" ".s32" => { + ast::Instruction::Dp4a(ast::ScalarType::S32, arg) + }, + "dp4a" ".u32" ".u32" => { + ast::Instruction::Dp4a(ast::ScalarType::U32, arg) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-match-sync +InstMatch: ast::Instruction> = { + "match" ".any" ".sync" ".b32" => { + ast::Instruction::MatchAny(arg) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-red +InstRed: ast::Instruction> = { + "red" "," => { + let atom_details = ast::AtomDetails { + semantics: ast::AtomSemantics::Relaxed, + scope: ast::MemScope::Gpu, + space, + inner: ast::AtomInnerDetails::Unsigned { op, typ } + }; + let arg = ast::Arg2St { src1, src2 }; + ast::Instruction::Red(atom_details, arg) + }, + "red" "," => { + let atom_details = ast::AtomDetails { + semantics: ast::AtomSemantics::Relaxed, + scope: ast::MemScope::Gpu, + space, + inner: ast::AtomInnerDetails::Bit { op, typ } + }; + let arg = ast::Arg2St { src1, src2 }; + ast::Instruction::Red(atom_details, arg) + }, + "red" ".add" "," => { + let op = ast::AtomFloatOp::Add; + let atom_details = ast::AtomDetails { + semantics: ast::AtomSemantics::Relaxed, + scope: ast::MemScope::Gpu, + space, + inner: ast::AtomInnerDetails::Float { op, typ } + }; + let arg = ast::Arg2St { src1, src2 }; + ast::Instruction::Red(atom_details, arg) + } +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#miscellaneous-instructions-nanosleep +InstNanosleep: ast::Instruction> = { + // Bare minimum for xgboost + "nanosleep" ".u32" => { + ast::Instruction::Nanosleep(a) + } +} + +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 = { + => ast::ArithDetails::Unsigned(t), + => ast::ArithDetails::Signed(ast::ArithSInt { + typ: t, + saturate: false, + }), + ".sat" ".s32" => ast::ArithDetails::Signed(ast::ArithSInt { + typ: ast::ScalarType::S32, + saturate: true, + }), + => ast::ArithDetails::Float(f) +} + +ArithFloat: ast::ArithFloat = { + ".f32" => ast::ArithFloat { + typ: ast::ScalarType::F32, + rounding: rn, + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, + ".f64" => ast::ArithFloat { + typ: ast::ScalarType::F64, + rounding: rn, + flush_to_zero: None, + saturate: false, + }, + ".f16" => ast::ArithFloat { + typ: ast::ScalarType::F16, + rounding: rn.map(|_| ast::RoundingMode::NearestEven), + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, + ".f16x2" => ast::ArithFloat { + typ: ast::ScalarType::F16x2, + rounding: rn.map(|_| ast::RoundingMode::NearestEven), + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, +} + +ArithFloatMustRound: ast::ArithFloat = { + ".f32" => ast::ArithFloat { + typ: ast::ScalarType::F32, + rounding: Some(rn), + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, + ".f64" => ast::ArithFloat { + typ: ast::ScalarType::F64, + rounding: Some(rn), + flush_to_zero: None, + saturate: false, + }, + ".rn" ".f16" => ast::ArithFloat { + typ: ast::ScalarType::F16, + rounding: Some(ast::RoundingMode::NearestEven), + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, + ".rn" ".f16x2" => ast::ArithFloat { + typ: ast::ScalarType::F16x2, + rounding: Some(ast::RoundingMode::NearestEven), + flush_to_zero: Some(ftz.is_some()), + saturate: sat.is_some(), + }, +} + +Operand: ast::Operand<&'input str> = { + => ast::Operand::Reg(r), + "+" => ast::Operand::RegOffset(r, offset), + => ast::Operand::Imm(x) +}; + +CallOperand: ast::Operand<&'input str> = { + => ast::Operand::Reg(r), + => 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 = { + => { + let (num, radix, is_unsigned) = x; + if neg.is_some() { + // because abs(i32::MIN) > abs(i32::MAX) + let mut neg_num = "-".to_string(); + neg_num.push_str(num); + match i64::from_str_radix(&neg_num, radix) { + Ok(x) => ast::ImmediateValue::S64(x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::S64(0) + } + } + } else if is_unsigned { + match u64::from_str_radix(num, radix) { + Ok(x) => ast::ImmediateValue::U64(x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::U64(0) + } + } + } else { + match i64::from_str_radix(num, radix) { + Ok(x) => ast::ImmediateValue::S64(x), + Err(_) => { + match u64::from_str_radix(num, radix) { + Ok(x) => ast::ImmediateValue::U64(x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::U64(0) + } + } + } + } + } + }, + => { + ast::ImmediateValue::F32(f) + }, + => { + ast::ImmediateValue::F64(f) + } +} + +Arg1: ast::Arg1> = { + => ast::Arg1{<>} +}; + +Arg1Bar: ast::Arg1Bar> = { + => ast::Arg1Bar{<>} +}; + +Arg2: ast::Arg2> = { + "," => ast::Arg2{<>} +}; + +MemberOperand: (&'input str, u8) = { + "." => { + let suf_idx = match vector_index(suf) { + Ok(x) => x, + Err(err) => { + errors.push(err); + 0 + } + }; + (pref, suf_idx) + }, + => { + let suf_idx = match vector_index(&suf[1..]) { + Ok(x) => x, + Err(err) => { + errors.push(err); + 0 + } + }; + (pref, suf_idx) + } +}; + +VectorExtract: Vec> = { + "{" "}" => { + vec![r1] + }, + "{" "," "}" => { + vec![r1, r2] + }, + "{" "," "," "," "}" => { + vec![r1, r2, r3, r4] + }, +}; + +RegOrImmediate: ast::RegOrImmediate<&'input str> = { + => ast::RegOrImmediate::Reg(r), + => ast::RegOrImmediate::Imm(imm), +}; + +Arg3: ast::Arg3> = { + "," "," => ast::Arg3{<>} +}; + +Arg3Atom: ast::Arg3> = { + "," "[" "]" "," => ast::Arg3{<>} +}; + +Arg4: ast::Arg4> = { + "," "," "," => ast::Arg4{<>} +}; + +Arg4Atom: ast::Arg4> = { + "," "[" "]" "," "," => ast::Arg4{<>} +}; + +Arg4Setp: ast::Arg4Setp> = { + "," "," => ast::Arg4Setp{<>} +}; + +Arg5: ast::Arg5> = { + "," "," "," "," => ast::Arg5{<>} +}; + +ArgCall: (Vec<&'input str>, &'input str, Vec>, Option<&'input str>) = { + "(" > ")" "," "," "(" > ")" => { + (ret_params, func, param_list, None) + }, + "(" > ")" "," "," "(" > ")" "," => { + (ret_params, func, param_list, Some(fproto)) + }, + "(" > ")" "," => { + (ret_params, func, Vec::new(), None) + }, + "(" > ")" "," "," => { + (ret_params, func, Vec::new(), Some(fproto)) + }, + "," "(" > ")" => + (Vec::new(), func, param_list, None), + "," "(" > ")" "," => + (Vec::new(), func, param_list, Some(fproto)), + => (Vec::new(), func, Vec::>::new(), None), + "," => + (Vec::new(), func, Vec::>::new(), Some(fproto)), +}; + +OptionalDst: &'input str = { + "|" => dst2 +} + +SrcOperand: ast::Operand<&'input str> = { + => ast::Operand::Reg(r), + "+" => ast::Operand::RegOffset(r, offset), + => ast::Operand::Imm(x), + => { + let (reg, idx) = mem_op; + ast::Operand::VecMember(reg, idx) + } +} + +SrcOperandVec: ast::Operand<&'input str> = { + => normal, + => ast::Operand::VecPack(vec), +} + +DstOperand: ast::Operand<&'input str> = { + => ast::Operand::Reg(r), + => { + let (reg, idx) = mem_op; + ast::Operand::VecMember(reg, idx) + } +} + +DstOperandVec: ast::Operand<&'input str> = { + => normal, + => 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 CommaNonEmpty => {}, + SectionLabel ":", + ".b32" SectionLabel, + ".b64" SectionLabel, + ".b32" SectionLabel "+" U32Num, + ".b64" SectionLabel "+" U32Num, +}; + +SectionLabel = { + ID, + DotID +}; + +AnyBitType: ast::ScalarType = { + ".b8" => ast::ScalarType::B8, + ".b16" => ast::ScalarType::B16, + ".b32" => ast::ScalarType::B32, + ".b64" => ast::ScalarType::B64, +}; + +VariableScalarUnitialized: (Option, T, &'input str) = { + => { + (align, type_, name) + } +} + +VariableScalar: (Option, T, &'input str, Vec) = { + => { + let initializer = init.map(ast::ImmediateValue::to_bytes).unwrap_or(Vec::new()); + (align, type_, name, initializer) + } +} + +VariableInitalizer: ast::ImmediateValue = { + "=" => v +} + +VariableVector: (Option, u8, T, &'input str) = { + => { + (align, v_len, type_, name) + } +} + +// empty dimensions [0] means it's a pointer +VariableArrayOrPointer: (Option, T, &'input str, ast::ArrayOrPointer) = { + => { + let mut dims = dims; + let array_init = match init { + Some(init) => { + let init_vec = match init.to_vec(typ, &mut dims) { + Err(error) => { + errors.push(ParseError::User { error }); + Vec::new() + } + Ok(x) => x + }; + ast::ArrayOrPointer::Array { dimensions: dims, init: init_vec } + } + None => { + if dims.len() > 1 && dims.contains(&0) { + errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); + } + match &*dims { + [0] => ast::ArrayOrPointer::Pointer, + _ => ast::ArrayOrPointer::Array { dimensions: dims, init: Vec::new() } + } + } + }; + (align, typ, name, array_init) + } +} + +// [0] and [] are treated the same +ArrayDimensions: Vec = { + ArrayEmptyDimension => vec![0u32], + ArrayEmptyDimension => { + let mut dims = dims; + let mut result = vec![0u32]; + result.append(&mut dims); + result + }, + => dims +} + +ArrayEmptyDimension = { + "[" "]" +} + +ArrayDimension: u32 = { + "[" "]" => n, +} + +ArrayInitializer: ast::NumsOrArrays<'input> = { + "=" => nums +} + +NumsOrArraysBracket: ast::NumsOrArrays<'input> = { + "{" "}" => nums +} + +NumsOrArrays: ast::NumsOrArrays<'input> = { + > => ast::NumsOrArrays::Arrays(n), + > => ast::NumsOrArrays::Nums(n.into_iter().map(|(x,radix,_)| (x, radix)).collect()), +} + +Comma: Vec = { + ",")*> => match e { + None => v, + Some(e) => { + let mut v = v; + v.push(e); + v + } + } +}; + +CommaNonEmpty: Vec = { + ",")*> => { + let mut v = v; + v.push(e); + v + } +}; diff --git a/ptx/src/raytracing.rs b/ptx/src/raytracing.rs new file mode 100644 index 0000000..4c68a11 --- /dev/null +++ b/ptx/src/raytracing.rs @@ -0,0 +1,3906 @@ +// Bulk of the work for raytracing is done across those three transformations: +// * Bounding box needs to convert result pointer from 6xfloat format to +// 8xfloat format. This is done with a very narrow and brittle transformation +// that looks for very specific assembly instructions +// * Conversions that change state space. This is mostly global -> local +// conversion and we don't have a way to generically convert argument +// form one state space to another. So we check only for obvious ones (ld/st). +// This category splits into two subcategories: +// * Variables with internally provided semantics (rtLaunchIndex and such), +// those variables are function arguments, so we convert the instruction +// state space +// * Variables with user-provided attributes, they need additional function +// call to adjust the pointer to use the specific variable +// * Conversion that preserves state space. This is robust and is done only for +// a pointer to a variable block (so with insertion of variable pointer +// calculation) + +use cpp_demangle::{BorrowedSymbol, DemangleOptions}; +use hip_common::raytracing::{Variable, VariablesBlock}; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::{ + alloc::Layout, + borrow::Cow, + cmp, + collections::BTreeMap, + convert, + ffi::{c_void, CStr, CString}, + mem, +}; + +use crate::{ + ast::{self, VariableDeclaration}, + translate::{ + self, ArgumentDescriptor, BrachCondition, CallGraph, ConstType, ConstantDefinition, + ExpandedArgParams, ExpandedStatement, Id, IdGenerator, IdNameMapBuilder, LoadVarDetails, + NormalizedArgParams, PtrAccess, RaytracingEntryPointKind, RaytracingTranslationState, + RepackVectorDetails, ResolvedCall, Statement, StoreVarDetails, TranslationDirective, + TranslationMethod, TranslationModule, TypedArgParams, TypedOperand, Visitable, + }, + TranslateError, +}; + +static ZLUDA_RT_PTX_IMPL_AMD: &'static [u8] = include_bytes!("../lib/zluda_rt_ptx_impl.bc"); +static KERNEL_SOURCE: &'static str = include_str!("../lib/raytracing.cpp"); +static KERNEL_HEADER: &'static str = include_str!("../lib/raytracing.hpp"); +static KERNEL_SOURCE_BOUNDING_BOX: &'static str = + include_str!("../lib/raytracing_bounding_box.cpp"); +static KERNEL_SOURCE_INTERSECT: &'static str = include_str!("../lib/raytracing_intersect.cpp"); +static KERNEL_SOURCE_CALLABLE: &'static str = include_str!("../lib/raytracing_callable.cpp"); +const BUILTIN_PREFIX: &'static str = "__zluda_rt_ptx_impl__"; + +// WARNING: KEEP THIS LIST SYNCHRONIZED WITH zluda_rt_ptx_impl.cpp and raytracing_kernel.cpp +static BUILTINS: &'static [( + ast::LinkingDirective, + &'static [ast::Type], + &'static str, + &'static [ast::Type], +)] = &[ + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B64)], + "_rt_buffer_get_64", + &[ + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B64)], + "_rt_buffer_get_id_64", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ], + "_rt_buffer_get_size_64", + &[ + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B64), + ], + "_rt_buffer_get_id_size_64", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[], + "_rt_trace_mask_flags_64", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[], + "_rt_trace_time_mask_flags_64", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B64), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B32)], + "_rt_get_exception_code", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B32)], + "_rt_print_active", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B32)], + "_rt_potential_intersection", + &[ast::Type::Scalar(ast::ScalarType::F32)], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B32)], + "_rt_report_intersection", + &[ast::Type::Scalar(ast::ScalarType::B32)], + ), + (ast::LinkingDirective::Extern, &[], "_rt_terminate_ray", &[]), + ( + ast::LinkingDirective::Extern, + &[], + "_rt_ignore_intersection", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_transform_tuple", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B64)], + "_rt_callable_program_from_id_64", + &[ast::Type::Scalar(ast::ScalarType::B32)], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B64)], + "_rt_callable_program_from_id_v2_64", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B64), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_texture_get_f_id", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_texture_grad_load_or_request_f_id", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B64), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_texture_lod_load_or_request_f_id", + &[ + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::B32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::B64), + ], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_get_triangle_barycentrics", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::B32)], + "_rt_get_primitive_index", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::F32)], + "_rt_is_triangle_hit", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::F32)], + "_rt_is_triangle_hit_front_face", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ast::Type::Scalar(ast::ScalarType::F32)], + "_rt_is_triangle_hit_back_face", + &[], + ), + ( + ast::LinkingDirective::Extern, + &[ + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ast::Type::Scalar(ast::ScalarType::F32), + ], + "_rt_get_transform", + &[ast::Type::Scalar(ast::ScalarType::B32)], + ), + ( + ast::LinkingDirective::Extern, + &[], + "_rt_throw", + &[ast::Type::Scalar(ast::ScalarType::B32)], + ), +]; + +// WARNING: keep in sync with OptiX runtime and LLVM builtins +static BUFFER_OBJECT_FIELDS: &'static [ast::ScalarType] = &[ + ast::ScalarType::B64, + ast::ScalarType::B64, + ast::ScalarType::B64, +]; + +// OptiX emits function calls, but does not emit function declarations +// This poses the problem at several points in the translation process, the +// earliest being the very first pass. Existing code assumes that if a fn name +// is not present it's ok to bail out with an unknown symbol error. +// We solve it below by injecting those declarations before first pass can run. +// An alternative design would be to change first pass to emit a new name +// for unknown symbol. The problem with that solution is we either: +// * Just ignore symbol coherence and create new symbol at first use, +// this way later passes get a slightly inconsistent. Maybe it's fine, but +// I like this guarantee +// * Keep list of valid places where a raytracing fn can be used. This has the +// problem that we need to keep a list of such places. No thanks +// Another alternative would be to inject into AST, but AST uses references to +// input string. We could change this to Cow, but I want to avoid burdening AST +// with data used only during compilation +pub(crate) fn create_module_with_builtins<'input>() -> TranslationModule<'input, NormalizedArgParams> +{ + let mut id_defs = IdNameMapBuilder::new(IdGenerator::new()); + let ptx_impl_imports = BTreeMap::new(); + let directives = BUILTINS + .into_iter() + .map(|(_, return_arguments, name, input_arguments)| { + create_func_declaration(&mut id_defs, true, return_arguments, name, input_arguments).0 + }) + .collect::>(); + TranslationModule { + compilation_mode: hip_common::CompilationMode::Wave32, + sm_version: 0, + id_defs, + ptx_impl_imports, + directives, + } +} + +fn create_func_declaration<'input, P: ast::ArgParams>( + id_defs: &mut IdNameMapBuilder<'input>, + is_replacement: bool, + return_arguments: &[ast::Type], + name: &'static str, + input_arguments: &[ast::Type], +) -> (TranslationDirective<'input, P>, Id) { + let id_name = id_defs.get_or_add_non_variable(name); + let return_arguments = return_arguments + .iter() + .map(|arg| ast::VariableDeclaration { + align: None, + type_: arg.clone(), + state_space: ast::StateSpace::Reg, + name: id_defs.id_gen.next(), + }) + .collect(); + let input_arguments = input_arguments + .iter() + .map(|arg| ast::VariableDeclaration { + align: None, + type_: arg.clone(), + state_space: ast::StateSpace::Reg, + name: id_defs.id_gen.next(), + }) + .collect(); + ( + TranslationDirective::Method(TranslationMethod { + return_arguments, + name: id_name, + input_arguments, + body: None, + tuning: Vec::new(), + is_kernel: false, + source_name: if is_replacement { + Some(Cow::Owned([BUILTIN_PREFIX, name].concat())) + } else { + None + }, + special_raytracing_linking: false, + }), + id_name, + ) +} + +fn create_func_definition<'input, P: ast::ArgParams>( + id_defs: &mut IdNameMapBuilder<'input>, + return_arguments: &[ast::Type], + name: &'static str, + input_arguments: impl Iterator, +) -> (TranslationMethod<'input, P>, String) { + let source_name = [BUILTIN_PREFIX, name].concat(); + let id_name = id_defs.get_or_add_non_variable(name); + let return_arguments = return_arguments + .iter() + .map(|arg| ast::VariableDeclaration { + align: None, + type_: arg.clone(), + state_space: ast::StateSpace::Reg, + name: id_defs.register_intermediate(Some((arg.clone(), ast::StateSpace::Reg))), + }) + .collect(); + let input_arguments = input_arguments + .map(|(arg, state_space)| ast::VariableDeclaration { + align: None, + type_: arg.clone(), + state_space, + name: id_defs.register_intermediate(Some((arg, state_space))), + }) + .collect(); + ( + TranslationMethod { + return_arguments, + name: id_name, + input_arguments, + body: None, + tuning: Vec::new(), + is_kernel: false, + source_name: Some(Cow::Owned(source_name.clone())), + special_raytracing_linking: true, + }, + source_name, + ) +} + +pub(crate) fn run_on_normalized<'input>( + translation_module: TranslationModule<'input, NormalizedArgParams>, + raytracing_state: &mut RaytracingTranslationState, +) -> Result, TranslateError> { + let translation_module = transform_entry_point(translation_module, raytracing_state)?; + convert_arguments_in_bounding_box_kernel(translation_module, raytracing_state) +} + +pub(crate) fn run_on_typed<'input, 'a>( + translation_module: TranslationModule<'input, TypedArgParams>, + raytracing_state: &'a mut RaytracingTranslationState<'_, 'input>, +) -> Result, TranslateError> { + let translation_module = remove_dead_code(translation_module, raytracing_state)?; + expand_buffer_globals(translation_module, raytracing_state) +} + +fn remove_dead_code<'input, 'a>( + mut translation_module: TranslationModule<'input, TypedArgParams>, + translation_state: &'a mut RaytracingTranslationState, +) -> Result, TranslateError> { + let entry_point = translation_state + .entry_point_id + .ok_or_else(TranslateError::unreachable)?; + let mut call_graph = CallGraph::new(&translation_module.directives[..]); + let mut reachable_user_functions = call_graph + .all_callees + .remove(&entry_point) + .ok_or_else(TranslateError::unreachable)?; + reachable_user_functions.insert(entry_point); + if reachable_user_functions.len() > 1 { + let entry_point_kind = translation_state + .entry_point_kind + .ok_or_else(TranslateError::unreachable)?; + if entry_point_kind == RaytracingEntryPointKind::BoundingBox { + return Err(TranslateError::unexpected_pattern()); + } + } + translation_module.directives = translation_module + .directives + .into_iter() + .filter(|directive| { + if let TranslationDirective::Method(method) = directive { + if method.is_kernel { + false + } else { + method.body.is_none() || reachable_user_functions.contains(&method.name) + } + } else { + true + } + }) + .collect::>(); + translation_state.reachable_user_functions = reachable_user_functions; + Ok(translation_module) +} + +fn fixup_indirect_calls<'input, 'a>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + raytracing_state: &RaytracingTranslationState, + finalized_args: &FinalizedVariablesLayout, +) -> Result, TranslateError> { + let id_defs = &mut translation_module.id_defs; + let directives = &mut translation_module.directives; + for directive in directives.iter_mut() { + match directive { + TranslationDirective::Variable(..) => {} + TranslationDirective::Method(method) => { + let injected_args = finalized_args.injected_args.get(&method.name); + if let Some(ref mut method_body) = method.body { + let injected_args = injected_args.ok_or_else(TranslateError::unreachable)?; + let old_statements = mem::take(method_body); + let mut new_statements = Vec::with_capacity(old_statements.len()); + for statement in old_statements { + match statement { + Statement::Call(mut call) if call.is_indirect => { + let global_state = InjectedArgument::GlobalState.get_type_space(); + let launch_index = InjectedArgument::LaunchIndex.get_type_space(); + let exception_code = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + call.return_arguments.push(( + exception_code, + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )); + call.input_arguments.push(( + injected_args + .get(InjectedArgument::GlobalState) + .ok_or_else(TranslateError::unreachable)?, + global_state.0, + global_state.1, + )); + call.input_arguments.push(( + injected_args + .get(InjectedArgument::LaunchIndex) + .ok_or_else(TranslateError::unreachable)?, + launch_index.0, + launch_index.1, + )); + let src = call.name; + let ld_dst = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + ))); + let ld = Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Global, + caching: ast::LdCacheOperator::Cached, + typ: ast::Type::Scalar(ast::ScalarType::B64), + non_coherent: false, + }, + ast::Arg2Ld { dst: ld_dst, src }, + )); + call.name = ld_dst; + call.input_arguments.push(( + src, + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Global, + )); + new_statements.push(ld); + new_statements.push(Statement::Call(call)); + interpret_exception_code( + id_defs, + raytracing_state, + &*method.return_arguments, + &mut new_statements, + exception_code, + )?; + } + statement => new_statements.push(statement), + } + } + *method_body = new_statements; + }; + } + } + } + Ok(translation_module) +} + +fn interpret_exception_code( + id_defs: &mut IdNameMapBuilder, + raytracing_state: &RaytracingTranslationState, + return_arguments: &[VariableDeclaration], + new_statements: &mut Vec, + exception_code: Id, +) -> Result<(), TranslateError> { + match raytracing_state.entry_point_kind { + Some(RaytracingEntryPointKind::Callable | RaytracingEntryPointKind::Unknown) => {} + _ => return Err(TranslateError::todo()), + }; + insert_call_with_exception_propagation( + id_defs, + new_statements, + exception_code, + |id_defs, body| { + zeroed_return_vector( + id_defs, + &return_arguments[..return_arguments.len() - 1], + body, + ) + }, + ) +} + +// Buffer declarations in PTX look like this: +// .global .align 1 .b8 result_buffer[1]; +// and then are used like this: +// mov.u64 %rd7, result_buffer; +// cvta.global.u64 %rd2, %rd7; +// call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd4, %rd6, %rd6); +// We simply detect this pattern and then convert the type of the global +// TODO: Currently, we detect only this exact pattern and do it badly, but it +// should be made more robust by checking if dst registers (in the example +// above %rd2 and %rd7) are SSA +fn expand_buffer_globals<'input, 'a>( + mut translation_module: TranslationModule<'input, TypedArgParams>, + variables: &'a mut RaytracingTranslationState<'_, 'input>, +) -> Result, TranslateError> { + static BUFFER_BUILTINS: &[&'static str] = &["_rt_buffer_get_64", "_rt_buffer_get_size_64"]; + let buffer_functions = + get_rt_functions_with_undecorated_names(&translation_module, BUFFER_BUILTINS)?; + let mut potential_buffers = FxHashMap::default(); + let mut address_reads = FxHashMap::default(); + let mut address_conversions = FxHashMap::default(); + let mut buffer_call_arguments = FxHashSet::default(); + for (index, directive) in translation_module.directives.iter().enumerate() { + match directive { + TranslationDirective::Variable( + _, + _, + translate::Variable { + align: Some(1), + type_: ast::Type::Array(ast::ScalarType::B8, array_dims), + state_space: ast::StateSpace::Global, + name, + initializer, + }, + ) => { + if &*array_dims == &[1] && initializer.is_none() { + potential_buffers.insert(*name, (index, false)); + } + } + TranslationDirective::Method(method) => { + for statement in method.body.iter().flatten() { + match statement { + Statement::Call(ResolvedCall { + name, + input_arguments, + .. + }) => { + if buffer_functions.contains(name) { + if let TypedOperand::Reg(reg) = input_arguments[0].0 { + buffer_call_arguments.insert(reg); + } + } + } + Statement::Instruction(ast::Instruction::Cvta( + ast::CvtaDetails { + from: ast::StateSpace::Global, + to: ast::StateSpace::Generic, + size: ast::CvtaSize::U64, + }, + ast::Arg2 { + dst: TypedOperand::Reg(dst), + src: TypedOperand::Reg(src), + }, + )) => { + address_conversions.insert(*dst, *src); + } + Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(ast::ScalarType::U64), + .. + }, + ast::Arg2Mov { + dst: TypedOperand::Reg(dst), + src: TypedOperand::Reg(src), + }, + )) => { + address_reads.insert(*dst, *src); + } + _ => {} + } + } + } + _ => {} + } + } + // Working backwards from calls is slightly more robust, because it's more + // likely that destination register is written into only once + for arg in buffer_call_arguments { + if let Some(cvta_src) = address_conversions.get(&arg) { + if let Some(mov_src) = address_reads.get(cvta_src) { + if let Some((_, is_buffer)) = potential_buffers.get_mut(mov_src) { + *is_buffer = true; + } + } + } + } + for (_, (directive_idx, is_buffer)) in potential_buffers { + if is_buffer { + match translation_module + .directives + .get_mut(directive_idx) + .unwrap() + { + TranslationDirective::Variable(_, _, translate::Variable { type_, name, .. }) => { + let str_name = translation_module + .id_defs + .globals + .reverse_variables + .get(name) + .cloned() + .ok_or_else(TranslateError::unreachable)?; + variables.buffers.insert(*name, str_name); + *type_ = ast::Type::Struct( + BUFFER_OBJECT_FIELDS + .iter() + .copied() + .map(ast::StructField::Scalar) + .collect(), + ) + } + _ => return Err(TranslateError::unreachable()), + } + } + } + Ok(translation_module) +} + +fn get_rt_functions_with_undecorated_names( + module: &TranslationModule, + names: &[&'static str], +) -> Result, TranslateError> { + let mut result = Vec::new(); + for directive in module.directives.iter() { + if let TranslationDirective::Method(method) = directive { + if let Some(ref name) = method.source_name { + if name.starts_with(BUILTIN_PREFIX) + && names.contains(&&name[BUILTIN_PREFIX.len()..]) + { + result.push(method.name); + if names.len() == result.len() { + return Ok(result); + } + } + } + } + } + Err(TranslateError::unreachable()) +} + +pub(crate) fn postprocess<'a, 'ast>( + translation_module: TranslationModule<'ast, ExpandedArgParams>, + variables: &mut RaytracingTranslationState<'a, 'ast>, +) -> Result, TranslateError> { + let (translation_module, generated_layout) = convert_global_variables( + translation_module, + variables, + variables + .entry_point_id + .ok_or_else(TranslateError::unreachable)?, + )?; + let translation_module: TranslationModule<'_, ExpandedArgParams> = + replace_exception_functions(translation_module, &variables, &generated_layout)?; + let translation_module = + fixup_indirect_calls(translation_module, &variables, &generated_layout)?; + let translation_module = + generate_attribute_wrapper(translation_module, variables, &generated_layout)?; + let translation_module = expand_rt_functions(translation_module, &generated_layout)?; + let translation_module = replace_trace_control_functions(translation_module, &variables)?; + let translation_module = replace_attribute_functions(translation_module, &generated_layout)?; + variables.variables = generated_layout.variables.globals; + variables.new_attribute_variables = generated_layout.variables.user_attributes; + Ok(translation_module) +} + +// TODO: support throwing from intersection and bounding box +fn replace_exception_functions<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + raytracing_state: &RaytracingTranslationState, + var_tracker: &FinalizedVariablesLayout<'input>, +) -> Result, TranslateError> { + let trace = + inject_return_arg_into_trace_fn(&mut translation_module, "_rt_trace_mask_flags_64")?; + let trace_time = + inject_return_arg_into_trace_fn(&mut translation_module, "_rt_trace_time_mask_flags_64")?; + match raytracing_state.entry_point_kind { + Some(RaytracingEntryPointKind::Unknown | RaytracingEntryPointKind::Callable) => {} + _ => return Ok(translation_module), + }; + let get_exception_code = translation_module + .id_defs + .globals + .variables + .get("_rt_get_exception_code") + .copied() + .ok_or_else(TranslateError::unreachable)?; + let throw = translation_module + .id_defs + .globals + .variables + .get("_rt_throw") + .copied() + .ok_or_else(TranslateError::unreachable)?; + let modified_funcs = get_functions_with_bodies(&translation_module.directives)?; + let mut fixup_declarations = FxHashSet::default(); + for directive in translation_module.directives.iter_mut() { + if let TranslationDirective::Method(method) = directive { + let old_body = match &mut method.body { + Some(body) => { + let name = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + method.return_arguments.push(ast::VariableDeclaration { + align: None, + type_: ast::Type::Scalar(ast::ScalarType::B32), + state_space: ast::StateSpace::Reg, + name, + }); + body.drain(..) + } + None => continue, + }; + fixup_declarations.insert(method.name); + let mut new_body = Vec::with_capacity(old_body.len()); + for statement in old_body { + match statement { + Statement::Call(call) if call.name == get_exception_code => { + let (dst, _, _) = call + .return_arguments + .get(0) + .ok_or_else(TranslateError::unexpected_pattern)?; + let injected_args = var_tracker + .injected_args + .get(&method.name) + .ok_or_else(TranslateError::unreachable)?; + let prim_idx = injected_args + .get(InjectedArgument::PrimitiveIndex) + .ok_or_else(TranslateError::unreachable)?; + new_body.push(Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(ast::ScalarType::B32), + dst_width: 0, + src_width: 0, + relaxed_src2_conv: false, + }, + ast::Arg2Mov { + dst: *dst, + src: prim_idx, + }, + ))) + } + Statement::Call(call) if call.name == throw => { + let mut returned = zeroed_return_vector( + &mut translation_module.id_defs, + &method.return_arguments[..method.return_arguments.len() - 1], + &mut new_body, + )?; + let (error, _, _) = call + .input_arguments + .get(0) + .ok_or_else(TranslateError::unexpected_pattern)?; + returned.push((*error, ast::Type::Scalar(ast::ScalarType::B32))); + new_body.push(Statement::RetValue( + ast::RetData { uniform: false }, + returned, + )) + } + Statement::Call( + mut call @ ResolvedCall { + name, + is_indirect: false, + .. + }, + ) if name == trace || name == trace_time || modified_funcs.contains(&name) => { + let dst = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + call.return_arguments.push(( + dst, + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )); + new_body.push(Statement::Call(call)); + let return_arguments = &method.return_arguments; + insert_call_with_exception_propagation( + &mut translation_module.id_defs, + &mut new_body, + dst, + |id_defs, body| { + zeroed_return_vector( + id_defs, + &return_arguments[..return_arguments.len() - 1], + body, + ) + }, + )?; + } + Statement::RetValue(ret, mut returned) => { + let zero_id = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + let constant = Statement::Constant(ConstantDefinition { + dst: zero_id, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(0), + }); + returned.push((zero_id, ast::Type::Scalar(ast::ScalarType::B32))); + new_body.extend([constant, Statement::RetValue(ret, returned)]); + } + Statement::Instruction(ast::Instruction::Ret(ret)) => { + let zero_id = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + let constant = Statement::Constant(ConstantDefinition { + dst: zero_id, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(0), + }); + let returned = vec![(zero_id, ast::Type::Scalar(ast::ScalarType::B32))]; + new_body.extend([constant, Statement::RetValue(ret, returned)]); + } + s => new_body.push(s), + } + } + method.body = Some(new_body); + } + } + // This is a disgusting hack that should be done better + for directive in translation_module.directives.iter_mut() { + if let TranslationDirective::Method(TranslationMethod { + body: None, + return_arguments, + name, + .. + }) = directive + { + if !fixup_declarations.contains(name) { + continue; + } + let name = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + return_arguments.push(ast::VariableDeclaration { + align: None, + type_: ast::Type::Scalar(ast::ScalarType::B32), + state_space: ast::StateSpace::Reg, + name, + }); + } + } + Ok(translation_module) +} + +fn get_functions_with_bodies( + directives: &[TranslationDirective], +) -> Result, TranslateError> { + let mut result = FxHashSet::default(); + for directive in directives { + match directive { + TranslationDirective::Variable(..) => continue, + TranslationDirective::Method(method) => { + if method.body.is_some() { + result.insert(method.name); + } + } + } + } + Ok(result) +} + +fn zeroed_return_vector<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + return_args: &[ast::VariableDeclaration], + body: &mut Vec, +) -> Result, TranslateError> { + return_args + .iter() + .map(|arg| Ok((zeroed(id_defs, body, &arg.type_)?, arg.type_.clone()))) + .collect::, _>>() +} + +fn zeroed<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + body: &mut Vec, + type_: &ast::Type, +) -> Result { + match type_ { + ast::Type::Scalar(ast::ScalarType::Pred) + | ast::Type::Vector(..) + | ast::Type::Pointer(..) + | ast::Type::Texref + | ast::Type::Surfref + | ast::Type::Struct(..) => Err(TranslateError::unexpected_pattern()), + ast::Type::Scalar(scalar) => { + let dst = id_defs.register_intermediate(Some((type_.clone(), ast::StateSpace::Reg))); + let value = if scalar.kind() == ast::ScalarKind::Float { + ast::ImmediateValue::F64(0f64) + } else { + ast::ImmediateValue::U64(0u64) + }; + body.push(Statement::Constant(ConstantDefinition { + dst, + typ: *scalar, + value, + })); + Ok(dst) + } + ast::Type::Array(scalar, dims) => { + let value = if scalar.kind() == ast::ScalarKind::Float { + ast::ImmediateValue::F64(0f64) + } else { + ast::ImmediateValue::U64(0u64) + }; + let name = id_defs.register_intermediate(Some(( + ast::Type::Array(*scalar, dims.clone()), + ast::StateSpace::Reg, + ))); + let (last_dims, rest_dims) = + dims.split_last().ok_or_else(TranslateError::unreachable)?; + let innermost_dim = ast::Initializer::Array(vec![ + ast::Initializer::Constant(value); + *last_dims as usize + ]); + let initializer = rest_dims.iter().rev().fold(innermost_dim, |init, dim| { + ast::Initializer::Array(vec![init; *dim as usize]) + }); + body.push(Statement::Variable(translate::Variable { + align: None, + type_: ast::Type::Array(*scalar, dims.clone()), + state_space: ast::StateSpace::Local, + name, + initializer: Some(initializer), + })); + let dst = id_defs.register_intermediate(Some(( + ast::Type::Array(*scalar, dims.clone()), + ast::StateSpace::Reg, + ))); + body.push(Statement::LoadVar(LoadVarDetails { + arg: ast::Arg2 { dst, src: name }, + typ: ast::Type::Array(*scalar, dims.clone()), + _state_space: ast::StateSpace::Local, + member_index: None, + })); + Ok(dst) + } + } +} + +fn insert_call_with_exception_propagation<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + new_body: &mut Vec, + exception_code: Id, + default_ret: impl FnOnce( + &mut IdNameMapBuilder<'input>, + &mut Vec, + ) -> Result, TranslateError>, +) -> Result<(), TranslateError> { + let constant = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + let constant_instruction = Statement::Constant(ConstantDefinition { + dst: constant, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(1024), + }); + let early_return = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + ))); + let return_check = Statement::Instruction(ast::Instruction::Setp( + ast::SetpData { + typ: ast::ScalarType::B32, + flush_to_zero: None, + cmp_op: ast::SetpCompareOp::GreaterOrEq, + }, + ast::Arg4Setp { + dst1: early_return, + dst2: None, + src1: exception_code, + src2: constant, + }, + )); + let return_label_id = id_defs.register_intermediate(None); + let return_label = Statement::Label(return_label_id); + let continue_label_id = id_defs.register_intermediate(None); + let continue_label = Statement::Label(continue_label_id); + let return_jmp = Statement::Conditional(BrachCondition { + predicate: early_return, + if_true: return_label_id, + if_false: continue_label_id, + }); + let mut returned = default_ret(id_defs, new_body)?; + returned.push((exception_code, ast::Type::Scalar(ast::ScalarType::B32))); + let return_ = Statement::RetValue(ast::RetData { uniform: false }, returned); + new_body.extend([ + constant_instruction, + return_check, + return_jmp, + return_label, + return_, + continue_label, + ]); + Ok(()) +} + +fn inject_return_arg_into_trace_fn( + translation_module: &mut TranslationModule, + name: &str, +) -> Result { + let fn_ = translation_module + .id_defs + .globals + .variables + .get(name) + .copied() + .ok_or_else(TranslateError::unreachable)?; + + for directive in translation_module.directives.iter_mut() { + if let TranslationDirective::Method(method) = directive { + if method.name != fn_ { + continue; + } + let name = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + method.return_arguments.push(ast::VariableDeclaration { + align: None, + type_: ast::Type::Scalar(ast::ScalarType::B32), + state_space: ast::StateSpace::Reg, + name, + }); + return Ok(fn_); + } + } + Err(TranslateError::unreachable()) +} + +// TODO: replace in subfunctions +fn replace_trace_control_functions<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + raytracing_state: &RaytracingTranslationState, +) -> Result, TranslateError> { + if raytracing_state.entry_point_kind != Some(RaytracingEntryPointKind::Unknown) { + return Ok(translation_module); + } + let ignore_intersection = translation_module + .id_defs + .globals + .variables + .get("_rt_ignore_intersection") + .copied() + .ok_or_else(TranslateError::unreachable)?; + let terminate_ray = translation_module + .id_defs + .globals + .variables + .get("_rt_terminate_ray") + .copied() + .ok_or_else(TranslateError::unreachable)?; + let entry_point = raytracing_state + .entry_point_id + .ok_or_else(TranslateError::unreachable)?; + let func = translation_module + .directives + .iter_mut() + .find_map(|directive| match directive { + TranslationDirective::Variable(..) => None, + TranslationDirective::Method(method) => { + if method.name == entry_point { + Some(method) + } else { + None + } + } + }) + .ok_or_else(TranslateError::unreachable)?; + let mut new_body = Vec::new(); + let old_body = func.body.take().ok_or_else(TranslateError::unreachable)?; + for statement in old_body.into_iter() { + match statement { + Statement::Instruction(ast::Instruction::Ret(ret)) => { + let constant_0 = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + new_body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant_0, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(0), + })); + new_body.push(Statement::RetValue( + ret, + vec![(constant_0, ast::Type::Scalar(ast::ScalarType::B32))], + )); + } + Statement::Call(ResolvedCall { name, .. }) if name == ignore_intersection => { + let constant_1 = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + new_body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant_1, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(1), + })); + new_body.push(Statement::RetValue( + ast::RetData { uniform: false }, + vec![(constant_1, ast::Type::Scalar(ast::ScalarType::B32))], + )); + } + Statement::Call(ResolvedCall { name, .. }) if name == terminate_ray => { + let constant_2 = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + new_body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant_2, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(2), + })); + new_body.push(Statement::RetValue( + ast::RetData { uniform: false }, + vec![(constant_2, ast::Type::Scalar(ast::ScalarType::B32))], + )); + } + statement => new_body.push(statement), + } + } + func.body = Some(new_body); + Ok(translation_module) +} + +fn generate_attribute_wrapper<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + raytracing_state: &mut RaytracingTranslationState, + finalized_args: &FinalizedVariablesLayout<'input>, +) -> Result, TranslateError> { + let get_var_ptr_global = translation_module + .id_defs + .globals + .variables + .get("__zluda_rt_ptx_impl__get_variable_pointer_global") + .copied() + .ok_or_else(TranslateError::unreachable)?; + let entry_point = raytracing_state + .entry_point_id + .ok_or_else(TranslateError::unreachable)?; + let intersection = match raytracing_state.entry_point_kind { + None => return Err(TranslateError::unreachable()), + Some(RaytracingEntryPointKind::Unknown) => false, + Some(RaytracingEntryPointKind::Intersection) => true, + _ => return Ok(translation_module), + }; + let mut original_input_arguments = None; + for directive in translation_module.directives.iter() { + match directive { + TranslationDirective::Variable(..) => continue, + TranslationDirective::Method(method) => { + if method.name != entry_point { + continue; + } + let input_arguments = method + .input_arguments + .iter() + .map(|arg| (arg.name, arg.type_.clone(), arg.state_space)) + .collect::>(); + original_input_arguments = Some(input_arguments); + break; + } + } + } + let original_input_arguments = + original_input_arguments.ok_or_else(TranslateError::unreachable)?; + let entry_injected_args = finalized_args + .injected_args + .get(&entry_point) + .ok_or_else(TranslateError::unreachable)?; + let attribute_block_index = injected_argument_index( + entry_injected_args, + InjectedArgument::AttributesBlock, + &original_input_arguments, + )?; + let variables_block_index = injected_argument_index( + entry_injected_args, + InjectedArgument::VariablesBlock, + &original_input_arguments, + )?; + let (mut method, wrapper_name) = create_func_definition( + &mut translation_module.id_defs, + if intersection { + &[] + } else { + &[ast::Type::Scalar(ast::ScalarType::B32)] + }, + "rollback_wrapper", + original_input_arguments + .iter() + .map(|(_, var_type, state_space)| (var_type.clone(), *state_space)), + ); + let maybe_anyhit_pointer_arg = if intersection { + None + } else { + let anyhit_pointer_arg = translation_module.id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + ))); + method.input_arguments.push(ast::VariableDeclaration { + align: None, + type_: ast::Type::Scalar(ast::ScalarType::B64), + state_space: ast::StateSpace::Reg, + name: anyhit_pointer_arg, + }); + Some(anyhit_pointer_arg) + }; + let mut body = Vec::new(); + let attribute_block = method + .input_arguments + .get(attribute_block_index) + .ok_or_else(TranslateError::unreachable)? + .name; + let original_attribute_values = insert_attribute_prologue( + &mut translation_module.id_defs, + &mut body, + &finalized_args.variables, + get_var_ptr_global, + attribute_block, + )?; + let input_args_to_copy = if intersection { + method.input_arguments.len() + } else { + method.input_arguments.len() - 1 + }; + insert_attribute_call( + &mut translation_module.id_defs, + &mut body, + entry_point, + intersection, + &method.input_arguments[..input_args_to_copy], + None, + )?; + let (control_variable, rollback_constant) = + if let Some(anyhit_pointer_arg) = maybe_anyhit_pointer_arg { + let anyhit_result = insert_attribute_call( + &mut translation_module.id_defs, + &mut body, + anyhit_pointer_arg, + false, + &method.input_arguments[..method.input_arguments.len() - 1], + Some(variables_block_index), + )?; + (anyhit_result, 1) + } else { + let intersection_result_index = injected_argument_index( + entry_injected_args, + InjectedArgument::IntersectionResult, + &original_input_arguments, + )?; + let intersection_result = method + .input_arguments + .get(intersection_result_index) + .ok_or_else(TranslateError::unreachable)? + .name; + let loaded_intersection_result = insert_attribute_intersection_result_load( + &mut translation_module.id_defs, + &mut body, + intersection_result, + ); + (loaded_intersection_result, 2) + }; + let return_label = translation_module.id_defs.register_intermediate(None); + insert_attribute_anyhit_check_rollback_jmp( + &mut translation_module.id_defs, + &mut body, + control_variable, + return_label, + rollback_constant, + ); + insert_attribute_rollback( + &mut translation_module.id_defs, + &mut body, + get_var_ptr_global, + attribute_block, + original_attribute_values, + ); + body.push(Statement::Label(return_label)); + if intersection { + body.push(Statement::Instruction(ast::Instruction::Ret( + ast::RetData { uniform: false }, + ))); + } else { + body.push(Statement::RetValue( + ast::RetData { uniform: false }, + vec![(control_variable, ast::Type::Scalar(ast::ScalarType::B32))], + )); + } + method.body = Some(body); + translation_module + .directives + .push(TranslationDirective::Method(method)); + if intersection { + raytracing_state.kernel_name = wrapper_name; + } + Ok(translation_module) +} + +fn insert_attribute_intersection_result_load( + id_defs: &mut IdNameMapBuilder, + body: &mut Vec, ExpandedArgParams>>, + intersection_result: Id, +) -> Id { + let (type_, state_space) = InjectedArgument::IntersectionResult.get_type_space(); + let dst = id_defs.register_intermediate(Some((type_.clone(), ast::StateSpace::Reg))); + body.push(Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + caching: ast::LdCacheOperator::Cached, + non_coherent: false, + state_space, + typ: type_, + }, + ast::Arg2Ld { + dst, + src: intersection_result, + }, + ))); + dst +} + +fn injected_argument_index( + entry_injected_args: &InjectedArguments, + kind: InjectedArgument, + original_input_arguments: &Vec<(Id, ast::Type, ast::StateSpace)>, +) -> Result { + let original_id = entry_injected_args + .get(kind) + .ok_or_else(TranslateError::unreachable)?; + let index = original_input_arguments + .iter() + .enumerate() + .find_map(|(index, (name, _, _))| { + if *name == original_id { + Some(index) + } else { + None + } + }) + .ok_or_else(TranslateError::unreachable)?; + Ok(index) +} + +fn insert_attribute_prologue<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + result: &mut Vec, + var_tracker: &VariablesLayout<'input>, + get_var_ptr_global: Id, + attribute_block: Id, +) -> Result, TranslateError> { + let mut new_values = Vec::new(); + for (id, sema) in var_tracker.tracker.global_to_semantic.iter() { + let (type_, offset) = if let VariableSemantic::Attribute { type_, .. } = sema { + let offset = var_tracker + .offsets + .get(id) + .ok_or_else(TranslateError::unreachable)?; + (type_, *offset) + } else { + continue; + }; + let var_ptr = insert_call_to_get_variable_pointer( + id_defs, + attribute_block, + (get_var_ptr_global, ast::StateSpace::Global), + result, + offset, + ); + let dst = id_defs.register_intermediate(Some((type_.clone(), ast::StateSpace::Reg))); + // TODO: use alignment + result.push(ExpandedStatement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Global, + caching: ast::LdCacheOperator::Cached, + typ: type_.clone(), + non_coherent: false, + }, + ast::Arg2Ld { dst, src: var_ptr }, + ))); + new_values.push((dst, type_.clone(), offset)); + } + Ok(new_values) +} + +fn insert_attribute_call( + id_defs: &mut IdNameMapBuilder, + fn_body: &mut Vec, + mut function: Id, + intersection: bool, + input_arguments: &[ast::VariableDeclaration], + indirect_remap: Option, +) -> Result { + fn input_arg_convert(var: &ast::VariableDeclaration) -> (Id, ast::Type, ast::StateSpace) { + (var.name, var.type_.clone(), var.state_space) + } + let mut input_arguments: Vec<_> = input_arguments.iter().map(input_arg_convert).collect(); + if let Some(index) = indirect_remap { + let constant_0_b64 = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + ))); + fn_body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant_0_b64, + typ: ast::ScalarType::B64, + value: ast::ImmediateValue::U64(0), + })); + let is_null = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + ))); + fn_body.push(Statement::Instruction(ast::Instruction::Setp( + ast::SetpData { + typ: ast::ScalarType::B64, + flush_to_zero: None, + cmp_op: ast::SetpCompareOp::Eq, + }, + ast::Arg4Setp { + dst1: is_null, + dst2: None, + src1: function, + src2: constant_0_b64, + }, + ))); + let early_exit = id_defs.register_intermediate(None); + let continue_execution = id_defs.register_intermediate(None); + let constant_0_b32 = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + fn_body.push(Statement::Conditional(BrachCondition { + predicate: is_null, + if_true: early_exit, + if_false: continue_execution, + })); + fn_body.push(Statement::Label(early_exit)); + fn_body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant_0_b32, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(0), + })); + fn_body.push(ExpandedStatement::RetValue( + ast::RetData { uniform: false }, + vec![(constant_0_b32, ast::Type::Scalar(ast::ScalarType::B32))], + )); + fn_body.push(Statement::Label(continue_execution)); + input_arguments[index].0 = function; + let fn_ptr = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + ))); + fn_body.push(Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Global, + caching: ast::LdCacheOperator::Cached, + typ: ast::Type::Scalar(ast::ScalarType::B64), + non_coherent: false, + }, + ast::Arg2Ld { + dst: fn_ptr, + src: function, + }, + ))); + function = fn_ptr; + } + let return_value = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + if intersection { + let return_arguments = vec![]; + fn_body.push(Statement::Call(ResolvedCall { + uniform: false, + return_arguments, + name: function, + input_arguments, + is_indirect: indirect_remap.is_some(), + })); + } else { + let return_arguments = vec![( + return_value, + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )]; + let call = ResolvedCall { + uniform: false, + return_arguments, + name: function, + input_arguments, + is_indirect: indirect_remap.is_some(), + }; + fn_body.push(Statement::Call(call)); + insert_call_with_exception_propagation(id_defs, fn_body, return_value, |_, _| { + Ok(Vec::new()) + })?; + }; + Ok(return_value) +} + +fn insert_attribute_anyhit_check_rollback_jmp( + id_defs: &mut IdNameMapBuilder, + body: &mut Vec, + anyhit_result: Id, + return_anyhit: Id, + rollback_on: u64, +) -> Id { + let constant = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + body.push(ExpandedStatement::Constant(ConstantDefinition { + dst: constant, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(rollback_on), + })); + let anyhit_is_eq = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + ))); + body.push(ExpandedStatement::Instruction(ast::Instruction::Setp( + ast::SetpData { + typ: ast::ScalarType::B32, + flush_to_zero: None, + cmp_op: ast::SetpCompareOp::Eq, + }, + ast::Arg4Setp { + dst1: anyhit_is_eq, + dst2: None, + src1: anyhit_result, + src2: constant, + }, + ))); + let rollback = id_defs.register_intermediate(None); + body.push(ExpandedStatement::Conditional(BrachCondition { + predicate: anyhit_is_eq, + if_true: rollback, + if_false: return_anyhit, + })); + body.push(ExpandedStatement::Label(rollback)); + rollback +} + +fn insert_attribute_rollback<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + result: &mut Vec, + get_var_ptr_global: Id, + attribute_block: Id, + original_attribute_values: Vec<(Id, ast::Type, u32)>, +) { + for (variable, type_, offset) in original_attribute_values.iter() { + let var_ptr = insert_call_to_get_variable_pointer( + id_defs, + attribute_block, + (get_var_ptr_global, ast::StateSpace::Global), + result, + *offset, + ); + // TODO: use alignment + result.push(ExpandedStatement::Instruction(ast::Instruction::St( + ast::StData { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Global, + caching: ast::StCacheOperator::Writeback, + typ: type_.clone(), + }, + ast::Arg2St { + src1: var_ptr, + src2: *variable, + }, + ))); + } +} + +fn expand_rt_functions<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + var_tracker: &FinalizedVariablesLayout<'input>, +) -> Result, TranslateError> { + let potential_intersection = + get_function_id(&translation_module, "_rt_potential_intersection")?; + let potential_intersection_new_args = [ + InjectedArgument::CurrentRay, + InjectedArgument::IntersectionDistance, + ]; + let report_intersection = get_function_id(&translation_module, "_rt_report_intersection")?; + let report_intersection_new_args = [ + InjectedArgument::GlobalState, + InjectedArgument::LaunchIndex, + InjectedArgument::LaunchDim, + InjectedArgument::CurrentRay, + InjectedArgument::CurrentTime, + InjectedArgument::Payload, + InjectedArgument::VariablesBlock, + InjectedArgument::AttributesBlock, + InjectedArgument::TransformBlock, + InjectedArgument::NewDistance, + InjectedArgument::IntersectionResult, + InjectedArgument::MaterialResult, + ]; + let is_triangle_hit = get_function_id(&translation_module, "_rt_is_triangle_hit")?; + let is_triangle_hit_new_args = [InjectedArgument::TriangleNormals]; + let is_triangle_hit_front_face = + get_function_id(&translation_module, "_rt_is_triangle_hit_front_face")?; + let is_triangle_hit_front_face_new_args = [ + InjectedArgument::CurrentRay, + InjectedArgument::TriangleNormals, + ]; + let is_triangle_hit_back_face = + get_function_id(&translation_module, "_rt_is_triangle_hit_back_face")?; + let is_triangle_hit_back_face_new_args = [ + InjectedArgument::CurrentRay, + InjectedArgument::TriangleNormals, + ]; + let rt_get_transform = get_function_id(&translation_module, "_rt_get_transform")?; + let rt_get_transform_new_args = [InjectedArgument::TransformBlock]; + let rt_trace_mask_flags = get_function_id(&translation_module, "_rt_trace_mask_flags_64")?; + let rt_trace_time_mask_flags = + get_function_id(&translation_module, "_rt_trace_time_mask_flags_64")?; + let rt_buffer_get_id_64 = get_function_id(&translation_module, "_rt_buffer_get_id_64")?; + let rt_buffer_get_id_size_64 = + get_function_id(&translation_module, "_rt_buffer_get_id_size_64")?; + let rt_callable_program_from_id_64 = + get_function_id(&translation_module, "_rt_callable_program_from_id_64")?; + let rt_callable_program_from_id_v2_64 = + get_function_id(&translation_module, "_rt_callable_program_from_id_v2_64")?; + let rt_texture_get_f_id = get_function_id(&translation_module, "_rt_texture_get_f_id")?; + let rt_texture_grad_load_or_request_f_id = + get_function_id(&translation_module, "_rt_texture_grad_load_or_request_f_id")?; + let rt_texture_lod_load_or_request_f_id = + get_function_id(&translation_module, "_rt_texture_lod_load_or_request_f_id")?; + let inject_globals_arg = [InjectedArgument::GlobalState]; + let injection_table = [ + ( + potential_intersection, + &potential_intersection_new_args[..], + true, + ), + (report_intersection, &report_intersection_new_args[..], true), + (is_triangle_hit, &is_triangle_hit_new_args[..], false), + ( + is_triangle_hit_front_face, + &is_triangle_hit_front_face_new_args[..], + false, + ), + ( + is_triangle_hit_back_face, + &is_triangle_hit_back_face_new_args[..], + false, + ), + (rt_get_transform, &rt_get_transform_new_args[..], false), + (rt_trace_mask_flags, &inject_globals_arg[..], false), + (rt_trace_time_mask_flags, &inject_globals_arg[..], false), + (rt_buffer_get_id_64, &inject_globals_arg[..], false), + (rt_buffer_get_id_size_64, &inject_globals_arg[..], false), + ( + rt_callable_program_from_id_64, + &inject_globals_arg[..], + false, + ), + ( + rt_callable_program_from_id_v2_64, + &inject_globals_arg[..], + false, + ), + (rt_texture_get_f_id, &inject_globals_arg[..], false), + ( + rt_texture_grad_load_or_request_f_id, + &inject_globals_arg[..], + false, + ), + ( + rt_texture_lod_load_or_request_f_id, + &inject_globals_arg[..], + false, + ), + ]; + for directive in translation_module.directives.iter_mut() { + match directive { + TranslationDirective::Method(method) => { + let func_name = method.name; + let extra_args = injection_table + .iter() + .find(|(name, _, _)| *name == func_name); + if let Some((_, extra_args, add_potential_dist)) = extra_args { + append_rt_function_arguments_to_declaration( + &mut translation_module.id_defs, + &mut method.input_arguments, + extra_args, + *add_potential_dist, + ); + continue; + } + if let Some(ref mut body) = method.body { + let injected_fn_args = var_tracker.injected_args.get(&func_name); + // Currently rollback wrapper does not emit information about injected args, so we skip + // TODO: make rollback wrapper emit injected args information and fail on None here + // TODO: replace match with unwrap_or_continue!(...) + let injected_fn_args = match injected_fn_args { + Some(a) => a, + None => continue, + }; + *body = expand_rt_instructions( + &mut translation_module.id_defs, + mem::take(body), + &injection_table[..], + injected_fn_args, + )?; + }; + } + TranslationDirective::Variable(..) => {} + } + } + Ok(translation_module) +} + +fn get_function_id( + translation_module: &TranslationModule, + name: &'static str, +) -> Result { + translation_module + .id_defs + .globals + .variables + .get(name) + .copied() + .ok_or_else(TranslateError::unreachable) +} + +fn replace_attribute_functions<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, + var_tracker: &FinalizedVariablesLayout<'input>, +) -> Result, TranslateError> { + let get_triangle_barycentrics = translation_module + .id_defs + .globals + .variables + .get("_rt_get_triangle_barycentrics") + .ok_or_else(TranslateError::unreachable)?; + let get_triangle_barycentrics_marker = InjectedArgument::TriangleBarycentrics; + let get_primitive_index = translation_module + .id_defs + .globals + .variables + .get("_rt_get_primitive_index") + .ok_or_else(TranslateError::unreachable)?; + let get_primitive_index_marker = InjectedArgument::PrimitiveIndex; + let replacement_candidates = [ + (*get_triangle_barycentrics, get_triangle_barycentrics_marker), + (*get_primitive_index, get_primitive_index_marker), + ]; + for directive in translation_module.directives.iter_mut() { + match directive { + TranslationDirective::Method(method) => { + let func_name = if method.is_kernel { + continue; + } else { + method.name + }; + let function_injected_args = match var_tracker.injected_args.get(&func_name) { + Some(args) => args, + None => continue, + }; + for statement in method.body.iter_mut().flatten() { + match statement { + Statement::Call(call) => { + if let Some(replacement_statement) = replace_attribute_function_call( + call, + function_injected_args, + replacement_candidates.iter().copied(), + )? { + *statement = replacement_statement; + } + } + _ => {} + } + } + } + _ => {} + } + } + Ok(translation_module) +} + +fn replace_attribute_function_call( + call: &mut ResolvedCall, + injected_args: &InjectedArguments, + candidates: impl Iterator, +) -> Result, TranslateError> { + for (function, injected_kind) in candidates { + if call.name != function { + continue; + } + let method_arg = injected_args + .get(injected_kind) + .ok_or_else(TranslateError::unreachable)?; + let (typ, space) = injected_kind.get_type_space(); + if space != ast::StateSpace::Reg { + return Err(TranslateError::unreachable()); + } + if call.return_arguments.len() == 1 { + return Ok(Some(Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: typ.clone(), + dst_width: 0, + src_width: 0, + relaxed_src2_conv: false, + }, + ast::Arg2Mov { + dst: call.return_arguments[0].0, + src: method_arg, + }, + )))); + } else { + let (scalar_type, vector_len) = match typ { + ast::Type::Vector(t, l) => (t, l), + _ => return Err(TranslateError::unreachable()), + }; + if call.return_arguments.len() != vector_len as usize { + return Err(TranslateError::unreachable()); + } + return Ok(Some(Statement::RepackVector(RepackVectorDetails { + is_extract: true, + typ: scalar_type, + packed: method_arg, + unpacked: call.return_arguments.iter().map(|(id, _, _)| *id).collect(), + non_default_implicit_conversion: None, + }))); + } + } + Ok(None) +} + +fn expand_rt_instructions( + id_defs: &mut IdNameMapBuilder, + method_body: Vec, + injection_table: &[(Id, &[InjectedArgument], bool)], + injected_fn_args: &InjectedArguments, +) -> Result, TranslateError> { + let mut result = Vec::with_capacity(method_body.len()); + let potential_distance_var = id_defs.register_variable_def( + None, + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Local, + Some(ast::Initializer::Constant(ast::ImmediateValue::F32(0f32))), + ); + let potential_distance = potential_distance_var.name; + result.push(Statement::Variable(potential_distance_var)); + for mut statement in method_body { + if let Statement::Call(ref mut call) = statement { + if let Some((_, new_args, inject_distance)) = injection_table + .iter() + .find(|(name, _, _)| *name == call.name) + { + append_intersection_arguments_to_call( + &mut call.input_arguments, + new_args, + injected_fn_args, + if *inject_distance { + Some(potential_distance) + } else { + None + }, + )?; + } + } + result.push(statement); + } + Ok(result) +} + +fn append_rt_function_arguments_to_declaration( + id_defs: &mut IdNameMapBuilder, + input_arguments: &mut Vec>, + new_args: &[InjectedArgument], + add_potential_distance: bool, +) { + for arg in new_args { + let (type_, state_space) = arg.get_type_space(); + let name = id_defs.register_intermediate(Some((type_.clone(), state_space))); + input_arguments.push(ast::VariableDeclaration { + type_, + state_space, + name, + align: None, + }); + } + if !add_potential_distance { + return; + } + let name = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Local, + ))); + input_arguments.push(ast::VariableDeclaration { + type_: ast::Type::Scalar(ast::ScalarType::F32), + state_space: ast::StateSpace::Local, + name, + align: None, + }) +} + +fn append_intersection_arguments_to_call( + input_arguments: &mut Vec<(Id, ast::Type, ast::StateSpace)>, + new_args: &[InjectedArgument], + fn_args: &InjectedArguments, + maybe_potential_distance: Option, +) -> Result<(), TranslateError> { + for arg in new_args { + let name = fn_args.get(*arg).ok_or_else(TranslateError::unreachable)?; + let (type_, state_space) = arg.get_type_space(); + input_arguments.push((name, type_, state_space)); + } + if let Some(potential_distance) = maybe_potential_distance { + input_arguments.push(( + potential_distance, + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Local, + )); + } + Ok(()) +} + +// Optix and HIP RT represent bounding boxes slightly differently +// Optix uses (xmin, ymin, zmin), (xmax, ymax, zmax) +// HIP RT uses (xmin, ymin, zmin, unused), (xmax, ymax, zmax, unused) +// This pass converts all store from OptiX format to HIP RT +// TODO: This pass is very brittle, have a fallback conversion if it does not succeed +fn convert_arguments_in_bounding_box_kernel<'input>( + mut translation_module: TranslationModule<'input, NormalizedArgParams>, + raytracing_state: &RaytracingTranslationState, +) -> Result, TranslateError> { + if raytracing_state.entry_point_kind != Some(RaytracingEntryPointKind::BoundingBox) { + return Ok(translation_module); + } + let entry_point_id = raytracing_state.entry_point_id.unwrap(); + for directive in translation_module.directives.iter_mut() { + match directive { + TranslationDirective::Method(method) => { + if method.name != entry_point_id { + continue; + } + let variable_id = method.input_arguments[1].name; + let mut lds = FxHashSet::default(); + for statement in method.body.iter().flatten() { + match statement { + Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + state_space: ast::StateSpace::Param, + typ, + .. + }, + ast::Arg2Ld { + dst: ast::Operand::Reg(dst), + src: ast::Operand::Reg(src_reg), + }, + )) if *src_reg == variable_id + && typ.layout().size() == mem::size_of::<*const c_void>() => + { + lds.insert(*dst); + } + _ => {} + } + } + if lds.len() == 0 { + return Err(TranslateError::unexpected_pattern()); + } + let mut cvtas = FxHashSet::default(); + for statement in method.body.iter().flatten() { + match statement { + Statement::Instruction(ast::Instruction::Cvta( + ast::CvtaDetails { + to: ast::StateSpace::Global, + .. + }, + ast::Arg2 { + dst: ast::Operand::Reg(dst), + src: ast::Operand::Reg(src), + }, + )) if lds.contains(src) => { + cvtas.insert(*dst); + } + _ => {} + } + } + if cvtas.len() == 0 { + return Err(TranslateError::unexpected_pattern()); + } + for statement in method.body.iter_mut().flatten() { + match statement { + Statement::Instruction(ast::Instruction::St( + _, + ast::Arg2St { + src1: ast::Operand::RegOffset(src_reg, offset), + .. + }, + )) if cvtas.contains(src_reg) => { + if *offset >= (mem::size_of::() * 3) as i64 { + *offset = *offset + mem::size_of::() as i64; + } + } + _ => {} + } + } + } + _ => {} + } + } + Ok(translation_module) +} + +// We do following transformations: +// * Make all methods with bodies except entry point private +// * Turn entry point from kernel to a function +// * Turn existing kernel .param arguments into .reg arguments +pub(crate) fn transform_entry_point<'ast, P: ast::ArgParams>( + mut translation_module: TranslationModule<'ast, P>, + translation_state: &mut RaytracingTranslationState, +) -> Result, TranslateError> { + let mut suffixed_entry_point = translation_state.entry_point_str.to_string(); + suffixed_entry_point.push('('); + for directive in translation_module.directives.iter_mut() { + if let TranslationDirective::Method(method) = directive { + if let Some(kernel_name) = is_raytracing_entry_point( + &method.source_name, + translation_state.entry_point_str, + &suffixed_entry_point, + )? { + let kind = if !method.is_kernel { + RaytracingEntryPointKind::Callable + } else if method.input_arguments.len() == 2 { + RaytracingEntryPointKind::BoundingBox + } else if method.input_arguments.len() == 1 { + RaytracingEntryPointKind::Intersection + } else { + RaytracingEntryPointKind::Unknown + }; + method.is_kernel = false; + method.special_raytracing_linking = true; + translation_state.kernel_name = kernel_name.to_string(); + translation_state.entry_point_id = Some(method.name); + translation_state.entry_point_kind = Some(kind); + } + } + } + if let None = translation_state.entry_point_id { + return Err(TranslateError::unexpected_pattern()); + } + Ok(translation_module) +} + +// We do following transformations: +// * Inject implicit OptiX parameters into entry point arguments +// * Convert Optix variables with builtin-semantic to movs from entry point arguments +// * Convert Optix variables with no builtin-semantic to loads from variable block +// * Convert Optix attribute variables to load from attribute block +// * Remove all globals (variables and methods) +// TODO: support non-2D launch indexes +// TODO: propagate RT variables to subfunctions +fn convert_global_variables<'a, 'ast>( + mut translation_module: TranslationModule<'ast, ExpandedArgParams>, + raytracing_state: &mut RaytracingTranslationState<'a, 'ast>, + entry_point: Id, +) -> Result< + ( + TranslationModule<'ast, ExpandedArgParams>, + FinalizedVariablesLayout<'ast>, + ), + TranslateError, +> { + let kind = raytracing_state + .entry_point_kind + .ok_or_else(TranslateError::unreachable)?; + let variables_layout = + collect_variable_and_attribute_declarations(&translation_module, raytracing_state)?; + let id_defs = &mut translation_module.id_defs; + let mut directives = Vec::new(); + let (get_var_pointer_global_decl, get_variable_pointer_global) = create_func_declaration( + id_defs, + false, + &[ast::Type::Pointer( + ast::ScalarType::B8, + ast::StateSpace::Global, + )], + "__zluda_rt_ptx_impl__get_variable_pointer_global", + &[ + ast::Type::Pointer(ast::ScalarType::B8, ast::StateSpace::Global), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ); + let (get_var_pointer_shared_decl, get_variable_pointer_shared) = create_func_declaration( + id_defs, + false, + &[ast::Type::Pointer( + ast::ScalarType::B8, + ast::StateSpace::Shared, + )], + "__zluda_rt_ptx_impl__get_variable_pointer_shared", + &[ + ast::Type::Pointer(ast::ScalarType::B8, ast::StateSpace::Shared), + ast::Type::Scalar(ast::ScalarType::B32), + ], + ); + directives.push(get_var_pointer_global_decl); + directives.push(get_var_pointer_shared_decl); + let (directives, mut layout_and_args) = + remove_unused_globals_and_inject_arguments_into_entry_point( + id_defs, + mem::take(&mut translation_module.directives), + directives, + entry_point, + kind, + variables_layout, + )?; + translation_module.directives = propagate_injected_arguments_to_callees( + id_defs, + directives, + entry_point, + &raytracing_state.reachable_user_functions, + &mut layout_and_args, + )?; + translation_module.directives = convert_optix_builtin_variable_and_attribute_access( + id_defs, + mem::take(&mut translation_module.directives), + &layout_and_args, + (get_variable_pointer_global, get_variable_pointer_shared), + )?; + translation_module.directives = fixup_variables_with_empty_semantic( + id_defs, + mem::take(&mut translation_module.directives), + &layout_and_args, + get_variable_pointer_global, + )?; + Ok((translation_module, layout_and_args)) +} + +fn propagate_injected_arguments_to_callees<'ast>( + id_defs: &mut IdNameMapBuilder<'ast>, + mut directives: Vec>, + entry_point_id: Id, + reachable_functions: &FxHashSet, + var_tracker: &mut FinalizedVariablesLayout<'ast>, +) -> Result>, TranslateError> { + let entry_point_method = get_function_by_id(&directives, entry_point_id)?; + let injected_args = get_injected_args( + entry_point_id, + &entry_point_method, + &var_tracker.injected_args, + )?; + propagate_injected_args( + id_defs, + &mut directives, + entry_point_id, + reachable_functions, + var_tracker, + injected_args, + )?; + Ok(directives) +} + +// We've removed all unreachable functions so everything at this point is reachable +fn propagate_injected_args<'input>( + id_defs: &mut IdNameMapBuilder, + directives: &mut Vec>, + entry_point: Id, + reachable_functions: &FxHashSet, + var_tracker: &mut FinalizedVariablesLayout<'input>, + injected_args: Vec, +) -> Result<(), TranslateError> { + for directive in directives { + if let TranslationDirective::Method(method) = directive { + let func_name = method.name; + let func_injected_args = if func_name == entry_point { + var_tracker + .injected_args + .get(&func_name) + .ok_or_else(TranslateError::unreachable)? + } else { + let mut func_injected_args = InjectedArguments::new(); + for arg in injected_args.iter().copied() { + let (type_, state_space) = arg.get_type_space(); + let name = id_defs.register_intermediate(Some((type_.clone(), state_space))); + method.input_arguments.push(ast::VariableDeclaration { + align: None, + type_, + state_space, + name, + }); + func_injected_args.set(arg, name); + } + if method.body.is_some() { + match var_tracker.injected_args.entry(func_name) { + std::collections::hash_map::Entry::Occupied(_) => { + return Err(TranslateError::unreachable()); + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(func_injected_args) + } + } + } else { + continue; + } + }; + for statement in method.body.iter_mut().flatten() { + if let Statement::Call(call) = statement { + if reachable_functions.contains(&call.name) { + for arg_kind in injected_args.iter() { + let (type_, space) = arg_kind.get_type_space(); + let name = func_injected_args + .get(*arg_kind) + .ok_or_else(TranslateError::unreachable)?; + call.input_arguments.push((name, type_, space)); + } + } + } + } + } + } + Ok(()) +} + +fn get_function_by_id<'a, 'ast>( + directives: &'a [TranslationDirective<'ast, ExpandedArgParams>], + fn_name: Id, +) -> Result<&'a TranslationMethod<'ast, ExpandedArgParams>, TranslateError> { + directives + .iter() + .find_map(|directive| { + if let TranslationDirective::Method(method) = directive { + if method.name == fn_name { + return Some(method); + } + } + None + }) + .ok_or_else(TranslateError::unreachable) +} + +fn get_injected_args<'a, 'ast>( + entry_point_id: Id, + entry_point: &'a TranslationMethod<'ast, ExpandedArgParams>, + injected_args: &FxHashMap, +) -> Result, TranslateError> { + let entry_injected = injected_args + .get(&entry_point_id) + .ok_or_else(TranslateError::unreachable)?; + Ok(entry_point + .input_arguments + .iter() + .filter_map(|arg| entry_injected.find_by_id(arg.name)) + .collect::>()) +} + +fn remove_unused_globals_and_inject_arguments_into_entry_point<'a, 'ast>( + id_defs: &mut IdNameMapBuilder<'ast>, + old_directives: Vec>, + mut new_directives: Vec>, + entry_point: Id, + kind: RaytracingEntryPointKind, + variables: VariablesLayout<'ast>, +) -> Result< + ( + Vec>, + FinalizedVariablesLayout<'ast>, + ), + TranslateError, +> { + let mut variables_with_args = FinalizedVariablesLayout { + variables, + injected_args: FxHashMap::default(), + }; + for directive in old_directives { + match directive { + TranslationDirective::Variable(_, _, variable) => { + if let Some(name) = id_defs.globals.reverse_variables.get(&variable.name) { + if let Some(demangled_name) = demangle(name) { + // Those variables are somehow used by exception programs + // TODO: use this correctly + if demangled_name.starts_with("rti_internal_register::") { + new_directives.push(TranslationDirective::Variable( + ast::LinkingDirective::None, + None, + variable, + )); + continue; + } else if demangled_name.starts_with("rti_internal") { + continue; + } + } + } + // String constants are used by exception handling + if variable.initializer.is_some() { + new_directives.push(TranslationDirective::Variable( + ast::LinkingDirective::None, + None, + variable, + )); + } + } + TranslationDirective::Method(mut method) => { + if method.name != entry_point { + new_directives.push(TranslationDirective::Method(method)); + continue; + } + let mut injected_args = InjectedArguments::new(); + injected_args.set( + InjectedArgument::GlobalState, + inject_argument( + InjectedArgument::GlobalState.get_type_space(), + id_defs, + &mut method, + ), + ); + if kind == RaytracingEntryPointKind::Unknown { + injected_args.set( + InjectedArgument::PrimitiveIndex, + inject_argument( + InjectedArgument::PrimitiveIndex.get_type_space(), + id_defs, + &mut method, + ), + ); + } else if kind == RaytracingEntryPointKind::BoundingBox + || kind == RaytracingEntryPointKind::Intersection + { + injected_args.set( + InjectedArgument::PrimitiveIndex, + method.input_arguments[0].name, + ); + } + variables_with_args.remap_fn_arguments( + kind, + &mut injected_args, + |type_, state_space| { + let var_name = + id_defs.register_intermediate(Some((type_.clone(), state_space))); + method.input_arguments.push(ast::VariableDeclaration { + type_: type_, + state_space, + name: var_name, + align: None, + }); + var_name + }, + ); + if kind == RaytracingEntryPointKind::Unknown { + injected_args.set( + InjectedArgument::TriangleBarycentrics, + inject_argument( + InjectedArgument::TriangleBarycentrics.get_type_space(), + id_defs, + &mut method, + ), + ); + injected_args.set( + InjectedArgument::TriangleNormals, + inject_argument( + InjectedArgument::TriangleNormals.get_type_space(), + id_defs, + &mut method, + ), + ); + } + injected_args.set( + InjectedArgument::VariablesBlock, + inject_argument( + InjectedArgument::VariablesBlock.get_type_space(), + id_defs, + &mut method, + ), + ); + if kind != RaytracingEntryPointKind::BoundingBox + && kind != RaytracingEntryPointKind::Callable + { + injected_args.set( + InjectedArgument::AttributesBlock, + inject_argument( + InjectedArgument::AttributesBlock.get_type_space(), + id_defs, + &mut method, + ), + ); + injected_args.set( + InjectedArgument::TransformBlock, + inject_argument( + InjectedArgument::TransformBlock.get_type_space(), + id_defs, + &mut method, + ), + ); + } + if kind == RaytracingEntryPointKind::Intersection { + injected_args.set( + InjectedArgument::NewDistance, + inject_argument( + InjectedArgument::NewDistance.get_type_space(), + id_defs, + &mut method, + ), + ); + injected_args.set( + InjectedArgument::IntersectionResult, + inject_argument( + InjectedArgument::IntersectionResult.get_type_space(), + id_defs, + &mut method, + ), + ); + injected_args.set( + InjectedArgument::MaterialResult, + inject_argument( + InjectedArgument::MaterialResult.get_type_space(), + id_defs, + &mut method, + ), + ); + } + variables_with_args + .injected_args + .insert(entry_point, injected_args); + new_directives.push(TranslationDirective::Method(method)) + } + } + } + Ok((new_directives, variables_with_args)) +} + +fn inject_argument<'input, P: ast::ArgParams>( + (type_, state_space): (ast::Type, ast::StateSpace), + id_defs: &mut IdNameMapBuilder, + func_decl: &mut TranslationMethod<'input, P>, +) -> Id { + let variable_block = id_defs.register_intermediate(Some((type_.clone(), state_space))); + func_decl.input_arguments.push(ast::VariableDeclaration { + state_space, + type_: type_, + name: variable_block, + align: None, + }); + variable_block +} + +fn fixup_variables_with_empty_semantic<'a, 'input>( + id_defs: &mut IdNameMapBuilder<'input>, + directives: Vec>, + var_tracker: &FinalizedVariablesLayout<'input>, + get_variable_pointer: Id, +) -> Result>, TranslateError> { + let mut result = Vec::with_capacity(directives.len()); + for directive in directives { + let new_directive = match directive { + TranslationDirective::Method(method) => fixup_variable_with_empty_semantic_method( + id_defs, + var_tracker, + get_variable_pointer, + method, + )?, + TranslationDirective::Variable(linking, compiled_name, var) => { + TranslationDirective::Variable(linking, compiled_name, var) + } + }; + result.push(new_directive); + } + Ok(result) +} + +fn fixup_variable_with_empty_semantic_method<'a, 'input>( + id_defs: &mut IdNameMapBuilder<'input>, + var_tracker: &FinalizedVariablesLayout<'input>, + get_variable_pointer: Id, + mut method: TranslationMethod<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + let variables_block = if let Some(injected_vars) = var_tracker.injected_args.get(&method.name) { + injected_vars + .get(InjectedArgument::VariablesBlock) + .ok_or_else(TranslateError::unreachable)? + } else { + return Ok(TranslationDirective::Method(method)); + }; + method.body = method + .body + .map(|body| { + let mut result = Vec::with_capacity(body.len()); + for statement in body { + let new_statement = match statement { + Statement::Call(call) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + call, + )?, + Statement::Instruction(inst) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + inst, + )?, + Statement::PtrAccess(access) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + access, + )?, + Statement::RepackVector(repack) => { + fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + repack, + )? + } + Statement::MadC(madc) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + madc, + )?, + Statement::MadCC(madcc) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + madcc, + )?, + Statement::AddC(details, arg) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + translate::VisitAddC(details, arg), + )?, + Statement::AddCC(type_, arg) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + translate::VisitAddCC(type_, arg), + )?, + Statement::SubC(details, arg) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + translate::VisitSubC(details, arg), + )?, + Statement::SubCC(type_, arg) => fixup_variable_with_empty_semantic_statement( + id_defs, + var_tracker, + get_variable_pointer, + variables_block, + &mut result, + translate::VisitSubCC(type_, arg), + )?, + s @ Statement::Conditional(_) + | s @ Statement::Conversion(_) + | s @ Statement::Label(_) + | s @ Statement::Constant(_) + | s @ Statement::Variable(_) + | s @ Statement::LoadVar(..) + | s @ Statement::StoreVar(..) + | s @ Statement::RetValue(..) + | s @ Statement::AsmVolatile { .. } + | s @ Statement::FunctionPointer(..) => s, + }; + result.push(new_statement); + } + Ok(result) + }) + .transpose()?; + Ok(TranslationDirective::Method(method)) +} + +fn fixup_variable_with_empty_semantic_statement<'input>( + id_def: &mut IdNameMapBuilder, + var_tracker: &FinalizedVariablesLayout<'input>, + get_variable_pointer: Id, + variables_block: Id, + result: &mut Vec, + stmt: impl Visitable, +) -> Result { + stmt.visit(&mut |arg_desc: ArgumentDescriptor, + _type: Option<(&ast::Type, ast::StateSpace)>| { + if let Some(offset) = var_tracker.empty_semantic_variable_offset(arg_desc.op)? { + Ok(insert_call_to_get_variable_pointer( + id_def, + variables_block, + (get_variable_pointer, ast::StateSpace::Global), + result, + offset, + )) + } else { + Ok(arg_desc.op) + } + }) +} + +fn insert_call_to_get_variable_pointer( + id_def: &mut IdNameMapBuilder, + variable_block: Id, + (get_variable_pointer_name, get_variable_pointer_space): (Id, ast::StateSpace), + result: &mut Vec, + offset: u32, +) -> Id { + let return_value = id_def.register_intermediate(Some(( + ast::Type::Pointer(ast::ScalarType::B8, get_variable_pointer_space), + ast::StateSpace::Reg, + ))); + let offset_constant = id_def.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ))); + result.push(ExpandedStatement::Constant(ConstantDefinition { + dst: offset_constant, + typ: ast::ScalarType::B32, + value: ast::ImmediateValue::U64(offset as u64), + })); + result.push(ExpandedStatement::Call(ResolvedCall { + uniform: false, + return_arguments: vec![( + return_value, + ast::Type::Pointer(ast::ScalarType::B8, get_variable_pointer_space), + ast::StateSpace::Reg, + )], + name: get_variable_pointer_name, + input_arguments: vec![ + ( + variable_block, + ast::Type::Pointer(ast::ScalarType::B8, get_variable_pointer_space), + ast::StateSpace::Reg, + ), + ( + offset_constant, + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ), + ], + is_indirect: false, + })); + return_value +} + +fn convert_optix_builtin_variable_and_attribute_access<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + mut directives: Vec>, + var_tracker: &FinalizedVariablesLayout<'input>, + get_variable_pointer: (Id, Id), +) -> Result>, TranslateError> { + for directive in directives.iter_mut() { + if let TranslationDirective::Method(method) = directive { + let func_name = method.name; + method.body = method + .body + .take() + .map(|statements| { + convert_optix_builtin_variable_and_attribute_access_single_function( + id_defs, + statements, + func_name, + var_tracker, + get_variable_pointer, + ) + }) + .transpose()?; + } + } + Ok(directives) +} + +fn convert_optix_builtin_variable_and_attribute_access_single_function<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + statements: Vec, + fn_name: Id, + var_tracker: &FinalizedVariablesLayout<'input>, + get_variable_pointer: (Id, Id), +) -> Result, TranslateError> { + let mut result = Vec::with_capacity(statements.len()); + let mut secondary_global_remap = FxHashMap::default(); + let mut ptr_mov_dsts = FxHashMap::default(); + let mut ptr_mov_variables = FxHashMap::default(); + let mut cvta_src_remap = FxHashMap::default(); + for statement in statements { + match statement { + Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(ast::ScalarType::U64), + .. + }, + ast::Arg2Mov { dst, src }, + )) + | Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(ast::ScalarType::B64), + .. + }, + ast::Arg2Mov { dst, src }, + )) => { + if let Some(remapping) = var_tracker.get_remapped_state_space(fn_name, src)? { + let (new_src, override_space) = + get_new_id_space(remapping, id_defs, &mut result, get_variable_pointer)?; + result.push(Statement::Instruction(ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(ast::ScalarType::U64), + dst_width: 0, + src_width: 0, + relaxed_src2_conv: false, + }, + ast::Arg2Mov { + dst: dst, + src: new_src, + }, + ))); + ptr_mov_dsts.insert(dst, override_space); + } else { + result.push(statement); + } + } + Statement::StoreVar(StoreVarDetails { + arg: ast::Arg2St { src1, src2 }, + .. + }) => { + if let Some(new_space) = ptr_mov_dsts.get(&src2) { + ptr_mov_variables.insert(src1, *new_space); + } + result.push(statement); + } + Statement::LoadVar(LoadVarDetails { + arg: ast::Arg2 { dst, src }, + .. + }) => { + if let Some(new_space) = ptr_mov_variables.get(&src) { + cvta_src_remap.insert(dst, *new_space); + } + result.push(statement); + } + Statement::Instruction(ast::Instruction::Cvta( + ast::CvtaDetails { + to: ast::StateSpace::Generic, + size, + .. + }, + ast::Arg2 { dst, src }, + )) => { + if let Some(new_space) = cvta_src_remap.get(&src) { + result.push(Statement::Instruction(ast::Instruction::Cvta( + ast::CvtaDetails { + from: *new_space, + to: ast::StateSpace::Generic, + size, + }, + ast::Arg2 { dst: dst, src: src }, + ))); + } else { + result.push(statement); + } + } + Statement::Instruction(ast::Instruction::St( + ast::StData { ref typ, .. }, + ast::Arg2St { src1, src2 }, + )) => { + if let Some(remapping) = var_tracker + .get_remapped_state_space(fn_name, src1)? + .or_else(|| secondary_global_remap.get(&src1).copied()) + { + let (src1, override_space) = + get_new_id_space(remapping, id_defs, &mut result, get_variable_pointer)?; + if override_space == ast::StateSpace::Reg { + return Err(TranslateError::unexpected_pattern()); + } + result.push(Statement::Instruction(ast::Instruction::St( + ast::StData { + qualifier: ast::LdStQualifier::Weak, + state_space: override_space, + caching: ast::StCacheOperator::Writeback, + typ: typ.clone(), + }, + ast::Arg2St { src1, src2: src2 }, + ))); + } else { + result.push(statement); + } + } + Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { ref typ, .. }, + ast::Arg2Ld { dst, src }, + )) => { + if let Some(remapping) = var_tracker + .get_remapped_state_space(fn_name, src)? + .or_else(|| secondary_global_remap.get(&src).copied()) + { + let (src, override_space) = + get_new_id_space(remapping, id_defs, &mut result, get_variable_pointer)?; + result.push(Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + typ: typ.clone(), + qualifier: ast::LdStQualifier::Weak, + state_space: override_space, + caching: ast::LdCacheOperator::Cached, + non_coherent: false, + }, + ast::Arg2Ld { dst: dst, src }, + ))); + } else { + result.push(statement); + } + } + Statement::PtrAccess(PtrAccess { + ref underlying_type, + dst, + ptr_src, + offset_src, + .. + }) => { + if let Some(remapping) = var_tracker.get_remapped_state_space(fn_name, ptr_src)? { + let (override_id, override_space) = + get_new_id_space(remapping, id_defs, &mut result, get_variable_pointer)?; + let new_dst = id_defs + .register_intermediate(Some((underlying_type.clone(), override_space))); + result.push(Statement::PtrAccess(PtrAccess { + underlying_type: underlying_type.clone(), + state_space: override_space, + dst: new_dst, + ptr_src: override_id, + offset_src: offset_src, + })); + secondary_global_remap.insert(dst, StateSpaceRemapping::ToVariable(new_dst)); + } else { + result.push(statement); + } + } + Statement::Instruction(ast::Instruction::Tex( + tex, + ast::Arg4Tex { + dst, + image, + layer, + coordinates, + }, + )) => { + if let Some(StateSpaceRemapping::ToBlock(id, ast::StateSpace::Global, offset)) = + var_tracker.get_remapped_state_space(fn_name, image)? + { + let (image, _) = get_new_id_space( + StateSpaceRemapping::ToBlock(id, ast::StateSpace::Global, offset), + id_defs, + &mut result, + get_variable_pointer, + )?; + result.push(Statement::Instruction(ast::Instruction::Tex( + tex, + ast::Arg4Tex { + dst, + image, + layer, + coordinates, + }, + ))); + } else { + return Err(TranslateError::unreachable()); + } + } + Statement::Instruction(inst) => { + let new_statement = inst.visit(&mut |desc: ArgumentDescriptor, + typ: Option<( + &ast::Type, + ast::StateSpace, + )>| { + let (expected_type_, expected_state_space) = match typ { + Some((t, s)) => (t, s), + None => return Ok(desc.op), + }; + if desc.is_dst { + return Ok(desc.op); + } + match var_tracker.get_remapped_state_space(fn_name, desc.op)? { + None => Ok(desc.op), + Some(remapping) => { + let (override_id, override_space) = get_new_id_space( + remapping, + id_defs, + &mut result, + get_variable_pointer, + )?; + let (override_type, _, _, _) = id_defs.get_typed(override_id)?; + if expected_type_ != &override_type + || expected_state_space != override_space + { + return Err(TranslateError::unreachable()); + } + Ok(override_id) + } + } + })?; + result.push(new_statement); + } + _ => result.push(statement), + } + } + Ok(result) +} + +pub(crate) fn replace_tex_builtins_hack<'a, 'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + for directive in translation_module.directives.iter_mut() { + if let TranslationDirective::Method(TranslationMethod { + source_name: Some(source_name), + .. + }) = directive + { + if source_name.starts_with("__zluda_ptx_impl__tex_") { + *source_name = Cow::Owned( + source_name.replace("__zluda_ptx_impl__tex_", "__zluda_rt_ptx_impl__tex_"), + ) + } + } + } + Ok(translation_module) +} + +fn get_new_id_space( + remapping: StateSpaceRemapping, + id_defs: &mut IdNameMapBuilder, + result: &mut Vec, ExpandedArgParams>>, + (get_variable_pointer_global, get_variable_pointer_shared): (Id, Id), +) -> Result<(Id, ast::StateSpace), TranslateError> { + let (override_id, override_space) = match remapping { + StateSpaceRemapping::ToVariable(new_id) => { + let (type_, new_state_space, _, _) = id_defs.get_typed(new_id)?; + if new_state_space == ast::StateSpace::Reg { + ( + copy_value_get_local_pointer(id_defs, result, (new_id, type_)), + ast::StateSpace::Local, + ) + } else { + (new_id, new_state_space) + } + } + StateSpaceRemapping::ToBlock(var_block, var_block_space, offset) => { + let get_variable_pointer = if var_block_space == ast::StateSpace::Global { + get_variable_pointer_global + } else { + get_variable_pointer_shared + }; + ( + insert_call_to_get_variable_pointer( + id_defs, + var_block, + (get_variable_pointer, var_block_space), + result, + offset, + ), + var_block_space, + ) + } + }; + Ok((override_id, override_space)) +} + +fn copy_value_get_local_pointer( + id_defs: &mut IdNameMapBuilder, + result: &mut Vec, + new_variable: (Id, ast::Type), +) -> Id { + let (new_id, variable_type) = new_variable; + let temp_var = + id_defs.register_variable_def(None, variable_type.clone(), ast::StateSpace::Local, None); + let temp_var_name = temp_var.name; + result.push(Statement::Variable(temp_var)); + result.push(Statement::StoreVar(StoreVarDetails { + arg: ast::Arg2St { + src1: temp_var_name, + src2: new_id, + }, + type_: variable_type.clone(), + member_index: None, + })); + temp_var_name +} + +fn collect_variable_and_attribute_declarations<'a, 'input>( + translation_module: &TranslationModule<'input, ExpandedArgParams>, + raytracing_state: &RaytracingTranslationState<'a, 'input>, +) -> Result, TranslateError> { + let mut result = RaytracingVariableTracker::new(); + let mut default_values = FxHashMap::::default(); + for directive in translation_module.directives.iter() { + if let TranslationDirective::Variable(_, _, variable) = directive { + if let Some(demangled) = + demangle(&translation_module.id_defs.globals.reverse_variables[&variable.name]) + { + if demangled.starts_with("rti_internal_semantic::") { + let global_name_str = &demangled[23..]; + let global_name_id = translation_module + .id_defs + .globals + .variables + .get(global_name_str) + .ok_or_else(TranslateError::unexpected_pattern)?; + let (type_, state_space, align, _) = + translation_module.id_defs.get_typed(*global_name_id)?; + if state_space != ast::StateSpace::Global { + return Err(TranslateError::unexpected_pattern()); + } + let default_value = default_values.get(global_name_id).copied(); + let semantic = VariableSemantic::new( + global_name_str, + type_, + align, + &variable.initializer, + default_value, + )?; + result.record_variable(*global_name_id, semantic); + } else { + default_values.insert(variable.name, &variable.initializer); + } + } + // Texref variables are emitted as plain globals, without metadata + else if variable.type_ == ast::Type::Texref { + let text_name = translation_module + .id_defs + .globals + .reverse_variables + .get(&variable.name) + .ok_or_else(TranslateError::unexpected_pattern)?; + result.record_variable( + variable.name, + VariableSemantic::Empty { + name: text_name.clone(), + type_: variable.type_.clone(), + align: None, + default_value: Vec::new(), + }, + ); + } else { + default_values.insert(variable.name, &variable.initializer); + } + } + } + for (buffer_id, buffer_str_name) in raytracing_state.buffers.iter() { + let buffer_type = ast::Type::Struct( + BUFFER_OBJECT_FIELDS + .iter() + .copied() + .map(ast::StructField::Scalar) + .collect(), + ); + result.record_variable( + *buffer_id, + VariableSemantic::Empty { + name: buffer_str_name.clone(), + type_: buffer_type, + align: None, + default_value: Vec::new(), + }, + ); + } + result.to_layout(raytracing_state) +} + +struct RaytracingVariableTracker<'input> { + // All declared globals (empty semantic variables, user attributes, builtin attributes) + // We don't need extra information about builtin attributes, we already know their size + // and they are not part of a memory block, but are converted from injected arguments + global_to_semantic: FxHashMap>, +} + +impl<'input> RaytracingVariableTracker<'input> { + fn new() -> Self { + Self { + global_to_semantic: FxHashMap::default(), + } + } + + fn record_variable(&mut self, id: Id, sema: VariableSemantic<'input>) { + self.global_to_semantic.insert(id, sema); + } + + fn to_layout( + self, + raytracing_state: &RaytracingTranslationState, + ) -> Result, TranslateError> { + fn effective_layout( + align: &Option, + type_: &ast::Type, + ) -> Result { + Ok(align + .map(|align| Layout::from_size_align(type_.layout().size(), align as usize)) + .transpose() + .map_err(|_| TranslateError::unreachable())? + .unwrap_or(type_.layout())) + } + let mut globals = Vec::new(); + let mut user_attributes = Vec::new(); + for (id, semantic) in self.global_to_semantic.iter() { + if semantic.is_builtin() { + continue; + } else if let VariableSemantic::Empty { + name, + type_, + align, + default_value, + } = semantic + { + let layout = effective_layout(align, type_)?; + globals.push((*id, &*name, layout, default_value.clone())); + } else if let VariableSemantic::Attribute { name, type_, align } = semantic { + let layout = effective_layout(align, type_)?; + user_attributes.push((*id, &*name, layout, Vec::new())); + } + } + let variable_block_layout_zero = match raytracing_state.entry_point_kind { + None => return Err(TranslateError::unreachable()), + Some(RaytracingEntryPointKind::Intersection) => { + let first_field = Layout::new::<*const ()>(); + first_field + .extend(Layout::new::()) + .map_err(|_| TranslateError::unreachable())? + .0 + } + Some(RaytracingEntryPointKind::BoundingBox) => Layout::new::<()>(), + Some(RaytracingEntryPointKind::Unknown | RaytracingEntryPointKind::Callable) => { + Layout::new::<*mut ()>() + } + }; + let mut offsets = FxHashMap::default(); + let globals = Self::compute_variables_block_impl( + VariablesBlock { + variables: FxHashMap::default(), + layout: variable_block_layout_zero, + }, + globals, + &mut offsets, + )?; + let user_attributes = Self::compute_variables_block_impl( + raytracing_state.old_attribute_variables.clone(), + user_attributes, + &mut offsets, + )?; + Ok(VariablesLayout { + tracker: self, + offsets, + globals, + user_attributes, + }) + } + + fn compute_variables_block_impl>( + mut var_block: VariablesBlock, + variables: Vec<(Id, T, Layout, Vec)>, + offsets: &mut FxHashMap, + ) -> Result { + let mut new_variables = variables + .into_iter() + .map(|(id, name, layout, default_value)| { + let name = + CString::new(name.as_ref()).map_err(|_| TranslateError::unreachable())?; + Ok(match var_block.variables.get(&name) { + Some(Variable { offset, .. }) => { + offsets.insert(id, *offset); + None + } + None => Some((id, name, layout, default_value)), + }) + }) + .map(Result::transpose) + .filter_map(convert::identity) + .collect::, _>>()?; + new_variables.sort_by_key(|(_, _, layout, _)| cmp::Reverse(layout.align())); + for (id, name, var_layout, default_value) in new_variables.into_iter() { + let (new_layout, offset) = var_block + .layout + .extend(var_layout) + .map_err(|_| TranslateError::unreachable())?; + offsets.insert(id, offset as u32); + var_block.variables.insert( + name, + Variable { + size: var_layout.size() as u32, + offset: offset as u32, + default_value, + }, + ); + var_block.layout = new_layout; + } + Ok(var_block) + } +} + +struct VariablesLayout<'input> { + tracker: RaytracingVariableTracker<'input>, + offsets: FxHashMap, + globals: VariablesBlock, + // This block is the layout of *all* attributes, + // both ones defined and ones defined in this module + user_attributes: VariablesBlock, +} + +struct FinalizedVariablesLayout<'input> { + variables: VariablesLayout<'input>, + injected_args: FxHashMap, +} + +impl<'input> FinalizedVariablesLayout<'input> { + fn remap_fn_arguments( + &mut self, + kind: RaytracingEntryPointKind, + injected_args: &mut InjectedArguments, + mut f: impl FnMut(ast::Type, ast::StateSpace) -> Id, + ) { + if kind == RaytracingEntryPointKind::BoundingBox { + return; + } + self.remap_single_fn_argument(&mut f, injected_args, VariableSemantic::LaunchIndex); + if kind == RaytracingEntryPointKind::Callable { + return; + } + self.remap_single_fn_argument(&mut f, injected_args, VariableSemantic::LaunchDim); + self.remap_single_fn_argument(&mut f, injected_args, VariableSemantic::CurrentRay); + self.remap_single_fn_argument(&mut f, injected_args, VariableSemantic::CurrentTime); + self.remap_single_fn_argument(&mut f, injected_args, VariableSemantic::Payload); + self.remap_single_fn_argument( + &mut f, + injected_args, + VariableSemantic::IntersectionDistance, + ); + } + + fn remap_single_fn_argument( + &mut self, + f: &mut impl FnMut(ast::Type, ast::StateSpace) -> Id, + injected_args: &mut InjectedArguments, + sema: VariableSemantic<'input>, + ) { + let injected_arg = sema.to_injected_arg(); + let (type_, space) = injected_arg.get_type_space(); + let new_id = f(type_, space); + injected_args.set(sema.to_injected_arg(), new_id); + } + + fn get_remapped_state_space( + &self, + func: Id, + id: Id, + ) -> Result, TranslateError> { + let func_injected_args = self + .injected_args + .get(&func) + .ok_or_else(TranslateError::unreachable)?; + Ok(match self.variables.tracker.global_to_semantic.get(&id) { + Some(semantic) => { + if semantic.is_builtin() { + let arg_kind = semantic.to_injected_arg(); + Some(StateSpaceRemapping::ToVariable( + func_injected_args + .get(arg_kind) + .ok_or_else(TranslateError::unreachable)?, + )) + } else if let VariableSemantic::Empty { .. } = semantic { + let block = func_injected_args + .get(InjectedArgument::VariablesBlock) + .ok_or_else(TranslateError::unreachable)?; + let offset = self + .variables + .offsets + .get(&id) + .ok_or_else(TranslateError::unreachable)?; + Some(StateSpaceRemapping::ToBlock( + block, + ast::StateSpace::Global, + *offset, + )) + } else if let VariableSemantic::Attribute { .. } = semantic { + let block = func_injected_args + .get(InjectedArgument::AttributesBlock) + .ok_or_else(TranslateError::unreachable)?; + let offset = self + .variables + .offsets + .get(&id) + .ok_or_else(TranslateError::unreachable)?; + Some(StateSpaceRemapping::ToBlock( + block, + ast::StateSpace::Global, + *offset, + )) + } else { + return Err(TranslateError::unreachable()); + } + } + None => None, + }) + } + + fn empty_semantic_variable_offset(&self, id: Id) -> Result, TranslateError> { + Ok(match self.variables.tracker.global_to_semantic.get(&id) { + Some(VariableSemantic::Empty { .. }) => Some( + self.variables + .offsets + .get(&id) + .copied() + .ok_or_else(TranslateError::unreachable)?, + ), + Some(_) => None, + None => None, + }) + } +} + +#[derive(Clone, Copy, Eq, PartialEq)] +enum StateSpaceRemapping { + ToVariable(Id), + ToBlock(Id, ast::StateSpace, u32), +} + +#[derive(Clone)] +enum VariableSemantic<'input> { + Empty { + name: Cow<'input, str>, + type_: ast::Type, + align: Option, + default_value: Vec, + }, + LaunchDim, + LaunchIndex, + Payload, + CurrentRay, + IntersectionDistance, + CurrentTime, + Attribute { + name: String, + type_: ast::Type, + align: Option, + }, +} + +impl<'a, 'input> VariableSemantic<'input> { + fn new( + global_name: &str, + type_: ast::Type, + align: Option, + declaration_initializer: &Option>, + definition_initializer: Option<&Option>>, + ) -> Result { + match declaration_initializer { + None => { + let default_value = match definition_initializer { + Some(Some(init)) => initializer_to_binary_vector(&type_, init)?, + _ => Vec::new(), + }; + return Ok(VariableSemantic::Empty { + name: Cow::Owned(global_name.to_string()), + type_, + align, + default_value, + }); + } + Some(declaration_initializer) => { + let declaration_initializer = initializer_to_binary_vector( + &ast::Type::Array(ast::ScalarType::U8, vec![0]), + declaration_initializer, + )?; + let text = unsafe { CStr::from_ptr(declaration_initializer.as_ptr() as _) } + .to_str() + .map_err(|_| TranslateError::unreachable())?; + if text.starts_with("attribute ") { + return Ok(VariableSemantic::Attribute { + name: text[10..].to_string(), + type_, + align, + }); + } + Ok(match text { + "rtLaunchDim" => VariableSemantic::LaunchDim, + "rtLaunchIndex" => VariableSemantic::LaunchIndex, + "rtPayload" => VariableSemantic::Payload, + "rtCurrentRay" => VariableSemantic::CurrentRay, + "rtIntersectionDistance" => VariableSemantic::IntersectionDistance, + "rtCurrentTime" => VariableSemantic::CurrentTime, + _ => return Err(TranslateError::todo()), + }) + } + } + } + + fn is_builtin(&self) -> bool { + match self { + VariableSemantic::Empty { .. } | VariableSemantic::Attribute { .. } => false, + VariableSemantic::LaunchDim + | VariableSemantic::LaunchIndex + | VariableSemantic::CurrentRay + | VariableSemantic::CurrentTime + | VariableSemantic::IntersectionDistance + | VariableSemantic::Payload => true, + } + } + + fn to_injected_arg(&self) -> InjectedArgument { + match self { + VariableSemantic::Empty { .. } => InjectedArgument::VariablesBlock, + VariableSemantic::LaunchDim => InjectedArgument::LaunchDim, + VariableSemantic::LaunchIndex => InjectedArgument::LaunchIndex, + VariableSemantic::Payload => InjectedArgument::Payload, + VariableSemantic::CurrentRay => InjectedArgument::CurrentRay, + VariableSemantic::CurrentTime => InjectedArgument::CurrentTime, + VariableSemantic::IntersectionDistance => InjectedArgument::IntersectionDistance, + VariableSemantic::Attribute { .. } => InjectedArgument::AttributesBlock, + } + } +} + +fn initializer_to_binary_vector( + type_: &ast::Type, + initializer: &ast::Initializer, +) -> Result, TranslateError> { + fn initializer_to_binary_vector_impl( + type_: ConstType, + initializer: &ast::Initializer, + result: &mut Vec, + ) -> Result<(), TranslateError> { + match (type_, initializer) { + (ConstType::Type(ast::Type::Array(scalar, dims)), ast::Initializer::Array(vec)) => { + for initializer in vec { + initializer_to_binary_vector_impl( + ConstType::ArraySubtype(*scalar, &dims[1..]), + initializer, + result, + )?; + } + } + (ConstType::ArraySubtype(scalar, dims), ast::Initializer::Array(vec)) => { + for initializer in vec { + initializer_to_binary_vector_impl( + ConstType::ArraySubtype(scalar, &dims[1..]), + initializer, + result, + )?; + } + } + (ConstType::ArraySubtype(ref scalar, []), ast::Initializer::Constant(constant)) + | ( + ConstType::Type(ast::Type::Scalar(ref scalar)), + ast::Initializer::Constant(constant), + ) => match scalar { + ast::ScalarType::B8 | ast::ScalarType::U8 => { + let bytes = constant + .as_u8() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::S8 => { + let bytes = constant + .as_i8() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::B16 | ast::ScalarType::U16 => { + let bytes = constant + .as_u16() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::S16 => { + let bytes = constant + .as_i16() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::B32 | ast::ScalarType::U32 => { + let bytes = constant + .as_u32() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::S32 => { + let bytes = constant + .as_i32() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::B64 | ast::ScalarType::U64 => { + let bytes = constant + .as_u64() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::S64 => { + let bytes = constant + .as_i64() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::F16 => return Err(TranslateError::unexpected_pattern()), + ast::ScalarType::F32 => { + let bytes = constant + .as_f32() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::F64 => { + let bytes = constant + .as_f64() + .ok_or_else(TranslateError::unexpected_pattern)? + .to_le_bytes(); + result.extend_from_slice(&bytes); + } + ast::ScalarType::F16x2 | ast::ScalarType::Pred => { + return Err(TranslateError::unexpected_pattern()) + } + }, + _ => return Err(TranslateError::unexpected_pattern()), + } + Ok(()) + } + let mut result = Vec::new(); + initializer_to_binary_vector_impl(ConstType::Type(type_), initializer, &mut result)?; + Ok(result) +} + +fn is_raytracing_entry_point<'a, 'input>( + source_name: &'a Option>, + entry_point: &str, + suffixed_entry_point: &str, +) -> Result>, TranslateError> { + if let Some(ref method_name) = source_name { + if method_name != entry_point { + if let Some(demangled) = demangle(&*method_name) { + if !demangled.starts_with(suffixed_entry_point) { + return Ok(None); + } + } else { + return Ok(None); + } + } + Ok(Some(method_name)) + } else { + Ok(None) + } +} + +fn demangle(input: &str) -> Option { + let symbol = BorrowedSymbol::new(input.as_bytes()).ok()?; + symbol.demangle(&DemangleOptions::new()).ok() +} + +pub(crate) fn bitcode() -> &'static [u8] { + ZLUDA_RT_PTX_IMPL_AMD +} + +pub struct Module<'input> { + pub compilation_module: crate::translate::Module<'input>, + pub kernel_source: &'static str, + pub variables: VariablesBlock, + pub attribute_variables: VariablesBlock, + pub headers: Vec>, + pub header_names: Vec<&'static CStr>, + pub is_callable: bool, + pub linker_module: Vec, +} + +impl<'input> Module<'input> { + pub const KERNEL_BOUNDING_BOX_NAME: &'static CStr = unsafe { + CStr::from_bytes_with_nul_unchecked(b"__zluda_rt_ptx_impl__generate_bounding_box\0") + }; + pub const FUNCTION_POINTER_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(b"__zluda_rt_ptx_impl__zluda_rt_func\0") }; + pub const ATTRIBUTE_FUNCTION_POINTER_NAME: &'static CStr = unsafe { + CStr::from_bytes_with_nul_unchecked(b"__zluda_rt_ptx_impl__zluda_rt_attribute_func\0") + }; + pub const KERNEL_NAME: &'static CStr = + unsafe { CStr::from_bytes_with_nul_unchecked(b"__zluda_rt_ptx_impl__zluda_rt_kernel\0") }; + + pub(crate) fn new( + internal_kernel_name: String, + compilation_module: crate::translate::Module<'input>, + variables: VariablesBlock, + kind: RaytracingEntryPointKind, + attribute_variables: VariablesBlock, + linker_module: Vec, + ) -> Self { + let template = match kind { + RaytracingEntryPointKind::BoundingBox => KERNEL_SOURCE_BOUNDING_BOX, + RaytracingEntryPointKind::Intersection => KERNEL_SOURCE_INTERSECT, + RaytracingEntryPointKind::Unknown => KERNEL_SOURCE, + RaytracingEntryPointKind::Callable => KERNEL_SOURCE_CALLABLE, + }; + let unique_header = format!( + "#define FUNCTION_NAME {} + #define EXPORTED_FUNCTION {} + #define EXPORTED_ATTRIBUTE_FUNCTION {} + #define EXPORTED_KERNEL {}\0", + internal_kernel_name, + Self::FUNCTION_POINTER_NAME.to_string_lossy(), + Self::ATTRIBUTE_FUNCTION_POINTER_NAME.to_string_lossy(), + Self::KERNEL_NAME.to_string_lossy() + ); + let headers = vec![Cow::Owned(unique_header), Cow::Borrowed(KERNEL_HEADER)]; + let header_names = unsafe { + vec![ + CStr::from_bytes_with_nul_unchecked(b"raytracing_defines.hpp\0"), + CStr::from_bytes_with_nul_unchecked(b"raytracing.hpp\0"), + ] + }; + Module { + compilation_module, + kernel_source: template, + variables, + attribute_variables, + headers, + header_names, + is_callable: kind == RaytracingEntryPointKind::Callable, + linker_module, + } + } +} + +pub(crate) struct InjectedArguments(Vec>); + +impl InjectedArguments { + fn new() -> Self { + InjectedArguments(vec![None; InjectedArgument::_Count as usize]) + } + + fn set(&mut self, arg: InjectedArgument, id: Id) { + self.0[arg as usize] = Some(id); + } + + fn get(&self, arg: InjectedArgument) -> Option { + self.0[arg as usize] + } + + fn find_by_id(&self, needle: Id) -> Option { + self.0 + .iter() + .copied() + .position(|maybe_id| maybe_id == Some(needle)) + .map(|index| unsafe { mem::transmute(index as u8) }) + } +} + +#[derive(Copy, Clone, Eq, PartialEq)] +#[repr(u8)] +pub(crate) enum InjectedArgument { + GlobalState, + PrimitiveIndex, + LaunchIndex, + LaunchDim, + CurrentRay, + CurrentTime, + Payload, + TriangleBarycentrics, + TriangleNormals, + VariablesBlock, + AttributesBlock, + TransformBlock, + NewDistance, + IntersectionResult, + IntersectionDistance, + MaterialResult, + // TODO: replace with mem::variant_count when it stabilizes + #[doc(hidden)] + _Count, +} + +impl InjectedArgument { + fn get_type_space(self) -> (ast::Type, ast::StateSpace) { + match self { + InjectedArgument::GlobalState => ( + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Shared, + ), + InjectedArgument::PrimitiveIndex => ( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + ), + InjectedArgument::LaunchIndex | InjectedArgument::LaunchDim => ( + ast::Type::Vector(ast::ScalarType::B32, 2), + ast::StateSpace::Reg, + ), + InjectedArgument::CurrentRay => ( + ast::Type::Array(ast::ScalarType::B8, vec![36]), + ast::StateSpace::Local, + ), + InjectedArgument::CurrentTime => ( + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Reg, + ), + InjectedArgument::Payload => ( + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Local, + ), + InjectedArgument::TriangleBarycentrics => ( + ast::Type::Vector(ast::ScalarType::F32, 2), + ast::StateSpace::Reg, + ), + InjectedArgument::TriangleNormals => ( + ast::Type::Vector(ast::ScalarType::F32, 3), + ast::StateSpace::Reg, + ), + InjectedArgument::VariablesBlock => ( + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Global, + ), + InjectedArgument::AttributesBlock => ( + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Global, + ), + InjectedArgument::TransformBlock => ( + ast::Type::Scalar(ast::ScalarType::B8), + ast::StateSpace::Global, + ), + InjectedArgument::NewDistance => ( + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Local, + ), + InjectedArgument::IntersectionResult => ( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Local, + ), + InjectedArgument::IntersectionDistance => ( + ast::Type::Scalar(ast::ScalarType::F32), + ast::StateSpace::Reg, + ), + InjectedArgument::MaterialResult => ( + ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Local, + ), + InjectedArgument::_Count => unreachable!(), + } + } +} diff --git a/ptx/src/test/mod.rs b/ptx/src/test/mod.rs index 0785f3e..31bad6e 100644 --- a/ptx/src/test/mod.rs +++ b/ptx/src/test/mod.rs @@ -1,6 +1,9 @@ +use hip_common::CompilationMode; + use super::ptx; use super::TranslateError; +mod raytracing; mod spirv_run; fn parse_and_assert(s: &str) { @@ -9,10 +12,10 @@ fn parse_and_assert(s: &str) { assert!(errors.len() == 0); } -fn compile_and_assert(s: &str) -> Result<(), TranslateError> { +fn compile_and_assert(compilation_mode: CompilationMode, s: &str) -> Result<(), TranslateError> { let mut errors = Vec::new(); let ast = ptx::ModuleParser::new().parse(&mut errors, s).unwrap(); - crate::to_spirv_module(ast)?; + crate::to_llvm_module(compilation_mode, vec![ast])?; Ok(()) } @@ -31,19 +34,19 @@ fn operands_ptx() { #[allow(non_snake_case)] fn vectorAdd_kernel64_ptx() -> Result<(), TranslateError> { let vector_add = include_str!("vectorAdd_kernel64.ptx"); - compile_and_assert(vector_add) + compile_and_assert(CompilationMode::Wave32, 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) + compile_and_assert(CompilationMode::Wave32, 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) + compile_and_assert(CompilationMode::Wave32, vector_add) } diff --git a/ptx/src/test/ptx_raytracing/closest_hit.cu b/ptx/src/test/ptx_raytracing/closest_hit.cu new file mode 100644 index 0000000..bfc23e1 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/closest_hit.cu @@ -0,0 +1,12 @@ +#include + +using namespace optix; + +rtBuffer output; +rtDeclareVariable(rtCallableProgramId, eval, , ); + +RT_PROGRAM void closest_hit() +{ + float3 result = eval(); + output[0] = make_float4(result.x, result.y, result.y, 0.0); +} \ No newline at end of file diff --git a/ptx/src/test/ptx_raytracing/closest_hit.ptx b/ptx/src/test/ptx_raytracing/closest_hit.ptx new file mode 100644 index 0000000..480471d --- /dev/null +++ b/ptx/src/test/ptx_raytracing/closest_hit.ptx @@ -0,0 +1,83 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z11closest_hitv +.visible .global .align 1 .b8 output[1]; +.visible .global .align 4 .b8 eval[4]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo4evalE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename4evalE[30] = {114, 116, 67, 97, 108, 108, 97, 98, 108, 101, 80, 114, 111, 103, 114, 97, 109, 73, 100, 60, 102, 108, 111, 97, 116, 51, 40, 41, 62, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum4evalE = 4920; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic4evalE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation4evalE[1]; + +.visible .entry _Z11closest_hitv() +{ + .reg .f32 %f<5>; + .reg .b32 %r<4>; + .reg .b64 %rd<11>; + + + ld.global.u32 %r1, [eval]; + mov.u64 %rd8, 0; + // begin inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd8); + // end inline asm + mov.u32 %r2, 1; + { // callseq 0, 0 + .reg .b32 temp_param_reg; + .param .align 4 .b8 retval0[12]; + prototype_0 : .callprototype (.param .align 4 .b8 _[12]) _ (); + call (retval0), + %rd1, + ( + ) + , prototype_0; + ld.param.f32 %f1, [retval0+0]; + ld.param.f32 %f2, [retval0+4]; + ld.param.f32 %f3, [retval0+8]; + } // callseq 0 + mov.u64 %rd10, output; + cvta.global.u64 %rd4, %rd10; + mov.u32 %r3, 16; + // begin inline asm + call (%rd3), _rt_buffer_get_64, (%rd4, %r2, %r3, %rd8, %rd8, %rd8, %rd8); + // end inline asm + mov.f32 %f4, 0f00000000; + st.v4.f32 [%rd3], {%f1, %f2, %f2, %f4}; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms.ptx b/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms.ptx new file mode 100644 index 0000000..f62f977 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms.ptx @@ -0,0 +1,226 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_52 +.address_size 64 + + // .globl _Z17shade_from_normal6float3 +.visible .global .align 4 .b8 prd_radiance[20]; +.visible .global .align 4 .b8 shade_normal[4]; +.visible .global .align 4 .b8 geometric_normal[12]; +.visible .global .align 1 .b8 shade_ray[1]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12prd_radianceE[8] = {82, 97, 121, 0, 20, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12shade_normalE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo16geometric_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12prd_radianceE[20] = {80, 101, 114, 82, 97, 121, 68, 97, 116, 97, 95, 114, 97, 100, 105, 97, 110, 99, 101, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12shade_normalE[55] = {111, 112, 116, 105, 120, 58, 58, 98, 111, 117, 110, 100, 67, 97, 108, 108, 97, 98, 108, 101, 80, 114, 111, 103, 114, 97, 109, 73, 100, 60, 102, 108, 111, 97, 116, 51, 32, 40, 32, 99, 111, 110, 115, 116, 32, 102, 108, 111, 97, 116, 51, 32, 41, 62, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename16geometric_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12prd_radianceE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12shade_normalE = 4921; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum16geometric_normalE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12prd_radianceE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12shade_normalE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic16geometric_normalE[27] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 103, 101, 111, 109, 101, 116, 114, 105, 99, 95, 110, 111, 114, 109, 97, 108, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12prd_radianceE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12shade_normalE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation16geometric_normalE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; + +.visible .func (.param .align 4 .b8 func_retval0[12]) _Z17shade_from_normal6float3( + .param .align 4 .b8 _Z17shade_from_normal6float3_param_0[12] +) +{ + .reg .f32 %f<14>; + + + ld.param.f32 %f1, [_Z17shade_from_normal6float3_param_0+8]; + ld.param.f32 %f2, [_Z17shade_from_normal6float3_param_0]; + ld.param.f32 %f3, [_Z17shade_from_normal6float3_param_0+4]; + mul.ftz.f32 %f4, %f3, %f3; + fma.rn.ftz.f32 %f5, %f2, %f2, %f4; + fma.rn.ftz.f32 %f6, %f1, %f1, %f5; + rsqrt.approx.ftz.f32 %f7, %f6; + mul.ftz.f32 %f8, %f2, %f7; + mul.ftz.f32 %f9, %f3, %f7; + mul.ftz.f32 %f10, %f1, %f7; + fma.rn.ftz.f32 %f11, %f10, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f12, %f9, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f13, %f8, 0f3F000000, 0f3F000000; + st.param.f32 [func_retval0+0], %f13; + st.param.f32 [func_retval0+4], %f12; + st.param.f32 [func_retval0+8], %f11; + ret; + +} + // .globl _Z14shade_from_rayN5optix3RayE +.visible .func (.param .align 4 .b8 func_retval0[12]) _Z14shade_from_rayN5optix3RayE( + .param .b64 _Z14shade_from_rayN5optix3RayE_param_0 +) +{ + .reg .f32 %f<14>; + .reg .b64 %rd<2>; + + + ld.param.u64 %rd1, [_Z14shade_from_rayN5optix3RayE_param_0]; + ld.f32 %f1, [%rd1+12]; + ld.f32 %f2, [%rd1+16]; + mul.ftz.f32 %f3, %f2, %f2; + fma.rn.ftz.f32 %f4, %f1, %f1, %f3; + ld.f32 %f5, [%rd1+20]; + fma.rn.ftz.f32 %f6, %f5, %f5, %f4; + rsqrt.approx.ftz.f32 %f7, %f6; + mul.ftz.f32 %f8, %f1, %f7; + mul.ftz.f32 %f9, %f7, %f2; + mul.ftz.f32 %f10, %f7, %f5; + fma.rn.ftz.f32 %f11, %f10, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f12, %f9, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f13, %f8, 0f3F000000, 0f3F000000; + st.param.f32 [func_retval0+0], %f13; + st.param.f32 [func_retval0+4], %f12; + st.param.f32 [func_retval0+8], %f11; + ret; + +} + // .globl _Z20closest_hit_radiancev +.visible .entry _Z20closest_hit_radiancev() +{ + .reg .f32 %f<7>; + .reg .b32 %r<2>; + .reg .b64 %rd<4>; + + + mov.u64 %rd2, 0; + ld.global.f32 %f1, [geometric_normal+8]; + ld.global.f32 %f2, [geometric_normal+4]; + ld.global.f32 %f3, [geometric_normal]; + ld.global.u32 %r1, [shade_normal]; + // begin inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd2); + // end inline asm + { // callseq 0, 0 + .reg .b32 temp_param_reg; + .param .align 4 .b8 param0[12]; + st.param.f32 [param0+0], %f3; + st.param.f32 [param0+4], %f2; + st.param.f32 [param0+8], %f1; + .param .align 4 .b8 retval0[12]; + prototype_0 : .callprototype (.param .align 4 .b8 _[12]) _ (.param .align 4 .b8 _[12]); + call (retval0), + %rd1, + ( + param0 + ) + , prototype_0; + ld.param.f32 %f4, [retval0+0]; + ld.param.f32 %f5, [retval0+4]; + ld.param.f32 %f6, [retval0+8]; + } // callseq 0 + st.global.f32 [prd_radiance], %f4; + st.global.f32 [prd_radiance+4], %f5; + st.global.f32 [prd_radiance+8], %f6; + ret; + +} + // .globl _Z4missv +.visible .entry _Z4missv() +{ + .local .align 4 .b8 __local_depot3[36]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .f32 %f<12>; + .reg .b32 %r<5>; + .reg .b64 %rd<13>; + + + mov.u64 %SPL, __local_depot3; + cvta.local.u64 %SP, %SPL; + add.u64 %rd9, %SP, 0; + add.u64 %rd10, %SPL, 0; + mov.u64 %rd11, shade_ray; + cvta.global.u64 %rd2, %rd11; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd8, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd8, %rd8, %rd8, %rd8); + // end inline asm + ld.global.f32 %f1, [ray]; + ld.global.f32 %f2, [ray+4]; + ld.global.f32 %f3, [ray+8]; + ld.global.f32 %f4, [ray+12]; + ld.global.f32 %f5, [ray+16]; + ld.global.f32 %f6, [ray+20]; + ld.global.u32 %r4, [ray+24]; + ld.global.f32 %f7, [ray+28]; + ld.global.f32 %f8, [ray+32]; + ld.u32 %r3, [%rd1]; + // begin inline asm + call (%rd7), _rt_callable_program_from_id_v2_64, (%r3, %rd8); + // end inline asm + st.local.f32 [%rd10], %f1; + st.local.f32 [%rd10+4], %f2; + st.local.f32 [%rd10+8], %f3; + st.local.f32 [%rd10+12], %f4; + st.local.f32 [%rd10+16], %f5; + st.local.f32 [%rd10+20], %f6; + st.local.u32 [%rd10+24], %r4; + st.local.f32 [%rd10+28], %f7; + st.local.f32 [%rd10+32], %f8; + { // callseq 1, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd9; + .param .align 4 .b8 retval0[12]; + prototype_1 : .callprototype (.param .align 4 .b8 _[12]) _ (.param .b64 _); + call (retval0), + %rd7, + ( + param0 + ) + , prototype_1; + ld.param.f32 %f9, [retval0+0]; + ld.param.f32 %f10, [retval0+4]; + ld.param.f32 %f11, [retval0+8]; + } // callseq 1 + st.global.f32 [prd_radiance], %f9; + st.global.f32 [prd_radiance+4], %f10; + st.global.f32 [prd_radiance+8], %f11; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms_miss.ll b/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms_miss.ll new file mode 100644 index 0000000..39b0a9f --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixCallablePrograms_generated_optixCallablePrograms_miss.ll @@ -0,0 +1,342 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected i32 @_Z4missv(ptr addrspace(3) %"437", i32 %"438", <2 x i32> %"439", <2 x i32> %"440", ptr addrspace(5) %"441", float %"442", ptr addrspace(5) %"443", float %"444", <2 x float> %"445", <3 x float> %"446", ptr addrspace(1) %"447", ptr addrspace(1) %"448", ptr addrspace(1) %"449") #1 { +"590": + %"544" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"544", align 4 + %"311" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"311", align 1 + %"312" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"312", align 1 + %"272" = alloca [36 x i8], align 4, addrspace(5) + %"273" = alloca i64, align 8, addrspace(5) + %"274" = alloca i64, align 8, addrspace(5) + %"275" = alloca float, align 4, addrspace(5) + %"276" = alloca float, align 4, addrspace(5) + %"277" = alloca float, align 4, addrspace(5) + %"278" = alloca float, align 4, addrspace(5) + %"279" = alloca float, align 4, addrspace(5) + %"280" = alloca float, align 4, addrspace(5) + %"281" = alloca float, align 4, addrspace(5) + %"282" = alloca float, align 4, addrspace(5) + %"283" = alloca float, align 4, addrspace(5) + %"284" = alloca float, align 4, addrspace(5) + %"285" = alloca float, align 4, addrspace(5) + %"286" = alloca float, align 4, addrspace(5) + %"287" = alloca i32, align 4, addrspace(5) + %"288" = alloca i32, align 4, addrspace(5) + %"289" = alloca i32, align 4, addrspace(5) + %"290" = alloca i32, align 4, addrspace(5) + %"291" = alloca i32, align 4, addrspace(5) + %"292" = alloca i64, align 8, addrspace(5) + %"293" = alloca i64, align 8, addrspace(5) + %"294" = alloca i64, align 8, addrspace(5) + %"295" = alloca i64, align 8, addrspace(5) + %"296" = alloca i64, align 8, addrspace(5) + %"297" = alloca i64, align 8, addrspace(5) + %"298" = alloca i64, align 8, addrspace(5) + %"299" = alloca i64, align 8, addrspace(5) + %"300" = alloca i64, align 8, addrspace(5) + %"301" = alloca i64, align 8, addrspace(5) + %"302" = alloca i64, align 8, addrspace(5) + %"303" = alloca i64, align 8, addrspace(5) + %"304" = alloca i64, align 8, addrspace(5) + %"305" = alloca i32, align 4, addrspace(5) + %"423" = alloca i64, align 8, addrspace(5) + %"425" = alloca [3 x i32], align 4, addrspace(5) + %"546" = ptrtoint ptr addrspace(5) %"272" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"546", ptr addrspace(5) %0, align 8 + %"545" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"545", ptr addrspace(5) %"274", align 8 + %"315" = load i64, ptr addrspace(5) %"274", align 8 + %1 = inttoptr i64 %"315" to ptr addrspace(5) + %2 = addrspacecast ptr addrspace(5) %1 to ptr + %"314" = ptrtoint ptr %2 to i64 + store i64 %"314", ptr addrspace(5) %"273", align 8 + %"317" = load i64, ptr addrspace(5) %"273", align 8 + %"547" = add i64 %"317", 0 + store i64 %"547", ptr addrspace(5) %"301", align 8 + %"319" = load i64, ptr addrspace(5) %"274", align 8 + %"549" = add i64 %"319", 0 + store i64 %"549", ptr addrspace(5) %"302", align 8 + %"450" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"447", i32 8) + %"552" = ptrtoint ptr addrspace(1) %"450" to i64 + %3 = alloca i64, align 8, addrspace(5) + store i64 %"552", ptr addrspace(5) %3, align 8 + %"551" = load i64, ptr addrspace(5) %3, align 8 + store i64 %"551", ptr addrspace(5) %"303", align 8 + %"322" = load i64, ptr addrspace(5) %"303", align 8 + %4 = inttoptr i64 %"322" to ptr addrspace(1) + %5 = addrspacecast ptr addrspace(1) %4 to ptr + %"321" = ptrtoint ptr %5 to i64 + store i64 %"321", ptr addrspace(5) %"294", align 8 + %6 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %6, align 4 + %"553" = load i32, ptr addrspace(5) %6, align 4 + store i32 %"553", ptr addrspace(5) %"288", align 4 + %7 = alloca i32, align 4, addrspace(5) + store i32 4, ptr addrspace(5) %7, align 4 + %"554" = load i32, ptr addrspace(5) %7, align 4 + store i32 %"554", ptr addrspace(5) %"289", align 4 + %8 = alloca i64, align 8, addrspace(5) + store i64 0, ptr addrspace(5) %8, align 8 + %"555" = load i64, ptr addrspace(5) %8, align 8 + store i64 %"555", ptr addrspace(5) %"300", align 8 + %"327" = load i64, ptr addrspace(5) %"294", align 8 + %"328" = load i32, ptr addrspace(5) %"288", align 4 + %"329" = load i32, ptr addrspace(5) %"289", align 4 + %"330" = load i64, ptr addrspace(5) %"300", align 8 + %"331" = load i64, ptr addrspace(5) %"300", align 8 + %"332" = load i64, ptr addrspace(5) %"300", align 8 + %"333" = load i64, ptr addrspace(5) %"300", align 8 + %"326" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"327", i32 %"328", i32 %"329", i64 %"330", i64 %"331", i64 %"332", i64 %"333") + store i64 %"326", ptr addrspace(5) %"293", align 8 + %"334" = load float, ptr addrspace(5) %"441", align 4 + store float %"334", ptr addrspace(5) %"276", align 4 + %"593" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 4 + %"335" = load float, ptr addrspace(5) %"593", align 4 + store float %"335", ptr addrspace(5) %"277", align 4 + %"595" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 8 + %"336" = load float, ptr addrspace(5) %"595", align 4 + store float %"336", ptr addrspace(5) %"278", align 4 + %"597" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 12 + %"337" = load float, ptr addrspace(5) %"597", align 4 + store float %"337", ptr addrspace(5) %"279", align 4 + %"599" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 16 + %"338" = load float, ptr addrspace(5) %"599", align 4 + store float %"338", ptr addrspace(5) %"280", align 4 + %"601" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 20 + %"339" = load float, ptr addrspace(5) %"601", align 4 + store float %"339", ptr addrspace(5) %"281", align 4 + %"603" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 24 + %"563" = load i32, ptr addrspace(5) %"603", align 4 + store i32 %"563", ptr addrspace(5) %"291", align 4 + %"605" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 28 + %"341" = load float, ptr addrspace(5) %"605", align 4 + store float %"341", ptr addrspace(5) %"282", align 4 + %"607" = getelementptr inbounds i8, ptr addrspace(5) %"441", i64 32 + %"342" = load float, ptr addrspace(5) %"607", align 4 + store float %"342", ptr addrspace(5) %"283", align 4 + %"344" = load i64, ptr addrspace(5) %"293", align 8 + %"567" = inttoptr i64 %"344" to ptr + %"566" = load i32, ptr %"567", align 4 + store i32 %"566", ptr addrspace(5) %"290", align 4 + %"346" = load i32, ptr addrspace(5) %"290", align 4 + %"347" = load i64, ptr addrspace(5) %"300", align 8 + %"345" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"346", i64 %"347", ptr addrspace(3) %"437") + store i64 %"345", ptr addrspace(5) %"299", align 8 + %"348" = load i64, ptr addrspace(5) %"302", align 8 + %"349" = load float, ptr addrspace(5) %"276", align 4 + %"568" = inttoptr i64 %"348" to ptr addrspace(5) + store float %"349", ptr addrspace(5) %"568", align 4 + %"350" = load i64, ptr addrspace(5) %"302", align 8 + %"351" = load float, ptr addrspace(5) %"277", align 4 + %"569" = inttoptr i64 %"350" to ptr addrspace(5) + %"609" = getelementptr inbounds i8, ptr addrspace(5) %"569", i64 4 + store float %"351", ptr addrspace(5) %"609", align 4 + %"352" = load i64, ptr addrspace(5) %"302", align 8 + %"353" = load float, ptr addrspace(5) %"278", align 4 + %"570" = inttoptr i64 %"352" to ptr addrspace(5) + %"611" = getelementptr inbounds i8, ptr addrspace(5) %"570", i64 8 + store float %"353", ptr addrspace(5) %"611", align 4 + %"354" = load i64, ptr addrspace(5) %"302", align 8 + %"355" = load float, ptr addrspace(5) %"279", align 4 + %"571" = inttoptr i64 %"354" to ptr addrspace(5) + %"613" = getelementptr inbounds i8, ptr addrspace(5) %"571", i64 12 + store float %"355", ptr addrspace(5) %"613", align 4 + %"356" = load i64, ptr addrspace(5) %"302", align 8 + %"357" = load float, ptr addrspace(5) %"280", align 4 + %"572" = inttoptr i64 %"356" to ptr addrspace(5) + %"615" = getelementptr inbounds i8, ptr addrspace(5) %"572", i64 16 + store float %"357", ptr addrspace(5) %"615", align 4 + %"358" = load i64, ptr addrspace(5) %"302", align 8 + %"359" = load float, ptr addrspace(5) %"281", align 4 + %"573" = inttoptr i64 %"358" to ptr addrspace(5) + %"617" = getelementptr inbounds i8, ptr addrspace(5) %"573", i64 20 + store float %"359", ptr addrspace(5) %"617", align 4 + %"360" = load i64, ptr addrspace(5) %"302", align 8 + %"361" = load i32, ptr addrspace(5) %"291", align 4 + %"574" = inttoptr i64 %"360" to ptr addrspace(5) + %"619" = getelementptr inbounds i8, ptr addrspace(5) %"574", i64 24 + store i32 %"361", ptr addrspace(5) %"619", align 4 + %"362" = load i64, ptr addrspace(5) %"302", align 8 + %"363" = load float, ptr addrspace(5) %"282", align 4 + %"576" = inttoptr i64 %"362" to ptr addrspace(5) + %"621" = getelementptr inbounds i8, ptr addrspace(5) %"576", i64 28 + store float %"363", ptr addrspace(5) %"621", align 4 + %"364" = load i64, ptr addrspace(5) %"302", align 8 + %"365" = load float, ptr addrspace(5) %"283", align 4 + %"577" = inttoptr i64 %"364" to ptr addrspace(5) + %"623" = getelementptr inbounds i8, ptr addrspace(5) %"577", i64 32 + store float %"365", ptr addrspace(5) %"623", align 4 + %"366" = load i64, ptr addrspace(5) %"301", align 8 + %"625" = getelementptr inbounds i8, ptr addrspace(5) %"423", i64 0 + store i64 %"366", ptr addrspace(5) %"625", align 8 + %"309" = load i64, ptr addrspace(5) %"423", align 8 + %"367" = load i64, ptr addrspace(5) %"299", align 8 + %"578" = inttoptr i64 %"367" to ptr addrspace(1) + %"467" = load i64, ptr addrspace(1) %"578", align 8 + %"579" = inttoptr i64 %"367" to ptr addrspace(1) + %9 = inttoptr i64 %"467" to ptr + %10 = call { [3 x i32], i32 } %9(i64 %"309", ptr addrspace(3) %"437", <2 x i32> %"439", ptr addrspace(1) %"579") + %"310" = extractvalue { [3 x i32], i32 } %10, 0 + %"466" = extractvalue { [3 x i32], i32 } %10, 1 + %"469" = icmp uge i32 %"466", 1024 + br i1 %"469", label %"470", label %"471" + +"470": ; preds = %"590" + ret i32 %"466" + +"471": ; preds = %"590" + store [3 x i32] %"310", ptr addrspace(5) %"425", align 4 + %"627" = getelementptr inbounds i8, ptr addrspace(5) %"425", i64 0 + %"368" = load float, ptr addrspace(5) %"627", align 4 + store float %"368", ptr addrspace(5) %"284", align 4 + %"629" = getelementptr inbounds i8, ptr addrspace(5) %"425", i64 4 + %"369" = load float, ptr addrspace(5) %"629", align 4 + store float %"369", ptr addrspace(5) %"285", align 4 + %"631" = getelementptr inbounds i8, ptr addrspace(5) %"425", i64 8 + %"370" = load float, ptr addrspace(5) %"631", align 4 + store float %"370", ptr addrspace(5) %"286", align 4 + %"371" = load float, ptr addrspace(5) %"284", align 4 + store float %"371", ptr addrspace(5) %"443", align 4 + %"372" = load float, ptr addrspace(5) %"285", align 4 + %"633" = getelementptr inbounds i8, ptr addrspace(5) %"443", i64 4 + store float %"372", ptr addrspace(5) %"633", align 4 + %"373" = load float, ptr addrspace(5) %"286", align 4 + %"635" = getelementptr inbounds i8, ptr addrspace(5) %"443", i64 8 + store float %"373", ptr addrspace(5) %"635", align 4 + ret i32 0 +} + +define protected i32 @__zluda_rt_ptx_impl__rollback_wrapper(ptr addrspace(3) %"474", i32 %"475", <2 x i32> %"476", <2 x i32> %"477", ptr addrspace(5) %"478", float %"479", ptr addrspace(5) %"480", float %"481", <2 x float> %"482", <3 x float> %"483", ptr addrspace(1) %"484", ptr addrspace(1) %"485", ptr addrspace(1) %"486", i64 %"487") #1 { +"591": + %"488" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"485", i32 0) + %"490" = load [12 x i8], ptr addrspace(1) %"488", align 1 + %"491" = call i32 @_Z4missv(ptr addrspace(3) %"474", i32 %"475", <2 x i32> %"476", <2 x i32> %"477", ptr addrspace(5) %"478", float %"479", ptr addrspace(5) %"480", float %"481", <2 x float> %"482", <3 x float> %"483", ptr addrspace(1) %"484", ptr addrspace(1) %"485", ptr addrspace(1) %"486") + %"493" = icmp uge i32 %"491", 1024 + br i1 %"493", label %"494", label %"495" + +"494": ; preds = %"591" + ret i32 %"491" + +"495": ; preds = %"591" + %"497" = icmp eq i64 %"487", 0 + br i1 %"497", label %"498", label %"499" + +"498": ; preds = %"495" + ret i32 0 + +"499": ; preds = %"495" + %"587" = inttoptr i64 %"487" to ptr addrspace(1) + %"501" = load i64, ptr addrspace(1) %"587", align 8 + %"588" = inttoptr i64 %"487" to ptr addrspace(1) + %0 = inttoptr i64 %"501" to ptr + %"502" = call i32 %0(ptr addrspace(3) %"474", i32 %"475", <2 x i32> %"476", <2 x i32> %"477", ptr addrspace(5) %"478", float %"479", ptr addrspace(5) %"480", float %"481", <2 x float> %"482", <3 x float> %"483", ptr addrspace(1) %"588", ptr addrspace(1) %"485", ptr addrspace(1) %"486") + %"504" = icmp uge i32 %"502", 1024 + br i1 %"504", label %"505", label %"506" + +"505": ; preds = %"499" + ret i32 %"502" + +"506": ; preds = %"499" + %"509" = icmp eq i32 %"502", 1 + br i1 %"509", label %"510", label %"507" + +"510": ; preds = %"506" + %"511" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"485", i32 0) + store [12 x i8] %"490", ptr addrspace(1) %"511", align 1 + br label %"507" + +"507": ; preds = %"510", %"506" + ret i32 %"502" +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color.ptx b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color.ptx new file mode 100644 index 0000000..dc4161f --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color.ptx @@ -0,0 +1,78 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _Z16draw_solid_colorv +.global .align 8 .b8 launch_index[8]; +.global .align 1 .b8 result_buffer[1]; +.global .align 4 .b8 draw_color[12]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10draw_colorE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10draw_colorE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10draw_colorE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic10draw_colorE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10draw_colorE[1]; + +.visible .entry _Z16draw_solid_colorv() +{ + .reg .f32 %f<5>; + .reg .b32 %r<7>; + .reg .b64 %rd<8>; + + + mov.u64 %rd6, 0; + ld.global.v2.u32 {%r3, %r4}, [launch_index]; + cvt.u64.u32 %rd3, %r3; + cvt.u64.u32 %rd4, %r4; + mov.u64 %rd7, result_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 2; + mov.u32 %r2, 16; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd4, %rd6, %rd6); + // end inline asm + ld.global.f32 %f1, [draw_color]; + ld.global.f32 %f2, [draw_color+4]; + ld.global.f32 %f3, [draw_color+8]; + mov.f32 %f4, 0f00000000; + st.v4.f32 [%rd1], {%f1, %f2, %f3, %f4}; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_draw_solid_color.ll b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_draw_solid_color.ll new file mode 100644 index 0000000..a94dcd1 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_draw_solid_color.ll @@ -0,0 +1,230 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected i32 @_Z16draw_solid_colorv(ptr addrspace(3) %"275", i32 %"276", <2 x i32> %"277", <2 x i32> %"278", ptr addrspace(5) %"279", float %"280", ptr addrspace(5) %"281", float %"282", <2 x float> %"283", <3 x float> %"284", ptr addrspace(1) %"285", ptr addrspace(1) %"286", ptr addrspace(1) %"287") #1 { +"389": + %"370" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"370", align 4 + %"228" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"228", align 1 + %"229" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"229", align 1 + %"206" = alloca float, align 4, addrspace(5) + %"207" = alloca float, align 4, addrspace(5) + %"208" = alloca float, align 4, addrspace(5) + %"209" = alloca float, align 4, addrspace(5) + %"210" = alloca float, align 4, addrspace(5) + %"211" = alloca i32, align 4, addrspace(5) + %"212" = alloca i32, align 4, addrspace(5) + %"213" = alloca i32, align 4, addrspace(5) + %"214" = alloca i32, align 4, addrspace(5) + %"215" = alloca i32, align 4, addrspace(5) + %"216" = alloca i32, align 4, addrspace(5) + %"217" = alloca i32, align 4, addrspace(5) + %"218" = alloca i64, align 8, addrspace(5) + %"219" = alloca i64, align 8, addrspace(5) + %"220" = alloca i64, align 8, addrspace(5) + %"221" = alloca i64, align 8, addrspace(5) + %"222" = alloca i64, align 8, addrspace(5) + %"223" = alloca i64, align 8, addrspace(5) + %"224" = alloca i64, align 8, addrspace(5) + %"225" = alloca i64, align 8, addrspace(5) + %"288" = alloca <2 x i32>, align 8, addrspace(5) + %0 = alloca i64, align 8, addrspace(5) + store i64 0, ptr addrspace(5) %0, align 8 + %"371" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"371", ptr addrspace(5) %"224", align 8 + store <2 x i32> %"277", ptr addrspace(5) %"288", align 8 + %"226" = load <2 x i32>, ptr addrspace(5) %"288", align 8 + %"373" = extractelement <2 x i32> %"226", i32 0 + %"374" = extractelement <2 x i32> %"226", i32 1 + store i32 %"373", ptr addrspace(5) %"214", align 4 + store i32 %"374", ptr addrspace(5) %"215", align 4 + %"234" = load i32, ptr addrspace(5) %"214", align 4 + %"375" = zext i32 %"234" to i64 + store i64 %"375", ptr addrspace(5) %"221", align 8 + %"236" = load i32, ptr addrspace(5) %"215", align 4 + %"377" = zext i32 %"236" to i64 + store i64 %"377", ptr addrspace(5) %"222", align 8 + %"289" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"285", i32 8) + %"380" = ptrtoint ptr addrspace(1) %"289" to i64 + %1 = alloca i64, align 8, addrspace(5) + store i64 %"380", ptr addrspace(5) %1, align 8 + %"379" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"379", ptr addrspace(5) %"225", align 8 + %"239" = load i64, ptr addrspace(5) %"225", align 8 + %2 = inttoptr i64 %"239" to ptr addrspace(1) + %3 = addrspacecast ptr addrspace(1) %2 to ptr + %"238" = ptrtoint ptr %3 to i64 + store i64 %"238", ptr addrspace(5) %"220", align 8 + %4 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %4, align 4 + %"381" = load i32, ptr addrspace(5) %4, align 4 + store i32 %"381", ptr addrspace(5) %"212", align 4 + %5 = alloca i32, align 4, addrspace(5) + store i32 16, ptr addrspace(5) %5, align 4 + %"382" = load i32, ptr addrspace(5) %5, align 4 + store i32 %"382", ptr addrspace(5) %"213", align 4 + %"243" = load i64, ptr addrspace(5) %"220", align 8 + %"244" = load i32, ptr addrspace(5) %"212", align 4 + %"245" = load i32, ptr addrspace(5) %"213", align 4 + %"246" = load i64, ptr addrspace(5) %"221", align 8 + %"247" = load i64, ptr addrspace(5) %"222", align 8 + %"248" = load i64, ptr addrspace(5) %"224", align 8 + %"249" = load i64, ptr addrspace(5) %"224", align 8 + %"242" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"243", i32 %"244", i32 %"245", i64 %"246", i64 %"247", i64 %"248", i64 %"249") + store i64 %"242", ptr addrspace(5) %"219", align 8 + %"291" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"285", i32 32) + %"250" = load float, ptr addrspace(1) %"291", align 4 + store float %"250", ptr addrspace(5) %"207", align 4 + %"293" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"285", i32 32) + %"392" = getelementptr inbounds i8, ptr addrspace(1) %"293", i64 4 + %"251" = load float, ptr addrspace(1) %"392", align 4 + store float %"251", ptr addrspace(5) %"208", align 4 + %"296" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"285", i32 32) + %"394" = getelementptr inbounds i8, ptr addrspace(1) %"296", i64 8 + %"252" = load float, ptr addrspace(1) %"394", align 4 + store float %"252", ptr addrspace(5) %"209", align 4 + %6 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %6, align 4 + %"253" = load float, ptr addrspace(5) %6, align 4 + store float %"253", ptr addrspace(5) %"210", align 4 + %"254" = load float, ptr addrspace(5) %"207", align 4 + %"255" = load float, ptr addrspace(5) %"208", align 4 + %"256" = load float, ptr addrspace(5) %"209", align 4 + %"257" = load float, ptr addrspace(5) %"210", align 4 + %7 = insertelement <4 x float> undef, float %"254", i32 0 + %8 = insertelement <4 x float> %7, float %"255", i32 1 + %9 = insertelement <4 x float> %8, float %"256", i32 2 + %"227" = insertelement <4 x float> %9, float %"257", i32 3 + %"258" = load i64, ptr addrspace(5) %"219", align 8 + %"386" = inttoptr i64 %"258" to ptr + store <4 x float> %"227", ptr %"386", align 16 + ret i32 0 +} + +define protected i32 @__zluda_rt_ptx_impl__rollback_wrapper(ptr addrspace(3) %"305", i32 %"306", <2 x i32> %"307", <2 x i32> %"308", ptr addrspace(5) %"309", float %"310", ptr addrspace(5) %"311", float %"312", <2 x float> %"313", <3 x float> %"314", ptr addrspace(1) %"315", ptr addrspace(1) %"316", ptr addrspace(1) %"317", i64 %"318") #1 { +"390": + %"319" = call i32 @_Z16draw_solid_colorv(ptr addrspace(3) %"305", i32 %"306", <2 x i32> %"307", <2 x i32> %"308", ptr addrspace(5) %"309", float %"310", ptr addrspace(5) %"311", float %"312", <2 x float> %"313", <3 x float> %"314", ptr addrspace(1) %"315", ptr addrspace(1) %"316", ptr addrspace(1) %"317") + %"321" = icmp uge i32 %"319", 1024 + br i1 %"321", label %"322", label %"323" + +"322": ; preds = %"390" + ret i32 %"319" + +"323": ; preds = %"390" + %"325" = icmp eq i64 %"318", 0 + br i1 %"325", label %"326", label %"327" + +"326": ; preds = %"323" + ret i32 0 + +"327": ; preds = %"323" + %"387" = inttoptr i64 %"318" to ptr addrspace(1) + %"329" = load i64, ptr addrspace(1) %"387", align 8 + %"388" = inttoptr i64 %"318" to ptr addrspace(1) + %0 = inttoptr i64 %"329" to ptr + %"330" = call i32 %0(ptr addrspace(3) %"305", i32 %"306", <2 x i32> %"307", <2 x i32> %"308", ptr addrspace(5) %"309", float %"310", ptr addrspace(5) %"311", float %"312", <2 x float> %"313", <3 x float> %"314", ptr addrspace(1) %"388", ptr addrspace(1) %"316", ptr addrspace(1) %"317") + %"332" = icmp uge i32 %"330", 1024 + br i1 %"332", label %"333", label %"334" + +"333": ; preds = %"327" + ret i32 %"330" + +"334": ; preds = %"327" + %"337" = icmp eq i32 %"330", 1 + br i1 %"337", label %"338", label %"335" + +"338": ; preds = %"334" + br label %"335" + +"335": ; preds = %"338", %"334" + ret i32 %"330" +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast.ptx b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast.ptx new file mode 100644 index 0000000..591205c --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast.ptx @@ -0,0 +1,79 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _Z16draw_solid_colorv +.global .align 8 .b8 launch_index[8]; +.global .align 1 .b8 result_buffer[1]; +.global .align 4 .b8 draw_color[12]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10draw_colorE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10draw_colorE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10draw_colorE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic10draw_colorE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10draw_colorE[1]; + +.visible .entry _Z16draw_solid_colorv() +{ + .reg .f32 %f<5>; + .reg .b32 %r<7>; + .reg .b64 %rd<8>; + + + mov.u64 %rd6, 0; + ld.global.u32 %r3, [launch_index]; + ld.global.u32 %r4, [launch_index+4]; + cvt.u64.u32 %rd3, %r3; + cvt.u64.u32 %rd4, %r4; + mov.u64 %rd7, result_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 2; + mov.u32 %r2, 16; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd4, %rd6, %rd6); + // end inline asm + ld.global.f32 %f1, [draw_color]; + ld.global.f32 %f2, [draw_color+4]; + ld.global.f32 %f3, [draw_color+8]; + mov.f32 %f4, 0f00000000; + st.v4.f32 [%rd1], {%f1, %f2, %f3, %f4}; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast_draw_solid_color.ll b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast_draw_solid_color.ll new file mode 100644 index 0000000..76ba350 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixHello_generated_draw_color_var_ptr_cast_draw_solid_color.ll @@ -0,0 +1,232 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected i32 @_Z16draw_solid_colorv(ptr addrspace(3) %"276", i32 %"277", <2 x i32> %"278", <2 x i32> %"279", ptr addrspace(5) %"280", float %"281", ptr addrspace(5) %"282", float %"283", <2 x float> %"284", <3 x float> %"285", ptr addrspace(1) %"286", ptr addrspace(1) %"287", ptr addrspace(1) %"288") #1 { +"393": + %"373" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"373", align 4 + %"227" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"227", align 1 + %"228" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"228", align 1 + %"206" = alloca float, align 4, addrspace(5) + %"207" = alloca float, align 4, addrspace(5) + %"208" = alloca float, align 4, addrspace(5) + %"209" = alloca float, align 4, addrspace(5) + %"210" = alloca float, align 4, addrspace(5) + %"211" = alloca i32, align 4, addrspace(5) + %"212" = alloca i32, align 4, addrspace(5) + %"213" = alloca i32, align 4, addrspace(5) + %"214" = alloca i32, align 4, addrspace(5) + %"215" = alloca i32, align 4, addrspace(5) + %"216" = alloca i32, align 4, addrspace(5) + %"217" = alloca i32, align 4, addrspace(5) + %"218" = alloca i64, align 8, addrspace(5) + %"219" = alloca i64, align 8, addrspace(5) + %"220" = alloca i64, align 8, addrspace(5) + %"221" = alloca i64, align 8, addrspace(5) + %"222" = alloca i64, align 8, addrspace(5) + %"223" = alloca i64, align 8, addrspace(5) + %"224" = alloca i64, align 8, addrspace(5) + %"225" = alloca i64, align 8, addrspace(5) + %"289" = alloca <2 x i32>, align 8, addrspace(5) + %"290" = alloca <2 x i32>, align 8, addrspace(5) + %0 = alloca i64, align 8, addrspace(5) + store i64 0, ptr addrspace(5) %0, align 8 + %"374" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"374", ptr addrspace(5) %"224", align 8 + store <2 x i32> %"278", ptr addrspace(5) %"289", align 8 + %"375" = load i32, ptr addrspace(5) %"289", align 4 + store i32 %"375", ptr addrspace(5) %"214", align 4 + store <2 x i32> %"278", ptr addrspace(5) %"290", align 8 + %"396" = getelementptr inbounds i8, ptr addrspace(5) %"290", i64 4 + %"378" = load i32, ptr addrspace(5) %"396", align 4 + store i32 %"378", ptr addrspace(5) %"215", align 4 + %"233" = load i32, ptr addrspace(5) %"214", align 4 + %"379" = zext i32 %"233" to i64 + store i64 %"379", ptr addrspace(5) %"221", align 8 + %"235" = load i32, ptr addrspace(5) %"215", align 4 + %"381" = zext i32 %"235" to i64 + store i64 %"381", ptr addrspace(5) %"222", align 8 + %"292" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"286", i32 8) + %"384" = ptrtoint ptr addrspace(1) %"292" to i64 + %1 = alloca i64, align 8, addrspace(5) + store i64 %"384", ptr addrspace(5) %1, align 8 + %"383" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"383", ptr addrspace(5) %"225", align 8 + %"238" = load i64, ptr addrspace(5) %"225", align 8 + %2 = inttoptr i64 %"238" to ptr addrspace(1) + %3 = addrspacecast ptr addrspace(1) %2 to ptr + %"237" = ptrtoint ptr %3 to i64 + store i64 %"237", ptr addrspace(5) %"220", align 8 + %4 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %4, align 4 + %"385" = load i32, ptr addrspace(5) %4, align 4 + store i32 %"385", ptr addrspace(5) %"212", align 4 + %5 = alloca i32, align 4, addrspace(5) + store i32 16, ptr addrspace(5) %5, align 4 + %"386" = load i32, ptr addrspace(5) %5, align 4 + store i32 %"386", ptr addrspace(5) %"213", align 4 + %"242" = load i64, ptr addrspace(5) %"220", align 8 + %"243" = load i32, ptr addrspace(5) %"212", align 4 + %"244" = load i32, ptr addrspace(5) %"213", align 4 + %"245" = load i64, ptr addrspace(5) %"221", align 8 + %"246" = load i64, ptr addrspace(5) %"222", align 8 + %"247" = load i64, ptr addrspace(5) %"224", align 8 + %"248" = load i64, ptr addrspace(5) %"224", align 8 + %"241" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"242", i32 %"243", i32 %"244", i64 %"245", i64 %"246", i64 %"247", i64 %"248") + store i64 %"241", ptr addrspace(5) %"219", align 8 + %"294" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"286", i32 32) + %"249" = load float, ptr addrspace(1) %"294", align 4 + store float %"249", ptr addrspace(5) %"207", align 4 + %"296" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"286", i32 32) + %"398" = getelementptr inbounds i8, ptr addrspace(1) %"296", i64 4 + %"250" = load float, ptr addrspace(1) %"398", align 4 + store float %"250", ptr addrspace(5) %"208", align 4 + %"299" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"286", i32 32) + %"400" = getelementptr inbounds i8, ptr addrspace(1) %"299", i64 8 + %"251" = load float, ptr addrspace(1) %"400", align 4 + store float %"251", ptr addrspace(5) %"209", align 4 + %6 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %6, align 4 + %"252" = load float, ptr addrspace(5) %6, align 4 + store float %"252", ptr addrspace(5) %"210", align 4 + %"253" = load float, ptr addrspace(5) %"207", align 4 + %"254" = load float, ptr addrspace(5) %"208", align 4 + %"255" = load float, ptr addrspace(5) %"209", align 4 + %"256" = load float, ptr addrspace(5) %"210", align 4 + %7 = insertelement <4 x float> undef, float %"253", i32 0 + %8 = insertelement <4 x float> %7, float %"254", i32 1 + %9 = insertelement <4 x float> %8, float %"255", i32 2 + %"226" = insertelement <4 x float> %9, float %"256", i32 3 + %"257" = load i64, ptr addrspace(5) %"219", align 8 + %"390" = inttoptr i64 %"257" to ptr + store <4 x float> %"226", ptr %"390", align 16 + ret i32 0 +} + +define protected i32 @__zluda_rt_ptx_impl__rollback_wrapper(ptr addrspace(3) %"308", i32 %"309", <2 x i32> %"310", <2 x i32> %"311", ptr addrspace(5) %"312", float %"313", ptr addrspace(5) %"314", float %"315", <2 x float> %"316", <3 x float> %"317", ptr addrspace(1) %"318", ptr addrspace(1) %"319", ptr addrspace(1) %"320", i64 %"321") #1 { +"394": + %"322" = call i32 @_Z16draw_solid_colorv(ptr addrspace(3) %"308", i32 %"309", <2 x i32> %"310", <2 x i32> %"311", ptr addrspace(5) %"312", float %"313", ptr addrspace(5) %"314", float %"315", <2 x float> %"316", <3 x float> %"317", ptr addrspace(1) %"318", ptr addrspace(1) %"319", ptr addrspace(1) %"320") + %"324" = icmp uge i32 %"322", 1024 + br i1 %"324", label %"325", label %"326" + +"325": ; preds = %"394" + ret i32 %"322" + +"326": ; preds = %"394" + %"328" = icmp eq i64 %"321", 0 + br i1 %"328", label %"329", label %"330" + +"329": ; preds = %"326" + ret i32 0 + +"330": ; preds = %"326" + %"391" = inttoptr i64 %"321" to ptr addrspace(1) + %"332" = load i64, ptr addrspace(1) %"391", align 8 + %"392" = inttoptr i64 %"321" to ptr addrspace(1) + %0 = inttoptr i64 %"332" to ptr + %"333" = call i32 %0(ptr addrspace(3) %"308", i32 %"309", <2 x i32> %"310", <2 x i32> %"311", ptr addrspace(5) %"312", float %"313", ptr addrspace(5) %"314", float %"315", <2 x float> %"316", <3 x float> %"317", ptr addrspace(1) %"392", ptr addrspace(1) %"319", ptr addrspace(1) %"320") + %"335" = icmp uge i32 %"333", 1024 + br i1 %"335", label %"336", label %"337" + +"336": ; preds = %"330" + ret i32 %"333" + +"337": ; preds = %"330" + %"340" = icmp eq i32 %"333", 1 + br i1 %"340", label %"341", label %"338" + +"341": ; preds = %"337" + br label %"338" + +"338": ; preds = %"341", %"337" + ret i32 %"333" +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney.ptx b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney.ptx new file mode 100644 index 0000000..467c814 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney.ptx @@ -0,0 +1,622 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _Z3absf +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; + +.visible .func (.param .b32 func_retval0) _Z3absf( + .param .b32 _Z3absf_param_0 +) +{ + .reg .f32 %f<3>; + + + ld.param.f32 %f1, [_Z3absf_param_0]; + abs.ftz.f32 %f2, %f1; + st.param.f32 [func_retval0+0], %f2; + ret; + +} + // .globl _Z4fabsf +.visible .func (.param .b32 func_retval0) _Z4fabsf( + .param .b32 _Z4fabsf_param_0 +) +{ + .reg .f32 %f<3>; + + + ld.param.f32 %f1, [_Z4fabsf_param_0]; + abs.ftz.f32 %f2, %f1; + st.param.f32 [func_retval0+0], %f2; + ret; + +} + // .globl _Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance +.visible .func _Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance( + .param .b64 _Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_0, + .param .b64 _Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_1, + .param .b64 _Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_2 +) +{ + .reg .pred %p<2>; + .reg .f32 %f<73>; + .reg .f64 %fd<5>; + .reg .b64 %rd<6>; + + + ld.param.u64 %rd3, [_Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_0]; + ld.param.u64 %rd4, [_Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_1]; + ld.param.u64 %rd5, [_Z3PdfR17MaterialParameterR5StateR19PerRayData_radiance_param_2]; + add.s64 %rd1, %rd5, 48; + add.s64 %rd2, %rd3, 40; + ld.f32 %f18, [%rd3+40]; + mov.f32 %f19, 0f3A83126F; + max.ftz.f32 %f20, %f19, %f18; + ld.f32 %f21, [%rd3+64]; + sub.ftz.f32 %f22, %f19, 0f3DCCCCCD; + fma.rn.ftz.f32 %f1, %f21, %f22, 0f3DCCCCCD; + ld.f32 %f2, [%rd3+28]; + ld.f32 %f3, [%rd5+36]; + ld.f32 %f23, [%rd5+48]; + add.ftz.f32 %f24, %f23, %f3; + ld.f32 %f4, [%rd5+40]; + ld.f32 %f25, [%rd5+52]; + add.ftz.f32 %f26, %f25, %f4; + ld.f32 %f5, [%rd5+44]; + ld.f32 %f27, [%rd5+56]; + add.ftz.f32 %f28, %f27, %f5; + mul.ftz.f32 %f29, %f26, %f26; + fma.rn.ftz.f32 %f30, %f24, %f24, %f29; + fma.rn.ftz.f32 %f31, %f28, %f28, %f30; + rsqrt.approx.ftz.f32 %f32, %f31; + mul.ftz.f32 %f6, %f24, %f32; + mul.ftz.f32 %f7, %f26, %f32; + mul.ftz.f32 %f8, %f28, %f32; + ld.f32 %f9, [%rd4+36]; + ld.f32 %f10, [%rd4+40]; + mul.ftz.f32 %f33, %f10, %f7; + fma.rn.ftz.f32 %f34, %f9, %f6, %f33; + ld.f32 %f11, [%rd4+44]; + fma.rn.ftz.f32 %f35, %f11, %f8, %f34; + abs.ftz.f32 %f12, %f35; + mul.ftz.f32 %f13, %f20, %f20; + add.ftz.f32 %f36, %f13, 0fBF800000; + mul.ftz.f32 %f37, %f36, %f12; + fma.rn.ftz.f32 %f14, %f12, %f37, 0f3F800000; + setp.ge.ftz.f32 %p1, %f1, 0f3F800000; + mov.f32 %f72, 0f3EA2F983; + @%p1 bra $L__BB2_2; + + mul.ftz.f32 %f38, %f1, %f1; + add.ftz.f32 %f39, %f38, 0fBF800000; + mul.ftz.f32 %f40, %f12, %f39; + fma.rn.ftz.f32 %f41, %f12, %f40, 0f3F800000; + lg2.approx.ftz.f32 %f42, %f38; + mul.ftz.f32 %f43, %f42, 0f3F317218; + mul.ftz.f32 %f44, %f43, 0f40490FDB; + mul.ftz.f32 %f45, %f41, %f44; + div.approx.ftz.f32 %f72, %f39, %f45; + +$L__BB2_2: + mov.f32 %f46, 0f3F800000; + sub.ftz.f32 %f47, %f46, %f2; + mul.ftz.f32 %f48, %f47, 0f3F000000; + ld.f32 %f49, [%rd2+20]; + add.ftz.f32 %f50, %f49, 0f3F800000; + rcp.approx.ftz.f32 %f51, %f50; + mul.ftz.f32 %f52, %f12, %f72; + mul.ftz.f32 %f53, %f14, 0f40490FDB; + mul.ftz.f32 %f54, %f14, %f53; + div.approx.ftz.f32 %f55, %f13, %f54; + mul.ftz.f32 %f56, %f12, %f55; + sub.ftz.f32 %f57, %f56, %f52; + fma.rn.ftz.f32 %f58, %f57, %f51, %f52; + cvt.ftz.f64.f32 %fd1, %f58; + mul.ftz.f32 %f59, %f4, %f7; + fma.rn.ftz.f32 %f60, %f3, %f6, %f59; + fma.rn.ftz.f32 %f61, %f5, %f8, %f60; + abs.ftz.f32 %f62, %f61; + cvt.ftz.f64.f32 %fd2, %f62; + mul.f64 %fd3, %fd2, 0d4010000000000000; + div.rn.f64 %fd4, %fd1, %fd3; + cvt.rn.ftz.f32.f64 %f63, %fd4; + mul.ftz.f32 %f64, %f10, %f4; + fma.rn.ftz.f32 %f65, %f9, %f3, %f64; + fma.rn.ftz.f32 %f66, %f11, %f5, %f65; + abs.ftz.f32 %f67, %f66; + mul.ftz.f32 %f68, %f67, 0f3EA2F983; + sub.ftz.f32 %f69, %f46, %f48; + mul.ftz.f32 %f70, %f69, %f63; + fma.rn.ftz.f32 %f71, %f48, %f68, %f70; + st.f32 [%rd1+24], %f71; + ret; + +} + // .globl _Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance +.visible .func _Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance( + .param .b64 _Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_0, + .param .b64 _Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_1, + .param .b64 _Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_2 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<110>; + .reg .b32 %r<8>; + .reg .b64 %rd<6>; + + + ld.param.u64 %rd3, [_Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_0]; + ld.param.u64 %rd4, [_Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_2]; + ld.param.u64 %rd5, [_Z6SampleR17MaterialParameterR5StateR19PerRayData_radiance_param_1]; + ld.f32 %f1, [%rd5+36]; + ld.f32 %f2, [%rd5+40]; + ld.f32 %f3, [%rd5+44]; + add.s64 %rd1, %rd4, 48; + ld.f32 %f21, [%rd5]; + ld.f32 %f22, [%rd5+4]; + ld.f32 %f23, [%rd5+8]; + st.f32 [%rd4+24], %f21; + st.f32 [%rd4+28], %f22; + st.f32 [%rd4+32], %f23; + ld.u32 %r1, [%rd4+4]; + mad.lo.s32 %r2, %r1, 1664525, 1013904223; + st.u32 [%rd4+4], %r2; + and.b32 %r3, %r2, 16777215; + cvt.rn.f32.u32 %f24, %r3; + mov.f32 %f25, 0f4B800000; + div.approx.ftz.f32 %f26, %f24, %f25; + add.s64 %rd2, %rd3, 28; + ld.f32 %f27, [%rd3+28]; + mov.f32 %f28, 0f3F800000; + sub.ftz.f32 %f29, %f28, %f27; + mul.ftz.f32 %f30, %f29, 0f3F000000; + mad.lo.s32 %r4, %r2, 1664525, 1013904223; + and.b32 %r5, %r4, 16777215; + cvt.rn.f32.u32 %f31, %r5; + div.approx.ftz.f32 %f4, %f31, %f25; + mad.lo.s32 %r6, %r4, 1664525, 1013904223; + st.u32 [%rd4+4], %r6; + and.b32 %r7, %r6, 16777215; + cvt.rn.f32.u32 %f32, %r7; + div.approx.ftz.f32 %f5, %f32, %f25; + abs.ftz.f32 %f33, %f1; + abs.ftz.f32 %f34, %f3; + setp.gt.ftz.f32 %p1, %f33, %f34; + neg.ftz.f32 %f35, %f2; + neg.ftz.f32 %f36, %f3; + selp.f32 %f37, %f35, 0f00000000, %p1; + selp.f32 %f38, %f1, %f36, %p1; + selp.f32 %f39, 0f00000000, %f2, %p1; + mul.ftz.f32 %f40, %f38, %f38; + fma.rn.ftz.f32 %f41, %f37, %f37, %f40; + fma.rn.ftz.f32 %f42, %f39, %f39, %f41; + rsqrt.approx.ftz.f32 %f43, %f42; + mul.ftz.f32 %f6, %f37, %f43; + mul.ftz.f32 %f7, %f38, %f43; + mul.ftz.f32 %f8, %f39, %f43; + mul.ftz.f32 %f44, %f3, %f7; + mul.ftz.f32 %f45, %f2, %f8; + sub.ftz.f32 %f9, %f44, %f45; + mul.ftz.f32 %f46, %f1, %f8; + mul.ftz.f32 %f47, %f3, %f6; + sub.ftz.f32 %f10, %f46, %f47; + mul.ftz.f32 %f48, %f2, %f6; + mul.ftz.f32 %f49, %f1, %f7; + sub.ftz.f32 %f11, %f48, %f49; + setp.lt.ftz.f32 %p2, %f26, %f30; + @%p2 bra $L__BB3_2; + bra.uni $L__BB3_1; + +$L__BB3_2: + sqrt.approx.ftz.f32 %f87, %f4; + mul.ftz.f32 %f88, %f5, 0f40C90FDB; + cos.approx.ftz.f32 %f89, %f88; + mul.ftz.f32 %f90, %f87, %f89; + sin.approx.ftz.f32 %f91, %f88; + mul.ftz.f32 %f92, %f87, %f91; + mul.ftz.f32 %f93, %f90, %f90; + sub.ftz.f32 %f95, %f28, %f93; + mul.ftz.f32 %f96, %f92, %f92; + sub.ftz.f32 %f97, %f95, %f96; + mov.f32 %f98, 0f00000000; + max.ftz.f32 %f99, %f98, %f97; + sqrt.approx.ftz.f32 %f100, %f99; + mul.ftz.f32 %f101, %f6, %f92; + mul.ftz.f32 %f102, %f7, %f92; + mul.ftz.f32 %f103, %f8, %f92; + fma.rn.ftz.f32 %f104, %f9, %f90, %f101; + fma.rn.ftz.f32 %f105, %f10, %f90, %f102; + fma.rn.ftz.f32 %f106, %f11, %f90, %f103; + fma.rn.ftz.f32 %f107, %f1, %f100, %f104; + fma.rn.ftz.f32 %f108, %f2, %f100, %f105; + fma.rn.ftz.f32 %f109, %f3, %f100, %f106; + bra.uni $L__BB3_3; + +$L__BB3_1: + ld.f32 %f50, [%rd1]; + ld.f32 %f51, [%rd1+4]; + ld.f32 %f52, [%rd1+8]; + ld.f32 %f53, [%rd2+12]; + mov.f32 %f54, 0f3A83126F; + max.ftz.f32 %f55, %f54, %f53; + add.ftz.f32 %f56, %f4, %f4; + mul.ftz.f32 %f57, %f56, 0f40490FDB; + fma.rn.ftz.f32 %f58, %f55, %f55, 0fBF800000; + fma.rn.ftz.f32 %f60, %f5, %f58, 0f3F800000; + sub.ftz.f32 %f61, %f28, %f5; + div.approx.ftz.f32 %f62, %f61, %f60; + sqrt.approx.ftz.f32 %f63, %f62; + mul.ftz.f32 %f64, %f63, %f63; + sub.ftz.f32 %f65, %f28, %f64; + sqrt.approx.ftz.f32 %f66, %f65; + sin.approx.ftz.f32 %f67, %f57; + cos.approx.ftz.f32 %f68, %f57; + mul.ftz.f32 %f69, %f66, %f68; + mul.ftz.f32 %f70, %f66, %f67; + mul.ftz.f32 %f71, %f9, %f69; + mul.ftz.f32 %f72, %f10, %f69; + mul.ftz.f32 %f73, %f11, %f69; + fma.rn.ftz.f32 %f74, %f6, %f70, %f71; + fma.rn.ftz.f32 %f75, %f7, %f70, %f72; + fma.rn.ftz.f32 %f76, %f8, %f70, %f73; + fma.rn.ftz.f32 %f77, %f1, %f63, %f74; + fma.rn.ftz.f32 %f78, %f2, %f63, %f75; + fma.rn.ftz.f32 %f79, %f3, %f63, %f76; + mul.ftz.f32 %f80, %f51, %f78; + fma.rn.ftz.f32 %f81, %f50, %f77, %f80; + fma.rn.ftz.f32 %f82, %f52, %f79, %f81; + add.ftz.f32 %f83, %f82, %f82; + mul.ftz.f32 %f84, %f77, %f83; + mul.ftz.f32 %f85, %f78, %f83; + mul.ftz.f32 %f86, %f79, %f83; + sub.ftz.f32 %f107, %f84, %f50; + sub.ftz.f32 %f108, %f85, %f51; + sub.ftz.f32 %f109, %f86, %f52; + +$L__BB3_3: + st.f32 [%rd1+-12], %f107; + st.f32 [%rd1+-8], %f108; + st.f32 [%rd1+-4], %f109; + ret; + +} + // .globl _Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance +.visible .func (.param .align 4 .b8 func_retval0[12]) _Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance( + .param .b64 _Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_0, + .param .b64 _Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_1, + .param .b64 _Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_2 +) +{ + .reg .pred %p<6>; + .reg .f32 %f<217>; + .reg .b64 %rd<5>; + + + ld.param.u64 %rd2, [_Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_0]; + ld.param.u64 %rd3, [_Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_1]; + ld.param.u64 %rd4, [_Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance_param_2]; + ld.f32 %f1, [%rd4+36]; + ld.f32 %f2, [%rd3+36]; + ld.f32 %f3, [%rd4+40]; + ld.f32 %f4, [%rd3+40]; + mul.ftz.f32 %f50, %f4, %f3; + fma.rn.ftz.f32 %f51, %f2, %f1, %f50; + ld.f32 %f5, [%rd4+44]; + ld.f32 %f6, [%rd3+44]; + fma.rn.ftz.f32 %f7, %f6, %f5, %f51; + ld.f32 %f8, [%rd4+48]; + ld.f32 %f9, [%rd4+52]; + mul.ftz.f32 %f52, %f4, %f9; + fma.rn.ftz.f32 %f53, %f2, %f8, %f52; + ld.f32 %f10, [%rd4+56]; + fma.rn.ftz.f32 %f11, %f6, %f10, %f53; + setp.le.ftz.f32 %p1, %f7, 0f00000000; + setp.le.ftz.f32 %p2, %f11, 0f00000000; + or.pred %p3, %p2, %p1; + mov.f32 %f214, 0f00000000; + mov.f32 %f215, %f214; + mov.f32 %f216, %f214; + @%p3 bra $L__BB4_6; + + add.ftz.f32 %f57, %f8, %f1; + add.ftz.f32 %f58, %f9, %f3; + mul.ftz.f32 %f59, %f58, %f58; + fma.rn.ftz.f32 %f60, %f57, %f57, %f59; + add.ftz.f32 %f61, %f10, %f5; + fma.rn.ftz.f32 %f62, %f61, %f61, %f60; + rsqrt.approx.ftz.f32 %f63, %f62; + mul.ftz.f32 %f64, %f57, %f63; + mul.ftz.f32 %f65, %f58, %f63; + mul.ftz.f32 %f66, %f61, %f63; + mul.ftz.f32 %f67, %f4, %f65; + fma.rn.ftz.f32 %f68, %f2, %f64, %f67; + fma.rn.ftz.f32 %f12, %f6, %f66, %f68; + mul.ftz.f32 %f69, %f3, %f65; + fma.rn.ftz.f32 %f70, %f1, %f64, %f69; + fma.rn.ftz.f32 %f13, %f5, %f66, %f70; + add.s64 %rd1, %rd2, 4; + ld.f32 %f14, [%rd2+4]; + ld.f32 %f15, [%rd2+8]; + mul.ftz.f32 %f71, %f15, 0f3F19999A; + fma.rn.ftz.f32 %f72, %f14, 0f3E99999A, %f71; + ld.f32 %f16, [%rd2+12]; + fma.rn.ftz.f32 %f17, %f16, 0f3DCCCCCD, %f72; + setp.leu.ftz.f32 %p4, %f17, 0f00000000; + mov.f32 %f56, 0f00000000; + mov.f32 %f210, %f56; + mov.f32 %f211, %f56; + mov.f32 %f212, %f56; + @%p4 bra $L__BB4_3; + + rcp.approx.ftz.f32 %f73, %f17; + fma.rn.ftz.f32 %f210, %f14, %f73, 0fBF800000; + fma.rn.ftz.f32 %f211, %f15, %f73, 0fBF800000; + fma.rn.ftz.f32 %f212, %f16, %f73, 0fBF800000; + +$L__BB4_3: + ld.f32 %f75, [%rd1+32]; + mul.ftz.f32 %f76, %f75, 0f3DA3D70A; + ld.f32 %f77, [%rd1+40]; + fma.rn.ftz.f32 %f78, %f210, %f77, 0f3F800000; + mov.f32 %f79, 0f3F800000; + fma.rn.ftz.f32 %f80, %f211, %f77, 0f3F800000; + fma.rn.ftz.f32 %f81, %f212, %f77, 0f3F800000; + mul.ftz.f32 %f82, %f76, %f78; + mul.ftz.f32 %f83, %f76, %f80; + mul.ftz.f32 %f84, %f76, %f81; + sub.ftz.f32 %f85, %f14, %f82; + sub.ftz.f32 %f86, %f15, %f83; + sub.ftz.f32 %f87, %f16, %f84; + ld.f32 %f24, [%rd1+24]; + fma.rn.ftz.f32 %f88, %f24, %f85, %f82; + fma.rn.ftz.f32 %f89, %f24, %f86, %f83; + fma.rn.ftz.f32 %f90, %f24, %f87, %f84; + ld.f32 %f91, [%rd1+52]; + fma.rn.ftz.f32 %f92, %f210, %f91, 0f3F800000; + fma.rn.ftz.f32 %f93, %f211, %f91, 0f3F800000; + fma.rn.ftz.f32 %f94, %f212, %f91, 0f3F800000; + sub.ftz.f32 %f95, %f79, %f7; + min.ftz.f32 %f96, %f95, %f79; + max.ftz.f32 %f98, %f56, %f96; + mul.ftz.f32 %f99, %f98, %f98; + mul.ftz.f32 %f100, %f99, %f99; + mul.ftz.f32 %f101, %f98, %f100; + sub.ftz.f32 %f102, %f79, %f11; + min.ftz.f32 %f103, %f102, %f79; + max.ftz.f32 %f104, %f56, %f103; + mul.ftz.f32 %f105, %f104, %f104; + mul.ftz.f32 %f106, %f105, %f105; + mul.ftz.f32 %f107, %f104, %f106; + add.ftz.f32 %f108, %f13, %f13; + mul.ftz.f32 %f109, %f13, %f108; + ld.f32 %f110, [%rd1+36]; + fma.rn.ftz.f32 %f111, %f109, %f110, 0f3F000000; + add.ftz.f32 %f112, %f111, 0fBF800000; + fma.rn.ftz.f32 %f113, %f101, %f112, 0f3F800000; + fma.rn.ftz.f32 %f114, %f107, %f112, 0f3F800000; + mul.ftz.f32 %f25, %f113, %f114; + mul.ftz.f32 %f115, %f13, %f13; + fma.rn.ftz.f32 %f116, %f115, %f110, 0fBF800000; + fma.rn.ftz.f32 %f117, %f101, %f116, 0f3F800000; + fma.rn.ftz.f32 %f118, %f107, %f116, 0f3F800000; + mul.ftz.f32 %f119, %f117, %f118; + add.ftz.f32 %f120, %f11, %f7; + rcp.approx.ftz.f32 %f121, %f120; + add.ftz.f32 %f122, %f121, 0fBF000000; + fma.rn.ftz.f32 %f123, %f122, %f119, 0f3F000000; + mul.ftz.f32 %f26, %f123, 0f3FA00000; + mov.f32 %f124, 0f3A83126F; + max.ftz.f32 %f125, %f124, %f110; + mul.ftz.f32 %f126, %f125, %f125; + add.ftz.f32 %f127, %f126, 0fBF800000; + mul.ftz.f32 %f128, %f12, %f127; + fma.rn.ftz.f32 %f129, %f12, %f128, 0f3F800000; + mul.ftz.f32 %f130, %f129, 0f40490FDB; + mul.ftz.f32 %f131, %f129, %f130; + div.approx.ftz.f32 %f27, %f126, %f131; + sub.ftz.f32 %f132, %f79, %f13; + min.ftz.f32 %f133, %f132, %f79; + max.ftz.f32 %f134, %f56, %f133; + mul.ftz.f32 %f135, %f134, %f134; + mul.ftz.f32 %f136, %f135, %f135; + mul.ftz.f32 %f28, %f134, %f136; + sub.ftz.f32 %f137, %f79, %f88; + sub.ftz.f32 %f138, %f79, %f89; + sub.ftz.f32 %f139, %f79, %f90; + fma.rn.ftz.f32 %f29, %f137, %f28, %f88; + fma.rn.ftz.f32 %f30, %f138, %f28, %f89; + fma.rn.ftz.f32 %f31, %f139, %f28, %f90; + fma.rn.ftz.f32 %f140, %f110, 0f3F000000, 0f3F000000; + mul.ftz.f32 %f141, %f140, %f140; + mul.ftz.f32 %f142, %f141, %f141; + mul.ftz.f32 %f32, %f7, %f7; + add.ftz.f32 %f143, %f32, %f142; + mul.ftz.f32 %f144, %f32, %f142; + sub.ftz.f32 %f145, %f143, %f144; + sqrt.approx.ftz.f32 %f146, %f145; + add.ftz.f32 %f147, %f7, %f146; + rcp.approx.ftz.f32 %f148, %f147; + mul.ftz.f32 %f33, %f11, %f11; + add.ftz.f32 %f149, %f33, %f142; + mul.ftz.f32 %f150, %f33, %f142; + sub.ftz.f32 %f151, %f149, %f150; + sqrt.approx.ftz.f32 %f152, %f151; + add.ftz.f32 %f153, %f11, %f152; + rcp.approx.ftz.f32 %f154, %f153; + mul.ftz.f32 %f34, %f148, %f154; + ld.f32 %f155, [%rd1+48]; + mul.ftz.f32 %f156, %f28, %f155; + mul.ftz.f32 %f35, %f92, %f156; + mul.ftz.f32 %f36, %f93, %f156; + mul.ftz.f32 %f37, %f94, %f156; + ld.f32 %f157, [%rd1+60]; + sub.ftz.f32 %f158, %f124, 0f3DCCCCCD; + fma.rn.ftz.f32 %f38, %f157, %f158, 0f3DCCCCCD; + setp.ge.ftz.f32 %p5, %f38, 0f3F800000; + mov.f32 %f213, 0f3EA2F983; + @%p5 bra $L__BB4_5; + + mul.ftz.f32 %f159, %f38, %f38; + add.ftz.f32 %f160, %f159, 0fBF800000; + mul.ftz.f32 %f161, %f12, %f160; + fma.rn.ftz.f32 %f162, %f12, %f161, 0f3F800000; + lg2.approx.ftz.f32 %f163, %f159; + mul.ftz.f32 %f164, %f163, 0f3F317218; + mul.ftz.f32 %f165, %f164, 0f40490FDB; + mul.ftz.f32 %f166, %f162, %f165; + div.approx.ftz.f32 %f213, %f160, %f166; + +$L__BB4_5: + sub.ftz.f32 %f168, %f79, 0f3D23D70A; + fma.rn.ftz.f32 %f169, %f28, %f168, 0f3D23D70A; + mul.ftz.f32 %f170, %f32, 0f3D800000; + add.ftz.f32 %f171, %f32, 0f3D800000; + sub.ftz.f32 %f172, %f171, %f170; + sqrt.approx.ftz.f32 %f173, %f172; + add.ftz.f32 %f174, %f7, %f173; + rcp.approx.ftz.f32 %f175, %f174; + mul.ftz.f32 %f176, %f33, 0f3D800000; + add.ftz.f32 %f177, %f33, 0f3D800000; + sub.ftz.f32 %f178, %f177, %f176; + sqrt.approx.ftz.f32 %f179, %f178; + add.ftz.f32 %f180, %f11, %f179; + rcp.approx.ftz.f32 %f181, %f180; + mul.ftz.f32 %f182, %f175, %f181; + sub.ftz.f32 %f183, %f26, %f25; + ld.f32 %f184, [%rd1+28]; + fma.rn.ftz.f32 %f185, %f183, %f184, %f25; + mul.ftz.f32 %f186, %f185, 0f3EA2F983; + fma.rn.ftz.f32 %f187, %f14, %f186, %f35; + fma.rn.ftz.f32 %f188, %f15, %f186, %f36; + fma.rn.ftz.f32 %f189, %f16, %f186, %f37; + sub.ftz.f32 %f190, %f79, %f24; + mul.ftz.f32 %f191, %f190, %f187; + mul.ftz.f32 %f192, %f190, %f188; + mul.ftz.f32 %f193, %f190, %f189; + mul.ftz.f32 %f194, %f29, %f34; + mul.ftz.f32 %f195, %f30, %f34; + mul.ftz.f32 %f196, %f31, %f34; + fma.rn.ftz.f32 %f197, %f27, %f194, %f191; + fma.rn.ftz.f32 %f198, %f27, %f195, %f192; + fma.rn.ftz.f32 %f199, %f27, %f196, %f193; + ld.f32 %f200, [%rd1+56]; + mul.ftz.f32 %f201, %f200, 0f3E800000; + mul.ftz.f32 %f202, %f182, %f201; + mul.ftz.f32 %f203, %f169, %f202; + fma.rn.ftz.f32 %f204, %f213, %f203, %f197; + fma.rn.ftz.f32 %f205, %f213, %f203, %f198; + fma.rn.ftz.f32 %f206, %f213, %f203, %f199; + min.ftz.f32 %f207, %f7, %f79; + mov.f32 %f208, 0f00000000; + max.ftz.f32 %f209, %f208, %f207; + mul.ftz.f32 %f216, %f209, %f206; + mul.ftz.f32 %f215, %f209, %f205; + mul.ftz.f32 %f214, %f209, %f204; + +$L__BB4_6: + st.param.f32 [func_retval0+0], %f214; + st.param.f32 [func_retval0+4], %f215; + st.param.f32 [func_retval0+8], %f216; + ret; + +} + // .globl _ZN5optix3OnbC2ERK6float3 +.visible .func _ZN5optix3OnbC2ERK6float3( + .param .b64 _ZN5optix3OnbC2ERK6float3_param_0, + .param .b64 _ZN5optix3OnbC2ERK6float3_param_1 +) +{ + .reg .pred %p<2>; + .reg .f32 %f<32>; + .reg .b32 %r<2>; + .reg .b64 %rd<4>; + + + ld.param.u64 %rd2, [_ZN5optix3OnbC2ERK6float3_param_0]; + ld.param.u64 %rd3, [_ZN5optix3OnbC2ERK6float3_param_1]; + ld.f32 %f1, [%rd3]; + ld.f32 %f2, [%rd3+4]; + ld.f32 %f3, [%rd3+8]; + add.s64 %rd1, %rd2, 24; + st.f32 [%rd2+24], %f1; + st.f32 [%rd2+28], %f2; + st.f32 [%rd2+32], %f3; + abs.ftz.f32 %f9, %f1; + abs.ftz.f32 %f10, %f3; + setp.gt.ftz.f32 %p1, %f9, %f10; + @%p1 bra $L__BB5_2; + bra.uni $L__BB5_1; + +$L__BB5_2: + neg.ftz.f32 %f30, %f2; + st.f32 [%rd1+-12], %f30; + mov.f32 %f31, 0f00000000; + mov.f32 %f29, %f1; + bra.uni $L__BB5_3; + +$L__BB5_1: + mov.f32 %f30, 0f00000000; + mov.u32 %r1, 0; + st.u32 [%rd1+-12], %r1; + neg.ftz.f32 %f29, %f3; + mov.f32 %f31, %f2; + +$L__BB5_3: + mul.ftz.f32 %f13, %f29, %f29; + fma.rn.ftz.f32 %f14, %f30, %f30, %f13; + fma.rn.ftz.f32 %f15, %f31, %f31, %f14; + rsqrt.approx.ftz.f32 %f16, %f15; + mul.ftz.f32 %f17, %f30, %f16; + mul.ftz.f32 %f18, %f16, %f29; + mul.ftz.f32 %f19, %f16, %f31; + st.f32 [%rd1+-12], %f17; + st.f32 [%rd1+-8], %f18; + st.f32 [%rd1+-4], %f19; + mul.ftz.f32 %f20, %f18, %f3; + mul.ftz.f32 %f21, %f19, %f2; + sub.ftz.f32 %f22, %f20, %f21; + mul.ftz.f32 %f23, %f19, %f1; + mul.ftz.f32 %f24, %f17, %f3; + sub.ftz.f32 %f25, %f23, %f24; + mul.ftz.f32 %f26, %f17, %f2; + mul.ftz.f32 %f27, %f18, %f1; + sub.ftz.f32 %f28, %f26, %f27; + st.f32 [%rd1+-24], %f22; + st.f32 [%rd1+-20], %f25; + st.f32 [%rd1+-16], %f28; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney_Eval.ll b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney_Eval.ll new file mode 100644 index 0000000..f94f164 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_disney_Eval.ll @@ -0,0 +1,1247 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected { [3 x i32], i32 } @_Z4EvalR17MaterialParameterR5StateR19PerRayData_radiance(i64 %"729", i64 %"730", i64 %"731", ptr addrspace(3) %"1435", <2 x i32> %"1436", ptr addrspace(1) %"1437") #1 { +"1506": + %"1473" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"1473", align 4 + %"724" = alloca i64, align 8, addrspace(5) + %"725" = alloca i64, align 8, addrspace(5) + %"726" = alloca i64, align 8, addrspace(5) + %"723" = alloca [3 x i32], align 4, addrspace(5) + %"727" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"727", align 1 + %"728" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"728", align 1 + %"1420" = alloca [3 x i32], align 4, addrspace(5) + %"1421" = alloca i64, align 8, addrspace(5) + %"1422" = alloca i64, align 8, addrspace(5) + %"1423" = alloca i64, align 8, addrspace(5) + %"441" = alloca i1, align 1, addrspace(5) + %"442" = alloca i1, align 1, addrspace(5) + %"443" = alloca i1, align 1, addrspace(5) + %"444" = alloca i1, align 1, addrspace(5) + %"445" = alloca i1, align 1, addrspace(5) + %"446" = alloca i1, align 1, addrspace(5) + %"447" = alloca float, align 4, addrspace(5) + %"448" = alloca float, align 4, addrspace(5) + %"449" = alloca float, align 4, addrspace(5) + %"450" = alloca float, align 4, addrspace(5) + %"451" = alloca float, align 4, addrspace(5) + %"452" = alloca float, align 4, addrspace(5) + %"453" = alloca float, align 4, addrspace(5) + %"454" = alloca float, align 4, addrspace(5) + %"455" = alloca float, align 4, addrspace(5) + %"456" = alloca float, align 4, addrspace(5) + %"457" = alloca float, align 4, addrspace(5) + %"458" = alloca float, align 4, addrspace(5) + %"459" = alloca float, align 4, addrspace(5) + %"460" = alloca float, align 4, addrspace(5) + %"461" = alloca float, align 4, addrspace(5) + %"462" = alloca float, align 4, addrspace(5) + %"463" = alloca float, align 4, addrspace(5) + %"464" = alloca float, align 4, addrspace(5) + %"465" = alloca float, align 4, addrspace(5) + %"466" = alloca float, align 4, addrspace(5) + %"467" = alloca float, align 4, addrspace(5) + %"468" = alloca float, align 4, addrspace(5) + %"469" = alloca float, align 4, addrspace(5) + %"470" = alloca float, align 4, addrspace(5) + %"471" = alloca float, align 4, addrspace(5) + %"472" = alloca float, align 4, addrspace(5) + %"473" = alloca float, align 4, addrspace(5) + %"474" = alloca float, align 4, addrspace(5) + %"475" = alloca float, align 4, addrspace(5) + %"476" = alloca float, align 4, addrspace(5) + %"477" = alloca float, align 4, addrspace(5) + %"478" = alloca float, align 4, addrspace(5) + %"479" = alloca float, align 4, addrspace(5) + %"480" = alloca float, align 4, addrspace(5) + %"481" = alloca float, align 4, addrspace(5) + %"482" = alloca float, align 4, addrspace(5) + %"483" = alloca float, align 4, addrspace(5) + %"484" = alloca float, align 4, addrspace(5) + %"485" = alloca float, align 4, addrspace(5) + %"486" = alloca float, align 4, addrspace(5) + %"487" = alloca float, align 4, addrspace(5) + %"488" = alloca float, align 4, addrspace(5) + %"489" = alloca float, align 4, addrspace(5) + %"490" = alloca float, align 4, addrspace(5) + %"491" = alloca float, align 4, addrspace(5) + %"492" = alloca float, align 4, addrspace(5) + %"493" = alloca float, align 4, addrspace(5) + %"494" = alloca float, align 4, addrspace(5) + %"495" = alloca float, align 4, addrspace(5) + %"496" = alloca float, align 4, addrspace(5) + %"497" = alloca float, align 4, addrspace(5) + %"498" = alloca float, align 4, addrspace(5) + %"499" = alloca float, align 4, addrspace(5) + %"500" = alloca float, align 4, addrspace(5) + %"501" = alloca float, align 4, addrspace(5) + %"502" = alloca float, align 4, addrspace(5) + %"503" = alloca float, align 4, addrspace(5) + %"504" = alloca float, align 4, addrspace(5) + %"505" = alloca float, align 4, addrspace(5) + %"506" = alloca float, align 4, addrspace(5) + %"507" = alloca float, align 4, addrspace(5) + %"508" = alloca float, align 4, addrspace(5) + %"509" = alloca float, align 4, addrspace(5) + %"510" = alloca float, align 4, addrspace(5) + %"511" = alloca float, align 4, addrspace(5) + %"512" = alloca float, align 4, addrspace(5) + %"513" = alloca float, align 4, addrspace(5) + %"514" = alloca float, align 4, addrspace(5) + %"515" = alloca float, align 4, addrspace(5) + %"516" = alloca float, align 4, addrspace(5) + %"517" = alloca float, align 4, addrspace(5) + %"518" = alloca float, align 4, addrspace(5) + %"519" = alloca float, align 4, addrspace(5) + %"520" = alloca float, align 4, addrspace(5) + %"521" = alloca float, align 4, addrspace(5) + %"522" = alloca float, align 4, addrspace(5) + %"523" = alloca float, align 4, addrspace(5) + %"524" = alloca float, align 4, addrspace(5) + %"525" = alloca float, align 4, addrspace(5) + %"526" = alloca float, align 4, addrspace(5) + %"527" = alloca float, align 4, addrspace(5) + %"528" = alloca float, align 4, addrspace(5) + %"529" = alloca float, align 4, addrspace(5) + %"530" = alloca float, align 4, addrspace(5) + %"531" = alloca float, align 4, addrspace(5) + %"532" = alloca float, align 4, addrspace(5) + %"533" = alloca float, align 4, addrspace(5) + %"534" = alloca float, align 4, addrspace(5) + %"535" = alloca float, align 4, addrspace(5) + %"536" = alloca float, align 4, addrspace(5) + %"537" = alloca float, align 4, addrspace(5) + %"538" = alloca float, align 4, addrspace(5) + %"539" = alloca float, align 4, addrspace(5) + %"540" = alloca float, align 4, addrspace(5) + %"541" = alloca float, align 4, addrspace(5) + %"542" = alloca float, align 4, addrspace(5) + %"543" = alloca float, align 4, addrspace(5) + %"544" = alloca float, align 4, addrspace(5) + %"545" = alloca float, align 4, addrspace(5) + %"546" = alloca float, align 4, addrspace(5) + %"547" = alloca float, align 4, addrspace(5) + %"548" = alloca float, align 4, addrspace(5) + %"549" = alloca float, align 4, addrspace(5) + %"550" = alloca float, align 4, addrspace(5) + %"551" = alloca float, align 4, addrspace(5) + %"552" = alloca float, align 4, addrspace(5) + %"553" = alloca float, align 4, addrspace(5) + %"554" = alloca float, align 4, addrspace(5) + %"555" = alloca float, align 4, addrspace(5) + %"556" = alloca float, align 4, addrspace(5) + %"557" = alloca float, align 4, addrspace(5) + %"558" = alloca float, align 4, addrspace(5) + %"559" = alloca float, align 4, addrspace(5) + %"560" = alloca float, align 4, addrspace(5) + %"561" = alloca float, align 4, addrspace(5) + %"562" = alloca float, align 4, addrspace(5) + %"563" = alloca float, align 4, addrspace(5) + %"564" = alloca float, align 4, addrspace(5) + %"565" = alloca float, align 4, addrspace(5) + %"566" = alloca float, align 4, addrspace(5) + %"567" = alloca float, align 4, addrspace(5) + %"568" = alloca float, align 4, addrspace(5) + %"569" = alloca float, align 4, addrspace(5) + %"570" = alloca float, align 4, addrspace(5) + %"571" = alloca float, align 4, addrspace(5) + %"572" = alloca float, align 4, addrspace(5) + %"573" = alloca float, align 4, addrspace(5) + %"574" = alloca float, align 4, addrspace(5) + %"575" = alloca float, align 4, addrspace(5) + %"576" = alloca float, align 4, addrspace(5) + %"577" = alloca float, align 4, addrspace(5) + %"578" = alloca float, align 4, addrspace(5) + %"579" = alloca float, align 4, addrspace(5) + %"580" = alloca float, align 4, addrspace(5) + %"581" = alloca float, align 4, addrspace(5) + %"582" = alloca float, align 4, addrspace(5) + %"583" = alloca float, align 4, addrspace(5) + %"584" = alloca float, align 4, addrspace(5) + %"585" = alloca float, align 4, addrspace(5) + %"586" = alloca float, align 4, addrspace(5) + %"587" = alloca float, align 4, addrspace(5) + %"588" = alloca float, align 4, addrspace(5) + %"589" = alloca float, align 4, addrspace(5) + %"590" = alloca float, align 4, addrspace(5) + %"591" = alloca float, align 4, addrspace(5) + %"592" = alloca float, align 4, addrspace(5) + %"593" = alloca float, align 4, addrspace(5) + %"594" = alloca float, align 4, addrspace(5) + %"595" = alloca float, align 4, addrspace(5) + %"596" = alloca float, align 4, addrspace(5) + %"597" = alloca float, align 4, addrspace(5) + %"598" = alloca float, align 4, addrspace(5) + %"599" = alloca float, align 4, addrspace(5) + %"600" = alloca float, align 4, addrspace(5) + %"601" = alloca float, align 4, addrspace(5) + %"602" = alloca float, align 4, addrspace(5) + %"603" = alloca float, align 4, addrspace(5) + %"604" = alloca float, align 4, addrspace(5) + %"605" = alloca float, align 4, addrspace(5) + %"606" = alloca float, align 4, addrspace(5) + %"607" = alloca float, align 4, addrspace(5) + %"608" = alloca float, align 4, addrspace(5) + %"609" = alloca float, align 4, addrspace(5) + %"610" = alloca float, align 4, addrspace(5) + %"611" = alloca float, align 4, addrspace(5) + %"612" = alloca float, align 4, addrspace(5) + %"613" = alloca float, align 4, addrspace(5) + %"614" = alloca float, align 4, addrspace(5) + %"615" = alloca float, align 4, addrspace(5) + %"616" = alloca float, align 4, addrspace(5) + %"617" = alloca float, align 4, addrspace(5) + %"618" = alloca float, align 4, addrspace(5) + %"619" = alloca float, align 4, addrspace(5) + %"620" = alloca float, align 4, addrspace(5) + %"621" = alloca float, align 4, addrspace(5) + %"622" = alloca float, align 4, addrspace(5) + %"623" = alloca float, align 4, addrspace(5) + %"624" = alloca float, align 4, addrspace(5) + %"625" = alloca float, align 4, addrspace(5) + %"626" = alloca float, align 4, addrspace(5) + %"627" = alloca float, align 4, addrspace(5) + %"628" = alloca float, align 4, addrspace(5) + %"629" = alloca float, align 4, addrspace(5) + %"630" = alloca float, align 4, addrspace(5) + %"631" = alloca float, align 4, addrspace(5) + %"632" = alloca float, align 4, addrspace(5) + %"633" = alloca float, align 4, addrspace(5) + %"634" = alloca float, align 4, addrspace(5) + %"635" = alloca float, align 4, addrspace(5) + %"636" = alloca float, align 4, addrspace(5) + %"637" = alloca float, align 4, addrspace(5) + %"638" = alloca float, align 4, addrspace(5) + %"639" = alloca float, align 4, addrspace(5) + %"640" = alloca float, align 4, addrspace(5) + %"641" = alloca float, align 4, addrspace(5) + %"642" = alloca float, align 4, addrspace(5) + %"643" = alloca float, align 4, addrspace(5) + %"644" = alloca float, align 4, addrspace(5) + %"645" = alloca float, align 4, addrspace(5) + %"646" = alloca float, align 4, addrspace(5) + %"647" = alloca float, align 4, addrspace(5) + %"648" = alloca float, align 4, addrspace(5) + %"649" = alloca float, align 4, addrspace(5) + %"650" = alloca float, align 4, addrspace(5) + %"651" = alloca float, align 4, addrspace(5) + %"652" = alloca float, align 4, addrspace(5) + %"653" = alloca float, align 4, addrspace(5) + %"654" = alloca float, align 4, addrspace(5) + %"655" = alloca float, align 4, addrspace(5) + %"656" = alloca float, align 4, addrspace(5) + %"657" = alloca float, align 4, addrspace(5) + %"658" = alloca float, align 4, addrspace(5) + %"659" = alloca float, align 4, addrspace(5) + %"660" = alloca float, align 4, addrspace(5) + %"661" = alloca float, align 4, addrspace(5) + %"662" = alloca float, align 4, addrspace(5) + %"663" = alloca float, align 4, addrspace(5) + %"664" = alloca i64, align 8, addrspace(5) + %"665" = alloca i64, align 8, addrspace(5) + %"666" = alloca i64, align 8, addrspace(5) + %"667" = alloca i64, align 8, addrspace(5) + %"668" = alloca i64, align 8, addrspace(5) + store i64 %"729", ptr addrspace(5) %"724", align 8 + store i64 %"730", ptr addrspace(5) %"725", align 8 + store i64 %"731", ptr addrspace(5) %"726", align 8 + %"732" = load i64, ptr addrspace(5) %"724", align 8 + store i64 %"732", ptr addrspace(5) %"1421", align 8 + %"733" = load i64, ptr addrspace(5) %"725", align 8 + store i64 %"733", ptr addrspace(5) %"1422", align 8 + %"734" = load i64, ptr addrspace(5) %"726", align 8 + store i64 %"734", ptr addrspace(5) %"1423", align 8 + %"1474" = load i64, ptr addrspace(5) %"1421", align 8 + store i64 %"1474", ptr addrspace(5) %"666", align 8 + %"1476" = load i64, ptr addrspace(5) %"1422", align 8 + store i64 %"1476", ptr addrspace(5) %"667", align 8 + %"1478" = load i64, ptr addrspace(5) %"1423", align 8 + store i64 %"1478", ptr addrspace(5) %"668", align 8 + %"739" = load i64, ptr addrspace(5) %"668", align 8 + %"1480" = inttoptr i64 %"739" to ptr + %"1508" = getelementptr inbounds i8, ptr %"1480", i64 36 + %"738" = load float, ptr %"1508", align 4 + store float %"738", ptr addrspace(5) %"448", align 4 + %"741" = load i64, ptr addrspace(5) %"667", align 8 + %"1481" = inttoptr i64 %"741" to ptr + %"1510" = getelementptr inbounds i8, ptr %"1481", i64 36 + %"740" = load float, ptr %"1510", align 4 + store float %"740", ptr addrspace(5) %"449", align 4 + %"743" = load i64, ptr addrspace(5) %"668", align 8 + %"1482" = inttoptr i64 %"743" to ptr + %"1512" = getelementptr inbounds i8, ptr %"1482", i64 40 + %"742" = load float, ptr %"1512", align 4 + store float %"742", ptr addrspace(5) %"450", align 4 + %"745" = load i64, ptr addrspace(5) %"667", align 8 + %"1483" = inttoptr i64 %"745" to ptr + %"1514" = getelementptr inbounds i8, ptr %"1483", i64 40 + %"744" = load float, ptr %"1514", align 4 + store float %"744", ptr addrspace(5) %"451", align 4 + %"747" = load float, ptr addrspace(5) %"451", align 4 + %"748" = load float, ptr addrspace(5) %"450", align 4 + %"746" = fmul float %"747", %"748" + store float %"746", ptr addrspace(5) %"497", align 4 + %"750" = load float, ptr addrspace(5) %"449", align 4 + %"751" = load float, ptr addrspace(5) %"448", align 4 + %"752" = load float, ptr addrspace(5) %"497", align 4 + %"749" = call float @llvm.fma.f32(float %"750", float %"751", float %"752") + store float %"749", ptr addrspace(5) %"498", align 4 + %"754" = load i64, ptr addrspace(5) %"668", align 8 + %"1484" = inttoptr i64 %"754" to ptr + %"1516" = getelementptr inbounds i8, ptr %"1484", i64 44 + %"753" = load float, ptr %"1516", align 4 + store float %"753", ptr addrspace(5) %"452", align 4 + %"756" = load i64, ptr addrspace(5) %"667", align 8 + %"1485" = inttoptr i64 %"756" to ptr + %"1518" = getelementptr inbounds i8, ptr %"1485", i64 44 + %"755" = load float, ptr %"1518", align 4 + store float %"755", ptr addrspace(5) %"453", align 4 + %"758" = load float, ptr addrspace(5) %"453", align 4 + %"759" = load float, ptr addrspace(5) %"452", align 4 + %"760" = load float, ptr addrspace(5) %"498", align 4 + %"757" = call float @llvm.fma.f32(float %"758", float %"759", float %"760") + store float %"757", ptr addrspace(5) %"454", align 4 + %"762" = load i64, ptr addrspace(5) %"668", align 8 + %"1486" = inttoptr i64 %"762" to ptr + %"1520" = getelementptr inbounds i8, ptr %"1486", i64 48 + %"761" = load float, ptr %"1520", align 4 + store float %"761", ptr addrspace(5) %"455", align 4 + %"764" = load i64, ptr addrspace(5) %"668", align 8 + %"1487" = inttoptr i64 %"764" to ptr + %"1522" = getelementptr inbounds i8, ptr %"1487", i64 52 + %"763" = load float, ptr %"1522", align 4 + store float %"763", ptr addrspace(5) %"456", align 4 + %"766" = load float, ptr addrspace(5) %"451", align 4 + %"767" = load float, ptr addrspace(5) %"456", align 4 + %"765" = fmul float %"766", %"767" + store float %"765", ptr addrspace(5) %"499", align 4 + %"769" = load float, ptr addrspace(5) %"449", align 4 + %"770" = load float, ptr addrspace(5) %"455", align 4 + %"771" = load float, ptr addrspace(5) %"499", align 4 + %"768" = call float @llvm.fma.f32(float %"769", float %"770", float %"771") + store float %"768", ptr addrspace(5) %"500", align 4 + %"773" = load i64, ptr addrspace(5) %"668", align 8 + %"1488" = inttoptr i64 %"773" to ptr + %"1524" = getelementptr inbounds i8, ptr %"1488", i64 56 + %"772" = load float, ptr %"1524", align 4 + store float %"772", ptr addrspace(5) %"457", align 4 + %"775" = load float, ptr addrspace(5) %"453", align 4 + %"776" = load float, ptr addrspace(5) %"457", align 4 + %"777" = load float, ptr addrspace(5) %"500", align 4 + %"774" = call float @llvm.fma.f32(float %"775", float %"776", float %"777") + store float %"774", ptr addrspace(5) %"458", align 4 + %"779" = load float, ptr addrspace(5) %"454", align 4 + %"778" = fcmp ole float %"779", 0.000000e+00 + store i1 %"778", ptr addrspace(5) %"442", align 1 + %"781" = load float, ptr addrspace(5) %"458", align 4 + %"780" = fcmp ole float %"781", 0.000000e+00 + store i1 %"780", ptr addrspace(5) %"443", align 1 + %"783" = load i1, ptr addrspace(5) %"443", align 1 + %"784" = load i1, ptr addrspace(5) %"442", align 1 + %"782" = or i1 %"783", %"784" + store i1 %"782", ptr addrspace(5) %"444", align 1 + %0 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %0, align 4 + %"785" = load float, ptr addrspace(5) %0, align 4 + store float %"785", ptr addrspace(5) %"661", align 4 + %"787" = load float, ptr addrspace(5) %"661", align 4 + %1 = alloca float, align 4, addrspace(5) + store float %"787", ptr addrspace(5) %1, align 4 + %"786" = load float, ptr addrspace(5) %1, align 4 + store float %"786", ptr addrspace(5) %"662", align 4 + %"789" = load float, ptr addrspace(5) %"661", align 4 + %2 = alloca float, align 4, addrspace(5) + store float %"789", ptr addrspace(5) %2, align 4 + %"788" = load float, ptr addrspace(5) %2, align 4 + store float %"788", ptr addrspace(5) %"663", align 4 + %"790" = load i1, ptr addrspace(5) %"444", align 1 + br i1 %"790", label %"440", label %"670" + +"670": ; preds = %"1506" + %"792" = load float, ptr addrspace(5) %"455", align 4 + %"793" = load float, ptr addrspace(5) %"448", align 4 + %"791" = fadd float %"792", %"793" + store float %"791", ptr addrspace(5) %"504", align 4 + %"795" = load float, ptr addrspace(5) %"456", align 4 + %"796" = load float, ptr addrspace(5) %"450", align 4 + %"794" = fadd float %"795", %"796" + store float %"794", ptr addrspace(5) %"505", align 4 + %"798" = load float, ptr addrspace(5) %"505", align 4 + %"799" = load float, ptr addrspace(5) %"505", align 4 + %"797" = fmul float %"798", %"799" + store float %"797", ptr addrspace(5) %"506", align 4 + %"801" = load float, ptr addrspace(5) %"504", align 4 + %"802" = load float, ptr addrspace(5) %"504", align 4 + %"803" = load float, ptr addrspace(5) %"506", align 4 + %"800" = call float @llvm.fma.f32(float %"801", float %"802", float %"803") + store float %"800", ptr addrspace(5) %"507", align 4 + %"805" = load float, ptr addrspace(5) %"457", align 4 + %"806" = load float, ptr addrspace(5) %"452", align 4 + %"804" = fadd float %"805", %"806" + store float %"804", ptr addrspace(5) %"508", align 4 + %"808" = load float, ptr addrspace(5) %"508", align 4 + %"809" = load float, ptr addrspace(5) %"508", align 4 + %"810" = load float, ptr addrspace(5) %"507", align 4 + %"807" = call float @llvm.fma.f32(float %"808", float %"809", float %"810") + store float %"807", ptr addrspace(5) %"509", align 4 + %"812" = load float, ptr addrspace(5) %"509", align 4 + %3 = call afn float @llvm.sqrt.f32(float %"812") + %"811" = fdiv arcp afn float 1.000000e+00, %3 + store float %"811", ptr addrspace(5) %"510", align 4 + %"814" = load float, ptr addrspace(5) %"504", align 4 + %"815" = load float, ptr addrspace(5) %"510", align 4 + %"813" = fmul float %"814", %"815" + store float %"813", ptr addrspace(5) %"511", align 4 + %"817" = load float, ptr addrspace(5) %"505", align 4 + %"818" = load float, ptr addrspace(5) %"510", align 4 + %"816" = fmul float %"817", %"818" + store float %"816", ptr addrspace(5) %"512", align 4 + %"820" = load float, ptr addrspace(5) %"508", align 4 + %"821" = load float, ptr addrspace(5) %"510", align 4 + %"819" = fmul float %"820", %"821" + store float %"819", ptr addrspace(5) %"513", align 4 + %"823" = load float, ptr addrspace(5) %"451", align 4 + %"824" = load float, ptr addrspace(5) %"512", align 4 + %"822" = fmul float %"823", %"824" + store float %"822", ptr addrspace(5) %"514", align 4 + %"826" = load float, ptr addrspace(5) %"449", align 4 + %"827" = load float, ptr addrspace(5) %"511", align 4 + %"828" = load float, ptr addrspace(5) %"514", align 4 + %"825" = call float @llvm.fma.f32(float %"826", float %"827", float %"828") + store float %"825", ptr addrspace(5) %"515", align 4 + %"830" = load float, ptr addrspace(5) %"453", align 4 + %"831" = load float, ptr addrspace(5) %"513", align 4 + %"832" = load float, ptr addrspace(5) %"515", align 4 + %"829" = call float @llvm.fma.f32(float %"830", float %"831", float %"832") + store float %"829", ptr addrspace(5) %"459", align 4 + %"834" = load float, ptr addrspace(5) %"450", align 4 + %"835" = load float, ptr addrspace(5) %"512", align 4 + %"833" = fmul float %"834", %"835" + store float %"833", ptr addrspace(5) %"516", align 4 + %"837" = load float, ptr addrspace(5) %"448", align 4 + %"838" = load float, ptr addrspace(5) %"511", align 4 + %"839" = load float, ptr addrspace(5) %"516", align 4 + %"836" = call float @llvm.fma.f32(float %"837", float %"838", float %"839") + store float %"836", ptr addrspace(5) %"517", align 4 + %"841" = load float, ptr addrspace(5) %"452", align 4 + %"842" = load float, ptr addrspace(5) %"513", align 4 + %"843" = load float, ptr addrspace(5) %"517", align 4 + %"840" = call float @llvm.fma.f32(float %"841", float %"842", float %"843") + store float %"840", ptr addrspace(5) %"460", align 4 + %"845" = load i64, ptr addrspace(5) %"666", align 8 + %"1489" = add i64 %"845", 4 + store i64 %"1489", ptr addrspace(5) %"665", align 8 + %"847" = load i64, ptr addrspace(5) %"666", align 8 + %"1491" = inttoptr i64 %"847" to ptr + %"1526" = getelementptr inbounds i8, ptr %"1491", i64 4 + %"846" = load float, ptr %"1526", align 4 + store float %"846", ptr addrspace(5) %"461", align 4 + %"849" = load i64, ptr addrspace(5) %"666", align 8 + %"1492" = inttoptr i64 %"849" to ptr + %"1528" = getelementptr inbounds i8, ptr %"1492", i64 8 + %"848" = load float, ptr %"1528", align 4 + store float %"848", ptr addrspace(5) %"462", align 4 + %"851" = load float, ptr addrspace(5) %"462", align 4 + %"850" = fmul float %"851", 0x3FE3333340000000 + store float %"850", ptr addrspace(5) %"518", align 4 + %"853" = load float, ptr addrspace(5) %"461", align 4 + %"854" = load float, ptr addrspace(5) %"518", align 4 + %"852" = call float @llvm.fma.f32(float %"853", float 0x3FD3333340000000, float %"854") + store float %"852", ptr addrspace(5) %"519", align 4 + %"856" = load i64, ptr addrspace(5) %"666", align 8 + %"1493" = inttoptr i64 %"856" to ptr + %"1530" = getelementptr inbounds i8, ptr %"1493", i64 12 + %"855" = load float, ptr %"1530", align 4 + store float %"855", ptr addrspace(5) %"463", align 4 + %"858" = load float, ptr addrspace(5) %"463", align 4 + %"859" = load float, ptr addrspace(5) %"519", align 4 + %"857" = call float @llvm.fma.f32(float %"858", float 0x3FB99999A0000000, float %"859") + store float %"857", ptr addrspace(5) %"464", align 4 + %"861" = load float, ptr addrspace(5) %"464", align 4 + %"860" = fcmp ule float %"861", 0.000000e+00 + store i1 %"860", ptr addrspace(5) %"445", align 1 + %4 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %4, align 4 + %"862" = load float, ptr addrspace(5) %4, align 4 + store float %"862", ptr addrspace(5) %"503", align 4 + %"864" = load float, ptr addrspace(5) %"503", align 4 + %5 = alloca float, align 4, addrspace(5) + store float %"864", ptr addrspace(5) %5, align 4 + %"863" = load float, ptr addrspace(5) %5, align 4 + store float %"863", ptr addrspace(5) %"657", align 4 + %"866" = load float, ptr addrspace(5) %"503", align 4 + %6 = alloca float, align 4, addrspace(5) + store float %"866", ptr addrspace(5) %6, align 4 + %"865" = load float, ptr addrspace(5) %6, align 4 + store float %"865", ptr addrspace(5) %"658", align 4 + %"868" = load float, ptr addrspace(5) %"503", align 4 + %7 = alloca float, align 4, addrspace(5) + store float %"868", ptr addrspace(5) %7, align 4 + %"867" = load float, ptr addrspace(5) %7, align 4 + store float %"867", ptr addrspace(5) %"659", align 4 + %"869" = load i1, ptr addrspace(5) %"445", align 1 + br i1 %"869", label %"438", label %"672" + +"672": ; preds = %"670" + %"871" = load float, ptr addrspace(5) %"464", align 4 + %"870" = fdiv arcp afn float 1.000000e+00, %"871" + store float %"870", ptr addrspace(5) %"520", align 4 + %"873" = load float, ptr addrspace(5) %"461", align 4 + %"874" = load float, ptr addrspace(5) %"520", align 4 + %"872" = call float @llvm.fma.f32(float %"873", float %"874", float -1.000000e+00) + store float %"872", ptr addrspace(5) %"657", align 4 + %"876" = load float, ptr addrspace(5) %"462", align 4 + %"877" = load float, ptr addrspace(5) %"520", align 4 + %"875" = call float @llvm.fma.f32(float %"876", float %"877", float -1.000000e+00) + store float %"875", ptr addrspace(5) %"658", align 4 + %"879" = load float, ptr addrspace(5) %"463", align 4 + %"880" = load float, ptr addrspace(5) %"520", align 4 + %"878" = call float @llvm.fma.f32(float %"879", float %"880", float -1.000000e+00) + store float %"878", ptr addrspace(5) %"659", align 4 + br label %"438" + +"438": ; preds = %"672", %"670" + %"882" = load i64, ptr addrspace(5) %"665", align 8 + %"1494" = inttoptr i64 %"882" to ptr + %"1532" = getelementptr inbounds i8, ptr %"1494", i64 32 + %"881" = load float, ptr %"1532", align 4 + store float %"881", ptr addrspace(5) %"522", align 4 + %"884" = load float, ptr addrspace(5) %"522", align 4 + %"883" = fmul float %"884", 0x3FB47AE140000000 + store float %"883", ptr addrspace(5) %"523", align 4 + %"886" = load i64, ptr addrspace(5) %"665", align 8 + %"1495" = inttoptr i64 %"886" to ptr + %"1534" = getelementptr inbounds i8, ptr %"1495", i64 40 + %"885" = load float, ptr %"1534", align 4 + store float %"885", ptr addrspace(5) %"524", align 4 + %"888" = load float, ptr addrspace(5) %"657", align 4 + %"889" = load float, ptr addrspace(5) %"524", align 4 + %"887" = call float @llvm.fma.f32(float %"888", float %"889", float 1.000000e+00) + store float %"887", ptr addrspace(5) %"525", align 4 + %8 = alloca float, align 4, addrspace(5) + store float 1.000000e+00, ptr addrspace(5) %8, align 4 + %"890" = load float, ptr addrspace(5) %8, align 4 + store float %"890", ptr addrspace(5) %"526", align 4 + %"892" = load float, ptr addrspace(5) %"658", align 4 + %"893" = load float, ptr addrspace(5) %"524", align 4 + %"891" = call float @llvm.fma.f32(float %"892", float %"893", float 1.000000e+00) + store float %"891", ptr addrspace(5) %"527", align 4 + %"895" = load float, ptr addrspace(5) %"659", align 4 + %"896" = load float, ptr addrspace(5) %"524", align 4 + %"894" = call float @llvm.fma.f32(float %"895", float %"896", float 1.000000e+00) + store float %"894", ptr addrspace(5) %"528", align 4 + %"898" = load float, ptr addrspace(5) %"523", align 4 + %"899" = load float, ptr addrspace(5) %"525", align 4 + %"897" = fmul float %"898", %"899" + store float %"897", ptr addrspace(5) %"529", align 4 + %"901" = load float, ptr addrspace(5) %"523", align 4 + %"902" = load float, ptr addrspace(5) %"527", align 4 + %"900" = fmul float %"901", %"902" + store float %"900", ptr addrspace(5) %"530", align 4 + %"904" = load float, ptr addrspace(5) %"523", align 4 + %"905" = load float, ptr addrspace(5) %"528", align 4 + %"903" = fmul float %"904", %"905" + store float %"903", ptr addrspace(5) %"531", align 4 + %"907" = load float, ptr addrspace(5) %"461", align 4 + %"908" = load float, ptr addrspace(5) %"529", align 4 + %"906" = fsub float %"907", %"908" + store float %"906", ptr addrspace(5) %"532", align 4 + %"910" = load float, ptr addrspace(5) %"462", align 4 + %"911" = load float, ptr addrspace(5) %"530", align 4 + %"909" = fsub float %"910", %"911" + store float %"909", ptr addrspace(5) %"533", align 4 + %"913" = load float, ptr addrspace(5) %"463", align 4 + %"914" = load float, ptr addrspace(5) %"531", align 4 + %"912" = fsub float %"913", %"914" + store float %"912", ptr addrspace(5) %"534", align 4 + %"916" = load i64, ptr addrspace(5) %"665", align 8 + %"1496" = inttoptr i64 %"916" to ptr + %"1536" = getelementptr inbounds i8, ptr %"1496", i64 24 + %"915" = load float, ptr %"1536", align 4 + store float %"915", ptr addrspace(5) %"471", align 4 + %"918" = load float, ptr addrspace(5) %"471", align 4 + %"919" = load float, ptr addrspace(5) %"532", align 4 + %"920" = load float, ptr addrspace(5) %"529", align 4 + %"917" = call float @llvm.fma.f32(float %"918", float %"919", float %"920") + store float %"917", ptr addrspace(5) %"535", align 4 + %"922" = load float, ptr addrspace(5) %"471", align 4 + %"923" = load float, ptr addrspace(5) %"533", align 4 + %"924" = load float, ptr addrspace(5) %"530", align 4 + %"921" = call float @llvm.fma.f32(float %"922", float %"923", float %"924") + store float %"921", ptr addrspace(5) %"536", align 4 + %"926" = load float, ptr addrspace(5) %"471", align 4 + %"927" = load float, ptr addrspace(5) %"534", align 4 + %"928" = load float, ptr addrspace(5) %"531", align 4 + %"925" = call float @llvm.fma.f32(float %"926", float %"927", float %"928") + store float %"925", ptr addrspace(5) %"537", align 4 + %"930" = load i64, ptr addrspace(5) %"665", align 8 + %"1497" = inttoptr i64 %"930" to ptr + %"1538" = getelementptr inbounds i8, ptr %"1497", i64 52 + %"929" = load float, ptr %"1538", align 4 + store float %"929", ptr addrspace(5) %"538", align 4 + %"932" = load float, ptr addrspace(5) %"657", align 4 + %"933" = load float, ptr addrspace(5) %"538", align 4 + %"931" = call float @llvm.fma.f32(float %"932", float %"933", float 1.000000e+00) + store float %"931", ptr addrspace(5) %"539", align 4 + %"935" = load float, ptr addrspace(5) %"658", align 4 + %"936" = load float, ptr addrspace(5) %"538", align 4 + %"934" = call float @llvm.fma.f32(float %"935", float %"936", float 1.000000e+00) + store float %"934", ptr addrspace(5) %"540", align 4 + %"938" = load float, ptr addrspace(5) %"659", align 4 + %"939" = load float, ptr addrspace(5) %"538", align 4 + %"937" = call float @llvm.fma.f32(float %"938", float %"939", float 1.000000e+00) + store float %"937", ptr addrspace(5) %"541", align 4 + %"941" = load float, ptr addrspace(5) %"526", align 4 + %"942" = load float, ptr addrspace(5) %"454", align 4 + %"940" = fsub float %"941", %"942" + store float %"940", ptr addrspace(5) %"542", align 4 + %"944" = load float, ptr addrspace(5) %"542", align 4 + %"945" = load float, ptr addrspace(5) %"526", align 4 + %"943" = call float @llvm.minnum.f32(float %"944", float %"945") + store float %"943", ptr addrspace(5) %"543", align 4 + %"947" = load float, ptr addrspace(5) %"503", align 4 + %"948" = load float, ptr addrspace(5) %"543", align 4 + %"946" = call float @llvm.maxnum.f32(float %"947", float %"948") + store float %"946", ptr addrspace(5) %"545", align 4 + %"950" = load float, ptr addrspace(5) %"545", align 4 + %"951" = load float, ptr addrspace(5) %"545", align 4 + %"949" = fmul float %"950", %"951" + store float %"949", ptr addrspace(5) %"546", align 4 + %"953" = load float, ptr addrspace(5) %"546", align 4 + %"954" = load float, ptr addrspace(5) %"546", align 4 + %"952" = fmul float %"953", %"954" + store float %"952", ptr addrspace(5) %"547", align 4 + %"956" = load float, ptr addrspace(5) %"545", align 4 + %"957" = load float, ptr addrspace(5) %"547", align 4 + %"955" = fmul float %"956", %"957" + store float %"955", ptr addrspace(5) %"548", align 4 + %"959" = load float, ptr addrspace(5) %"526", align 4 + %"960" = load float, ptr addrspace(5) %"458", align 4 + %"958" = fsub float %"959", %"960" + store float %"958", ptr addrspace(5) %"549", align 4 + %"962" = load float, ptr addrspace(5) %"549", align 4 + %"963" = load float, ptr addrspace(5) %"526", align 4 + %"961" = call float @llvm.minnum.f32(float %"962", float %"963") + store float %"961", ptr addrspace(5) %"550", align 4 + %"965" = load float, ptr addrspace(5) %"503", align 4 + %"966" = load float, ptr addrspace(5) %"550", align 4 + %"964" = call float @llvm.maxnum.f32(float %"965", float %"966") + store float %"964", ptr addrspace(5) %"551", align 4 + %"968" = load float, ptr addrspace(5) %"551", align 4 + %"969" = load float, ptr addrspace(5) %"551", align 4 + %"967" = fmul float %"968", %"969" + store float %"967", ptr addrspace(5) %"552", align 4 + %"971" = load float, ptr addrspace(5) %"552", align 4 + %"972" = load float, ptr addrspace(5) %"552", align 4 + %"970" = fmul float %"971", %"972" + store float %"970", ptr addrspace(5) %"553", align 4 + %"974" = load float, ptr addrspace(5) %"551", align 4 + %"975" = load float, ptr addrspace(5) %"553", align 4 + %"973" = fmul float %"974", %"975" + store float %"973", ptr addrspace(5) %"554", align 4 + %"977" = load float, ptr addrspace(5) %"460", align 4 + %"978" = load float, ptr addrspace(5) %"460", align 4 + %"976" = fadd float %"977", %"978" + store float %"976", ptr addrspace(5) %"555", align 4 + %"980" = load float, ptr addrspace(5) %"460", align 4 + %"981" = load float, ptr addrspace(5) %"555", align 4 + %"979" = fmul float %"980", %"981" + store float %"979", ptr addrspace(5) %"556", align 4 + %"983" = load i64, ptr addrspace(5) %"665", align 8 + %"1498" = inttoptr i64 %"983" to ptr + %"1540" = getelementptr inbounds i8, ptr %"1498", i64 36 + %"982" = load float, ptr %"1540", align 4 + store float %"982", ptr addrspace(5) %"557", align 4 + %"985" = load float, ptr addrspace(5) %"556", align 4 + %"986" = load float, ptr addrspace(5) %"557", align 4 + %"984" = call float @llvm.fma.f32(float %"985", float %"986", float 5.000000e-01) + store float %"984", ptr addrspace(5) %"558", align 4 + %"988" = load float, ptr addrspace(5) %"558", align 4 + %"987" = fadd float %"988", -1.000000e+00 + store float %"987", ptr addrspace(5) %"559", align 4 + %"990" = load float, ptr addrspace(5) %"548", align 4 + %"991" = load float, ptr addrspace(5) %"559", align 4 + %"989" = call float @llvm.fma.f32(float %"990", float %"991", float 1.000000e+00) + store float %"989", ptr addrspace(5) %"560", align 4 + %"993" = load float, ptr addrspace(5) %"554", align 4 + %"994" = load float, ptr addrspace(5) %"559", align 4 + %"992" = call float @llvm.fma.f32(float %"993", float %"994", float 1.000000e+00) + store float %"992", ptr addrspace(5) %"561", align 4 + %"996" = load float, ptr addrspace(5) %"560", align 4 + %"997" = load float, ptr addrspace(5) %"561", align 4 + %"995" = fmul float %"996", %"997" + store float %"995", ptr addrspace(5) %"472", align 4 + %"999" = load float, ptr addrspace(5) %"460", align 4 + %"1000" = load float, ptr addrspace(5) %"460", align 4 + %"998" = fmul float %"999", %"1000" + store float %"998", ptr addrspace(5) %"562", align 4 + %"1002" = load float, ptr addrspace(5) %"562", align 4 + %"1003" = load float, ptr addrspace(5) %"557", align 4 + %"1001" = call float @llvm.fma.f32(float %"1002", float %"1003", float -1.000000e+00) + store float %"1001", ptr addrspace(5) %"563", align 4 + %"1005" = load float, ptr addrspace(5) %"548", align 4 + %"1006" = load float, ptr addrspace(5) %"563", align 4 + %"1004" = call float @llvm.fma.f32(float %"1005", float %"1006", float 1.000000e+00) + store float %"1004", ptr addrspace(5) %"564", align 4 + %"1008" = load float, ptr addrspace(5) %"554", align 4 + %"1009" = load float, ptr addrspace(5) %"563", align 4 + %"1007" = call float @llvm.fma.f32(float %"1008", float %"1009", float 1.000000e+00) + store float %"1007", ptr addrspace(5) %"565", align 4 + %"1011" = load float, ptr addrspace(5) %"564", align 4 + %"1012" = load float, ptr addrspace(5) %"565", align 4 + %"1010" = fmul float %"1011", %"1012" + store float %"1010", ptr addrspace(5) %"566", align 4 + %"1014" = load float, ptr addrspace(5) %"458", align 4 + %"1015" = load float, ptr addrspace(5) %"454", align 4 + %"1013" = fadd float %"1014", %"1015" + store float %"1013", ptr addrspace(5) %"567", align 4 + %"1017" = load float, ptr addrspace(5) %"567", align 4 + %"1016" = fdiv arcp afn float 1.000000e+00, %"1017" + store float %"1016", ptr addrspace(5) %"568", align 4 + %"1019" = load float, ptr addrspace(5) %"568", align 4 + %"1018" = fadd float %"1019", -5.000000e-01 + store float %"1018", ptr addrspace(5) %"569", align 4 + %"1021" = load float, ptr addrspace(5) %"569", align 4 + %"1022" = load float, ptr addrspace(5) %"566", align 4 + %"1020" = call float @llvm.fma.f32(float %"1021", float %"1022", float 5.000000e-01) + store float %"1020", ptr addrspace(5) %"570", align 4 + %"1024" = load float, ptr addrspace(5) %"570", align 4 + %"1023" = fmul float %"1024", 1.250000e+00 + store float %"1023", ptr addrspace(5) %"473", align 4 + %9 = alloca float, align 4, addrspace(5) + store float 0x3F50624DE0000000, ptr addrspace(5) %9, align 4 + %"1025" = load float, ptr addrspace(5) %9, align 4 + store float %"1025", ptr addrspace(5) %"571", align 4 + %"1027" = load float, ptr addrspace(5) %"571", align 4 + %"1028" = load float, ptr addrspace(5) %"557", align 4 + %"1026" = call float @llvm.maxnum.f32(float %"1027", float %"1028") + store float %"1026", ptr addrspace(5) %"572", align 4 + %"1030" = load float, ptr addrspace(5) %"572", align 4 + %"1031" = load float, ptr addrspace(5) %"572", align 4 + %"1029" = fmul float %"1030", %"1031" + store float %"1029", ptr addrspace(5) %"573", align 4 + %"1033" = load float, ptr addrspace(5) %"573", align 4 + %"1032" = fadd float %"1033", -1.000000e+00 + store float %"1032", ptr addrspace(5) %"574", align 4 + %"1035" = load float, ptr addrspace(5) %"459", align 4 + %"1036" = load float, ptr addrspace(5) %"574", align 4 + %"1034" = fmul float %"1035", %"1036" + store float %"1034", ptr addrspace(5) %"575", align 4 + %"1038" = load float, ptr addrspace(5) %"459", align 4 + %"1039" = load float, ptr addrspace(5) %"575", align 4 + %"1037" = call float @llvm.fma.f32(float %"1038", float %"1039", float 1.000000e+00) + store float %"1037", ptr addrspace(5) %"576", align 4 + %"1041" = load float, ptr addrspace(5) %"576", align 4 + %"1040" = fmul float %"1041", 0x400921FB60000000 + store float %"1040", ptr addrspace(5) %"577", align 4 + %"1043" = load float, ptr addrspace(5) %"576", align 4 + %"1044" = load float, ptr addrspace(5) %"577", align 4 + %"1042" = fmul float %"1043", %"1044" + store float %"1042", ptr addrspace(5) %"578", align 4 + %"1046" = load float, ptr addrspace(5) %"573", align 4 + %"1047" = load float, ptr addrspace(5) %"578", align 4 + %"1045" = fdiv arcp afn float %"1046", %"1047" + store float %"1045", ptr addrspace(5) %"474", align 4 + %"1049" = load float, ptr addrspace(5) %"526", align 4 + %"1050" = load float, ptr addrspace(5) %"460", align 4 + %"1048" = fsub float %"1049", %"1050" + store float %"1048", ptr addrspace(5) %"579", align 4 + %"1052" = load float, ptr addrspace(5) %"579", align 4 + %"1053" = load float, ptr addrspace(5) %"526", align 4 + %"1051" = call float @llvm.minnum.f32(float %"1052", float %"1053") + store float %"1051", ptr addrspace(5) %"580", align 4 + %"1055" = load float, ptr addrspace(5) %"503", align 4 + %"1056" = load float, ptr addrspace(5) %"580", align 4 + %"1054" = call float @llvm.maxnum.f32(float %"1055", float %"1056") + store float %"1054", ptr addrspace(5) %"581", align 4 + %"1058" = load float, ptr addrspace(5) %"581", align 4 + %"1059" = load float, ptr addrspace(5) %"581", align 4 + %"1057" = fmul float %"1058", %"1059" + store float %"1057", ptr addrspace(5) %"582", align 4 + %"1061" = load float, ptr addrspace(5) %"582", align 4 + %"1062" = load float, ptr addrspace(5) %"582", align 4 + %"1060" = fmul float %"1061", %"1062" + store float %"1060", ptr addrspace(5) %"583", align 4 + %"1064" = load float, ptr addrspace(5) %"581", align 4 + %"1065" = load float, ptr addrspace(5) %"583", align 4 + %"1063" = fmul float %"1064", %"1065" + store float %"1063", ptr addrspace(5) %"475", align 4 + %"1067" = load float, ptr addrspace(5) %"526", align 4 + %"1068" = load float, ptr addrspace(5) %"535", align 4 + %"1066" = fsub float %"1067", %"1068" + store float %"1066", ptr addrspace(5) %"584", align 4 + %"1070" = load float, ptr addrspace(5) %"526", align 4 + %"1071" = load float, ptr addrspace(5) %"536", align 4 + %"1069" = fsub float %"1070", %"1071" + store float %"1069", ptr addrspace(5) %"585", align 4 + %"1073" = load float, ptr addrspace(5) %"526", align 4 + %"1074" = load float, ptr addrspace(5) %"537", align 4 + %"1072" = fsub float %"1073", %"1074" + store float %"1072", ptr addrspace(5) %"586", align 4 + %"1076" = load float, ptr addrspace(5) %"584", align 4 + %"1077" = load float, ptr addrspace(5) %"475", align 4 + %"1078" = load float, ptr addrspace(5) %"535", align 4 + %"1075" = call float @llvm.fma.f32(float %"1076", float %"1077", float %"1078") + store float %"1075", ptr addrspace(5) %"476", align 4 + %"1080" = load float, ptr addrspace(5) %"585", align 4 + %"1081" = load float, ptr addrspace(5) %"475", align 4 + %"1082" = load float, ptr addrspace(5) %"536", align 4 + %"1079" = call float @llvm.fma.f32(float %"1080", float %"1081", float %"1082") + store float %"1079", ptr addrspace(5) %"477", align 4 + %"1084" = load float, ptr addrspace(5) %"586", align 4 + %"1085" = load float, ptr addrspace(5) %"475", align 4 + %"1086" = load float, ptr addrspace(5) %"537", align 4 + %"1083" = call float @llvm.fma.f32(float %"1084", float %"1085", float %"1086") + store float %"1083", ptr addrspace(5) %"478", align 4 + %"1088" = load float, ptr addrspace(5) %"557", align 4 + %"1087" = call float @llvm.fma.f32(float %"1088", float 5.000000e-01, float 5.000000e-01) + store float %"1087", ptr addrspace(5) %"587", align 4 + %"1090" = load float, ptr addrspace(5) %"587", align 4 + %"1091" = load float, ptr addrspace(5) %"587", align 4 + %"1089" = fmul float %"1090", %"1091" + store float %"1089", ptr addrspace(5) %"588", align 4 + %"1093" = load float, ptr addrspace(5) %"588", align 4 + %"1094" = load float, ptr addrspace(5) %"588", align 4 + %"1092" = fmul float %"1093", %"1094" + store float %"1092", ptr addrspace(5) %"589", align 4 + %"1096" = load float, ptr addrspace(5) %"454", align 4 + %"1097" = load float, ptr addrspace(5) %"454", align 4 + %"1095" = fmul float %"1096", %"1097" + store float %"1095", ptr addrspace(5) %"479", align 4 + %"1099" = load float, ptr addrspace(5) %"479", align 4 + %"1100" = load float, ptr addrspace(5) %"589", align 4 + %"1098" = fadd float %"1099", %"1100" + store float %"1098", ptr addrspace(5) %"590", align 4 + %"1102" = load float, ptr addrspace(5) %"479", align 4 + %"1103" = load float, ptr addrspace(5) %"589", align 4 + %"1101" = fmul float %"1102", %"1103" + store float %"1101", ptr addrspace(5) %"591", align 4 + %"1105" = load float, ptr addrspace(5) %"590", align 4 + %"1106" = load float, ptr addrspace(5) %"591", align 4 + %"1104" = fsub float %"1105", %"1106" + store float %"1104", ptr addrspace(5) %"592", align 4 + %"1108" = load float, ptr addrspace(5) %"592", align 4 + %"1107" = call afn float @llvm.sqrt.f32(float %"1108") + store float %"1107", ptr addrspace(5) %"593", align 4 + %"1110" = load float, ptr addrspace(5) %"454", align 4 + %"1111" = load float, ptr addrspace(5) %"593", align 4 + %"1109" = fadd float %"1110", %"1111" + store float %"1109", ptr addrspace(5) %"594", align 4 + %"1113" = load float, ptr addrspace(5) %"594", align 4 + %"1112" = fdiv arcp afn float 1.000000e+00, %"1113" + store float %"1112", ptr addrspace(5) %"595", align 4 + %"1115" = load float, ptr addrspace(5) %"458", align 4 + %"1116" = load float, ptr addrspace(5) %"458", align 4 + %"1114" = fmul float %"1115", %"1116" + store float %"1114", ptr addrspace(5) %"480", align 4 + %"1118" = load float, ptr addrspace(5) %"480", align 4 + %"1119" = load float, ptr addrspace(5) %"589", align 4 + %"1117" = fadd float %"1118", %"1119" + store float %"1117", ptr addrspace(5) %"596", align 4 + %"1121" = load float, ptr addrspace(5) %"480", align 4 + %"1122" = load float, ptr addrspace(5) %"589", align 4 + %"1120" = fmul float %"1121", %"1122" + store float %"1120", ptr addrspace(5) %"597", align 4 + %"1124" = load float, ptr addrspace(5) %"596", align 4 + %"1125" = load float, ptr addrspace(5) %"597", align 4 + %"1123" = fsub float %"1124", %"1125" + store float %"1123", ptr addrspace(5) %"598", align 4 + %"1127" = load float, ptr addrspace(5) %"598", align 4 + %"1126" = call afn float @llvm.sqrt.f32(float %"1127") + store float %"1126", ptr addrspace(5) %"599", align 4 + %"1129" = load float, ptr addrspace(5) %"458", align 4 + %"1130" = load float, ptr addrspace(5) %"599", align 4 + %"1128" = fadd float %"1129", %"1130" + store float %"1128", ptr addrspace(5) %"600", align 4 + %"1132" = load float, ptr addrspace(5) %"600", align 4 + %"1131" = fdiv arcp afn float 1.000000e+00, %"1132" + store float %"1131", ptr addrspace(5) %"601", align 4 + %"1134" = load float, ptr addrspace(5) %"595", align 4 + %"1135" = load float, ptr addrspace(5) %"601", align 4 + %"1133" = fmul float %"1134", %"1135" + store float %"1133", ptr addrspace(5) %"481", align 4 + %"1137" = load i64, ptr addrspace(5) %"665", align 8 + %"1499" = inttoptr i64 %"1137" to ptr + %"1542" = getelementptr inbounds i8, ptr %"1499", i64 48 + %"1136" = load float, ptr %"1542", align 4 + store float %"1136", ptr addrspace(5) %"602", align 4 + %"1139" = load float, ptr addrspace(5) %"475", align 4 + %"1140" = load float, ptr addrspace(5) %"602", align 4 + %"1138" = fmul float %"1139", %"1140" + store float %"1138", ptr addrspace(5) %"603", align 4 + %"1142" = load float, ptr addrspace(5) %"539", align 4 + %"1143" = load float, ptr addrspace(5) %"603", align 4 + %"1141" = fmul float %"1142", %"1143" + store float %"1141", ptr addrspace(5) %"482", align 4 + %"1145" = load float, ptr addrspace(5) %"540", align 4 + %"1146" = load float, ptr addrspace(5) %"603", align 4 + %"1144" = fmul float %"1145", %"1146" + store float %"1144", ptr addrspace(5) %"483", align 4 + %"1148" = load float, ptr addrspace(5) %"541", align 4 + %"1149" = load float, ptr addrspace(5) %"603", align 4 + %"1147" = fmul float %"1148", %"1149" + store float %"1147", ptr addrspace(5) %"484", align 4 + %"1151" = load i64, ptr addrspace(5) %"665", align 8 + %"1500" = inttoptr i64 %"1151" to ptr + %"1544" = getelementptr inbounds i8, ptr %"1500", i64 60 + %"1150" = load float, ptr %"1544", align 4 + store float %"1150", ptr addrspace(5) %"604", align 4 + %"1153" = load float, ptr addrspace(5) %"571", align 4 + %"1152" = fsub float %"1153", 0x3FB99999A0000000 + store float %"1152", ptr addrspace(5) %"605", align 4 + %"1155" = load float, ptr addrspace(5) %"604", align 4 + %"1156" = load float, ptr addrspace(5) %"605", align 4 + %"1154" = call float @llvm.fma.f32(float %"1155", float %"1156", float 0x3FB99999A0000000) + store float %"1154", ptr addrspace(5) %"485", align 4 + %"1158" = load float, ptr addrspace(5) %"485", align 4 + %"1157" = fcmp oge float %"1158", 1.000000e+00 + store i1 %"1157", ptr addrspace(5) %"446", align 1 + %10 = alloca float, align 4, addrspace(5) + store float 0x3FD45F3060000000, ptr addrspace(5) %10, align 4 + %"1159" = load float, ptr addrspace(5) %10, align 4 + store float %"1159", ptr addrspace(5) %"660", align 4 + %"1160" = load i1, ptr addrspace(5) %"446", align 1 + br i1 %"1160", label %"439", label %"674" + +"674": ; preds = %"438" + %"1162" = load float, ptr addrspace(5) %"485", align 4 + %"1163" = load float, ptr addrspace(5) %"485", align 4 + %"1161" = fmul float %"1162", %"1163" + store float %"1161", ptr addrspace(5) %"606", align 4 + %"1165" = load float, ptr addrspace(5) %"606", align 4 + %"1164" = fadd float %"1165", -1.000000e+00 + store float %"1164", ptr addrspace(5) %"607", align 4 + %"1167" = load float, ptr addrspace(5) %"459", align 4 + %"1168" = load float, ptr addrspace(5) %"607", align 4 + %"1166" = fmul float %"1167", %"1168" + store float %"1166", ptr addrspace(5) %"608", align 4 + %"1170" = load float, ptr addrspace(5) %"459", align 4 + %"1171" = load float, ptr addrspace(5) %"608", align 4 + %"1169" = call float @llvm.fma.f32(float %"1170", float %"1171", float 1.000000e+00) + store float %"1169", ptr addrspace(5) %"609", align 4 + %"1173" = load float, ptr addrspace(5) %"606", align 4 + %"1172" = call afn float @llvm.log2.f32(float %"1173") + store float %"1172", ptr addrspace(5) %"610", align 4 + %"1175" = load float, ptr addrspace(5) %"610", align 4 + %"1174" = fmul float %"1175", 0x3FE62E4300000000 + store float %"1174", ptr addrspace(5) %"611", align 4 + %"1177" = load float, ptr addrspace(5) %"611", align 4 + %"1176" = fmul float %"1177", 0x400921FB60000000 + store float %"1176", ptr addrspace(5) %"612", align 4 + %"1179" = load float, ptr addrspace(5) %"609", align 4 + %"1180" = load float, ptr addrspace(5) %"612", align 4 + %"1178" = fmul float %"1179", %"1180" + store float %"1178", ptr addrspace(5) %"613", align 4 + %"1182" = load float, ptr addrspace(5) %"607", align 4 + %"1183" = load float, ptr addrspace(5) %"613", align 4 + %"1181" = fdiv arcp afn float %"1182", %"1183" + store float %"1181", ptr addrspace(5) %"660", align 4 + br label %"439" + +"439": ; preds = %"674", %"438" + %"1185" = load float, ptr addrspace(5) %"526", align 4 + %"1184" = fsub float %"1185", 0x3FA47AE140000000 + store float %"1184", ptr addrspace(5) %"615", align 4 + %"1187" = load float, ptr addrspace(5) %"475", align 4 + %"1188" = load float, ptr addrspace(5) %"615", align 4 + %"1186" = call float @llvm.fma.f32(float %"1187", float %"1188", float 0x3FA47AE140000000) + store float %"1186", ptr addrspace(5) %"616", align 4 + %"1190" = load float, ptr addrspace(5) %"479", align 4 + %"1189" = fmul float %"1190", 6.250000e-02 + store float %"1189", ptr addrspace(5) %"617", align 4 + %"1192" = load float, ptr addrspace(5) %"479", align 4 + %"1191" = fadd float %"1192", 6.250000e-02 + store float %"1191", ptr addrspace(5) %"618", align 4 + %"1194" = load float, ptr addrspace(5) %"618", align 4 + %"1195" = load float, ptr addrspace(5) %"617", align 4 + %"1193" = fsub float %"1194", %"1195" + store float %"1193", ptr addrspace(5) %"619", align 4 + %"1197" = load float, ptr addrspace(5) %"619", align 4 + %"1196" = call afn float @llvm.sqrt.f32(float %"1197") + store float %"1196", ptr addrspace(5) %"620", align 4 + %"1199" = load float, ptr addrspace(5) %"454", align 4 + %"1200" = load float, ptr addrspace(5) %"620", align 4 + %"1198" = fadd float %"1199", %"1200" + store float %"1198", ptr addrspace(5) %"621", align 4 + %"1202" = load float, ptr addrspace(5) %"621", align 4 + %"1201" = fdiv arcp afn float 1.000000e+00, %"1202" + store float %"1201", ptr addrspace(5) %"622", align 4 + %"1204" = load float, ptr addrspace(5) %"480", align 4 + %"1203" = fmul float %"1204", 6.250000e-02 + store float %"1203", ptr addrspace(5) %"623", align 4 + %"1206" = load float, ptr addrspace(5) %"480", align 4 + %"1205" = fadd float %"1206", 6.250000e-02 + store float %"1205", ptr addrspace(5) %"624", align 4 + %"1208" = load float, ptr addrspace(5) %"624", align 4 + %"1209" = load float, ptr addrspace(5) %"623", align 4 + %"1207" = fsub float %"1208", %"1209" + store float %"1207", ptr addrspace(5) %"625", align 4 + %"1211" = load float, ptr addrspace(5) %"625", align 4 + %"1210" = call afn float @llvm.sqrt.f32(float %"1211") + store float %"1210", ptr addrspace(5) %"626", align 4 + %"1213" = load float, ptr addrspace(5) %"458", align 4 + %"1214" = load float, ptr addrspace(5) %"626", align 4 + %"1212" = fadd float %"1213", %"1214" + store float %"1212", ptr addrspace(5) %"627", align 4 + %"1216" = load float, ptr addrspace(5) %"627", align 4 + %"1215" = fdiv arcp afn float 1.000000e+00, %"1216" + store float %"1215", ptr addrspace(5) %"628", align 4 + %"1218" = load float, ptr addrspace(5) %"622", align 4 + %"1219" = load float, ptr addrspace(5) %"628", align 4 + %"1217" = fmul float %"1218", %"1219" + store float %"1217", ptr addrspace(5) %"629", align 4 + %"1221" = load float, ptr addrspace(5) %"473", align 4 + %"1222" = load float, ptr addrspace(5) %"472", align 4 + %"1220" = fsub float %"1221", %"1222" + store float %"1220", ptr addrspace(5) %"630", align 4 + %"1224" = load i64, ptr addrspace(5) %"665", align 8 + %"1501" = inttoptr i64 %"1224" to ptr + %"1546" = getelementptr inbounds i8, ptr %"1501", i64 28 + %"1223" = load float, ptr %"1546", align 4 + store float %"1223", ptr addrspace(5) %"631", align 4 + %"1226" = load float, ptr addrspace(5) %"630", align 4 + %"1227" = load float, ptr addrspace(5) %"631", align 4 + %"1228" = load float, ptr addrspace(5) %"472", align 4 + %"1225" = call float @llvm.fma.f32(float %"1226", float %"1227", float %"1228") + store float %"1225", ptr addrspace(5) %"632", align 4 + %"1230" = load float, ptr addrspace(5) %"632", align 4 + %"1229" = fmul float %"1230", 0x3FD45F3060000000 + store float %"1229", ptr addrspace(5) %"633", align 4 + %"1232" = load float, ptr addrspace(5) %"461", align 4 + %"1233" = load float, ptr addrspace(5) %"633", align 4 + %"1234" = load float, ptr addrspace(5) %"482", align 4 + %"1231" = call float @llvm.fma.f32(float %"1232", float %"1233", float %"1234") + store float %"1231", ptr addrspace(5) %"634", align 4 + %"1236" = load float, ptr addrspace(5) %"462", align 4 + %"1237" = load float, ptr addrspace(5) %"633", align 4 + %"1238" = load float, ptr addrspace(5) %"483", align 4 + %"1235" = call float @llvm.fma.f32(float %"1236", float %"1237", float %"1238") + store float %"1235", ptr addrspace(5) %"635", align 4 + %"1240" = load float, ptr addrspace(5) %"463", align 4 + %"1241" = load float, ptr addrspace(5) %"633", align 4 + %"1242" = load float, ptr addrspace(5) %"484", align 4 + %"1239" = call float @llvm.fma.f32(float %"1240", float %"1241", float %"1242") + store float %"1239", ptr addrspace(5) %"636", align 4 + %"1244" = load float, ptr addrspace(5) %"526", align 4 + %"1245" = load float, ptr addrspace(5) %"471", align 4 + %"1243" = fsub float %"1244", %"1245" + store float %"1243", ptr addrspace(5) %"637", align 4 + %"1247" = load float, ptr addrspace(5) %"637", align 4 + %"1248" = load float, ptr addrspace(5) %"634", align 4 + %"1246" = fmul float %"1247", %"1248" + store float %"1246", ptr addrspace(5) %"638", align 4 + %"1250" = load float, ptr addrspace(5) %"637", align 4 + %"1251" = load float, ptr addrspace(5) %"635", align 4 + %"1249" = fmul float %"1250", %"1251" + store float %"1249", ptr addrspace(5) %"639", align 4 + %"1253" = load float, ptr addrspace(5) %"637", align 4 + %"1254" = load float, ptr addrspace(5) %"636", align 4 + %"1252" = fmul float %"1253", %"1254" + store float %"1252", ptr addrspace(5) %"640", align 4 + %"1256" = load float, ptr addrspace(5) %"476", align 4 + %"1257" = load float, ptr addrspace(5) %"481", align 4 + %"1255" = fmul float %"1256", %"1257" + store float %"1255", ptr addrspace(5) %"641", align 4 + %"1259" = load float, ptr addrspace(5) %"477", align 4 + %"1260" = load float, ptr addrspace(5) %"481", align 4 + %"1258" = fmul float %"1259", %"1260" + store float %"1258", ptr addrspace(5) %"642", align 4 + %"1262" = load float, ptr addrspace(5) %"478", align 4 + %"1263" = load float, ptr addrspace(5) %"481", align 4 + %"1261" = fmul float %"1262", %"1263" + store float %"1261", ptr addrspace(5) %"643", align 4 + %"1265" = load float, ptr addrspace(5) %"474", align 4 + %"1266" = load float, ptr addrspace(5) %"641", align 4 + %"1267" = load float, ptr addrspace(5) %"638", align 4 + %"1264" = call float @llvm.fma.f32(float %"1265", float %"1266", float %"1267") + store float %"1264", ptr addrspace(5) %"644", align 4 + %"1269" = load float, ptr addrspace(5) %"474", align 4 + %"1270" = load float, ptr addrspace(5) %"642", align 4 + %"1271" = load float, ptr addrspace(5) %"639", align 4 + %"1268" = call float @llvm.fma.f32(float %"1269", float %"1270", float %"1271") + store float %"1268", ptr addrspace(5) %"645", align 4 + %"1273" = load float, ptr addrspace(5) %"474", align 4 + %"1274" = load float, ptr addrspace(5) %"643", align 4 + %"1275" = load float, ptr addrspace(5) %"640", align 4 + %"1272" = call float @llvm.fma.f32(float %"1273", float %"1274", float %"1275") + store float %"1272", ptr addrspace(5) %"646", align 4 + %"1277" = load i64, ptr addrspace(5) %"665", align 8 + %"1502" = inttoptr i64 %"1277" to ptr + %"1548" = getelementptr inbounds i8, ptr %"1502", i64 56 + %"1276" = load float, ptr %"1548", align 4 + store float %"1276", ptr addrspace(5) %"647", align 4 + %"1279" = load float, ptr addrspace(5) %"647", align 4 + %"1278" = fmul float %"1279", 2.500000e-01 + store float %"1278", ptr addrspace(5) %"648", align 4 + %"1281" = load float, ptr addrspace(5) %"629", align 4 + %"1282" = load float, ptr addrspace(5) %"648", align 4 + %"1280" = fmul float %"1281", %"1282" + store float %"1280", ptr addrspace(5) %"649", align 4 + %"1284" = load float, ptr addrspace(5) %"616", align 4 + %"1285" = load float, ptr addrspace(5) %"649", align 4 + %"1283" = fmul float %"1284", %"1285" + store float %"1283", ptr addrspace(5) %"650", align 4 + %"1287" = load float, ptr addrspace(5) %"660", align 4 + %"1288" = load float, ptr addrspace(5) %"650", align 4 + %"1289" = load float, ptr addrspace(5) %"644", align 4 + %"1286" = call float @llvm.fma.f32(float %"1287", float %"1288", float %"1289") + store float %"1286", ptr addrspace(5) %"651", align 4 + %"1291" = load float, ptr addrspace(5) %"660", align 4 + %"1292" = load float, ptr addrspace(5) %"650", align 4 + %"1293" = load float, ptr addrspace(5) %"645", align 4 + %"1290" = call float @llvm.fma.f32(float %"1291", float %"1292", float %"1293") + store float %"1290", ptr addrspace(5) %"652", align 4 + %"1295" = load float, ptr addrspace(5) %"660", align 4 + %"1296" = load float, ptr addrspace(5) %"650", align 4 + %"1297" = load float, ptr addrspace(5) %"646", align 4 + %"1294" = call float @llvm.fma.f32(float %"1295", float %"1296", float %"1297") + store float %"1294", ptr addrspace(5) %"653", align 4 + %"1299" = load float, ptr addrspace(5) %"454", align 4 + %"1300" = load float, ptr addrspace(5) %"526", align 4 + %"1298" = call float @llvm.minnum.f32(float %"1299", float %"1300") + store float %"1298", ptr addrspace(5) %"654", align 4 + %11 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %11, align 4 + %"1301" = load float, ptr addrspace(5) %11, align 4 + store float %"1301", ptr addrspace(5) %"655", align 4 + %"1303" = load float, ptr addrspace(5) %"655", align 4 + %"1304" = load float, ptr addrspace(5) %"654", align 4 + %"1302" = call float @llvm.maxnum.f32(float %"1303", float %"1304") + store float %"1302", ptr addrspace(5) %"656", align 4 + %"1306" = load float, ptr addrspace(5) %"656", align 4 + %"1307" = load float, ptr addrspace(5) %"653", align 4 + %"1305" = fmul float %"1306", %"1307" + store float %"1305", ptr addrspace(5) %"663", align 4 + %"1309" = load float, ptr addrspace(5) %"656", align 4 + %"1310" = load float, ptr addrspace(5) %"652", align 4 + %"1308" = fmul float %"1309", %"1310" + store float %"1308", ptr addrspace(5) %"662", align 4 + %"1312" = load float, ptr addrspace(5) %"656", align 4 + %"1313" = load float, ptr addrspace(5) %"651", align 4 + %"1311" = fmul float %"1312", %"1313" + store float %"1311", ptr addrspace(5) %"661", align 4 + br label %"440" + +"440": ; preds = %"439", %"1506" + %"1314" = load float, ptr addrspace(5) %"661", align 4 + %"1550" = getelementptr inbounds i8, ptr addrspace(5) %"1420", i64 0 + store float %"1314", ptr addrspace(5) %"1550", align 4 + %"1315" = load float, ptr addrspace(5) %"662", align 4 + %"1552" = getelementptr inbounds i8, ptr addrspace(5) %"1420", i64 4 + store float %"1315", ptr addrspace(5) %"1552", align 4 + %"1316" = load float, ptr addrspace(5) %"663", align 4 + %"1554" = getelementptr inbounds i8, ptr addrspace(5) %"1420", i64 8 + store float %"1316", ptr addrspace(5) %"1554", align 4 + %"1317" = load [3 x i32], ptr addrspace(5) %"1420", align 4 + store [3 x i32] %"1317", ptr addrspace(5) %"723", align 4 + %"1318" = load [3 x i32], ptr addrspace(5) %"723", align 4 + %12 = insertvalue { [3 x i32], i32 } undef, [3 x i32] %"1318", 0 + %13 = insertvalue { [3 x i32], i32 } %12, i32 0, 1 + ret { [3 x i32], i32 } %13 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sqrt.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.minnum.f32(float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.maxnum.f32(float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.log2.f32(float) #2 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program.ptx b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program.ptx new file mode 100644 index 0000000..0a4a3bd --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program.ptx @@ -0,0 +1,946 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _ZN5optix3RayC1ERKS0_ +.global .align 4 .b8 shading_normal[12]; +.global .align 4 .b8 geometric_normal[12]; +.global .align 4 .b8 front_hit_point[12]; +.global .align 4 .b8 back_hit_point[12]; +.global .align 4 .b8 texcoord[12]; +.global .align 4 .b8 ray[36]; +.global .align 4 .f32 t_hit; +.global .align 4 .b8 prd[76]; +.global .align 1 .b8 prd_shadow[1]; +.global .align 4 .b8 top_object[4]; +.global .align 4 .f32 scene_epsilon; +.global .align 4 .u32 max_depth; +.global .align 1 .b8 sysBRDFPdf[1]; +.global .align 1 .b8 sysBRDFSample[1]; +.global .align 1 .b8 sysBRDFEval[1]; +.global .align 1 .b8 sysLightSample[1]; +.global .align 1 .b8 sysMaterialParameters[1]; +.global .align 4 .u32 materialId; +.global .align 4 .u32 programId; +.global .align 4 .u32 sysNumberOfLights; +.global .align 1 .b8 sysLightParameters[1]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo14shading_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo16geometric_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo15front_hit_pointE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo14back_hit_pointE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo8texcoordE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo5t_hitE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3prdE[8] = {82, 97, 121, 0, 76, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10prd_shadowE[8] = {82, 97, 121, 0, 1, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10top_objectE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo13scene_epsilonE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo9max_depthE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10materialIdE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo9programIdE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo17sysNumberOfLightsE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename14shading_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename16geometric_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename15front_hit_pointE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename14back_hit_pointE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename8texcoordE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3rayE[4] = {82, 97, 121, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename5t_hitE[6] = {102, 108, 111, 97, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3prdE[20] = {80, 101, 114, 82, 97, 121, 68, 97, 116, 97, 95, 114, 97, 100, 105, 97, 110, 99, 101, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10prd_shadowE[18] = {80, 101, 114, 82, 97, 121, 68, 97, 116, 97, 95, 115, 104, 97, 100, 111, 119, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10top_objectE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename13scene_epsilonE[6] = {102, 108, 111, 97, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename9max_depthE[4] = {105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10materialIdE[4] = {105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename9programIdE[4] = {105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename17sysNumberOfLightsE[4] = {105, 110, 116, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum14shading_normalE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum16geometric_normalE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum15front_hit_pointE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum14back_hit_pointE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum8texcoordE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum5t_hitE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3prdE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10prd_shadowE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10top_objectE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum13scene_epsilonE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum9max_depthE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10materialIdE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum9programIdE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum17sysNumberOfLightsE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic14shading_normalE[25] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 115, 104, 97, 100, 105, 110, 103, 95, 110, 111, 114, 109, 97, 108, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic16geometric_normalE[27] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 103, 101, 111, 109, 101, 116, 114, 105, 99, 95, 110, 111, 114, 109, 97, 108, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic15front_hit_pointE[26] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 102, 114, 111, 110, 116, 95, 104, 105, 116, 95, 112, 111, 105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic14back_hit_pointE[25] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 98, 97, 99, 107, 95, 104, 105, 116, 95, 112, 111, 105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic8texcoordE[19] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 116, 101, 120, 99, 111, 111, 114, 100, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic5t_hitE[23] = {114, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 105, 111, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic3prdE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic10prd_shadowE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic10top_objectE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic13scene_epsilonE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic9max_depthE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic10materialIdE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic9programIdE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic17sysNumberOfLightsE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation14shading_normalE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation16geometric_normalE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation15front_hit_pointE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation14back_hit_pointE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation8texcoordE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation5t_hitE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3prdE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10prd_shadowE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10top_objectE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation13scene_epsilonE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation9max_depthE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10materialIdE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation9programIdE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation17sysNumberOfLightsE[1]; + +.visible .func _ZN5optix3RayC1ERKS0_( + .param .b64 _ZN5optix3RayC1ERKS0__param_0, + .param .b64 _ZN5optix3RayC1ERKS0__param_1 +) +{ + .reg .f32 %f<9>; + .reg .b32 %r<2>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd1, [_ZN5optix3RayC1ERKS0__param_0]; + ld.param.u64 %rd2, [_ZN5optix3RayC1ERKS0__param_1]; + ld.f32 %f1, [%rd2]; + ld.f32 %f2, [%rd2+4]; + ld.f32 %f3, [%rd2+8]; + st.f32 [%rd1], %f1; + st.f32 [%rd1+4], %f2; + st.f32 [%rd1+8], %f3; + ld.f32 %f4, [%rd2+12]; + ld.f32 %f5, [%rd2+16]; + ld.f32 %f6, [%rd2+20]; + st.f32 [%rd1+12], %f4; + st.f32 [%rd1+16], %f5; + st.f32 [%rd1+20], %f6; + ld.u32 %r1, [%rd2+24]; + st.u32 [%rd1+24], %r1; + ld.f32 %f7, [%rd2+28]; + st.f32 [%rd1+28], %f7; + ld.f32 %f8, [%rd2+32]; + st.f32 [%rd1+32], %f8; + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .local .align 4 .b8 __local_depot1[236]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .pred %p<8>; + .reg .b16 %rs<5>; + .reg .f32 %f<231>; + .reg .b32 %r<48>; + .reg .b64 %rd<95>; + + + mov.u64 %SPL, __local_depot1; + cvta.local.u64 %SP, %SPL; + add.u64 %rd10, %SP, 116; + add.u64 %rd1, %SPL, 116; + mov.u64 %rd9, 0; + ld.global.f32 %f32, [shading_normal]; + ld.global.f32 %f33, [shading_normal+4]; + ld.global.f32 %f34, [shading_normal+8]; + mov.u32 %r4, 7937; + mov.f32 %f228, 0f00000000; + // begin inline asm + call (%f28, %f29, %f30, %f31), _rt_transform_tuple, (%r4, %f32, %f33, %f34, %f228); + // end inline asm + mul.ftz.f32 %f44, %f29, %f29; + fma.rn.ftz.f32 %f45, %f28, %f28, %f44; + fma.rn.ftz.f32 %f46, %f30, %f30, %f45; + rsqrt.approx.ftz.f32 %f47, %f46; + mul.ftz.f32 %f1, %f47, %f28; + mul.ftz.f32 %f2, %f47, %f29; + mul.ftz.f32 %f3, %f47, %f30; + ld.global.f32 %f40, [geometric_normal]; + ld.global.f32 %f41, [geometric_normal+4]; + ld.global.f32 %f42, [geometric_normal+8]; + // begin inline asm + call (%f36, %f37, %f38, %f39), _rt_transform_tuple, (%r4, %f40, %f41, %f42, %f228); + // end inline asm + mul.ftz.f32 %f48, %f37, %f37; + fma.rn.ftz.f32 %f49, %f36, %f36, %f48; + fma.rn.ftz.f32 %f50, %f38, %f38, %f49; + rsqrt.approx.ftz.f32 %f51, %f50; + mul.ftz.f32 %f52, %f51, %f36; + mul.ftz.f32 %f53, %f51, %f37; + mul.ftz.f32 %f54, %f51, %f38; + ld.global.f32 %f55, [ray+12]; + mul.ftz.f32 %f56, %f55, %f52; + ld.global.f32 %f57, [ray+16]; + mul.ftz.f32 %f58, %f57, %f53; + neg.ftz.f32 %f59, %f58; + sub.ftz.f32 %f60, %f59, %f56; + ld.global.f32 %f61, [ray+20]; + mul.ftz.f32 %f62, %f61, %f54; + sub.ftz.f32 %f63, %f60, %f62; + mov.b32 %r7, %f63; + and.b32 %r8, %r7, -2147483648; + or.b32 %r9, %r8, 1065353216; + mov.b32 %f64, %r9; + mul.ftz.f32 %f4, %f1, %f64; + mul.ftz.f32 %f5, %f2, %f64; + mul.ftz.f32 %f6, %f3, %f64; + ld.global.s32 %rd6, [materialId]; + mov.u64 %rd11, sysMaterialParameters; + cvta.global.u64 %rd5, %rd11; + mov.u32 %r5, 1; + mov.u32 %r6, 72; + // begin inline asm + call (%rd4), _rt_buffer_get_64, (%rd5, %r5, %r6, %rd6, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r1, [%rd4]; + ld.f32 %f65, [%rd4+4]; + ld.f32 %f66, [%rd4+8]; + ld.f32 %f67, [%rd4+12]; + ld.f32 %f7, [%rd4+16]; + ld.f32 %f8, [%rd4+20]; + ld.f32 %f9, [%rd4+24]; + ld.f32 %f68, [%rd4+28]; + ld.f32 %f69, [%rd4+32]; + ld.f32 %f70, [%rd4+36]; + ld.f32 %f71, [%rd4+40]; + ld.f32 %f72, [%rd4+44]; + ld.f32 %f73, [%rd4+48]; + ld.f32 %f74, [%rd4+52]; + ld.f32 %f75, [%rd4+56]; + ld.f32 %f76, [%rd4+60]; + ld.f32 %f77, [%rd4+64]; + ld.u32 %r2, [%rd4+68]; + st.local.u32 [%rd1], %r1; + st.local.f32 [%rd1+4], %f65; + st.local.f32 [%rd1+8], %f66; + st.local.f32 [%rd1+12], %f67; + st.local.f32 [%rd1+16], %f7; + st.local.f32 [%rd1+20], %f8; + st.local.f32 [%rd1+24], %f9; + st.local.f32 [%rd1+28], %f68; + st.local.f32 [%rd1+32], %f69; + st.local.f32 [%rd1+36], %f70; + st.local.f32 [%rd1+40], %f71; + st.local.f32 [%rd1+44], %f72; + st.local.f32 [%rd1+48], %f73; + st.local.f32 [%rd1+52], %f74; + st.local.f32 [%rd1+56], %f75; + st.local.f32 [%rd1+60], %f76; + st.local.f32 [%rd1+64], %f77; + st.local.u32 [%rd1+68], %r2; + setp.eq.s32 %p1, %r1, 0; + @%p1 bra $L__BB1_2; + + ld.global.f32 %f82, [texcoord]; + ld.global.f32 %f83, [texcoord+4]; + mov.u32 %r11, 2; + // begin inline asm + call (%f78, %f79, %f80, %f81), _rt_texture_get_f_id, (%r1, %r11, %f82, %f83, %f228, %f228); + // end inline asm + lg2.approx.ftz.f32 %f86, %f78; + mul.ftz.f32 %f87, %f86, 0f400CCCCD; + ex2.approx.ftz.f32 %f88, %f87; + lg2.approx.ftz.f32 %f89, %f79; + mul.ftz.f32 %f90, %f89, 0f400CCCCD; + ex2.approx.ftz.f32 %f91, %f90; + lg2.approx.ftz.f32 %f92, %f80; + mul.ftz.f32 %f93, %f92, 0f400CCCCD; + ex2.approx.ftz.f32 %f94, %f93; + st.local.f32 [%rd1+4], %f88; + st.local.f32 [%rd1+8], %f91; + st.local.f32 [%rd1+12], %f94; + +$L__BB1_2: + ld.global.f32 %f10, [front_hit_point]; + ld.global.f32 %f11, [front_hit_point+4]; + ld.global.f32 %f12, [front_hit_point+8]; + add.u64 %rd12, %SP, 188; + add.u64 %rd13, %SPL, 188; + st.local.f32 [%rd13], %f10; + st.local.f32 [%rd13+4], %f11; + st.local.f32 [%rd13+8], %f12; + ld.global.f32 %f95, [back_hit_point]; + ld.global.f32 %f96, [back_hit_point+4]; + ld.global.f32 %f97, [back_hit_point+8]; + st.local.f32 [%rd13+12], %f95; + st.local.f32 [%rd13+16], %f96; + st.local.f32 [%rd13+20], %f97; + st.local.f32 [%rd13+24], %f1; + st.local.f32 [%rd13+28], %f2; + st.local.f32 [%rd13+32], %f3; + st.local.f32 [%rd13+36], %f4; + st.local.f32 [%rd13+40], %f5; + st.local.f32 [%rd13+44], %f6; + ld.global.f32 %f98, [ray+12]; + neg.ftz.f32 %f99, %f98; + ld.global.f32 %f100, [ray+16]; + neg.ftz.f32 %f101, %f100; + ld.global.f32 %f102, [ray+20]; + neg.ftz.f32 %f103, %f102; + st.global.f32 [prd+48], %f99; + st.global.f32 [prd+52], %f101; + st.global.f32 [prd+56], %f103; + ld.global.f32 %f104, [prd+60]; + ld.global.f32 %f105, [prd+64]; + ld.global.f32 %f106, [prd+68]; + ld.global.f32 %f107, [prd+12]; + fma.rn.ftz.f32 %f108, %f7, %f104, %f107; + st.global.f32 [prd+12], %f108; + ld.global.f32 %f109, [prd+16]; + fma.rn.ftz.f32 %f110, %f8, %f105, %f109; + st.global.f32 [prd+16], %f110; + ld.global.f32 %f111, [prd+20]; + fma.rn.ftz.f32 %f112, %f9, %f106, %f111; + st.global.f32 [prd+20], %f112; + setp.eq.s32 %p2, %r2, 1; + selp.u16 %rs1, 1, 0, %p2; + st.global.u8 [prd+10], %rs1; + @%p2 bra $L__BB1_9; + + ld.global.u32 %r12, [prd]; + ld.global.u32 %r13, [max_depth]; + setp.ge.s32 %p3, %r12, %r13; + mov.f32 %f229, 0f00000000; + mov.f32 %f230, 0f00000000; + @%p3 bra $L__BB1_9; + + mov.u64 %rd28, prd; + ld.global.u32 %r19, [prd+4]; + mad.lo.s32 %r20, %r19, 1664525, 1013904223; + st.global.u32 [prd+4], %r20; + and.b32 %r21, %r20, 16777215; + cvt.rn.f32.u32 %f116, %r21; + mov.f32 %f117, 0f4B800000; + div.approx.ftz.f32 %f118, %f116, %f117; + ld.global.u32 %r22, [sysNumberOfLights]; + cvt.rn.f32.s32 %f119, %r22; + mul.ftz.f32 %f120, %f118, %f119; + cvt.rmi.ftz.f32.f32 %f121, %f120; + cvt.rzi.ftz.s32.f32 %r23, %f121; + add.s32 %r24, %r22, -1; + min.s32 %r25, %r23, %r24; + max.s32 %r26, %r25, 0; + cvt.s64.s32 %rd16, %r26; + mov.u64 %rd29, sysLightParameters; + cvta.global.u64 %rd15, %rd29; + // begin inline asm + call (%rd14), _rt_buffer_get_64, (%rd15, %r5, %r6, %rd16, %rd9, %rd9, %rd9); + // end inline asm + ld.f32 %f122, [%rd14]; + ld.f32 %f123, [%rd14+4]; + ld.f32 %f124, [%rd14+8]; + ld.f32 %f125, [%rd14+12]; + ld.f32 %f126, [%rd14+16]; + ld.f32 %f127, [%rd14+20]; + ld.f32 %f128, [%rd14+24]; + ld.f32 %f129, [%rd14+28]; + ld.f32 %f130, [%rd14+32]; + ld.f32 %f131, [%rd14+36]; + ld.f32 %f132, [%rd14+40]; + ld.f32 %f133, [%rd14+44]; + ld.f32 %f134, [%rd14+48]; + ld.f32 %f135, [%rd14+52]; + ld.f32 %f136, [%rd14+56]; + ld.f32 %f137, [%rd14+60]; + ld.f32 %f138, [%rd14+64]; + ld.u32 %r27, [%rd14+68]; + add.u64 %rd30, %SP, 0; + add.u64 %rd2, %SPL, 0; + st.local.f32 [%rd2], %f122; + st.local.f32 [%rd2+4], %f123; + st.local.f32 [%rd2+8], %f124; + st.local.f32 [%rd2+12], %f125; + st.local.f32 [%rd2+16], %f126; + st.local.f32 [%rd2+20], %f127; + st.local.f32 [%rd2+24], %f128; + st.local.f32 [%rd2+28], %f129; + st.local.f32 [%rd2+32], %f130; + st.local.f32 [%rd2+36], %f131; + st.local.f32 [%rd2+40], %f132; + st.local.f32 [%rd2+44], %f133; + st.local.f32 [%rd2+48], %f134; + st.local.f32 [%rd2+52], %f135; + st.local.f32 [%rd2+56], %f136; + st.local.f32 [%rd2+60], %f137; + st.local.f32 [%rd2+64], %f138; + st.local.u32 [%rd2+68], %r27; + cvt.s64.s32 %rd22, %r27; + mov.u64 %rd31, sysLightSample; + cvta.global.u64 %rd21, %rd31; + mov.u32 %r17, 4; + // begin inline asm + call (%rd20), _rt_buffer_get_64, (%rd21, %r5, %r17, %rd22, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r18, [%rd20]; + // begin inline asm + call (%rd26), _rt_callable_program_from_id_v2_64, (%r18, %rd9); + // end inline asm + cvta.global.u64 %rd33, %rd28; + add.u64 %rd34, %SP, 72; + { // callseq 0, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd30; + .param .b64 param1; + st.param.b64 [param1+0], %rd33; + .param .b64 param2; + st.param.b64 [param2+0], %rd34; + prototype_0 : .callprototype ()_ (.param .b64 _, .param .b64 _, .param .b64 _); + call + %rd26, + ( + param0, + param1, + param2 + ) + , prototype_0; + } // callseq 0 + add.u64 %rd3, %SPL, 72; + ld.local.f32 %f139, [%rd3]; + sub.ftz.f32 %f140, %f139, %f10; + ld.local.f32 %f141, [%rd3+4]; + sub.ftz.f32 %f142, %f141, %f11; + ld.local.f32 %f143, [%rd3+8]; + sub.ftz.f32 %f144, %f143, %f12; + mul.ftz.f32 %f145, %f142, %f142; + fma.rn.ftz.f32 %f146, %f140, %f140, %f145; + fma.rn.ftz.f32 %f147, %f144, %f144, %f146; + sqrt.approx.ftz.f32 %f13, %f147; + mul.ftz.f32 %f14, %f13, %f13; + rsqrt.approx.ftz.f32 %f148, %f14; + mul.ftz.f32 %f15, %f140, %f148; + mul.ftz.f32 %f16, %f142, %f148; + mul.ftz.f32 %f17, %f144, %f148; + mul.ftz.f32 %f149, %f5, %f16; + fma.rn.ftz.f32 %f150, %f4, %f15, %f149; + fma.rn.ftz.f32 %f151, %f6, %f17, %f150; + setp.le.ftz.f32 %p4, %f151, 0f00000000; + @%p4 bra $L__BB1_8; + + ld.local.f32 %f155, [%rd3+12]; + ld.local.f32 %f156, [%rd3+16]; + mul.ftz.f32 %f157, %f16, %f156; + fma.rn.ftz.f32 %f158, %f15, %f155, %f157; + ld.local.f32 %f159, [%rd3+20]; + fma.rn.ftz.f32 %f160, %f17, %f159, %f158; + setp.ge.ftz.f32 %p5, %f160, 0f00000000; + @%p5 bra $L__BB1_8; + + add.u64 %rd35, %SP, 112; + add.u64 %rd36, %SPL, 112; + mov.u16 %rs2, 0; + st.local.u8 [%rd36], %rs2; + ld.global.f32 %f167, [scene_epsilon]; + sub.ftz.f32 %f168, %f13, %f167; + ld.global.u32 %r28, [top_object]; + mov.u32 %r30, 255; + mov.u32 %r31, 0; + // begin inline asm + call _rt_trace_mask_flags_64, (%r28, %f10, %f11, %f12, %f15, %f16, %f17, %r5, %f167, %f168, %r30, %r31, %rd35, %r5); + // end inline asm + ld.local.u8 %rs3, [%rd36]; + setp.ne.s16 %p6, %rs3, 0; + @%p6 bra $L__BB1_8; + + ld.local.f32 %f172, [%rd3+12]; + mul.ftz.f32 %f173, %f15, %f172; + ld.local.f32 %f174, [%rd3+16]; + mul.ftz.f32 %f175, %f16, %f174; + neg.ftz.f32 %f176, %f175; + sub.ftz.f32 %f177, %f176, %f173; + ld.local.f32 %f178, [%rd3+20]; + mul.ftz.f32 %f179, %f17, %f178; + sub.ftz.f32 %f180, %f177, %f179; + ld.local.f32 %f181, [%rd2+60]; + mul.ftz.f32 %f182, %f181, %f180; + div.approx.ftz.f32 %f183, %f14, %f182; + st.global.f32 [prd+36], %f15; + st.global.f32 [prd+40], %f16; + st.global.f32 [prd+44], %f17; + ld.global.s32 %rd39, [programId]; + mov.u64 %rd54, sysBRDFPdf; + cvta.global.u64 %rd38, %rd54; + // begin inline asm + call (%rd37), _rt_buffer_get_64, (%rd38, %r5, %r17, %rd39, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r35, [%rd37]; + // begin inline asm + call (%rd43), _rt_callable_program_from_id_v2_64, (%r35, %rd9); + // end inline asm + { // callseq 1, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd10; + .param .b64 param1; + st.param.b64 [param1+0], %rd12; + .param .b64 param2; + st.param.b64 [param2+0], %rd33; + prototype_1 : .callprototype ()_ (.param .b64 _, .param .b64 _, .param .b64 _); + call + %rd43, + ( + param0, + param1, + param2 + ) + , prototype_1; + } // callseq 1 + ld.global.s32 %rd47, [programId]; + mov.u64 %rd59, sysBRDFEval; + cvta.global.u64 %rd46, %rd59; + // begin inline asm + call (%rd45), _rt_buffer_get_64, (%rd46, %r5, %r17, %rd47, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r38, [%rd45]; + // begin inline asm + call (%rd51), _rt_callable_program_from_id_v2_64, (%r38, %rd9); + // end inline asm + { // callseq 2, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd10; + .param .b64 param1; + st.param.b64 [param1+0], %rd12; + .param .b64 param2; + st.param.b64 [param2+0], %rd33; + .param .align 4 .b8 retval0[12]; + prototype_2 : .callprototype (.param .align 4 .b8 _[12]) _ (.param .b64 _, .param .b64 _, .param .b64 _); + call (retval0), + %rd51, + ( + param0, + param1, + param2 + ) + , prototype_2; + ld.param.f32 %f184, [retval0+0]; + ld.param.f32 %f185, [retval0+4]; + ld.param.f32 %f186, [retval0+8]; + } // callseq 2 + mul.ftz.f32 %f187, %f183, %f183; + ld.global.f32 %f188, [prd+72]; + fma.rn.ftz.f32 %f189, %f188, %f188, %f187; + div.approx.ftz.f32 %f190, %f187, %f189; + ld.global.f32 %f191, [prd+60]; + mul.ftz.f32 %f192, %f190, %f191; + ld.global.f32 %f193, [prd+64]; + mul.ftz.f32 %f194, %f190, %f193; + ld.global.f32 %f195, [prd+68]; + mul.ftz.f32 %f196, %f190, %f195; + mul.ftz.f32 %f197, %f184, %f192; + mul.ftz.f32 %f198, %f185, %f194; + mul.ftz.f32 %f199, %f186, %f196; + ld.local.f32 %f200, [%rd3+24]; + mul.ftz.f32 %f201, %f200, %f197; + ld.local.f32 %f202, [%rd3+28]; + mul.ftz.f32 %f203, %f202, %f198; + ld.local.f32 %f204, [%rd3+32]; + mul.ftz.f32 %f205, %f204, %f199; + mov.f32 %f206, 0f3A83126F; + max.ftz.f32 %f207, %f206, %f183; + rcp.approx.ftz.f32 %f208, %f207; + mul.ftz.f32 %f230, %f208, %f205; + mul.ftz.f32 %f229, %f208, %f203; + mul.ftz.f32 %f228, %f208, %f201; + +$L__BB1_8: + ld.global.f32 %f209, [prd+12]; + add.ftz.f32 %f210, %f228, %f209; + st.global.f32 [prd+12], %f210; + ld.global.f32 %f211, [prd+16]; + add.ftz.f32 %f212, %f229, %f211; + st.global.f32 [prd+16], %f212; + ld.global.f32 %f213, [prd+20]; + add.ftz.f32 %f214, %f230, %f213; + st.global.f32 [prd+20], %f214; + +$L__BB1_9: + ld.global.s32 %rd63, [programId]; + mov.u64 %rd85, sysBRDFSample; + cvta.global.u64 %rd62, %rd85; + mov.u32 %r46, 4; + // begin inline asm + call (%rd61), _rt_buffer_get_64, (%rd62, %r5, %r46, %rd63, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r41, [%rd61]; + // begin inline asm + call (%rd67), _rt_callable_program_from_id_v2_64, (%r41, %rd9); + // end inline asm + mov.u64 %rd87, prd; + cvta.global.u64 %rd88, %rd87; + { // callseq 3, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd10; + .param .b64 param1; + st.param.b64 [param1+0], %rd12; + .param .b64 param2; + st.param.b64 [param2+0], %rd88; + prototype_3 : .callprototype ()_ (.param .b64 _, .param .b64 _, .param .b64 _); + call + %rd67, + ( + param0, + param1, + param2 + ) + , prototype_3; + } // callseq 3 + ld.global.s32 %rd71, [programId]; + mov.u64 %rd91, sysBRDFPdf; + cvta.global.u64 %rd70, %rd91; + // begin inline asm + call (%rd69), _rt_buffer_get_64, (%rd70, %r5, %r46, %rd71, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r44, [%rd69]; + // begin inline asm + call (%rd75), _rt_callable_program_from_id_v2_64, (%r44, %rd9); + // end inline asm + { // callseq 4, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd10; + .param .b64 param1; + st.param.b64 [param1+0], %rd12; + .param .b64 param2; + st.param.b64 [param2+0], %rd88; + prototype_4 : .callprototype ()_ (.param .b64 _, .param .b64 _, .param .b64 _); + call + %rd75, + ( + param0, + param1, + param2 + ) + , prototype_4; + } // callseq 4 + ld.global.s32 %rd79, [programId]; + mov.u64 %rd93, sysBRDFEval; + cvta.global.u64 %rd78, %rd93; + // begin inline asm + call (%rd77), _rt_buffer_get_64, (%rd78, %r5, %r46, %rd79, %rd9, %rd9, %rd9); + // end inline asm + ld.u32 %r47, [%rd77]; + // begin inline asm + call (%rd83), _rt_callable_program_from_id_v2_64, (%r47, %rd9); + // end inline asm + { // callseq 5, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd10; + .param .b64 param1; + st.param.b64 [param1+0], %rd12; + .param .b64 param2; + st.param.b64 [param2+0], %rd88; + .param .align 4 .b8 retval0[12]; + prototype_5 : .callprototype (.param .align 4 .b8 _[12]) _ (.param .b64 _, .param .b64 _, .param .b64 _); + call (retval0), + %rd83, + ( + param0, + param1, + param2 + ) + , prototype_5; + ld.param.f32 %f24, [retval0+0]; + ld.param.f32 %f25, [retval0+4]; + ld.param.f32 %f26, [retval0+8]; + } // callseq 5 + ld.global.f32 %f27, [prd+72]; + setp.gt.ftz.f32 %p7, %f27, 0f00000000; + @%p7 bra $L__BB1_11; + bra.uni $L__BB1_10; + +$L__BB1_11: + rcp.approx.ftz.f32 %f215, %f27; + mul.ftz.f32 %f216, %f24, %f215; + mul.ftz.f32 %f217, %f25, %f215; + mul.ftz.f32 %f218, %f26, %f215; + ld.global.f32 %f219, [prd+60]; + mul.ftz.f32 %f220, %f219, %f216; + st.global.f32 [prd+60], %f220; + ld.global.f32 %f221, [prd+64]; + mul.ftz.f32 %f222, %f221, %f217; + st.global.f32 [prd+64], %f222; + ld.global.f32 %f223, [prd+68]; + mul.ftz.f32 %f224, %f223, %f218; + st.global.f32 [prd+68], %f224; + bra.uni $L__BB1_12; + +$L__BB1_10: + mov.u16 %rs4, 1; + st.global.u8 [prd+8], %rs4; + +$L__BB1_12: + ret; + +} + // .globl _ZN5optix7rtTex2DI6float4EET_iff +.visible .func (.param .align 16 .b8 func_retval0[16]) _ZN5optix7rtTex2DI6float4EET_iff( + .param .b32 _ZN5optix7rtTex2DI6float4EET_iff_param_0, + .param .b32 _ZN5optix7rtTex2DI6float4EET_iff_param_1, + .param .b32 _ZN5optix7rtTex2DI6float4EET_iff_param_2 +) +{ + .reg .f32 %f<9>; + .reg .b32 %r<3>; + + + ld.param.u32 %r1, [_ZN5optix7rtTex2DI6float4EET_iff_param_0]; + ld.param.f32 %f5, [_ZN5optix7rtTex2DI6float4EET_iff_param_1]; + ld.param.f32 %f6, [_ZN5optix7rtTex2DI6float4EET_iff_param_2]; + mov.u32 %r2, 2; + mov.f32 %f8, 0f00000000; + // begin inline asm + call (%f1, %f2, %f3, %f4), _rt_texture_get_f_id, (%r1, %r2, %f5, %f6, %f8, %f8); + // end inline asm + st.param.f32 [func_retval0+0], %f1; + st.param.f32 [func_retval0+4], %f2; + st.param.f32 [func_retval0+8], %f3; + st.param.f32 [func_retval0+12], %f4; + ret; + +} + // .globl _Z7any_hitv +.visible .entry _Z7any_hitv() +{ + .reg .b16 %rs<2>; + + + mov.u16 %rs1, 1; + st.global.u8 [prd_shadow], %rs1; + // begin inline asm + call _rt_terminate_ray, (); + // end inline asm + ret; + +} + // .globl _ZN5optix3RayC1Ev +.visible .func _ZN5optix3RayC1Ev( + .param .b64 _ZN5optix3RayC1Ev_param_0 +) +{ + + + + ret; + +} + // .globl _ZN5optix3RayC2Ev +.visible .func _ZN5optix3RayC2Ev( + .param .b64 _ZN5optix3RayC2Ev_param_0 +) +{ + + + + ret; + +} + // .globl _ZN5optix3RayC2ERKS0_ +.visible .func _ZN5optix3RayC2ERKS0_( + .param .b64 _ZN5optix3RayC2ERKS0__param_0, + .param .b64 _ZN5optix3RayC2ERKS0__param_1 +) +{ + .reg .f32 %f<9>; + .reg .b32 %r<2>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd1, [_ZN5optix3RayC2ERKS0__param_0]; + ld.param.u64 %rd2, [_ZN5optix3RayC2ERKS0__param_1]; + ld.f32 %f1, [%rd2]; + ld.f32 %f2, [%rd2+4]; + ld.f32 %f3, [%rd2+8]; + st.f32 [%rd1], %f1; + st.f32 [%rd1+4], %f2; + st.f32 [%rd1+8], %f3; + ld.f32 %f4, [%rd2+12]; + ld.f32 %f5, [%rd2+16]; + ld.f32 %f6, [%rd2+20]; + st.f32 [%rd1+12], %f4; + st.f32 [%rd1+16], %f5; + st.f32 [%rd1+20], %f6; + ld.u32 %r1, [%rd2+24]; + st.u32 [%rd1+24], %r1; + ld.f32 %f7, [%rd2+28]; + st.f32 [%rd1+28], %f7; + ld.f32 %f8, [%rd2+32]; + st.f32 [%rd1+32], %f8; + ret; + +} + // .globl _ZN5optix7size_t4C1Ev +.visible .func _ZN5optix7size_t4C1Ev( + .param .b64 _ZN5optix7size_t4C1Ev_param_0 +) +{ + + + + ret; + +} + // .globl _ZN5optix7size_t4C2Ev +.visible .func _ZN5optix7size_t4C2Ev( + .param .b64 _ZN5optix7size_t4C2Ev_param_0 +) +{ + + + + ret; + +} + // .globl _ZN5optix6bufferINS_17callableProgramIdIFvR17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix6bufferINS_17callableProgramIdIFvR17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy( + .param .b64 _ZN5optix6bufferINS_17callableProgramIdIFvR17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy_param_0 +) +{ + .reg .b64 %rd<3>; + + + mov.u64 %rd1, 0; + ld.param.u64 %rd2, [_ZN5optix6bufferINS_17callableProgramIdIFvR17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy_param_0]; + st.param.b64 [func_retval0+0], %rd2; + st.param.b64 [func_retval0+8], %rd1; + st.param.b64 [func_retval0+16], %rd1; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + // .globl _ZN5optix12make_size_t4Eyyyy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix12make_size_t4Eyyyy( + .param .b64 _ZN5optix12make_size_t4Eyyyy_param_0, + .param .b64 _ZN5optix12make_size_t4Eyyyy_param_1, + .param .b64 _ZN5optix12make_size_t4Eyyyy_param_2, + .param .b64 _ZN5optix12make_size_t4Eyyyy_param_3 +) +{ + .reg .b64 %rd<5>; + + + ld.param.u64 %rd1, [_ZN5optix12make_size_t4Eyyyy_param_3]; + ld.param.u64 %rd2, [_ZN5optix12make_size_t4Eyyyy_param_2]; + ld.param.u64 %rd3, [_ZN5optix12make_size_t4Eyyyy_param_1]; + ld.param.u64 %rd4, [_ZN5optix12make_size_t4Eyyyy_param_0]; + st.param.b64 [func_retval0+0], %rd4; + st.param.b64 [func_retval0+8], %rd3; + st.param.b64 [func_retval0+16], %rd2; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + // .globl _ZN5optix6bufferINS_17callableProgramIdIF6float3R17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix6bufferINS_17callableProgramIdIF6float3R17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy( + .param .b64 _ZN5optix6bufferINS_17callableProgramIdIF6float3R17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy_param_0 +) +{ + .reg .b64 %rd<3>; + + + mov.u64 %rd1, 0; + ld.param.u64 %rd2, [_ZN5optix6bufferINS_17callableProgramIdIF6float3R17MaterialParameterR5StateR19PerRayData_radianceEEELi1EE10make_indexEy_param_0]; + st.param.b64 [func_retval0+0], %rd2; + st.param.b64 [func_retval0+8], %rd1; + st.param.b64 [func_retval0+16], %rd1; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + // .globl _ZN5optix6bufferINS_17callableProgramIdIFvR14LightParameterR19PerRayData_radianceR11LightSampleEEELi1EE10make_indexEy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix6bufferINS_17callableProgramIdIFvR14LightParameterR19PerRayData_radianceR11LightSampleEEELi1EE10make_indexEy( + .param .b64 _ZN5optix6bufferINS_17callableProgramIdIFvR14LightParameterR19PerRayData_radianceR11LightSampleEEELi1EE10make_indexEy_param_0 +) +{ + .reg .b64 %rd<3>; + + + mov.u64 %rd1, 0; + ld.param.u64 %rd2, [_ZN5optix6bufferINS_17callableProgramIdIFvR14LightParameterR19PerRayData_radianceR11LightSampleEEELi1EE10make_indexEy_param_0]; + st.param.b64 [func_retval0+0], %rd2; + st.param.b64 [func_retval0+8], %rd1; + st.param.b64 [func_retval0+16], %rd1; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + // .globl _ZN5optix6bufferI17MaterialParameterLi1EE10make_indexEy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix6bufferI17MaterialParameterLi1EE10make_indexEy( + .param .b64 _ZN5optix6bufferI17MaterialParameterLi1EE10make_indexEy_param_0 +) +{ + .reg .b64 %rd<3>; + + + mov.u64 %rd1, 0; + ld.param.u64 %rd2, [_ZN5optix6bufferI17MaterialParameterLi1EE10make_indexEy_param_0]; + st.param.b64 [func_retval0+0], %rd2; + st.param.b64 [func_retval0+8], %rd1; + st.param.b64 [func_retval0+16], %rd1; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + // .globl _ZN5optix6bufferI14LightParameterLi1EE10make_indexEy +.visible .func (.param .align 16 .b8 func_retval0[32]) _ZN5optix6bufferI14LightParameterLi1EE10make_indexEy( + .param .b64 _ZN5optix6bufferI14LightParameterLi1EE10make_indexEy_param_0 +) +{ + .reg .b64 %rd<3>; + + + mov.u64 %rd1, 0; + ld.param.u64 %rd2, [_ZN5optix6bufferI14LightParameterLi1EE10make_indexEy_param_0]; + st.param.b64 [func_retval0+0], %rd2; + st.param.b64 [func_retval0+8], %rd1; + st.param.b64 [func_retval0+16], %rd1; + st.param.b64 [func_retval0+24], %rd1; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program_closest_hit.ll b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program_closest_hit.ll new file mode 100644 index 0000000..fa3c69c --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixPathTracer_generated_hit_program_closest_hit.ll @@ -0,0 +1,2396 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare float @__zluda_ptx_impl__cvt_rn_f32_s32(i32) #0 + +declare float @__zluda_ptx_impl__cvt_rn_f32_u32(i32) #0 + +declare i32 @__zluda_ptx_impl__cvt_rz_s32_f32(float) #0 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected i32 @_Z11closest_hitv(ptr addrspace(3) %"2127", i32 %"2128", <2 x i32> %"2129", <2 x i32> %"2130", ptr addrspace(5) %"2131", float %"2132", ptr addrspace(5) %"2133", float %"2134", <2 x float> %"2135", <3 x float> %"2136", ptr addrspace(1) %"2137", ptr addrspace(1) %"2138", ptr addrspace(1) %"2139") #1 { +"2703": + %"2392" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"2392", align 4 + %"854" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"854", align 1 + %"855" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"855", align 1 + %"312" = alloca [236 x i8], align 4, addrspace(5) + %"313" = alloca i64, align 8, addrspace(5) + %"314" = alloca i64, align 8, addrspace(5) + %"315" = alloca i1, align 1, addrspace(5) + %"316" = alloca i1, align 1, addrspace(5) + %"317" = alloca i1, align 1, addrspace(5) + %"318" = alloca i1, align 1, addrspace(5) + %"319" = alloca i1, align 1, addrspace(5) + %"320" = alloca i1, align 1, addrspace(5) + %"321" = alloca i1, align 1, addrspace(5) + %"322" = alloca i1, align 1, addrspace(5) + %"323" = alloca i16, align 2, addrspace(5) + %"324" = alloca i16, align 2, addrspace(5) + %"325" = alloca i16, align 2, addrspace(5) + %"326" = alloca i16, align 2, addrspace(5) + %"327" = alloca i16, align 2, addrspace(5) + %"328" = alloca float, align 4, addrspace(5) + %"329" = alloca float, align 4, addrspace(5) + %"330" = alloca float, align 4, addrspace(5) + %"331" = alloca float, align 4, addrspace(5) + %"332" = alloca float, align 4, addrspace(5) + %"333" = alloca float, align 4, addrspace(5) + %"334" = alloca float, align 4, addrspace(5) + %"335" = alloca float, align 4, addrspace(5) + %"336" = alloca float, align 4, addrspace(5) + %"337" = alloca float, align 4, addrspace(5) + %"338" = alloca float, align 4, addrspace(5) + %"339" = alloca float, align 4, addrspace(5) + %"340" = alloca float, align 4, addrspace(5) + %"341" = alloca float, align 4, addrspace(5) + %"342" = alloca float, align 4, addrspace(5) + %"343" = alloca float, align 4, addrspace(5) + %"344" = alloca float, align 4, addrspace(5) + %"345" = alloca float, align 4, addrspace(5) + %"346" = alloca float, align 4, addrspace(5) + %"347" = alloca float, align 4, addrspace(5) + %"348" = alloca float, align 4, addrspace(5) + %"349" = alloca float, align 4, addrspace(5) + %"350" = alloca float, align 4, addrspace(5) + %"351" = alloca float, align 4, addrspace(5) + %"352" = alloca float, align 4, addrspace(5) + %"353" = alloca float, align 4, addrspace(5) + %"354" = alloca float, align 4, addrspace(5) + %"355" = alloca float, align 4, addrspace(5) + %"356" = alloca float, align 4, addrspace(5) + %"357" = alloca float, align 4, addrspace(5) + %"358" = alloca float, align 4, addrspace(5) + %"359" = alloca float, align 4, addrspace(5) + %"360" = alloca float, align 4, addrspace(5) + %"361" = alloca float, align 4, addrspace(5) + %"362" = alloca float, align 4, addrspace(5) + %"363" = alloca float, align 4, addrspace(5) + %"364" = alloca float, align 4, addrspace(5) + %"365" = alloca float, align 4, addrspace(5) + %"366" = alloca float, align 4, addrspace(5) + %"367" = alloca float, align 4, addrspace(5) + %"368" = alloca float, align 4, addrspace(5) + %"369" = alloca float, align 4, addrspace(5) + %"370" = alloca float, align 4, addrspace(5) + %"371" = alloca float, align 4, addrspace(5) + %"372" = alloca float, align 4, addrspace(5) + %"373" = alloca float, align 4, addrspace(5) + %"374" = alloca float, align 4, addrspace(5) + %"375" = alloca float, align 4, addrspace(5) + %"376" = alloca float, align 4, addrspace(5) + %"377" = alloca float, align 4, addrspace(5) + %"378" = alloca float, align 4, addrspace(5) + %"379" = alloca float, align 4, addrspace(5) + %"380" = alloca float, align 4, addrspace(5) + %"381" = alloca float, align 4, addrspace(5) + %"382" = alloca float, align 4, addrspace(5) + %"383" = alloca float, align 4, addrspace(5) + %"384" = alloca float, align 4, addrspace(5) + %"385" = alloca float, align 4, addrspace(5) + %"386" = alloca float, align 4, addrspace(5) + %"387" = alloca float, align 4, addrspace(5) + %"388" = alloca float, align 4, addrspace(5) + %"389" = alloca float, align 4, addrspace(5) + %"390" = alloca float, align 4, addrspace(5) + %"391" = alloca float, align 4, addrspace(5) + %"392" = alloca float, align 4, addrspace(5) + %"393" = alloca float, align 4, addrspace(5) + %"394" = alloca float, align 4, addrspace(5) + %"395" = alloca float, align 4, addrspace(5) + %"396" = alloca float, align 4, addrspace(5) + %"397" = alloca float, align 4, addrspace(5) + %"398" = alloca float, align 4, addrspace(5) + %"399" = alloca float, align 4, addrspace(5) + %"400" = alloca float, align 4, addrspace(5) + %"401" = alloca float, align 4, addrspace(5) + %"402" = alloca float, align 4, addrspace(5) + %"403" = alloca float, align 4, addrspace(5) + %"404" = alloca float, align 4, addrspace(5) + %"405" = alloca float, align 4, addrspace(5) + %"406" = alloca float, align 4, addrspace(5) + %"407" = alloca float, align 4, addrspace(5) + %"408" = alloca float, align 4, addrspace(5) + %"409" = alloca float, align 4, addrspace(5) + %"410" = alloca float, align 4, addrspace(5) + %"411" = alloca float, align 4, addrspace(5) + %"412" = alloca float, align 4, addrspace(5) + %"413" = alloca float, align 4, addrspace(5) + %"414" = alloca float, align 4, addrspace(5) + %"415" = alloca float, align 4, addrspace(5) + %"416" = alloca float, align 4, addrspace(5) + %"417" = alloca float, align 4, addrspace(5) + %"418" = alloca float, align 4, addrspace(5) + %"419" = alloca float, align 4, addrspace(5) + %"420" = alloca float, align 4, addrspace(5) + %"421" = alloca float, align 4, addrspace(5) + %"422" = alloca float, align 4, addrspace(5) + %"423" = alloca float, align 4, addrspace(5) + %"424" = alloca float, align 4, addrspace(5) + %"425" = alloca float, align 4, addrspace(5) + %"426" = alloca float, align 4, addrspace(5) + %"427" = alloca float, align 4, addrspace(5) + %"428" = alloca float, align 4, addrspace(5) + %"429" = alloca float, align 4, addrspace(5) + %"430" = alloca float, align 4, addrspace(5) + %"431" = alloca float, align 4, addrspace(5) + %"432" = alloca float, align 4, addrspace(5) + %"433" = alloca float, align 4, addrspace(5) + %"434" = alloca float, align 4, addrspace(5) + %"435" = alloca float, align 4, addrspace(5) + %"436" = alloca float, align 4, addrspace(5) + %"437" = alloca float, align 4, addrspace(5) + %"438" = alloca float, align 4, addrspace(5) + %"439" = alloca float, align 4, addrspace(5) + %"440" = alloca float, align 4, addrspace(5) + %"441" = alloca float, align 4, addrspace(5) + %"442" = alloca float, align 4, addrspace(5) + %"443" = alloca float, align 4, addrspace(5) + %"444" = alloca float, align 4, addrspace(5) + %"445" = alloca float, align 4, addrspace(5) + %"446" = alloca float, align 4, addrspace(5) + %"447" = alloca float, align 4, addrspace(5) + %"448" = alloca float, align 4, addrspace(5) + %"449" = alloca float, align 4, addrspace(5) + %"450" = alloca float, align 4, addrspace(5) + %"451" = alloca float, align 4, addrspace(5) + %"452" = alloca float, align 4, addrspace(5) + %"453" = alloca float, align 4, addrspace(5) + %"454" = alloca float, align 4, addrspace(5) + %"455" = alloca float, align 4, addrspace(5) + %"456" = alloca float, align 4, addrspace(5) + %"457" = alloca float, align 4, addrspace(5) + %"458" = alloca float, align 4, addrspace(5) + %"459" = alloca float, align 4, addrspace(5) + %"460" = alloca float, align 4, addrspace(5) + %"461" = alloca float, align 4, addrspace(5) + %"462" = alloca float, align 4, addrspace(5) + %"463" = alloca float, align 4, addrspace(5) + %"464" = alloca float, align 4, addrspace(5) + %"465" = alloca float, align 4, addrspace(5) + %"466" = alloca float, align 4, addrspace(5) + %"467" = alloca float, align 4, addrspace(5) + %"468" = alloca float, align 4, addrspace(5) + %"469" = alloca float, align 4, addrspace(5) + %"470" = alloca float, align 4, addrspace(5) + %"471" = alloca float, align 4, addrspace(5) + %"472" = alloca float, align 4, addrspace(5) + %"473" = alloca float, align 4, addrspace(5) + %"474" = alloca float, align 4, addrspace(5) + %"475" = alloca float, align 4, addrspace(5) + %"476" = alloca float, align 4, addrspace(5) + %"477" = alloca float, align 4, addrspace(5) + %"478" = alloca float, align 4, addrspace(5) + %"479" = alloca float, align 4, addrspace(5) + %"480" = alloca float, align 4, addrspace(5) + %"481" = alloca float, align 4, addrspace(5) + %"482" = alloca float, align 4, addrspace(5) + %"483" = alloca float, align 4, addrspace(5) + %"484" = alloca float, align 4, addrspace(5) + %"485" = alloca float, align 4, addrspace(5) + %"486" = alloca float, align 4, addrspace(5) + %"487" = alloca float, align 4, addrspace(5) + %"488" = alloca float, align 4, addrspace(5) + %"489" = alloca float, align 4, addrspace(5) + %"490" = alloca float, align 4, addrspace(5) + %"491" = alloca float, align 4, addrspace(5) + %"492" = alloca float, align 4, addrspace(5) + %"493" = alloca float, align 4, addrspace(5) + %"494" = alloca float, align 4, addrspace(5) + %"495" = alloca float, align 4, addrspace(5) + %"496" = alloca float, align 4, addrspace(5) + %"497" = alloca float, align 4, addrspace(5) + %"498" = alloca float, align 4, addrspace(5) + %"499" = alloca float, align 4, addrspace(5) + %"500" = alloca float, align 4, addrspace(5) + %"501" = alloca float, align 4, addrspace(5) + %"502" = alloca float, align 4, addrspace(5) + %"503" = alloca float, align 4, addrspace(5) + %"504" = alloca float, align 4, addrspace(5) + %"505" = alloca float, align 4, addrspace(5) + %"506" = alloca float, align 4, addrspace(5) + %"507" = alloca float, align 4, addrspace(5) + %"508" = alloca float, align 4, addrspace(5) + %"509" = alloca float, align 4, addrspace(5) + %"510" = alloca float, align 4, addrspace(5) + %"511" = alloca float, align 4, addrspace(5) + %"512" = alloca float, align 4, addrspace(5) + %"513" = alloca float, align 4, addrspace(5) + %"514" = alloca float, align 4, addrspace(5) + %"515" = alloca float, align 4, addrspace(5) + %"516" = alloca float, align 4, addrspace(5) + %"517" = alloca float, align 4, addrspace(5) + %"518" = alloca float, align 4, addrspace(5) + %"519" = alloca float, align 4, addrspace(5) + %"520" = alloca float, align 4, addrspace(5) + %"521" = alloca float, align 4, addrspace(5) + %"522" = alloca float, align 4, addrspace(5) + %"523" = alloca float, align 4, addrspace(5) + %"524" = alloca float, align 4, addrspace(5) + %"525" = alloca float, align 4, addrspace(5) + %"526" = alloca float, align 4, addrspace(5) + %"527" = alloca float, align 4, addrspace(5) + %"528" = alloca float, align 4, addrspace(5) + %"529" = alloca float, align 4, addrspace(5) + %"530" = alloca float, align 4, addrspace(5) + %"531" = alloca float, align 4, addrspace(5) + %"532" = alloca float, align 4, addrspace(5) + %"533" = alloca float, align 4, addrspace(5) + %"534" = alloca float, align 4, addrspace(5) + %"535" = alloca float, align 4, addrspace(5) + %"536" = alloca float, align 4, addrspace(5) + %"537" = alloca float, align 4, addrspace(5) + %"538" = alloca float, align 4, addrspace(5) + %"539" = alloca float, align 4, addrspace(5) + %"540" = alloca float, align 4, addrspace(5) + %"541" = alloca float, align 4, addrspace(5) + %"542" = alloca float, align 4, addrspace(5) + %"543" = alloca float, align 4, addrspace(5) + %"544" = alloca float, align 4, addrspace(5) + %"545" = alloca float, align 4, addrspace(5) + %"546" = alloca float, align 4, addrspace(5) + %"547" = alloca float, align 4, addrspace(5) + %"548" = alloca float, align 4, addrspace(5) + %"549" = alloca float, align 4, addrspace(5) + %"550" = alloca float, align 4, addrspace(5) + %"551" = alloca float, align 4, addrspace(5) + %"552" = alloca float, align 4, addrspace(5) + %"553" = alloca float, align 4, addrspace(5) + %"554" = alloca float, align 4, addrspace(5) + %"555" = alloca float, align 4, addrspace(5) + %"556" = alloca float, align 4, addrspace(5) + %"557" = alloca float, align 4, addrspace(5) + %"558" = alloca float, align 4, addrspace(5) + %"559" = alloca i32, align 4, addrspace(5) + %"560" = alloca i32, align 4, addrspace(5) + %"561" = alloca i32, align 4, addrspace(5) + %"562" = alloca i32, align 4, addrspace(5) + %"563" = alloca i32, align 4, addrspace(5) + %"564" = alloca i32, align 4, addrspace(5) + %"565" = alloca i32, align 4, addrspace(5) + %"566" = alloca i32, align 4, addrspace(5) + %"567" = alloca i32, align 4, addrspace(5) + %"568" = alloca i32, align 4, addrspace(5) + %"569" = alloca i32, align 4, addrspace(5) + %"570" = alloca i32, align 4, addrspace(5) + %"571" = alloca i32, align 4, addrspace(5) + %"572" = alloca i32, align 4, addrspace(5) + %"573" = alloca i32, align 4, addrspace(5) + %"574" = alloca i32, align 4, addrspace(5) + %"575" = alloca i32, align 4, addrspace(5) + %"576" = alloca i32, align 4, addrspace(5) + %"577" = alloca i32, align 4, addrspace(5) + %"578" = alloca i32, align 4, addrspace(5) + %"579" = alloca i32, align 4, addrspace(5) + %"580" = alloca i32, align 4, addrspace(5) + %"581" = alloca i32, align 4, addrspace(5) + %"582" = alloca i32, align 4, addrspace(5) + %"583" = alloca i32, align 4, addrspace(5) + %"584" = alloca i32, align 4, addrspace(5) + %"585" = alloca i32, align 4, addrspace(5) + %"586" = alloca i32, align 4, addrspace(5) + %"587" = alloca i32, align 4, addrspace(5) + %"588" = alloca i32, align 4, addrspace(5) + %"589" = alloca i32, align 4, addrspace(5) + %"590" = alloca i32, align 4, addrspace(5) + %"591" = alloca i32, align 4, addrspace(5) + %"592" = alloca i32, align 4, addrspace(5) + %"593" = alloca i32, align 4, addrspace(5) + %"594" = alloca i32, align 4, addrspace(5) + %"595" = alloca i32, align 4, addrspace(5) + %"596" = alloca i32, align 4, addrspace(5) + %"597" = alloca i32, align 4, addrspace(5) + %"598" = alloca i32, align 4, addrspace(5) + %"599" = alloca i32, align 4, addrspace(5) + %"600" = alloca i32, align 4, addrspace(5) + %"601" = alloca i32, align 4, addrspace(5) + %"602" = alloca i32, align 4, addrspace(5) + %"603" = alloca i32, align 4, addrspace(5) + %"604" = alloca i32, align 4, addrspace(5) + %"605" = alloca i32, align 4, addrspace(5) + %"606" = alloca i32, align 4, addrspace(5) + %"607" = alloca i64, align 8, addrspace(5) + %"608" = alloca i64, align 8, addrspace(5) + %"609" = alloca i64, align 8, addrspace(5) + %"610" = alloca i64, align 8, addrspace(5) + %"611" = alloca i64, align 8, addrspace(5) + %"612" = alloca i64, align 8, addrspace(5) + %"613" = alloca i64, align 8, addrspace(5) + %"614" = alloca i64, align 8, addrspace(5) + %"615" = alloca i64, align 8, addrspace(5) + %"616" = alloca i64, align 8, addrspace(5) + %"617" = alloca i64, align 8, addrspace(5) + %"618" = alloca i64, align 8, addrspace(5) + %"619" = alloca i64, align 8, addrspace(5) + %"620" = alloca i64, align 8, addrspace(5) + %"621" = alloca i64, align 8, addrspace(5) + %"622" = alloca i64, align 8, addrspace(5) + %"623" = alloca i64, align 8, addrspace(5) + %"624" = alloca i64, align 8, addrspace(5) + %"625" = alloca i64, align 8, addrspace(5) + %"626" = alloca i64, align 8, addrspace(5) + %"627" = alloca i64, align 8, addrspace(5) + %"628" = alloca i64, align 8, addrspace(5) + %"629" = alloca i64, align 8, addrspace(5) + %"630" = alloca i64, align 8, addrspace(5) + %"631" = alloca i64, align 8, addrspace(5) + %"632" = alloca i64, align 8, addrspace(5) + %"633" = alloca i64, align 8, addrspace(5) + %"634" = alloca i64, align 8, addrspace(5) + %"635" = alloca i64, align 8, addrspace(5) + %"636" = alloca i64, align 8, addrspace(5) + %"637" = alloca i64, align 8, addrspace(5) + %"638" = alloca i64, align 8, addrspace(5) + %"639" = alloca i64, align 8, addrspace(5) + %"640" = alloca i64, align 8, addrspace(5) + %"641" = alloca i64, align 8, addrspace(5) + %"642" = alloca i64, align 8, addrspace(5) + %"643" = alloca i64, align 8, addrspace(5) + %"644" = alloca i64, align 8, addrspace(5) + %"645" = alloca i64, align 8, addrspace(5) + %"646" = alloca i64, align 8, addrspace(5) + %"647" = alloca i64, align 8, addrspace(5) + %"648" = alloca i64, align 8, addrspace(5) + %"649" = alloca i64, align 8, addrspace(5) + %"650" = alloca i64, align 8, addrspace(5) + %"651" = alloca i64, align 8, addrspace(5) + %"652" = alloca i64, align 8, addrspace(5) + %"653" = alloca i64, align 8, addrspace(5) + %"654" = alloca i64, align 8, addrspace(5) + %"655" = alloca i64, align 8, addrspace(5) + %"656" = alloca i64, align 8, addrspace(5) + %"657" = alloca i64, align 8, addrspace(5) + %"658" = alloca i64, align 8, addrspace(5) + %"659" = alloca i64, align 8, addrspace(5) + %"660" = alloca i64, align 8, addrspace(5) + %"661" = alloca i64, align 8, addrspace(5) + %"662" = alloca i64, align 8, addrspace(5) + %"663" = alloca i64, align 8, addrspace(5) + %"664" = alloca i64, align 8, addrspace(5) + %"665" = alloca i64, align 8, addrspace(5) + %"666" = alloca i64, align 8, addrspace(5) + %"667" = alloca i64, align 8, addrspace(5) + %"668" = alloca i64, align 8, addrspace(5) + %"669" = alloca i64, align 8, addrspace(5) + %"670" = alloca i64, align 8, addrspace(5) + %"671" = alloca i64, align 8, addrspace(5) + %"672" = alloca i64, align 8, addrspace(5) + %"673" = alloca i64, align 8, addrspace(5) + %"674" = alloca i64, align 8, addrspace(5) + %"675" = alloca i64, align 8, addrspace(5) + %"676" = alloca i64, align 8, addrspace(5) + %"677" = alloca i64, align 8, addrspace(5) + %"678" = alloca i64, align 8, addrspace(5) + %"679" = alloca i64, align 8, addrspace(5) + %"680" = alloca i64, align 8, addrspace(5) + %"681" = alloca i64, align 8, addrspace(5) + %"682" = alloca i64, align 8, addrspace(5) + %"683" = alloca i64, align 8, addrspace(5) + %"684" = alloca i64, align 8, addrspace(5) + %"685" = alloca i64, align 8, addrspace(5) + %"686" = alloca i64, align 8, addrspace(5) + %"687" = alloca i64, align 8, addrspace(5) + %"688" = alloca i64, align 8, addrspace(5) + %"689" = alloca i64, align 8, addrspace(5) + %"690" = alloca i64, align 8, addrspace(5) + %"691" = alloca i64, align 8, addrspace(5) + %"692" = alloca i64, align 8, addrspace(5) + %"693" = alloca i64, align 8, addrspace(5) + %"694" = alloca i64, align 8, addrspace(5) + %"695" = alloca i64, align 8, addrspace(5) + %"696" = alloca i64, align 8, addrspace(5) + %"697" = alloca i64, align 8, addrspace(5) + %"698" = alloca i64, align 8, addrspace(5) + %"699" = alloca i64, align 8, addrspace(5) + %"700" = alloca i64, align 8, addrspace(5) + %"701" = alloca i64, align 8, addrspace(5) + %"702" = alloca i32, align 4, addrspace(5) + %"2075" = alloca i64, align 8, addrspace(5) + %"2077" = alloca i64, align 8, addrspace(5) + %"2079" = alloca i64, align 8, addrspace(5) + %"707" = alloca i32, align 4, addrspace(5) + %"2081" = alloca i64, align 8, addrspace(5) + %"2083" = alloca i64, align 8, addrspace(5) + %"2085" = alloca i64, align 8, addrspace(5) + %"712" = alloca i32, align 4, addrspace(5) + %"2087" = alloca i64, align 8, addrspace(5) + %"2089" = alloca i64, align 8, addrspace(5) + %"2091" = alloca i64, align 8, addrspace(5) + %"2093" = alloca [3 x i32], align 4, addrspace(5) + %"718" = alloca i32, align 4, addrspace(5) + %"2097" = alloca i64, align 8, addrspace(5) + %"2099" = alloca i64, align 8, addrspace(5) + %"2101" = alloca i64, align 8, addrspace(5) + %"723" = alloca i32, align 4, addrspace(5) + %"2103" = alloca i64, align 8, addrspace(5) + %"2105" = alloca i64, align 8, addrspace(5) + %"2107" = alloca i64, align 8, addrspace(5) + %"728" = alloca i32, align 4, addrspace(5) + %"2109" = alloca i64, align 8, addrspace(5) + %"2111" = alloca i64, align 8, addrspace(5) + %"2113" = alloca i64, align 8, addrspace(5) + %"2115" = alloca [3 x i32], align 4, addrspace(5) + %"2394" = ptrtoint ptr addrspace(5) %"312" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"2394", ptr addrspace(5) %0, align 8 + %"2393" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"2393", ptr addrspace(5) %"314", align 8 + %"858" = load i64, ptr addrspace(5) %"314", align 8 + %1 = inttoptr i64 %"858" to ptr addrspace(5) + %2 = addrspacecast ptr addrspace(5) %1 to ptr + %"857" = ptrtoint ptr %2 to i64 + store i64 %"857", ptr addrspace(5) %"313", align 8 + %"860" = load i64, ptr addrspace(5) %"313", align 8 + %"2395" = add i64 %"860", 116 + store i64 %"2395", ptr addrspace(5) %"617", align 8 + %"862" = load i64, ptr addrspace(5) %"314", align 8 + %"2397" = add i64 %"862", 116 + store i64 %"2397", ptr addrspace(5) %"608", align 8 + %3 = alloca i64, align 8, addrspace(5) + store i64 0, ptr addrspace(5) %3, align 8 + %"2399" = load i64, ptr addrspace(5) %3, align 8 + store i64 %"2399", ptr addrspace(5) %"616", align 8 + %"2140" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 12) + %"864" = load float, ptr addrspace(1) %"2140", align 4 + store float %"864", ptr addrspace(5) %"360", align 4 + %"2142" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 12) + %"2715" = getelementptr inbounds i8, ptr addrspace(1) %"2142", i64 4 + %"865" = load float, ptr addrspace(1) %"2715", align 4 + store float %"865", ptr addrspace(5) %"361", align 4 + %"2145" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 12) + %"2717" = getelementptr inbounds i8, ptr addrspace(1) %"2145", i64 8 + %"866" = load float, ptr addrspace(1) %"2717", align 4 + store float %"866", ptr addrspace(5) %"362", align 4 + %4 = alloca i32, align 4, addrspace(5) + store i32 7937, ptr addrspace(5) %4, align 4 + %"2403" = load i32, ptr addrspace(5) %4, align 4 + store i32 %"2403", ptr addrspace(5) %"563", align 4 + %5 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %5, align 4 + %"868" = load float, ptr addrspace(5) %5, align 4 + store float %"868", ptr addrspace(5) %"556", align 4 + %"873" = load i32, ptr addrspace(5) %"563", align 4 + %"874" = load float, ptr addrspace(5) %"360", align 4 + %"875" = load float, ptr addrspace(5) %"361", align 4 + %"876" = load float, ptr addrspace(5) %"362", align 4 + %"877" = load float, ptr addrspace(5) %"556", align 4 + %6 = call %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32 %"873", float %"874", float %"875", float %"876", float %"877") + %"869" = extractvalue %struct.f32f32f32f32 %6, 0 + %"870" = extractvalue %struct.f32f32f32f32 %6, 1 + %"871" = extractvalue %struct.f32f32f32f32 %6, 2 + %"872" = extractvalue %struct.f32f32f32f32 %6, 3 + store float %"869", ptr addrspace(5) %"356", align 4 + store float %"870", ptr addrspace(5) %"357", align 4 + store float %"871", ptr addrspace(5) %"358", align 4 + store float %"872", ptr addrspace(5) %"359", align 4 + %"879" = load float, ptr addrspace(5) %"357", align 4 + %"880" = load float, ptr addrspace(5) %"357", align 4 + %"878" = fmul float %"879", %"880" + store float %"878", ptr addrspace(5) %"372", align 4 + %"882" = load float, ptr addrspace(5) %"356", align 4 + %"883" = load float, ptr addrspace(5) %"356", align 4 + %"884" = load float, ptr addrspace(5) %"372", align 4 + %"881" = call float @llvm.fma.f32(float %"882", float %"883", float %"884") + store float %"881", ptr addrspace(5) %"373", align 4 + %"886" = load float, ptr addrspace(5) %"358", align 4 + %"887" = load float, ptr addrspace(5) %"358", align 4 + %"888" = load float, ptr addrspace(5) %"373", align 4 + %"885" = call float @llvm.fma.f32(float %"886", float %"887", float %"888") + store float %"885", ptr addrspace(5) %"374", align 4 + %"890" = load float, ptr addrspace(5) %"374", align 4 + %7 = call afn float @llvm.sqrt.f32(float %"890") + %"889" = fdiv arcp afn float 1.000000e+00, %7 + store float %"889", ptr addrspace(5) %"375", align 4 + %"892" = load float, ptr addrspace(5) %"375", align 4 + %"893" = load float, ptr addrspace(5) %"356", align 4 + %"891" = fmul float %"892", %"893" + store float %"891", ptr addrspace(5) %"329", align 4 + %"895" = load float, ptr addrspace(5) %"375", align 4 + %"896" = load float, ptr addrspace(5) %"357", align 4 + %"894" = fmul float %"895", %"896" + store float %"894", ptr addrspace(5) %"330", align 4 + %"898" = load float, ptr addrspace(5) %"375", align 4 + %"899" = load float, ptr addrspace(5) %"358", align 4 + %"897" = fmul float %"898", %"899" + store float %"897", ptr addrspace(5) %"331", align 4 + %"2148" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 48) + %"900" = load float, ptr addrspace(1) %"2148", align 4 + store float %"900", ptr addrspace(5) %"368", align 4 + %"2150" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 48) + %"2719" = getelementptr inbounds i8, ptr addrspace(1) %"2150", i64 4 + %"901" = load float, ptr addrspace(1) %"2719", align 4 + store float %"901", ptr addrspace(5) %"369", align 4 + %"2153" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 48) + %"2721" = getelementptr inbounds i8, ptr addrspace(1) %"2153", i64 8 + %"902" = load float, ptr addrspace(1) %"2721", align 4 + store float %"902", ptr addrspace(5) %"370", align 4 + %"907" = load i32, ptr addrspace(5) %"563", align 4 + %"908" = load float, ptr addrspace(5) %"368", align 4 + %"909" = load float, ptr addrspace(5) %"369", align 4 + %"910" = load float, ptr addrspace(5) %"370", align 4 + %"911" = load float, ptr addrspace(5) %"556", align 4 + %8 = call %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32 %"907", float %"908", float %"909", float %"910", float %"911") + %"903" = extractvalue %struct.f32f32f32f32 %8, 0 + %"904" = extractvalue %struct.f32f32f32f32 %8, 1 + %"905" = extractvalue %struct.f32f32f32f32 %8, 2 + %"906" = extractvalue %struct.f32f32f32f32 %8, 3 + store float %"903", ptr addrspace(5) %"364", align 4 + store float %"904", ptr addrspace(5) %"365", align 4 + store float %"905", ptr addrspace(5) %"366", align 4 + store float %"906", ptr addrspace(5) %"367", align 4 + %"913" = load float, ptr addrspace(5) %"365", align 4 + %"914" = load float, ptr addrspace(5) %"365", align 4 + %"912" = fmul float %"913", %"914" + store float %"912", ptr addrspace(5) %"376", align 4 + %"916" = load float, ptr addrspace(5) %"364", align 4 + %"917" = load float, ptr addrspace(5) %"364", align 4 + %"918" = load float, ptr addrspace(5) %"376", align 4 + %"915" = call float @llvm.fma.f32(float %"916", float %"917", float %"918") + store float %"915", ptr addrspace(5) %"377", align 4 + %"920" = load float, ptr addrspace(5) %"366", align 4 + %"921" = load float, ptr addrspace(5) %"366", align 4 + %"922" = load float, ptr addrspace(5) %"377", align 4 + %"919" = call float @llvm.fma.f32(float %"920", float %"921", float %"922") + store float %"919", ptr addrspace(5) %"378", align 4 + %"924" = load float, ptr addrspace(5) %"378", align 4 + %9 = call afn float @llvm.sqrt.f32(float %"924") + %"923" = fdiv arcp afn float 1.000000e+00, %9 + store float %"923", ptr addrspace(5) %"379", align 4 + %"926" = load float, ptr addrspace(5) %"379", align 4 + %"927" = load float, ptr addrspace(5) %"364", align 4 + %"925" = fmul float %"926", %"927" + store float %"925", ptr addrspace(5) %"380", align 4 + %"929" = load float, ptr addrspace(5) %"379", align 4 + %"930" = load float, ptr addrspace(5) %"365", align 4 + %"928" = fmul float %"929", %"930" + store float %"928", ptr addrspace(5) %"381", align 4 + %"932" = load float, ptr addrspace(5) %"379", align 4 + %"933" = load float, ptr addrspace(5) %"366", align 4 + %"931" = fmul float %"932", %"933" + store float %"931", ptr addrspace(5) %"382", align 4 + %"2723" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 12 + %"934" = load float, ptr addrspace(5) %"2723", align 4 + store float %"934", ptr addrspace(5) %"383", align 4 + %"936" = load float, ptr addrspace(5) %"383", align 4 + %"937" = load float, ptr addrspace(5) %"380", align 4 + %"935" = fmul float %"936", %"937" + store float %"935", ptr addrspace(5) %"384", align 4 + %"2725" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 16 + %"938" = load float, ptr addrspace(5) %"2725", align 4 + store float %"938", ptr addrspace(5) %"385", align 4 + %"940" = load float, ptr addrspace(5) %"385", align 4 + %"941" = load float, ptr addrspace(5) %"381", align 4 + %"939" = fmul float %"940", %"941" + store float %"939", ptr addrspace(5) %"386", align 4 + %"943" = load float, ptr addrspace(5) %"386", align 4 + %"942" = fsub float 0.000000e+00, %"943" + store float %"942", ptr addrspace(5) %"387", align 4 + %"945" = load float, ptr addrspace(5) %"387", align 4 + %"946" = load float, ptr addrspace(5) %"384", align 4 + %"944" = fsub float %"945", %"946" + store float %"944", ptr addrspace(5) %"388", align 4 + %"2727" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 20 + %"947" = load float, ptr addrspace(5) %"2727", align 4 + store float %"947", ptr addrspace(5) %"389", align 4 + %"949" = load float, ptr addrspace(5) %"389", align 4 + %"950" = load float, ptr addrspace(5) %"382", align 4 + %"948" = fmul float %"949", %"950" + store float %"948", ptr addrspace(5) %"390", align 4 + %"952" = load float, ptr addrspace(5) %"388", align 4 + %"953" = load float, ptr addrspace(5) %"390", align 4 + %"951" = fsub float %"952", %"953" + store float %"951", ptr addrspace(5) %"391", align 4 + %"955" = load float, ptr addrspace(5) %"391", align 4 + %"2410" = bitcast float %"955" to i32 + %10 = alloca i32, align 4, addrspace(5) + store i32 %"2410", ptr addrspace(5) %10, align 4 + %"954" = load i32, ptr addrspace(5) %10, align 4 + store i32 %"954", ptr addrspace(5) %"566", align 4 + %"957" = load i32, ptr addrspace(5) %"566", align 4 + %"956" = and i32 %"957", -2147483648 + store i32 %"956", ptr addrspace(5) %"567", align 4 + %"959" = load i32, ptr addrspace(5) %"567", align 4 + %"958" = or i32 %"959", 1065353216 + store i32 %"958", ptr addrspace(5) %"568", align 4 + %"961" = load i32, ptr addrspace(5) %"568", align 4 + %11 = alloca i32, align 4, addrspace(5) + store i32 %"961", ptr addrspace(5) %11, align 4 + %"2411" = load i32, ptr addrspace(5) %11, align 4 + %"960" = bitcast i32 %"2411" to float + store float %"960", ptr addrspace(5) %"392", align 4 + %"963" = load float, ptr addrspace(5) %"329", align 4 + %"964" = load float, ptr addrspace(5) %"392", align 4 + %"962" = fmul float %"963", %"964" + store float %"962", ptr addrspace(5) %"332", align 4 + %"966" = load float, ptr addrspace(5) %"330", align 4 + %"967" = load float, ptr addrspace(5) %"392", align 4 + %"965" = fmul float %"966", %"967" + store float %"965", ptr addrspace(5) %"333", align 4 + %"969" = load float, ptr addrspace(5) %"331", align 4 + %"970" = load float, ptr addrspace(5) %"392", align 4 + %"968" = fmul float %"969", %"970" + store float %"968", ptr addrspace(5) %"334", align 4 + %"2159" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 160) + %"2412" = load i32, ptr addrspace(1) %"2159", align 4 + %"971" = sext i32 %"2412" to i64 + store i64 %"971", ptr addrspace(5) %"613", align 8 + %"2161" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 104) + %"2415" = ptrtoint ptr addrspace(1) %"2161" to i64 + %12 = alloca i64, align 8, addrspace(5) + store i64 %"2415", ptr addrspace(5) %12, align 8 + %"2414" = load i64, ptr addrspace(5) %12, align 8 + store i64 %"2414", ptr addrspace(5) %"618", align 8 + %"974" = load i64, ptr addrspace(5) %"618", align 8 + %13 = inttoptr i64 %"974" to ptr addrspace(1) + %14 = addrspacecast ptr addrspace(1) %13 to ptr + %"973" = ptrtoint ptr %14 to i64 + store i64 %"973", ptr addrspace(5) %"612", align 8 + %15 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %15, align 4 + %"2416" = load i32, ptr addrspace(5) %15, align 4 + store i32 %"2416", ptr addrspace(5) %"564", align 4 + %16 = alloca i32, align 4, addrspace(5) + store i32 72, ptr addrspace(5) %16, align 4 + %"2417" = load i32, ptr addrspace(5) %16, align 4 + store i32 %"2417", ptr addrspace(5) %"565", align 4 + %"978" = load i64, ptr addrspace(5) %"612", align 8 + %"979" = load i32, ptr addrspace(5) %"564", align 4 + %"980" = load i32, ptr addrspace(5) %"565", align 4 + %"981" = load i64, ptr addrspace(5) %"613", align 8 + %"982" = load i64, ptr addrspace(5) %"616", align 8 + %"983" = load i64, ptr addrspace(5) %"616", align 8 + %"984" = load i64, ptr addrspace(5) %"616", align 8 + %"977" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"978", i32 %"979", i32 %"980", i64 %"981", i64 %"982", i64 %"983", i64 %"984") + store i64 %"977", ptr addrspace(5) %"611", align 8 + %"986" = load i64, ptr addrspace(5) %"611", align 8 + %"2419" = inttoptr i64 %"986" to ptr + %"2418" = load i32, ptr %"2419", align 4 + store i32 %"2418", ptr addrspace(5) %"560", align 4 + %"988" = load i64, ptr addrspace(5) %"611", align 8 + %"2420" = inttoptr i64 %"988" to ptr + %"2729" = getelementptr inbounds i8, ptr %"2420", i64 4 + %"987" = load float, ptr %"2729", align 4 + store float %"987", ptr addrspace(5) %"393", align 4 + %"990" = load i64, ptr addrspace(5) %"611", align 8 + %"2421" = inttoptr i64 %"990" to ptr + %"2731" = getelementptr inbounds i8, ptr %"2421", i64 8 + %"989" = load float, ptr %"2731", align 4 + store float %"989", ptr addrspace(5) %"394", align 4 + %"992" = load i64, ptr addrspace(5) %"611", align 8 + %"2422" = inttoptr i64 %"992" to ptr + %"2733" = getelementptr inbounds i8, ptr %"2422", i64 12 + %"991" = load float, ptr %"2733", align 4 + store float %"991", ptr addrspace(5) %"395", align 4 + %"994" = load i64, ptr addrspace(5) %"611", align 8 + %"2423" = inttoptr i64 %"994" to ptr + %"2735" = getelementptr inbounds i8, ptr %"2423", i64 16 + %"993" = load float, ptr %"2735", align 4 + store float %"993", ptr addrspace(5) %"335", align 4 + %"996" = load i64, ptr addrspace(5) %"611", align 8 + %"2424" = inttoptr i64 %"996" to ptr + %"2737" = getelementptr inbounds i8, ptr %"2424", i64 20 + %"995" = load float, ptr %"2737", align 4 + store float %"995", ptr addrspace(5) %"336", align 4 + %"998" = load i64, ptr addrspace(5) %"611", align 8 + %"2425" = inttoptr i64 %"998" to ptr + %"2739" = getelementptr inbounds i8, ptr %"2425", i64 24 + %"997" = load float, ptr %"2739", align 4 + store float %"997", ptr addrspace(5) %"337", align 4 + %"1000" = load i64, ptr addrspace(5) %"611", align 8 + %"2426" = inttoptr i64 %"1000" to ptr + %"2741" = getelementptr inbounds i8, ptr %"2426", i64 28 + %"999" = load float, ptr %"2741", align 4 + store float %"999", ptr addrspace(5) %"396", align 4 + %"1002" = load i64, ptr addrspace(5) %"611", align 8 + %"2427" = inttoptr i64 %"1002" to ptr + %"2743" = getelementptr inbounds i8, ptr %"2427", i64 32 + %"1001" = load float, ptr %"2743", align 4 + store float %"1001", ptr addrspace(5) %"397", align 4 + %"1004" = load i64, ptr addrspace(5) %"611", align 8 + %"2428" = inttoptr i64 %"1004" to ptr + %"2745" = getelementptr inbounds i8, ptr %"2428", i64 36 + %"1003" = load float, ptr %"2745", align 4 + store float %"1003", ptr addrspace(5) %"398", align 4 + %"1006" = load i64, ptr addrspace(5) %"611", align 8 + %"2429" = inttoptr i64 %"1006" to ptr + %"2747" = getelementptr inbounds i8, ptr %"2429", i64 40 + %"1005" = load float, ptr %"2747", align 4 + store float %"1005", ptr addrspace(5) %"399", align 4 + %"1008" = load i64, ptr addrspace(5) %"611", align 8 + %"2430" = inttoptr i64 %"1008" to ptr + %"2749" = getelementptr inbounds i8, ptr %"2430", i64 44 + %"1007" = load float, ptr %"2749", align 4 + store float %"1007", ptr addrspace(5) %"400", align 4 + %"1010" = load i64, ptr addrspace(5) %"611", align 8 + %"2431" = inttoptr i64 %"1010" to ptr + %"2751" = getelementptr inbounds i8, ptr %"2431", i64 48 + %"1009" = load float, ptr %"2751", align 4 + store float %"1009", ptr addrspace(5) %"401", align 4 + %"1012" = load i64, ptr addrspace(5) %"611", align 8 + %"2432" = inttoptr i64 %"1012" to ptr + %"2753" = getelementptr inbounds i8, ptr %"2432", i64 52 + %"1011" = load float, ptr %"2753", align 4 + store float %"1011", ptr addrspace(5) %"402", align 4 + %"1014" = load i64, ptr addrspace(5) %"611", align 8 + %"2433" = inttoptr i64 %"1014" to ptr + %"2755" = getelementptr inbounds i8, ptr %"2433", i64 56 + %"1013" = load float, ptr %"2755", align 4 + store float %"1013", ptr addrspace(5) %"403", align 4 + %"1016" = load i64, ptr addrspace(5) %"611", align 8 + %"2434" = inttoptr i64 %"1016" to ptr + %"2757" = getelementptr inbounds i8, ptr %"2434", i64 60 + %"1015" = load float, ptr %"2757", align 4 + store float %"1015", ptr addrspace(5) %"404", align 4 + %"1018" = load i64, ptr addrspace(5) %"611", align 8 + %"2435" = inttoptr i64 %"1018" to ptr + %"2759" = getelementptr inbounds i8, ptr %"2435", i64 64 + %"1017" = load float, ptr %"2759", align 4 + store float %"1017", ptr addrspace(5) %"405", align 4 + %"1020" = load i64, ptr addrspace(5) %"611", align 8 + %"2436" = inttoptr i64 %"1020" to ptr + %"2761" = getelementptr inbounds i8, ptr %"2436", i64 68 + %"2437" = load i32, ptr %"2761", align 4 + store i32 %"2437", ptr addrspace(5) %"561", align 4 + %"1021" = load i64, ptr addrspace(5) %"608", align 8 + %"1022" = load i32, ptr addrspace(5) %"560", align 4 + %"2438" = inttoptr i64 %"1021" to ptr addrspace(5) + store i32 %"1022", ptr addrspace(5) %"2438", align 4 + %"1023" = load i64, ptr addrspace(5) %"608", align 8 + %"1024" = load float, ptr addrspace(5) %"393", align 4 + %"2440" = inttoptr i64 %"1023" to ptr addrspace(5) + %"2763" = getelementptr inbounds i8, ptr addrspace(5) %"2440", i64 4 + store float %"1024", ptr addrspace(5) %"2763", align 4 + %"1025" = load i64, ptr addrspace(5) %"608", align 8 + %"1026" = load float, ptr addrspace(5) %"394", align 4 + %"2441" = inttoptr i64 %"1025" to ptr addrspace(5) + %"2765" = getelementptr inbounds i8, ptr addrspace(5) %"2441", i64 8 + store float %"1026", ptr addrspace(5) %"2765", align 4 + %"1027" = load i64, ptr addrspace(5) %"608", align 8 + %"1028" = load float, ptr addrspace(5) %"395", align 4 + %"2442" = inttoptr i64 %"1027" to ptr addrspace(5) + %"2767" = getelementptr inbounds i8, ptr addrspace(5) %"2442", i64 12 + store float %"1028", ptr addrspace(5) %"2767", align 4 + %"1029" = load i64, ptr addrspace(5) %"608", align 8 + %"1030" = load float, ptr addrspace(5) %"335", align 4 + %"2443" = inttoptr i64 %"1029" to ptr addrspace(5) + %"2769" = getelementptr inbounds i8, ptr addrspace(5) %"2443", i64 16 + store float %"1030", ptr addrspace(5) %"2769", align 4 + %"1031" = load i64, ptr addrspace(5) %"608", align 8 + %"1032" = load float, ptr addrspace(5) %"336", align 4 + %"2444" = inttoptr i64 %"1031" to ptr addrspace(5) + %"2771" = getelementptr inbounds i8, ptr addrspace(5) %"2444", i64 20 + store float %"1032", ptr addrspace(5) %"2771", align 4 + %"1033" = load i64, ptr addrspace(5) %"608", align 8 + %"1034" = load float, ptr addrspace(5) %"337", align 4 + %"2445" = inttoptr i64 %"1033" to ptr addrspace(5) + %"2773" = getelementptr inbounds i8, ptr addrspace(5) %"2445", i64 24 + store float %"1034", ptr addrspace(5) %"2773", align 4 + %"1035" = load i64, ptr addrspace(5) %"608", align 8 + %"1036" = load float, ptr addrspace(5) %"396", align 4 + %"2446" = inttoptr i64 %"1035" to ptr addrspace(5) + %"2775" = getelementptr inbounds i8, ptr addrspace(5) %"2446", i64 28 + store float %"1036", ptr addrspace(5) %"2775", align 4 + %"1037" = load i64, ptr addrspace(5) %"608", align 8 + %"1038" = load float, ptr addrspace(5) %"397", align 4 + %"2447" = inttoptr i64 %"1037" to ptr addrspace(5) + %"2777" = getelementptr inbounds i8, ptr addrspace(5) %"2447", i64 32 + store float %"1038", ptr addrspace(5) %"2777", align 4 + %"1039" = load i64, ptr addrspace(5) %"608", align 8 + %"1040" = load float, ptr addrspace(5) %"398", align 4 + %"2448" = inttoptr i64 %"1039" to ptr addrspace(5) + %"2779" = getelementptr inbounds i8, ptr addrspace(5) %"2448", i64 36 + store float %"1040", ptr addrspace(5) %"2779", align 4 + %"1041" = load i64, ptr addrspace(5) %"608", align 8 + %"1042" = load float, ptr addrspace(5) %"399", align 4 + %"2449" = inttoptr i64 %"1041" to ptr addrspace(5) + %"2781" = getelementptr inbounds i8, ptr addrspace(5) %"2449", i64 40 + store float %"1042", ptr addrspace(5) %"2781", align 4 + %"1043" = load i64, ptr addrspace(5) %"608", align 8 + %"1044" = load float, ptr addrspace(5) %"400", align 4 + %"2450" = inttoptr i64 %"1043" to ptr addrspace(5) + %"2783" = getelementptr inbounds i8, ptr addrspace(5) %"2450", i64 44 + store float %"1044", ptr addrspace(5) %"2783", align 4 + %"1045" = load i64, ptr addrspace(5) %"608", align 8 + %"1046" = load float, ptr addrspace(5) %"401", align 4 + %"2451" = inttoptr i64 %"1045" to ptr addrspace(5) + %"2785" = getelementptr inbounds i8, ptr addrspace(5) %"2451", i64 48 + store float %"1046", ptr addrspace(5) %"2785", align 4 + %"1047" = load i64, ptr addrspace(5) %"608", align 8 + %"1048" = load float, ptr addrspace(5) %"402", align 4 + %"2452" = inttoptr i64 %"1047" to ptr addrspace(5) + %"2787" = getelementptr inbounds i8, ptr addrspace(5) %"2452", i64 52 + store float %"1048", ptr addrspace(5) %"2787", align 4 + %"1049" = load i64, ptr addrspace(5) %"608", align 8 + %"1050" = load float, ptr addrspace(5) %"403", align 4 + %"2453" = inttoptr i64 %"1049" to ptr addrspace(5) + %"2789" = getelementptr inbounds i8, ptr addrspace(5) %"2453", i64 56 + store float %"1050", ptr addrspace(5) %"2789", align 4 + %"1051" = load i64, ptr addrspace(5) %"608", align 8 + %"1052" = load float, ptr addrspace(5) %"404", align 4 + %"2454" = inttoptr i64 %"1051" to ptr addrspace(5) + %"2791" = getelementptr inbounds i8, ptr addrspace(5) %"2454", i64 60 + store float %"1052", ptr addrspace(5) %"2791", align 4 + %"1053" = load i64, ptr addrspace(5) %"608", align 8 + %"1054" = load float, ptr addrspace(5) %"405", align 4 + %"2455" = inttoptr i64 %"1053" to ptr addrspace(5) + %"2793" = getelementptr inbounds i8, ptr addrspace(5) %"2455", i64 64 + store float %"1054", ptr addrspace(5) %"2793", align 4 + %"1055" = load i64, ptr addrspace(5) %"608", align 8 + %"1056" = load i32, ptr addrspace(5) %"561", align 4 + %"2456" = inttoptr i64 %"1055" to ptr addrspace(5) + %"2795" = getelementptr inbounds i8, ptr addrspace(5) %"2456", i64 68 + store i32 %"1056", ptr addrspace(5) %"2795", align 4 + %"1058" = load i32, ptr addrspace(5) %"560", align 4 + %"1057" = icmp eq i32 %"1058", 0 + store i1 %"1057", ptr addrspace(5) %"316", align 1 + %"1059" = load i1, ptr addrspace(5) %"316", align 1 + br i1 %"1059", label %"306", label %"735" + +"735": ; preds = %"2703" + %"2163" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 36) + %"1060" = load float, ptr addrspace(1) %"2163", align 4 + store float %"1060", ptr addrspace(5) %"410", align 4 + %"2165" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 36) + %"2797" = getelementptr inbounds i8, ptr addrspace(1) %"2165", i64 4 + %"1061" = load float, ptr addrspace(1) %"2797", align 4 + store float %"1061", ptr addrspace(5) %"411", align 4 + %17 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %17, align 4 + %"2461" = load i32, ptr addrspace(5) %17, align 4 + store i32 %"2461", ptr addrspace(5) %"570", align 4 + %"1067" = load i32, ptr addrspace(5) %"560", align 4 + %"1068" = load i32, ptr addrspace(5) %"570", align 4 + %"1069" = load float, ptr addrspace(5) %"410", align 4 + %"1070" = load float, ptr addrspace(5) %"411", align 4 + %"1071" = load float, ptr addrspace(5) %"556", align 4 + %"1072" = load float, ptr addrspace(5) %"556", align 4 + %18 = call %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32 %"1067", i32 %"1068", float %"1069", float %"1070", float %"1071", float %"1072", ptr addrspace(3) %"2127") + %"1063" = extractvalue %struct.f32f32f32f32 %18, 0 + %"1064" = extractvalue %struct.f32f32f32f32 %18, 1 + %"1065" = extractvalue %struct.f32f32f32f32 %18, 2 + %"1066" = extractvalue %struct.f32f32f32f32 %18, 3 + store float %"1063", ptr addrspace(5) %"406", align 4 + store float %"1064", ptr addrspace(5) %"407", align 4 + store float %"1065", ptr addrspace(5) %"408", align 4 + store float %"1066", ptr addrspace(5) %"409", align 4 + %"1074" = load float, ptr addrspace(5) %"406", align 4 + %"1073" = call afn float @llvm.log2.f32(float %"1074") + store float %"1073", ptr addrspace(5) %"414", align 4 + %"1076" = load float, ptr addrspace(5) %"414", align 4 + %"1075" = fmul float %"1076", 0x40019999A0000000 + store float %"1075", ptr addrspace(5) %"415", align 4 + %"1078" = load float, ptr addrspace(5) %"415", align 4 + %"1077" = call afn float @llvm.exp2.f32(float %"1078") + store float %"1077", ptr addrspace(5) %"416", align 4 + %"1080" = load float, ptr addrspace(5) %"407", align 4 + %"1079" = call afn float @llvm.log2.f32(float %"1080") + store float %"1079", ptr addrspace(5) %"417", align 4 + %"1082" = load float, ptr addrspace(5) %"417", align 4 + %"1081" = fmul float %"1082", 0x40019999A0000000 + store float %"1081", ptr addrspace(5) %"418", align 4 + %"1084" = load float, ptr addrspace(5) %"418", align 4 + %"1083" = call afn float @llvm.exp2.f32(float %"1084") + store float %"1083", ptr addrspace(5) %"419", align 4 + %"1086" = load float, ptr addrspace(5) %"408", align 4 + %"1085" = call afn float @llvm.log2.f32(float %"1086") + store float %"1085", ptr addrspace(5) %"420", align 4 + %"1088" = load float, ptr addrspace(5) %"420", align 4 + %"1087" = fmul float %"1088", 0x40019999A0000000 + store float %"1087", ptr addrspace(5) %"421", align 4 + %"1090" = load float, ptr addrspace(5) %"421", align 4 + %"1089" = call afn float @llvm.exp2.f32(float %"1090") + store float %"1089", ptr addrspace(5) %"422", align 4 + %"1091" = load i64, ptr addrspace(5) %"608", align 8 + %"1092" = load float, ptr addrspace(5) %"416", align 4 + %"2462" = inttoptr i64 %"1091" to ptr addrspace(5) + %"2799" = getelementptr inbounds i8, ptr addrspace(5) %"2462", i64 4 + store float %"1092", ptr addrspace(5) %"2799", align 4 + %"1093" = load i64, ptr addrspace(5) %"608", align 8 + %"1094" = load float, ptr addrspace(5) %"419", align 4 + %"2463" = inttoptr i64 %"1093" to ptr addrspace(5) + %"2801" = getelementptr inbounds i8, ptr addrspace(5) %"2463", i64 8 + store float %"1094", ptr addrspace(5) %"2801", align 4 + %"1095" = load i64, ptr addrspace(5) %"608", align 8 + %"1096" = load float, ptr addrspace(5) %"422", align 4 + %"2464" = inttoptr i64 %"1095" to ptr addrspace(5) + %"2803" = getelementptr inbounds i8, ptr addrspace(5) %"2464", i64 12 + store float %"1096", ptr addrspace(5) %"2803", align 4 + br label %"306" + +"306": ; preds = %"735", %"2703" + %"2168" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 24) + %"1097" = load float, ptr addrspace(1) %"2168", align 4 + store float %"1097", ptr addrspace(5) %"338", align 4 + %"2170" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 24) + %"2805" = getelementptr inbounds i8, ptr addrspace(1) %"2170", i64 4 + %"1098" = load float, ptr addrspace(1) %"2805", align 4 + store float %"1098", ptr addrspace(5) %"339", align 4 + %"2173" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 24) + %"2807" = getelementptr inbounds i8, ptr addrspace(1) %"2173", i64 8 + %"1099" = load float, ptr addrspace(1) %"2807", align 4 + store float %"1099", ptr addrspace(5) %"340", align 4 + %"1101" = load i64, ptr addrspace(5) %"313", align 8 + %"2468" = add i64 %"1101", 188 + store i64 %"2468", ptr addrspace(5) %"619", align 8 + %"1103" = load i64, ptr addrspace(5) %"314", align 8 + %"2470" = add i64 %"1103", 188 + store i64 %"2470", ptr addrspace(5) %"620", align 8 + %"1104" = load i64, ptr addrspace(5) %"620", align 8 + %"1105" = load float, ptr addrspace(5) %"338", align 4 + %"2472" = inttoptr i64 %"1104" to ptr addrspace(5) + store float %"1105", ptr addrspace(5) %"2472", align 4 + %"1106" = load i64, ptr addrspace(5) %"620", align 8 + %"1107" = load float, ptr addrspace(5) %"339", align 4 + %"2473" = inttoptr i64 %"1106" to ptr addrspace(5) + %"2809" = getelementptr inbounds i8, ptr addrspace(5) %"2473", i64 4 + store float %"1107", ptr addrspace(5) %"2809", align 4 + %"1108" = load i64, ptr addrspace(5) %"620", align 8 + %"1109" = load float, ptr addrspace(5) %"340", align 4 + %"2474" = inttoptr i64 %"1108" to ptr addrspace(5) + %"2811" = getelementptr inbounds i8, ptr addrspace(5) %"2474", i64 8 + store float %"1109", ptr addrspace(5) %"2811", align 4 + %"2176" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 0) + %"1110" = load float, ptr addrspace(1) %"2176", align 4 + store float %"1110", ptr addrspace(5) %"423", align 4 + %"2178" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 0) + %"2813" = getelementptr inbounds i8, ptr addrspace(1) %"2178", i64 4 + %"1111" = load float, ptr addrspace(1) %"2813", align 4 + store float %"1111", ptr addrspace(5) %"424", align 4 + %"2181" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2138", i32 0) + %"2815" = getelementptr inbounds i8, ptr addrspace(1) %"2181", i64 8 + %"1112" = load float, ptr addrspace(1) %"2815", align 4 + store float %"1112", ptr addrspace(5) %"425", align 4 + %"1113" = load i64, ptr addrspace(5) %"620", align 8 + %"1114" = load float, ptr addrspace(5) %"423", align 4 + %"2478" = inttoptr i64 %"1113" to ptr addrspace(5) + %"2817" = getelementptr inbounds i8, ptr addrspace(5) %"2478", i64 12 + store float %"1114", ptr addrspace(5) %"2817", align 4 + %"1115" = load i64, ptr addrspace(5) %"620", align 8 + %"1116" = load float, ptr addrspace(5) %"424", align 4 + %"2479" = inttoptr i64 %"1115" to ptr addrspace(5) + %"2819" = getelementptr inbounds i8, ptr addrspace(5) %"2479", i64 16 + store float %"1116", ptr addrspace(5) %"2819", align 4 + %"1117" = load i64, ptr addrspace(5) %"620", align 8 + %"1118" = load float, ptr addrspace(5) %"425", align 4 + %"2480" = inttoptr i64 %"1117" to ptr addrspace(5) + %"2821" = getelementptr inbounds i8, ptr addrspace(5) %"2480", i64 20 + store float %"1118", ptr addrspace(5) %"2821", align 4 + %"1119" = load i64, ptr addrspace(5) %"620", align 8 + %"1120" = load float, ptr addrspace(5) %"329", align 4 + %"2481" = inttoptr i64 %"1119" to ptr addrspace(5) + %"2823" = getelementptr inbounds i8, ptr addrspace(5) %"2481", i64 24 + store float %"1120", ptr addrspace(5) %"2823", align 4 + %"1121" = load i64, ptr addrspace(5) %"620", align 8 + %"1122" = load float, ptr addrspace(5) %"330", align 4 + %"2482" = inttoptr i64 %"1121" to ptr addrspace(5) + %"2825" = getelementptr inbounds i8, ptr addrspace(5) %"2482", i64 28 + store float %"1122", ptr addrspace(5) %"2825", align 4 + %"1123" = load i64, ptr addrspace(5) %"620", align 8 + %"1124" = load float, ptr addrspace(5) %"331", align 4 + %"2483" = inttoptr i64 %"1123" to ptr addrspace(5) + %"2827" = getelementptr inbounds i8, ptr addrspace(5) %"2483", i64 32 + store float %"1124", ptr addrspace(5) %"2827", align 4 + %"1125" = load i64, ptr addrspace(5) %"620", align 8 + %"1126" = load float, ptr addrspace(5) %"332", align 4 + %"2484" = inttoptr i64 %"1125" to ptr addrspace(5) + %"2829" = getelementptr inbounds i8, ptr addrspace(5) %"2484", i64 36 + store float %"1126", ptr addrspace(5) %"2829", align 4 + %"1127" = load i64, ptr addrspace(5) %"620", align 8 + %"1128" = load float, ptr addrspace(5) %"333", align 4 + %"2485" = inttoptr i64 %"1127" to ptr addrspace(5) + %"2831" = getelementptr inbounds i8, ptr addrspace(5) %"2485", i64 40 + store float %"1128", ptr addrspace(5) %"2831", align 4 + %"1129" = load i64, ptr addrspace(5) %"620", align 8 + %"1130" = load float, ptr addrspace(5) %"334", align 4 + %"2486" = inttoptr i64 %"1129" to ptr addrspace(5) + %"2833" = getelementptr inbounds i8, ptr addrspace(5) %"2486", i64 44 + store float %"1130", ptr addrspace(5) %"2833", align 4 + %"2835" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 12 + %"1131" = load float, ptr addrspace(5) %"2835", align 4 + store float %"1131", ptr addrspace(5) %"426", align 4 + %"1133" = load float, ptr addrspace(5) %"426", align 4 + %"1132" = fsub float 0.000000e+00, %"1133" + store float %"1132", ptr addrspace(5) %"427", align 4 + %"2837" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 16 + %"1134" = load float, ptr addrspace(5) %"2837", align 4 + store float %"1134", ptr addrspace(5) %"428", align 4 + %"1136" = load float, ptr addrspace(5) %"428", align 4 + %"1135" = fsub float 0.000000e+00, %"1136" + store float %"1135", ptr addrspace(5) %"429", align 4 + %"2839" = getelementptr inbounds i8, ptr addrspace(5) %"2131", i64 20 + %"1137" = load float, ptr addrspace(5) %"2839", align 4 + store float %"1137", ptr addrspace(5) %"430", align 4 + %"1139" = load float, ptr addrspace(5) %"430", align 4 + %"1138" = fsub float 0.000000e+00, %"1139" + store float %"1138", ptr addrspace(5) %"431", align 4 + %"1140" = load float, ptr addrspace(5) %"427", align 4 + %"2841" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 48 + store float %"1140", ptr addrspace(5) %"2841", align 4 + %"1141" = load float, ptr addrspace(5) %"429", align 4 + %"2843" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 52 + store float %"1141", ptr addrspace(5) %"2843", align 4 + %"1142" = load float, ptr addrspace(5) %"431", align 4 + %"2845" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 56 + store float %"1142", ptr addrspace(5) %"2845", align 4 + %"2847" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 60 + %"1143" = load float, ptr addrspace(5) %"2847", align 4 + store float %"1143", ptr addrspace(5) %"432", align 4 + %"2849" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 64 + %"1144" = load float, ptr addrspace(5) %"2849", align 4 + store float %"1144", ptr addrspace(5) %"433", align 4 + %"2851" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 68 + %"1145" = load float, ptr addrspace(5) %"2851", align 4 + store float %"1145", ptr addrspace(5) %"434", align 4 + %"2853" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 12 + %"1146" = load float, ptr addrspace(5) %"2853", align 4 + store float %"1146", ptr addrspace(5) %"435", align 4 + %"1148" = load float, ptr addrspace(5) %"335", align 4 + %"1149" = load float, ptr addrspace(5) %"432", align 4 + %"1150" = load float, ptr addrspace(5) %"435", align 4 + %"1147" = call float @llvm.fma.f32(float %"1148", float %"1149", float %"1150") + store float %"1147", ptr addrspace(5) %"436", align 4 + %"1151" = load float, ptr addrspace(5) %"436", align 4 + %"2855" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 12 + store float %"1151", ptr addrspace(5) %"2855", align 4 + %"2857" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 16 + %"1152" = load float, ptr addrspace(5) %"2857", align 4 + store float %"1152", ptr addrspace(5) %"437", align 4 + %"1154" = load float, ptr addrspace(5) %"336", align 4 + %"1155" = load float, ptr addrspace(5) %"433", align 4 + %"1156" = load float, ptr addrspace(5) %"437", align 4 + %"1153" = call float @llvm.fma.f32(float %"1154", float %"1155", float %"1156") + store float %"1153", ptr addrspace(5) %"438", align 4 + %"1157" = load float, ptr addrspace(5) %"438", align 4 + %"2859" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 16 + store float %"1157", ptr addrspace(5) %"2859", align 4 + %"2861" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 20 + %"1158" = load float, ptr addrspace(5) %"2861", align 4 + store float %"1158", ptr addrspace(5) %"439", align 4 + %"1160" = load float, ptr addrspace(5) %"337", align 4 + %"1161" = load float, ptr addrspace(5) %"434", align 4 + %"1162" = load float, ptr addrspace(5) %"439", align 4 + %"1159" = call float @llvm.fma.f32(float %"1160", float %"1161", float %"1162") + store float %"1159", ptr addrspace(5) %"440", align 4 + %"1163" = load float, ptr addrspace(5) %"440", align 4 + %"2863" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 20 + store float %"1163", ptr addrspace(5) %"2863", align 4 + %"1165" = load i32, ptr addrspace(5) %"561", align 4 + %"1164" = icmp eq i32 %"1165", 1 + store i1 %"1164", ptr addrspace(5) %"317", align 1 + %"1167" = load i1, ptr addrspace(5) %"317", align 1 + %"2503" = select i1 %"1167", i16 1, i16 0 + store i16 %"2503", ptr addrspace(5) %"324", align 2 + %"1168" = load i16, ptr addrspace(5) %"324", align 2 + %"2865" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 10 + %"2505" = trunc i16 %"1168" to i8 + store i8 %"2505", ptr addrspace(5) %"2865", align 1 + %"1169" = load i1, ptr addrspace(5) %"317", align 1 + br i1 %"1169", label %"308", label %"737" + +"737": ; preds = %"306" + %"2506" = load i32, ptr addrspace(5) %"2133", align 4 + store i32 %"2506", ptr addrspace(5) %"571", align 4 + %"2200" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 164) + %"2508" = load i32, ptr addrspace(1) %"2200", align 4 + store i32 %"2508", ptr addrspace(5) %"572", align 4 + %"1173" = load i32, ptr addrspace(5) %"571", align 4 + %"1174" = load i32, ptr addrspace(5) %"572", align 4 + %"1172" = icmp sge i32 %"1173", %"1174" + store i1 %"1172", ptr addrspace(5) %"318", align 1 + %19 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %19, align 4 + %"1175" = load float, ptr addrspace(5) %19, align 4 + store float %"1175", ptr addrspace(5) %"557", align 4 + %20 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %20, align 4 + %"1176" = load float, ptr addrspace(5) %20, align 4 + store float %"1176", ptr addrspace(5) %"558", align 4 + %"1177" = load i1, ptr addrspace(5) %"318", align 1 + br i1 %"1177", label %"308", label %"739" + +"739": ; preds = %"737" + %"2513" = ptrtoint ptr addrspace(5) %"2133" to i64 + %21 = alloca i64, align 8, addrspace(5) + store i64 %"2513", ptr addrspace(5) %21, align 8 + %"2512" = load i64, ptr addrspace(5) %21, align 8 + store i64 %"2512", ptr addrspace(5) %"635", align 8 + %"2868" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 4 + %"2515" = load i32, ptr addrspace(5) %"2868", align 4 + store i32 %"2515", ptr addrspace(5) %"578", align 4 + %"1181" = load i32, ptr addrspace(5) %"578", align 4 + %22 = mul i32 %"1181", 1664525 + %"2516" = add i32 %22, 1013904223 + store i32 %"2516", ptr addrspace(5) %"579", align 4 + %"1182" = load i32, ptr addrspace(5) %"579", align 4 + %"2870" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 4 + store i32 %"1182", ptr addrspace(5) %"2870", align 4 + %"1184" = load i32, ptr addrspace(5) %"579", align 4 + %"1183" = and i32 %"1184", 16777215 + store i32 %"1183", ptr addrspace(5) %"580", align 4 + %"1186" = load i32, ptr addrspace(5) %"580", align 4 + %"1185" = call float @__zluda_ptx_impl__cvt_rn_f32_u32(i32 %"1186") + store float %"1185", ptr addrspace(5) %"444", align 4 + %23 = alloca float, align 4, addrspace(5) + store float 0x4170000000000000, ptr addrspace(5) %23, align 4 + %"1187" = load float, ptr addrspace(5) %23, align 4 + store float %"1187", ptr addrspace(5) %"445", align 4 + %"1189" = load float, ptr addrspace(5) %"444", align 4 + %"1190" = load float, ptr addrspace(5) %"445", align 4 + %"1188" = fdiv arcp afn float %"1189", %"1190" + store float %"1188", ptr addrspace(5) %"446", align 4 + %"2204" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 168) + %"2521" = load i32, ptr addrspace(1) %"2204", align 4 + store i32 %"2521", ptr addrspace(5) %"581", align 4 + %"1193" = load i32, ptr addrspace(5) %"581", align 4 + %"1192" = call float @__zluda_ptx_impl__cvt_rn_f32_s32(i32 %"1193") + store float %"1192", ptr addrspace(5) %"447", align 4 + %"1195" = load float, ptr addrspace(5) %"446", align 4 + %"1196" = load float, ptr addrspace(5) %"447", align 4 + %"1194" = fmul float %"1195", %"1196" + store float %"1194", ptr addrspace(5) %"448", align 4 + %"1198" = load float, ptr addrspace(5) %"448", align 4 + %"1197" = call float @llvm.floor.f32(float %"1198") + store float %"1197", ptr addrspace(5) %"449", align 4 + %"1200" = load float, ptr addrspace(5) %"449", align 4 + %"2524" = call i32 @__zluda_ptx_impl__cvt_rz_s32_f32(float %"1200") + store i32 %"2524", ptr addrspace(5) %"582", align 4 + %"1202" = load i32, ptr addrspace(5) %"581", align 4 + %"2525" = add i32 %"1202", -1 + store i32 %"2525", ptr addrspace(5) %"583", align 4 + %"1204" = load i32, ptr addrspace(5) %"582", align 4 + %"1205" = load i32, ptr addrspace(5) %"583", align 4 + %"2527" = call i32 @llvm.smin.i32(i32 %"1204", i32 %"1205") + store i32 %"2527", ptr addrspace(5) %"584", align 4 + %"1207" = load i32, ptr addrspace(5) %"584", align 4 + %"2530" = call i32 @llvm.smax.i32(i32 %"1207", i32 0) + store i32 %"2530", ptr addrspace(5) %"585", align 4 + %"1209" = load i32, ptr addrspace(5) %"585", align 4 + %"2532" = sext i32 %"1209" to i64 + store i64 %"2532", ptr addrspace(5) %"623", align 8 + %"2206" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 56) + %"2535" = ptrtoint ptr addrspace(1) %"2206" to i64 + %24 = alloca i64, align 8, addrspace(5) + store i64 %"2535", ptr addrspace(5) %24, align 8 + %"2534" = load i64, ptr addrspace(5) %24, align 8 + store i64 %"2534", ptr addrspace(5) %"636", align 8 + %"1212" = load i64, ptr addrspace(5) %"636", align 8 + %25 = inttoptr i64 %"1212" to ptr addrspace(1) + %26 = addrspacecast ptr addrspace(1) %25 to ptr + %"1211" = ptrtoint ptr %26 to i64 + store i64 %"1211", ptr addrspace(5) %"622", align 8 + %"1214" = load i64, ptr addrspace(5) %"622", align 8 + %"1215" = load i32, ptr addrspace(5) %"564", align 4 + %"1216" = load i32, ptr addrspace(5) %"565", align 4 + %"1217" = load i64, ptr addrspace(5) %"623", align 8 + %"1218" = load i64, ptr addrspace(5) %"616", align 8 + %"1219" = load i64, ptr addrspace(5) %"616", align 8 + %"1220" = load i64, ptr addrspace(5) %"616", align 8 + %"1213" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1214", i32 %"1215", i32 %"1216", i64 %"1217", i64 %"1218", i64 %"1219", i64 %"1220") + store i64 %"1213", ptr addrspace(5) %"621", align 8 + %"1222" = load i64, ptr addrspace(5) %"621", align 8 + %"2536" = inttoptr i64 %"1222" to ptr + %"1221" = load float, ptr %"2536", align 4 + store float %"1221", ptr addrspace(5) %"450", align 4 + %"1224" = load i64, ptr addrspace(5) %"621", align 8 + %"2537" = inttoptr i64 %"1224" to ptr + %"2872" = getelementptr inbounds i8, ptr %"2537", i64 4 + %"1223" = load float, ptr %"2872", align 4 + store float %"1223", ptr addrspace(5) %"451", align 4 + %"1226" = load i64, ptr addrspace(5) %"621", align 8 + %"2538" = inttoptr i64 %"1226" to ptr + %"2874" = getelementptr inbounds i8, ptr %"2538", i64 8 + %"1225" = load float, ptr %"2874", align 4 + store float %"1225", ptr addrspace(5) %"452", align 4 + %"1228" = load i64, ptr addrspace(5) %"621", align 8 + %"2539" = inttoptr i64 %"1228" to ptr + %"2876" = getelementptr inbounds i8, ptr %"2539", i64 12 + %"1227" = load float, ptr %"2876", align 4 + store float %"1227", ptr addrspace(5) %"453", align 4 + %"1230" = load i64, ptr addrspace(5) %"621", align 8 + %"2540" = inttoptr i64 %"1230" to ptr + %"2878" = getelementptr inbounds i8, ptr %"2540", i64 16 + %"1229" = load float, ptr %"2878", align 4 + store float %"1229", ptr addrspace(5) %"454", align 4 + %"1232" = load i64, ptr addrspace(5) %"621", align 8 + %"2541" = inttoptr i64 %"1232" to ptr + %"2880" = getelementptr inbounds i8, ptr %"2541", i64 20 + %"1231" = load float, ptr %"2880", align 4 + store float %"1231", ptr addrspace(5) %"455", align 4 + %"1234" = load i64, ptr addrspace(5) %"621", align 8 + %"2542" = inttoptr i64 %"1234" to ptr + %"2882" = getelementptr inbounds i8, ptr %"2542", i64 24 + %"1233" = load float, ptr %"2882", align 4 + store float %"1233", ptr addrspace(5) %"456", align 4 + %"1236" = load i64, ptr addrspace(5) %"621", align 8 + %"2543" = inttoptr i64 %"1236" to ptr + %"2884" = getelementptr inbounds i8, ptr %"2543", i64 28 + %"1235" = load float, ptr %"2884", align 4 + store float %"1235", ptr addrspace(5) %"457", align 4 + %"1238" = load i64, ptr addrspace(5) %"621", align 8 + %"2544" = inttoptr i64 %"1238" to ptr + %"2886" = getelementptr inbounds i8, ptr %"2544", i64 32 + %"1237" = load float, ptr %"2886", align 4 + store float %"1237", ptr addrspace(5) %"458", align 4 + %"1240" = load i64, ptr addrspace(5) %"621", align 8 + %"2545" = inttoptr i64 %"1240" to ptr + %"2888" = getelementptr inbounds i8, ptr %"2545", i64 36 + %"1239" = load float, ptr %"2888", align 4 + store float %"1239", ptr addrspace(5) %"459", align 4 + %"1242" = load i64, ptr addrspace(5) %"621", align 8 + %"2546" = inttoptr i64 %"1242" to ptr + %"2890" = getelementptr inbounds i8, ptr %"2546", i64 40 + %"1241" = load float, ptr %"2890", align 4 + store float %"1241", ptr addrspace(5) %"460", align 4 + %"1244" = load i64, ptr addrspace(5) %"621", align 8 + %"2547" = inttoptr i64 %"1244" to ptr + %"2892" = getelementptr inbounds i8, ptr %"2547", i64 44 + %"1243" = load float, ptr %"2892", align 4 + store float %"1243", ptr addrspace(5) %"461", align 4 + %"1246" = load i64, ptr addrspace(5) %"621", align 8 + %"2548" = inttoptr i64 %"1246" to ptr + %"2894" = getelementptr inbounds i8, ptr %"2548", i64 48 + %"1245" = load float, ptr %"2894", align 4 + store float %"1245", ptr addrspace(5) %"462", align 4 + %"1248" = load i64, ptr addrspace(5) %"621", align 8 + %"2549" = inttoptr i64 %"1248" to ptr + %"2896" = getelementptr inbounds i8, ptr %"2549", i64 52 + %"1247" = load float, ptr %"2896", align 4 + store float %"1247", ptr addrspace(5) %"463", align 4 + %"1250" = load i64, ptr addrspace(5) %"621", align 8 + %"2550" = inttoptr i64 %"1250" to ptr + %"2898" = getelementptr inbounds i8, ptr %"2550", i64 56 + %"1249" = load float, ptr %"2898", align 4 + store float %"1249", ptr addrspace(5) %"464", align 4 + %"1252" = load i64, ptr addrspace(5) %"621", align 8 + %"2551" = inttoptr i64 %"1252" to ptr + %"2900" = getelementptr inbounds i8, ptr %"2551", i64 60 + %"1251" = load float, ptr %"2900", align 4 + store float %"1251", ptr addrspace(5) %"465", align 4 + %"1254" = load i64, ptr addrspace(5) %"621", align 8 + %"2552" = inttoptr i64 %"1254" to ptr + %"2902" = getelementptr inbounds i8, ptr %"2552", i64 64 + %"1253" = load float, ptr %"2902", align 4 + store float %"1253", ptr addrspace(5) %"466", align 4 + %"1256" = load i64, ptr addrspace(5) %"621", align 8 + %"2553" = inttoptr i64 %"1256" to ptr + %"2904" = getelementptr inbounds i8, ptr %"2553", i64 68 + %"2554" = load i32, ptr %"2904", align 4 + store i32 %"2554", ptr addrspace(5) %"586", align 4 + %"1258" = load i64, ptr addrspace(5) %"313", align 8 + %"2555" = add i64 %"1258", 0 + store i64 %"2555", ptr addrspace(5) %"637", align 8 + %"1260" = load i64, ptr addrspace(5) %"314", align 8 + %"2557" = add i64 %"1260", 0 + store i64 %"2557", ptr addrspace(5) %"609", align 8 + %"1261" = load i64, ptr addrspace(5) %"609", align 8 + %"1262" = load float, ptr addrspace(5) %"450", align 4 + %"2559" = inttoptr i64 %"1261" to ptr addrspace(5) + store float %"1262", ptr addrspace(5) %"2559", align 4 + %"1263" = load i64, ptr addrspace(5) %"609", align 8 + %"1264" = load float, ptr addrspace(5) %"451", align 4 + %"2560" = inttoptr i64 %"1263" to ptr addrspace(5) + %"2906" = getelementptr inbounds i8, ptr addrspace(5) %"2560", i64 4 + store float %"1264", ptr addrspace(5) %"2906", align 4 + %"1265" = load i64, ptr addrspace(5) %"609", align 8 + %"1266" = load float, ptr addrspace(5) %"452", align 4 + %"2561" = inttoptr i64 %"1265" to ptr addrspace(5) + %"2908" = getelementptr inbounds i8, ptr addrspace(5) %"2561", i64 8 + store float %"1266", ptr addrspace(5) %"2908", align 4 + %"1267" = load i64, ptr addrspace(5) %"609", align 8 + %"1268" = load float, ptr addrspace(5) %"453", align 4 + %"2562" = inttoptr i64 %"1267" to ptr addrspace(5) + %"2910" = getelementptr inbounds i8, ptr addrspace(5) %"2562", i64 12 + store float %"1268", ptr addrspace(5) %"2910", align 4 + %"1269" = load i64, ptr addrspace(5) %"609", align 8 + %"1270" = load float, ptr addrspace(5) %"454", align 4 + %"2563" = inttoptr i64 %"1269" to ptr addrspace(5) + %"2912" = getelementptr inbounds i8, ptr addrspace(5) %"2563", i64 16 + store float %"1270", ptr addrspace(5) %"2912", align 4 + %"1271" = load i64, ptr addrspace(5) %"609", align 8 + %"1272" = load float, ptr addrspace(5) %"455", align 4 + %"2564" = inttoptr i64 %"1271" to ptr addrspace(5) + %"2914" = getelementptr inbounds i8, ptr addrspace(5) %"2564", i64 20 + store float %"1272", ptr addrspace(5) %"2914", align 4 + %"1273" = load i64, ptr addrspace(5) %"609", align 8 + %"1274" = load float, ptr addrspace(5) %"456", align 4 + %"2565" = inttoptr i64 %"1273" to ptr addrspace(5) + %"2916" = getelementptr inbounds i8, ptr addrspace(5) %"2565", i64 24 + store float %"1274", ptr addrspace(5) %"2916", align 4 + %"1275" = load i64, ptr addrspace(5) %"609", align 8 + %"1276" = load float, ptr addrspace(5) %"457", align 4 + %"2566" = inttoptr i64 %"1275" to ptr addrspace(5) + %"2918" = getelementptr inbounds i8, ptr addrspace(5) %"2566", i64 28 + store float %"1276", ptr addrspace(5) %"2918", align 4 + %"1277" = load i64, ptr addrspace(5) %"609", align 8 + %"1278" = load float, ptr addrspace(5) %"458", align 4 + %"2567" = inttoptr i64 %"1277" to ptr addrspace(5) + %"2920" = getelementptr inbounds i8, ptr addrspace(5) %"2567", i64 32 + store float %"1278", ptr addrspace(5) %"2920", align 4 + %"1279" = load i64, ptr addrspace(5) %"609", align 8 + %"1280" = load float, ptr addrspace(5) %"459", align 4 + %"2568" = inttoptr i64 %"1279" to ptr addrspace(5) + %"2922" = getelementptr inbounds i8, ptr addrspace(5) %"2568", i64 36 + store float %"1280", ptr addrspace(5) %"2922", align 4 + %"1281" = load i64, ptr addrspace(5) %"609", align 8 + %"1282" = load float, ptr addrspace(5) %"460", align 4 + %"2569" = inttoptr i64 %"1281" to ptr addrspace(5) + %"2924" = getelementptr inbounds i8, ptr addrspace(5) %"2569", i64 40 + store float %"1282", ptr addrspace(5) %"2924", align 4 + %"1283" = load i64, ptr addrspace(5) %"609", align 8 + %"1284" = load float, ptr addrspace(5) %"461", align 4 + %"2570" = inttoptr i64 %"1283" to ptr addrspace(5) + %"2926" = getelementptr inbounds i8, ptr addrspace(5) %"2570", i64 44 + store float %"1284", ptr addrspace(5) %"2926", align 4 + %"1285" = load i64, ptr addrspace(5) %"609", align 8 + %"1286" = load float, ptr addrspace(5) %"462", align 4 + %"2571" = inttoptr i64 %"1285" to ptr addrspace(5) + %"2928" = getelementptr inbounds i8, ptr addrspace(5) %"2571", i64 48 + store float %"1286", ptr addrspace(5) %"2928", align 4 + %"1287" = load i64, ptr addrspace(5) %"609", align 8 + %"1288" = load float, ptr addrspace(5) %"463", align 4 + %"2572" = inttoptr i64 %"1287" to ptr addrspace(5) + %"2930" = getelementptr inbounds i8, ptr addrspace(5) %"2572", i64 52 + store float %"1288", ptr addrspace(5) %"2930", align 4 + %"1289" = load i64, ptr addrspace(5) %"609", align 8 + %"1290" = load float, ptr addrspace(5) %"464", align 4 + %"2573" = inttoptr i64 %"1289" to ptr addrspace(5) + %"2932" = getelementptr inbounds i8, ptr addrspace(5) %"2573", i64 56 + store float %"1290", ptr addrspace(5) %"2932", align 4 + %"1291" = load i64, ptr addrspace(5) %"609", align 8 + %"1292" = load float, ptr addrspace(5) %"465", align 4 + %"2574" = inttoptr i64 %"1291" to ptr addrspace(5) + %"2934" = getelementptr inbounds i8, ptr addrspace(5) %"2574", i64 60 + store float %"1292", ptr addrspace(5) %"2934", align 4 + %"1293" = load i64, ptr addrspace(5) %"609", align 8 + %"1294" = load float, ptr addrspace(5) %"466", align 4 + %"2575" = inttoptr i64 %"1293" to ptr addrspace(5) + %"2936" = getelementptr inbounds i8, ptr addrspace(5) %"2575", i64 64 + store float %"1294", ptr addrspace(5) %"2936", align 4 + %"1295" = load i64, ptr addrspace(5) %"609", align 8 + %"1296" = load i32, ptr addrspace(5) %"586", align 4 + %"2576" = inttoptr i64 %"1295" to ptr addrspace(5) + %"2938" = getelementptr inbounds i8, ptr addrspace(5) %"2576", i64 68 + store i32 %"1296", ptr addrspace(5) %"2938", align 4 + %"1298" = load i32, ptr addrspace(5) %"586", align 4 + %"2578" = sext i32 %"1298" to i64 + store i64 %"2578", ptr addrspace(5) %"629", align 8 + %"2208" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 8) + %"2581" = ptrtoint ptr addrspace(1) %"2208" to i64 + %27 = alloca i64, align 8, addrspace(5) + store i64 %"2581", ptr addrspace(5) %27, align 8 + %"2580" = load i64, ptr addrspace(5) %27, align 8 + store i64 %"2580", ptr addrspace(5) %"638", align 8 + %"1301" = load i64, ptr addrspace(5) %"638", align 8 + %28 = inttoptr i64 %"1301" to ptr addrspace(1) + %29 = addrspacecast ptr addrspace(1) %28 to ptr + %"1300" = ptrtoint ptr %29 to i64 + store i64 %"1300", ptr addrspace(5) %"628", align 8 + %30 = alloca i32, align 4, addrspace(5) + store i32 4, ptr addrspace(5) %30, align 4 + %"2582" = load i32, ptr addrspace(5) %30, align 4 + store i32 %"2582", ptr addrspace(5) %"576", align 4 + %"1304" = load i64, ptr addrspace(5) %"628", align 8 + %"1305" = load i32, ptr addrspace(5) %"564", align 4 + %"1306" = load i32, ptr addrspace(5) %"576", align 4 + %"1307" = load i64, ptr addrspace(5) %"629", align 8 + %"1308" = load i64, ptr addrspace(5) %"616", align 8 + %"1309" = load i64, ptr addrspace(5) %"616", align 8 + %"1310" = load i64, ptr addrspace(5) %"616", align 8 + %"1303" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1304", i32 %"1305", i32 %"1306", i64 %"1307", i64 %"1308", i64 %"1309", i64 %"1310") + store i64 %"1303", ptr addrspace(5) %"627", align 8 + %"1312" = load i64, ptr addrspace(5) %"627", align 8 + %"2584" = inttoptr i64 %"1312" to ptr + %"2583" = load i32, ptr %"2584", align 4 + store i32 %"2583", ptr addrspace(5) %"577", align 4 + %"1314" = load i32, ptr addrspace(5) %"577", align 4 + %"1315" = load i64, ptr addrspace(5) %"616", align 8 + %"1313" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1314", i64 %"1315", ptr addrspace(3) %"2127") + store i64 %"1313", ptr addrspace(5) %"633", align 8 + %"1317" = load i64, ptr addrspace(5) %"635", align 8 + %31 = inttoptr i64 %"1317" to ptr addrspace(5) + %32 = addrspacecast ptr addrspace(5) %31 to ptr + %"1316" = ptrtoint ptr %32 to i64 + store i64 %"1316", ptr addrspace(5) %"640", align 8 + %"1319" = load i64, ptr addrspace(5) %"313", align 8 + %"2585" = add i64 %"1319", 72 + store i64 %"2585", ptr addrspace(5) %"641", align 8 + %"1320" = load i64, ptr addrspace(5) %"637", align 8 + %"2940" = getelementptr inbounds i8, ptr addrspace(5) %"2075", i64 0 + store i64 %"1320", ptr addrspace(5) %"2940", align 8 + %"1321" = load i64, ptr addrspace(5) %"640", align 8 + %"2942" = getelementptr inbounds i8, ptr addrspace(5) %"2077", i64 0 + store i64 %"1321", ptr addrspace(5) %"2942", align 8 + %"1322" = load i64, ptr addrspace(5) %"641", align 8 + %"2944" = getelementptr inbounds i8, ptr addrspace(5) %"2079", i64 0 + store i64 %"1322", ptr addrspace(5) %"2944", align 8 + %"834" = load i64, ptr addrspace(5) %"2075", align 8 + %"835" = load i64, ptr addrspace(5) %"2077", align 8 + %"836" = load i64, ptr addrspace(5) %"2079", align 8 + %"1323" = load i64, ptr addrspace(5) %"633", align 8 + %"2587" = inttoptr i64 %"1323" to ptr addrspace(1) + %"2265" = load i64, ptr addrspace(1) %"2587", align 8 + %"2588" = inttoptr i64 %"1323" to ptr addrspace(1) + %33 = inttoptr i64 %"2265" to ptr + %"2264" = call i32 %33(i64 %"834", i64 %"835", i64 %"836", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2588") + %"2267" = icmp uge i32 %"2264", 1024 + br i1 %"2267", label %"2268", label %"2269" + +"2268": ; preds = %"739" + ret i32 %"2264" + +"2269": ; preds = %"739" + %"1325" = load i64, ptr addrspace(5) %"314", align 8 + %"2589" = add i64 %"1325", 72 + store i64 %"2589", ptr addrspace(5) %"610", align 8 + %"1327" = load i64, ptr addrspace(5) %"610", align 8 + %"2591" = inttoptr i64 %"1327" to ptr addrspace(5) + %"1326" = load float, ptr addrspace(5) %"2591", align 4 + store float %"1326", ptr addrspace(5) %"467", align 4 + %"1329" = load float, ptr addrspace(5) %"467", align 4 + %"1330" = load float, ptr addrspace(5) %"338", align 4 + %"1328" = fsub float %"1329", %"1330" + store float %"1328", ptr addrspace(5) %"468", align 4 + %"1332" = load i64, ptr addrspace(5) %"610", align 8 + %"2592" = inttoptr i64 %"1332" to ptr addrspace(5) + %"2946" = getelementptr inbounds i8, ptr addrspace(5) %"2592", i64 4 + %"1331" = load float, ptr addrspace(5) %"2946", align 4 + store float %"1331", ptr addrspace(5) %"469", align 4 + %"1334" = load float, ptr addrspace(5) %"469", align 4 + %"1335" = load float, ptr addrspace(5) %"339", align 4 + %"1333" = fsub float %"1334", %"1335" + store float %"1333", ptr addrspace(5) %"470", align 4 + %"1337" = load i64, ptr addrspace(5) %"610", align 8 + %"2593" = inttoptr i64 %"1337" to ptr addrspace(5) + %"2948" = getelementptr inbounds i8, ptr addrspace(5) %"2593", i64 8 + %"1336" = load float, ptr addrspace(5) %"2948", align 4 + store float %"1336", ptr addrspace(5) %"471", align 4 + %"1339" = load float, ptr addrspace(5) %"471", align 4 + %"1340" = load float, ptr addrspace(5) %"340", align 4 + %"1338" = fsub float %"1339", %"1340" + store float %"1338", ptr addrspace(5) %"472", align 4 + %"1342" = load float, ptr addrspace(5) %"470", align 4 + %"1343" = load float, ptr addrspace(5) %"470", align 4 + %"1341" = fmul float %"1342", %"1343" + store float %"1341", ptr addrspace(5) %"473", align 4 + %"1345" = load float, ptr addrspace(5) %"468", align 4 + %"1346" = load float, ptr addrspace(5) %"468", align 4 + %"1347" = load float, ptr addrspace(5) %"473", align 4 + %"1344" = call float @llvm.fma.f32(float %"1345", float %"1346", float %"1347") + store float %"1344", ptr addrspace(5) %"474", align 4 + %"1349" = load float, ptr addrspace(5) %"472", align 4 + %"1350" = load float, ptr addrspace(5) %"472", align 4 + %"1351" = load float, ptr addrspace(5) %"474", align 4 + %"1348" = call float @llvm.fma.f32(float %"1349", float %"1350", float %"1351") + store float %"1348", ptr addrspace(5) %"475", align 4 + %"1353" = load float, ptr addrspace(5) %"475", align 4 + %"1352" = call afn float @llvm.sqrt.f32(float %"1353") + store float %"1352", ptr addrspace(5) %"341", align 4 + %"1355" = load float, ptr addrspace(5) %"341", align 4 + %"1356" = load float, ptr addrspace(5) %"341", align 4 + %"1354" = fmul float %"1355", %"1356" + store float %"1354", ptr addrspace(5) %"342", align 4 + %"1358" = load float, ptr addrspace(5) %"342", align 4 + %34 = call afn float @llvm.sqrt.f32(float %"1358") + %"1357" = fdiv arcp afn float 1.000000e+00, %34 + store float %"1357", ptr addrspace(5) %"476", align 4 + %"1360" = load float, ptr addrspace(5) %"468", align 4 + %"1361" = load float, ptr addrspace(5) %"476", align 4 + %"1359" = fmul float %"1360", %"1361" + store float %"1359", ptr addrspace(5) %"343", align 4 + %"1363" = load float, ptr addrspace(5) %"470", align 4 + %"1364" = load float, ptr addrspace(5) %"476", align 4 + %"1362" = fmul float %"1363", %"1364" + store float %"1362", ptr addrspace(5) %"344", align 4 + %"1366" = load float, ptr addrspace(5) %"472", align 4 + %"1367" = load float, ptr addrspace(5) %"476", align 4 + %"1365" = fmul float %"1366", %"1367" + store float %"1365", ptr addrspace(5) %"345", align 4 + %"1369" = load float, ptr addrspace(5) %"333", align 4 + %"1370" = load float, ptr addrspace(5) %"344", align 4 + %"1368" = fmul float %"1369", %"1370" + store float %"1368", ptr addrspace(5) %"477", align 4 + %"1372" = load float, ptr addrspace(5) %"332", align 4 + %"1373" = load float, ptr addrspace(5) %"343", align 4 + %"1374" = load float, ptr addrspace(5) %"477", align 4 + %"1371" = call float @llvm.fma.f32(float %"1372", float %"1373", float %"1374") + store float %"1371", ptr addrspace(5) %"478", align 4 + %"1376" = load float, ptr addrspace(5) %"334", align 4 + %"1377" = load float, ptr addrspace(5) %"345", align 4 + %"1378" = load float, ptr addrspace(5) %"478", align 4 + %"1375" = call float @llvm.fma.f32(float %"1376", float %"1377", float %"1378") + store float %"1375", ptr addrspace(5) %"479", align 4 + %"1380" = load float, ptr addrspace(5) %"479", align 4 + %"1379" = fcmp ole float %"1380", 0.000000e+00 + store i1 %"1379", ptr addrspace(5) %"319", align 1 + %"1381" = load i1, ptr addrspace(5) %"319", align 1 + br i1 %"1381", label %"307", label %"741" + +"741": ; preds = %"2269" + %"1383" = load i64, ptr addrspace(5) %"610", align 8 + %"2594" = inttoptr i64 %"1383" to ptr addrspace(5) + %"2950" = getelementptr inbounds i8, ptr addrspace(5) %"2594", i64 12 + %"1382" = load float, ptr addrspace(5) %"2950", align 4 + store float %"1382", ptr addrspace(5) %"483", align 4 + %"1385" = load i64, ptr addrspace(5) %"610", align 8 + %"2595" = inttoptr i64 %"1385" to ptr addrspace(5) + %"2952" = getelementptr inbounds i8, ptr addrspace(5) %"2595", i64 16 + %"1384" = load float, ptr addrspace(5) %"2952", align 4 + store float %"1384", ptr addrspace(5) %"484", align 4 + %"1387" = load float, ptr addrspace(5) %"344", align 4 + %"1388" = load float, ptr addrspace(5) %"484", align 4 + %"1386" = fmul float %"1387", %"1388" + store float %"1386", ptr addrspace(5) %"485", align 4 + %"1390" = load float, ptr addrspace(5) %"343", align 4 + %"1391" = load float, ptr addrspace(5) %"483", align 4 + %"1392" = load float, ptr addrspace(5) %"485", align 4 + %"1389" = call float @llvm.fma.f32(float %"1390", float %"1391", float %"1392") + store float %"1389", ptr addrspace(5) %"486", align 4 + %"1394" = load i64, ptr addrspace(5) %"610", align 8 + %"2596" = inttoptr i64 %"1394" to ptr addrspace(5) + %"2954" = getelementptr inbounds i8, ptr addrspace(5) %"2596", i64 20 + %"1393" = load float, ptr addrspace(5) %"2954", align 4 + store float %"1393", ptr addrspace(5) %"487", align 4 + %"1396" = load float, ptr addrspace(5) %"345", align 4 + %"1397" = load float, ptr addrspace(5) %"487", align 4 + %"1398" = load float, ptr addrspace(5) %"486", align 4 + %"1395" = call float @llvm.fma.f32(float %"1396", float %"1397", float %"1398") + store float %"1395", ptr addrspace(5) %"488", align 4 + %"1400" = load float, ptr addrspace(5) %"488", align 4 + %"1399" = fcmp oge float %"1400", 0.000000e+00 + store i1 %"1399", ptr addrspace(5) %"320", align 1 + %"1401" = load i1, ptr addrspace(5) %"320", align 1 + br i1 %"1401", label %"307", label %"743" + +"743": ; preds = %"741" + %"1403" = load i64, ptr addrspace(5) %"313", align 8 + %"2597" = add i64 %"1403", 112 + store i64 %"2597", ptr addrspace(5) %"642", align 8 + %"1405" = load i64, ptr addrspace(5) %"314", align 8 + %"2599" = add i64 %"1405", 112 + store i64 %"2599", ptr addrspace(5) %"643", align 8 + %35 = alloca i16, align 2, addrspace(5) + store i16 0, ptr addrspace(5) %35, align 2 + %"2601" = load i16, ptr addrspace(5) %35, align 2 + store i16 %"2601", ptr addrspace(5) %"325", align 2 + %"1407" = load i64, ptr addrspace(5) %"643", align 8 + %"1408" = load i16, ptr addrspace(5) %"325", align 2 + %"2602" = inttoptr i64 %"1407" to ptr addrspace(5) + %"2603" = trunc i16 %"1408" to i8 + store i8 %"2603", ptr addrspace(5) %"2602", align 1 + %"2210" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 172) + %"1409" = load float, ptr addrspace(1) %"2210", align 4 + store float %"1409", ptr addrspace(5) %"495", align 4 + %"1411" = load float, ptr addrspace(5) %"341", align 4 + %"1412" = load float, ptr addrspace(5) %"495", align 4 + %"1410" = fsub float %"1411", %"1412" + store float %"1410", ptr addrspace(5) %"496", align 4 + %"2212" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 156) + %"2605" = load i32, ptr addrspace(1) %"2212", align 4 + store i32 %"2605", ptr addrspace(5) %"587", align 4 + %36 = alloca i32, align 4, addrspace(5) + store i32 255, ptr addrspace(5) %36, align 4 + %"2607" = load i32, ptr addrspace(5) %36, align 4 + store i32 %"2607", ptr addrspace(5) %"589", align 4 + %37 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %37, align 4 + %"2608" = load i32, ptr addrspace(5) %37, align 4 + store i32 %"2608", ptr addrspace(5) %"590", align 4 + %"1416" = load i32, ptr addrspace(5) %"587", align 4 + %"1417" = load float, ptr addrspace(5) %"338", align 4 + %"1418" = load float, ptr addrspace(5) %"339", align 4 + %"1419" = load float, ptr addrspace(5) %"340", align 4 + %"1420" = load float, ptr addrspace(5) %"343", align 4 + %"1421" = load float, ptr addrspace(5) %"344", align 4 + %"1422" = load float, ptr addrspace(5) %"345", align 4 + %"1423" = load i32, ptr addrspace(5) %"564", align 4 + %"1424" = load float, ptr addrspace(5) %"495", align 4 + %"1425" = load float, ptr addrspace(5) %"496", align 4 + %"1426" = load i32, ptr addrspace(5) %"589", align 4 + %"1427" = load i32, ptr addrspace(5) %"590", align 4 + %"1428" = load i64, ptr addrspace(5) %"642", align 8 + %"1429" = load i32, ptr addrspace(5) %"564", align 4 + %"2258" = call i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32 %"1416", float %"1417", float %"1418", float %"1419", float %"1420", float %"1421", float %"1422", i32 %"1423", float %"1424", float %"1425", i32 %"1426", i32 %"1427", i64 %"1428", i32 %"1429", ptr addrspace(3) %"2127") + %"2260" = icmp uge i32 %"2258", 1024 + br i1 %"2260", label %"2261", label %"2262" + +"2261": ; preds = %"743" + ret i32 %"2258" + +"2262": ; preds = %"743" + %"1431" = load i64, ptr addrspace(5) %"643", align 8 + %"2610" = inttoptr i64 %"1431" to ptr addrspace(5) + %"2609" = load i8, ptr addrspace(5) %"2610", align 1 + %"1430" = zext i8 %"2609" to i16 + store i16 %"1430", ptr addrspace(5) %"326", align 2 + %"1433" = load i16, ptr addrspace(5) %"326", align 2 + %"1432" = icmp ne i16 %"1433", 0 + store i1 %"1432", ptr addrspace(5) %"321", align 1 + %"1434" = load i1, ptr addrspace(5) %"321", align 1 + br i1 %"1434", label %"307", label %"745" + +"745": ; preds = %"2262" + %"1436" = load i64, ptr addrspace(5) %"610", align 8 + %"2612" = inttoptr i64 %"1436" to ptr addrspace(5) + %"2958" = getelementptr inbounds i8, ptr addrspace(5) %"2612", i64 12 + %"1435" = load float, ptr addrspace(5) %"2958", align 4 + store float %"1435", ptr addrspace(5) %"500", align 4 + %"1438" = load float, ptr addrspace(5) %"343", align 4 + %"1439" = load float, ptr addrspace(5) %"500", align 4 + %"1437" = fmul float %"1438", %"1439" + store float %"1437", ptr addrspace(5) %"501", align 4 + %"1441" = load i64, ptr addrspace(5) %"610", align 8 + %"2613" = inttoptr i64 %"1441" to ptr addrspace(5) + %"2960" = getelementptr inbounds i8, ptr addrspace(5) %"2613", i64 16 + %"1440" = load float, ptr addrspace(5) %"2960", align 4 + store float %"1440", ptr addrspace(5) %"502", align 4 + %"1443" = load float, ptr addrspace(5) %"344", align 4 + %"1444" = load float, ptr addrspace(5) %"502", align 4 + %"1442" = fmul float %"1443", %"1444" + store float %"1442", ptr addrspace(5) %"503", align 4 + %"1446" = load float, ptr addrspace(5) %"503", align 4 + %"1445" = fsub float 0.000000e+00, %"1446" + store float %"1445", ptr addrspace(5) %"504", align 4 + %"1448" = load float, ptr addrspace(5) %"504", align 4 + %"1449" = load float, ptr addrspace(5) %"501", align 4 + %"1447" = fsub float %"1448", %"1449" + store float %"1447", ptr addrspace(5) %"505", align 4 + %"1451" = load i64, ptr addrspace(5) %"610", align 8 + %"2614" = inttoptr i64 %"1451" to ptr addrspace(5) + %"2962" = getelementptr inbounds i8, ptr addrspace(5) %"2614", i64 20 + %"1450" = load float, ptr addrspace(5) %"2962", align 4 + store float %"1450", ptr addrspace(5) %"506", align 4 + %"1453" = load float, ptr addrspace(5) %"345", align 4 + %"1454" = load float, ptr addrspace(5) %"506", align 4 + %"1452" = fmul float %"1453", %"1454" + store float %"1452", ptr addrspace(5) %"507", align 4 + %"1456" = load float, ptr addrspace(5) %"505", align 4 + %"1457" = load float, ptr addrspace(5) %"507", align 4 + %"1455" = fsub float %"1456", %"1457" + store float %"1455", ptr addrspace(5) %"508", align 4 + %"1459" = load i64, ptr addrspace(5) %"609", align 8 + %"2615" = inttoptr i64 %"1459" to ptr addrspace(5) + %"2964" = getelementptr inbounds i8, ptr addrspace(5) %"2615", i64 60 + %"1458" = load float, ptr addrspace(5) %"2964", align 4 + store float %"1458", ptr addrspace(5) %"509", align 4 + %"1461" = load float, ptr addrspace(5) %"509", align 4 + %"1462" = load float, ptr addrspace(5) %"508", align 4 + %"1460" = fmul float %"1461", %"1462" + store float %"1460", ptr addrspace(5) %"510", align 4 + %"1464" = load float, ptr addrspace(5) %"342", align 4 + %"1465" = load float, ptr addrspace(5) %"510", align 4 + %"1463" = fdiv arcp afn float %"1464", %"1465" + store float %"1463", ptr addrspace(5) %"511", align 4 + %"1466" = load float, ptr addrspace(5) %"343", align 4 + %"2966" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 36 + store float %"1466", ptr addrspace(5) %"2966", align 4 + %"1467" = load float, ptr addrspace(5) %"344", align 4 + %"2968" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 40 + store float %"1467", ptr addrspace(5) %"2968", align 4 + %"1468" = load float, ptr addrspace(5) %"345", align 4 + %"2970" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 44 + store float %"1468", ptr addrspace(5) %"2970", align 4 + %"2217" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 152) + %"2619" = load i32, ptr addrspace(1) %"2217", align 4 + %"1469" = sext i32 %"2619" to i64 + store i64 %"1469", ptr addrspace(5) %"646", align 8 + %"2219" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 32) + %"2622" = ptrtoint ptr addrspace(1) %"2219" to i64 + %38 = alloca i64, align 8, addrspace(5) + store i64 %"2622", ptr addrspace(5) %38, align 8 + %"2621" = load i64, ptr addrspace(5) %38, align 8 + store i64 %"2621", ptr addrspace(5) %"661", align 8 + %"1472" = load i64, ptr addrspace(5) %"661", align 8 + %39 = inttoptr i64 %"1472" to ptr addrspace(1) + %40 = addrspacecast ptr addrspace(1) %39 to ptr + %"1471" = ptrtoint ptr %40 to i64 + store i64 %"1471", ptr addrspace(5) %"645", align 8 + %"1474" = load i64, ptr addrspace(5) %"645", align 8 + %"1475" = load i32, ptr addrspace(5) %"564", align 4 + %"1476" = load i32, ptr addrspace(5) %"576", align 4 + %"1477" = load i64, ptr addrspace(5) %"646", align 8 + %"1478" = load i64, ptr addrspace(5) %"616", align 8 + %"1479" = load i64, ptr addrspace(5) %"616", align 8 + %"1480" = load i64, ptr addrspace(5) %"616", align 8 + %"1473" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1474", i32 %"1475", i32 %"1476", i64 %"1477", i64 %"1478", i64 %"1479", i64 %"1480") + store i64 %"1473", ptr addrspace(5) %"644", align 8 + %"1482" = load i64, ptr addrspace(5) %"644", align 8 + %"2624" = inttoptr i64 %"1482" to ptr + %"2623" = load i32, ptr %"2624", align 4 + store i32 %"2623", ptr addrspace(5) %"594", align 4 + %"1484" = load i32, ptr addrspace(5) %"594", align 4 + %"1485" = load i64, ptr addrspace(5) %"616", align 8 + %"1483" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1484", i64 %"1485", ptr addrspace(3) %"2127") + store i64 %"1483", ptr addrspace(5) %"650", align 8 + %"1486" = load i64, ptr addrspace(5) %"617", align 8 + %"2972" = getelementptr inbounds i8, ptr addrspace(5) %"2081", i64 0 + store i64 %"1486", ptr addrspace(5) %"2972", align 8 + %"1487" = load i64, ptr addrspace(5) %"619", align 8 + %"2974" = getelementptr inbounds i8, ptr addrspace(5) %"2083", i64 0 + store i64 %"1487", ptr addrspace(5) %"2974", align 8 + %"1488" = load i64, ptr addrspace(5) %"640", align 8 + %"2976" = getelementptr inbounds i8, ptr addrspace(5) %"2085", i64 0 + store i64 %"1488", ptr addrspace(5) %"2976", align 8 + %"837" = load i64, ptr addrspace(5) %"2081", align 8 + %"838" = load i64, ptr addrspace(5) %"2083", align 8 + %"839" = load i64, ptr addrspace(5) %"2085", align 8 + %"1489" = load i64, ptr addrspace(5) %"650", align 8 + %"2625" = inttoptr i64 %"1489" to ptr addrspace(1) + %"2271" = load i64, ptr addrspace(1) %"2625", align 8 + %"2626" = inttoptr i64 %"1489" to ptr addrspace(1) + %41 = inttoptr i64 %"2271" to ptr + %"2270" = call i32 %41(i64 %"837", i64 %"838", i64 %"839", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2626") + %"2273" = icmp uge i32 %"2270", 1024 + br i1 %"2273", label %"2274", label %"2275" + +"2274": ; preds = %"745" + ret i32 %"2270" + +"2275": ; preds = %"745" + %"2221" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 152) + %"2627" = load i32, ptr addrspace(1) %"2221", align 4 + %"1490" = sext i32 %"2627" to i64 + store i64 %"1490", ptr addrspace(5) %"654", align 8 + %"2223" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 80) + %"2630" = ptrtoint ptr addrspace(1) %"2223" to i64 + %42 = alloca i64, align 8, addrspace(5) + store i64 %"2630", ptr addrspace(5) %42, align 8 + %"2629" = load i64, ptr addrspace(5) %42, align 8 + store i64 %"2629", ptr addrspace(5) %"666", align 8 + %"1493" = load i64, ptr addrspace(5) %"666", align 8 + %43 = inttoptr i64 %"1493" to ptr addrspace(1) + %44 = addrspacecast ptr addrspace(1) %43 to ptr + %"1492" = ptrtoint ptr %44 to i64 + store i64 %"1492", ptr addrspace(5) %"653", align 8 + %"1495" = load i64, ptr addrspace(5) %"653", align 8 + %"1496" = load i32, ptr addrspace(5) %"564", align 4 + %"1497" = load i32, ptr addrspace(5) %"576", align 4 + %"1498" = load i64, ptr addrspace(5) %"654", align 8 + %"1499" = load i64, ptr addrspace(5) %"616", align 8 + %"1500" = load i64, ptr addrspace(5) %"616", align 8 + %"1501" = load i64, ptr addrspace(5) %"616", align 8 + %"1494" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1495", i32 %"1496", i32 %"1497", i64 %"1498", i64 %"1499", i64 %"1500", i64 %"1501") + store i64 %"1494", ptr addrspace(5) %"652", align 8 + %"1503" = load i64, ptr addrspace(5) %"652", align 8 + %"2632" = inttoptr i64 %"1503" to ptr + %"2631" = load i32, ptr %"2632", align 4 + store i32 %"2631", ptr addrspace(5) %"597", align 4 + %"1505" = load i32, ptr addrspace(5) %"597", align 4 + %"1506" = load i64, ptr addrspace(5) %"616", align 8 + %"1504" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1505", i64 %"1506", ptr addrspace(3) %"2127") + store i64 %"1504", ptr addrspace(5) %"658", align 8 + %"1507" = load i64, ptr addrspace(5) %"617", align 8 + %"2978" = getelementptr inbounds i8, ptr addrspace(5) %"2087", i64 0 + store i64 %"1507", ptr addrspace(5) %"2978", align 8 + %"1508" = load i64, ptr addrspace(5) %"619", align 8 + %"2980" = getelementptr inbounds i8, ptr addrspace(5) %"2089", i64 0 + store i64 %"1508", ptr addrspace(5) %"2980", align 8 + %"1509" = load i64, ptr addrspace(5) %"640", align 8 + %"2982" = getelementptr inbounds i8, ptr addrspace(5) %"2091", i64 0 + store i64 %"1509", ptr addrspace(5) %"2982", align 8 + %"840" = load i64, ptr addrspace(5) %"2087", align 8 + %"841" = load i64, ptr addrspace(5) %"2089", align 8 + %"842" = load i64, ptr addrspace(5) %"2091", align 8 + %"1510" = load i64, ptr addrspace(5) %"658", align 8 + %"2633" = inttoptr i64 %"1510" to ptr addrspace(1) + %"2277" = load i64, ptr addrspace(1) %"2633", align 8 + %"2634" = inttoptr i64 %"1510" to ptr addrspace(1) + %45 = inttoptr i64 %"2277" to ptr + %46 = call { [3 x i32], i32 } %45(i64 %"840", i64 %"841", i64 %"842", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2634") + %"843" = extractvalue { [3 x i32], i32 } %46, 0 + %"2276" = extractvalue { [3 x i32], i32 } %46, 1 + %"2279" = icmp uge i32 %"2276", 1024 + br i1 %"2279", label %"2280", label %"2281" + +"2280": ; preds = %"2275" + ret i32 %"2276" + +"2281": ; preds = %"2275" + store [3 x i32] %"843", ptr addrspace(5) %"2093", align 4 + %"2984" = getelementptr inbounds i8, ptr addrspace(5) %"2093", i64 0 + %"1511" = load float, ptr addrspace(5) %"2984", align 4 + store float %"1511", ptr addrspace(5) %"512", align 4 + %"2986" = getelementptr inbounds i8, ptr addrspace(5) %"2093", i64 4 + %"1512" = load float, ptr addrspace(5) %"2986", align 4 + store float %"1512", ptr addrspace(5) %"513", align 4 + %"2988" = getelementptr inbounds i8, ptr addrspace(5) %"2093", i64 8 + %"1513" = load float, ptr addrspace(5) %"2988", align 4 + store float %"1513", ptr addrspace(5) %"514", align 4 + %"1515" = load float, ptr addrspace(5) %"511", align 4 + %"1516" = load float, ptr addrspace(5) %"511", align 4 + %"1514" = fmul float %"1515", %"1516" + store float %"1514", ptr addrspace(5) %"515", align 4 + %"2990" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 72 + %"1517" = load float, ptr addrspace(5) %"2990", align 4 + store float %"1517", ptr addrspace(5) %"516", align 4 + %"1519" = load float, ptr addrspace(5) %"516", align 4 + %"1520" = load float, ptr addrspace(5) %"516", align 4 + %"1521" = load float, ptr addrspace(5) %"515", align 4 + %"1518" = call float @llvm.fma.f32(float %"1519", float %"1520", float %"1521") + store float %"1518", ptr addrspace(5) %"517", align 4 + %"1523" = load float, ptr addrspace(5) %"515", align 4 + %"1524" = load float, ptr addrspace(5) %"517", align 4 + %"1522" = fdiv arcp afn float %"1523", %"1524" + store float %"1522", ptr addrspace(5) %"518", align 4 + %"2992" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 60 + %"1525" = load float, ptr addrspace(5) %"2992", align 4 + store float %"1525", ptr addrspace(5) %"519", align 4 + %"1527" = load float, ptr addrspace(5) %"518", align 4 + %"1528" = load float, ptr addrspace(5) %"519", align 4 + %"1526" = fmul float %"1527", %"1528" + store float %"1526", ptr addrspace(5) %"520", align 4 + %"2994" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 64 + %"1529" = load float, ptr addrspace(5) %"2994", align 4 + store float %"1529", ptr addrspace(5) %"521", align 4 + %"1531" = load float, ptr addrspace(5) %"518", align 4 + %"1532" = load float, ptr addrspace(5) %"521", align 4 + %"1530" = fmul float %"1531", %"1532" + store float %"1530", ptr addrspace(5) %"522", align 4 + %"2996" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 68 + %"1533" = load float, ptr addrspace(5) %"2996", align 4 + store float %"1533", ptr addrspace(5) %"523", align 4 + %"1535" = load float, ptr addrspace(5) %"518", align 4 + %"1536" = load float, ptr addrspace(5) %"523", align 4 + %"1534" = fmul float %"1535", %"1536" + store float %"1534", ptr addrspace(5) %"524", align 4 + %"1538" = load float, ptr addrspace(5) %"512", align 4 + %"1539" = load float, ptr addrspace(5) %"520", align 4 + %"1537" = fmul float %"1538", %"1539" + store float %"1537", ptr addrspace(5) %"525", align 4 + %"1541" = load float, ptr addrspace(5) %"513", align 4 + %"1542" = load float, ptr addrspace(5) %"522", align 4 + %"1540" = fmul float %"1541", %"1542" + store float %"1540", ptr addrspace(5) %"526", align 4 + %"1544" = load float, ptr addrspace(5) %"514", align 4 + %"1545" = load float, ptr addrspace(5) %"524", align 4 + %"1543" = fmul float %"1544", %"1545" + store float %"1543", ptr addrspace(5) %"527", align 4 + %"1547" = load i64, ptr addrspace(5) %"610", align 8 + %"2642" = inttoptr i64 %"1547" to ptr addrspace(5) + %"2998" = getelementptr inbounds i8, ptr addrspace(5) %"2642", i64 24 + %"1546" = load float, ptr addrspace(5) %"2998", align 4 + store float %"1546", ptr addrspace(5) %"528", align 4 + %"1549" = load float, ptr addrspace(5) %"528", align 4 + %"1550" = load float, ptr addrspace(5) %"525", align 4 + %"1548" = fmul float %"1549", %"1550" + store float %"1548", ptr addrspace(5) %"529", align 4 + %"1552" = load i64, ptr addrspace(5) %"610", align 8 + %"2643" = inttoptr i64 %"1552" to ptr addrspace(5) + %"3000" = getelementptr inbounds i8, ptr addrspace(5) %"2643", i64 28 + %"1551" = load float, ptr addrspace(5) %"3000", align 4 + store float %"1551", ptr addrspace(5) %"530", align 4 + %"1554" = load float, ptr addrspace(5) %"530", align 4 + %"1555" = load float, ptr addrspace(5) %"526", align 4 + %"1553" = fmul float %"1554", %"1555" + store float %"1553", ptr addrspace(5) %"531", align 4 + %"1557" = load i64, ptr addrspace(5) %"610", align 8 + %"2644" = inttoptr i64 %"1557" to ptr addrspace(5) + %"3002" = getelementptr inbounds i8, ptr addrspace(5) %"2644", i64 32 + %"1556" = load float, ptr addrspace(5) %"3002", align 4 + store float %"1556", ptr addrspace(5) %"532", align 4 + %"1559" = load float, ptr addrspace(5) %"532", align 4 + %"1560" = load float, ptr addrspace(5) %"527", align 4 + %"1558" = fmul float %"1559", %"1560" + store float %"1558", ptr addrspace(5) %"533", align 4 + %47 = alloca float, align 4, addrspace(5) + store float 0x3F50624DE0000000, ptr addrspace(5) %47, align 4 + %"1561" = load float, ptr addrspace(5) %47, align 4 + store float %"1561", ptr addrspace(5) %"534", align 4 + %"1563" = load float, ptr addrspace(5) %"534", align 4 + %"1564" = load float, ptr addrspace(5) %"511", align 4 + %"1562" = call float @llvm.maxnum.f32(float %"1563", float %"1564") + store float %"1562", ptr addrspace(5) %"535", align 4 + %"1566" = load float, ptr addrspace(5) %"535", align 4 + %"1565" = fdiv arcp afn float 1.000000e+00, %"1566" + store float %"1565", ptr addrspace(5) %"536", align 4 + %"1568" = load float, ptr addrspace(5) %"536", align 4 + %"1569" = load float, ptr addrspace(5) %"533", align 4 + %"1567" = fmul float %"1568", %"1569" + store float %"1567", ptr addrspace(5) %"558", align 4 + %"1571" = load float, ptr addrspace(5) %"536", align 4 + %"1572" = load float, ptr addrspace(5) %"531", align 4 + %"1570" = fmul float %"1571", %"1572" + store float %"1570", ptr addrspace(5) %"557", align 4 + %"1574" = load float, ptr addrspace(5) %"536", align 4 + %"1575" = load float, ptr addrspace(5) %"529", align 4 + %"1573" = fmul float %"1574", %"1575" + store float %"1573", ptr addrspace(5) %"556", align 4 + br label %"307" + +"307": ; preds = %"2281", %"2262", %"741", %"2269" + %"3004" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 12 + %"1576" = load float, ptr addrspace(5) %"3004", align 4 + store float %"1576", ptr addrspace(5) %"537", align 4 + %"1578" = load float, ptr addrspace(5) %"556", align 4 + %"1579" = load float, ptr addrspace(5) %"537", align 4 + %"1577" = fadd float %"1578", %"1579" + store float %"1577", ptr addrspace(5) %"538", align 4 + %"1580" = load float, ptr addrspace(5) %"538", align 4 + %"3006" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 12 + store float %"1580", ptr addrspace(5) %"3006", align 4 + %"3008" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 16 + %"1581" = load float, ptr addrspace(5) %"3008", align 4 + store float %"1581", ptr addrspace(5) %"539", align 4 + %"1583" = load float, ptr addrspace(5) %"557", align 4 + %"1584" = load float, ptr addrspace(5) %"539", align 4 + %"1582" = fadd float %"1583", %"1584" + store float %"1582", ptr addrspace(5) %"540", align 4 + %"1585" = load float, ptr addrspace(5) %"540", align 4 + %"3010" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 16 + store float %"1585", ptr addrspace(5) %"3010", align 4 + %"3012" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 20 + %"1586" = load float, ptr addrspace(5) %"3012", align 4 + store float %"1586", ptr addrspace(5) %"541", align 4 + %"1588" = load float, ptr addrspace(5) %"558", align 4 + %"1589" = load float, ptr addrspace(5) %"541", align 4 + %"1587" = fadd float %"1588", %"1589" + store float %"1587", ptr addrspace(5) %"542", align 4 + %"1590" = load float, ptr addrspace(5) %"542", align 4 + %"3014" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 20 + store float %"1590", ptr addrspace(5) %"3014", align 4 + br label %"308" + +"308": ; preds = %"307", %"737", %"306" + %"2235" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 152) + %"2651" = load i32, ptr addrspace(1) %"2235", align 4 + %"1591" = sext i32 %"2651" to i64 + store i64 %"1591", ptr addrspace(5) %"670", align 8 + %"2237" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 128) + %"2654" = ptrtoint ptr addrspace(1) %"2237" to i64 + %48 = alloca i64, align 8, addrspace(5) + store i64 %"2654", ptr addrspace(5) %48, align 8 + %"2653" = load i64, ptr addrspace(5) %48, align 8 + store i64 %"2653", ptr addrspace(5) %"692", align 8 + %"1594" = load i64, ptr addrspace(5) %"692", align 8 + %49 = inttoptr i64 %"1594" to ptr addrspace(1) + %50 = addrspacecast ptr addrspace(1) %49 to ptr + %"1593" = ptrtoint ptr %50 to i64 + store i64 %"1593", ptr addrspace(5) %"669", align 8 + %51 = alloca i32, align 4, addrspace(5) + store i32 4, ptr addrspace(5) %51, align 4 + %"2655" = load i32, ptr addrspace(5) %51, align 4 + store i32 %"2655", ptr addrspace(5) %"605", align 4 + %"1597" = load i64, ptr addrspace(5) %"669", align 8 + %"1598" = load i32, ptr addrspace(5) %"564", align 4 + %"1599" = load i32, ptr addrspace(5) %"605", align 4 + %"1600" = load i64, ptr addrspace(5) %"670", align 8 + %"1601" = load i64, ptr addrspace(5) %"616", align 8 + %"1602" = load i64, ptr addrspace(5) %"616", align 8 + %"1603" = load i64, ptr addrspace(5) %"616", align 8 + %"1596" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1597", i32 %"1598", i32 %"1599", i64 %"1600", i64 %"1601", i64 %"1602", i64 %"1603") + store i64 %"1596", ptr addrspace(5) %"668", align 8 + %"1605" = load i64, ptr addrspace(5) %"668", align 8 + %"2657" = inttoptr i64 %"1605" to ptr + %"2656" = load i32, ptr %"2657", align 4 + store i32 %"2656", ptr addrspace(5) %"600", align 4 + %"1607" = load i32, ptr addrspace(5) %"600", align 4 + %"1608" = load i64, ptr addrspace(5) %"616", align 8 + %"1606" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1607", i64 %"1608", ptr addrspace(3) %"2127") + store i64 %"1606", ptr addrspace(5) %"674", align 8 + %"2659" = ptrtoint ptr addrspace(5) %"2133" to i64 + %52 = alloca i64, align 8, addrspace(5) + store i64 %"2659", ptr addrspace(5) %52, align 8 + %"2658" = load i64, ptr addrspace(5) %52, align 8 + store i64 %"2658", ptr addrspace(5) %"694", align 8 + %"1611" = load i64, ptr addrspace(5) %"694", align 8 + %53 = inttoptr i64 %"1611" to ptr addrspace(5) + %54 = addrspacecast ptr addrspace(5) %53 to ptr + %"1610" = ptrtoint ptr %54 to i64 + store i64 %"1610", ptr addrspace(5) %"695", align 8 + %"1612" = load i64, ptr addrspace(5) %"617", align 8 + %"3016" = getelementptr inbounds i8, ptr addrspace(5) %"2097", i64 0 + store i64 %"1612", ptr addrspace(5) %"3016", align 8 + %"1613" = load i64, ptr addrspace(5) %"619", align 8 + %"3018" = getelementptr inbounds i8, ptr addrspace(5) %"2099", i64 0 + store i64 %"1613", ptr addrspace(5) %"3018", align 8 + %"1614" = load i64, ptr addrspace(5) %"695", align 8 + %"3020" = getelementptr inbounds i8, ptr addrspace(5) %"2101", i64 0 + store i64 %"1614", ptr addrspace(5) %"3020", align 8 + %"844" = load i64, ptr addrspace(5) %"2097", align 8 + %"845" = load i64, ptr addrspace(5) %"2099", align 8 + %"846" = load i64, ptr addrspace(5) %"2101", align 8 + %"1615" = load i64, ptr addrspace(5) %"674", align 8 + %"2660" = inttoptr i64 %"1615" to ptr addrspace(1) + %"2283" = load i64, ptr addrspace(1) %"2660", align 8 + %"2661" = inttoptr i64 %"1615" to ptr addrspace(1) + %55 = inttoptr i64 %"2283" to ptr + %"2282" = call i32 %55(i64 %"844", i64 %"845", i64 %"846", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2661") + %"2285" = icmp uge i32 %"2282", 1024 + br i1 %"2285", label %"2286", label %"2287" + +"2286": ; preds = %"308" + ret i32 %"2282" + +"2287": ; preds = %"308" + %"2239" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 152) + %"2662" = load i32, ptr addrspace(1) %"2239", align 4 + %"1616" = sext i32 %"2662" to i64 + store i64 %"1616", ptr addrspace(5) %"678", align 8 + %"2241" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 32) + %"2665" = ptrtoint ptr addrspace(1) %"2241" to i64 + %56 = alloca i64, align 8, addrspace(5) + store i64 %"2665", ptr addrspace(5) %56, align 8 + %"2664" = load i64, ptr addrspace(5) %56, align 8 + store i64 %"2664", ptr addrspace(5) %"698", align 8 + %"1619" = load i64, ptr addrspace(5) %"698", align 8 + %57 = inttoptr i64 %"1619" to ptr addrspace(1) + %58 = addrspacecast ptr addrspace(1) %57 to ptr + %"1618" = ptrtoint ptr %58 to i64 + store i64 %"1618", ptr addrspace(5) %"677", align 8 + %"1621" = load i64, ptr addrspace(5) %"677", align 8 + %"1622" = load i32, ptr addrspace(5) %"564", align 4 + %"1623" = load i32, ptr addrspace(5) %"605", align 4 + %"1624" = load i64, ptr addrspace(5) %"678", align 8 + %"1625" = load i64, ptr addrspace(5) %"616", align 8 + %"1626" = load i64, ptr addrspace(5) %"616", align 8 + %"1627" = load i64, ptr addrspace(5) %"616", align 8 + %"1620" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1621", i32 %"1622", i32 %"1623", i64 %"1624", i64 %"1625", i64 %"1626", i64 %"1627") + store i64 %"1620", ptr addrspace(5) %"676", align 8 + %"1629" = load i64, ptr addrspace(5) %"676", align 8 + %"2667" = inttoptr i64 %"1629" to ptr + %"2666" = load i32, ptr %"2667", align 4 + store i32 %"2666", ptr addrspace(5) %"603", align 4 + %"1631" = load i32, ptr addrspace(5) %"603", align 4 + %"1632" = load i64, ptr addrspace(5) %"616", align 8 + %"1630" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1631", i64 %"1632", ptr addrspace(3) %"2127") + store i64 %"1630", ptr addrspace(5) %"682", align 8 + %"1633" = load i64, ptr addrspace(5) %"617", align 8 + %"3022" = getelementptr inbounds i8, ptr addrspace(5) %"2103", i64 0 + store i64 %"1633", ptr addrspace(5) %"3022", align 8 + %"1634" = load i64, ptr addrspace(5) %"619", align 8 + %"3024" = getelementptr inbounds i8, ptr addrspace(5) %"2105", i64 0 + store i64 %"1634", ptr addrspace(5) %"3024", align 8 + %"1635" = load i64, ptr addrspace(5) %"695", align 8 + %"3026" = getelementptr inbounds i8, ptr addrspace(5) %"2107", i64 0 + store i64 %"1635", ptr addrspace(5) %"3026", align 8 + %"847" = load i64, ptr addrspace(5) %"2103", align 8 + %"848" = load i64, ptr addrspace(5) %"2105", align 8 + %"849" = load i64, ptr addrspace(5) %"2107", align 8 + %"1636" = load i64, ptr addrspace(5) %"682", align 8 + %"2668" = inttoptr i64 %"1636" to ptr addrspace(1) + %"2289" = load i64, ptr addrspace(1) %"2668", align 8 + %"2669" = inttoptr i64 %"1636" to ptr addrspace(1) + %59 = inttoptr i64 %"2289" to ptr + %"2288" = call i32 %59(i64 %"847", i64 %"848", i64 %"849", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2669") + %"2291" = icmp uge i32 %"2288", 1024 + br i1 %"2291", label %"2292", label %"2293" + +"2292": ; preds = %"2287" + ret i32 %"2288" + +"2293": ; preds = %"2287" + %"2243" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 152) + %"2670" = load i32, ptr addrspace(1) %"2243", align 4 + %"1637" = sext i32 %"2670" to i64 + store i64 %"1637", ptr addrspace(5) %"686", align 8 + %"2245" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2137", i32 80) + %"2673" = ptrtoint ptr addrspace(1) %"2245" to i64 + %60 = alloca i64, align 8, addrspace(5) + store i64 %"2673", ptr addrspace(5) %60, align 8 + %"2672" = load i64, ptr addrspace(5) %60, align 8 + store i64 %"2672", ptr addrspace(5) %"700", align 8 + %"1640" = load i64, ptr addrspace(5) %"700", align 8 + %61 = inttoptr i64 %"1640" to ptr addrspace(1) + %62 = addrspacecast ptr addrspace(1) %61 to ptr + %"1639" = ptrtoint ptr %62 to i64 + store i64 %"1639", ptr addrspace(5) %"685", align 8 + %"1642" = load i64, ptr addrspace(5) %"685", align 8 + %"1643" = load i32, ptr addrspace(5) %"564", align 4 + %"1644" = load i32, ptr addrspace(5) %"605", align 4 + %"1645" = load i64, ptr addrspace(5) %"686", align 8 + %"1646" = load i64, ptr addrspace(5) %"616", align 8 + %"1647" = load i64, ptr addrspace(5) %"616", align 8 + %"1648" = load i64, ptr addrspace(5) %"616", align 8 + %"1641" = call i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64 %"1642", i32 %"1643", i32 %"1644", i64 %"1645", i64 %"1646", i64 %"1647", i64 %"1648") + store i64 %"1641", ptr addrspace(5) %"684", align 8 + %"1650" = load i64, ptr addrspace(5) %"684", align 8 + %"2675" = inttoptr i64 %"1650" to ptr + %"2674" = load i32, ptr %"2675", align 4 + store i32 %"2674", ptr addrspace(5) %"606", align 4 + %"1652" = load i32, ptr addrspace(5) %"606", align 4 + %"1653" = load i64, ptr addrspace(5) %"616", align 8 + %"1651" = call i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32 %"1652", i64 %"1653", ptr addrspace(3) %"2127") + store i64 %"1651", ptr addrspace(5) %"690", align 8 + %"1654" = load i64, ptr addrspace(5) %"617", align 8 + %"3028" = getelementptr inbounds i8, ptr addrspace(5) %"2109", i64 0 + store i64 %"1654", ptr addrspace(5) %"3028", align 8 + %"1655" = load i64, ptr addrspace(5) %"619", align 8 + %"3030" = getelementptr inbounds i8, ptr addrspace(5) %"2111", i64 0 + store i64 %"1655", ptr addrspace(5) %"3030", align 8 + %"1656" = load i64, ptr addrspace(5) %"695", align 8 + %"3032" = getelementptr inbounds i8, ptr addrspace(5) %"2113", i64 0 + store i64 %"1656", ptr addrspace(5) %"3032", align 8 + %"850" = load i64, ptr addrspace(5) %"2109", align 8 + %"851" = load i64, ptr addrspace(5) %"2111", align 8 + %"852" = load i64, ptr addrspace(5) %"2113", align 8 + %"1657" = load i64, ptr addrspace(5) %"690", align 8 + %"2676" = inttoptr i64 %"1657" to ptr addrspace(1) + %"2295" = load i64, ptr addrspace(1) %"2676", align 8 + %"2677" = inttoptr i64 %"1657" to ptr addrspace(1) + %63 = inttoptr i64 %"2295" to ptr + %64 = call { [3 x i32], i32 } %63(i64 %"850", i64 %"851", i64 %"852", ptr addrspace(3) %"2127", <2 x i32> %"2129", ptr addrspace(1) %"2677") + %"853" = extractvalue { [3 x i32], i32 } %64, 0 + %"2294" = extractvalue { [3 x i32], i32 } %64, 1 + %"2297" = icmp uge i32 %"2294", 1024 + br i1 %"2297", label %"2298", label %"2299" + +"2298": ; preds = %"2293" + ret i32 %"2294" + +"2299": ; preds = %"2293" + store [3 x i32] %"853", ptr addrspace(5) %"2115", align 4 + %"3034" = getelementptr inbounds i8, ptr addrspace(5) %"2115", i64 0 + %"1658" = load float, ptr addrspace(5) %"3034", align 4 + store float %"1658", ptr addrspace(5) %"352", align 4 + %"3036" = getelementptr inbounds i8, ptr addrspace(5) %"2115", i64 4 + %"1659" = load float, ptr addrspace(5) %"3036", align 4 + store float %"1659", ptr addrspace(5) %"353", align 4 + %"3038" = getelementptr inbounds i8, ptr addrspace(5) %"2115", i64 8 + %"1660" = load float, ptr addrspace(5) %"3038", align 4 + store float %"1660", ptr addrspace(5) %"354", align 4 + %"3040" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 72 + %"1661" = load float, ptr addrspace(5) %"3040", align 4 + store float %"1661", ptr addrspace(5) %"355", align 4 + %"1663" = load float, ptr addrspace(5) %"355", align 4 + %"1662" = fcmp ogt float %"1663", 0.000000e+00 + store i1 %"1662", ptr addrspace(5) %"322", align 1 + %"1664" = load i1, ptr addrspace(5) %"322", align 1 + br i1 %"1664", label %"309", label %"747" + +"747": ; preds = %"2299" + br label %"310" + +"309": ; preds = %"2299" + %"1666" = load float, ptr addrspace(5) %"355", align 4 + %"1665" = fdiv arcp afn float 1.000000e+00, %"1666" + store float %"1665", ptr addrspace(5) %"543", align 4 + %"1668" = load float, ptr addrspace(5) %"352", align 4 + %"1669" = load float, ptr addrspace(5) %"543", align 4 + %"1667" = fmul float %"1668", %"1669" + store float %"1667", ptr addrspace(5) %"544", align 4 + %"1671" = load float, ptr addrspace(5) %"353", align 4 + %"1672" = load float, ptr addrspace(5) %"543", align 4 + %"1670" = fmul float %"1671", %"1672" + store float %"1670", ptr addrspace(5) %"545", align 4 + %"1674" = load float, ptr addrspace(5) %"354", align 4 + %"1675" = load float, ptr addrspace(5) %"543", align 4 + %"1673" = fmul float %"1674", %"1675" + store float %"1673", ptr addrspace(5) %"546", align 4 + %"3042" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 60 + %"1676" = load float, ptr addrspace(5) %"3042", align 4 + store float %"1676", ptr addrspace(5) %"547", align 4 + %"1678" = load float, ptr addrspace(5) %"547", align 4 + %"1679" = load float, ptr addrspace(5) %"544", align 4 + %"1677" = fmul float %"1678", %"1679" + store float %"1677", ptr addrspace(5) %"548", align 4 + %"1680" = load float, ptr addrspace(5) %"548", align 4 + %"3044" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 60 + store float %"1680", ptr addrspace(5) %"3044", align 4 + %"3046" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 64 + %"1681" = load float, ptr addrspace(5) %"3046", align 4 + store float %"1681", ptr addrspace(5) %"549", align 4 + %"1683" = load float, ptr addrspace(5) %"549", align 4 + %"1684" = load float, ptr addrspace(5) %"545", align 4 + %"1682" = fmul float %"1683", %"1684" + store float %"1682", ptr addrspace(5) %"550", align 4 + %"1685" = load float, ptr addrspace(5) %"550", align 4 + %"3048" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 64 + store float %"1685", ptr addrspace(5) %"3048", align 4 + %"3050" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 68 + %"1686" = load float, ptr addrspace(5) %"3050", align 4 + store float %"1686", ptr addrspace(5) %"551", align 4 + %"1688" = load float, ptr addrspace(5) %"551", align 4 + %"1689" = load float, ptr addrspace(5) %"546", align 4 + %"1687" = fmul float %"1688", %"1689" + store float %"1687", ptr addrspace(5) %"552", align 4 + %"1690" = load float, ptr addrspace(5) %"552", align 4 + %"3052" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 68 + store float %"1690", ptr addrspace(5) %"3052", align 4 + br label %"311" + +"310": ; preds = %"747" + %65 = alloca i16, align 2, addrspace(5) + store i16 1, ptr addrspace(5) %65, align 2 + %"2688" = load i16, ptr addrspace(5) %65, align 2 + store i16 %"2688", ptr addrspace(5) %"327", align 2 + %"1692" = load i16, ptr addrspace(5) %"327", align 2 + %"3054" = getelementptr inbounds i8, ptr addrspace(5) %"2133", i64 8 + %"2690" = trunc i16 %"1692" to i8 + store i8 %"2690", ptr addrspace(5) %"3054", align 1 + br label %"311" + +"311": ; preds = %"310", %"309" + ret i32 0 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sqrt.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.log2.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.exp2.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.floor.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smin.i32(i32, i32) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smax.i32(i32, i32) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.maxnum.f32(float, float) #2 + +define protected i32 @__zluda_rt_ptx_impl__rollback_wrapper(ptr addrspace(3) %"2302", i32 %"2303", <2 x i32> %"2304", <2 x i32> %"2305", ptr addrspace(5) %"2306", float %"2307", ptr addrspace(5) %"2308", float %"2309", <2 x float> %"2310", <3 x float> %"2311", ptr addrspace(1) %"2312", ptr addrspace(1) %"2313", ptr addrspace(1) %"2314", i64 %"2315") #3 { +"2704": + %"2316" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 0) + %"2318" = load [12 x i8], ptr addrspace(1) %"2316", align 1 + %"2319" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 12) + %"2321" = load [12 x i8], ptr addrspace(1) %"2319", align 1 + %"2322" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 24) + %"2324" = load [12 x i8], ptr addrspace(1) %"2322", align 1 + %"2325" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 36) + %"2327" = load [12 x i8], ptr addrspace(1) %"2325", align 1 + %"2328" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 48) + %"2330" = load [12 x i8], ptr addrspace(1) %"2328", align 1 + %"2331" = call i32 @_Z11closest_hitv(ptr addrspace(3) %"2302", i32 %"2303", <2 x i32> %"2304", <2 x i32> %"2305", ptr addrspace(5) %"2306", float %"2307", ptr addrspace(5) %"2308", float %"2309", <2 x float> %"2310", <3 x float> %"2311", ptr addrspace(1) %"2312", ptr addrspace(1) %"2313", ptr addrspace(1) %"2314") + %"2333" = icmp uge i32 %"2331", 1024 + br i1 %"2333", label %"2334", label %"2335" + +"2334": ; preds = %"2704" + ret i32 %"2331" + +"2335": ; preds = %"2704" + %"2337" = icmp eq i64 %"2315", 0 + br i1 %"2337", label %"2338", label %"2339" + +"2338": ; preds = %"2335" + ret i32 0 + +"2339": ; preds = %"2335" + %"2696" = inttoptr i64 %"2315" to ptr addrspace(1) + %"2341" = load i64, ptr addrspace(1) %"2696", align 8 + %"2697" = inttoptr i64 %"2315" to ptr addrspace(1) + %0 = inttoptr i64 %"2341" to ptr + %"2342" = call i32 %0(ptr addrspace(3) %"2302", i32 %"2303", <2 x i32> %"2304", <2 x i32> %"2305", ptr addrspace(5) %"2306", float %"2307", ptr addrspace(5) %"2308", float %"2309", <2 x float> %"2310", <3 x float> %"2311", ptr addrspace(1) %"2697", ptr addrspace(1) %"2313", ptr addrspace(1) %"2314") + %"2344" = icmp uge i32 %"2342", 1024 + br i1 %"2344", label %"2345", label %"2346" + +"2345": ; preds = %"2339" + ret i32 %"2342" + +"2346": ; preds = %"2339" + %"2349" = icmp eq i32 %"2342", 1 + br i1 %"2349", label %"2350", label %"2347" + +"2350": ; preds = %"2346" + %"2351" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 0) + store [12 x i8] %"2318", ptr addrspace(1) %"2351", align 1 + %"2353" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 12) + store [12 x i8] %"2321", ptr addrspace(1) %"2353", align 1 + %"2355" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 24) + store [12 x i8] %"2324", ptr addrspace(1) %"2355", align 1 + %"2357" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 36) + store [12 x i8] %"2327", ptr addrspace(1) %"2357", align 1 + %"2359" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"2313", i32 48) + store [12 x i8] %"2330", ptr addrspace(1) %"2359", align 1 + br label %"2347" + +"2347": ; preds = %"2350", %"2346" + ret i32 %"2342" +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader.ptx b/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader.ptx new file mode 100644 index 0000000..96b57e6 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader.ptx @@ -0,0 +1,103 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _Z14any_hit_shadowv +.global .align 4 .b8 shading_normal[12]; +.global .align 4 .b8 prd_radiance[20]; +.global .align 4 .b8 prd_shadow[12]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo14shading_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo12prd_radianceE[8] = {82, 97, 121, 0, 20, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo10prd_shadowE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename14shading_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename12prd_radianceE[20] = {80, 101, 114, 82, 97, 121, 68, 97, 116, 97, 95, 114, 97, 100, 105, 97, 110, 99, 101, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename10prd_shadowE[18] = {80, 101, 114, 82, 97, 121, 68, 97, 116, 97, 95, 115, 104, 97, 100, 111, 119, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum14shading_normalE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum12prd_radianceE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum10prd_shadowE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic14shading_normalE[25] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 115, 104, 97, 100, 105, 110, 103, 95, 110, 111, 114, 109, 97, 108, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic12prd_radianceE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic10prd_shadowE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 1 .b8 _ZN23rti_internal_annotation14shading_normalE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation12prd_radianceE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation10prd_shadowE[1]; + +.visible .entry _Z14any_hit_shadowv() +{ + .reg .b32 %r<2>; + + + mov.u32 %r1, 0; + st.global.u32 [prd_shadow], %r1; + st.global.u32 [prd_shadow+4], %r1; + st.global.u32 [prd_shadow+8], %r1; + // begin inline asm + call _rt_terminate_ray, (); + // end inline asm + ret; + +} + // .globl _Z20closest_hit_radiancev +.visible .entry _Z20closest_hit_radiancev() +{ + .reg .f32 %f<19>; + .reg .b32 %r<2>; + + + ld.global.f32 %f5, [shading_normal]; + ld.global.f32 %f6, [shading_normal+4]; + ld.global.f32 %f7, [shading_normal+8]; + mov.u32 %r1, 7937; + mov.f32 %f8, 0f00000000; + // begin inline asm + call (%f1, %f2, %f3, %f4), _rt_transform_tuple, (%r1, %f5, %f6, %f7, %f8); + // end inline asm + mul.ftz.f32 %f9, %f2, %f2; + fma.rn.ftz.f32 %f10, %f1, %f1, %f9; + fma.rn.ftz.f32 %f11, %f3, %f3, %f10; + rsqrt.approx.ftz.f32 %f12, %f11; + mul.ftz.f32 %f13, %f12, %f1; + mul.ftz.f32 %f14, %f12, %f2; + mul.ftz.f32 %f15, %f12, %f3; + fma.rn.ftz.f32 %f16, %f13, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f17, %f14, 0f3F000000, 0f3F000000; + fma.rn.ftz.f32 %f18, %f15, 0f3F000000, 0f3F000000; + st.global.f32 [prd_radiance], %f16; + st.global.f32 [prd_radiance+4], %f17; + st.global.f32 [prd_radiance+8], %f18; + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader_closest_hit_radiance.ll b/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader_closest_hit_radiance.ll new file mode 100644 index 0000000..c987876 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixSphere_generated_normal_shader_closest_hit_radiance.ll @@ -0,0 +1,252 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected i32 @_Z20closest_hit_radiancev(ptr addrspace(3) %"306", i32 %"307", <2 x i32> %"308", <2 x i32> %"309", ptr addrspace(5) %"310", float %"311", ptr addrspace(5) %"312", float %"313", <2 x float> %"314", <3 x float> %"315", ptr addrspace(1) %"316", ptr addrspace(1) %"317", ptr addrspace(1) %"318") #1 { +"417": + %"405" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"405", align 4 + %"235" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"235", align 1 + %"236" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"236", align 1 + %"214" = alloca float, align 4, addrspace(5) + %"215" = alloca float, align 4, addrspace(5) + %"216" = alloca float, align 4, addrspace(5) + %"217" = alloca float, align 4, addrspace(5) + %"218" = alloca float, align 4, addrspace(5) + %"219" = alloca float, align 4, addrspace(5) + %"220" = alloca float, align 4, addrspace(5) + %"221" = alloca float, align 4, addrspace(5) + %"222" = alloca float, align 4, addrspace(5) + %"223" = alloca float, align 4, addrspace(5) + %"224" = alloca float, align 4, addrspace(5) + %"225" = alloca float, align 4, addrspace(5) + %"226" = alloca float, align 4, addrspace(5) + %"227" = alloca float, align 4, addrspace(5) + %"228" = alloca float, align 4, addrspace(5) + %"229" = alloca float, align 4, addrspace(5) + %"230" = alloca float, align 4, addrspace(5) + %"231" = alloca float, align 4, addrspace(5) + %"232" = alloca float, align 4, addrspace(5) + %"233" = alloca i32, align 4, addrspace(5) + %"234" = alloca i32, align 4, addrspace(5) + %"319" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"317", i32 0) + %"237" = load float, ptr addrspace(1) %"319", align 4 + store float %"237", ptr addrspace(5) %"219", align 4 + %"321" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"317", i32 0) + %"420" = getelementptr inbounds i8, ptr addrspace(1) %"321", i64 4 + %"238" = load float, ptr addrspace(1) %"420", align 4 + store float %"238", ptr addrspace(5) %"220", align 4 + %"324" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"317", i32 0) + %"422" = getelementptr inbounds i8, ptr addrspace(1) %"324", i64 8 + %"239" = load float, ptr addrspace(1) %"422", align 4 + store float %"239", ptr addrspace(5) %"221", align 4 + %0 = alloca i32, align 4, addrspace(5) + store i32 7937, ptr addrspace(5) %0, align 4 + %"409" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"409", ptr addrspace(5) %"234", align 4 + %1 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %1, align 4 + %"241" = load float, ptr addrspace(5) %1, align 4 + store float %"241", ptr addrspace(5) %"222", align 4 + %"246" = load i32, ptr addrspace(5) %"234", align 4 + %"247" = load float, ptr addrspace(5) %"219", align 4 + %"248" = load float, ptr addrspace(5) %"220", align 4 + %"249" = load float, ptr addrspace(5) %"221", align 4 + %"250" = load float, ptr addrspace(5) %"222", align 4 + %2 = call %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32 %"246", float %"247", float %"248", float %"249", float %"250") + %"242" = extractvalue %struct.f32f32f32f32 %2, 0 + %"243" = extractvalue %struct.f32f32f32f32 %2, 1 + %"244" = extractvalue %struct.f32f32f32f32 %2, 2 + %"245" = extractvalue %struct.f32f32f32f32 %2, 3 + store float %"242", ptr addrspace(5) %"215", align 4 + store float %"243", ptr addrspace(5) %"216", align 4 + store float %"244", ptr addrspace(5) %"217", align 4 + store float %"245", ptr addrspace(5) %"218", align 4 + %"252" = load float, ptr addrspace(5) %"216", align 4 + %"253" = load float, ptr addrspace(5) %"216", align 4 + %"251" = fmul float %"252", %"253" + store float %"251", ptr addrspace(5) %"223", align 4 + %"255" = load float, ptr addrspace(5) %"215", align 4 + %"256" = load float, ptr addrspace(5) %"215", align 4 + %"257" = load float, ptr addrspace(5) %"223", align 4 + %"254" = call float @llvm.fma.f32(float %"255", float %"256", float %"257") + store float %"254", ptr addrspace(5) %"224", align 4 + %"259" = load float, ptr addrspace(5) %"217", align 4 + %"260" = load float, ptr addrspace(5) %"217", align 4 + %"261" = load float, ptr addrspace(5) %"224", align 4 + %"258" = call float @llvm.fma.f32(float %"259", float %"260", float %"261") + store float %"258", ptr addrspace(5) %"225", align 4 + %"263" = load float, ptr addrspace(5) %"225", align 4 + %3 = call afn float @llvm.sqrt.f32(float %"263") + %"262" = fdiv arcp afn float 1.000000e+00, %3 + store float %"262", ptr addrspace(5) %"226", align 4 + %"265" = load float, ptr addrspace(5) %"226", align 4 + %"266" = load float, ptr addrspace(5) %"215", align 4 + %"264" = fmul float %"265", %"266" + store float %"264", ptr addrspace(5) %"227", align 4 + %"268" = load float, ptr addrspace(5) %"226", align 4 + %"269" = load float, ptr addrspace(5) %"216", align 4 + %"267" = fmul float %"268", %"269" + store float %"267", ptr addrspace(5) %"228", align 4 + %"271" = load float, ptr addrspace(5) %"226", align 4 + %"272" = load float, ptr addrspace(5) %"217", align 4 + %"270" = fmul float %"271", %"272" + store float %"270", ptr addrspace(5) %"229", align 4 + %"274" = load float, ptr addrspace(5) %"227", align 4 + %"273" = call float @llvm.fma.f32(float %"274", float 5.000000e-01, float 5.000000e-01) + store float %"273", ptr addrspace(5) %"230", align 4 + %"276" = load float, ptr addrspace(5) %"228", align 4 + %"275" = call float @llvm.fma.f32(float %"276", float 5.000000e-01, float 5.000000e-01) + store float %"275", ptr addrspace(5) %"231", align 4 + %"278" = load float, ptr addrspace(5) %"229", align 4 + %"277" = call float @llvm.fma.f32(float %"278", float 5.000000e-01, float 5.000000e-01) + store float %"277", ptr addrspace(5) %"232", align 4 + %"279" = load float, ptr addrspace(5) %"230", align 4 + store float %"279", ptr addrspace(5) %"312", align 4 + %"280" = load float, ptr addrspace(5) %"231", align 4 + %"424" = getelementptr inbounds i8, ptr addrspace(5) %"312", i64 4 + store float %"280", ptr addrspace(5) %"424", align 4 + %"281" = load float, ptr addrspace(5) %"232", align 4 + %"426" = getelementptr inbounds i8, ptr addrspace(5) %"312", i64 8 + store float %"281", ptr addrspace(5) %"426", align 4 + ret i32 0 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sqrt.f32(float) #2 + +define protected i32 @__zluda_rt_ptx_impl__rollback_wrapper(ptr addrspace(3) %"335", i32 %"336", <2 x i32> %"337", <2 x i32> %"338", ptr addrspace(5) %"339", float %"340", ptr addrspace(5) %"341", float %"342", <2 x float> %"343", <3 x float> %"344", ptr addrspace(1) %"345", ptr addrspace(1) %"346", ptr addrspace(1) %"347", i64 %"348") #3 { +"418": + %"349" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"346", i32 0) + %"351" = load [12 x i8], ptr addrspace(1) %"349", align 1 + %"352" = call i32 @_Z20closest_hit_radiancev(ptr addrspace(3) %"335", i32 %"336", <2 x i32> %"337", <2 x i32> %"338", ptr addrspace(5) %"339", float %"340", ptr addrspace(5) %"341", float %"342", <2 x float> %"343", <3 x float> %"344", ptr addrspace(1) %"345", ptr addrspace(1) %"346", ptr addrspace(1) %"347") + %"354" = icmp uge i32 %"352", 1024 + br i1 %"354", label %"355", label %"356" + +"355": ; preds = %"418" + ret i32 %"352" + +"356": ; preds = %"418" + %"358" = icmp eq i64 %"348", 0 + br i1 %"358", label %"359", label %"360" + +"359": ; preds = %"356" + ret i32 0 + +"360": ; preds = %"356" + %"414" = inttoptr i64 %"348" to ptr addrspace(1) + %"362" = load i64, ptr addrspace(1) %"414", align 8 + %"415" = inttoptr i64 %"348" to ptr addrspace(1) + %0 = inttoptr i64 %"362" to ptr + %"363" = call i32 %0(ptr addrspace(3) %"335", i32 %"336", <2 x i32> %"337", <2 x i32> %"338", ptr addrspace(5) %"339", float %"340", ptr addrspace(5) %"341", float %"342", <2 x float> %"343", <3 x float> %"344", ptr addrspace(1) %"415", ptr addrspace(1) %"346", ptr addrspace(1) %"347") + %"365" = icmp uge i32 %"363", 1024 + br i1 %"365", label %"366", label %"367" + +"366": ; preds = %"360" + ret i32 %"363" + +"367": ; preds = %"360" + %"370" = icmp eq i32 %"363", 1 + br i1 %"370", label %"371", label %"368" + +"371": ; preds = %"367" + %"372" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"346", i32 0) + store [12 x i8] %"351", ptr addrspace(1) %"372", align 1 + br label %"368" + +"368": ; preds = %"371", %"367" + ret i32 %"363" +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere.ptx b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere.ptx new file mode 100644 index 0000000..79f16c0 --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere.ptx @@ -0,0 +1,348 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-30672275 +// Cuda compilation tools, release 11.5, V11.5.119 +// Based on NVVM 7.0.1 +// + +.version 7.5 +.target sm_60 +.address_size 64 + + // .globl _Z9intersecti +.global .align 16 .b8 sphere[16]; +.global .align 4 .b8 geometric_normal[12]; +.global .align 4 .b8 shading_normal[12]; +.global .align 4 .b8 ray[36]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo16geometric_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo14shading_normalE[8] = {82, 97, 121, 0, 12, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename16geometric_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename14shading_normalE[7] = {102, 108, 111, 97, 116, 51, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum16geometric_normalE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum14shading_normalE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic16geometric_normalE[27] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 103, 101, 111, 109, 101, 116, 114, 105, 99, 95, 110, 111, 114, 109, 97, 108, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic14shading_normalE[25] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 115, 104, 97, 100, 105, 110, 103, 95, 110, 111, 114, 109, 97, 108, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation16geometric_normalE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation14shading_normalE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; + +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<5>; + .reg .f32 %f<57>; + .reg .b32 %r<7>; + + + ld.global.v4.f32 {%f14, %f15, %f16, %f17}, [sphere]; + ld.global.f32 %f21, [ray]; + sub.ftz.f32 %f2, %f21, %f14; + ld.global.f32 %f22, [ray+4]; + sub.ftz.f32 %f3, %f22, %f15; + ld.global.f32 %f23, [ray+8]; + sub.ftz.f32 %f4, %f23, %f16; + ld.global.f32 %f24, [ray+12]; + ld.global.f32 %f25, [ray+16]; + mul.ftz.f32 %f26, %f25, %f25; + fma.rn.ftz.f32 %f27, %f24, %f24, %f26; + ld.global.f32 %f28, [ray+20]; + fma.rn.ftz.f32 %f29, %f28, %f28, %f27; + rsqrt.approx.ftz.f32 %f5, %f29; + mul.ftz.f32 %f6, %f24, %f5; + mul.ftz.f32 %f7, %f5, %f25; + mul.ftz.f32 %f8, %f5, %f28; + mul.ftz.f32 %f30, %f3, %f7; + fma.rn.ftz.f32 %f31, %f2, %f6, %f30; + fma.rn.ftz.f32 %f9, %f4, %f8, %f31; + mul.ftz.f32 %f32, %f3, %f3; + fma.rn.ftz.f32 %f33, %f2, %f2, %f32; + fma.rn.ftz.f32 %f34, %f4, %f4, %f33; + mul.ftz.f32 %f35, %f17, %f17; + sub.ftz.f32 %f36, %f34, %f35; + mul.ftz.f32 %f37, %f9, %f9; + sub.ftz.f32 %f10, %f37, %f36; + setp.leu.ftz.f32 %p1, %f10, 0f00000000; + @%p1 bra $L__BB0_5; + + sqrt.approx.ftz.f32 %f11, %f10; + neg.ftz.f32 %f39, %f9; + sub.ftz.f32 %f40, %f39, %f11; + add.ftz.f32 %f12, %f40, 0f00000000; + mul.ftz.f32 %f38, %f5, %f12; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f38); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB0_3; + + fma.rn.ftz.f32 %f41, %f6, %f12, %f2; + fma.rn.ftz.f32 %f42, %f7, %f12, %f3; + fma.rn.ftz.f32 %f43, %f8, %f12, %f4; + rcp.approx.ftz.f32 %f44, %f17; + mul.ftz.f32 %f45, %f44, %f41; + mul.ftz.f32 %f46, %f44, %f42; + mul.ftz.f32 %f47, %f44, %f43; + st.global.f32 [geometric_normal], %f45; + st.global.f32 [geometric_normal+4], %f46; + st.global.f32 [geometric_normal+8], %f47; + st.global.f32 [shading_normal], %f45; + st.global.f32 [shading_normal+4], %f46; + st.global.f32 [shading_normal+8], %f47; + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.ne.s32 %p3, %r2, 0; + @%p3 bra $L__BB0_5; + +$L__BB0_3: + sub.ftz.f32 %f49, %f11, %f9; + add.ftz.f32 %f13, %f49, 0f00000000; + mul.ftz.f32 %f48, %f5, %f13; + // begin inline asm + call (%r4), _rt_potential_intersection, (%f48); + // end inline asm + setp.eq.s32 %p4, %r4, 0; + @%p4 bra $L__BB0_5; + + fma.rn.ftz.f32 %f50, %f6, %f13, %f2; + fma.rn.ftz.f32 %f51, %f7, %f13, %f3; + fma.rn.ftz.f32 %f52, %f8, %f13, %f4; + rcp.approx.ftz.f32 %f53, %f17; + mul.ftz.f32 %f54, %f53, %f50; + mul.ftz.f32 %f55, %f53, %f51; + mul.ftz.f32 %f56, %f53, %f52; + st.global.f32 [geometric_normal], %f54; + st.global.f32 [geometric_normal+4], %f55; + st.global.f32 [geometric_normal+8], %f56; + st.global.f32 [shading_normal], %f54; + st.global.f32 [shading_normal+4], %f55; + st.global.f32 [shading_normal+8], %f56; + mov.u32 %r6, 0; + // begin inline asm + call (%r5), _rt_report_intersection, (%r6); + // end inline asm + +$L__BB0_5: + ret; + +} + // .globl _Z16robust_intersecti +.visible .entry _Z16robust_intersecti( + .param .u32 _Z16robust_intersecti_param_0 +) +{ + .reg .pred %p<8>; + .reg .f32 %f<84>; + .reg .b32 %r<7>; + + + ld.global.v4.f32 {%f25, %f26, %f27, %f28}, [sphere]; + ld.global.f32 %f32, [ray]; + sub.ftz.f32 %f2, %f32, %f25; + ld.global.f32 %f33, [ray+4]; + sub.ftz.f32 %f3, %f33, %f26; + ld.global.f32 %f34, [ray+8]; + sub.ftz.f32 %f4, %f34, %f27; + ld.global.f32 %f35, [ray+12]; + ld.global.f32 %f36, [ray+16]; + mul.ftz.f32 %f37, %f36, %f36; + fma.rn.ftz.f32 %f38, %f35, %f35, %f37; + ld.global.f32 %f39, [ray+20]; + fma.rn.ftz.f32 %f40, %f39, %f39, %f38; + rsqrt.approx.ftz.f32 %f5, %f40; + mul.ftz.f32 %f6, %f35, %f5; + mul.ftz.f32 %f7, %f5, %f36; + mul.ftz.f32 %f8, %f5, %f39; + mul.ftz.f32 %f41, %f3, %f7; + fma.rn.ftz.f32 %f42, %f2, %f6, %f41; + fma.rn.ftz.f32 %f82, %f4, %f8, %f42; + mul.ftz.f32 %f43, %f3, %f3; + fma.rn.ftz.f32 %f44, %f2, %f2, %f43; + fma.rn.ftz.f32 %f45, %f4, %f4, %f44; + mul.ftz.f32 %f10, %f28, %f28; + sub.ftz.f32 %f46, %f45, %f10; + mul.ftz.f32 %f47, %f82, %f82; + sub.ftz.f32 %f11, %f47, %f46; + setp.leu.ftz.f32 %p1, %f11, 0f00000000; + mov.f32 %f83, 0f00000000; + @%p1 bra $L__BB1_8; + + sqrt.approx.ftz.f32 %f81, %f11; + neg.ftz.f32 %f49, %f82; + sub.ftz.f32 %f13, %f49, %f81; + abs.ftz.f32 %f14, %f13; + mul.ftz.f32 %f15, %f28, 0f41200000; + setp.leu.ftz.f32 %p2, %f14, %f15; + @%p2 bra $L__BB1_4; + + fma.rn.ftz.f32 %f51, %f6, %f13, %f2; + fma.rn.ftz.f32 %f52, %f7, %f13, %f3; + fma.rn.ftz.f32 %f53, %f8, %f13, %f4; + mul.ftz.f32 %f54, %f7, %f52; + fma.rn.ftz.f32 %f55, %f6, %f51, %f54; + fma.rn.ftz.f32 %f82, %f8, %f53, %f55; + mul.ftz.f32 %f56, %f52, %f52; + fma.rn.ftz.f32 %f57, %f51, %f51, %f56; + fma.rn.ftz.f32 %f58, %f53, %f53, %f57; + sub.ftz.f32 %f59, %f58, %f10; + mul.ftz.f32 %f60, %f82, %f82; + sub.ftz.f32 %f17, %f60, %f59; + setp.leu.ftz.f32 %p3, %f17, 0f00000000; + @%p3 bra $L__BB1_4; + + sqrt.approx.ftz.f32 %f81, %f17; + neg.ftz.f32 %f61, %f82; + sub.ftz.f32 %f83, %f61, %f81; + +$L__BB1_4: + add.ftz.f32 %f23, %f13, %f83; + mul.ftz.f32 %f62, %f5, %f23; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f62); + // end inline asm + setp.eq.s32 %p4, %r1, 0; + @%p4 bra $L__BB1_6; + + fma.rn.ftz.f32 %f63, %f6, %f23, %f2; + fma.rn.ftz.f32 %f64, %f7, %f23, %f3; + fma.rn.ftz.f32 %f65, %f8, %f23, %f4; + rcp.approx.ftz.f32 %f66, %f28; + mul.ftz.f32 %f67, %f66, %f63; + mul.ftz.f32 %f68, %f66, %f64; + mul.ftz.f32 %f69, %f66, %f65; + st.global.f32 [geometric_normal], %f67; + st.global.f32 [geometric_normal+4], %f68; + st.global.f32 [geometric_normal+8], %f69; + st.global.f32 [shading_normal], %f67; + st.global.f32 [shading_normal+4], %f68; + st.global.f32 [shading_normal+8], %f69; + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.ne.s32 %p5, %r2, 0; + @%p5 bra $L__BB1_8; + +$L__BB1_6: + setp.gt.ftz.f32 %p6, %f14, %f15; + selp.f32 %f71, %f13, 0f00000000, %p6; + sub.ftz.f32 %f72, %f81, %f82; + add.ftz.f32 %f24, %f71, %f72; + mul.ftz.f32 %f70, %f5, %f24; + // begin inline asm + call (%r4), _rt_potential_intersection, (%f70); + // end inline asm + setp.eq.s32 %p7, %r4, 0; + @%p7 bra $L__BB1_8; + + fma.rn.ftz.f32 %f73, %f6, %f24, %f2; + fma.rn.ftz.f32 %f74, %f7, %f24, %f3; + fma.rn.ftz.f32 %f75, %f8, %f24, %f4; + rcp.approx.ftz.f32 %f76, %f28; + mul.ftz.f32 %f77, %f76, %f73; + mul.ftz.f32 %f78, %f76, %f74; + mul.ftz.f32 %f79, %f76, %f75; + st.global.f32 [geometric_normal], %f77; + st.global.f32 [geometric_normal+4], %f78; + st.global.f32 [geometric_normal+8], %f79; + st.global.f32 [shading_normal], %f77; + st.global.f32 [shading_normal+4], %f78; + st.global.f32 [shading_normal+8], %f79; + mov.u32 %r6, 0; + // begin inline asm + call (%r5), _rt_report_intersection, (%r6); + // end inline asm + +$L__BB1_8: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.ftz.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.ftz.f32 %f10, %f9; + setp.neu.ftz.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.ftz.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.ftz.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.ftz.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.ftz.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.ftz.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.ftz.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + diff --git a/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_bounds.ll b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_bounds.ll new file mode 100644 index 0000000..d51249d --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_bounds.ll @@ -0,0 +1,273 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected void @_Z6boundsiPf(i32 %"456", i64 %"457", ptr addrspace(3) %"553", ptr addrspace(1) %"554") #1 { +"613": + %"590" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"590", align 4 + %"452" = alloca i32, align 4, addrspace(5) + %"453" = alloca i64, align 8, addrspace(5) + %"454" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"454", align 1 + %"455" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"455", align 1 + %"543" = alloca i32, align 4, addrspace(5) + %"544" = alloca i64, align 8, addrspace(5) + %"419" = alloca i1, align 1, addrspace(5) + %"420" = alloca i1, align 1, addrspace(5) + %"421" = alloca i1, align 1, addrspace(5) + %"422" = alloca float, align 4, addrspace(5) + %"423" = alloca float, align 4, addrspace(5) + %"424" = alloca float, align 4, addrspace(5) + %"425" = alloca float, align 4, addrspace(5) + %"426" = alloca float, align 4, addrspace(5) + %"427" = alloca float, align 4, addrspace(5) + %"428" = alloca float, align 4, addrspace(5) + %"429" = alloca float, align 4, addrspace(5) + %"430" = alloca float, align 4, addrspace(5) + %"431" = alloca float, align 4, addrspace(5) + %"432" = alloca float, align 4, addrspace(5) + %"433" = alloca float, align 4, addrspace(5) + %"434" = alloca float, align 4, addrspace(5) + %"435" = alloca float, align 4, addrspace(5) + %"436" = alloca float, align 4, addrspace(5) + %"437" = alloca float, align 4, addrspace(5) + %"438" = alloca float, align 4, addrspace(5) + %"439" = alloca i32, align 4, addrspace(5) + %"440" = alloca i32, align 4, addrspace(5) + %"441" = alloca i32, align 4, addrspace(5) + %"442" = alloca i64, align 8, addrspace(5) + %"443" = alloca i64, align 8, addrspace(5) + %"444" = alloca i64, align 8, addrspace(5) + store i32 %"456", ptr addrspace(5) %"452", align 4 + store i64 %"457", ptr addrspace(5) %"453", align 8 + %"458" = load i32, ptr addrspace(5) %"452", align 4 + store i32 %"458", ptr addrspace(5) %"543", align 4 + %"459" = load i64, ptr addrspace(5) %"453", align 8 + store i64 %"459", ptr addrspace(5) %"544", align 8 + %"591" = load i64, ptr addrspace(5) %"544", align 8 + store i64 %"591", ptr addrspace(5) %"444", align 8 + %"462" = load i64, ptr addrspace(5) %"444", align 8 + %0 = inttoptr i64 %"462" to ptr + %1 = addrspacecast ptr %0 to ptr addrspace(1) + %"461" = ptrtoint ptr addrspace(1) %1 to i64 + store i64 %"461", ptr addrspace(5) %"443", align 8 + %"555" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"554", i32 0) + %"451" = load <4 x float>, ptr addrspace(1) %"555", align 16 + %"463" = extractelement <4 x float> %"451", i32 0 + %"464" = extractelement <4 x float> %"451", i32 1 + %"465" = extractelement <4 x float> %"451", i32 2 + %"466" = extractelement <4 x float> %"451", i32 3 + store float %"463", ptr addrspace(5) %"428", align 4 + store float %"464", ptr addrspace(5) %"429", align 4 + store float %"465", ptr addrspace(5) %"430", align 4 + store float %"466", ptr addrspace(5) %"431", align 4 + %"468" = load float, ptr addrspace(5) %"431", align 4 + %"467" = fcmp ule float %"468", 0.000000e+00 + store i1 %"467", ptr addrspace(5) %"420", align 1 + %"469" = load i1, ptr addrspace(5) %"420", align 1 + br i1 %"469", label %"417", label %"446" + +"446": ; preds = %"613" + %"471" = load float, ptr addrspace(5) %"431", align 4 + %"470" = call float @llvm.fabs.f32(float %"471") + store float %"470", ptr addrspace(5) %"432", align 4 + %"473" = load float, ptr addrspace(5) %"432", align 4 + %"472" = fcmp une float %"473", 0x7FF0000000000000 + store i1 %"472", ptr addrspace(5) %"421", align 1 + %"474" = load i1, ptr addrspace(5) %"421", align 1 + br i1 %"474", label %"416", label %"448" + +"448": ; preds = %"446" + br label %"417" + +"416": ; preds = %"446" + %"476" = load float, ptr addrspace(5) %"428", align 4 + %"477" = load float, ptr addrspace(5) %"431", align 4 + %"475" = fsub float %"476", %"477" + store float %"475", ptr addrspace(5) %"433", align 4 + %"478" = load i64, ptr addrspace(5) %"443", align 8 + %"479" = load float, ptr addrspace(5) %"433", align 4 + %"593" = inttoptr i64 %"478" to ptr addrspace(1) + store float %"479", ptr addrspace(1) %"593", align 4 + %"481" = load float, ptr addrspace(5) %"429", align 4 + %"482" = load float, ptr addrspace(5) %"431", align 4 + %"480" = fsub float %"481", %"482" + store float %"480", ptr addrspace(5) %"434", align 4 + %"483" = load i64, ptr addrspace(5) %"443", align 8 + %"484" = load float, ptr addrspace(5) %"434", align 4 + %"594" = inttoptr i64 %"483" to ptr addrspace(1) + %"615" = getelementptr inbounds i8, ptr addrspace(1) %"594", i64 4 + store float %"484", ptr addrspace(1) %"615", align 4 + %"486" = load float, ptr addrspace(5) %"430", align 4 + %"487" = load float, ptr addrspace(5) %"431", align 4 + %"485" = fsub float %"486", %"487" + store float %"485", ptr addrspace(5) %"435", align 4 + %"488" = load i64, ptr addrspace(5) %"443", align 8 + %"489" = load float, ptr addrspace(5) %"435", align 4 + %"595" = inttoptr i64 %"488" to ptr addrspace(1) + %"617" = getelementptr inbounds i8, ptr addrspace(1) %"595", i64 8 + store float %"489", ptr addrspace(1) %"617", align 4 + %"491" = load float, ptr addrspace(5) %"428", align 4 + %"492" = load float, ptr addrspace(5) %"431", align 4 + %"490" = fadd float %"491", %"492" + store float %"490", ptr addrspace(5) %"436", align 4 + %"493" = load i64, ptr addrspace(5) %"443", align 8 + %"494" = load float, ptr addrspace(5) %"436", align 4 + %"596" = inttoptr i64 %"493" to ptr addrspace(1) + %"619" = getelementptr inbounds i8, ptr addrspace(1) %"596", i64 16 + store float %"494", ptr addrspace(1) %"619", align 4 + %"496" = load float, ptr addrspace(5) %"429", align 4 + %"497" = load float, ptr addrspace(5) %"431", align 4 + %"495" = fadd float %"496", %"497" + store float %"495", ptr addrspace(5) %"437", align 4 + %"498" = load i64, ptr addrspace(5) %"443", align 8 + %"499" = load float, ptr addrspace(5) %"437", align 4 + %"597" = inttoptr i64 %"498" to ptr addrspace(1) + %"621" = getelementptr inbounds i8, ptr addrspace(1) %"597", i64 20 + store float %"499", ptr addrspace(1) %"621", align 4 + %"501" = load float, ptr addrspace(5) %"430", align 4 + %"502" = load float, ptr addrspace(5) %"431", align 4 + %"500" = fadd float %"501", %"502" + store float %"500", ptr addrspace(5) %"438", align 4 + %"503" = load i64, ptr addrspace(5) %"443", align 8 + %"504" = load float, ptr addrspace(5) %"438", align 4 + %"598" = inttoptr i64 %"503" to ptr addrspace(1) + %"623" = getelementptr inbounds i8, ptr addrspace(1) %"598", i64 24 + store float %"504", ptr addrspace(1) %"623", align 4 + br label %"418" + +"417": ; preds = %"448", %"613" + %2 = alloca i32, align 4, addrspace(5) + store i32 2096152002, ptr addrspace(5) %2, align 4 + %"599" = load i32, ptr addrspace(5) %2, align 4 + store i32 %"599", ptr addrspace(5) %"440", align 4 + %"506" = load i64, ptr addrspace(5) %"443", align 8 + %"507" = load i32, ptr addrspace(5) %"440", align 4 + %"600" = inttoptr i64 %"506" to ptr addrspace(1) + store i32 %"507", ptr addrspace(1) %"600", align 4 + %"508" = load i64, ptr addrspace(5) %"443", align 8 + %"509" = load i32, ptr addrspace(5) %"440", align 4 + %"602" = inttoptr i64 %"508" to ptr addrspace(1) + %"625" = getelementptr inbounds i8, ptr addrspace(1) %"602", i64 4 + store i32 %"509", ptr addrspace(1) %"625", align 4 + %"510" = load i64, ptr addrspace(5) %"443", align 8 + %"511" = load i32, ptr addrspace(5) %"440", align 4 + %"604" = inttoptr i64 %"510" to ptr addrspace(1) + %"627" = getelementptr inbounds i8, ptr addrspace(1) %"604", i64 8 + store i32 %"511", ptr addrspace(1) %"627", align 4 + %3 = alloca i32, align 4, addrspace(5) + store i32 -51331646, ptr addrspace(5) %3, align 4 + %"606" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"606", ptr addrspace(5) %"441", align 4 + %"513" = load i64, ptr addrspace(5) %"443", align 8 + %"514" = load i32, ptr addrspace(5) %"441", align 4 + %"607" = inttoptr i64 %"513" to ptr addrspace(1) + %"629" = getelementptr inbounds i8, ptr addrspace(1) %"607", i64 16 + store i32 %"514", ptr addrspace(1) %"629", align 4 + %"515" = load i64, ptr addrspace(5) %"443", align 8 + %"516" = load i32, ptr addrspace(5) %"441", align 4 + %"609" = inttoptr i64 %"515" to ptr addrspace(1) + %"631" = getelementptr inbounds i8, ptr addrspace(1) %"609", i64 20 + store i32 %"516", ptr addrspace(1) %"631", align 4 + %"517" = load i64, ptr addrspace(5) %"443", align 8 + %"518" = load i32, ptr addrspace(5) %"441", align 4 + %"611" = inttoptr i64 %"517" to ptr addrspace(1) + %"633" = getelementptr inbounds i8, ptr addrspace(1) %"611", i64 24 + store i32 %"518", ptr addrspace(1) %"633", align 4 + br label %"418" + +"418": ; preds = %"417", %"416" + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fabs.f32(float) #2 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_robust_intersect.ll b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_robust_intersect.ll new file mode 100644 index 0000000..6b279be --- /dev/null +++ b/ptx/src/test/ptx_raytracing/optixSphere_generated_sphere_robust_intersect.ll @@ -0,0 +1,639 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i64i64i64 = type { i64, i64, i64, i64 } +%struct.f32f32f32f32 = type { float, float, float, float } +%struct.f32f32 = type { float, float } +%struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float } + +@_ZN21rti_internal_register20reg_bitness_detectorE = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail0E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail1E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail2E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail3E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail4E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail5E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail6E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail7E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail8E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register24reg_exception_64_detail9E = private addrspace(1) externally_initialized global i64 0, align 8 +@_ZN21rti_internal_register21reg_exception_detail0E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail1E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail2E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail3E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail4E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail5E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail6E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail7E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail8E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register21reg_exception_detail9E = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_xE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_yE = private addrspace(1) externally_initialized global i32 0, align 4 +@_ZN21rti_internal_register14reg_rayIndex_zE = private addrspace(1) externally_initialized global i32 0, align 4 + +declare ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1), i32) #0 + +declare ptr addrspace(3) @__zluda_rt_ptx_impl__get_variable_pointer_shared(ptr addrspace(3), i32) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_64(i64, i32, i32, i64, i64, i64, i64) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_64(i32, i32, i32, i64, i64, i64, i64, ptr addrspace(3)) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_size_64(i64, i32, i32) #0 + +declare %struct.i64i64i64i64 @__zluda_rt_ptx_impl___rt_buffer_get_id_size_64(i32, i32, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_trace_time_mask_flags_64(i32, float, float, float, float, float, float, i32, float, float, float, i32, i32, i64, i32, ptr addrspace(3)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_exception_code() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_print_active() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float, ptr addrspace(5), float, ptr addrspace(5)) #0 + +declare i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32, ptr addrspace(3), <2 x i32>, <2 x i32>, ptr addrspace(5), float, ptr addrspace(5), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5), ptr addrspace(5)) #0 + +declare void @__zluda_rt_ptx_impl___rt_terminate_ray() #0 + +declare void @__zluda_rt_ptx_impl___rt_ignore_intersection() #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_transform_tuple(i32, float, float, float, float) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_64(i32, ptr addrspace(3)) #0 + +declare i64 @__zluda_rt_ptx_impl___rt_callable_program_from_id_v2_64(i32, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_get_f_id(i32, i32, float, float, float, float, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_grad_load_or_request_f_id(i32, i32, float, float, float, float, float, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32f32f32 @__zluda_rt_ptx_impl___rt_texture_lod_load_or_request_f_id(i32, i32, float, float, float, float, float, i64, ptr addrspace(3)) #0 + +declare %struct.f32f32 @__zluda_rt_ptx_impl___rt_get_triangle_barycentrics() #0 + +declare i32 @__zluda_rt_ptx_impl___rt_get_primitive_index() #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit(<3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_front_face(ptr addrspace(5), <3 x float>) #0 + +declare float @__zluda_rt_ptx_impl___rt_is_triangle_hit_back_face(ptr addrspace(5), <3 x float>) #0 + +declare %struct.f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32f32 @__zluda_rt_ptx_impl___rt_get_transform(i32, ptr addrspace(1)) #0 + +declare void @__zluda_rt_ptx_impl___rt_throw(i32) #0 + +define protected void @_Z16robust_intersecti(i32 %"455", ptr addrspace(3) %"747", <2 x i32> %"748", <2 x i32> %"749", ptr addrspace(5) %"750", float %"751", ptr addrspace(5) %"752", float %"753", ptr addrspace(1) %"754", ptr addrspace(1) %"755", ptr addrspace(1) %"756", ptr addrspace(5) %"757", ptr addrspace(5) %"758", ptr addrspace(5) %"759") #1 { +"892": + %"863" = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %"863", align 4 + %"452" = alloca i32, align 4, addrspace(5) + %"453" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"453", align 1 + %"454" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"454", align 1 + %"738" = alloca i32, align 4, addrspace(5) + %"302" = alloca i1, align 1, addrspace(5) + %"303" = alloca i1, align 1, addrspace(5) + %"304" = alloca i1, align 1, addrspace(5) + %"305" = alloca i1, align 1, addrspace(5) + %"306" = alloca i1, align 1, addrspace(5) + %"307" = alloca i1, align 1, addrspace(5) + %"308" = alloca i1, align 1, addrspace(5) + %"309" = alloca i1, align 1, addrspace(5) + %"310" = alloca float, align 4, addrspace(5) + %"311" = alloca float, align 4, addrspace(5) + %"312" = alloca float, align 4, addrspace(5) + %"313" = alloca float, align 4, addrspace(5) + %"314" = alloca float, align 4, addrspace(5) + %"315" = alloca float, align 4, addrspace(5) + %"316" = alloca float, align 4, addrspace(5) + %"317" = alloca float, align 4, addrspace(5) + %"318" = alloca float, align 4, addrspace(5) + %"319" = alloca float, align 4, addrspace(5) + %"320" = alloca float, align 4, addrspace(5) + %"321" = alloca float, align 4, addrspace(5) + %"322" = alloca float, align 4, addrspace(5) + %"323" = alloca float, align 4, addrspace(5) + %"324" = alloca float, align 4, addrspace(5) + %"325" = alloca float, align 4, addrspace(5) + %"326" = alloca float, align 4, addrspace(5) + %"327" = alloca float, align 4, addrspace(5) + %"328" = alloca float, align 4, addrspace(5) + %"329" = alloca float, align 4, addrspace(5) + %"330" = alloca float, align 4, addrspace(5) + %"331" = alloca float, align 4, addrspace(5) + %"332" = alloca float, align 4, addrspace(5) + %"333" = alloca float, align 4, addrspace(5) + %"334" = alloca float, align 4, addrspace(5) + %"335" = alloca float, align 4, addrspace(5) + %"336" = alloca float, align 4, addrspace(5) + %"337" = alloca float, align 4, addrspace(5) + %"338" = alloca float, align 4, addrspace(5) + %"339" = alloca float, align 4, addrspace(5) + %"340" = alloca float, align 4, addrspace(5) + %"341" = alloca float, align 4, addrspace(5) + %"342" = alloca float, align 4, addrspace(5) + %"343" = alloca float, align 4, addrspace(5) + %"344" = alloca float, align 4, addrspace(5) + %"345" = alloca float, align 4, addrspace(5) + %"346" = alloca float, align 4, addrspace(5) + %"347" = alloca float, align 4, addrspace(5) + %"348" = alloca float, align 4, addrspace(5) + %"349" = alloca float, align 4, addrspace(5) + %"350" = alloca float, align 4, addrspace(5) + %"351" = alloca float, align 4, addrspace(5) + %"352" = alloca float, align 4, addrspace(5) + %"353" = alloca float, align 4, addrspace(5) + %"354" = alloca float, align 4, addrspace(5) + %"355" = alloca float, align 4, addrspace(5) + %"356" = alloca float, align 4, addrspace(5) + %"357" = alloca float, align 4, addrspace(5) + %"358" = alloca float, align 4, addrspace(5) + %"359" = alloca float, align 4, addrspace(5) + %"360" = alloca float, align 4, addrspace(5) + %"361" = alloca float, align 4, addrspace(5) + %"362" = alloca float, align 4, addrspace(5) + %"363" = alloca float, align 4, addrspace(5) + %"364" = alloca float, align 4, addrspace(5) + %"365" = alloca float, align 4, addrspace(5) + %"366" = alloca float, align 4, addrspace(5) + %"367" = alloca float, align 4, addrspace(5) + %"368" = alloca float, align 4, addrspace(5) + %"369" = alloca float, align 4, addrspace(5) + %"370" = alloca float, align 4, addrspace(5) + %"371" = alloca float, align 4, addrspace(5) + %"372" = alloca float, align 4, addrspace(5) + %"373" = alloca float, align 4, addrspace(5) + %"374" = alloca float, align 4, addrspace(5) + %"375" = alloca float, align 4, addrspace(5) + %"376" = alloca float, align 4, addrspace(5) + %"377" = alloca float, align 4, addrspace(5) + %"378" = alloca float, align 4, addrspace(5) + %"379" = alloca float, align 4, addrspace(5) + %"380" = alloca float, align 4, addrspace(5) + %"381" = alloca float, align 4, addrspace(5) + %"382" = alloca float, align 4, addrspace(5) + %"383" = alloca float, align 4, addrspace(5) + %"384" = alloca float, align 4, addrspace(5) + %"385" = alloca float, align 4, addrspace(5) + %"386" = alloca float, align 4, addrspace(5) + %"387" = alloca float, align 4, addrspace(5) + %"388" = alloca float, align 4, addrspace(5) + %"389" = alloca float, align 4, addrspace(5) + %"390" = alloca float, align 4, addrspace(5) + %"391" = alloca float, align 4, addrspace(5) + %"392" = alloca float, align 4, addrspace(5) + %"393" = alloca float, align 4, addrspace(5) + %"394" = alloca i32, align 4, addrspace(5) + %"395" = alloca i32, align 4, addrspace(5) + %"396" = alloca i32, align 4, addrspace(5) + %"397" = alloca i32, align 4, addrspace(5) + %"398" = alloca i32, align 4, addrspace(5) + %"399" = alloca i32, align 4, addrspace(5) + %"400" = alloca i32, align 4, addrspace(5) + store i32 %"455", ptr addrspace(5) %"452", align 4 + %"456" = load i32, ptr addrspace(5) %"452", align 4 + store i32 %"456", ptr addrspace(5) %"738", align 4 + %"760" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"754", i32 16) + %"450" = load <4 x float>, ptr addrspace(1) %"760", align 16 + %"457" = extractelement <4 x float> %"450", i32 0 + %"458" = extractelement <4 x float> %"450", i32 1 + %"459" = extractelement <4 x float> %"450", i32 2 + %"460" = extractelement <4 x float> %"450", i32 3 + store float %"457", ptr addrspace(5) %"335", align 4 + store float %"458", ptr addrspace(5) %"336", align 4 + store float %"459", ptr addrspace(5) %"337", align 4 + store float %"460", ptr addrspace(5) %"338", align 4 + %"461" = load float, ptr addrspace(5) %"750", align 4 + store float %"461", ptr addrspace(5) %"342", align 4 + %"463" = load float, ptr addrspace(5) %"342", align 4 + %"464" = load float, ptr addrspace(5) %"335", align 4 + %"462" = fsub float %"463", %"464" + store float %"462", ptr addrspace(5) %"312", align 4 + %"895" = getelementptr inbounds i8, ptr addrspace(5) %"750", i64 4 + %"465" = load float, ptr addrspace(5) %"895", align 4 + store float %"465", ptr addrspace(5) %"343", align 4 + %"467" = load float, ptr addrspace(5) %"343", align 4 + %"468" = load float, ptr addrspace(5) %"336", align 4 + %"466" = fsub float %"467", %"468" + store float %"466", ptr addrspace(5) %"313", align 4 + %"897" = getelementptr inbounds i8, ptr addrspace(5) %"750", i64 8 + %"469" = load float, ptr addrspace(5) %"897", align 4 + store float %"469", ptr addrspace(5) %"344", align 4 + %"471" = load float, ptr addrspace(5) %"344", align 4 + %"472" = load float, ptr addrspace(5) %"337", align 4 + %"470" = fsub float %"471", %"472" + store float %"470", ptr addrspace(5) %"314", align 4 + %"899" = getelementptr inbounds i8, ptr addrspace(5) %"750", i64 12 + %"473" = load float, ptr addrspace(5) %"899", align 4 + store float %"473", ptr addrspace(5) %"345", align 4 + %"901" = getelementptr inbounds i8, ptr addrspace(5) %"750", i64 16 + %"474" = load float, ptr addrspace(5) %"901", align 4 + store float %"474", ptr addrspace(5) %"346", align 4 + %"476" = load float, ptr addrspace(5) %"346", align 4 + %"477" = load float, ptr addrspace(5) %"346", align 4 + %"475" = fmul float %"476", %"477" + store float %"475", ptr addrspace(5) %"347", align 4 + %"479" = load float, ptr addrspace(5) %"345", align 4 + %"480" = load float, ptr addrspace(5) %"345", align 4 + %"481" = load float, ptr addrspace(5) %"347", align 4 + %"478" = call float @llvm.fma.f32(float %"479", float %"480", float %"481") + store float %"478", ptr addrspace(5) %"348", align 4 + %"903" = getelementptr inbounds i8, ptr addrspace(5) %"750", i64 20 + %"482" = load float, ptr addrspace(5) %"903", align 4 + store float %"482", ptr addrspace(5) %"349", align 4 + %"484" = load float, ptr addrspace(5) %"349", align 4 + %"485" = load float, ptr addrspace(5) %"349", align 4 + %"486" = load float, ptr addrspace(5) %"348", align 4 + %"483" = call float @llvm.fma.f32(float %"484", float %"485", float %"486") + store float %"483", ptr addrspace(5) %"350", align 4 + %"488" = load float, ptr addrspace(5) %"350", align 4 + %0 = call afn float @llvm.sqrt.f32(float %"488") + %"487" = fdiv arcp afn float 1.000000e+00, %0 + store float %"487", ptr addrspace(5) %"315", align 4 + %"490" = load float, ptr addrspace(5) %"345", align 4 + %"491" = load float, ptr addrspace(5) %"315", align 4 + %"489" = fmul float %"490", %"491" + store float %"489", ptr addrspace(5) %"316", align 4 + %"493" = load float, ptr addrspace(5) %"315", align 4 + %"494" = load float, ptr addrspace(5) %"346", align 4 + %"492" = fmul float %"493", %"494" + store float %"492", ptr addrspace(5) %"317", align 4 + %"496" = load float, ptr addrspace(5) %"315", align 4 + %"497" = load float, ptr addrspace(5) %"349", align 4 + %"495" = fmul float %"496", %"497" + store float %"495", ptr addrspace(5) %"318", align 4 + %"499" = load float, ptr addrspace(5) %"313", align 4 + %"500" = load float, ptr addrspace(5) %"317", align 4 + %"498" = fmul float %"499", %"500" + store float %"498", ptr addrspace(5) %"351", align 4 + %"502" = load float, ptr addrspace(5) %"312", align 4 + %"503" = load float, ptr addrspace(5) %"316", align 4 + %"504" = load float, ptr addrspace(5) %"351", align 4 + %"501" = call float @llvm.fma.f32(float %"502", float %"503", float %"504") + store float %"501", ptr addrspace(5) %"352", align 4 + %"506" = load float, ptr addrspace(5) %"314", align 4 + %"507" = load float, ptr addrspace(5) %"318", align 4 + %"508" = load float, ptr addrspace(5) %"352", align 4 + %"505" = call float @llvm.fma.f32(float %"506", float %"507", float %"508") + store float %"505", ptr addrspace(5) %"392", align 4 + %"510" = load float, ptr addrspace(5) %"313", align 4 + %"511" = load float, ptr addrspace(5) %"313", align 4 + %"509" = fmul float %"510", %"511" + store float %"509", ptr addrspace(5) %"353", align 4 + %"513" = load float, ptr addrspace(5) %"312", align 4 + %"514" = load float, ptr addrspace(5) %"312", align 4 + %"515" = load float, ptr addrspace(5) %"353", align 4 + %"512" = call float @llvm.fma.f32(float %"513", float %"514", float %"515") + store float %"512", ptr addrspace(5) %"354", align 4 + %"517" = load float, ptr addrspace(5) %"314", align 4 + %"518" = load float, ptr addrspace(5) %"314", align 4 + %"519" = load float, ptr addrspace(5) %"354", align 4 + %"516" = call float @llvm.fma.f32(float %"517", float %"518", float %"519") + store float %"516", ptr addrspace(5) %"355", align 4 + %"521" = load float, ptr addrspace(5) %"338", align 4 + %"522" = load float, ptr addrspace(5) %"338", align 4 + %"520" = fmul float %"521", %"522" + store float %"520", ptr addrspace(5) %"320", align 4 + %"524" = load float, ptr addrspace(5) %"355", align 4 + %"525" = load float, ptr addrspace(5) %"320", align 4 + %"523" = fsub float %"524", %"525" + store float %"523", ptr addrspace(5) %"356", align 4 + %"527" = load float, ptr addrspace(5) %"392", align 4 + %"528" = load float, ptr addrspace(5) %"392", align 4 + %"526" = fmul float %"527", %"528" + store float %"526", ptr addrspace(5) %"357", align 4 + %"530" = load float, ptr addrspace(5) %"357", align 4 + %"531" = load float, ptr addrspace(5) %"356", align 4 + %"529" = fsub float %"530", %"531" + store float %"529", ptr addrspace(5) %"321", align 4 + %"533" = load float, ptr addrspace(5) %"321", align 4 + %"532" = fcmp ule float %"533", 0.000000e+00 + store i1 %"532", ptr addrspace(5) %"303", align 1 + %1 = alloca float, align 4, addrspace(5) + store float 0.000000e+00, ptr addrspace(5) %1, align 4 + %"534" = load float, ptr addrspace(5) %1, align 4 + store float %"534", ptr addrspace(5) %"393", align 4 + %"535" = load i1, ptr addrspace(5) %"303", align 1 + br i1 %"535", label %"301", label %"402" + +"402": ; preds = %"892" + %"537" = load float, ptr addrspace(5) %"321", align 4 + %"536" = call afn float @llvm.sqrt.f32(float %"537") + store float %"536", ptr addrspace(5) %"391", align 4 + %"539" = load float, ptr addrspace(5) %"392", align 4 + %"538" = fsub float 0.000000e+00, %"539" + store float %"538", ptr addrspace(5) %"359", align 4 + %"541" = load float, ptr addrspace(5) %"359", align 4 + %"542" = load float, ptr addrspace(5) %"391", align 4 + %"540" = fsub float %"541", %"542" + store float %"540", ptr addrspace(5) %"323", align 4 + %"544" = load float, ptr addrspace(5) %"323", align 4 + %"543" = call float @llvm.fabs.f32(float %"544") + store float %"543", ptr addrspace(5) %"324", align 4 + %"546" = load float, ptr addrspace(5) %"338", align 4 + %"545" = fmul float %"546", 1.000000e+01 + store float %"545", ptr addrspace(5) %"325", align 4 + %"548" = load float, ptr addrspace(5) %"324", align 4 + %"549" = load float, ptr addrspace(5) %"325", align 4 + %"547" = fcmp ule float %"548", %"549" + store i1 %"547", ptr addrspace(5) %"304", align 1 + %"550" = load i1, ptr addrspace(5) %"304", align 1 + br i1 %"550", label %"299", label %"404" + +"404": ; preds = %"402" + %"552" = load float, ptr addrspace(5) %"316", align 4 + %"553" = load float, ptr addrspace(5) %"323", align 4 + %"554" = load float, ptr addrspace(5) %"312", align 4 + %"551" = call float @llvm.fma.f32(float %"552", float %"553", float %"554") + store float %"551", ptr addrspace(5) %"361", align 4 + %"556" = load float, ptr addrspace(5) %"317", align 4 + %"557" = load float, ptr addrspace(5) %"323", align 4 + %"558" = load float, ptr addrspace(5) %"313", align 4 + %"555" = call float @llvm.fma.f32(float %"556", float %"557", float %"558") + store float %"555", ptr addrspace(5) %"362", align 4 + %"560" = load float, ptr addrspace(5) %"318", align 4 + %"561" = load float, ptr addrspace(5) %"323", align 4 + %"562" = load float, ptr addrspace(5) %"314", align 4 + %"559" = call float @llvm.fma.f32(float %"560", float %"561", float %"562") + store float %"559", ptr addrspace(5) %"363", align 4 + %"564" = load float, ptr addrspace(5) %"317", align 4 + %"565" = load float, ptr addrspace(5) %"362", align 4 + %"563" = fmul float %"564", %"565" + store float %"563", ptr addrspace(5) %"364", align 4 + %"567" = load float, ptr addrspace(5) %"316", align 4 + %"568" = load float, ptr addrspace(5) %"361", align 4 + %"569" = load float, ptr addrspace(5) %"364", align 4 + %"566" = call float @llvm.fma.f32(float %"567", float %"568", float %"569") + store float %"566", ptr addrspace(5) %"365", align 4 + %"571" = load float, ptr addrspace(5) %"318", align 4 + %"572" = load float, ptr addrspace(5) %"363", align 4 + %"573" = load float, ptr addrspace(5) %"365", align 4 + %"570" = call float @llvm.fma.f32(float %"571", float %"572", float %"573") + store float %"570", ptr addrspace(5) %"392", align 4 + %"575" = load float, ptr addrspace(5) %"362", align 4 + %"576" = load float, ptr addrspace(5) %"362", align 4 + %"574" = fmul float %"575", %"576" + store float %"574", ptr addrspace(5) %"366", align 4 + %"578" = load float, ptr addrspace(5) %"361", align 4 + %"579" = load float, ptr addrspace(5) %"361", align 4 + %"580" = load float, ptr addrspace(5) %"366", align 4 + %"577" = call float @llvm.fma.f32(float %"578", float %"579", float %"580") + store float %"577", ptr addrspace(5) %"367", align 4 + %"582" = load float, ptr addrspace(5) %"363", align 4 + %"583" = load float, ptr addrspace(5) %"363", align 4 + %"584" = load float, ptr addrspace(5) %"367", align 4 + %"581" = call float @llvm.fma.f32(float %"582", float %"583", float %"584") + store float %"581", ptr addrspace(5) %"368", align 4 + %"586" = load float, ptr addrspace(5) %"368", align 4 + %"587" = load float, ptr addrspace(5) %"320", align 4 + %"585" = fsub float %"586", %"587" + store float %"585", ptr addrspace(5) %"369", align 4 + %"589" = load float, ptr addrspace(5) %"392", align 4 + %"590" = load float, ptr addrspace(5) %"392", align 4 + %"588" = fmul float %"589", %"590" + store float %"588", ptr addrspace(5) %"370", align 4 + %"592" = load float, ptr addrspace(5) %"370", align 4 + %"593" = load float, ptr addrspace(5) %"369", align 4 + %"591" = fsub float %"592", %"593" + store float %"591", ptr addrspace(5) %"327", align 4 + %"595" = load float, ptr addrspace(5) %"327", align 4 + %"594" = fcmp ule float %"595", 0.000000e+00 + store i1 %"594", ptr addrspace(5) %"305", align 1 + %"596" = load i1, ptr addrspace(5) %"305", align 1 + br i1 %"596", label %"299", label %"406" + +"406": ; preds = %"404" + %"598" = load float, ptr addrspace(5) %"327", align 4 + %"597" = call afn float @llvm.sqrt.f32(float %"598") + store float %"597", ptr addrspace(5) %"391", align 4 + %"600" = load float, ptr addrspace(5) %"392", align 4 + %"599" = fsub float 0.000000e+00, %"600" + store float %"599", ptr addrspace(5) %"371", align 4 + %"602" = load float, ptr addrspace(5) %"371", align 4 + %"603" = load float, ptr addrspace(5) %"391", align 4 + %"601" = fsub float %"602", %"603" + store float %"601", ptr addrspace(5) %"393", align 4 + br label %"299" + +"299": ; preds = %"406", %"404", %"402" + %"605" = load float, ptr addrspace(5) %"323", align 4 + %"606" = load float, ptr addrspace(5) %"393", align 4 + %"604" = fadd float %"605", %"606" + store float %"604", ptr addrspace(5) %"333", align 4 + %"608" = load float, ptr addrspace(5) %"315", align 4 + %"609" = load float, ptr addrspace(5) %"333", align 4 + %"607" = fmul float %"608", %"609" + store float %"607", ptr addrspace(5) %"372", align 4 + %"611" = load float, ptr addrspace(5) %"372", align 4 + %"610" = call i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float %"611", ptr addrspace(5) %"750", float %"753", ptr addrspace(5) %"863") + store i32 %"610", ptr addrspace(5) %"395", align 4 + %"613" = load i32, ptr addrspace(5) %"395", align 4 + %"612" = icmp eq i32 %"613", 0 + store i1 %"612", ptr addrspace(5) %"306", align 1 + %"614" = load i1, ptr addrspace(5) %"306", align 1 + br i1 %"614", label %"300", label %"408" + +"408": ; preds = %"299" + %"616" = load float, ptr addrspace(5) %"316", align 4 + %"617" = load float, ptr addrspace(5) %"333", align 4 + %"618" = load float, ptr addrspace(5) %"312", align 4 + %"615" = call float @llvm.fma.f32(float %"616", float %"617", float %"618") + store float %"615", ptr addrspace(5) %"373", align 4 + %"620" = load float, ptr addrspace(5) %"317", align 4 + %"621" = load float, ptr addrspace(5) %"333", align 4 + %"622" = load float, ptr addrspace(5) %"313", align 4 + %"619" = call float @llvm.fma.f32(float %"620", float %"621", float %"622") + store float %"619", ptr addrspace(5) %"374", align 4 + %"624" = load float, ptr addrspace(5) %"318", align 4 + %"625" = load float, ptr addrspace(5) %"333", align 4 + %"626" = load float, ptr addrspace(5) %"314", align 4 + %"623" = call float @llvm.fma.f32(float %"624", float %"625", float %"626") + store float %"623", ptr addrspace(5) %"375", align 4 + %"628" = load float, ptr addrspace(5) %"338", align 4 + %"627" = fdiv arcp afn float 1.000000e+00, %"628" + store float %"627", ptr addrspace(5) %"376", align 4 + %"630" = load float, ptr addrspace(5) %"376", align 4 + %"631" = load float, ptr addrspace(5) %"373", align 4 + %"629" = fmul float %"630", %"631" + store float %"629", ptr addrspace(5) %"377", align 4 + %"633" = load float, ptr addrspace(5) %"376", align 4 + %"634" = load float, ptr addrspace(5) %"374", align 4 + %"632" = fmul float %"633", %"634" + store float %"632", ptr addrspace(5) %"378", align 4 + %"636" = load float, ptr addrspace(5) %"376", align 4 + %"637" = load float, ptr addrspace(5) %"375", align 4 + %"635" = fmul float %"636", %"637" + store float %"635", ptr addrspace(5) %"379", align 4 + %"638" = load float, ptr addrspace(5) %"377", align 4 + %"767" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + store float %"638", ptr addrspace(1) %"767", align 4 + %"639" = load float, ptr addrspace(5) %"378", align 4 + %"769" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + %"905" = getelementptr inbounds i8, ptr addrspace(1) %"769", i64 4 + store float %"639", ptr addrspace(1) %"905", align 4 + %"640" = load float, ptr addrspace(5) %"379", align 4 + %"772" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + %"907" = getelementptr inbounds i8, ptr addrspace(1) %"772", i64 8 + store float %"640", ptr addrspace(1) %"907", align 4 + %"641" = load float, ptr addrspace(5) %"377", align 4 + %"775" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + store float %"641", ptr addrspace(1) %"775", align 4 + %"642" = load float, ptr addrspace(5) %"378", align 4 + %"777" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + %"909" = getelementptr inbounds i8, ptr addrspace(1) %"777", i64 4 + store float %"642", ptr addrspace(1) %"909", align 4 + %"643" = load float, ptr addrspace(5) %"379", align 4 + %"780" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + %"911" = getelementptr inbounds i8, ptr addrspace(1) %"780", i64 8 + store float %"643", ptr addrspace(1) %"911", align 4 + %2 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %2, align 4 + %"878" = load i32, ptr addrspace(5) %2, align 4 + store i32 %"878", ptr addrspace(5) %"397", align 4 + %"646" = load i32, ptr addrspace(5) %"397", align 4 + %"645" = call i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32 %"646", ptr addrspace(3) %"747", <2 x i32> %"748", <2 x i32> %"749", ptr addrspace(5) %"750", float %"751", ptr addrspace(5) %"752", ptr addrspace(1) %"754", ptr addrspace(1) %"755", ptr addrspace(1) %"756", ptr addrspace(5) %"757", ptr addrspace(5) %"758", ptr addrspace(5) %"759", ptr addrspace(5) %"863") + store i32 %"645", ptr addrspace(5) %"396", align 4 + %"648" = load i32, ptr addrspace(5) %"396", align 4 + %"647" = icmp ne i32 %"648", 0 + store i1 %"647", ptr addrspace(5) %"307", align 1 + %"649" = load i1, ptr addrspace(5) %"307", align 1 + br i1 %"649", label %"301", label %"410" + +"410": ; preds = %"408" + br label %"300" + +"300": ; preds = %"410", %"299" + %"651" = load float, ptr addrspace(5) %"324", align 4 + %"652" = load float, ptr addrspace(5) %"325", align 4 + %"650" = fcmp ogt float %"651", %"652" + store i1 %"650", ptr addrspace(5) %"308", align 1 + %"654" = load float, ptr addrspace(5) %"323", align 4 + %"655" = load i1, ptr addrspace(5) %"308", align 1 + %"653" = select i1 %"655", float %"654", float 0.000000e+00 + store float %"653", ptr addrspace(5) %"381", align 4 + %"657" = load float, ptr addrspace(5) %"391", align 4 + %"658" = load float, ptr addrspace(5) %"392", align 4 + %"656" = fsub float %"657", %"658" + store float %"656", ptr addrspace(5) %"382", align 4 + %"660" = load float, ptr addrspace(5) %"381", align 4 + %"661" = load float, ptr addrspace(5) %"382", align 4 + %"659" = fadd float %"660", %"661" + store float %"659", ptr addrspace(5) %"334", align 4 + %"663" = load float, ptr addrspace(5) %"315", align 4 + %"664" = load float, ptr addrspace(5) %"334", align 4 + %"662" = fmul float %"663", %"664" + store float %"662", ptr addrspace(5) %"380", align 4 + %"666" = load float, ptr addrspace(5) %"380", align 4 + %"665" = call i32 @__zluda_rt_ptx_impl___rt_potential_intersection(float %"666", ptr addrspace(5) %"750", float %"753", ptr addrspace(5) %"863") + store i32 %"665", ptr addrspace(5) %"398", align 4 + %"668" = load i32, ptr addrspace(5) %"398", align 4 + %"667" = icmp eq i32 %"668", 0 + store i1 %"667", ptr addrspace(5) %"309", align 1 + %"669" = load i1, ptr addrspace(5) %"309", align 1 + br i1 %"669", label %"301", label %"412" + +"412": ; preds = %"300" + %"671" = load float, ptr addrspace(5) %"316", align 4 + %"672" = load float, ptr addrspace(5) %"334", align 4 + %"673" = load float, ptr addrspace(5) %"312", align 4 + %"670" = call float @llvm.fma.f32(float %"671", float %"672", float %"673") + store float %"670", ptr addrspace(5) %"383", align 4 + %"675" = load float, ptr addrspace(5) %"317", align 4 + %"676" = load float, ptr addrspace(5) %"334", align 4 + %"677" = load float, ptr addrspace(5) %"313", align 4 + %"674" = call float @llvm.fma.f32(float %"675", float %"676", float %"677") + store float %"674", ptr addrspace(5) %"384", align 4 + %"679" = load float, ptr addrspace(5) %"318", align 4 + %"680" = load float, ptr addrspace(5) %"334", align 4 + %"681" = load float, ptr addrspace(5) %"314", align 4 + %"678" = call float @llvm.fma.f32(float %"679", float %"680", float %"681") + store float %"678", ptr addrspace(5) %"385", align 4 + %"683" = load float, ptr addrspace(5) %"338", align 4 + %"682" = fdiv arcp afn float 1.000000e+00, %"683" + store float %"682", ptr addrspace(5) %"386", align 4 + %"685" = load float, ptr addrspace(5) %"386", align 4 + %"686" = load float, ptr addrspace(5) %"383", align 4 + %"684" = fmul float %"685", %"686" + store float %"684", ptr addrspace(5) %"387", align 4 + %"688" = load float, ptr addrspace(5) %"386", align 4 + %"689" = load float, ptr addrspace(5) %"384", align 4 + %"687" = fmul float %"688", %"689" + store float %"687", ptr addrspace(5) %"388", align 4 + %"691" = load float, ptr addrspace(5) %"386", align 4 + %"692" = load float, ptr addrspace(5) %"385", align 4 + %"690" = fmul float %"691", %"692" + store float %"690", ptr addrspace(5) %"389", align 4 + %"693" = load float, ptr addrspace(5) %"387", align 4 + %"783" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + store float %"693", ptr addrspace(1) %"783", align 4 + %"694" = load float, ptr addrspace(5) %"388", align 4 + %"785" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + %"913" = getelementptr inbounds i8, ptr addrspace(1) %"785", i64 4 + store float %"694", ptr addrspace(1) %"913", align 4 + %"695" = load float, ptr addrspace(5) %"389", align 4 + %"788" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 12) + %"915" = getelementptr inbounds i8, ptr addrspace(1) %"788", i64 8 + store float %"695", ptr addrspace(1) %"915", align 4 + %"696" = load float, ptr addrspace(5) %"387", align 4 + %"791" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + store float %"696", ptr addrspace(1) %"791", align 4 + %"697" = load float, ptr addrspace(5) %"388", align 4 + %"793" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + %"917" = getelementptr inbounds i8, ptr addrspace(1) %"793", i64 4 + store float %"697", ptr addrspace(1) %"917", align 4 + %"698" = load float, ptr addrspace(5) %"389", align 4 + %"796" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"755", i32 0) + %"919" = getelementptr inbounds i8, ptr addrspace(1) %"796", i64 8 + store float %"698", ptr addrspace(1) %"919", align 4 + %3 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %3, align 4 + %"887" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"887", ptr addrspace(5) %"400", align 4 + %"701" = load i32, ptr addrspace(5) %"400", align 4 + %"700" = call i32 @__zluda_rt_ptx_impl___rt_report_intersection(i32 %"701", ptr addrspace(3) %"747", <2 x i32> %"748", <2 x i32> %"749", ptr addrspace(5) %"750", float %"751", ptr addrspace(5) %"752", ptr addrspace(1) %"754", ptr addrspace(1) %"755", ptr addrspace(1) %"756", ptr addrspace(5) %"757", ptr addrspace(5) %"758", ptr addrspace(5) %"759", ptr addrspace(5) %"863") + store i32 %"700", ptr addrspace(5) %"399", align 4 + br label %"301" + +"301": ; preds = %"412", %"300", %"408", %"892" + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sqrt.f32(float) #2 + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fabs.f32(float) #2 + +define protected void @__zluda_rt_ptx_impl__rollback_wrapper(i32 %"802", ptr addrspace(3) %"803", <2 x i32> %"804", <2 x i32> %"805", ptr addrspace(5) %"806", float %"807", ptr addrspace(5) %"808", float %"809", ptr addrspace(1) %"810", ptr addrspace(1) %"811", ptr addrspace(1) %"812", ptr addrspace(5) %"813", ptr addrspace(5) %"814", ptr addrspace(5) %"815") #3 { +"893": + %"816" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"811", i32 0) + %"818" = load [12 x i8], ptr addrspace(1) %"816", align 1 + %"819" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"811", i32 12) + %"821" = load [12 x i8], ptr addrspace(1) %"819", align 1 + call void @_Z16robust_intersecti(i32 %"802", ptr addrspace(3) %"803", <2 x i32> %"804", <2 x i32> %"805", ptr addrspace(5) %"806", float %"807", ptr addrspace(5) %"808", float %"809", ptr addrspace(1) %"810", ptr addrspace(1) %"811", ptr addrspace(1) %"812", ptr addrspace(5) %"813", ptr addrspace(5) %"814", ptr addrspace(5) %"815") + %"823" = load i32, ptr addrspace(5) %"814", align 4 + %"826" = icmp eq i32 %"823", 2 + br i1 %"826", label %"827", label %"824" + +"827": ; preds = %"893" + %"828" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"811", i32 0) + store [12 x i8] %"818", ptr addrspace(1) %"828", align 1 + %"830" = call ptr addrspace(1) @__zluda_rt_ptx_impl__get_variable_pointer_global(ptr addrspace(1) %"811", i32 12) + store [12 x i8] %"821", ptr addrspace(1) %"830", align 1 + br label %"824" + +"824": ; preds = %"827", %"893" + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #2 = { nocallback nofree nosync nounwind readnone speculatable willreturn } +attributes #3 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/raytracing.rs b/ptx/src/test/raytracing.rs new file mode 100644 index 0000000..d6d821b --- /dev/null +++ b/ptx/src/test/raytracing.rs @@ -0,0 +1,144 @@ +use crate::{llvm, translate, ModuleParser}; +use hip_common::raytracing::VariablesBlock; +use hip_runtime_sys::*; +use hiprt_sys::*; +use lazy_static::lazy_static; +use paste::paste; +use std::ffi::c_void; +use std::fs; +use std::path::PathBuf; +use std::sync::Mutex; +use std::{env, ptr}; +use zluda_llvm::bit_writer::*; + +macro_rules! test_raytracing { + ($file:ident, $fn_name:ident) => { + paste! { + #[test] + #[allow(non_snake_case)] + fn [<$file _ $fn_name>] () { + let ptx = include_str!(concat!("ptx_raytracing/", stringify!($file), ".ptx")); + let llvm_file_name = concat!("ptx_raytracing/", stringify!([<$file _ $fn_name>]), ".ll"); + let bitcode = include_bytes!(concat!("ptx_raytracing/", stringify!([<$file _ $fn_name>]), ".ll")); + let fn_name = stringify!($fn_name); + unsafe { test(ptx, bitcode, llvm_file_name, fn_name) } + } + } + }; +} + +// HIP-RT is not thread safe +lazy_static! { + static ref HIPRT_MUTEX: Mutex = Mutex::new(unsafe { HipRt::load() }.unwrap()); +} + +unsafe fn test(ptx_txt: &str, llvm_ir: &[u8], llvm_file_name: &str, fn_name: &str) { + let mut errors = Vec::new(); + let ast = ModuleParser::new().parse(&mut errors, ptx_txt).unwrap(); + assert!(errors.len() == 0); + let mut empty_attribute_variables = VariablesBlock::empty(); + let raytracing_module = + translate::to_llvm_module_for_raytracing(ast, fn_name, &mut empty_attribute_variables) + .unwrap(); + let llvm_bitcode_from_ptx = raytracing_module.compilation_module.get_bitcode_main(); + let mut llvm_ir_copy = llvm_ir.to_vec(); + llvm_ir_copy.push(0); + let reference_llvm_ir_buffer = llvm::MemoryBuffer::create_no_copy(&*llvm_ir_copy, true); + let reference_module = llvm::parse_ir_in_context( + &raytracing_module.compilation_module._llvm_context, + reference_llvm_ir_buffer, + ) + .unwrap(); + let reference_llvm_bitcode_buffer = + llvm::MemoryBuffer::from_ffi(LLVMWriteBitcodeToMemoryBuffer(reference_module.get())); + if reference_llvm_bitcode_buffer.as_slice() != llvm_bitcode_from_ptx.as_slice() { + let ptx_string = raytracing_module.compilation_module.get_llvm_text(); + if ptx_string.as_cstr().to_bytes() != llvm_ir { + if let Ok(dump_path) = env::var("ZLUDA_TEST_LLVM_DUMP_DIR") { + let mut path = PathBuf::from(dump_path); + path.push(llvm_file_name); + if let Ok(()) = fs::create_dir_all(path.parent().unwrap()) { + fs::write(path, &*ptx_string.as_cstr().to_string_lossy()).ok(); + } + } + panic!("{}", ptx_string); + } + } + assert_eq!(hipInit(0), hipError_t(0)); + let mut hip_context = ptr::null_mut(); + assert_eq!(hipCtxCreate(&mut hip_context, 0, 0), hipError_t(0)); + let mut context_input = hiprtContextCreationInput { + ctxt: hip_context as _, + device: 0, + deviceType: hiprtDeviceType::hiprtDeviceAMD, + }; + let mut context = ptr::null_mut(); + let hiprt = HIPRT_MUTEX.lock().unwrap(); + assert!( + hiprt.hiprtCreateContext( + hiprt_sys::HIPRT_API_VERSION, + &mut context_input, + &mut context + ) == hiprtError(0) + ); + let debug_level = if cfg!(debug_assertions) { + b"-g\0".as_ptr() + } else { + b"-g0\0".as_ptr() + }; + let options = [ + debug_level, + // We just want to emit LLVM, we'd use O0, but somehow IR emitted by O0 prevents inling. + // Weirdly, -disable-llvm-optzns produces much bigger code + b"-O1\0".as_ptr(), + // Stop compilation at LLVM + b"-fgpu-rdc\0".as_ptr(), + // hiprtc injects -mcumode which we don't want + b"-mno-cumode\0".as_ptr(), + // Internalization makes so that _rt_trace_time_mask_flags_64 is module-private + // and does not get linked with the code generated by ptx compiler + b"-mllvm\0".as_ptr(), + b"-amdgpu-internalize-symbols=0\0".as_ptr(), + ]; + let mut rt_program = ptr::null_mut::(); + let headers = raytracing_module + .headers + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + let header_names = raytracing_module + .header_names + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + assert!( + hiprt.hiprtBuildTraceProgram( + context, + translate::RaytracingModule::KERNEL_NAME.as_ptr(), + raytracing_module.kernel_source.as_ptr() as _, + "zluda_rt_kernel\0".as_ptr() as _, + headers.len() as i32, + headers.as_ptr() as _, + header_names.as_ptr() as _, + options.as_ptr() as _, + options.len() as i32, + (&mut rt_program) as *mut _ as _, + ) == hiprtError(0) + ); + // It would be intresting to compile into a relocatable to check for + // fn declaration implementation mismatch between C++ wrapper and emitted + // bitcode, but unfortunately in case of mismatches LLVM linker just + // bitcasts incompatible function (which makes sense to a certain degree) +} + +test_raytracing!(optixHello_generated_draw_color, draw_solid_color); +test_raytracing!( + optixHello_generated_draw_color_var_ptr_cast, + draw_solid_color +); +test_raytracing!(optixSphere_generated_sphere, bounds); +test_raytracing!(optixSphere_generated_sphere, robust_intersect); +test_raytracing!(optixSphere_generated_normal_shader, closest_hit_radiance); +test_raytracing!(optixPathTracer_generated_disney, Eval); +test_raytracing!(optixCallablePrograms_generated_optixCallablePrograms, miss); +test_raytracing!(optixPathTracer_generated_hit_program, closest_hit); diff --git a/ptx/src/test/spirv_run/abs.ll b/ptx/src/test/spirv_run/abs.ll new file mode 100644 index 0000000..c698e66 --- /dev/null +++ b/ptx/src/test/spirv_run/abs.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @abs(ptr addrspace(4) byref(i64) %"28", ptr addrspace(4) byref(i64) %"29") #0 { +"38": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"13" to ptr + %"30" = load i32, ptr %"31", align 4 + store i32 %"30", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"15" to ptr + %"40" = getelementptr inbounds i8, ptr %"32", i64 4 + %"33" = load i32, ptr %"40", align 4 + store i32 %"33", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"16" = call i32 @llvm.abs.i32(i32 %"17", i1 false) + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i32, ptr addrspace(5) %"7", align 4 + %"18" = call i32 @llvm.abs.i32(i32 %"19", i1 false) + store i32 %"18", ptr addrspace(5) %"7", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i32, ptr addrspace(5) %"6", align 4 + %"34" = inttoptr i64 %"20" to ptr + store i32 %"21", ptr %"34", align 4 + %"22" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = load i32, ptr addrspace(5) %"7", align 4 + %"36" = inttoptr i64 %"22" to ptr + %"42" = getelementptr inbounds i8, ptr %"36", i64 4 + store i32 %"23", ptr %"42", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.abs.i32(i32, i1 immarg) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/abs.ptx b/ptx/src/test/spirv_run/abs.ptx new file mode 100644 index 0000000..61ecb10 --- /dev/null +++ b/ptx/src/test/spirv_run/abs.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry abs( + .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.b32 temp1, [in_addr]; + ld.b32 temp2, [in_addr+4]; + abs.s32 temp1, temp1; + abs.s32 temp2, temp2; + st.b32 [out_addr], temp1; + st.b32 [out_addr+4], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/activemask.ll b/ptx/src/test/spirv_run/activemask.ll new file mode 100644 index 0000000..4e53429 --- /dev/null +++ b/ptx/src/test/spirv_run/activemask.ll @@ -0,0 +1,26 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__activemask() #0 + +define protected amdgpu_kernel void @activemask(ptr addrspace(4) byref(i64) %"12", ptr addrspace(4) byref(i64) %"13") #1 { +"16": + %"6" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"6", align 1 + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i32, align 4, addrspace(5) + %"8" = load i64, ptr addrspace(4) %"13", align 8 + store i64 %"8", ptr addrspace(5) %"4", align 8 + %"9" = call i32 @__zluda_ptx_impl__activemask() + store i32 %"9", ptr addrspace(5) %"5", align 4 + %"10" = load i64, ptr addrspace(5) %"4", align 8 + %"11" = load i32, ptr addrspace(5) %"5", align 4 + %"14" = inttoptr i64 %"10" to ptr + store i32 %"11", ptr %"14", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/activemask.ptx b/ptx/src/test/spirv_run/activemask.ptx new file mode 100644 index 0000000..c352bb2 --- /dev/null +++ b/ptx/src/test/spirv_run/activemask.ptx @@ -0,0 +1,18 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry activemask( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .b32 temp; + + ld.param.u64 out_addr, [output]; + + activemask.b32 temp; + st.u32 [out_addr], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/add.ll b/ptx/src/test/spirv_run/add.ll new file mode 100644 index 0000000..3b11a73 --- /dev/null +++ b/ptx/src/test/spirv_run/add.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @add(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = add i64 %"15", 1 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/add.ptx b/ptx/src/test/spirv_run/add.ptx index 6762eae..c2db603 100644 --- a/ptx/src/test/spirv_run/add.ptx +++ b/ptx/src/test/spirv_run/add.ptx @@ -2,7 +2,7 @@ .target sm_30 .address_size 64 -.visible .entry add( +.entry add( .param .u64 input, .param .u64 output ) diff --git a/ptx/src/test/spirv_run/add.spvtxt b/ptx/src/test/spirv_run/add.spvtxt deleted file mode 100644 index b468693..0000000 --- a/ptx/src/test/spirv_run/add.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/add_global.ll b/ptx/src/test/spirv_run/add_global.ll new file mode 100644 index 0000000..14ae1f9 --- /dev/null +++ b/ptx/src/test/spirv_run/add_global.ll @@ -0,0 +1,37 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@PI = protected addrspace(1) externally_initialized global float 0x400921FB60000000, align 4 + +define protected amdgpu_kernel void @add_global(ptr addrspace(4) byref(i64) %"21", ptr addrspace(4) byref(i64) %"22") #0 { +"25": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"21", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(4) %"22", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = inttoptr i64 %"14" to ptr + %"13" = load float, ptr %"23", align 4 + store float %"13", ptr addrspace(5) %"7", align 4 + %"15" = load float, ptr addrspace(1) @PI, align 4 + store float %"15", ptr addrspace(5) %"8", align 4 + %"17" = load float, ptr addrspace(5) %"7", align 4 + %"18" = load float, ptr addrspace(5) %"8", align 4 + %"16" = fadd float %"17", %"18" + store float %"16", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"6", align 8 + %"20" = load float, ptr addrspace(5) %"7", align 4 + %"24" = inttoptr i64 %"19" to ptr + store float %"20", ptr %"24", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/add_global.ptx b/ptx/src/test/spirv_run/add_global.ptx new file mode 100644 index 0000000..e0c7672 --- /dev/null +++ b/ptx/src/test/spirv_run/add_global.ptx @@ -0,0 +1,26 @@ +.version 6.5 +.target sm_30 +.address_size 64 + + +.global .align 4 .f32 PI = 0f40490FDB; + +.visible .entry add_global( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 temp; + .reg .f32 pi; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.f32 temp, [in_addr]; + ld.global.f32 pi, [PI]; + add.f32 temp, temp, pi; + st.f32 [out_addr], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/add_non_coherent.ll b/ptx/src/test/spirv_run/add_non_coherent.ll new file mode 100644 index 0000000..7cf364c --- /dev/null +++ b/ptx/src/test/spirv_run/add_non_coherent.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @add_non_coherent(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr addrspace(1) + %"12" = load i64, ptr addrspace(1) %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = add i64 %"15", 1 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr addrspace(1) + store i64 %"17", ptr addrspace(1) %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/add_non_coherent.ptx b/ptx/src/test/spirv_run/add_non_coherent.ptx new file mode 100644 index 0000000..c35c123 --- /dev/null +++ b/ptx/src/test/spirv_run/add_non_coherent.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_32 +.address_size 64 + +.visible .entry add_non_coherent( + .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.global.nc.u64 temp, [in_addr]; + add.u64 temp2, temp, 1; + st.global.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/add_param_ptr.ll b/ptx/src/test/spirv_run/add_param_ptr.ll new file mode 100644 index 0000000..9d90b23 --- /dev/null +++ b/ptx/src/test/spirv_run/add_param_ptr.ll @@ -0,0 +1,48 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @add_param_ptr(ptr addrspace(4) byref(i64) %"27", ptr addrspace(4) byref(i64) %"28") #0 { +"39": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"32" = ptrtoint ptr addrspace(4) %"27" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"32", ptr addrspace(5) %0, align 8 + %"31" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"31", ptr addrspace(5) %"4", align 8 + %"34" = ptrtoint ptr addrspace(4) %"28" to i64 + %1 = alloca i64, align 8, addrspace(5) + store i64 %"34", ptr addrspace(5) %1, align 8 + %"33" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"33", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"35" = inttoptr i64 %"13" to ptr addrspace(4) + %"41" = getelementptr inbounds i8, ptr addrspace(4) %"35", i64 0 + %"12" = load i64, ptr addrspace(4) %"41", align 8 + store i64 %"12", ptr addrspace(5) %"4", align 8 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"36" = inttoptr i64 %"15" to ptr addrspace(4) + %"43" = getelementptr inbounds i8, ptr addrspace(4) %"36", i64 0 + %"14" = load i64, ptr addrspace(4) %"43", align 8 + store i64 %"14", ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"17" to ptr + %"16" = load i64, ptr %"37", align 8 + store i64 %"16", ptr addrspace(5) %"6", align 8 + %"19" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = add i64 %"19", 1 + store i64 %"18", ptr addrspace(5) %"7", align 8 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i64, ptr addrspace(5) %"7", align 8 + %"38" = inttoptr i64 %"20" to ptr + store i64 %"21", ptr %"38", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/add_param_ptr.ptx b/ptx/src/test/spirv_run/add_param_ptr.ptx new file mode 100644 index 0000000..3717165 --- /dev/null +++ b/ptx/src/test/spirv_run/add_param_ptr.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.entry add_param_ptr( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + + mov.b64 in_addr, input; + mov.b64 out_addr, output; + + ld.param.u64 in_addr, [in_addr+0]; + ld.param.u64 out_addr, [out_addr+0]; + + 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_tuning.ll b/ptx/src/test/spirv_run/add_tuning.ll new file mode 100644 index 0000000..1f36397 --- /dev/null +++ b/ptx/src/test/spirv_run/add_tuning.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @add_tuning(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = add i64 %"15", 1 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-flat-work-group-size"="1,256" "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/add_tuning.ptx b/ptx/src/test/spirv_run/add_tuning.ptx new file mode 100644 index 0000000..2a5dcf8 --- /dev/null +++ b/ptx/src/test/spirv_run/add_tuning.ptx @@ -0,0 +1,24 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry add_tuning( + .param .u64 input, + .param .u64 output +) +.maxntid 256, 1, 1 +.minnctapersm 4 +{ + .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/addc_cc.ll b/ptx/src/test/spirv_run/addc_cc.ll new file mode 100644 index 0000000..9015a80 --- /dev/null +++ b/ptx/src/test/spirv_run/addc_cc.ll @@ -0,0 +1,90 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @addc_cc(ptr addrspace(4) byref(i64) %"54", ptr addrspace(4) byref(i64) %"55") #0 { +"69": + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"12" = alloca i32, align 4, addrspace(5) + %"15" = load i64, ptr addrspace(4) %"54", align 8 + store i64 %"15", ptr addrspace(5) %"4", align 8 + %"16" = load i64, ptr addrspace(4) %"55", align 8 + store i64 %"16", ptr addrspace(5) %"5", align 8 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"57" = inttoptr i64 %"18" to ptr + %"56" = load i32, ptr %"57", align 4 + store i32 %"56", ptr addrspace(5) %"9", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"58" = inttoptr i64 %"20" to ptr + %"71" = getelementptr inbounds i8, ptr %"58", i64 4 + %"59" = load i32, ptr %"71", align 4 + store i32 %"59", ptr addrspace(5) %"10", align 4 + %"22" = load i64, ptr addrspace(5) %"4", align 8 + %"60" = inttoptr i64 %"22" to ptr + %"73" = getelementptr inbounds i8, ptr %"60", i64 8 + %"21" = load i32, ptr %"73", align 4 + store i32 %"21", ptr addrspace(5) %"11", align 4 + %"24" = load i64, ptr addrspace(5) %"4", align 8 + %"61" = inttoptr i64 %"24" to ptr + %"75" = getelementptr inbounds i8, ptr %"61", i64 12 + %"23" = load i32, ptr %"75", align 4 + store i32 %"23", ptr addrspace(5) %"12", align 4 + %"27" = load i32, ptr addrspace(5) %"9", align 4 + %"28" = load i32, ptr addrspace(5) %"10", align 4 + %0 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %"27", i32 %"28") + %"25" = extractvalue { i32, i1 } %0, 0 + %"26" = extractvalue { i32, i1 } %0, 1 + store i32 %"25", ptr addrspace(5) %"6", align 4 + store i1 %"26", ptr addrspace(5) %"13", align 1 + %"31" = load i1, ptr addrspace(5) %"13", align 1 + %"32" = load i32, ptr addrspace(5) %"6", align 4 + %"33" = load i32, ptr addrspace(5) %"11", align 4 + %1 = zext i1 %"31" to i32 + %2 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %"32", i32 %"33") + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %5 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %3, i32 %1) + %"29" = extractvalue { i32, i1 } %5, 0 + %6 = extractvalue { i32, i1 } %5, 1 + %"30" = xor i1 %4, %6 + store i32 %"29", ptr addrspace(5) %"7", align 4 + store i1 %"30", ptr addrspace(5) %"13", align 1 + %"35" = load i1, ptr addrspace(5) %"13", align 1 + %"36" = load i32, ptr addrspace(5) %"7", align 4 + %"37" = load i32, ptr addrspace(5) %"12", align 4 + %7 = zext i1 %"35" to i32 + %8 = add i32 %"36", %"37" + %"34" = add i32 %8, %7 + store i32 %"34", ptr addrspace(5) %"8", align 4 + %"38" = load i64, ptr addrspace(5) %"5", align 8 + %"39" = load i32, ptr addrspace(5) %"6", align 4 + %"66" = inttoptr i64 %"38" to ptr + store i32 %"39", ptr %"66", align 4 + %"40" = load i64, ptr addrspace(5) %"5", align 8 + %"41" = load i32, ptr addrspace(5) %"7", align 4 + %"67" = inttoptr i64 %"40" to ptr + %"77" = getelementptr inbounds i8, ptr %"67", i64 4 + store i32 %"41", ptr %"77", align 4 + %"42" = load i64, ptr addrspace(5) %"5", align 8 + %"43" = load i32, ptr addrspace(5) %"8", align 4 + %"68" = inttoptr i64 %"42" to ptr + %"79" = getelementptr inbounds i8, ptr %"68", i64 8 + store i32 %"43", ptr %"79", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/addc_cc.ptx b/ptx/src/test/spirv_run/addc_cc.ptx new file mode 100644 index 0000000..50a1902 --- /dev/null +++ b/ptx/src/test/spirv_run/addc_cc.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry addc_cc( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .s32 dst1; + .reg .s32 dst2; + .reg .s32 dst3; + .reg .b32 src1; + .reg .b32 src2; + .reg .b32 src3; + .reg .b32 src4; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.s32 src1, [in_addr]; + ld.s32 src2, [in_addr+4]; + ld.b32 src3, [in_addr+8]; + ld.b32 src4, [in_addr+12]; + add.cc.s32 dst1, src1, src2; + addc.cc.s32 dst2, dst1, src3; + addc.s32 dst3, dst2, src4; + st.s32 [out_addr], dst1; + st.s32 [out_addr+4], dst2; + st.s32 [out_addr+8], dst3; + ret; +} diff --git a/ptx/src/test/spirv_run/addc_cc2.ll b/ptx/src/test/spirv_run/addc_cc2.ll new file mode 100644 index 0000000..982be96 --- /dev/null +++ b/ptx/src/test/spirv_run/addc_cc2.ll @@ -0,0 +1,68 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @addc_cc2(ptr addrspace(4) byref(i64) %"40", ptr addrspace(4) byref(i64) %"41") #0 { +"51": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"41", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %0 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 -1, i32 -1) + %"42" = extractvalue { i32, i1 } %0, 0 + %"13" = extractvalue { i32, i1 } %0, 1 + store i32 %"42", ptr addrspace(5) %"6", align 4 + store i1 %"13", ptr addrspace(5) %"9", align 1 + %"16" = load i1, ptr addrspace(5) %"9", align 1 + %1 = zext i1 %"16" to i32 + %2 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 -4, i32 -4) + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %5 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %3, i32 %1) + %"43" = extractvalue { i32, i1 } %5, 0 + %6 = extractvalue { i32, i1 } %5, 1 + %"15" = xor i1 %4, %6 + store i32 %"43", ptr addrspace(5) %"6", align 4 + store i1 %"15", ptr addrspace(5) %"9", align 1 + %"18" = load i1, ptr addrspace(5) %"9", align 1 + %7 = zext i1 %"18" to i32 + %"44" = add i32 0, %7 + store i32 %"44", ptr addrspace(5) %"7", align 4 + %"21" = load i1, ptr addrspace(5) %"9", align 1 + %8 = zext i1 %"21" to i32 + %9 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 0, i32 -1) + %10 = extractvalue { i32, i1 } %9, 0 + %11 = extractvalue { i32, i1 } %9, 1 + %12 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %10, i32 %8) + %"45" = extractvalue { i32, i1 } %12, 0 + %13 = extractvalue { i32, i1 } %12, 1 + %"20" = xor i1 %11, %13 + store i32 %"45", ptr addrspace(5) %"6", align 4 + store i1 %"20", ptr addrspace(5) %"9", align 1 + %"23" = load i1, ptr addrspace(5) %"9", align 1 + %14 = zext i1 %"23" to i32 + %"46" = add i32 0, %14 + store i32 %"46", ptr addrspace(5) %"8", align 4 + %"24" = load i64, ptr addrspace(5) %"5", align 8 + %"25" = load i32, ptr addrspace(5) %"7", align 4 + %"47" = inttoptr i64 %"24" to ptr + store i32 %"25", ptr %"47", align 4 + %"26" = load i64, ptr addrspace(5) %"5", align 8 + %"27" = load i32, ptr addrspace(5) %"8", align 4 + %"49" = inttoptr i64 %"26" to ptr + %"53" = getelementptr inbounds i8, ptr %"49", i64 4 + store i32 %"27", ptr %"53", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/addc_cc2.ptx b/ptx/src/test/spirv_run/addc_cc2.ptx new file mode 100644 index 0000000..88860a8 --- /dev/null +++ b/ptx/src/test/spirv_run/addc_cc2.ptx @@ -0,0 +1,33 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry addc_cc2( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 unused; + + .reg .b32 carry_out_1; + .reg .b32 carry_out_2; + + ld.param.u64 out_addr, [output]; + + // set CC.CF + add.cc.s32 unused, 4294967295, 4294967295; + // overflow when doing a + b, but not CC.CF + addc.cc.s32 unused, 4294967292, 4294967292; + // write carry + addc.s32 carry_out_1, 0, 0; + // overflow when doing b + CC.CF, but not a + addc.cc.s32 unused, 0, 4294967295; + // write carry + addc.s32 carry_out_2, 0, 0; + + st.s32 [out_addr], carry_out_1; + st.s32 [out_addr+4], carry_out_2; + ret; +} diff --git a/ptx/src/test/spirv_run/alloca_call.ll b/ptx/src/test/spirv_run/alloca_call.ll new file mode 100644 index 0000000..1ae760b --- /dev/null +++ b/ptx/src/test/spirv_run/alloca_call.ll @@ -0,0 +1,61 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @_Z13callback_onlyIdEvPvS0_10callback_tx(ptr addrspace(4) byref(i64) %"43", ptr addrspace(4) byref(i64) %"44", ptr addrspace(4) byref(i64) %"45", ptr addrspace(4) byref(i64) %"46") #0 { +"59": + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"23" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"23", align 1 + %"7" = alloca i1, align 1, addrspace(5) + %"8" = alloca double, align 8, addrspace(5) + %"9" = alloca double, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"11" = alloca i64, align 8, addrspace(5) + %"12" = alloca i64, align 8, addrspace(5) + %"13" = alloca i64, align 8, addrspace(5) + %"47" = alloca i64, align 8, addrspace(5) + %"49" = alloca [4 x i32], align 16, addrspace(5) + %"51" = load i64, ptr addrspace(4) %"43", align 8 + store i64 %"51", ptr addrspace(5) %"10", align 8 + %"52" = load i64, ptr addrspace(4) %"44", align 8 + store i64 %"52", ptr addrspace(5) %"11", align 8 + %"53" = load i64, ptr addrspace(4) %"45", align 8 + store i64 %"53", ptr addrspace(5) %"12", align 8 + %"54" = load i64, ptr addrspace(4) %"46", align 8 + store i64 %"54", ptr addrspace(5) %"13", align 8 + %"29" = load i64, ptr addrspace(5) %"12", align 8 + %"30" = load i64, ptr addrspace(5) %"13", align 8 + %"28" = icmp sge i64 %"29", %"30" + store i1 %"28", ptr addrspace(5) %"7", align 1 + %"31" = load i1, ptr addrspace(5) %"7", align 1 + br i1 %"31", label %"6", label %"18" + +"18": ; preds = %"59" + %"32" = load i64, ptr addrspace(5) %"11", align 8 + %"61" = getelementptr inbounds i8, ptr addrspace(5) %"47", i64 0 + store i64 %"32", ptr addrspace(5) %"61", align 8 + %"33" = load i64, ptr addrspace(5) %"11", align 8 + %0 = inttoptr i64 %"33" to ptr + %"21" = call [4 x i32] %0() + store [4 x i32] %"21", ptr addrspace(5) %"49", align 4 + %"63" = getelementptr inbounds i8, ptr addrspace(5) %"49", i64 0 + %"19" = load <2 x double>, ptr addrspace(5) %"63", align 16 + %"34" = extractelement <2 x double> %"19", i32 0 + %"35" = extractelement <2 x double> %"19", i32 1 + store double %"34", ptr addrspace(5) %"8", align 8 + store double %"35", ptr addrspace(5) %"9", align 8 + %"36" = load double, ptr addrspace(5) %"8", align 8 + %"37" = load double, ptr addrspace(5) %"9", align 8 + %1 = insertelement <2 x double> undef, double %"36", i32 0 + %"20" = insertelement <2 x double> %1, double %"37", i32 1 + %"38" = load i64, ptr addrspace(5) %"10", align 8 + %"58" = inttoptr i64 %"38" to ptr addrspace(1) + store <2 x double> %"20", ptr addrspace(1) %"58", align 16 + br label %"6" + +"6": ; preds = %"18", %"59" + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/alloca_call.ptx b/ptx/src/test/spirv_run/alloca_call.ptx new file mode 100644 index 0000000..3ab426b --- /dev/null +++ b/ptx/src/test/spirv_run/alloca_call.ptx @@ -0,0 +1,43 @@ +.version 7.8 +.target sm_50 +.address_size 64 + +.visible .entry _Z13callback_onlyIdEvPvS0_10callback_tx( +.param .u64 _Z13callback_onlyIdEvPvS0_10callback_tx_param_0, +.param .u64 _Z13callback_onlyIdEvPvS0_10callback_tx_param_1, +.param .u64 _Z13callback_onlyIdEvPvS0_10callback_tx_param_2, +.param .u64 _Z13callback_onlyIdEvPvS0_10callback_tx_param_3 +) +{ +.reg .pred early_exit; +.reg .f64 %fd<2>; + + +.reg .b64 result_ptr; +.reg .b64 func_ptr; +.reg .b64 x; +.reg .b64 y; + + +ld.param.u64 result_ptr, [_Z13callback_onlyIdEvPvS0_10callback_tx_param_0]; +ld.param.u64 func_ptr, [_Z13callback_onlyIdEvPvS0_10callback_tx_param_1]; +ld.param.u64 x, [_Z13callback_onlyIdEvPvS0_10callback_tx_param_2]; +ld.param.u64 y, [_Z13callback_onlyIdEvPvS0_10callback_tx_param_3]; +setp.ge.s64 early_exit, x, y; +@early_exit bra $L__BB1_2; + +{ + .param .b64 param0; + st.param.b64 [param0+0], func_ptr; + .param .align 16 .b8 retval0[16]; + prototype_1 : .callprototype (.param .align 16 .b8 _[16]) _ (); + call (retval0), func_ptr, () , prototype_1; + ld.param.v2.f64 {%fd0, %fd1}, [retval0+0]; +} +st.global.v2.f64 [result_ptr], {%fd0, %fd1}; + +$L__BB1_2: +ret; + +} + diff --git a/ptx/src/test/spirv_run/amdgpu_unnamed.ll b/ptx/src/test/spirv_run/amdgpu_unnamed.ll new file mode 100644 index 0000000..b08350b --- /dev/null +++ b/ptx/src/test/spirv_run/amdgpu_unnamed.ll @@ -0,0 +1,84 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@0 = protected addrspace(1) externally_initialized global [2 x i8] c"v\00", align 1 +@1 = protected addrspace(1) externally_initialized global [2 x i8] c"*\00", align 1 +@2 = protected addrspace(1) externally_initialized global [2 x i8] c"s\00", align 1 + +declare void @__zluda_ptx_impl____assertfail(i64, i64, i32, i64, i64) #0 + +define protected amdgpu_kernel void @amdgpu_unnamed(ptr addrspace(4) byref(i64) %"58", ptr addrspace(4) byref(i64) %"59") #1 { +"74": + %"33" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"33", align 1 + %"34" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"34", align 1 + %"14" = alloca i64, align 8, addrspace(5) + %"15" = alloca i64, align 8, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + %"17" = alloca i64, align 8, addrspace(5) + %"18" = alloca i1, align 1, addrspace(5) + %"19" = alloca i64, align 8, addrspace(5) + %"20" = alloca i32, align 4, addrspace(5) + %"60" = alloca i64, align 8, addrspace(5) + %"61" = alloca i64, align 8, addrspace(5) + %"62" = alloca i32, align 4, addrspace(5) + %"63" = alloca i64, align 8, addrspace(5) + %"64" = alloca i64, align 8, addrspace(5) + %"35" = load i64, ptr addrspace(4) %"58", align 8 + store i64 %"35", ptr addrspace(5) %"14", align 8 + %"36" = load i64, ptr addrspace(4) %"59", align 8 + store i64 %"36", ptr addrspace(5) %"15", align 8 + %"38" = load i64, ptr addrspace(5) %"14", align 8 + %"66" = inttoptr i64 %"38" to ptr + %"37" = load i64, ptr %"66", align 8 + store i64 %"37", ptr addrspace(5) %"16", align 8 + %"40" = load i64, ptr addrspace(5) %"16", align 8 + %"39" = icmp uge i64 %"40", 1 + store i1 %"39", ptr addrspace(5) %"18", align 1 + %"41" = load i1, ptr addrspace(5) %"18", align 1 + br i1 %"41", label %"13", label %"27" + +"27": ; preds = %"74" + %0 = alloca i64, align 8, addrspace(5) + store i64 ptrtoint (ptr addrspace(1) @0 to i64), ptr addrspace(5) %0, align 8 + %"67" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"67", ptr addrspace(5) %"19", align 8 + %"43" = load i64, ptr addrspace(5) %"19", align 8 + store i64 %"43", ptr addrspace(5) %"60", align 8 + %1 = alloca i64, align 8, addrspace(5) + store i64 ptrtoint (ptr addrspace(1) @1 to i64), ptr addrspace(5) %1, align 8 + %"69" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"69", ptr addrspace(5) %"19", align 8 + %"45" = load i64, ptr addrspace(5) %"19", align 8 + store i64 %"45", ptr addrspace(5) %"61", align 8 + store i32 1, ptr addrspace(5) %"62", align 4 + %2 = alloca i64, align 8, addrspace(5) + store i64 ptrtoint (ptr addrspace(1) @2 to i64), ptr addrspace(5) %2, align 8 + %"71" = load i64, ptr addrspace(5) %2, align 8 + store i64 %"71", ptr addrspace(5) %"19", align 8 + %"47" = load i64, ptr addrspace(5) %"19", align 8 + store i64 %"47", ptr addrspace(5) %"63", align 8 + %"76" = getelementptr inbounds i8, ptr addrspace(5) %"64", i64 0 + store i64 1, ptr addrspace(5) %"76", align 8 + %"28" = load i64, ptr addrspace(5) %"60", align 8 + %"29" = load i64, ptr addrspace(5) %"61", align 8 + %"30" = load i32, ptr addrspace(5) %"62", align 4 + %"31" = load i64, ptr addrspace(5) %"63", align 8 + %"32" = load i64, ptr addrspace(5) %"64", align 8 + call void @__zluda_ptx_impl____assertfail(i64 %"28", i64 %"29", i32 %"30", i64 %"31", i64 %"32") + br label %"13" + +"13": ; preds = %"27", %"74" + %"49" = load i64, ptr addrspace(5) %"16", align 8 + %"48" = add i64 %"49", 1 + store i64 %"48", ptr addrspace(5) %"17", align 8 + %"50" = load i64, ptr addrspace(5) %"15", align 8 + %"51" = load i64, ptr addrspace(5) %"17", align 8 + %"73" = inttoptr i64 %"50" to ptr + store i64 %"51", ptr %"73", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/amdgpu_unnamed.ptx b/ptx/src/test/spirv_run/amdgpu_unnamed.ptx new file mode 100644 index 0000000..972b93d --- /dev/null +++ b/ptx/src/test/spirv_run/amdgpu_unnamed.ptx @@ -0,0 +1,57 @@ +// For some reason presence of __unnamed_1 in emitted bitcode makes comgr fail inside LLVM +.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 +); + +.global .align 1 .b8 __unnamed_1[2] = {118, 0}; +.global .align 1 .b8 $str[2] = {42, 0}; +.global .align 1 .b8 $str1[2] = {115, 0}; + +.visible .entry amdgpu_unnamed( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + .reg .pred always_true; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u64 temp, [in_addr]; + setp.ge.u64 always_true, temp, 1; + @always_true bra NOFAIL; + + .reg .b64 b64_temp; + .reg .b32 b32_temp; + .param .b64 param0; + mov.u64 b64_temp, __unnamed_1; + st.param.b64 [param0], b64_temp; + .param .b64 param1; + mov.u64 b64_temp, $str; + st.param.b64 [param1], b64_temp; + .param .b32 param2; + st.param.b32 [param2], 1; + .param .b64 param3; + mov.u64 b64_temp, $str1; + st.param.b64 [param3], b64_temp; + .param .b64 param4; + st.param.b64 [param4+0], 1; + call.uni __assertfail, (param0, param1, param2, param3, param4); +NOFAIL: + add.u64 temp2, temp, 1; + st.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/and.ll b/ptx/src/test/spirv_run/and.ll new file mode 100644 index 0000000..2862bcc --- /dev/null +++ b/ptx/src/test/spirv_run/and.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @and(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"31": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"33" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"33", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"27" = and i32 %"17", %"18" + store i32 %"27", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"30" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"30", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/and.spvtxt b/ptx/src/test/spirv_run/and.spvtxt deleted file mode 100644 index a378602..0000000 --- a/ptx/src/test/spirv_run/and.spvtxt +++ /dev/null @@ -1,58 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %22 - %14 = OpLoad %uint %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/assertfail.ll b/ptx/src/test/spirv_run/assertfail.ll new file mode 100644 index 0000000..0fb51f7 --- /dev/null +++ b/ptx/src/test/spirv_run/assertfail.ll @@ -0,0 +1,66 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare void @__zluda_ptx_impl____assertfail(i64, i64, i32, i64, i64) #0 + +define protected amdgpu_kernel void @assertfail(ptr addrspace(4) byref(i64) %"63", ptr addrspace(4) byref(i64) %"64") #1 { +"82": + %"35" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"35", align 1 + %"36" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"36", align 1 + %"15" = alloca i64, align 8, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + %"17" = alloca i64, align 8, addrspace(5) + %"18" = alloca i64, align 8, addrspace(5) + %"19" = alloca i32, align 4, addrspace(5) + %"65" = alloca i64, align 8, addrspace(5) + %"67" = alloca i64, align 8, addrspace(5) + %"69" = alloca i32, align 4, addrspace(5) + %"71" = alloca i64, align 8, addrspace(5) + %"73" = alloca i64, align 8, addrspace(5) + %"37" = load i64, ptr addrspace(4) %"63", align 8 + store i64 %"37", ptr addrspace(5) %"15", align 8 + %"38" = load i64, ptr addrspace(4) %"64", align 8 + store i64 %"38", ptr addrspace(5) %"16", align 8 + %0 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %0, align 4 + %"75" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"75", ptr addrspace(5) %"19", align 4 + %"40" = load i64, ptr addrspace(5) %"15", align 8 + %"84" = getelementptr inbounds i8, ptr addrspace(5) %"65", i64 0 + store i64 %"40", ptr addrspace(5) %"84", align 8 + %"41" = load i64, ptr addrspace(5) %"15", align 8 + %"86" = getelementptr inbounds i8, ptr addrspace(5) %"67", i64 0 + store i64 %"41", ptr addrspace(5) %"86", align 8 + %"42" = load i32, ptr addrspace(5) %"19", align 4 + %"88" = getelementptr inbounds i8, ptr addrspace(5) %"69", i64 0 + store i32 %"42", ptr addrspace(5) %"88", align 4 + %"43" = load i64, ptr addrspace(5) %"15", align 8 + %"90" = getelementptr inbounds i8, ptr addrspace(5) %"71", i64 0 + store i64 %"43", ptr addrspace(5) %"90", align 8 + %"44" = load i64, ptr addrspace(5) %"15", align 8 + %"92" = getelementptr inbounds i8, ptr addrspace(5) %"73", i64 0 + store i64 %"44", ptr addrspace(5) %"92", align 8 + %"30" = load i64, ptr addrspace(5) %"65", align 8 + %"31" = load i64, ptr addrspace(5) %"67", align 8 + %"32" = load i32, ptr addrspace(5) %"69", align 4 + %"33" = load i64, ptr addrspace(5) %"71", align 8 + %"34" = load i64, ptr addrspace(5) %"73", align 8 + call void @__zluda_ptx_impl____assertfail(i64 %"30", i64 %"31", i32 %"32", i64 %"33", i64 %"34") + %"46" = load i64, ptr addrspace(5) %"15", align 8 + %"80" = inttoptr i64 %"46" to ptr + %"45" = load i64, ptr %"80", align 8 + store i64 %"45", ptr addrspace(5) %"17", align 8 + %"48" = load i64, ptr addrspace(5) %"17", align 8 + %"47" = add i64 %"48", 1 + store i64 %"47", ptr addrspace(5) %"18", align 8 + %"49" = load i64, ptr addrspace(5) %"16", align 8 + %"50" = load i64, ptr addrspace(5) %"18", align 8 + %"81" = inttoptr i64 %"49" to ptr + store i64 %"50", ptr %"81", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/assertfail.spvtxt b/ptx/src/test/spirv_run/assertfail.spvtxt deleted file mode 100644 index 8ed84fa..0000000 --- a/ptx/src/test/spirv_run/assertfail.spvtxt +++ /dev/null @@ -1,105 +0,0 @@ - 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 Aligned 8 - OpStore %15 %27 - %28 = OpLoad %ulong %14 Aligned 8 - 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 Aligned 8 - %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 Aligned 8 - %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 Aligned 4 - %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 Aligned 8 - %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 Aligned 8 - %87 = OpFunctionCall %void %1 %20 %21 %22 %23 %24 - %36 = OpLoad %ulong %15 - %58 = OpConvertUToPtr %_ptr_Generic_ulong %36 - %35 = OpLoad %ulong %58 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_add.ll b/ptx/src/test/spirv_run/atom_add.ll new file mode 100644 index 0000000..88ccc57 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_add.ll @@ -0,0 +1,48 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@"4" = private addrspace(3) global [1024 x i8] undef, align 4 + +define protected amdgpu_kernel void @atom_add(ptr addrspace(4) byref(i64) %"29", ptr addrspace(4) byref(i64) %"30") #0 { +"38": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"31", align 4 + store i32 %"13", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = inttoptr i64 %"16" to ptr + %"40" = getelementptr inbounds i8, ptr %"32", i64 4 + %"15" = load i32, ptr %"40", align 4 + store i32 %"15", ptr addrspace(5) %"8", align 4 + %"17" = load i32, ptr addrspace(5) %"7", align 4 + store i32 %"17", ptr addrspace(3) @"4", align 4 + %"19" = load i32, ptr addrspace(5) %"8", align 4 + %"18" = atomicrmw add ptr addrspace(3) @"4", i32 %"19" syncscope("agent-one-as") monotonic, align 4 + store i32 %"18", ptr addrspace(5) %"7", align 4 + %"20" = load i32, ptr addrspace(3) @"4", align 4 + store i32 %"20", ptr addrspace(5) %"8", align 4 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load i32, ptr addrspace(5) %"7", align 4 + %"36" = inttoptr i64 %"21" to ptr + store i32 %"22", ptr %"36", align 4 + %"23" = load i64, ptr addrspace(5) %"6", align 8 + %"24" = load i32, ptr addrspace(5) %"8", align 4 + %"37" = inttoptr i64 %"23" to ptr + %"42" = getelementptr inbounds i8, ptr %"37", i64 4 + store i32 %"24", ptr %"42", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_add.spvtxt b/ptx/src/test/spirv_run/atom_add.spvtxt deleted file mode 100644 index 3966da6..0000000 --- a/ptx/src/test/spirv_run/atom_add.spvtxt +++ /dev/null @@ -1,76 +0,0 @@ - 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 Aligned 8 - OpStore %5 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %29 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %29 Aligned 4 - OpStore %7 %13 - %16 = OpLoad %ulong %5 - %26 = OpIAdd %ulong %16 %ulong_4 - %30 = OpConvertUToPtr %_ptr_Generic_uint %26 - %15 = OpLoad %uint %30 Aligned 4 - OpStore %8 %15 - %17 = OpLoad %uint %7 - %31 = OpBitcast %_ptr_Workgroup_uint %4 - OpStore %31 %17 Aligned 4 - %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 Aligned 4 - OpStore %8 %20 - %21 = OpLoad %ulong %6 - %22 = OpLoad %uint %7 - %34 = OpConvertUToPtr %_ptr_Generic_uint %21 - OpStore %34 %22 Aligned 4 - %23 = OpLoad %ulong %6 - %24 = OpLoad %uint %8 - %28 = OpIAdd %ulong %23 %ulong_4_0 - %35 = OpConvertUToPtr %_ptr_Generic_uint %28 - OpStore %35 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_add_f16.ll b/ptx/src/test/spirv_run/atom_add_f16.ll new file mode 100644 index 0000000..10a22a0 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_add_f16.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@"4" = private addrspace(3) global [1024 x i8] undef, align 4 + +define protected amdgpu_kernel void @atom_add_f16(ptr addrspace(4) byref(i64) %"27", ptr addrspace(4) byref(i64) %"28") #0 { +"38": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca half, align 2, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"27", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"11" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"29" = inttoptr i64 %"13" to ptr + %"40" = getelementptr inbounds i8, ptr %"29", i64 2 + %"30" = load i16, ptr %"40", align 2 + %"12" = bitcast i16 %"30" to half + store half %"12", ptr addrspace(5) %"7", align 2 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load half, ptr addrspace(5) %"7", align 2 + %"31" = inttoptr i64 %"15" to ptr + %"14" = atomicrmw fadd ptr %"31", half %"16" syncscope("agent-one-as") monotonic, align 2 + store half %"14", ptr addrspace(5) %"7", align 2 + %"17" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = load half, ptr addrspace(5) %"7", align 2 + %"32" = inttoptr i64 %"17" to ptr + %"33" = bitcast half %"18" to i16 + store i16 %"33", ptr %"32", align 2 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"35" = inttoptr i64 %"20" to ptr + %"34" = load i16, ptr %"35", align 2 + %"19" = bitcast i16 %"34" to half + store half %"19", ptr addrspace(5) %"7", align 2 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load half, ptr addrspace(5) %"7", align 2 + %"36" = inttoptr i64 %"21" to ptr + %"42" = getelementptr inbounds i8, ptr %"36", i64 2 + %"37" = bitcast half %"22" to i16 + store i16 %"37", ptr %"42", align 2 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_add_f16.ptx b/ptx/src/test/spirv_run/atom_add_f16.ptx new file mode 100644 index 0000000..0dc684d --- /dev/null +++ b/ptx/src/test/spirv_run/atom_add_f16.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_70 +.address_size 64 + +.visible .entry atom_add_f16( + .param .u64 input, + .param .u64 output +) +{ + .shared .align 4 .b8 shared_mem[1024]; + + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f16 temp; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.b16 temp, [in_addr+2]; + atom.add.noftz.f16 temp, [in_addr], temp; + st.b16 [out_addr], temp; + ld.b16 temp, [in_addr]; + st.b16 [out_addr+2], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/atom_add_float.ll b/ptx/src/test/spirv_run/atom_add_float.ll new file mode 100644 index 0000000..efce26c --- /dev/null +++ b/ptx/src/test/spirv_run/atom_add_float.ll @@ -0,0 +1,48 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@"4" = private addrspace(3) global [1024 x i8] undef, align 4 + +define protected amdgpu_kernel void @atom_add_float(ptr addrspace(4) byref(i64) %"29", ptr addrspace(4) byref(i64) %"30") #0 { +"38": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = inttoptr i64 %"14" to ptr + %"13" = load float, ptr %"31", align 4 + store float %"13", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = inttoptr i64 %"16" to ptr + %"40" = getelementptr inbounds i8, ptr %"32", i64 4 + %"15" = load float, ptr %"40", align 4 + store float %"15", ptr addrspace(5) %"8", align 4 + %"17" = load float, ptr addrspace(5) %"7", align 4 + store float %"17", ptr addrspace(3) @"4", align 4 + %"19" = load float, ptr addrspace(5) %"8", align 4 + %"18" = atomicrmw fadd ptr addrspace(3) @"4", float %"19" syncscope("agent-one-as") monotonic, align 4 + store float %"18", ptr addrspace(5) %"7", align 4 + %"20" = load float, ptr addrspace(3) @"4", align 4 + store float %"20", ptr addrspace(5) %"8", align 4 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load float, ptr addrspace(5) %"7", align 4 + %"36" = inttoptr i64 %"21" to ptr + store float %"22", ptr %"36", align 4 + %"23" = load i64, ptr addrspace(5) %"6", align 8 + %"24" = load float, ptr addrspace(5) %"8", align 4 + %"37" = inttoptr i64 %"23" to ptr + %"42" = getelementptr inbounds i8, ptr %"37", i64 4 + store float %"24", ptr %"42", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_add_float.ptx b/ptx/src/test/spirv_run/atom_add_float.ptx new file mode 100644 index 0000000..3e3b748 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_add_float.ptx @@ -0,0 +1,28 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry atom_add_float( + .param .u64 input, + .param .u64 output +) +{ + .shared .align 4 .b8 shared_mem[1024]; + + .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]; + st.shared.f32 [shared_mem], temp1; + atom.shared.add.f32 temp1, [shared_mem], temp2; + ld.shared.f32 temp2, [shared_mem]; + st.f32 [out_addr], temp1; + st.f32 [out_addr+4], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/atom_cas.ll b/ptx/src/test/spirv_run/atom_cas.ll new file mode 100644 index 0000000..fb83ed4 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_cas.ll @@ -0,0 +1,46 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @atom_cas(ptr addrspace(4) byref(i64) %"30", ptr addrspace(4) byref(i64) %"31") #0 { +"39": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"31", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"32", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"33" = inttoptr i64 %"15" to ptr + %"41" = getelementptr inbounds i8, ptr %"33", i64 4 + %0 = cmpxchg ptr %"41", i32 %"16", i32 100 syncscope("agent-one-as") monotonic monotonic, align 4 + %"34" = extractvalue { i32, i1 } %0, 0 + store i32 %"34", ptr addrspace(5) %"6", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"36" = inttoptr i64 %"18" to ptr + %"43" = getelementptr inbounds i8, ptr %"36", i64 4 + %"17" = load i32, ptr %"43", align 4 + store i32 %"17", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"37" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"37", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load i32, ptr addrspace(5) %"7", align 4 + %"38" = inttoptr i64 %"21" to ptr + %"45" = getelementptr inbounds i8, ptr %"38", i64 4 + store i32 %"22", ptr %"45", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_cas.spvtxt b/ptx/src/test/spirv_run/atom_cas.spvtxt deleted file mode 100644 index e1feb0a..0000000 --- a/ptx/src/test/spirv_run/atom_cas.spvtxt +++ /dev/null @@ -1,69 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %30 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %30 Aligned 4 - 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 Aligned 4 - OpStore %7 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %35 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %35 %20 Aligned 4 - %21 = OpLoad %ulong %5 - %22 = OpLoad %uint %7 - %29 = OpIAdd %ulong %21 %ulong_4_1 - %36 = OpConvertUToPtr %_ptr_Generic_uint %29 - OpStore %36 %22 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_inc.ll b/ptx/src/test/spirv_run/atom_inc.ll new file mode 100644 index 0000000..26b7b70 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_inc.ll @@ -0,0 +1,53 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__atom_relaxed_gpu_generic_inc(ptr, i32) #0 + +declare i32 @__zluda_ptx_impl__atom_relaxed_gpu_global_inc(ptr addrspace(1), i32) #0 + +define protected amdgpu_kernel void @atom_inc(ptr addrspace(4) byref(i64) %"31", ptr addrspace(4) byref(i64) %"32") #1 { +"39": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"31", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"32", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"33" = inttoptr i64 %"14" to ptr + %"13" = call i32 @__zluda_ptx_impl__atom_relaxed_gpu_generic_inc(ptr %"33", i32 101) + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"34" = inttoptr i64 %"16" to ptr addrspace(1) + %"15" = call i32 @__zluda_ptx_impl__atom_relaxed_gpu_global_inc(ptr addrspace(1) %"34", i32 101) + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"35" = inttoptr i64 %"18" to ptr + %"17" = load i32, ptr %"35", align 4 + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"36" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"36", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load i32, ptr addrspace(5) %"7", align 4 + %"37" = inttoptr i64 %"21" to ptr + %"49" = getelementptr inbounds i8, ptr %"37", i64 4 + store i32 %"22", ptr %"49", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load i32, ptr addrspace(5) %"8", align 4 + %"38" = inttoptr i64 %"23" to ptr + %"51" = getelementptr inbounds i8, ptr %"38", i64 8 + store i32 %"24", ptr %"51", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_inc.spvtxt b/ptx/src/test/spirv_run/atom_inc.spvtxt deleted file mode 100644 index 11b4243..0000000 --- a/ptx/src/test/spirv_run/atom_inc.spvtxt +++ /dev/null @@ -1,81 +0,0 @@ - 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 %42 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_global_inc" Import - OpDecorate %38 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_generic_inc" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %51 = OpTypeFunction %uint %_ptr_CrossWorkgroup_uint %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %53 = OpTypeFunction %uint %_ptr_Generic_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 - %42 = OpFunction %uint None %51 - %44 = OpFunctionParameter %_ptr_CrossWorkgroup_uint - %45 = OpFunctionParameter %uint - OpFunctionEnd - %38 = OpFunction %uint None %53 - %40 = OpFunctionParameter %_ptr_Generic_uint - %41 = 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - 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 Aligned 4 - OpStore %8 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %34 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %34 %20 Aligned 4 - %21 = OpLoad %ulong %5 - %22 = OpLoad %uint %7 - %28 = OpIAdd %ulong %21 %ulong_4 - %35 = OpConvertUToPtr %_ptr_Generic_uint %28 - OpStore %35 %22 Aligned 4 - %23 = OpLoad %ulong %5 - %24 = OpLoad %uint %8 - %30 = OpIAdd %ulong %23 %ulong_8 - %36 = OpConvertUToPtr %_ptr_Generic_uint %30 - OpStore %36 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_ld_st.ll b/ptx/src/test/spirv_run/atom_ld_st.ll new file mode 100644 index 0000000..31f39c8 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_ld_st.ll @@ -0,0 +1,28 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @atom_ld_st(ptr addrspace(4) byref(i64) %"15", ptr addrspace(4) byref(i64) %"16") #0 { +"19": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"15", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"16", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"17" = inttoptr i64 %"12" to ptr + %"11" = load atomic i32, ptr %"17" syncscope("agent-one-as") acquire, align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = inttoptr i64 %"13" to ptr + store atomic i32 %"14", ptr %"18" syncscope("agent-one-as") release, align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_ld_st.ptx b/ptx/src/test/spirv_run/atom_ld_st.ptx new file mode 100644 index 0000000..032bcfb --- /dev/null +++ b/ptx/src/test/spirv_run/atom_ld_st.ptx @@ -0,0 +1,19 @@ +.version 6.5 +.target sm_70 +.address_size 64 + +.visible .entry atom_ld_st( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + ld.acquire.gpu.u32 temp, [in_addr]; + st.release.gpu.u32 [out_addr], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/atom_ld_st_vec.ll b/ptx/src/test/spirv_run/atom_ld_st_vec.ll new file mode 100644 index 0000000..95ff710 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_ld_st_vec.ll @@ -0,0 +1,37 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @atom_ld_st_vec(ptr addrspace(4) byref(i64) %"20", ptr addrspace(4) byref(i64) %"21") #0 { +"24": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"12", ptr addrspace(5) %"4", align 8 + %"13" = load i64, ptr addrspace(4) %"21", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"22" = inttoptr i64 %"14" to ptr + %0 = load atomic i128, ptr %"22" syncscope("agent-one-as") acquire, align 16 + %"8" = bitcast i128 %0 to <2 x i64> + %"15" = extractelement <2 x i64> %"8", i32 0 + %"16" = extractelement <2 x i64> %"8", i32 1 + store i64 %"15", ptr addrspace(5) %"6", align 8 + store i64 %"16", ptr addrspace(5) %"7", align 8 + %"17" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = load i64, ptr addrspace(5) %"7", align 8 + %1 = insertelement <2 x i64> undef, i64 %"17", i32 0 + %"9" = insertelement <2 x i64> %1, i64 %"18", i32 1 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = inttoptr i64 %"19" to ptr + %2 = bitcast <2 x i64> %"9" to i128 + store atomic i128 %2, ptr %"23" syncscope("agent-one-as") release, align 16 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_ld_st_vec.ptx b/ptx/src/test/spirv_run/atom_ld_st_vec.ptx new file mode 100644 index 0000000..962ab1a --- /dev/null +++ b/ptx/src/test/spirv_run/atom_ld_st_vec.ptx @@ -0,0 +1,20 @@ +.version 6.5 +.target sm_70 +.address_size 64 + +.visible .entry atom_ld_st_vec( + .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.acquire.gpu.v2.u64 {temp1, temp2}, [in_addr]; + st.release.gpu.v2.u64 [out_addr], {temp1, temp2}; + ret; +} diff --git a/ptx/src/test/spirv_run/atom_max_u32.ll b/ptx/src/test/spirv_run/atom_max_u32.ll new file mode 100644 index 0000000..7a89a13 --- /dev/null +++ b/ptx/src/test/spirv_run/atom_max_u32.ll @@ -0,0 +1,39 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @atom_max_u32(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"31": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"15" = load i32, ptr addrspace(5) %"6", align 4 + %"26" = inttoptr i64 %"14" to ptr + store i32 %"15", ptr %"26", align 4 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"17" to ptr + %"33" = getelementptr inbounds i8, ptr %"27", i64 4 + %"16" = load i32, ptr %"33", align 4 + store i32 %"16", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"7", align 4 + %"29" = inttoptr i64 %"19" to ptr + %"28" = atomicrmw umax ptr %"29", i32 %"20" syncscope("agent-one-as") monotonic, align 4 + store i32 %"28", ptr addrspace(5) %"6", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/atom_max_u32.ptx b/ptx/src/test/spirv_run/atom_max_u32.ptx new file mode 100644 index 0000000..c85757e --- /dev/null +++ b/ptx/src/test/spirv_run/atom_max_u32.ptx @@ -0,0 +1,23 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry atom_max_u32( + .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]; + st.b32 [out_addr], temp1; + ld.b32 temp2, [in_addr+4]; + atom.max.u32 temp1, [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/b64tof64.ll b/ptx/src/test/spirv_run/b64tof64.ll new file mode 100644 index 0000000..2c2b674 --- /dev/null +++ b/ptx/src/test/spirv_run/b64tof64.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @b64tof64(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca double, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load double, ptr addrspace(4) %"18", align 8 + store double %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load double, ptr addrspace(5) %"4", align 8 + %"21" = bitcast double %"13" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"21", ptr addrspace(5) %0, align 8 + %"12" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = inttoptr i64 %"15" to ptr + %"14" = load i64, ptr %"22", align 8 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"6", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"23" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"23", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/b64tof64.spvtxt b/ptx/src/test/spirv_run/b64tof64.spvtxt deleted file mode 100644 index 54ac111..0000000 --- a/ptx/src/test/spirv_run/b64tof64.spvtxt +++ /dev/null @@ -1,50 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - 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 Aligned 8 - OpStore %7 %14 - %16 = OpLoad %ulong %6 - %17 = OpLoad %ulong %7 - %21 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %21 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/barrier.ll b/ptx/src/test/spirv_run/barrier.ll new file mode 100644 index 0000000..c247e32 --- /dev/null +++ b/ptx/src/test/spirv_run/barrier.ll @@ -0,0 +1,17 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare void @__zluda_ptx_impl__barrier_sync(i32) #0 + +define protected amdgpu_kernel void @barrier() #1 { +"5": + %"2" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"2", align 1 + %"3" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"3", align 1 + call void @__zluda_ptx_impl__barrier_sync(i32 0) + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/barrier.ptx b/ptx/src/test/spirv_run/barrier.ptx new file mode 100644 index 0000000..3c6d767 --- /dev/null +++ b/ptx/src/test/spirv_run/barrier.ptx @@ -0,0 +1,9 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry barrier() +{ + barrier.sync 0; + ret; +} diff --git a/ptx/src/test/spirv_run/bfe.ll b/ptx/src/test/spirv_run/bfe.ll new file mode 100644 index 0000000..c67513a --- /dev/null +++ b/ptx/src/test/spirv_run/bfe.ll @@ -0,0 +1,48 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__bfe_u32(i32, i32, i32) #0 + +define protected amdgpu_kernel void @bfe(ptr addrspace(4) byref(i64) %"29", ptr addrspace(4) byref(i64) %"30") #1 { +"35": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"31", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"16" to ptr + %"42" = getelementptr inbounds i8, ptr %"32", i64 4 + %"15" = load i32, ptr %"42", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"33" = inttoptr i64 %"18" to ptr + %"44" = getelementptr inbounds i8, ptr %"33", i64 8 + %"17" = load i32, ptr %"44", align 4 + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"21" = load i32, ptr addrspace(5) %"7", align 4 + %"22" = load i32, ptr addrspace(5) %"8", align 4 + %"19" = call i32 @__zluda_ptx_impl__bfe_u32(i32 %"20", i32 %"21", i32 %"22") + store i32 %"19", ptr addrspace(5) %"6", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load i32, ptr addrspace(5) %"6", align 4 + %"34" = inttoptr i64 %"23" to ptr + store i32 %"24", ptr %"34", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/bfe.spvtxt b/ptx/src/test/spirv_run/bfe.spvtxt deleted file mode 100644 index 535ede9..0000000 --- a/ptx/src/test/spirv_run/bfe.spvtxt +++ /dev/null @@ -1,70 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %29 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %26 = OpIAdd %ulong %16 %ulong_4 - %30 = OpConvertUToPtr %_ptr_Generic_uint %26 - %15 = OpLoad %uint %30 Aligned 4 - OpStore %7 %15 - %18 = OpLoad %ulong %4 - %28 = OpIAdd %ulong %18 %ulong_8 - %31 = OpConvertUToPtr %_ptr_Generic_uint %28 - %17 = OpLoad %uint %31 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/bfi.ll b/ptx/src/test/spirv_run/bfi.ll new file mode 100644 index 0000000..2fc4191 --- /dev/null +++ b/ptx/src/test/spirv_run/bfi.ll @@ -0,0 +1,55 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__bfi_b32(i32, i32, i32, i32) #0 + +define protected amdgpu_kernel void @bfi(ptr addrspace(4) byref(i64) %"35", ptr addrspace(4) byref(i64) %"36") #1 { +"45": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"12", ptr addrspace(5) %"4", align 8 + %"13" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"15" to ptr + %"14" = load i32, ptr %"37", align 4 + store i32 %"14", ptr addrspace(5) %"6", align 4 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"38" = inttoptr i64 %"17" to ptr + %"53" = getelementptr inbounds i8, ptr %"38", i64 4 + %"16" = load i32, ptr %"53", align 4 + store i32 %"16", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"39" = inttoptr i64 %"19" to ptr + %"55" = getelementptr inbounds i8, ptr %"39", i64 8 + %"18" = load i32, ptr %"55", align 4 + store i32 %"18", ptr addrspace(5) %"8", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"40" = inttoptr i64 %"21" to ptr + %"57" = getelementptr inbounds i8, ptr %"40", i64 12 + %"20" = load i32, ptr %"57", align 4 + store i32 %"20", ptr addrspace(5) %"9", align 4 + %"23" = load i32, ptr addrspace(5) %"6", align 4 + %"24" = load i32, ptr addrspace(5) %"7", align 4 + %"25" = load i32, ptr addrspace(5) %"8", align 4 + %"26" = load i32, ptr addrspace(5) %"9", align 4 + %"41" = call i32 @__zluda_ptx_impl__bfi_b32(i32 %"23", i32 %"24", i32 %"25", i32 %"26") + store i32 %"41", ptr addrspace(5) %"6", align 4 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = load i32, ptr addrspace(5) %"6", align 4 + %"44" = inttoptr i64 %"27" to ptr + store i32 %"28", ptr %"44", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/bfi.ptx b/ptx/src/test/spirv_run/bfi.ptx new file mode 100644 index 0000000..f2bca91 --- /dev/null +++ b/ptx/src/test/spirv_run/bfi.ptx @@ -0,0 +1,24 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry bfi( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp<4>; + + 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]; + ld.u32 temp3, [in_addr+12]; + bfi.b32 temp0, temp0, temp1, temp2, temp3; + st.u32 [out_addr], temp0; + ret; +} diff --git a/ptx/src/test/spirv_run/bfind.ll b/ptx/src/test/spirv_run/bfind.ll new file mode 100644 index 0000000..4b7dc1b --- /dev/null +++ b/ptx/src/test/spirv_run/bfind.ll @@ -0,0 +1,75 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @bfind(ptr addrspace(4) byref(i64) %"42", ptr addrspace(4) byref(i64) %"43") #0 { +"53": + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"14" = load i64, ptr addrspace(4) %"42", align 8 + store i64 %"14", ptr addrspace(5) %"4", align 8 + %"15" = load i64, ptr addrspace(4) %"43", align 8 + store i64 %"15", ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"44" = inttoptr i64 %"17" to ptr + %"16" = load i32, ptr %"44", align 4 + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"45" = inttoptr i64 %"19" to ptr + %"55" = getelementptr inbounds i8, ptr %"45", i64 4 + %"18" = load i32, ptr %"55", align 4 + store i32 %"18", ptr addrspace(5) %"7", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"46" = inttoptr i64 %"21" to ptr + %"57" = getelementptr inbounds i8, ptr %"46", i64 8 + %"20" = load i32, ptr %"57", align 4 + store i32 %"20", ptr addrspace(5) %"8", align 4 + %"23" = load i32, ptr addrspace(5) %"6", align 4 + %0 = icmp eq i32 %"23", 0 + %1 = call i32 @llvm.ctlz.i32(i32 %"23", i1 true) + %2 = sub i32 31, %1 + %"47" = select i1 %0, i32 -1, i32 %2 + store i32 %"47", ptr addrspace(5) %"9", align 4 + %"25" = load i32, ptr addrspace(5) %"7", align 4 + %3 = icmp eq i32 %"25", 0 + %4 = call i32 @llvm.ctlz.i32(i32 %"25", i1 true) + %5 = sub i32 31, %4 + %"48" = select i1 %3, i32 -1, i32 %5 + store i32 %"48", ptr addrspace(5) %"10", align 4 + %"27" = load i32, ptr addrspace(5) %"8", align 4 + %6 = icmp eq i32 %"27", 0 + %7 = call i32 @llvm.ctlz.i32(i32 %"27", i1 true) + %8 = sub i32 31, %7 + %"49" = select i1 %6, i32 -1, i32 %8 + store i32 %"49", ptr addrspace(5) %"11", align 4 + %"28" = load i64, ptr addrspace(5) %"5", align 8 + %"29" = load i32, ptr addrspace(5) %"9", align 4 + %"50" = inttoptr i64 %"28" to ptr + store i32 %"29", ptr %"50", align 4 + %"30" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = load i32, ptr addrspace(5) %"10", align 4 + %"51" = inttoptr i64 %"30" to ptr + %"59" = getelementptr inbounds i8, ptr %"51", i64 4 + store i32 %"31", ptr %"59", align 4 + %"32" = load i64, ptr addrspace(5) %"5", align 8 + %"33" = load i32, ptr addrspace(5) %"11", align 4 + %"52" = inttoptr i64 %"32" to ptr + %"61" = getelementptr inbounds i8, ptr %"52", i64 8 + store i32 %"33", ptr %"61", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.ctlz.i32(i32, i1 immarg) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/bfind.ptx b/ptx/src/test/spirv_run/bfind.ptx new file mode 100644 index 0000000..a49fce3 --- /dev/null +++ b/ptx/src/test/spirv_run/bfind.ptx @@ -0,0 +1,27 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry bfind( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp<6>; + + 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]; + bfind.u32 temp3, temp0; + bfind.u32 temp4, temp1; + bfind.u32 temp5, temp2; + st.u32 [out_addr], temp3; + st.u32 [out_addr+4], temp4; + st.u32 [out_addr+8], temp5; + ret; +} diff --git a/ptx/src/test/spirv_run/bfind_shiftamt.ll b/ptx/src/test/spirv_run/bfind_shiftamt.ll new file mode 100644 index 0000000..6a3ca72 --- /dev/null +++ b/ptx/src/test/spirv_run/bfind_shiftamt.ll @@ -0,0 +1,72 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @bfind_shiftamt(ptr addrspace(4) byref(i64) %"42", ptr addrspace(4) byref(i64) %"43") #0 { +"53": + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"14" = load i64, ptr addrspace(4) %"42", align 8 + store i64 %"14", ptr addrspace(5) %"4", align 8 + %"15" = load i64, ptr addrspace(4) %"43", align 8 + store i64 %"15", ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"44" = inttoptr i64 %"17" to ptr + %"16" = load i32, ptr %"44", align 4 + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"45" = inttoptr i64 %"19" to ptr + %"55" = getelementptr inbounds i8, ptr %"45", i64 4 + %"18" = load i32, ptr %"55", align 4 + store i32 %"18", ptr addrspace(5) %"7", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"46" = inttoptr i64 %"21" to ptr + %"57" = getelementptr inbounds i8, ptr %"46", i64 8 + %"20" = load i32, ptr %"57", align 4 + store i32 %"20", ptr addrspace(5) %"8", align 4 + %"23" = load i32, ptr addrspace(5) %"6", align 4 + %0 = icmp eq i32 %"23", 0 + %1 = call i32 @llvm.ctlz.i32(i32 %"23", i1 true) + %"47" = select i1 %0, i32 -1, i32 %1 + store i32 %"47", ptr addrspace(5) %"9", align 4 + %"25" = load i32, ptr addrspace(5) %"7", align 4 + %2 = icmp eq i32 %"25", 0 + %3 = call i32 @llvm.ctlz.i32(i32 %"25", i1 true) + %"48" = select i1 %2, i32 -1, i32 %3 + store i32 %"48", ptr addrspace(5) %"10", align 4 + %"27" = load i32, ptr addrspace(5) %"8", align 4 + %4 = icmp eq i32 %"27", 0 + %5 = call i32 @llvm.ctlz.i32(i32 %"27", i1 true) + %"49" = select i1 %4, i32 -1, i32 %5 + store i32 %"49", ptr addrspace(5) %"11", align 4 + %"28" = load i64, ptr addrspace(5) %"5", align 8 + %"29" = load i32, ptr addrspace(5) %"9", align 4 + %"50" = inttoptr i64 %"28" to ptr + store i32 %"29", ptr %"50", align 4 + %"30" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = load i32, ptr addrspace(5) %"10", align 4 + %"51" = inttoptr i64 %"30" to ptr + %"59" = getelementptr inbounds i8, ptr %"51", i64 4 + store i32 %"31", ptr %"59", align 4 + %"32" = load i64, ptr addrspace(5) %"5", align 8 + %"33" = load i32, ptr addrspace(5) %"11", align 4 + %"52" = inttoptr i64 %"32" to ptr + %"61" = getelementptr inbounds i8, ptr %"52", i64 8 + store i32 %"33", ptr %"61", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.ctlz.i32(i32, i1 immarg) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/bfind_shiftamt.ptx b/ptx/src/test/spirv_run/bfind_shiftamt.ptx new file mode 100644 index 0000000..210488f --- /dev/null +++ b/ptx/src/test/spirv_run/bfind_shiftamt.ptx @@ -0,0 +1,27 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry bfind_shiftamt( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp<6>; + + 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]; + bfind.shiftamt.u32 temp3, temp0; + bfind.shiftamt.u32 temp4, temp1; + bfind.shiftamt.u32 temp5, temp2; + st.u32 [out_addr], temp3; + st.u32 [out_addr+4], temp4; + st.u32 [out_addr+8], temp5; + ret; +} diff --git a/ptx/src/test/spirv_run/block.ll b/ptx/src/test/spirv_run/block.ll new file mode 100644 index 0000000..87c9374 --- /dev/null +++ b/ptx/src/test/spirv_run/block.ll @@ -0,0 +1,36 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @block(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"27": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"14" to ptr + %"13" = load i64, ptr %"25", align 8 + store i64 %"13", ptr addrspace(5) %"6", align 8 + %"16" = load i64, ptr addrspace(5) %"6", align 8 + %"15" = add i64 %"16", 1 + store i64 %"15", ptr addrspace(5) %"7", align 8 + %"18" = load i64, ptr addrspace(5) %"8", align 8 + %"17" = add i64 %"18", 1 + store i64 %"17", ptr addrspace(5) %"8", align 8 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i64, ptr addrspace(5) %"7", align 8 + %"26" = inttoptr i64 %"19" to ptr + store i64 %"20", ptr %"26", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/block.spvtxt b/ptx/src/test/spirv_run/block.spvtxt deleted file mode 100644 index 6921c04..0000000 --- a/ptx/src/test/spirv_run/block.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_ulong %14 - %13 = OpLoad %ulong %23 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/bra.ll b/ptx/src/test/spirv_run/bra.ll new file mode 100644 index 0000000..6188dc7 --- /dev/null +++ b/ptx/src/test/spirv_run/bra.ll @@ -0,0 +1,44 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @bra(ptr addrspace(4) byref(i64) %"25", ptr addrspace(4) byref(i64) %"26") #0 { +"29": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"13", ptr addrspace(5) %"7", align 8 + %"14" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"14", ptr addrspace(5) %"8", align 8 + %"16" = load i64, ptr addrspace(5) %"7", align 8 + %"27" = inttoptr i64 %"16" to ptr + %"15" = load i64, ptr %"27", align 8 + store i64 %"15", ptr addrspace(5) %"9", align 8 + br label %"4" + +"4": ; preds = %"29" + %"18" = load i64, ptr addrspace(5) %"9", align 8 + %"17" = add i64 %"18", 1 + store i64 %"17", ptr addrspace(5) %"10", align 8 + br label %"6" + +0: ; No predecessors! + %"20" = load i64, ptr addrspace(5) %"9", align 8 + %"19" = add i64 %"20", 2 + store i64 %"19", ptr addrspace(5) %"10", align 8 + br label %"6" + +"6": ; preds = %0, %"4" + %"21" = load i64, ptr addrspace(5) %"8", align 8 + %"22" = load i64, ptr addrspace(5) %"10", align 8 + %"28" = inttoptr i64 %"21" to ptr + store i64 %"22", ptr %"28", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/bra.spvtxt b/ptx/src/test/spirv_run/bra.spvtxt deleted file mode 100644 index c2c1e1c..0000000 --- a/ptx/src/test/spirv_run/bra.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - 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 Aligned 8 - OpStore %7 %13 - %14 = OpLoad %ulong %3 Aligned 8 - OpStore %8 %14 - %16 = OpLoad %ulong %7 - %25 = OpConvertUToPtr %_ptr_Generic_ulong %16 - %15 = OpLoad %ulong %25 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/brev.ll b/ptx/src/test/spirv_run/brev.ll new file mode 100644 index 0000000..e43d1c6 --- /dev/null +++ b/ptx/src/test/spirv_run/brev.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @brev(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load i32, ptr %"19", align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"13" = call i32 @llvm.bitreverse.i32(i32 %"14") + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store i32 %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.bitreverse.i32(i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/brev.spvtxt b/ptx/src/test/spirv_run/brev.spvtxt deleted file mode 100644 index 68faeca..0000000 --- a/ptx/src/test/spirv_run/brev.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/call.ll b/ptx/src/test/spirv_run/call.ll new file mode 100644 index 0000000..af26549 --- /dev/null +++ b/ptx/src/test/spirv_run/call.ll @@ -0,0 +1,64 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define private i64 @incr(i64 %"31") #0 { +"51": + %"18" = alloca i64, align 8, addrspace(5) + %"17" = alloca i64, align 8, addrspace(5) + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"44" = alloca i64, align 8, addrspace(5) + %"45" = alloca i64, align 8, addrspace(5) + %"14" = alloca i64, align 8, addrspace(5) + store i64 %"31", ptr addrspace(5) %"18", align 8 + %"32" = load i64, ptr addrspace(5) %"18", align 8 + store i64 %"32", ptr addrspace(5) %"45", align 8 + %"33" = load i64, ptr addrspace(5) %"45", align 8 + store i64 %"33", ptr addrspace(5) %"14", align 8 + %"35" = load i64, ptr addrspace(5) %"14", align 8 + %"34" = add i64 %"35", 1 + store i64 %"34", ptr addrspace(5) %"14", align 8 + %"36" = load i64, ptr addrspace(5) %"14", align 8 + store i64 %"36", ptr addrspace(5) %"44", align 8 + %"37" = load i64, ptr addrspace(5) %"44", align 8 + store i64 %"37", ptr addrspace(5) %"17", align 8 + %"38" = load i64, ptr addrspace(5) %"17", align 8 + ret i64 %"38" +} + +define protected amdgpu_kernel void @call(ptr addrspace(4) byref(i64) %"40", ptr addrspace(4) byref(i64) %"41") #0 { +"50": + %"19" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"19", align 1 + %"20" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"20", align 1 + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"42" = alloca i64, align 8, addrspace(5) + %"43" = alloca i64, align 8, addrspace(5) + %"23" = load i64, ptr addrspace(4) %"40", align 8 + store i64 %"23", ptr addrspace(5) %"7", align 8 + %"24" = load i64, ptr addrspace(4) %"41", align 8 + store i64 %"24", ptr addrspace(5) %"8", align 8 + %"26" = load i64, ptr addrspace(5) %"7", align 8 + %"46" = inttoptr i64 %"26" to ptr addrspace(1) + %"25" = load i64, ptr addrspace(1) %"46", align 8 + store i64 %"25", ptr addrspace(5) %"9", align 8 + %"27" = load i64, ptr addrspace(5) %"9", align 8 + store i64 %"27", ptr addrspace(5) %"42", align 8 + %"15" = load i64, ptr addrspace(5) %"42", align 8 + %"16" = call i64 @incr(i64 %"15") + store i64 %"16", ptr addrspace(5) %"43", align 8 + %"28" = load i64, ptr addrspace(5) %"43", align 8 + store i64 %"28", ptr addrspace(5) %"9", align 8 + %"29" = load i64, ptr addrspace(5) %"8", align 8 + %"30" = load i64, ptr addrspace(5) %"9", align 8 + %"49" = inttoptr i64 %"29" to ptr addrspace(1) + store i64 %"30", ptr addrspace(1) %"49", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/call.ptx b/ptx/src/test/spirv_run/call.ptx index f2ac39c..537fce2 100644 --- a/ptx/src/test/spirv_run/call.ptx +++ b/ptx/src/test/spirv_run/call.ptx @@ -2,7 +2,7 @@ .target sm_30 .address_size 64 -.func (.param.u64 output) incr (.param.u64 input); +.visible .func (.param.u64 output) incr (.param.u64 input); .visible .entry call( .param .u64 input, @@ -26,7 +26,7 @@ ret; } -.func (.param .u64 output) incr( +.visible .func (.param .u64 output) incr( .param .u64 input ) { diff --git a/ptx/src/test/spirv_run/call.spvtxt b/ptx/src/test/spirv_run/call.spvtxt deleted file mode 100644 index 5473234..0000000 --- a/ptx/src/test/spirv_run/call.spvtxt +++ /dev/null @@ -1,67 +0,0 @@ - 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 Aligned 8 - OpStore %7 %14 - %15 = OpLoad %ulong %6 Aligned 8 - OpStore %8 %15 - %17 = OpLoad %ulong %7 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17 - %16 = OpLoad %ulong %22 Aligned 8 - OpStore %9 %16 - %18 = OpLoad %ulong %9 - %23 = OpBitcast %_ptr_Function_ulong %10 - %24 = OpCopyObject %ulong %18 - OpStore %23 %24 Aligned 8 - %43 = OpFunctionCall %void %1 %11 %10 - %19 = OpLoad %ulong %11 Aligned 8 - OpStore %9 %19 - %20 = OpLoad %ulong %8 - %21 = OpLoad %ulong %9 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %20 - OpStore %25 %21 Aligned 8 - 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 Aligned 8 - OpStore %29 %30 - %32 = OpLoad %ulong %29 - %31 = OpIAdd %ulong %32 %ulong_1 - OpStore %29 %31 - %33 = OpLoad %ulong %29 - OpStore %27 %33 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/call_bug.ll b/ptx/src/test/spirv_run/call_bug.ll new file mode 100644 index 0000000..749b2b6 --- /dev/null +++ b/ptx/src/test/spirv_run/call_bug.ll @@ -0,0 +1,69 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define private [2 x i32] @incr(i64 %"23") #0 { +"58": + %"16" = alloca i64, align 8, addrspace(5) + %"15" = alloca [2 x i32], align 4, addrspace(5) + %"19" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"19", align 1 + %"20" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"20", align 1 + %"44" = alloca [2 x i32], align 4, addrspace(5) + %"45" = alloca i64, align 8, addrspace(5) + %"4" = alloca i64, align 8, addrspace(5) + store i64 %"23", ptr addrspace(5) %"16", align 8 + %"24" = load i64, ptr addrspace(5) %"16", align 8 + store i64 %"24", ptr addrspace(5) %"45", align 8 + %"25" = load i64, ptr addrspace(5) %"45", align 8 + store i64 %"25", ptr addrspace(5) %"4", align 8 + %"27" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = add i64 %"27", 1 + store i64 %"26", ptr addrspace(5) %"4", align 8 + %"28" = load i64, ptr addrspace(5) %"4", align 8 + store i64 %"28", ptr addrspace(5) %"44", align 8 + %"29" = load [2 x i32], ptr addrspace(5) %"44", align 4 + store [2 x i32] %"29", ptr addrspace(5) %"15", align 4 + %"30" = load [2 x i32], ptr addrspace(5) %"15", align 4 + ret [2 x i32] %"30" +} + +define protected amdgpu_kernel void @call_bug(ptr addrspace(4) byref(i64) %"46", ptr addrspace(4) byref(i64) %"47") #0 { +"59": + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"11" = alloca i64, align 8, addrspace(5) + %"48" = alloca i64, align 8, addrspace(5) + %"49" = alloca [2 x i32], align 4, addrspace(5) + %"31" = load i64, ptr addrspace(4) %"46", align 8 + store i64 %"31", ptr addrspace(5) %"8", align 8 + %"32" = load i64, ptr addrspace(4) %"47", align 8 + store i64 %"32", ptr addrspace(5) %"9", align 8 + %"34" = load i64, ptr addrspace(5) %"8", align 8 + %"52" = inttoptr i64 %"34" to ptr addrspace(1) + %"33" = load i64, ptr addrspace(1) %"52", align 8 + store i64 %"33", ptr addrspace(5) %"10", align 8 + %"35" = load i64, ptr addrspace(5) %"10", align 8 + store i64 %"35", ptr addrspace(5) %"48", align 8 + store i64 ptrtoint (ptr @incr to i64), ptr addrspace(5) %"11", align 8 + %"17" = load i64, ptr addrspace(5) %"48", align 8 + %"37" = load i64, ptr addrspace(5) %"11", align 8 + %0 = inttoptr i64 %"37" to ptr + %"18" = call [2 x i32] %0(i64 %"17") + store [2 x i32] %"18", ptr addrspace(5) %"49", align 4 + %"61" = getelementptr inbounds i8, ptr addrspace(5) %"49", i64 0 + %"38" = load i64, ptr addrspace(5) %"61", align 8 + store i64 %"38", ptr addrspace(5) %"10", align 8 + %"39" = load i64, ptr addrspace(5) %"9", align 8 + %"40" = load i64, ptr addrspace(5) %"10", align 8 + %"57" = inttoptr i64 %"39" to ptr addrspace(1) + store i64 %"40", ptr addrspace(1) %"57", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/call_bug.ptx b/ptx/src/test/spirv_run/call_bug.ptx new file mode 100644 index 0000000..15895bf --- /dev/null +++ b/ptx/src/test/spirv_run/call_bug.ptx @@ -0,0 +1,40 @@ +.version 6.5 +.target sm_30 +.address_size 64 + + +.visible .func (.param .b8 output[8]) incr( + .param .u64 input +) +{ + .reg .u64 temp; + ld.param.u64 temp, [input]; + add.u64 temp, temp, 1; + st.param.u64 [output], temp; + ret; +} + +.visible .entry call_bug( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 fn_ptr; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.u64 temp, [in_addr]; + .param.u64 incr_in; + .param.b8 incr_out[8]; + st.param.b64 [incr_in], temp; + prototype_1 : .callprototype (.param.b8 _[8]) _ (.param.u64 _); + mov.u64 fn_ptr, incr; + call (incr_out), fn_ptr, (incr_in), prototype_1; + ld.param.u64 temp, [incr_out+0]; + st.global.u64 [out_addr], temp; + ret; +} \ No newline at end of file diff --git a/ptx/src/test/spirv_run/call_multi_return.ll b/ptx/src/test/spirv_run/call_multi_return.ll new file mode 100644 index 0000000..a6cb883 --- /dev/null +++ b/ptx/src/test/spirv_run/call_multi_return.ll @@ -0,0 +1,85 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +%struct.i64i32 = type { i64, i32 } + +define private %struct.i64i32 @"1"(i32 %"41", i32 %"42") #0 { +"64": + %"18" = alloca i32, align 4, addrspace(5) + %"19" = alloca i32, align 4, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + %"17" = alloca i32, align 4, addrspace(5) + %"23" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"23", align 1 + %"24" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"24", align 1 + %"20" = alloca i32, align 4, addrspace(5) + store i32 %"41", ptr addrspace(5) %"18", align 4 + store i32 %"42", ptr addrspace(5) %"19", align 4 + %"44" = load i32, ptr addrspace(5) %"18", align 4 + %"45" = load i32, ptr addrspace(5) %"19", align 4 + %"43" = add i32 %"44", %"45" + store i32 %"43", ptr addrspace(5) %"20", align 4 + %"47" = load i32, ptr addrspace(5) %"20", align 4 + %"46" = zext i32 %"47" to i64 + store i64 %"46", ptr addrspace(5) %"16", align 8 + %"49" = load i32, ptr addrspace(5) %"18", align 4 + %"50" = load i32, ptr addrspace(5) %"19", align 4 + %"48" = mul i32 %"49", %"50" + store i32 %"48", ptr addrspace(5) %"17", align 4 + %"51" = load i64, ptr addrspace(5) %"16", align 8 + %"52" = load i32, ptr addrspace(5) %"17", align 4 + %0 = insertvalue %struct.i64i32 undef, i64 %"51", 0 + %1 = insertvalue %struct.i64i32 %0, i32 %"52", 1 + ret %struct.i64i32 %1 +} + +define protected amdgpu_kernel void @call_multi_return(ptr addrspace(4) byref(i64) %"57", ptr addrspace(4) byref(i64) %"58") #0 { +"63": + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"12" = alloca i32, align 4, addrspace(5) + %"13" = alloca i64, align 8, addrspace(5) + %"14" = alloca i64, align 8, addrspace(5) + %"15" = alloca i32, align 4, addrspace(5) + %"25" = load i64, ptr addrspace(4) %"57", align 8 + store i64 %"25", ptr addrspace(5) %"9", align 8 + %"26" = load i64, ptr addrspace(4) %"58", align 8 + store i64 %"26", ptr addrspace(5) %"10", align 8 + %"28" = load i64, ptr addrspace(5) %"9", align 8 + %"59" = inttoptr i64 %"28" to ptr addrspace(1) + %"27" = load i32, ptr addrspace(1) %"59", align 4 + store i32 %"27", ptr addrspace(5) %"11", align 4 + %"30" = load i64, ptr addrspace(5) %"9", align 8 + %"60" = inttoptr i64 %"30" to ptr addrspace(1) + %"66" = getelementptr inbounds i8, ptr addrspace(1) %"60", i64 4 + %"29" = load i32, ptr addrspace(1) %"66", align 4 + store i32 %"29", ptr addrspace(5) %"12", align 4 + %"33" = load i32, ptr addrspace(5) %"11", align 4 + %"34" = load i32, ptr addrspace(5) %"12", align 4 + %0 = call %struct.i64i32 @"1"(i32 %"33", i32 %"34") + %"31" = extractvalue %struct.i64i32 %0, 0 + %"32" = extractvalue %struct.i64i32 %0, 1 + store i64 %"31", ptr addrspace(5) %"13", align 8 + store i32 %"32", ptr addrspace(5) %"15", align 4 + %"36" = load i32, ptr addrspace(5) %"15", align 4 + %"35" = zext i32 %"36" to i64 + store i64 %"35", ptr addrspace(5) %"14", align 8 + %"37" = load i64, ptr addrspace(5) %"10", align 8 + %"38" = load i64, ptr addrspace(5) %"13", align 8 + %"61" = inttoptr i64 %"37" to ptr addrspace(1) + store i64 %"38", ptr addrspace(1) %"61", align 8 + %"39" = load i64, ptr addrspace(5) %"10", align 8 + %"40" = load i64, ptr addrspace(5) %"14", align 8 + %"62" = inttoptr i64 %"39" to ptr addrspace(1) + %"68" = getelementptr inbounds i8, ptr addrspace(1) %"62", i64 8 + store i64 %"40", ptr addrspace(1) %"68", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/call_multi_return.ptx b/ptx/src/test/spirv_run/call_multi_return.ptx new file mode 100644 index 0000000..eb2a4f9 --- /dev/null +++ b/ptx/src/test/spirv_run/call_multi_return.ptx @@ -0,0 +1,46 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.func (.reg.u64 add, .reg.u32 mult) add_mult (.reg.u32 x, .reg.u32 y); + +.visible .entry call_multi_return( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + + + .reg .u32 x; + .reg .u32 y; + + .reg .u64 add; + .reg .u64 mul; + .reg .u32 mul_32; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.u32 x, [in_addr]; + ld.global.u32 y, [in_addr+4]; + call (add, mul_32), add_mult, (x, y); + cvt.u64.u32 mul, mul_32; + st.global.u64 [out_addr], add; + st.global.u64 [out_addr+8], mul; + ret; +} + +.func (.reg.u64 add, .reg.u32 mul) add_mult ( + .reg.u32 x, + .reg.u32 y +) +{ + .reg .u32 add_32; + + add.u32 add_32, x, y; + cvt.u64.u32 add, add_32; + mul.lo.u32 mul, x, y; + ret; +} diff --git a/ptx/src/test/spirv_run/callprototype.ll b/ptx/src/test/spirv_run/callprototype.ll new file mode 100644 index 0000000..84e5987 --- /dev/null +++ b/ptx/src/test/spirv_run/callprototype.ll @@ -0,0 +1,68 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define private i64 @incr(i64 %"35") #0 { +"56": + %"20" = alloca i64, align 8, addrspace(5) + %"19" = alloca i64, align 8, addrspace(5) + %"23" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"23", align 1 + %"24" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"24", align 1 + %"48" = alloca i64, align 8, addrspace(5) + %"49" = alloca i64, align 8, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + store i64 %"35", ptr addrspace(5) %"20", align 8 + %"36" = load i64, ptr addrspace(5) %"20", align 8 + store i64 %"36", ptr addrspace(5) %"49", align 8 + %"37" = load i64, ptr addrspace(5) %"49", align 8 + store i64 %"37", ptr addrspace(5) %"16", align 8 + %"39" = load i64, ptr addrspace(5) %"16", align 8 + %"38" = add i64 %"39", 1 + store i64 %"38", ptr addrspace(5) %"16", align 8 + %"40" = load i64, ptr addrspace(5) %"16", align 8 + store i64 %"40", ptr addrspace(5) %"48", align 8 + %"41" = load i64, ptr addrspace(5) %"48", align 8 + store i64 %"41", ptr addrspace(5) %"19", align 8 + %"42" = load i64, ptr addrspace(5) %"19", align 8 + ret i64 %"42" +} + +define protected amdgpu_kernel void @callprototype(ptr addrspace(4) byref(i64) %"44", ptr addrspace(4) byref(i64) %"45") #0 { +"55": + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"46" = alloca i64, align 8, addrspace(5) + %"47" = alloca i64, align 8, addrspace(5) + %"25" = load i64, ptr addrspace(4) %"44", align 8 + store i64 %"25", ptr addrspace(5) %"7", align 8 + %"26" = load i64, ptr addrspace(4) %"45", align 8 + store i64 %"26", ptr addrspace(5) %"8", align 8 + %"28" = load i64, ptr addrspace(5) %"7", align 8 + %"50" = inttoptr i64 %"28" to ptr addrspace(1) + %"27" = load i64, ptr addrspace(1) %"50", align 8 + store i64 %"27", ptr addrspace(5) %"9", align 8 + %"29" = load i64, ptr addrspace(5) %"9", align 8 + store i64 %"29", ptr addrspace(5) %"46", align 8 + store i64 ptrtoint (ptr @incr to i64), ptr addrspace(5) %"10", align 8 + %"17" = load i64, ptr addrspace(5) %"46", align 8 + %"31" = load i64, ptr addrspace(5) %"10", align 8 + %0 = inttoptr i64 %"31" to ptr + %"18" = call i64 %0(i64 %"17") + store i64 %"18", ptr addrspace(5) %"47", align 8 + %"32" = load i64, ptr addrspace(5) %"47", align 8 + store i64 %"32", ptr addrspace(5) %"9", align 8 + %"33" = load i64, ptr addrspace(5) %"8", align 8 + %"34" = load i64, ptr addrspace(5) %"9", align 8 + %"54" = inttoptr i64 %"33" to ptr addrspace(1) + store i64 %"34", ptr addrspace(1) %"54", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/callprototype.ptx b/ptx/src/test/spirv_run/callprototype.ptx new file mode 100644 index 0000000..73c9746 --- /dev/null +++ b/ptx/src/test/spirv_run/callprototype.ptx @@ -0,0 +1,41 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .func (.param.u64 output) incr (.param.u64 input); + +.visible .entry callprototype( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 fn_ptr; + + 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; + prototype_1 : .callprototype (.param.u64 incr_in) _ (.param.u64 _); + mov.u64 fn_ptr, incr; + call (incr_out), fn_ptr, (incr_in), prototype_1; + ld.param.u64 temp, [incr_out]; + st.global.u64 [out_addr], temp; + ret; +} + +.visible .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/carry_mixed.ll b/ptx/src/test/spirv_run/carry_mixed.ll new file mode 100644 index 0000000..c33cc5e --- /dev/null +++ b/ptx/src/test/spirv_run/carry_mixed.ll @@ -0,0 +1,51 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @carry_mixed(ptr addrspace(4) byref(i64) %"34", ptr addrspace(4) byref(i64) %"35") #0 { +"44": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %0 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 1) + %"36" = extractvalue { i32, i1 } %0, 0 + %"13" = extractvalue { i32, i1 } %0, 1 + store i32 %"36", ptr addrspace(5) %"6", align 4 + store i1 %"13", ptr addrspace(5) %"10", align 1 + %"15" = load i1, ptr addrspace(5) %"10", align 1 + %1 = zext i1 %"15" to i32 + %"37" = sub i32 2, %1 + store i32 %"37", ptr addrspace(5) %"7", align 4 + %2 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 1) + %"38" = extractvalue { i32, i1 } %2, 0 + %"17" = extractvalue { i32, i1 } %2, 1 + store i32 %"38", ptr addrspace(5) %"6", align 4 + store i1 %"17", ptr addrspace(5) %"10", align 1 + %"19" = load i1, ptr addrspace(5) %"9", align 1 + %3 = zext i1 %"19" to i32 + %"39" = add i32 1, %3 + store i32 %"39", ptr addrspace(5) %"8", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i32, ptr addrspace(5) %"7", align 4 + %"40" = inttoptr i64 %"20" to ptr + store i32 %"21", ptr %"40", align 4 + %"22" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = load i32, ptr addrspace(5) %"8", align 4 + %"42" = inttoptr i64 %"22" to ptr + %"46" = getelementptr inbounds i8, ptr %"42", i64 4 + store i32 %"23", ptr %"46", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/carry_mixed.ptx b/ptx/src/test/spirv_run/carry_mixed.ptx new file mode 100644 index 0000000..b4f2caa --- /dev/null +++ b/ptx/src/test/spirv_run/carry_mixed.ptx @@ -0,0 +1,32 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry carry_mixed( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 unused; + + .reg .b32 carry_out_1; + .reg .b32 carry_out_2; + + ld.param.u64 out_addr, [output]; + + // set carry with sub + sub.cc.s32 unused, 0, 1; + // write carry with sub + subc.s32 carry_out_1, 2, 0; + + // set carry with sub + sub.cc.s32 unused, 0, 1; + // fail writing carry with add + addc.s32 carry_out_2, 1, 0; + + st.s32 [out_addr], carry_out_1; + st.s32 [out_addr+4], carry_out_2; + ret; +} diff --git a/ptx/src/test/spirv_run/clz.ll b/ptx/src/test/spirv_run/clz.ll new file mode 100644 index 0000000..356ee7d --- /dev/null +++ b/ptx/src/test/spirv_run/clz.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @clz(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load i32, ptr %"19", align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %0 = call i32 @llvm.ctlz.i32(i32 %"14", i1 false) + store i32 %0, ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store i32 %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.ctlz.i32(i32, i1 immarg) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/clz.spvtxt b/ptx/src/test/spirv_run/clz.spvtxt deleted file mode 100644 index 9a7f254..0000000 --- a/ptx/src/test/spirv_run/clz.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/const.ll b/ptx/src/test/spirv_run/const.ll new file mode 100644 index 0000000..472421d --- /dev/null +++ b/ptx/src/test/spirv_run/const.ll @@ -0,0 +1,52 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@constparams = protected addrspace(4) externally_initialized global [4 x i16] [i16 10, i16 20, i16 30, i16 40], align 8 + +define protected amdgpu_kernel void @const(ptr addrspace(4) byref(i64) %"39", ptr addrspace(4) byref(i64) %"40") #0 { +"53": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i16, align 2, addrspace(5) + %"8" = alloca i16, align 2, addrspace(5) + %"9" = alloca i16, align 2, addrspace(5) + %"10" = alloca i16, align 2, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"39", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(4) %"40", align 8 + store i64 %"14", ptr addrspace(5) %"6", align 8 + %"15" = load i16, ptr addrspace(4) @constparams, align 2 + store i16 %"15", ptr addrspace(5) %"7", align 2 + %"16" = load i16, ptr addrspace(4) getelementptr inbounds (i8, ptr addrspace(4) @constparams, i64 2), align 2 + store i16 %"16", ptr addrspace(5) %"8", align 2 + %"17" = load i16, ptr addrspace(4) getelementptr inbounds (i8, ptr addrspace(4) @constparams, i64 4), align 2 + store i16 %"17", ptr addrspace(5) %"9", align 2 + %"18" = load i16, ptr addrspace(4) getelementptr inbounds (i8, ptr addrspace(4) @constparams, i64 6), align 2 + store i16 %"18", ptr addrspace(5) %"10", align 2 + %"19" = load i64, ptr addrspace(5) %"6", align 8 + %"20" = load i16, ptr addrspace(5) %"7", align 2 + %"45" = inttoptr i64 %"19" to ptr + store i16 %"20", ptr %"45", align 2 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load i16, ptr addrspace(5) %"8", align 2 + %"47" = inttoptr i64 %"21" to ptr + %"61" = getelementptr inbounds i8, ptr %"47", i64 2 + store i16 %"22", ptr %"61", align 2 + %"23" = load i64, ptr addrspace(5) %"6", align 8 + %"24" = load i16, ptr addrspace(5) %"9", align 2 + %"49" = inttoptr i64 %"23" to ptr + %"63" = getelementptr inbounds i8, ptr %"49", i64 4 + store i16 %"24", ptr %"63", align 2 + %"25" = load i64, ptr addrspace(5) %"6", align 8 + %"26" = load i16, ptr addrspace(5) %"10", align 2 + %"51" = inttoptr i64 %"25" to ptr + %"65" = getelementptr inbounds i8, ptr %"51", i64 6 + store i16 %"26", ptr %"65", align 2 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/const.ptx b/ptx/src/test/spirv_run/const.ptx new file mode 100644 index 0000000..90ac09d --- /dev/null +++ b/ptx/src/test/spirv_run/const.ptx @@ -0,0 +1,31 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.const .align 8 .b16 constparams[4] = { 10, 20, 30, 40 }; + +.visible .entry const( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b16 temp1; + .reg .b16 temp2; + .reg .b16 temp3; + .reg .b16 temp4; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.const.b16 temp1, [constparams]; + ld.const.b16 temp2, [constparams+2]; + ld.const.b16 temp3, [constparams+4]; + ld.const.b16 temp4, [constparams+6]; + st.u16 [out_addr], temp1; + st.u16 [out_addr+2], temp2; + st.u16 [out_addr+4], temp3; + st.u16 [out_addr+6], temp4; + ret; +} diff --git a/ptx/src/test/spirv_run/constant_f32.ll b/ptx/src/test/spirv_run/constant_f32.ll new file mode 100644 index 0000000..e918c89 --- /dev/null +++ b/ptx/src/test/spirv_run/constant_f32.ll @@ -0,0 +1,31 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @constant_f32(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"22": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"20", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = fmul float %"14", 5.000000e-01 + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"21" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"21", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/constant_f32.spvtxt b/ptx/src/test/spirv_run/constant_f32.spvtxt deleted file mode 100644 index b331ae6..0000000 --- a/ptx/src/test/spirv_run/constant_f32.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %18 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/constant_negative.ll b/ptx/src/test/spirv_run/constant_negative.ll new file mode 100644 index 0000000..09478b6 --- /dev/null +++ b/ptx/src/test/spirv_run/constant_negative.ll @@ -0,0 +1,31 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @constant_negative(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"22": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"12" to ptr + %"11" = load i32, ptr %"20", align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"13" = mul i32 %"14", -1 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"21" = inttoptr i64 %"15" to ptr + store i32 %"16", ptr %"21", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/constant_negative.spvtxt b/ptx/src/test/spirv_run/constant_negative.spvtxt deleted file mode 100644 index 9a5c7de..0000000 --- a/ptx/src/test/spirv_run/constant_negative.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %18 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cos.ll b/ptx/src/test/spirv_run/cos.ll new file mode 100644 index 0000000..0cf9c30 --- /dev/null +++ b/ptx/src/test/spirv_run/cos.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cos(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"19", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call afn float @llvm.cos.f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.cos.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/cos.spvtxt b/ptx/src/test/spirv_run/cos.spvtxt deleted file mode 100644 index 6fafcb5..0000000 --- a/ptx/src/test/spirv_run/cos.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_clamp.ll b/ptx/src/test/spirv_run/cvt_clamp.ll new file mode 100644 index 0000000..29de682 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_clamp.ll @@ -0,0 +1,73 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare float @__zluda_ptx_impl__cvt_sat_f32_f32(float) #0 + +define protected amdgpu_kernel void @cvt_clamp(ptr addrspace(4) byref(i64) %"47", ptr addrspace(4) byref(i64) %"48") #1 { +"57": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"47", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"48", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"49" = inttoptr i64 %"12" to ptr addrspace(1) + %"11" = load float, ptr addrspace(1) %"49", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call float @__zluda_ptx_impl__cvt_sat_f32_f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"50" = inttoptr i64 %"15" to ptr addrspace(1) + store float %"16", ptr addrspace(1) %"50", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"51" = inttoptr i64 %"18" to ptr addrspace(1) + %"62" = getelementptr inbounds i8, ptr addrspace(1) %"51", i64 4 + %"17" = load float, ptr addrspace(1) %"62", align 4 + store float %"17", ptr addrspace(5) %"6", align 4 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"19" = call float @__zluda_ptx_impl__cvt_sat_f32_f32(float %"20") + store float %"19", ptr addrspace(5) %"6", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load float, ptr addrspace(5) %"6", align 4 + %"52" = inttoptr i64 %"21" to ptr addrspace(1) + %"64" = getelementptr inbounds i8, ptr addrspace(1) %"52", i64 4 + store float %"22", ptr addrspace(1) %"64", align 4 + %"24" = load i64, ptr addrspace(5) %"4", align 8 + %"53" = inttoptr i64 %"24" to ptr addrspace(1) + %"66" = getelementptr inbounds i8, ptr addrspace(1) %"53", i64 8 + %"23" = load float, ptr addrspace(1) %"66", align 4 + store float %"23", ptr addrspace(5) %"6", align 4 + %"26" = load float, ptr addrspace(5) %"6", align 4 + %"25" = call float @__zluda_ptx_impl__cvt_sat_f32_f32(float %"26") + store float %"25", ptr addrspace(5) %"6", align 4 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = load float, ptr addrspace(5) %"6", align 4 + %"54" = inttoptr i64 %"27" to ptr addrspace(1) + %"68" = getelementptr inbounds i8, ptr addrspace(1) %"54", i64 8 + store float %"28", ptr addrspace(1) %"68", align 4 + %"30" = load i64, ptr addrspace(5) %"4", align 8 + %"55" = inttoptr i64 %"30" to ptr addrspace(1) + %"70" = getelementptr inbounds i8, ptr addrspace(1) %"55", i64 12 + %"29" = load float, ptr addrspace(1) %"70", align 4 + store float %"29", ptr addrspace(5) %"6", align 4 + %"32" = load float, ptr addrspace(5) %"6", align 4 + %"31" = call float @__zluda_ptx_impl__cvt_sat_f32_f32(float %"32") + store float %"31", ptr addrspace(5) %"6", align 4 + %"33" = load i64, ptr addrspace(5) %"5", align 8 + %"34" = load float, ptr addrspace(5) %"6", align 4 + %"56" = inttoptr i64 %"33" to ptr addrspace(1) + %"72" = getelementptr inbounds i8, ptr addrspace(1) %"56", i64 12 + store float %"34", ptr addrspace(1) %"72", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_clamp.ptx b/ptx/src/test/spirv_run/cvt_clamp.ptx new file mode 100644 index 0000000..1e68d87 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_clamp.ptx @@ -0,0 +1,30 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_clamp( + .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.global.f32 temp, [in_addr]; + cvt.ftz.sat.f32.f32 temp, temp; + st.global.f32 [out_addr], temp; + ld.global.f32 temp, [in_addr+4]; + cvt.ftz.sat.f32.f32 temp, temp; + st.global.f32 [out_addr+4], temp; + ld.global.f32 temp, [in_addr+8]; + cvt.ftz.sat.f32.f32 temp, temp; + st.global.f32 [out_addr+8], temp; + ld.global.f32 temp, [in_addr+12]; + cvt.ftz.sat.f32.f32 temp, temp; + st.global.f32 [out_addr+12], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/cvt_f32_f16.ll b/ptx/src/test/spirv_run/cvt_f32_f16.ll new file mode 100644 index 0000000..169eb59 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f32_f16.ll @@ -0,0 +1,33 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_f32_f16(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca half, align 2, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr addrspace(1) + %"20" = load i16, ptr addrspace(1) %"21", align 2 + %"12" = bitcast i16 %"20" to half + store half %"12", ptr addrspace(5) %"6", align 2 + %"15" = load half, ptr addrspace(5) %"6", align 2 + %"14" = fpext half %"15" to float + store float %"14", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load float, ptr addrspace(5) %"7", align 4 + %"22" = inttoptr i64 %"16" to ptr + store float %"17", ptr %"22", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_f32_f16.ptx b/ptx/src/test/spirv_run/cvt_f32_f16.ptx new file mode 100644 index 0000000..f55c498 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f32_f16.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_f32_f16( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f16 temp_f16; + .reg .f32 temp_f32; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.b16 temp_f16, [in_addr]; + cvt.f32.f16 temp_f32, temp_f16; + st.f32 [out_addr], temp_f32; + ret; +} diff --git a/ptx/src/test/spirv_run/cvt_f32_s32.ll b/ptx/src/test/spirv_run/cvt_f32_s32.ll new file mode 100644 index 0000000..119d052 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f32_s32.ll @@ -0,0 +1,90 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare float @__zluda_ptx_impl__cvt_rm_f32_s32(i32) #0 + +declare float @__zluda_ptx_impl__cvt_rn_f32_s32(i32) #0 + +declare float @__zluda_ptx_impl__cvt_rp_f32_s32(i32) #0 + +declare float @__zluda_ptx_impl__cvt_rz_f32_s32(i32) #0 + +define protected amdgpu_kernel void @cvt_f32_s32(ptr addrspace(4) byref(i64) %"50", ptr addrspace(4) byref(i64) %"51") #1 { +"76": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"50", align 8 + store i64 %"12", ptr addrspace(5) %"4", align 8 + %"13" = load i64, ptr addrspace(4) %"51", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"53" = inttoptr i64 %"15" to ptr + %"52" = load i32, ptr %"53", align 4 + store i32 %"52", ptr addrspace(5) %"6", align 4 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"54" = inttoptr i64 %"17" to ptr + %"90" = getelementptr inbounds i8, ptr %"54", i64 4 + %"55" = load i32, ptr %"90", align 4 + store i32 %"55", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"56" = inttoptr i64 %"19" to ptr + %"92" = getelementptr inbounds i8, ptr %"56", i64 8 + %"57" = load i32, ptr %"92", align 4 + store i32 %"57", ptr addrspace(5) %"8", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"58" = inttoptr i64 %"21" to ptr + %"94" = getelementptr inbounds i8, ptr %"58", i64 12 + %"59" = load i32, ptr %"94", align 4 + store i32 %"59", ptr addrspace(5) %"9", align 4 + %"23" = load i32, ptr addrspace(5) %"6", align 4 + %"60" = call float @__zluda_ptx_impl__cvt_rn_f32_s32(i32 %"23") + %"22" = bitcast float %"60" to i32 + store i32 %"22", ptr addrspace(5) %"6", align 4 + %"25" = load i32, ptr addrspace(5) %"7", align 4 + %"62" = call float @__zluda_ptx_impl__cvt_rz_f32_s32(i32 %"25") + %"24" = bitcast float %"62" to i32 + store i32 %"24", ptr addrspace(5) %"7", align 4 + %"27" = load i32, ptr addrspace(5) %"8", align 4 + %"64" = call float @__zluda_ptx_impl__cvt_rm_f32_s32(i32 %"27") + %"26" = bitcast float %"64" to i32 + store i32 %"26", ptr addrspace(5) %"8", align 4 + %"29" = load i32, ptr addrspace(5) %"9", align 4 + %"66" = call float @__zluda_ptx_impl__cvt_rp_f32_s32(i32 %"29") + %"28" = bitcast float %"66" to i32 + store i32 %"28", ptr addrspace(5) %"9", align 4 + %"30" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = load i32, ptr addrspace(5) %"6", align 4 + %"68" = inttoptr i64 %"30" to ptr addrspace(1) + %"69" = bitcast i32 %"31" to float + store float %"69", ptr addrspace(1) %"68", align 4 + %"32" = load i64, ptr addrspace(5) %"5", align 8 + %"33" = load i32, ptr addrspace(5) %"7", align 4 + %"70" = inttoptr i64 %"32" to ptr addrspace(1) + %"96" = getelementptr inbounds i8, ptr addrspace(1) %"70", i64 4 + %"71" = bitcast i32 %"33" to float + store float %"71", ptr addrspace(1) %"96", align 4 + %"34" = load i64, ptr addrspace(5) %"5", align 8 + %"35" = load i32, ptr addrspace(5) %"8", align 4 + %"72" = inttoptr i64 %"34" to ptr addrspace(1) + %"98" = getelementptr inbounds i8, ptr addrspace(1) %"72", i64 8 + %"73" = bitcast i32 %"35" to float + store float %"73", ptr addrspace(1) %"98", align 4 + %"36" = load i64, ptr addrspace(5) %"5", align 8 + %"37" = load i32, ptr addrspace(5) %"9", align 4 + %"74" = inttoptr i64 %"36" to ptr addrspace(1) + %"100" = getelementptr inbounds i8, ptr addrspace(1) %"74", i64 12 + %"75" = bitcast i32 %"37" to float + store float %"75", ptr addrspace(1) %"100", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_f32_s32.ptx b/ptx/src/test/spirv_run/cvt_f32_s32.ptx new file mode 100644 index 0000000..0e50a34 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f32_s32.ptx @@ -0,0 +1,33 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_f32_s32( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 temp1; + .reg .b32 temp2; + .reg .b32 temp3; + .reg .b32 temp4; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.s32 temp1, [in_addr]; + ld.s32 temp2, [in_addr+4]; + ld.s32 temp3, [in_addr+8]; + ld.s32 temp4, [in_addr+12]; + cvt.rn.ftz.f32.s32 temp1, temp1; + cvt.rz.ftz.f32.s32 temp2, temp2; + cvt.rm.ftz.f32.s32 temp3, temp3; + cvt.rp.ftz.f32.s32 temp4, temp4; + st.global.f32 [out_addr], temp1; + st.global.f32 [out_addr+4], temp2; + st.global.f32 [out_addr+8], temp3; + st.global.f32 [out_addr+12], temp4; + ret; +} diff --git a/ptx/src/test/spirv_run/cvt_f64_f32.ll b/ptx/src/test/spirv_run/cvt_f64_f32.ll new file mode 100644 index 0000000..f608ed1 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f64_f32.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_f64_f32(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"22": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca double, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr addrspace(1) + %"12" = load float, ptr addrspace(1) %"20", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load float, ptr addrspace(5) %"6", align 4 + %"14" = fpext float %"15" to double + store double %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load double, ptr addrspace(5) %"7", align 8 + %"21" = inttoptr i64 %"16" to ptr + store double %"17", ptr %"21", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_f64_f32.ptx b/ptx/src/test/spirv_run/cvt_f64_f32.ptx new file mode 100644 index 0000000..7aba351 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_f64_f32.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_f64_f32( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 temp_f32; + .reg .f64 temp_f64; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.f32 temp_f32, [in_addr]; + cvt.ftz.f64.f32 temp_f64, temp_f32; + st.f64 [out_addr], temp_f64; + ret; +} diff --git a/ptx/src/test/spirv_run/cvt_rni.ll b/ptx/src/test/spirv_run/cvt_rni.ll new file mode 100644 index 0000000..fa56dfa --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_rni.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_rni(ptr addrspace(4) byref(i64) %"28", ptr addrspace(4) byref(i64) %"29") #0 { +"34": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"30" = inttoptr i64 %"13" to ptr + %"12" = load float, ptr %"30", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"15" to ptr + %"36" = getelementptr inbounds i8, ptr %"31", i64 4 + %"14" = load float, ptr %"36", align 4 + store float %"14", ptr addrspace(5) %"7", align 4 + %"17" = load float, ptr addrspace(5) %"6", align 4 + %"16" = call float @llvm.rint.f32(float %"17") + store float %"16", ptr addrspace(5) %"6", align 4 + %"19" = load float, ptr addrspace(5) %"7", align 4 + %"18" = call float @llvm.rint.f32(float %"19") + store float %"18", ptr addrspace(5) %"7", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load float, ptr addrspace(5) %"6", align 4 + %"32" = inttoptr i64 %"20" to ptr + store float %"21", ptr %"32", align 4 + %"22" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = load float, ptr addrspace(5) %"7", align 4 + %"33" = inttoptr i64 %"22" to ptr + %"38" = getelementptr inbounds i8, ptr %"33", i64 4 + store float %"23", ptr %"38", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.rint.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/cvt_rni.spvtxt b/ptx/src/test/spirv_run/cvt_rni.spvtxt deleted file mode 100644 index 288a939..0000000 --- a/ptx/src/test/spirv_run/cvt_rni.spvtxt +++ /dev/null @@ -1,63 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %28 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %28 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpIAdd %ulong %15 %ulong_4 - %29 = OpConvertUToPtr %_ptr_Generic_float %25 - %14 = OpLoad %float %29 Aligned 4 - 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 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %float %7 - %27 = OpIAdd %ulong %22 %ulong_4_0 - %31 = OpConvertUToPtr %_ptr_Generic_float %27 - OpStore %31 %23 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_rzi.ll b/ptx/src/test/spirv_run/cvt_rzi.ll new file mode 100644 index 0000000..ad4a305 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_rzi.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_rzi(ptr addrspace(4) byref(i64) %"28", ptr addrspace(4) byref(i64) %"29") #0 { +"34": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"30" = inttoptr i64 %"13" to ptr + %"12" = load float, ptr %"30", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"15" to ptr + %"36" = getelementptr inbounds i8, ptr %"31", i64 4 + %"14" = load float, ptr %"36", align 4 + store float %"14", ptr addrspace(5) %"7", align 4 + %"17" = load float, ptr addrspace(5) %"6", align 4 + %"16" = call float @llvm.trunc.f32(float %"17") + store float %"16", ptr addrspace(5) %"6", align 4 + %"19" = load float, ptr addrspace(5) %"7", align 4 + %"18" = call float @llvm.trunc.f32(float %"19") + store float %"18", ptr addrspace(5) %"7", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load float, ptr addrspace(5) %"6", align 4 + %"32" = inttoptr i64 %"20" to ptr + store float %"21", ptr %"32", align 4 + %"22" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = load float, ptr addrspace(5) %"7", align 4 + %"33" = inttoptr i64 %"22" to ptr + %"38" = getelementptr inbounds i8, ptr %"33", i64 4 + store float %"23", ptr %"38", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.trunc.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/cvt_rzi.spvtxt b/ptx/src/test/spirv_run/cvt_rzi.spvtxt deleted file mode 100644 index 68c12c6..0000000 --- a/ptx/src/test/spirv_run/cvt_rzi.spvtxt +++ /dev/null @@ -1,63 +0,0 @@ - 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_rzi" - %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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %28 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %28 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpIAdd %ulong %15 %ulong_4 - %29 = OpConvertUToPtr %_ptr_Generic_float %25 - %14 = OpLoad %float %29 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %16 = OpExtInst %float %34 trunc %17 - OpStore %6 %16 - %19 = OpLoad %float %7 - %18 = OpExtInst %float %34 trunc %19 - OpStore %7 %18 - %20 = OpLoad %ulong %5 - %21 = OpLoad %float %6 - %30 = OpConvertUToPtr %_ptr_Generic_float %20 - OpStore %30 %21 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %float %7 - %27 = OpIAdd %ulong %22 %ulong_4_0 - %31 = OpConvertUToPtr %_ptr_Generic_float %27 - OpStore %31 %23 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_s16_s8.ll b/ptx/src/test/spirv_run/cvt_s16_s8.ll new file mode 100644 index 0000000..dcf4555 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_s16_s8.ll @@ -0,0 +1,34 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_s16_s8(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr addrspace(1) + %"12" = load i32, ptr addrspace(1) %"20", align 4 + store i32 %"12", ptr addrspace(5) %"7", align 4 + %"15" = load i32, ptr addrspace(5) %"7", align 4 + %"26" = trunc i32 %"15" to i8 + %"21" = sext i8 %"26" to i16 + %"14" = sext i16 %"21" to i32 + store i32 %"14", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"23" = inttoptr i64 %"16" to ptr + store i32 %"17", ptr %"23", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_s16_s8.ptx b/ptx/src/test/spirv_run/cvt_s16_s8.ptx new file mode 100644 index 0000000..44c0891 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_s16_s8.ptx @@ -0,0 +1,26 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_s16_s8( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 temp_16; + .reg .b32 temp_8; + + // inline asm + /*ptx_texBake_end*/ + // inline asm + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.b32 temp_8, [in_addr]; + cvt.s16.s8 temp_16, temp_8; + st.b32 [out_addr], temp_16; + ret; +} diff --git a/ptx/src/test/spirv_run/cvt_s32_f32.ll b/ptx/src/test/spirv_run/cvt_s32_f32.ll new file mode 100644 index 0000000..b8f8b2b --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_s32_f32.ll @@ -0,0 +1,52 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__cvt_rp_s32_f32(float) #0 + +define protected amdgpu_kernel void @cvt_s32_f32(ptr addrspace(4) byref(i64) %"28", ptr addrspace(4) byref(i64) %"29") #1 { +"42": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"13" to ptr + %"30" = load float, ptr %"31", align 4 + %"12" = bitcast float %"30" to i32 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"15" to ptr + %"47" = getelementptr inbounds i8, ptr %"32", i64 4 + %"33" = load float, ptr %"47", align 4 + %"14" = bitcast float %"33" to i32 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"35" = bitcast i32 %"17" to float + %"34" = call i32 @__zluda_ptx_impl__cvt_rp_s32_f32(float %"35") + store i32 %"34", ptr addrspace(5) %"6", align 4 + %"19" = load i32, ptr addrspace(5) %"7", align 4 + %"37" = bitcast i32 %"19" to float + %"36" = call i32 @__zluda_ptx_impl__cvt_rp_s32_f32(float %"37") + store i32 %"36", ptr addrspace(5) %"7", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i32, ptr addrspace(5) %"6", align 4 + %"38" = inttoptr i64 %"20" to ptr addrspace(1) + store i32 %"21", ptr addrspace(1) %"38", align 4 + %"22" = load i64, ptr addrspace(5) %"5", align 8 + %"23" = load i32, ptr addrspace(5) %"7", align 4 + %"40" = inttoptr i64 %"22" to ptr addrspace(1) + %"49" = getelementptr inbounds i8, ptr addrspace(1) %"40", i64 4 + store i32 %"23", ptr addrspace(1) %"49", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt b/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt deleted file mode 100644 index d9ae053..0000000 --- a/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt +++ /dev/null @@ -1,75 +0,0 @@ - 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 "cvt_s32_f32" - OpDecorate %32 FPRoundingMode RTP - OpDecorate %34 FPRoundingMode RTP - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %float = OpTypeFloat 32 -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %ulong_4_0 = OpConstant %ulong 4 - %1 = OpFunction %void None %45 - %8 = OpFunctionParameter %ulong - %9 = 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_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %13 - %28 = OpLoad %float %29 Aligned 4 - %12 = OpBitcast %uint %28 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpIAdd %ulong %15 %ulong_4 - %31 = OpConvertUToPtr %_ptr_Generic_float %25 - %30 = OpLoad %float %31 Aligned 4 - %14 = OpBitcast %uint %30 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %33 = OpBitcast %float %17 - %32 = OpConvertFToS %uint %33 - %16 = OpCopyObject %uint %32 - OpStore %6 %16 - %19 = OpLoad %uint %7 - %35 = OpBitcast %float %19 - %34 = OpConvertFToS %uint %35 - %18 = OpCopyObject %uint %34 - OpStore %7 %18 - %20 = OpLoad %ulong %5 - %21 = OpLoad %uint %6 - %36 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %20 - %37 = OpCopyObject %uint %21 - OpStore %36 %37 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %uint %7 - %27 = OpIAdd %ulong %22 %ulong_4_0 - %38 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %27 - %39 = OpCopyObject %uint %23 - OpStore %38 %39 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_s64_s32.ll b/ptx/src/test/spirv_run/cvt_s64_s32.ll new file mode 100644 index 0000000..a272a4c --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_s64_s32.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_s64_s32(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"20" = load i32, ptr %"21", align 4 + store i32 %"20", ptr addrspace(5) %"6", align 4 + %"15" = load i32, ptr addrspace(5) %"6", align 4 + %"14" = sext i32 %"15" to i64 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt b/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt deleted file mode 100644 index 3f46103..0000000 --- a/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt +++ /dev/null @@ -1,53 +0,0 @@ - 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 "cvt_s64_s32" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = 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 -%_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_uint Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_uint %13 - %18 = OpLoad %uint %19 Aligned 4 - %12 = OpCopyObject %uint %18 - OpStore %6 %12 - %15 = OpLoad %uint %6 - %32 = OpBitcast %uint %15 - %33 = OpSConvert %ulong %32 - %14 = OpCopyObject %ulong %33 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - %21 = OpCopyObject %ulong %17 - OpStore %20 %21 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_sat_s_u.ll b/ptx/src/test/spirv_run/cvt_sat_s_u.ll new file mode 100644 index 0000000..946ece1 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_sat_s_u.ll @@ -0,0 +1,55 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_sat_s_u(ptr addrspace(4) byref(i64) %"27", ptr addrspace(4) byref(i64) %"28") #0 { +"35": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"27", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"29" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"29", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %0 = call i32 @llvm.smax.i32(i32 %"16", i32 0) + %1 = alloca i32, align 4, addrspace(5) + store i32 %0, ptr addrspace(5) %1, align 4 + %"15" = load i32, ptr addrspace(5) %1, align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %2 = alloca i32, align 4, addrspace(5) + store i32 %"18", ptr addrspace(5) %2, align 4 + %"30" = load i32, ptr addrspace(5) %2, align 4 + store i32 %"30", ptr addrspace(5) %"7", align 4 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %3 = alloca i32, align 4, addrspace(5) + store i32 %"20", ptr addrspace(5) %3, align 4 + %"31" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"31", ptr addrspace(5) %"8", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load i32, ptr addrspace(5) %"7", align 4 + %"32" = inttoptr i64 %"21" to ptr + store i32 %"22", ptr %"32", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load i32, ptr addrspace(5) %"8", align 4 + %"34" = inttoptr i64 %"23" to ptr + %"37" = getelementptr inbounds i8, ptr %"34", i64 4 + store i32 %"24", ptr %"37", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smax.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/cvt_sat_s_u.ptx b/ptx/src/test/spirv_run/cvt_sat_s_u.ptx index ef0a10f..2c2ed43 100644 --- a/ptx/src/test/spirv_run/cvt_sat_s_u.ptx +++ b/ptx/src/test/spirv_run/cvt_sat_s_u.ptx @@ -9,16 +9,18 @@ { .reg .u64 in_addr; .reg .u64 out_addr; - .reg .s32 temp; - .reg .u32 temp2; - .reg .s32 temp3; + .reg .s32 input_value; + .reg .u32 temp1; + .reg .s32 temp2; 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; + ld.s32 input_value, [in_addr]; + cvt.sat.u32.s32 temp1, input_value; + cvt.s32.u32 temp1, temp1; + cvt.u32.s32 temp2, input_value; + st.s32 [out_addr], temp1; + st.s32 [out_addr+4], temp2; 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 deleted file mode 100644 index b676049..0000000 --- a/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %21 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %21 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_u32_s16.ll b/ptx/src/test/spirv_run/cvt_u32_s16.ll new file mode 100644 index 0000000..7ab8366 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_u32_s16.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvt_u32_s16(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i16, align 2, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr addrspace(1) + %"12" = load i16, ptr addrspace(1) %"20", align 2 + store i16 %"12", ptr addrspace(5) %"6", align 2 + %"15" = load i16, ptr addrspace(5) %"6", align 2 + %"21" = sext i16 %"15" to i32 + store i32 %"21", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i32, ptr addrspace(5) %"7", align 4 + %"23" = inttoptr i64 %"16" to ptr + store i32 %"17", ptr %"23", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvt_u32_s16.ptx b/ptx/src/test/spirv_run/cvt_u32_s16.ptx new file mode 100644 index 0000000..a89c480 --- /dev/null +++ b/ptx/src/test/spirv_run/cvt_u32_s16.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry cvt_u32_s16( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b16 temp_16; + .reg .b32 temp_32; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.global.b16 temp_16, [in_addr]; + cvt.u32.s16 temp_32, temp_16; + st.b32 [out_addr], temp_32; + ret; +} diff --git a/ptx/src/test/spirv_run/cvta.ll b/ptx/src/test/spirv_run/cvta.ll new file mode 100644 index 0000000..8cba990 --- /dev/null +++ b/ptx/src/test/spirv_run/cvta.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @cvta(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"27": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %0 = inttoptr i64 %"12" to ptr + %1 = addrspacecast ptr %0 to ptr addrspace(1) + %"21" = ptrtoint ptr addrspace(1) %1 to i64 + store i64 %"21", ptr addrspace(5) %"4", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %2 = inttoptr i64 %"14" to ptr + %3 = addrspacecast ptr %2 to ptr addrspace(1) + %"23" = ptrtoint ptr addrspace(1) %3 to i64 + store i64 %"23", ptr addrspace(5) %"5", align 8 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"16" to ptr addrspace(1) + %"15" = load float, ptr addrspace(1) %"25", align 4 + store float %"15", ptr addrspace(5) %"6", align 4 + %"17" = load i64, ptr addrspace(5) %"5", align 8 + %"18" = load float, ptr addrspace(5) %"6", align 4 + %"26" = inttoptr i64 %"17" to ptr addrspace(1) + store float %"18", ptr addrspace(1) %"26", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/cvta.spvtxt b/ptx/src/test/spirv_run/cvta.spvtxt deleted file mode 100644 index e7a5655..0000000 --- a/ptx/src/test/spirv_run/cvta.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - 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 Aligned 8 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %9 - OpStore %7 %19 - %12 = OpBitcast %_ptr_Function_ulong %3 - %11 = OpLoad %ulong %12 Aligned 8 - %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 Aligned 4 - OpStore %6 %25 - %27 = OpLoad %_ptr_CrossWorkgroup_uchar %8 - %28 = OpLoad %float %6 - %34 = OpBitcast %_ptr_CrossWorkgroup_float %27 - OpStore %34 %28 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/div_approx.ll b/ptx/src/test/spirv_run/div_approx.ll new file mode 100644 index 0000000..91b3fb7 --- /dev/null +++ b/ptx/src/test/spirv_run/div_approx.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @div_approx(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load float, ptr %"25", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load float, ptr %"30", align 4 + store float %"14", ptr addrspace(5) %"7", align 4 + %"17" = load float, ptr addrspace(5) %"6", align 4 + %"18" = load float, ptr addrspace(5) %"7", align 4 + %"16" = fdiv arcp afn float %"17", %"18" + store float %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store float %"20", ptr %"27", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/div_approx.spvtxt b/ptx/src/test/spirv_run/div_approx.spvtxt deleted file mode 100644 index 274f73e..0000000 --- a/ptx/src/test/spirv_run/div_approx.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_float %22 - %14 = OpLoad %float %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/dp4a.ll b/ptx/src/test/spirv_run/dp4a.ll new file mode 100644 index 0000000..f55aa62 --- /dev/null +++ b/ptx/src/test/spirv_run/dp4a.ll @@ -0,0 +1,48 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__dp4a_s32_s32(i32, i32, i32) #0 + +define protected amdgpu_kernel void @dp4a(ptr addrspace(4) byref(i64) %"29", ptr addrspace(4) byref(i64) %"30") #1 { +"39": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"31", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"16" to ptr + %"46" = getelementptr inbounds i8, ptr %"32", i64 4 + %"15" = load i32, ptr %"46", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"33" = inttoptr i64 %"18" to ptr + %"48" = getelementptr inbounds i8, ptr %"33", i64 8 + %"17" = load i32, ptr %"48", align 4 + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"21" = load i32, ptr addrspace(5) %"7", align 4 + %"22" = load i32, ptr addrspace(5) %"8", align 4 + %"34" = call i32 @__zluda_ptx_impl__dp4a_s32_s32(i32 %"20", i32 %"21", i32 %"22") + store i32 %"34", ptr addrspace(5) %"6", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load i32, ptr addrspace(5) %"6", align 4 + %"38" = inttoptr i64 %"23" to ptr + store i32 %"24", ptr %"38", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/dp4a.ptx b/ptx/src/test/spirv_run/dp4a.ptx new file mode 100644 index 0000000..d1478d9 --- /dev/null +++ b/ptx/src/test/spirv_run/dp4a.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_61 +.address_size 64 + +.entry dp4a( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 temp0; + .reg .b32 temp1; + .reg .b32 temp2; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.b32 temp0, [in_addr]; + ld.b32 temp1, [in_addr+4]; + ld.b32 temp2, [in_addr+8]; + dp4a.s32.s32 temp0, temp0, temp1, temp2; + st.b32 [out_addr], temp0; + ret; +} diff --git a/ptx/src/test/spirv_run/ex2.ll b/ptx/src/test/spirv_run/ex2.ll new file mode 100644 index 0000000..8e13d43 --- /dev/null +++ b/ptx/src/test/spirv_run/ex2.ll @@ -0,0 +1,74 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @ex2(ptr addrspace(4) byref(i64) %"47", ptr addrspace(4) byref(i64) %"48") #0 { +"57": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"47", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"48", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"49" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"49", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call afn float @llvm.exp2.f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"50" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"50", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"51" = inttoptr i64 %"18" to ptr + %"59" = getelementptr inbounds i8, ptr %"51", i64 4 + %"17" = load float, ptr %"59", align 4 + store float %"17", ptr addrspace(5) %"6", align 4 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"19" = call afn float @llvm.exp2.f32(float %"20") + store float %"19", ptr addrspace(5) %"6", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load float, ptr addrspace(5) %"6", align 4 + %"52" = inttoptr i64 %"21" to ptr + %"61" = getelementptr inbounds i8, ptr %"52", i64 4 + store float %"22", ptr %"61", align 4 + %"24" = load i64, ptr addrspace(5) %"4", align 8 + %"53" = inttoptr i64 %"24" to ptr + %"63" = getelementptr inbounds i8, ptr %"53", i64 8 + %"23" = load float, ptr %"63", align 4 + store float %"23", ptr addrspace(5) %"6", align 4 + %"26" = load float, ptr addrspace(5) %"6", align 4 + %"25" = call afn float @llvm.exp2.f32(float %"26") + store float %"25", ptr addrspace(5) %"6", align 4 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = load float, ptr addrspace(5) %"6", align 4 + %"54" = inttoptr i64 %"27" to ptr + %"65" = getelementptr inbounds i8, ptr %"54", i64 8 + store float %"28", ptr %"65", align 4 + %"30" = load i64, ptr addrspace(5) %"4", align 8 + %"55" = inttoptr i64 %"30" to ptr + %"67" = getelementptr inbounds i8, ptr %"55", i64 12 + %"29" = load float, ptr %"67", align 4 + store float %"29", ptr addrspace(5) %"6", align 4 + %"32" = load float, ptr addrspace(5) %"6", align 4 + %"31" = call afn float @llvm.exp2.f32(float %"32") + store float %"31", ptr addrspace(5) %"6", align 4 + %"33" = load i64, ptr addrspace(5) %"5", align 8 + %"34" = load float, ptr addrspace(5) %"6", align 4 + %"56" = inttoptr i64 %"33" to ptr + %"69" = getelementptr inbounds i8, ptr %"56", i64 12 + store float %"34", ptr %"69", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.exp2.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/ex2.ptx b/ptx/src/test/spirv_run/ex2.ptx index 1edbcc6..0670497 100644 --- a/ptx/src/test/spirv_run/ex2.ptx +++ b/ptx/src/test/spirv_run/ex2.ptx @@ -17,5 +17,15 @@ ld.f32 temp, [in_addr]; ex2.approx.f32 temp, temp; st.f32 [out_addr], temp; + ld.f32 temp, [in_addr+4]; + ex2.approx.f32 temp, temp; + st.f32 [out_addr+4], temp; + ld.f32 temp, [in_addr+8]; + ex2.approx.f32 temp, temp; + st.f32 [out_addr+8], temp; + ld.f32 temp, [in_addr+12]; + ex2.approx.f32 temp, temp; + st.f32 [out_addr+12], temp; + ret; } diff --git a/ptx/src/test/spirv_run/ex2.spvtxt b/ptx/src/test/spirv_run/ex2.spvtxt deleted file mode 100644 index 62c44b8..0000000 --- a/ptx/src/test/spirv_run/ex2.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/extern_shared.ll b/ptx/src/test/spirv_run/extern_shared.ll new file mode 100644 index 0000000..34f1d33 --- /dev/null +++ b/ptx/src/test/spirv_run/extern_shared.ll @@ -0,0 +1,34 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_mem = external hidden addrspace(3) global [0 x i32] + +define protected amdgpu_kernel void @extern_shared(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = inttoptr i64 %"13" to ptr addrspace(1) + %"12" = load i64, ptr addrspace(1) %"20", align 8 + store i64 %"12", ptr addrspace(5) %"7", align 8 + %"14" = load i64, ptr addrspace(5) %"7", align 8 + store i64 %"14", ptr addrspace(3) @shared_mem, align 8 + %"15" = load i64, ptr addrspace(3) @shared_mem, align 8 + store i64 %"15", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"6", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"23" = inttoptr i64 %"16" to ptr addrspace(1) + store i64 %"17", ptr addrspace(1) %"23", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/extern_shared.spvtxt b/ptx/src/test/spirv_run/extern_shared.spvtxt deleted file mode 100644 index fb2987e..0000000 --- a/ptx/src/test/spirv_run/extern_shared.spvtxt +++ /dev/null @@ -1,66 +0,0 @@ - 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 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %4 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %20 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13 - %12 = OpLoad %ulong %20 Aligned 8 - 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 Aligned 8 - %29 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %27 - %17 = OpLoad %_ptr_Workgroup_uint %29 - %22 = OpBitcast %_ptr_Workgroup_ulong %17 - %16 = OpLoad %ulong %22 Aligned 8 - OpStore %7 %16 - %18 = OpLoad %ulong %6 - %19 = OpLoad %ulong %7 - %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %18 - OpStore %23 %19 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/extern_shared_call.ll b/ptx/src/test/spirv_run/extern_shared_call.ll new file mode 100644 index 0000000..241053f --- /dev/null +++ b/ptx/src/test/spirv_run/extern_shared_call.ll @@ -0,0 +1,52 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_mem = external hidden addrspace(3) global [0 x i32], align 4 + +define private void @"2"(ptr addrspace(3) %"37") #0 { +"35": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"3" = alloca i64, align 8, addrspace(5) + %"14" = load i64, ptr addrspace(3) %"37", align 8 + store i64 %"14", ptr addrspace(5) %"3", align 8 + %"16" = load i64, ptr addrspace(5) %"3", align 8 + %"15" = add i64 %"16", 2 + store i64 %"15", ptr addrspace(5) %"3", align 8 + %"17" = load i64, ptr addrspace(5) %"3", align 8 + store i64 %"17", ptr addrspace(3) %"37", align 8 + ret void +} + +define protected amdgpu_kernel void @extern_shared_call(ptr addrspace(4) byref(i64) %"27", ptr addrspace(4) byref(i64) %"28") #0 { +"36": + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"18" = load i64, ptr addrspace(4) %"27", align 8 + store i64 %"18", ptr addrspace(5) %"7", align 8 + %"19" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"19", ptr addrspace(5) %"8", align 8 + %"21" = load i64, ptr addrspace(5) %"7", align 8 + %"31" = inttoptr i64 %"21" to ptr addrspace(1) + %"20" = load i64, ptr addrspace(1) %"31", align 8 + store i64 %"20", ptr addrspace(5) %"9", align 8 + %"22" = load i64, ptr addrspace(5) %"9", align 8 + store i64 %"22", ptr addrspace(3) @shared_mem, align 8 + call void @"2"(ptr addrspace(3) @shared_mem) + %"23" = load i64, ptr addrspace(3) @shared_mem, align 8 + store i64 %"23", ptr addrspace(5) %"9", align 8 + %"24" = load i64, ptr addrspace(5) %"8", align 8 + %"25" = load i64, ptr addrspace(5) %"9", align 8 + %"34" = inttoptr i64 %"24" to ptr addrspace(1) + store i64 %"25", ptr addrspace(1) %"34", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/extern_shared_call.spvtxt b/ptx/src/test/spirv_run/extern_shared_call.spvtxt deleted file mode 100644 index 7043172..0000000 --- a/ptx/src/test/spirv_run/extern_shared_call.spvtxt +++ /dev/null @@ -1,93 +0,0 @@ - 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 Aligned 8 - 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 Aligned 8 - 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 Aligned 8 - OpStore %17 %22 - %23 = OpLoad %ulong %16 Aligned 8 - OpStore %18 %23 - %25 = OpLoad %ulong %17 - %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %25 - %24 = OpLoad %ulong %32 Aligned 8 - 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 Aligned 8 - %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 Aligned 8 - OpStore %19 %28 - %30 = OpLoad %ulong %18 - %31 = OpLoad %ulong %19 - %35 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %30 - OpStore %35 %31 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/fma.ll b/ptx/src/test/spirv_run/fma.ll new file mode 100644 index 0000000..d518432 --- /dev/null +++ b/ptx/src/test/spirv_run/fma.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @fma(ptr addrspace(4) byref(i64) %"29", ptr addrspace(4) byref(i64) %"30") #0 { +"35": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"14" to ptr + %"13" = load float, ptr %"31", align 4 + store float %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"32" = inttoptr i64 %"16" to ptr + %"37" = getelementptr inbounds i8, ptr %"32", i64 4 + %"15" = load float, ptr %"37", align 4 + store float %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"33" = inttoptr i64 %"18" to ptr + %"39" = getelementptr inbounds i8, ptr %"33", i64 8 + %"17" = load float, ptr %"39", align 4 + store float %"17", ptr addrspace(5) %"8", align 4 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"21" = load float, ptr addrspace(5) %"7", align 4 + %"22" = load float, ptr addrspace(5) %"8", align 4 + %"19" = call float @llvm.fma.f32(float %"20", float %"21", float %"22") + store float %"19", ptr addrspace(5) %"6", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load float, ptr addrspace(5) %"6", align 4 + %"34" = inttoptr i64 %"23" to ptr + store float %"24", ptr %"34", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.fma.f32(float, float, float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/fma.spvtxt b/ptx/src/test/spirv_run/fma.spvtxt deleted file mode 100644 index 300a328..0000000 --- a/ptx/src/test/spirv_run/fma.spvtxt +++ /dev/null @@ -1,63 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %14 - %13 = OpLoad %float %29 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %26 = OpIAdd %ulong %16 %ulong_4 - %30 = OpConvertUToPtr %_ptr_Generic_float %26 - %15 = OpLoad %float %30 Aligned 4 - OpStore %7 %15 - %18 = OpLoad %ulong %4 - %28 = OpIAdd %ulong %18 %ulong_8 - %31 = OpConvertUToPtr %_ptr_Generic_float %28 - %17 = OpLoad %float %31 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/func_ptr.ll b/ptx/src/test/spirv_run/func_ptr.ll new file mode 100644 index 0000000..b7c0603 --- /dev/null +++ b/ptx/src/test/spirv_run/func_ptr.ll @@ -0,0 +1,57 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define private float @"1"(float %"17", float %"18") #0 { +"40": + %"3" = alloca float, align 4, addrspace(5) + %"4" = alloca float, align 4, addrspace(5) + %"2" = alloca float, align 4, addrspace(5) + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + store float %"17", ptr addrspace(5) %"3", align 4 + store float %"18", ptr addrspace(5) %"4", align 4 + %"20" = load float, ptr addrspace(5) %"3", align 4 + %"21" = load float, ptr addrspace(5) %"4", align 4 + %"19" = fadd float %"20", %"21" + store float %"19", ptr addrspace(5) %"2", align 4 + %"22" = load float, ptr addrspace(5) %"2", align 4 + ret float %"22" +} + +define protected amdgpu_kernel void @func_ptr(ptr addrspace(4) byref(i64) %"36", ptr addrspace(4) byref(i64) %"37") #0 { +"41": + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"16" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"16", align 1 + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"11" = alloca i64, align 8, addrspace(5) + %"12" = alloca i64, align 8, addrspace(5) + %"23" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"23", ptr addrspace(5) %"8", align 8 + %"24" = load i64, ptr addrspace(4) %"37", align 8 + store i64 %"24", ptr addrspace(5) %"9", align 8 + %"26" = load i64, ptr addrspace(5) %"8", align 8 + %"38" = inttoptr i64 %"26" to ptr + %"25" = load i64, ptr %"38", align 8 + store i64 %"25", ptr addrspace(5) %"10", align 8 + %"28" = load i64, ptr addrspace(5) %"10", align 8 + %"27" = add i64 %"28", 1 + store i64 %"27", ptr addrspace(5) %"11", align 8 + store i64 ptrtoint (ptr @"1" to i64), ptr addrspace(5) %"12", align 8 + %"31" = load i64, ptr addrspace(5) %"11", align 8 + %"32" = load i64, ptr addrspace(5) %"12", align 8 + %"30" = add i64 %"31", %"32" + store i64 %"30", ptr addrspace(5) %"11", align 8 + %"33" = load i64, ptr addrspace(5) %"9", align 8 + %"34" = load i64, ptr addrspace(5) %"11", align 8 + %"39" = inttoptr i64 %"33" to ptr + store i64 %"34", ptr %"39", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/func_ptr.ptx b/ptx/src/test/spirv_run/func_ptr.ptx new file mode 100644 index 0000000..aa94f2b --- /dev/null +++ b/ptx/src/test/spirv_run/func_ptr.ptx @@ -0,0 +1,31 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.func (.reg .f32 out) foobar(.reg .f32 x, .reg .f32 y) +{ + add.f32 out, x, y; + ret; +} + +.visible .entry func_ptr( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + .reg .u64 f_addr; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u64 temp, [in_addr]; + add.u64 temp2, temp, 1; + mov.u64 f_addr, foobar; + add.u64 temp2, temp2, f_addr; + st.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/generic.ll b/ptx/src/test/spirv_run/generic.ll new file mode 100644 index 0000000..d746a22 --- /dev/null +++ b/ptx/src/test/spirv_run/generic.ll @@ -0,0 +1,70 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@foo = protected addrspace(1) externally_initialized global [4 x i32] [i32 2, i32 3, i32 5, i32 7] +@bar = protected addrspace(1) externally_initialized global [4 x i64] [i64 ptrtoint (ptr addrspacecast (ptr addrspace(1) @foo to ptr) to i64), i64 add (i64 ptrtoint (ptr addrspacecast (ptr addrspace(1) @foo to ptr) to i64), i64 4), i64 add (i64 ptrtoint (ptr addrspacecast (ptr addrspace(1) @foo to ptr) to i64), i64 8), i64 add (i64 ptrtoint (ptr addrspacecast (ptr addrspace(1) @foo to ptr) to i64), i64 12)] + +define protected amdgpu_kernel void @generic(ptr addrspace(4) byref(i64) %"47", ptr addrspace(4) byref(i64) %"48") #0 { +"58": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"48", align 8 + store i64 %"12", ptr addrspace(5) %"7", align 8 + %0 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %0, align 4 + %"13" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"13", ptr addrspace(5) %"8", align 4 + %"14" = load i64, ptr addrspace(1) @bar, align 8 + store i64 %"14", ptr addrspace(5) %"6", align 8 + %"16" = load i64, ptr addrspace(5) %"6", align 8 + %"50" = inttoptr i64 %"16" to ptr + %"15" = load i32, ptr %"50", align 4 + store i32 %"15", ptr addrspace(5) %"9", align 4 + %"18" = load i32, ptr addrspace(5) %"8", align 4 + %"19" = load i32, ptr addrspace(5) %"9", align 4 + %"17" = mul i32 %"18", %"19" + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"20" = load i64, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @bar, i64 8), align 8 + store i64 %"20", ptr addrspace(5) %"6", align 8 + %"22" = load i64, ptr addrspace(5) %"6", align 8 + %"52" = inttoptr i64 %"22" to ptr + %"21" = load i32, ptr %"52", align 4 + store i32 %"21", ptr addrspace(5) %"9", align 4 + %"24" = load i32, ptr addrspace(5) %"8", align 4 + %"25" = load i32, ptr addrspace(5) %"9", align 4 + %"23" = mul i32 %"24", %"25" + store i32 %"23", ptr addrspace(5) %"8", align 4 + %"26" = load i64, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @bar, i64 16), align 8 + store i64 %"26", ptr addrspace(5) %"6", align 8 + %"28" = load i64, ptr addrspace(5) %"6", align 8 + %"54" = inttoptr i64 %"28" to ptr + %"27" = load i32, ptr %"54", align 4 + store i32 %"27", ptr addrspace(5) %"9", align 4 + %"30" = load i32, ptr addrspace(5) %"8", align 4 + %"31" = load i32, ptr addrspace(5) %"9", align 4 + %"29" = mul i32 %"30", %"31" + store i32 %"29", ptr addrspace(5) %"8", align 4 + %"32" = load i64, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @bar, i64 24), align 8 + store i64 %"32", ptr addrspace(5) %"6", align 8 + %"34" = load i64, ptr addrspace(5) %"6", align 8 + %"56" = inttoptr i64 %"34" to ptr + %"33" = load i32, ptr %"56", align 4 + store i32 %"33", ptr addrspace(5) %"9", align 4 + %"36" = load i32, ptr addrspace(5) %"8", align 4 + %"37" = load i32, ptr addrspace(5) %"9", align 4 + %"35" = mul i32 %"36", %"37" + store i32 %"35", ptr addrspace(5) %"8", align 4 + %"38" = load i64, ptr addrspace(5) %"7", align 8 + %"39" = load i32, ptr addrspace(5) %"8", align 4 + %"57" = inttoptr i64 %"38" to ptr + store i32 %"39", ptr %"57", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/generic.ptx b/ptx/src/test/spirv_run/generic.ptx new file mode 100644 index 0000000..1174c57 --- /dev/null +++ b/ptx/src/test/spirv_run/generic.ptx @@ -0,0 +1,40 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .u32 foo[4] = { 2,3,5,7 }; +.global .u64 bar[4] = { generic(foo), generic(foo)+4, generic(foo)+8, generic(foo)+12 }; + +.visible .entry generic( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp32_1; + .reg .u32 temp32_2; + + ld.param.u64 out_addr, [output]; + + mov.u32 temp32_1, 1; + + ld.global.u64 in_addr, [bar]; + ld.u32 temp32_2, [in_addr]; + mul.lo.u32 temp32_1, temp32_1, temp32_2; + + ld.global.u64 in_addr, [bar+8]; + ld.u32 temp32_2, [in_addr]; + mul.lo.u32 temp32_1, temp32_1, temp32_2; + + ld.global.u64 in_addr, [bar+16]; + ld.u32 temp32_2, [in_addr]; + mul.lo.u32 temp32_1, temp32_1, temp32_2; + + ld.global.u64 in_addr, [bar+24]; + ld.u32 temp32_2, [in_addr]; + mul.lo.u32 temp32_1, temp32_1, temp32_2; + + st.u32 [out_addr], temp32_1; + ret; +} diff --git a/ptx/src/test/spirv_run/global_array.ll b/ptx/src/test/spirv_run/global_array.ll new file mode 100644 index 0000000..3a8da01 --- /dev/null +++ b/ptx/src/test/spirv_run/global_array.ll @@ -0,0 +1,33 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@asdas = protected addrspace(1) externally_initialized global [4 x [2 x i32]] [[2 x i32] [i32 -1, i32 2], [2 x i32] [i32 3, i32 0], [2 x i32] zeroinitializer, [2 x i32] zeroinitializer] +@foobar = protected addrspace(1) externally_initialized global [4 x [2 x i64]] [[2 x i64] [i64 -1, i64 2], [2 x i64] [i64 3, i64 0], [2 x i64] [i64 ptrtoint (ptr addrspace(1) @asdas to i64), i64 0], [2 x i64] zeroinitializer] + +define protected amdgpu_kernel void @global_array(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"22": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %0 = alloca i64, align 8, addrspace(5) + store i64 ptrtoint (ptr addrspace(1) @foobar to i64), ptr addrspace(5) %0, align 8 + %"11" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"12" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"12", ptr addrspace(5) %"7", align 8 + %"14" = load i64, ptr addrspace(5) %"6", align 8 + %"20" = inttoptr i64 %"14" to ptr addrspace(1) + %"13" = load i32, ptr addrspace(1) %"20", align 4 + store i32 %"13", ptr addrspace(5) %"8", align 4 + %"15" = load i64, ptr addrspace(5) %"7", align 8 + %"16" = load i32, ptr addrspace(5) %"8", align 4 + %"21" = inttoptr i64 %"15" to ptr addrspace(1) + store i32 %"16", ptr addrspace(1) %"21", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/global_array.ptx b/ptx/src/test/spirv_run/global_array.ptx index 7ac8bce..90c4968 100644 --- a/ptx/src/test/spirv_run/global_array.ptx +++ b/ptx/src/test/spirv_run/global_array.ptx @@ -2,7 +2,8 @@ .target sm_30 .address_size 64 -.global .s32 foobar[4] = {1}; +.global .u32 asdas[4][2] = {{-1,2}, {3}}; +.global .u64 foobar[4][2] = {{-1,2}, {3}, {asdas}}; .visible .entry global_array( .param .u64 input, diff --git a/ptx/src/test/spirv_run/global_array.spvtxt b/ptx/src/test/spirv_run/global_array.spvtxt deleted file mode 100644 index 4eccb2f..0000000 --- a/ptx/src/test/spirv_run/global_array.spvtxt +++ /dev/null @@ -1,53 +0,0 @@ - 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 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %17 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %13 - %12 = OpLoad %uint %17 Aligned 4 - OpStore %7 %12 - %14 = OpLoad %ulong %6 - %15 = OpLoad %uint %7 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14 - OpStore %18 %15 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/implicit_param.ll b/ptx/src/test/spirv_run/implicit_param.ll new file mode 100644 index 0000000..09fa3e9 --- /dev/null +++ b/ptx/src/test/spirv_run/implicit_param.ll @@ -0,0 +1,55 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-ni:7" +target triple = "amdgcn-amd-amdhsa" + +; Function Attrs: nounwind +define amdgpu_kernel void @implicit_param(i64 %0, i64 %1) #0 !kernel_arg_addr_space !6 !kernel_arg_access_qual !7 !kernel_arg_type !8 !kernel_arg_type_qual !9 !kernel_arg_base_type !8 { + %3 = alloca i64, align 8, addrspace(5) + %4 = alloca i64, align 8, addrspace(5) + %5 = alloca i64, align 8, addrspace(5) + %6 = alloca i64, align 8, addrspace(5) + %7 = alloca float, align 4, addrspace(5) + %8 = alloca i32, align 4, addrspace(5) + store i64 %0, i64 addrspace(5)* %3, align 8 + store i64 %1, i64 addrspace(5)* %4, align 8 + %9 = load i64, i64 addrspace(5)* %3, align 8 + store i64 %9, i64 addrspace(5)* %5, align 8 + %10 = load i64, i64 addrspace(5)* %4, align 8 + store i64 %10, i64 addrspace(5)* %6, align 8 + %11 = load i64, i64 addrspace(5)* %5, align 8 + %12 = inttoptr i64 %11 to float addrspace(1)* + %13 = load float, float addrspace(1)* %12, align 4 + store float %13, float addrspace(5)* %7, align 4 + %14 = load float, float addrspace(5)* %7, align 4 + %15 = bitcast i32 addrspace(5)* %8 to float addrspace(5)* + store float %14, float addrspace(5)* %15, align 4 + %16 = bitcast i32 addrspace(5)* %8 to float addrspace(5)* + %17 = load float, float addrspace(5)* %16, align 4 + store float %17, float addrspace(5)* %7, align 4 + %18 = load i64, i64 addrspace(5)* %6, align 8 + %19 = load float, float addrspace(5)* %7, align 4 + %20 = inttoptr i64 %18 to float addrspace(1)* + store float %19, float addrspace(1)* %20, align 4 + ret void +} + +attributes #0 = { nounwind } + +!spirv.MemoryModel = !{!0} +!opencl.enable.FP_CONTRACT = !{} +!spirv.Source = !{!1} +!opencl.spir.version = !{!2} +!opencl.ocl.version = !{!2} +!opencl.used.extensions = !{!3} +!opencl.used.optional.core.features = !{!4} +!spirv.Generator = !{!5} + +!0 = !{i32 2, i32 2} +!1 = !{i32 3, i32 102000} +!2 = !{i32 1, i32 2} +!3 = !{!"cl_khr_fp16"} +!4 = !{!"cl_doubles"} +!5 = !{i16 7, i16 0} +!6 = !{i32 5, i32 5} +!7 = !{!"none", !"none"} +!8 = !{!"long", !"long"} +!9 = !{!"", !""} diff --git a/ptx/src/test/spirv_run/implicit_param.spvtxt b/ptx/src/test/spirv_run/implicit_param.spvtxt deleted file mode 100644 index 760761a..0000000 --- a/ptx/src/test/spirv_run/implicit_param.spvtxt +++ /dev/null @@ -1,53 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13 - %12 = OpLoad %float %18 Aligned 4 - OpStore %6 %12 - %14 = OpLoad %float %6 - %19 = OpBitcast %_ptr_Function_float %7 - OpStore %19 %14 Aligned 4 - %20 = OpBitcast %_ptr_Function_float %7 - %15 = OpLoad %float %20 Aligned 4 - OpStore %6 %15 - %16 = OpLoad %ulong %5 - %17 = OpLoad %float %6 - %21 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %16 - OpStore %21 %17 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/laneid.ptx b/ptx/src/test/spirv_run/laneid.ptx new file mode 100644 index 0000000..5303870 --- /dev/null +++ b/ptx/src/test/spirv_run/laneid.ptx @@ -0,0 +1,24 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry laneid( + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u32 tid; + .reg .u64 tid_64; + .reg .u32 result; + + ld.param.u64 out_addr, [output]; + + mov.b32 tid, %tid.x; + cvt.u64.u32 tid_64, tid; + + mov.b32 result, %laneid; + + mad.lo.u64 out_addr, tid_64, 4, out_addr; + st.u32 [out_addr], result; + ret; +} diff --git a/ptx/src/test/spirv_run/lanemask_lt.ll b/ptx/src/test/spirv_run/lanemask_lt.ll new file mode 100644 index 0000000..d36d4a2 --- /dev/null +++ b/ptx/src/test/spirv_run/lanemask_lt.ll @@ -0,0 +1,45 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__sreg_lanemask_lt() #0 + +define protected amdgpu_kernel void @lanemask_lt(ptr addrspace(4) byref(i64) %"28", ptr addrspace(4) byref(i64) %"29") #1 { +"40": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"15" = load i64, ptr addrspace(4) %"28", align 8 + store i64 %"15", ptr addrspace(5) %"4", align 8 + %"16" = load i64, ptr addrspace(4) %"29", align 8 + store i64 %"16", ptr addrspace(5) %"5", align 8 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"31" = inttoptr i64 %"18" to ptr + %"30" = load i32, ptr %"31", align 4 + store i32 %"30", ptr addrspace(5) %"6", align 4 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"32" = add i32 %"20", 1 + store i32 %"32", ptr addrspace(5) %"7", align 4 + %"12" = call i32 @__zluda_ptx_impl__sreg_lanemask_lt() + %0 = alloca i32, align 4, addrspace(5) + store i32 %"12", ptr addrspace(5) %0, align 4 + %"34" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"34", ptr addrspace(5) %"8", align 4 + %"23" = load i32, ptr addrspace(5) %"7", align 4 + %"24" = load i32, ptr addrspace(5) %"8", align 4 + %"35" = add i32 %"23", %"24" + store i32 %"35", ptr addrspace(5) %"7", align 4 + %"25" = load i64, ptr addrspace(5) %"5", align 8 + %"26" = load i32, ptr addrspace(5) %"7", align 4 + %"38" = inttoptr i64 %"25" to ptr + store i32 %"26", ptr %"38", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/lanemask_lt.ptx b/ptx/src/test/spirv_run/lanemask_lt.ptx new file mode 100644 index 0000000..02b13ce --- /dev/null +++ b/ptx/src/test/spirv_run/lanemask_lt.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry lanemask_lt( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 temp; + .reg .b32 temp2; + .reg .b32 less_lane; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp, [in_addr]; + add.u32 temp2, temp, 1; + mov.u32 less_lane, %lanemask_lt; + add.u32 temp2, temp2, less_lane; + st.u32 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/ld_st.ll b/ptx/src/test/spirv_run/ld_st.ll new file mode 100644 index 0000000..c8d6eb1 --- /dev/null +++ b/ptx/src/test/spirv_run/ld_st.ll @@ -0,0 +1,28 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @ld_st(ptr addrspace(4) byref(i64) %"15", ptr addrspace(4) byref(i64) %"16") #0 { +"19": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"15", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"16", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"17" = inttoptr i64 %"12" to ptr + %"11" = load i64, ptr %"17", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = inttoptr i64 %"13" to ptr + store i64 %"14", ptr %"18", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/ld_st.spvtxt b/ptx/src/test/spirv_run/ld_st.spvtxt deleted file mode 100644 index 447b1aa..0000000 --- a/ptx/src/test/spirv_run/ld_st.spvtxt +++ /dev/null @@ -1,42 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %15 = OpConvertUToPtr %_ptr_Generic_ulong %12 - %11 = OpLoad %ulong %15 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %14 = OpLoad %ulong %6 - %16 = OpConvertUToPtr %_ptr_Generic_ulong %13 - OpStore %16 %14 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ld_st_implicit.ll b/ptx/src/test/spirv_run/ld_st_implicit.ll new file mode 100644 index 0000000..da47ad8 --- /dev/null +++ b/ptx/src/test/spirv_run/ld_st_implicit.ll @@ -0,0 +1,36 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @ld_st_implicit(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"23": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %0 = alloca i64, align 8, addrspace(5) + store i64 81985529216486895, ptr addrspace(5) %0, align 8 + %"11" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr addrspace(1) + %"19" = load float, ptr addrspace(1) %"20", align 4 + %"24" = bitcast float %"19" to i32 + %"12" = zext i32 %"24" to i64 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"21" = inttoptr i64 %"14" to ptr addrspace(1) + %"26" = trunc i64 %"15" to i32 + %"22" = bitcast i32 %"26" to float + store float %"22", ptr addrspace(1) %"21", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/ld_st_implicit.ptx b/ptx/src/test/spirv_run/ld_st_implicit.ptx index 8562286..1294248 100644 --- a/ptx/src/test/spirv_run/ld_st_implicit.ptx +++ b/ptx/src/test/spirv_run/ld_st_implicit.ptx @@ -14,7 +14,8 @@ ld.param.u64 in_addr, [input]; ld.param.u64 out_addr, [output]; - ld.global.f32 temp, [in_addr]; - st.global.f32 [out_addr], temp; + mov.b64 temp, 0x0123456789abcdef; + 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 deleted file mode 100644 index 29f46f9..0000000 --- a/ptx/src/test/spirv_run/ld_st_implicit.spvtxt +++ /dev/null @@ -1,49 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %16 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %12 - %15 = OpLoad %float %16 Aligned 4 - %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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ld_st_offset.ll b/ptx/src/test/spirv_run/ld_st_offset.ll new file mode 100644 index 0000000..1b020cb --- /dev/null +++ b/ptx/src/test/spirv_run/ld_st_offset.ll @@ -0,0 +1,39 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @ld_st_offset(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"30": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"26", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"15" to ptr + %"32" = getelementptr inbounds i8, ptr %"27", i64 4 + %"14" = load i32, ptr %"32", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i32, ptr addrspace(5) %"7", align 4 + %"28" = inttoptr i64 %"16" to ptr + store i32 %"17", ptr %"28", align 4 + %"18" = load i64, ptr addrspace(5) %"5", align 8 + %"19" = load i32, ptr addrspace(5) %"6", align 4 + %"29" = inttoptr i64 %"18" to ptr + %"34" = getelementptr inbounds i8, ptr %"29", i64 4 + store i32 %"19", ptr %"34", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/ld_st_offset.spvtxt b/ptx/src/test/spirv_run/ld_st_offset.spvtxt deleted file mode 100644 index 5e314a0..0000000 --- a/ptx/src/test/spirv_run/ld_st_offset.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %24 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %21 = OpIAdd %ulong %15 %ulong_4 - %25 = OpConvertUToPtr %_ptr_Generic_uint %21 - %14 = OpLoad %uint %25 Aligned 4 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %uint %7 - %26 = OpConvertUToPtr %_ptr_Generic_uint %16 - OpStore %26 %17 Aligned 4 - %18 = OpLoad %ulong %5 - %19 = OpLoad %uint %6 - %23 = OpIAdd %ulong %18 %ulong_4_0 - %27 = OpConvertUToPtr %_ptr_Generic_uint %23 - OpStore %27 %19 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/lg2.ll b/ptx/src/test/spirv_run/lg2.ll new file mode 100644 index 0000000..5e29fe2 --- /dev/null +++ b/ptx/src/test/spirv_run/lg2.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @lg2(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"19", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call afn float @llvm.log2.f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.log2.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/lg2.spvtxt b/ptx/src/test/spirv_run/lg2.spvtxt deleted file mode 100644 index 3c7ca77..0000000 --- a/ptx/src/test/spirv_run/lg2.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/local_align.ll b/ptx/src/test/spirv_run/local_align.ll new file mode 100644 index 0000000..035d1f7 --- /dev/null +++ b/ptx/src/test/spirv_run/local_align.ll @@ -0,0 +1,29 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @local_align(ptr addrspace(4) byref(i64) %"16", ptr addrspace(4) byref(i64) %"17") #0 { +"20": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca [8 x i8], align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"16", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"11" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"18" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"18", align 8 + store i64 %"12", ptr addrspace(5) %"7", align 8 + %"14" = load i64, ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"7", align 8 + %"19" = inttoptr i64 %"14" to ptr + store i64 %"15", ptr %"19", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/local_align.spvtxt b/ptx/src/test/spirv_run/local_align.spvtxt deleted file mode 100644 index a2cfd4c..0000000 --- a/ptx/src/test/spirv_run/local_align.spvtxt +++ /dev/null @@ -1,49 +0,0 @@ - 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 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %16 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %16 Aligned 8 - OpStore %7 %12 - %14 = OpLoad %ulong %6 - %15 = OpLoad %ulong %7 - %17 = OpConvertUToPtr %_ptr_Generic_ulong %14 - OpStore %17 %15 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mad_s32.ll b/ptx/src/test/spirv_run/mad_s32.ll new file mode 100644 index 0000000..75a204a --- /dev/null +++ b/ptx/src/test/spirv_run/mad_s32.ll @@ -0,0 +1,83 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mad_s32(ptr addrspace(4) byref(i64) %"53", ptr addrspace(4) byref(i64) %"54") #0 { +"76": + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"12" = alloca i64, align 8, addrspace(5) + %"15" = load i64, ptr addrspace(4) %"53", align 8 + store i64 %"15", ptr addrspace(5) %"4", align 8 + %"16" = load i64, ptr addrspace(4) %"54", align 8 + store i64 %"16", ptr addrspace(5) %"5", align 8 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"56" = inttoptr i64 %"18" to ptr + %"55" = load i32, ptr %"56", align 4 + store i32 %"55", ptr addrspace(5) %"9", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"57" = inttoptr i64 %"20" to ptr + %"78" = getelementptr inbounds i8, ptr %"57", i64 4 + %"58" = load i32, ptr %"78", align 4 + store i32 %"58", ptr addrspace(5) %"10", align 4 + %"22" = load i64, ptr addrspace(5) %"4", align 8 + %"59" = inttoptr i64 %"22" to ptr + %"80" = getelementptr inbounds i8, ptr %"59", i64 8 + %"21" = load i64, ptr %"80", align 8 + store i64 %"21", ptr addrspace(5) %"12", align 8 + %"24" = load i64, ptr addrspace(5) %"4", align 8 + %"60" = inttoptr i64 %"24" to ptr + %"82" = getelementptr inbounds i8, ptr %"60", i64 16 + %"61" = load i32, ptr %"82", align 4 + store i32 %"61", ptr addrspace(5) %"11", align 4 + %"26" = load i32, ptr addrspace(5) %"9", align 4 + %"27" = load i32, ptr addrspace(5) %"10", align 4 + %"28" = load i32, ptr addrspace(5) %"11", align 4 + %0 = mul i32 %"26", %"27" + %"25" = add i32 %0, %"28" + store i32 %"25", ptr addrspace(5) %"6", align 4 + %"30" = load i32, ptr addrspace(5) %"9", align 4 + %"31" = load i32, ptr addrspace(5) %"10", align 4 + %"32" = load i32, ptr addrspace(5) %"11", align 4 + %1 = sext i32 %"30" to i64 + %2 = sext i32 %"31" to i64 + %3 = mul nsw i64 %1, %2 + %4 = lshr i64 %3, 32 + %5 = trunc i64 %4 to i32 + %"29" = add i32 %5, %"32" + store i32 %"29", ptr addrspace(5) %"7", align 4 + %"34" = load i32, ptr addrspace(5) %"9", align 4 + %"35" = load i32, ptr addrspace(5) %"10", align 4 + %"36" = load i64, ptr addrspace(5) %"12", align 8 + %6 = sext i32 %"34" to i64 + %7 = sext i32 %"35" to i64 + %8 = mul nsw i64 %6, %7 + %"68" = add i64 %8, %"36" + store i64 %"68", ptr addrspace(5) %"8", align 8 + %"37" = load i64, ptr addrspace(5) %"5", align 8 + %"38" = load i32, ptr addrspace(5) %"6", align 4 + %"72" = inttoptr i64 %"37" to ptr + store i32 %"38", ptr %"72", align 4 + %"39" = load i64, ptr addrspace(5) %"5", align 8 + %"40" = load i32, ptr addrspace(5) %"7", align 4 + %"73" = inttoptr i64 %"39" to ptr + %"84" = getelementptr inbounds i8, ptr %"73", i64 8 + store i32 %"40", ptr %"84", align 4 + %"41" = load i64, ptr addrspace(5) %"5", align 8 + %"42" = load i64, ptr addrspace(5) %"8", align 8 + %"74" = inttoptr i64 %"41" to ptr + %"86" = getelementptr inbounds i8, ptr %"74", i64 16 + store i64 %"42", ptr %"86", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mad_s32.ptx b/ptx/src/test/spirv_run/mad_s32.ptx index a864266..9087808 100644 --- a/ptx/src/test/spirv_run/mad_s32.ptx +++ b/ptx/src/test/spirv_run/mad_s32.ptx @@ -9,20 +9,26 @@ { .reg .u64 in_addr; .reg .u64 out_addr; - .reg .s32 dst; - .reg .s32 src1; - .reg .s32 src2; - .reg .s32 src3; + .reg .s32 dst1; + .reg .s32 dst2; + .reg .u64 dst3; + .reg .b32 src1; + .reg .b32 src2; + .reg .b32 src3; + .reg .b64 src4; 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; + ld.b64 src4, [in_addr+8]; + ld.s32 src3, [in_addr+16]; + mad.lo.s32 dst1, src1, src2, src3; + mad.hi.s32 dst2, src1, src2, src3; + mad.wide.s32 dst3, src1, src2, src4; + st.s32 [out_addr], dst1; + st.s32 [out_addr+8], dst2; + st.s64 [out_addr+16], dst3; ret; } diff --git a/ptx/src/test/spirv_run/mad_s32.spvtxt b/ptx/src/test/spirv_run/mad_s32.spvtxt deleted file mode 100644 index bb44af0..0000000 --- a/ptx/src/test/spirv_run/mad_s32.spvtxt +++ /dev/null @@ -1,77 +0,0 @@ - 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 Aligned 8 - OpStore %4 %12 - %13 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %13 - %15 = OpLoad %ulong %4 - %38 = OpConvertUToPtr %_ptr_Generic_uint %15 - %14 = OpLoad %uint %38 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %ulong %4 - %31 = OpIAdd %ulong %17 %ulong_4 - %39 = OpConvertUToPtr %_ptr_Generic_uint %31 - %16 = OpLoad %uint %39 Aligned 4 - OpStore %8 %16 - %19 = OpLoad %ulong %4 - %33 = OpIAdd %ulong %19 %ulong_8 - %40 = OpConvertUToPtr %_ptr_Generic_uint %33 - %18 = OpLoad %uint %40 Aligned 4 - 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 Aligned 4 - %26 = OpLoad %ulong %5 - %27 = OpLoad %uint %6 - %35 = OpIAdd %ulong %26 %ulong_4_0 - %42 = OpConvertUToPtr %_ptr_Generic_uint %35 - OpStore %42 %27 Aligned 4 - %28 = OpLoad %ulong %5 - %29 = OpLoad %uint %6 - %37 = OpIAdd %ulong %28 %ulong_8_0 - %43 = OpConvertUToPtr %_ptr_Generic_uint %37 - OpStore %43 %29 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/madc_cc.ll b/ptx/src/test/spirv_run/madc_cc.ll new file mode 100644 index 0000000..626149c --- /dev/null +++ b/ptx/src/test/spirv_run/madc_cc.ll @@ -0,0 +1,72 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @madc_cc(ptr addrspace(4) byref(i64) %"41", ptr addrspace(4) byref(i64) %"42") #0 { +"55": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"41", align 8 + store i64 %"13", ptr addrspace(5) %"4", align 8 + %"14" = load i64, ptr addrspace(4) %"42", align 8 + store i64 %"14", ptr addrspace(5) %"5", align 8 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"44" = inttoptr i64 %"16" to ptr + %"43" = load i32, ptr %"44", align 4 + store i32 %"43", ptr addrspace(5) %"8", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"45" = inttoptr i64 %"18" to ptr + %"57" = getelementptr inbounds i8, ptr %"45", i64 4 + %"46" = load i32, ptr %"57", align 4 + store i32 %"46", ptr addrspace(5) %"9", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"47" = inttoptr i64 %"20" to ptr + %"59" = getelementptr inbounds i8, ptr %"47", i64 8 + %"19" = load i32, ptr %"59", align 4 + store i32 %"19", ptr addrspace(5) %"10", align 4 + %"23" = load i32, ptr addrspace(5) %"8", align 4 + %"24" = load i32, ptr addrspace(5) %"9", align 4 + %"25" = load i32, ptr addrspace(5) %"10", align 4 + %0 = mul i32 %"23", %"24" + %1 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %0, i32 %"25") + %"21" = extractvalue { i32, i1 } %1, 0 + %"22" = extractvalue { i32, i1 } %1, 1 + store i32 %"21", ptr addrspace(5) %"6", align 4 + store i1 %"22", ptr addrspace(5) %"11", align 1 + %"27" = load i1, ptr addrspace(5) %"11", align 1 + %"28" = load i32, ptr addrspace(5) %"8", align 4 + %"29" = load i32, ptr addrspace(5) %"9", align 4 + %2 = sext i32 %"28" to i64 + %3 = sext i32 %"29" to i64 + %4 = mul nsw i64 %2, %3 + %5 = lshr i64 %4, 32 + %6 = trunc i64 %5 to i32 + %7 = zext i1 %"27" to i32 + %8 = add i32 %6, 3 + %"26" = add i32 %8, %7 + store i32 %"26", ptr addrspace(5) %"7", align 4 + %"30" = load i64, ptr addrspace(5) %"5", align 8 + %"31" = load i32, ptr addrspace(5) %"6", align 4 + %"53" = inttoptr i64 %"30" to ptr + store i32 %"31", ptr %"53", align 4 + %"32" = load i64, ptr addrspace(5) %"5", align 8 + %"33" = load i32, ptr addrspace(5) %"7", align 4 + %"54" = inttoptr i64 %"32" to ptr + %"61" = getelementptr inbounds i8, ptr %"54", i64 4 + store i32 %"33", ptr %"61", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/madc_cc.ptx b/ptx/src/test/spirv_run/madc_cc.ptx new file mode 100644 index 0000000..1dc885e --- /dev/null +++ b/ptx/src/test/spirv_run/madc_cc.ptx @@ -0,0 +1,29 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry madc_cc( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .s32 dst1; + .reg .s32 dst2; + .reg .b32 src1; + .reg .b32 src2; + .reg .b32 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.b32 src3, [in_addr+8]; + mad.lo.cc.s32 dst1, src1, src2, src3; + madc.hi.s32 dst2, src1, src2, 3; + st.s32 [out_addr], dst1; + st.s32 [out_addr+4], dst2; + ret; +} diff --git a/ptx/src/test/spirv_run/madc_cc2.ll b/ptx/src/test/spirv_run/madc_cc2.ll new file mode 100644 index 0000000..bea7193 --- /dev/null +++ b/ptx/src/test/spirv_run/madc_cc2.ll @@ -0,0 +1,73 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @madc_cc2(ptr addrspace(4) byref(i64) %"52", ptr addrspace(4) byref(i64) %"53") #0 { +"66": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"53", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %0 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 0, i32 -1) + %"14" = extractvalue { i32, i1 } %0, 0 + %"15" = extractvalue { i32, i1 } %0, 1 + store i32 %"14", ptr addrspace(5) %"6", align 4 + store i1 %"15", ptr addrspace(5) %"11", align 1 + %"18" = load i1, ptr addrspace(5) %"11", align 1 + %1 = zext i1 %"18" to i32 + %2 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 1, i32 -1) + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %5 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %3, i32 %1) + %"54" = extractvalue { i32, i1 } %5, 0 + %6 = extractvalue { i32, i1 } %5, 1 + %"17" = xor i1 %4, %6 + store i32 %"54", ptr addrspace(5) %"7", align 4 + store i1 %"17", ptr addrspace(5) %"11", align 1 + %"20" = load i1, ptr addrspace(5) %"11", align 1 + %7 = zext i1 %"20" to i32 + %"55" = add i32 0, %7 + store i32 %"55", ptr addrspace(5) %"8", align 4 + %"22" = load i1, ptr addrspace(5) %"11", align 1 + %8 = zext i1 %"22" to i32 + %"56" = add i32 0, %8 + store i32 %"56", ptr addrspace(5) %"9", align 4 + %"24" = load i1, ptr addrspace(5) %"12", align 1 + %9 = zext i1 %"24" to i32 + %"57" = sub i32 2, %9 + store i32 %"57", ptr addrspace(5) %"10", align 4 + %"25" = load i64, ptr addrspace(5) %"5", align 8 + %"26" = load i32, ptr addrspace(5) %"7", align 4 + %"58" = inttoptr i64 %"25" to ptr + store i32 %"26", ptr %"58", align 4 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = load i32, ptr addrspace(5) %"8", align 4 + %"60" = inttoptr i64 %"27" to ptr + %"68" = getelementptr inbounds i8, ptr %"60", i64 4 + store i32 %"28", ptr %"68", align 4 + %"29" = load i64, ptr addrspace(5) %"5", align 8 + %"30" = load i32, ptr addrspace(5) %"9", align 4 + %"62" = inttoptr i64 %"29" to ptr + %"70" = getelementptr inbounds i8, ptr %"62", i64 8 + store i32 %"30", ptr %"70", align 4 + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load i32, ptr addrspace(5) %"10", align 4 + %"64" = inttoptr i64 %"31" to ptr + %"72" = getelementptr inbounds i8, ptr %"64", i64 12 + store i32 %"32", ptr %"72", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/madc_cc2.ptx b/ptx/src/test/spirv_run/madc_cc2.ptx new file mode 100644 index 0000000..163c39b --- /dev/null +++ b/ptx/src/test/spirv_run/madc_cc2.ptx @@ -0,0 +1,38 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry madc_cc2( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 unused; + + .reg .b32 result_1; + .reg .b32 carry_out_1_1; + .reg .b32 carry_out_1_2; + .reg .b32 carry_out_1_3; + + ld.param.u64 out_addr, [output]; + + // set carry=1 + mad.lo.cc.u32 unused, 0, 0, 4294967295; + // overflow addition + madc.lo.cc.u32 result_1, 1, 1, 4294967295; + // write carry + madc.lo.u32 carry_out_1_1, 0, 0, 0; + // overflow is also detected by addc + addc.u32 carry_out_1_2, 0, 0; + // but not subc + subc.u32 carry_out_1_3, 2, 0; + + st.s32 [out_addr], result_1; + st.s32 [out_addr+4], carry_out_1_1; + st.s32 [out_addr+8], carry_out_1_2; + st.s32 [out_addr+12], carry_out_1_3; + + ret; +} diff --git a/ptx/src/test/spirv_run/match_any_32.ptx b/ptx/src/test/spirv_run/match_any_32.ptx new file mode 100644 index 0000000..d97263c --- /dev/null +++ b/ptx/src/test/spirv_run/match_any_32.ptx @@ -0,0 +1,32 @@ +.version 6.5 +.target sm_70 +.address_size 64 + +.global .u32 values[64] = { 3, 1, 2, 1, 3, 3, 2, 1, 3, 1, 3, 3, 1, 2, 2, 1, 1, 3, 2, 3, 3, 2, 1, 2, 1, 3, 3, 3, 3, 1, 1, 2, 3, 2, 3, 1, 3, 3, 2, 2, 1, 3, 1, 2, 3, 2, 2, 2, 1, 1, 3, 2, 3, 1, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1 }; + +.visible .entry match_any_32( + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u32 tid; + .reg .u64 tid_64; + .reg .u64 values_addr; + .reg .u32 result; + + ld.param.u64 out_addr, [output]; + + mov.b32 tid, %tid.x; + cvt.u64.u32 tid_64, tid; + + mov.b64 values_addr, values; + mad.lo.u64 values_addr, tid_64, 4, values_addr; + ld.global.b32 result, [values_addr]; + + match.any.sync.b32 result, result, 0xd6e2d0b4; + + + mad.lo.u64 out_addr, tid_64, 4, out_addr; + st.u32 [out_addr], result; + ret; +} diff --git a/ptx/src/test/spirv_run/max.ll b/ptx/src/test/spirv_run/max.ll new file mode 100644 index 0000000..79b6f48 --- /dev/null +++ b/ptx/src/test/spirv_run/max.ll @@ -0,0 +1,42 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @max(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"30", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"16" = call i32 @llvm.smax.i32(i32 %"17", i32 %"18") + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"27", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smax.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/max.spvtxt b/ptx/src/test/spirv_run/max.spvtxt deleted file mode 100644 index d3ffa2f..0000000 --- a/ptx/src/test/spirv_run/max.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %22 - %14 = OpLoad %uint %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/membar.ll b/ptx/src/test/spirv_run/membar.ll new file mode 100644 index 0000000..c9ec8b9 --- /dev/null +++ b/ptx/src/test/spirv_run/membar.ll @@ -0,0 +1,29 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @membar(ptr addrspace(4) byref(i64) %"15", ptr addrspace(4) byref(i64) %"16") #0 { +"20": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"15", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"16", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"18" = inttoptr i64 %"12" to ptr + %"17" = load i32, ptr %"18", align 4 + store i32 %"17", ptr addrspace(5) %"6", align 4 + fence seq_cst + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"19" = inttoptr i64 %"13" to ptr + store i32 %"14", ptr %"19", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shr.ptx b/ptx/src/test/spirv_run/membar.ptx similarity index 72% rename from ptx/src/test/spirv_run/shr.ptx rename to ptx/src/test/spirv_run/membar.ptx index 0a12fa7..01aa9f2 100644 --- a/ptx/src/test/spirv_run/shr.ptx +++ b/ptx/src/test/spirv_run/membar.ptx @@ -2,7 +2,7 @@ .target sm_30 .address_size 64 -.visible .entry shr( +.visible .entry membar( .param .u64 input, .param .u64 output ) @@ -14,8 +14,8 @@ ld.param.u64 in_addr, [input]; ld.param.u64 out_addr, [output]; - ld.s32 temp, [in_addr]; - shr.s32 temp, temp, 1; + ld.u32 temp, [in_addr]; + membar.sys; st.s32 [out_addr], temp; ret; } diff --git a/ptx/src/test/spirv_run/min.ll b/ptx/src/test/spirv_run/min.ll new file mode 100644 index 0000000..0828070 --- /dev/null +++ b/ptx/src/test/spirv_run/min.ll @@ -0,0 +1,42 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @min(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"30", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"16" = call i32 @llvm.smin.i32(i32 %"17", i32 %"18") + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"27", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smin.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/min.spvtxt b/ptx/src/test/spirv_run/min.spvtxt deleted file mode 100644 index de2e35e..0000000 --- a/ptx/src/test/spirv_run/min.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %22 - %14 = OpLoad %uint %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mod.rs b/ptx/src/test/spirv_run/mod.rs index 7c790eb..bd745fd 100644 --- a/ptx/src/test/spirv_run/mod.rs +++ b/ptx/src/test/spirv_run/mod.rs @@ -1,86 +1,167 @@ +use crate::llvm; 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 comgr::Comgr; +use half::f16; +use hip_common::CompilationMode; +use hip_runtime_sys::*; +use paste::paste; use std::error; -use std::ffi::{c_void, CStr, CString}; +use std::ffi::{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}; +use std::sync::Once; +use std::{env, fs, path::PathBuf, ptr, str}; +use zluda_llvm::bit_writer::*; macro_rules! test_ptx { ($fn_name:ident, $input:expr, $output:expr) => { - paste::item! { + paste! { #[test] - fn [<$fn_name _ptx>]() -> Result<(), Box> { + fn [<$fn_name _hip>]() -> Result<(), Box> { 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) + test_hip_assert(stringify!($fn_name), ptx, &input, &mut output) } } - paste::item! { + paste! { #[test] - fn [<$fn_name _spvtxt>]() -> Result<(), Box> { + fn [<$fn_name _cuda>]() -> Result<(), Box> { + let ptx = include_str!(concat!(stringify!($fn_name), ".ptx")); + let input = $input; + let mut output = $output; + test_cuda_assert(stringify!($fn_name), ptx, Some(&input), &mut output, 1) + } + } + + paste! { + #[test] + fn [<$fn_name _llvm_ir>]() -> Result<(), Box> { 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) + let llvm_file_name = concat!(stringify!($fn_name), ".ll"); + let llvm_ir = include_bytes!(concat!(stringify!($fn_name), ".ll")); + unsafe { test_llvm_assert(ptx_txt, llvm_ir, llvm_file_name) } + } + } + }; + + ($fn_name:ident) => { + paste! { + #[test] + fn [<$fn_name _comgr>]() -> Result<(), Box> { + let ptx_txt = include_str!(concat!(stringify!($fn_name), ".ptx")); + unsafe { test_compile_assert(ptx_txt) } + } + } + + paste! { + #[test] + fn [<$fn_name _llvm_ir>]() -> Result<(), Box> { + let ptx_txt = include_str!(concat!(stringify!($fn_name), ".ptx")); + let llvm_file_name = concat!(stringify!($fn_name), ".ll"); + let llvm_ir = include_bytes!(concat!(stringify!($fn_name), ".ll")); + unsafe { test_llvm_assert(ptx_txt, llvm_ir, llvm_file_name) } } } }; } +macro_rules! test_ptx_warp { + ($fn_name:ident, $expected:expr) => { + paste! { + #[test] + fn [<$fn_name _cuda>]() -> Result<(), Box> { + let ptx = include_str!(concat!(stringify!($fn_name), ".ptx")); + let mut expected = $expected; + test_cuda_assert::(stringify!($fn_name), ptx, None, &mut expected, 64) + } + + #[test] + fn [<$fn_name _hip_wave32>]() -> Result<(), Box> { + let ptx = include_str!(concat!(stringify!($fn_name), ".ptx")); + let mut expected = $expected; + test_hip_assert_output(CompilationMode::Wave32, stringify!($fn_name), ptx, &mut expected) + } + + #[test] + fn [<$fn_name _hip_wave32onwave64>]() -> Result<(), Box> { + let ptx = include_str!(concat!(stringify!($fn_name), ".ptx")); + let mut expected = $expected; + test_hip_assert_output(CompilationMode::Wave32OnWave64,stringify!($fn_name), ptx, &mut expected) + } + + #[test] + fn [<$fn_name _hip_doublewave32onwave64>]() -> Result<(), Box> { + let ptx = include_str!(concat!(stringify!($fn_name), ".ptx")); + let mut expected = $expected; + test_hip_assert_output(CompilationMode::DoubleWave32OnWave64, stringify!($fn_name), ptx, &mut expected) + } + } + } +} + test_ptx!(ld_st, [1u64], [1u64]); -test_ptx!(ld_st_implicit, [0.5f32], [0.5f32]); +test_ptx!(ld_st_implicit, [0.5f32, 0.25f32], [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!(add_global, [1f32], [0x408487EEu32]); +test_ptx!(amdgpu_unnamed, [2u64], [3u64]); test_ptx!(setp, [10u64, 11u64], [1u64, 0u64]); test_ptx!(setp_gt, [f32::NAN, 1f32], [1f32]); +test_ptx!(setp_pred2, [100f32, 23f32], [100f32]); +test_ptx!(setp_bool, [100f32, 23f32, 9f32], [9f32]); test_ptx!(setp_leu, [1f32, f32::NAN], [1f32]); test_ptx!(bra, [10u64], [11u64]); test_ptx!(not, [0u64], [u64::max_value()]); +test_ptx!(shf, [11u32, 12u32], [196608u32]); test_ptx!(shl, [11u64], [44u64]); test_ptx!(shl_link_hack, [11u64], [44u64]); -test_ptx!(cvt_sat_s_u, [-1i32], [0i32]); +test_ptx!(shl_overflow, [1u32, 31, 32, 33], [2147483648u32, 0, 0]); +test_ptx!(cvt_sat_s_u, [-1i32], [0i32, -1i32]); test_ptx!(cvta, [3.0f32], [3.0f32]); test_ptx!(block, [1u64], [2u64]); test_ptx!(local_align, [1u64], [1u64]); test_ptx!(call, [1u64], [2u64]); +// In certain situations LLVM will miscompile AMDGPU binaries. +// This happens if the return type of a function is a .b8 array. +// This test checks if our workaround for this bug works +test_ptx!(call_bug, [1u64], [2u64]); +test_ptx!(callprototype, [1u64], [2u64]); +test_ptx!(call_multi_return, [2u32, 3u32], [5u64, 6u64]); test_ptx!(vector, [1u32, 2u32], [3u32, 3u32]); +test_ptx!(vector4, [1u32, 2u32, 3u32, 4u32], [4u32]); 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]); +// This segfaults NV compiler +// 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!( + mad_s32, + [0xffffffu32, 0xffffffu32, 1u32, 0u32, 1u32], + [0xFE000002u64, 0x10000u64, 0xFFFFFE000002u64] +); +// 16777216 * -268435456 = -4503599627370496 test_ptx!( mul_wide, - [0x01_00_00_00__01_00_00_00i64], - [0x1_00_00_00_00_00_00i64] + [0x01_00_00_00__f0_00_00_00i64], + [0xff_f0_00_00_00_00_00_00u64] ); test_ptx!(vector_extract, [1u8, 2u8, 3u8, 4u8], [3u8, 4u8, 1u8, 2u8]); -test_ptx!(shr, [-2i32], [-1i32]); +test_ptx!(shr_s32, [-4i32, 32i32], [-1i32]); +test_ptx!(shr_u32, [u32::MAX, 31u32, 32u32], [1u32, 0u32]); 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!(max, [555i32, -1i32], [555i32]); +test_ptx!(global_array, [0xDEADu32], [4294967295u32]); test_ptx!(extern_shared, [127u64], [127u64]); test_ptx!(extern_shared_call, [121u64], [123u64]); test_ptx!(rcp, [2f32], [0.5f32]); @@ -114,9 +195,20 @@ 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!( + ex2, + [10f32, f32::NEG_INFINITY, 0f32, f32::INFINITY], + [1024f32, 0f32, 1f32, f32::INFINITY] +); test_ptx!(cvt_rni, [9.5f32, 10.5f32], [10f32, 10f32]); test_ptx!(cvt_rzi, [-13.8f32, 12.9f32], [-13f32, 12f32]); +// Logically, 33554434i32 with `rn` rounding could round to either 33554432f32 or 33554436f32 +// Maybe IEEE is more precise than NV PTX docs? +test_ptx!( + cvt_f32_s32, + [33554434i32, 33554435i32, 33554435i32, 33554435i32], + [33554432f32, 33554432f32, 33554432f32, 33554436f32] +); test_ptx!(cvt_s32_f32, [-13.8f32, 12.9f32], [-13i32, 13i32]); test_ptx!(clz, [0b00000101_00101101_00010011_10101011u32], [5u32]); test_ptx!(popc, [0b10111100_10010010_01001001_10001010u32], [14u32]); @@ -139,14 +231,225 @@ test_ptx!( [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!(bfi, [0b10u32, 0b101u32, 0u32, 2u32], [0b110u32]); test_ptx!(shared_ptr_take_address, [97815231u64], [97815231u64]); -// For now, we just make sure that it builds and links -test_ptx!(assertfail, [716523871u64], [716523872u64]); test_ptx!(cvt_s64_s32, [-1i32], [-1i64]); +test_ptx!(add_tuning, [2u64], [3u64]); +test_ptx!(add_non_coherent, [3u64], [4u64]); +test_ptx!(sign_extend, [-1i16], [-1i32]); +test_ptx!(atom_add_float, [1.25f32, 0.5f32], [1.25f32, 1.75f32]); +test_ptx!( + setp_nan, + [ + 0.5f32, + f32::NAN, + f32::NAN, + 0.5f32, + f32::NAN, + f32::NAN, + 0.5f32, + 0.5f32 + ], + [1u32, 1u32, 1u32, 0u32] +); +test_ptx!( + setp_num, + [ + 0.5f32, + f32::NAN, + f32::NAN, + 0.5f32, + f32::NAN, + f32::NAN, + 0.5f32, + 0.5f32 + ], + [0u32, 0u32, 0u32, 2u32] +); +test_ptx!(non_scalar_ptr_offset, [1u32, 2u32, 3u32, 4u32], [7u32]); +test_ptx!(const, [0u16], [10u16, 20, 30, 40]); +test_ptx!(cvt_s16_s8, [0x139231C2u32], [0xFFFFFFC2u32]); +test_ptx!(cvt_f64_f32, [0.125f32], [0.125f64]); +test_ptx!(cvt_f32_f16, [0xa1u16], [0x37210000u32]); +test_ptx!(prmt, [0x70c507d6u32, 0x6fbd4b5cu32], [0x6fbdd65cu32]); +test_ptx!( + prmt_non_immediate, + [0x70c507d6u32, 0x6fbd4b5cu32], + [0xD6D65CD6u32] +); +test_ptx!(activemask, [0u32], [1u32]); +test_ptx!(membar, [152731u32], [152731u32]); +test_ptx!(shared_unify_decl, [7681u64, 7682u64], [15363u64]); +test_ptx!(shared_unify_extern, [7681u64, 7682u64], [15363u64]); +test_ptx!(shared_unify_local, [16752u64, 714u64], [17466u64]); +test_ptx!(cvt_u32_s16, [-1i16, -1i16], [0xffffffffu32]); +test_ptx!(abs, [i32::MIN, -134i32], [i32::MIN, 134i32]); +test_ptx!( + madc_cc, + [65521u32, 2147549199, 0x1000], + [2147487519u32, 4294934539] +); +test_ptx!(madc_cc2, [0xDEADu32], [0u32, 1, 1, 2]); +test_ptx!(mov_vector_cast, [0x200000001u64], [2u32, 1u32]); +test_ptx!( + cvt_clamp, + [f32::NAN, f32::NEG_INFINITY, f32::INFINITY, 1.00001], + [0f32, 0.0, 1.0, 1.0] +); +test_ptx!(generic, [0xDEADu32], [210u32]); +test_ptx!(vote_ballot, [0xDEADu32], [1u32, 0, 0, 1]); +test_ptx!(param_ptr, [1u64], [2u64]); +test_ptx!(s64_min, [0xDEADu32], [i64::MIN]); +test_ptx!(multireg, [441u64], [442u64]); +test_ptx!( + addc_cc, + [ + 2_147_483_650u32, + 2_147_483_649u32, + 4_294_967_294u32, + 4_294_967_294u32 + ], + [3u32, 2u32, 1u32] +); +test_ptx!(addc_cc2, [0xDEADu32], [1u32, 1u32]); +test_ptx!( + subc_cc, + [ + 2_147_483_649u32, + 2_147_483_650u32, + 4_294_967_294u32, + 4_294_967_294u32 + ], + [4294967295u32, 0, 2] +); +test_ptx!(carry_mixed, [0xDEADu32], [1u32, 1u32]); +test_ptx!( + subc_cc2, + [0xDEADu32], + [0u32, 1, 0, 4294967295, 1, 4294967295, 1] +); +test_ptx!(vshr, [0x6f3650f4u32, 22, 0xc62d4586], [0xC62D4742u32]); +test_ptx!(bfind, [0u32, 1u32, 0x64eb0414], [u32::MAX, 0, 30]); +test_ptx!(bfind_shiftamt, [0u32, 1u32, 0x19bea67d], [u32::MAX, 31, 3]); +test_ptx!( + atom_add_f16, + [f16::from_f32(2.0), f16::from_f32(3.0)], + [f16::from_f32(2.0), f16::from_f32(5.0)] +); +test_ptx!(st_f16x2, [0xc1690e6eu32, 0x13739444u32], [0xffffu32]); +test_ptx!( + dp4a, + [0xde3032f5u32, 0x2474fe15, 0xf51d8d6c], + [0xF51D9D19u32] +); +test_ptx!(add_param_ptr, [61382u64], [61383u64]); +test_ptx!(atom_max_u32, [1u32, u32::MAX], [u32::MAX]); +test_ptx!(atom_ld_st, [1923569713u32], [1923569713u32]); +test_ptx!( + atom_ld_st_vec, + [1923569713u64, 1923569712], + [1923569713u64, 1923569712] +); + +test_ptx_warp!( + shfl, + [ + 1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63 + ] +); +test_ptx_warp!( + laneid, + [ + 0u32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ] +); +test_ptx_warp!( + match_any_32, + [ + 369229872u32, + 1077973120, + 2157985796, + 1077973120, + 369229872, + 369229872, + 2157985796, + 1077973120, + 369229872, + 1077973120, + 369229872, + 369229872, + 1077973120, + 2157985796, + 2157985796, + 1077973120, + 1077973120, + 369229872, + 2157985796, + 369229872, + 369229872, + 2157985796, + 1077973120, + 2157985796, + 1077973120, + 369229872, + 369229872, + 369229872, + 369229872, + 1077973120, + 1077973120, + 2157985796, + 4148, + 348176512, + 4148, + 3257008128, + 4148, + 4148, + 348176512, + 348176512, + 3257008128, + 4148, + 3257008128, + 348176512, + 4148, + 348176512, + 348176512, + 348176512, + 3257008128, + 3257008128, + 4148, + 348176512, + 4148, + 3257008128, + 348176512, + 348176512, + 3257008128, + 3257008128, + 348176512, + 3257008128, + 348176512, + 3257008128, + 3257008128, + 3257008128 + ] +); +test_ptx_warp!( + red_shared, + [ + 1025u32, 1058, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 + ] +); + +test_ptx!(barrier); +test_ptx!(assertfail); +test_ptx!(func_ptr); +test_ptx!(lanemask_lt); +test_ptx!(alloca_call); struct DisplayError { err: T, @@ -166,10 +469,10 @@ impl Debug for DisplayError { impl error::Error for DisplayError {} -fn test_ptx_assert< +fn test_hip_assert< 'a, - Input: From + ze::SafeRepr + Debug + Copy + PartialEq, - Output: From + ze::SafeRepr + Debug + Copy + PartialEq, + Input: From + Debug + Copy + PartialEq, + Output: From + Debug + Copy + PartialEq + Default, >( name: &str, ptx_text: &'a str, @@ -179,357 +482,290 @@ fn test_ptx_assert< 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 zluda_module = translate::to_llvm_module(CompilationMode::Wave32, vec![ast])?; let name = CString::new(name)?; - let result = run_spirv(name.as_c_str(), zluda_module, input, output) - .map_err(|err| DisplayError { err })?; + let result = run_hip( + CompilationMode::Wave32, + name.as_c_str(), + zluda_module, + Some(input), + output, + [1, 1, 1], + ) + .map_err(|err| DisplayError { err })?; assert_eq!(result.as_slice(), output); Ok(()) } -fn run_spirv< - Input: From + ze::SafeRepr + Copy + Debug, - Output: From + ze::SafeRepr + Copy + Debug, ->( - name: &CStr, - module: translate::Module, - input: &[Input], - output: &mut [Output], -) -> ze::Result> { - ze::init()?; - let spirv = module.spirv.assemble(); - let byte_il = unsafe { - slice::from_raw_parts::( - spirv.as_ptr() as *const _, - spirv.len() * mem::size_of::(), - ) +fn test_hip_assert_output<'a>( + compilation_mode: CompilationMode, + name: &str, + ptx_text: &'a str, + expected: &mut [u32], +) -> Result<(), Box> { + let mut errors = Vec::new(); + let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_text)?; + assert!(errors.len() == 0); + let zluda_module = translate::to_llvm_module(compilation_mode, vec![ast])?; + let name = CString::new(name)?; + let z_dimension = if compilation_mode == CompilationMode::Wave32OnWave64 { + 2 + } else { + 1 }; - let use_shared_mem = module - .kernel_info - .get(name.to_str().unwrap()) - .map(|info| info.uses_shared_mem) - .unwrap_or(false); + let result = run_hip::( + compilation_mode, + name.as_c_str(), + zluda_module, + None, + expected, + [64, 1, z_dimension], + ) + .map_err(|err| DisplayError { err })?; + assert_eq!(result.as_slice(), expected); + Ok(()) +} + +fn test_cuda_assert< + 'a, + Input: From + Debug + Copy + PartialEq, + Output: From + Debug + Copy + PartialEq + Default, +>( + name: &str, + ptx_text: &'a str, + input: Option<&[Input]>, + output: &mut [Output], + block_size_x: u32, +) -> Result<(), Box> { + let name = CString::new(name)?; + let result = unsafe { run_cuda(name.as_c_str(), ptx_text, input, output, block_size_x) }; + assert_eq!(result.as_slice(), output); + Ok(()) +} + +macro_rules! hip_call { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(err); + } + } + }; +} + +unsafe fn run_cuda + Copy + Debug, Output: From + Copy + Debug + Default>( + name: &CStr, + ptx_module: &str, + input: Option<&[Input]>, + output: &mut [Output], + block_size_x: u32, +) -> Vec { + use cuda_types::*; + let cuda = CudaTestLibrary::new(); + cuda.cuInit(0); + let ptx_module = CString::new(ptx_module).unwrap(); 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_logged( - &mut ctx, - &dev, - byte_il, - Some(module.build_options.as_c_str()), - ); - (module, Some(log)) - } + let mut ctx = ptr::null_mut(); + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)); + let mut module = ptr::null_mut(); + cuda.cuModuleLoadData(&mut module, ptx_module.as_ptr() as _); + let mut kernel = ptr::null_mut(); + cuda.cuModuleGetFunction(&mut kernel, module, name.as_ptr()); + let mut inp_b = unsafe { mem::zeroed() }; + let mut out_b = unsafe { mem::zeroed() }; + cuda.cuMemAlloc_v2(&mut out_b, output.len() * mem::size_of::()); + let mut args = if let Some(input) = input { + cuda.cuMemAlloc_v2(&mut inp_b, input.len() * mem::size_of::()); + cuda.cuMemcpyHtoD_v2( + inp_b, + input.as_ptr() as _, + input.len() * mem::size_of::(), + ); + [&inp_b, &out_b] + } else { + [&out_b, &inp_b] }; - 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); - } + cuda.cuMemsetD8_v2(out_b, 0, output.len() * mem::size_of::()); + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + block_size_x, + 1, + 1, + 1024, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ); + cuda.cuMemcpyDtoH_v2( + result.as_mut_ptr() as _, + out_b, + output.len() * mem::size_of::(), + ); + cuda.cuStreamSynchronize(0 as _); + cuda.cuMemFree_v2(inp_b); + cuda.cuMemFree_v2(out_b); + cuda.cuModuleUnload(module); + cuda.cuCtxDestroy_v2(ctx); + } + result +} + +static mut COMGR: comgr::Result = + comgr::Result::Err(comgr::sys::amd_comgr_status_t::AMD_COMGR_STATUS_ERROR); +static COMGR_INIT: Once = Once::new(); + +fn get_comgr() -> comgr::Result<&'static Comgr> { + COMGR_INIT.call_once(|| unsafe { COMGR = Comgr::find_and_load() }); + match unsafe { &COMGR } { + Ok(c) => Ok(c), + Err(e) => Err(*e), + } +} + +fn run_hip + Copy + Debug, Output: From + Copy + Debug + Default>( + compilation_mode: CompilationMode, + name: &CStr, + module: translate::Module, + input: Option<&[Input]>, + output: &mut [Output], + block_size: [u32; 3], +) -> Result, hipError_t> { + use hip_runtime_sys::*; + let mut result = vec![0u8.into(); output.len()]; + let comgr = get_comgr().unwrap(); + let isa = unsafe { hip_common::comgr_isa(0)? }; + let compiled = comgr + .compile( + compilation_mode, + &isa, + module.get_bitcode_all(), + &module.metadata.to_elf_section(), + ) + .unwrap(); + hip_call! { hipInit(0) }; + { + let dev = 0; + let mut stream = ptr::null_mut(); + hip_call! { hipStreamCreateWithFlags(&mut stream, hipStreamNonBlocking) }; + let mut dev_props = unsafe { mem::zeroed() }; + hip_call! { hipGetDeviceProperties(&mut dev_props, dev) }; + let mut module = ptr::null_mut(); + hip_call! { hipModuleLoadData(&mut module, compiled.as_ptr() as _) }; + let mut kernel = ptr::null_mut(); + hip_call! { hipModuleGetFunction(&mut kernel, module, name.as_ptr()) }; + let mut inp_b = ptr::null_mut(); + let mut out_b = ptr::null_mut(); + hip_call! { hipMalloc(&mut out_b, output.len() * mem::size_of::()) }; + let mut args = if let Some(input) = input { + hip_call! { hipMalloc(&mut inp_b, input.len() * mem::size_of::()) }; + hip_call! { hipMemcpyWithStream(inp_b, input.as_ptr() as _, input.len() * mem::size_of::(), hipMemcpyKind::hipMemcpyHostToDevice, stream) }; + [&inp_b, &out_b] + } else { + [&out_b, &out_b] }; - 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::::new(&mut ctx, &dev, cmp::max(input.len(), 1))?; - let mut out_b = ze::DeviceBuffer::::new(&mut ctx, &dev, cmp::max(output.len(), 1))?; - let inp_b_ptr_mut: ze::BufferPtrMut = (&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 = (&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)?; + hip_call! { hipMemsetAsync(out_b, 0, output.len() * mem::size_of::(), stream) }; + hip_call! { hipModuleLaunchKernel(kernel, 1,1,1, block_size[0],block_size[1],block_size[2], 1024, stream, args.as_mut_ptr().cast(), ptr::null_mut()) }; + hip_call! { hipMemcpyAsync(result.as_mut_ptr() as _, out_b, output.len() * mem::size_of::(), hipMemcpyKind::hipMemcpyDeviceToHost, stream) }; + hip_call! { hipStreamSynchronize(stream) }; + hip_call! { hipFree(inp_b) }; + hip_call! { hipFree(out_b) }; + hip_call! { hipModuleUnload(module) }; } Ok(result) } -fn test_spvtxt_assert<'a>( +unsafe fn test_llvm_assert<'a>( ptx_txt: &'a str, - spirv_txt: &'a [u8], - spirv_file_name: &'a str, + llvm_ir: &'a [u8], + llvm_file_name: &'a str, ) -> Result<(), Box> { 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::::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()); + let llvm_module_from_ptx = translate::to_llvm_module(CompilationMode::Wave32, vec![ast])?; + let llvm_bitcode_from_ptx = llvm_module_from_ptx.get_bitcode_main(); + let mut llvm_ir_copy = llvm_ir.to_vec(); + llvm_ir_copy.push(0); + let reference_llvm_ir_buffer = llvm::MemoryBuffer::create_no_copy(&*llvm_ir_copy, true); + let reference_module = llvm::parse_ir_in_context( + &llvm_module_from_ptx._llvm_context, + reference_llvm_ir_buffer, + )?; + let reference_llvm_bitcode_buffer = + llvm::MemoryBuffer::from_ffi(LLVMWriteBitcodeToMemoryBuffer(reference_module.get())); + if reference_llvm_bitcode_buffer.as_slice() != llvm_bitcode_from_ptx.as_slice() { + let ptx_string = llvm_module_from_ptx.get_llvm_text(); + if ptx_string.as_cstr().to_bytes() != llvm_ir { + if let Ok(dump_path) = env::var("ZLUDA_TEST_LLVM_DUMP_DIR") { + let mut path = PathBuf::from(dump_path); + if let Ok(()) = fs::create_dir_all(&path) { + path.push(llvm_file_name); + fs::write(path, &*ptx_string.as_cstr().to_string_lossy()).ok(); } } + return Err(ptx_string.into()); } - panic!(spirv_text.to_string()); } - unsafe { spirv_tools::spvContextDestroy(spv_context) }; Ok(()) } -struct EqMap -where - T: Eq + Copy + Hash, -{ - m1: HashMap, - m2: HashMap, +unsafe fn test_compile_assert<'a>(ptx_txt: &'a str) -> Result<(), Box> { + let mut errors = Vec::new(); + let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_txt)?; + assert!(errors.is_empty()); + let zluda_module = translate::to_llvm_module(CompilationMode::Wave32, vec![ast])?; + let comgr = get_comgr().unwrap(); + let compilation_mode = CompilationMode::Wave32; + let isa = unsafe { CStr::from_bytes_with_nul_unchecked(b"amdgcn-amd-amdhsa--gfx1030\0") }; + comgr + .compile( + compilation_mode, + isa, + zluda_module.get_bitcode_all(), + &zluda_module.metadata.to_elf_section(), + ) + .unwrap(); + Ok(()) +} +pub(crate) struct CudaTestLibrary { + pub(crate) lib_handle: libloading::Library, } -impl EqMap { - fn new() -> Self { - EqMap { - m1: HashMap::new(), - m2: HashMap::new(), - } - } +impl CudaTestLibrary { + // We use full path because otherwise we will open ZLUDA's CUDA binary from target/debug + #[cfg(target_os = "windows")] + const CUDA_PATH: &'static str = "C:\\Windows\\System32\\nvcuda.dll"; + #[cfg(not(target_os = "windows"))] + const CUDA_PATH: &'static str = "/usr/lib/x86_64-linux-gnu/libcuda.so"; - 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, - } + unsafe fn new() -> Self { + let lib_handle = libloading::Library::new(Self::CUDA_PATH).unwrap(); + Self { lib_handle } } } -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) -> 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) -> 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; +macro_rules! emit_cuda_fn_table { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + impl CudaTestLibrary { + $( + #[allow(dead_code)] + unsafe fn $fn_name(&self, $($arg_id : $arg_type),*) { + let fn_ = self.lib_handle.get:: $ret_type>(stringify!($fn_name).as_bytes()).unwrap(); + let result = fn_($($arg_id),*); + if result != cuda_types::CUresult::CUDA_SUCCESS { + panic!("{:?}", result); + } } - } - (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) -> bool { - map.is_equal(*t1, *t2) -} - -fn is_option_equal) -> bool>( - o1: &Option, - o2: &Option, - map: &mut EqMap, - 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 = 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 = 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 -} +use cuda_base::cuda_function_declarations; +cuda_function_declarations!(cuda_types, emit_cuda_fn_table, emit_cuda_fn_table, []); diff --git a/ptx/src/test/spirv_run/mov.ll b/ptx/src/test/spirv_run/mov.ll new file mode 100644 index 0000000..e876ced --- /dev/null +++ b/ptx/src/test/spirv_run/mov.ll @@ -0,0 +1,34 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mov(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"22": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"20", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"15", ptr addrspace(5) %0, align 8 + %"14" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"21" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"21", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mov.spvtxt b/ptx/src/test/spirv_run/mov.spvtxt deleted file mode 100644 index 13473d9..0000000 --- a/ptx/src/test/spirv_run/mov.spvtxt +++ /dev/null @@ -1,46 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %18 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mov_address.ll b/ptx/src/test/spirv_run/mov_address.ll new file mode 100644 index 0000000..b9f3a8a --- /dev/null +++ b/ptx/src/test/spirv_run/mov_address.ll @@ -0,0 +1,20 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mov_address(ptr addrspace(4) byref(i64) %"9", ptr addrspace(4) byref(i64) %"10") #0 { +"12": + %"6" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"6", align 1 + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"4" = alloca [8 x i8], align 1, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"11" = ptrtoint ptr addrspace(5) %"4" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"11", ptr addrspace(5) %0, align 8 + %"8" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"8", ptr addrspace(5) %"5", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mov_address.spvtxt b/ptx/src/test/spirv_run/mov_address.spvtxt deleted file mode 100644 index 26ae21f..0000000 --- a/ptx/src/test/spirv_run/mov_address.spvtxt +++ /dev/null @@ -1,33 +0,0 @@ - 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/mov_vector_cast.ll b/ptx/src/test/spirv_run/mov_vector_cast.ll new file mode 100644 index 0000000..1f52a3b --- /dev/null +++ b/ptx/src/test/spirv_run/mov_vector_cast.ll @@ -0,0 +1,67 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mov_vector_cast(ptr addrspace(4) byref(i64) %"35", ptr addrspace(4) byref(i64) %"36") #0 { +"50": + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"16" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"16", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca half, align 2, addrspace(5) + %"10" = alloca half, align 2, addrspace(5) + %"11" = alloca half, align 2, addrspace(5) + %"12" = alloca half, align 2, addrspace(5) + %"17" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"17", ptr addrspace(5) %"4", align 8 + %"18" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"18", ptr addrspace(5) %"5", align 8 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"20" to ptr + %"19" = load i64, ptr %"37", align 8 + store i64 %"19", ptr addrspace(5) %"6", align 8 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"21", ptr addrspace(5) %0, align 8 + %"13" = load i64, ptr addrspace(5) %0, align 8 + %"39" = bitcast i64 %"13" to <2 x i32> + %"40" = extractelement <2 x i32> %"39", i32 0 + %"41" = extractelement <2 x i32> %"39", i32 1 + %"22" = bitcast i32 %"40" to float + %"23" = bitcast i32 %"41" to float + store float %"22", ptr addrspace(5) %"7", align 4 + store float %"23", ptr addrspace(5) %"8", align 4 + %"24" = load i64, ptr addrspace(5) %"6", align 8 + %1 = alloca i64, align 8, addrspace(5) + store i64 %"24", ptr addrspace(5) %1, align 8 + %"14" = load i64, ptr addrspace(5) %1, align 8 + %"43" = bitcast i64 %"14" to <4 x i16> + %"44" = extractelement <4 x i16> %"43", i32 0 + %"45" = extractelement <4 x i16> %"43", i32 1 + %"46" = extractelement <4 x i16> %"43", i32 2 + %"47" = extractelement <4 x i16> %"43", i32 3 + %"25" = bitcast i16 %"44" to half + %"26" = bitcast i16 %"45" to half + %"27" = bitcast i16 %"46" to half + %"28" = bitcast i16 %"47" to half + store half %"25", ptr addrspace(5) %"9", align 2 + store half %"26", ptr addrspace(5) %"10", align 2 + store half %"27", ptr addrspace(5) %"11", align 2 + store half %"28", ptr addrspace(5) %"12", align 2 + %"29" = load i64, ptr addrspace(5) %"5", align 8 + %"30" = load float, ptr addrspace(5) %"8", align 4 + %"48" = inttoptr i64 %"29" to ptr + store float %"30", ptr %"48", align 4 + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load float, ptr addrspace(5) %"7", align 4 + %"49" = inttoptr i64 %"31" to ptr + %"52" = getelementptr inbounds i8, ptr %"49", i64 4 + store float %"32", ptr %"52", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mov_vector_cast.ptx b/ptx/src/test/spirv_run/mov_vector_cast.ptx new file mode 100644 index 0000000..7c56e22 --- /dev/null +++ b/ptx/src/test/spirv_run/mov_vector_cast.ptx @@ -0,0 +1,30 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry mov_vector_cast( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp_wide; + .reg .f32 temp1; + .reg .f32 temp2; + .reg .f16 temp3; + .reg .f16 temp4; + .reg .f16 temp5; + .reg .f16 temp6; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u64 temp_wide, [in_addr]; + mov.b64 {temp1, temp2}, temp_wide; + mov.b64 {temp3, temp4, temp5, temp6}, temp_wide; + st.f32 [out_addr], temp2; + st.f32 [out_addr+4], temp1; + + ret; +} diff --git a/ptx/src/test/spirv_run/mul_ftz.ll b/ptx/src/test/spirv_run/mul_ftz.ll new file mode 100644 index 0000000..04de6f2 --- /dev/null +++ b/ptx/src/test/spirv_run/mul_ftz.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mul_ftz(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load float, ptr %"25", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load float, ptr %"30", align 4 + store float %"14", ptr addrspace(5) %"7", align 4 + %"17" = load float, ptr addrspace(5) %"6", align 4 + %"18" = load float, ptr addrspace(5) %"7", align 4 + %"16" = fmul float %"17", %"18" + store float %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store float %"20", ptr %"27", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mul_ftz.spvtxt b/ptx/src/test/spirv_run/mul_ftz.spvtxt deleted file mode 100644 index ed268fb..0000000 --- a/ptx/src/test/spirv_run/mul_ftz.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_float %22 - %14 = OpLoad %float %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_hi.ll b/ptx/src/test/spirv_run/mul_hi.ll new file mode 100644 index 0000000..e57141b --- /dev/null +++ b/ptx/src/test/spirv_run/mul_hi.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i64 @__zluda_ptx_impl__mul_hi_u64(i64, i64) #0 + +define protected amdgpu_kernel void @mul_hi(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #1 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = call i64 @__zluda_ptx_impl__mul_hi_u64(i64 %"15", i64 2) + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mul_hi.spvtxt b/ptx/src/test/spirv_run/mul_hi.spvtxt deleted file mode 100644 index 93537b3..0000000 --- a/ptx/src/test/spirv_run/mul_hi.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_lo.ll b/ptx/src/test/spirv_run/mul_lo.ll new file mode 100644 index 0000000..1a915fa --- /dev/null +++ b/ptx/src/test/spirv_run/mul_lo.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mul_lo(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = mul i64 %"15", 2 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mul_lo.spvtxt b/ptx/src/test/spirv_run/mul_lo.spvtxt deleted file mode 100644 index 7d69cfb..0000000 --- a/ptx/src/test/spirv_run/mul_lo.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_non_ftz.ll b/ptx/src/test/spirv_run/mul_non_ftz.ll new file mode 100644 index 0000000..d0d2bcd --- /dev/null +++ b/ptx/src/test/spirv_run/mul_non_ftz.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mul_non_ftz(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load float, ptr %"25", align 4 + store float %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load float, ptr %"30", align 4 + store float %"14", ptr addrspace(5) %"7", align 4 + %"17" = load float, ptr addrspace(5) %"6", align 4 + %"18" = load float, ptr addrspace(5) %"7", align 4 + %"16" = fmul float %"17", %"18" + store float %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load float, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store float %"20", ptr %"27", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mul_non_ftz.spvtxt b/ptx/src/test/spirv_run/mul_non_ftz.spvtxt deleted file mode 100644 index 436aca1..0000000 --- a/ptx/src/test/spirv_run/mul_non_ftz.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_float %22 - %14 = OpLoad %float %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_wide.ll b/ptx/src/test/spirv_run/mul_wide.ll new file mode 100644 index 0000000..b1dec22 --- /dev/null +++ b/ptx/src/test/spirv_run/mul_wide.ll @@ -0,0 +1,41 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @mul_wide(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"30": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"14" to ptr addrspace(1) + %"13" = load i32, ptr addrspace(1) %"26", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"16" to ptr addrspace(1) + %"32" = getelementptr inbounds i8, ptr addrspace(1) %"27", i64 4 + %"15" = load i32, ptr addrspace(1) %"32", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i32, ptr addrspace(5) %"6", align 4 + %"19" = load i32, ptr addrspace(5) %"7", align 4 + %0 = sext i32 %"18" to i64 + %1 = sext i32 %"19" to i64 + %"17" = mul nsw i64 %0, %1 + store i64 %"17", ptr addrspace(5) %"8", align 8 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i64, ptr addrspace(5) %"8", align 8 + %"28" = inttoptr i64 %"20" to ptr + store i64 %"21", ptr %"28", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/mul_wide.spvtxt b/ptx/src/test/spirv_run/mul_wide.spvtxt deleted file mode 100644 index 7ac81cf..0000000 --- a/ptx/src/test/spirv_run/mul_wide.spvtxt +++ /dev/null @@ -1,64 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14 - %13 = OpLoad %uint %24 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %23 = OpIAdd %ulong %16 %ulong_4 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %23 - %15 = OpLoad %uint %25 Aligned 4 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/multireg.ll b/ptx/src/test/spirv_run/multireg.ll new file mode 100644 index 0000000..3826c19 --- /dev/null +++ b/ptx/src/test/spirv_run/multireg.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @multireg(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = add i64 %"15", 1 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/multireg.ptx b/ptx/src/test/spirv_run/multireg.ptx new file mode 100644 index 0000000..0e711a1 --- /dev/null +++ b/ptx/src/test/spirv_run/multireg.ptx @@ -0,0 +1,19 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry multireg( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr, out_addr, temp<2>; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u64 temp0, [in_addr]; + add.u64 temp1, temp0, 1; + st.u64 [out_addr], temp1; + ret; +} diff --git a/ptx/src/test/spirv_run/neg.ll b/ptx/src/test/spirv_run/neg.ll new file mode 100644 index 0000000..c1087b4 --- /dev/null +++ b/ptx/src/test/spirv_run/neg.ll @@ -0,0 +1,31 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @neg(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load i32, ptr %"19", align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"13" = sub i32 0, %"14" + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store i32 %"16", ptr %"20", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/neg.spvtxt b/ptx/src/test/spirv_run/neg.spvtxt deleted file mode 100644 index d5ab925..0000000 --- a/ptx/src/test/spirv_run/neg.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/non_scalar_ptr_offset.ll b/ptx/src/test/spirv_run/non_scalar_ptr_offset.ll new file mode 100644 index 0000000..718a512 --- /dev/null +++ b/ptx/src/test/spirv_run/non_scalar_ptr_offset.ll @@ -0,0 +1,37 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @non_scalar_ptr_offset(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"27": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr addrspace(1) + %"29" = getelementptr inbounds i8, ptr addrspace(1) %"25", i64 8 + %"8" = load <2 x i32>, ptr addrspace(1) %"29", align 8 + %"14" = extractelement <2 x i32> %"8", i32 0 + %"15" = extractelement <2 x i32> %"8", i32 1 + store i32 %"14", ptr addrspace(5) %"6", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"16" = add i32 %"17", %"18" + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"26" = inttoptr i64 %"19" to ptr addrspace(1) + store i32 %"20", ptr addrspace(1) %"26", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/non_scalar_ptr_offset.ptx b/ptx/src/test/spirv_run/non_scalar_ptr_offset.ptx new file mode 100644 index 0000000..14d3d2c --- /dev/null +++ b/ptx/src/test/spirv_run/non_scalar_ptr_offset.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry non_scalar_ptr_offset( + .param .u64 input_p, + .param .u64 output_p +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 x; + .reg .u32 y; + + ld.param.u64 in_addr, [input_p]; + ld.param.u64 out_addr, [output_p]; + + ld.global.v2.u32 {x,y}, [in_addr+8]; + add.u32 x, x, y; + st.global.u32 [out_addr], x; + ret; +} diff --git a/ptx/src/test/spirv_run/not.ll b/ptx/src/test/spirv_run/not.ll new file mode 100644 index 0000000..10dd56c --- /dev/null +++ b/ptx/src/test/spirv_run/not.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @not(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"20", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"21" = xor i64 %"15", -1 + store i64 %"21", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"23" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"23", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/not.spvtxt b/ptx/src/test/spirv_run/not.spvtxt deleted file mode 100644 index 655a892..0000000 --- a/ptx/src/test/spirv_run/not.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %18 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ntid.ll b/ptx/src/test/spirv_run/ntid.ll new file mode 100644 index 0000000..93c95bf --- /dev/null +++ b/ptx/src/test/spirv_run/ntid.ll @@ -0,0 +1,41 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__sreg_ntid(i8) #0 + +define protected amdgpu_kernel void @ntid(ptr addrspace(4) byref(i64) %"26", ptr addrspace(4) byref(i64) %"27") #1 { +"30": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"16", ptr addrspace(5) %"4", align 8 + %"17" = load i64, ptr addrspace(4) %"27", align 8 + store i64 %"17", ptr addrspace(5) %"5", align 8 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"28" = inttoptr i64 %"19" to ptr + %"18" = load i32, ptr %"28", align 4 + store i32 %"18", ptr addrspace(5) %"6", align 4 + %"12" = call i32 @__zluda_ptx_impl__sreg_ntid(i8 0) + %0 = alloca i32, align 4, addrspace(5) + store i32 %"12", ptr addrspace(5) %0, align 4 + %"20" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"20", ptr addrspace(5) %"7", align 4 + %"22" = load i32, ptr addrspace(5) %"6", align 4 + %"23" = load i32, ptr addrspace(5) %"7", align 4 + %"21" = add i32 %"22", %"23" + store i32 %"21", ptr addrspace(5) %"6", align 4 + %"24" = load i64, ptr addrspace(5) %"5", align 8 + %"25" = load i32, ptr addrspace(5) %"6", align 4 + %"29" = inttoptr i64 %"24" to ptr + store i32 %"25", ptr %"29", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/ntid.spvtxt b/ptx/src/test/spirv_run/ntid.spvtxt deleted file mode 100644 index 7b5a630..0000000 --- a/ptx/src/test/spirv_run/ntid.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - 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 "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 - %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 - %1 = OpFunction %void None %33 - %9 = OpFunctionParameter %ulong - %10 = 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 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %24 Aligned 4 - OpStore %6 %13 - %38 = OpLoad %v3ulong %gl_WorkGroupSize - %23 = OpCompositeExtract %ulong %38 0 - %39 = OpBitcast %ulong %23 - %16 = OpUConvert %uint %39 - %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 - %25 = OpConvertUToPtr %_ptr_Generic_uint %20 - OpStore %25 %21 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/or.ll b/ptx/src/test/spirv_run/or.ll new file mode 100644 index 0000000..13e844b --- /dev/null +++ b/ptx/src/test/spirv_run/or.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @or(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"31": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"25", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"33" = getelementptr inbounds i8, ptr %"26", i64 8 + %"14" = load i64, ptr %"33", align 8 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"17" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = load i64, ptr addrspace(5) %"7", align 8 + %"27" = or i64 %"17", %"18" + store i64 %"27", ptr addrspace(5) %"6", align 8 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i64, ptr addrspace(5) %"6", align 8 + %"30" = inttoptr i64 %"19" to ptr + store i64 %"20", ptr %"30", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/or.spvtxt b/ptx/src/test/spirv_run/or.spvtxt deleted file mode 100644 index fef3f40..0000000 --- a/ptx/src/test/spirv_run/or.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %23 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_8 - %24 = OpConvertUToPtr %_ptr_Generic_ulong %22 - %14 = OpLoad %ulong %24 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/param_ptr.ll b/ptx/src/test/spirv_run/param_ptr.ll new file mode 100644 index 0000000..3634669 --- /dev/null +++ b/ptx/src/test/spirv_run/param_ptr.ll @@ -0,0 +1,40 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @param_ptr(ptr addrspace(4) byref(i64) %"22", ptr addrspace(4) byref(i64) %"23") #0 { +"29": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"25" = ptrtoint ptr addrspace(4) %"22" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"25", ptr addrspace(5) %0, align 8 + %"24" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"24", ptr addrspace(5) %"4", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"13" to ptr addrspace(4) + %"12" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"14", ptr addrspace(5) %"6", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"27" = inttoptr i64 %"16" to ptr + %"15" = load i64, ptr %"27", align 8 + store i64 %"15", ptr addrspace(5) %"7", align 8 + %"18" = load i64, ptr addrspace(5) %"7", align 8 + %"17" = add i64 %"18", 1 + store i64 %"17", ptr addrspace(5) %"8", align 8 + %"19" = load i64, ptr addrspace(5) %"6", align 8 + %"20" = load i64, ptr addrspace(5) %"8", align 8 + %"28" = inttoptr i64 %"19" to ptr + store i64 %"20", ptr %"28", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/param_ptr.ptx b/ptx/src/test/spirv_run/param_ptr.ptx new file mode 100644 index 0000000..2539ef3 --- /dev/null +++ b/ptx/src/test/spirv_run/param_ptr.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry param_ptr( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 ptr; + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + + mov.b64 ptr, input; + + ld.param.u64 in_addr, [ptr]; + 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/popc.ll b/ptx/src/test/spirv_run/popc.ll new file mode 100644 index 0000000..e93f8ad --- /dev/null +++ b/ptx/src/test/spirv_run/popc.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @popc(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load i32, ptr %"19", align 4 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"13" = call i32 @llvm.ctpop.i32(i32 %"14") + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load i32, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store i32 %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.ctpop.i32(i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/popc.spvtxt b/ptx/src/test/spirv_run/popc.spvtxt deleted file mode 100644 index 845add7..0000000 --- a/ptx/src/test/spirv_run/popc.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/pred_not.ll b/ptx/src/test/spirv_run/pred_not.ll new file mode 100644 index 0000000..047f94a --- /dev/null +++ b/ptx/src/test/spirv_run/pred_not.ll @@ -0,0 +1,65 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @pred_not(ptr addrspace(4) byref(i64) %"37", ptr addrspace(4) byref(i64) %"38") #0 { +"42": + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"37", align 8 + store i64 %"16", ptr addrspace(5) %"4", align 8 + %"17" = load i64, ptr addrspace(4) %"38", align 8 + store i64 %"17", ptr addrspace(5) %"5", align 8 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"39" = inttoptr i64 %"19" to ptr + %"18" = load i64, ptr %"39", align 8 + store i64 %"18", ptr addrspace(5) %"6", align 8 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"40" = inttoptr i64 %"21" to ptr + %"44" = getelementptr inbounds i8, ptr %"40", i64 8 + %"20" = load i64, ptr %"44", align 8 + store i64 %"20", ptr addrspace(5) %"7", align 8 + %"23" = load i64, ptr addrspace(5) %"6", align 8 + %"24" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = icmp ult i64 %"23", %"24" + store i1 %"22", ptr addrspace(5) %"9", align 1 + %"26" = load i1, ptr addrspace(5) %"9", align 1 + %"25" = xor i1 %"26", true + store i1 %"25", ptr addrspace(5) %"9", align 1 + %"27" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"27", label %"10", label %"11" + +"10": ; preds = %"42" + %0 = alloca i64, align 8, addrspace(5) + store i64 1, ptr addrspace(5) %0, align 8 + %"28" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"28", ptr addrspace(5) %"8", align 8 + br label %"11" + +"11": ; preds = %"10", %"42" + %"29" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"29", label %"13", label %"12" + +"12": ; preds = %"11" + %1 = alloca i64, align 8, addrspace(5) + store i64 2, ptr addrspace(5) %1, align 8 + %"30" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"30", ptr addrspace(5) %"8", align 8 + br label %"13" + +"13": ; preds = %"12", %"11" + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load i64, ptr addrspace(5) %"8", align 8 + %"41" = inttoptr i64 %"31" to ptr + store i64 %"32", ptr %"41", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/pred_not.spvtxt b/ptx/src/test/spirv_run/pred_not.spvtxt deleted file mode 100644 index 18fde05..0000000 --- a/ptx/src/test/spirv_run/pred_not.spvtxt +++ /dev/null @@ -1,78 +0,0 @@ - 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 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %37 = OpConvertUToPtr %_ptr_Generic_ulong %19 - %18 = OpLoad %ulong %37 Aligned 8 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %34 = OpIAdd %ulong %21 %ulong_8 - %38 = OpConvertUToPtr %_ptr_Generic_ulong %34 - %20 = OpLoad %ulong %38 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/prmt.ll b/ptx/src/test/spirv_run/prmt.ll new file mode 100644 index 0000000..a901ce4 --- /dev/null +++ b/ptx/src/test/spirv_run/prmt.ll @@ -0,0 +1,41 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @prmt(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"31": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"33" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"33", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %0 = bitcast i32 %"17" to <4 x i8> + %1 = bitcast i32 %"18" to <4 x i8> + %2 = shufflevector <4 x i8> %0, <4 x i8> %1, <4 x i32> + %"27" = bitcast <4 x i8> %2 to i32 + store i32 %"27", ptr addrspace(5) %"7", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"7", align 4 + %"30" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"30", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/prmt.ptx b/ptx/src/test/spirv_run/prmt.ptx new file mode 100644 index 0000000..ba339e8 --- /dev/null +++ b/ptx/src/test/spirv_run/prmt.ptx @@ -0,0 +1,23 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry prmt( + .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]; + prmt.b32 temp2, temp1, temp2, 30212; + st.u32 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/prmt_non_immediate.ll b/ptx/src/test/spirv_run/prmt_non_immediate.ll new file mode 100644 index 0000000..c1a1b9d --- /dev/null +++ b/ptx/src/test/spirv_run/prmt_non_immediate.ll @@ -0,0 +1,46 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @prmt_non_immediate(ptr addrspace(4) byref(i64) %"26", ptr addrspace(4) byref(i64) %"27") #0 { +"34": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"27", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"28" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"28", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"29" = inttoptr i64 %"16" to ptr + %"36" = getelementptr inbounds i8, ptr %"29", i64 4 + %"15" = load i32, ptr %"36", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %0 = alloca i32, align 4, addrspace(5) + store i32 64, ptr addrspace(5) %0, align 4 + %"17" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"19" = load i32, ptr addrspace(5) %"6", align 4 + %"20" = load i32, ptr addrspace(5) %"7", align 4 + %1 = bitcast i32 %"19" to <4 x i8> + %2 = bitcast i32 %"20" to <4 x i8> + %3 = shufflevector <4 x i8> %1, <4 x i8> %2, <4 x i32> + %"30" = bitcast <4 x i8> %3 to i32 + store i32 %"30", ptr addrspace(5) %"7", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load i32, ptr addrspace(5) %"7", align 4 + %"33" = inttoptr i64 %"21" to ptr + store i32 %"22", ptr %"33", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/prmt_non_immediate.ptx b/ptx/src/test/spirv_run/prmt_non_immediate.ptx new file mode 100644 index 0000000..6693621 --- /dev/null +++ b/ptx/src/test/spirv_run/prmt_non_immediate.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry prmt_non_immediate( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp1; + .reg .u32 temp2; + .reg .u32 control; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp1, [in_addr]; + ld.u32 temp2, [in_addr+4]; + mov.u32 control, 64; + prmt.b32 temp2, temp1, temp2, control; + st.u32 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/rcp.ll b/ptx/src/test/spirv_run/rcp.ll new file mode 100644 index 0000000..cb55c6a --- /dev/null +++ b/ptx/src/test/spirv_run/rcp.ll @@ -0,0 +1,31 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @rcp(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"19", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = fdiv arcp afn float 1.000000e+00, %"14" + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"20", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/rcp.spvtxt b/ptx/src/test/spirv_run/rcp.spvtxt deleted file mode 100644 index 2d56ee8..0000000 --- a/ptx/src/test/spirv_run/rcp.spvtxt +++ /dev/null @@ -1,49 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/red_shared.ptx b/ptx/src/test/spirv_run/red_shared.ptx new file mode 100644 index 0000000..2630057 --- /dev/null +++ b/ptx/src/test/spirv_run/red_shared.ptx @@ -0,0 +1,39 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.shared .b32 shmem[64]; + +.visible .entry red_shared( + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u32 tid; + .reg .u32 tid_1; + .reg .u64 tid_64; + .reg .u32 result; + .reg .u32 shmem_tid_addr; + .reg .u32 temp1; + .reg .u32 shmem_copy; + + ld.param.u64 out_addr, [output]; + mov.b32 tid, %tid.x; + cvt.u64.u32 tid_64, tid; + + mov.b32 shmem_tid_addr, shmem; + mad.lo.u32 shmem_tid_addr, tid, 4, shmem_tid_addr; + add.u32 tid_1, tid, 1; + st.shared.u32 [shmem_tid_addr], tid_1; + bar.sync 0; + rem.u32 temp1, tid, 2; + mov.u32 shmem_copy, shmem; + mad.lo.u32 shmem_copy, 4, temp1, shmem_copy; + red.shared.add.u32 [shmem_copy], tid_1; + bar.sync 0; + ld.shared.u32 result, [shmem_tid_addr]; + + mad.lo.u64 out_addr, tid_64, 4, out_addr; + st.u32 [out_addr], result; + ret; +} diff --git a/ptx/src/test/spirv_run/reg_local.ll b/ptx/src/test/spirv_run/reg_local.ll new file mode 100644 index 0000000..c01a5e0 --- /dev/null +++ b/ptx/src/test/spirv_run/reg_local.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @reg_local(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"34": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca [8 x i8], align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"11" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"11", ptr addrspace(5) %"6", align 8 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"27" = inttoptr i64 %"13" to ptr addrspace(1) + %"26" = load i64, ptr addrspace(1) %"27", align 8 + store i64 %"26", ptr addrspace(5) %"7", align 8 + %"14" = load i64, ptr addrspace(5) %"7", align 8 + %"19" = add i64 %"14", 1 + %"28" = addrspacecast ptr addrspace(5) %"4" to ptr + store i64 %"19", ptr %"28", align 8 + %"30" = addrspacecast ptr addrspace(5) %"4" to ptr + %"38" = getelementptr inbounds i8, ptr %"30", i64 0 + %"31" = load i64, ptr %"38", align 8 + store i64 %"31", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"6", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"32" = inttoptr i64 %"16" to ptr addrspace(1) + %"40" = getelementptr inbounds i8, ptr addrspace(1) %"32", i64 0 + store i64 %"17", ptr addrspace(1) %"40", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/reg_local.spvtxt b/ptx/src/test/spirv_run/reg_local.spvtxt deleted file mode 100644 index 7bb5bd9..0000000 --- a/ptx/src/test/spirv_run/reg_local.spvtxt +++ /dev/null @@ -1,69 +0,0 @@ - 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 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13 - %24 = OpLoad %ulong %25 Aligned 8 - %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 Aligned 8 - %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 Aligned 8 - %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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/rem.ll b/ptx/src/test/spirv_run/rem.ll new file mode 100644 index 0000000..3a1e26c --- /dev/null +++ b/ptx/src/test/spirv_run/rem.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @rem(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"30", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"16" = srem i32 %"17", %"18" + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"27", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/rem.spvtxt b/ptx/src/test/spirv_run/rem.spvtxt deleted file mode 100644 index ce1d3e6..0000000 --- a/ptx/src/test/spirv_run/rem.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %22 - %14 = OpLoad %uint %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/rsqrt.ll b/ptx/src/test/spirv_run/rsqrt.ll new file mode 100644 index 0000000..ffdd662 --- /dev/null +++ b/ptx/src/test/spirv_run/rsqrt.ll @@ -0,0 +1,36 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @rsqrt(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca double, align 8, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load double, ptr %"19", align 8 + store double %"11", ptr addrspace(5) %"6", align 8 + %"14" = load double, ptr addrspace(5) %"6", align 8 + %0 = call afn double @llvm.sqrt.f64(double %"14") + %"13" = fdiv arcp afn double 1.000000e+00, %0 + store double %"13", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load double, ptr addrspace(5) %"6", align 8 + %"20" = inttoptr i64 %"15" to ptr + store double %"16", ptr %"20", align 8 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare double @llvm.sqrt.f64(double) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/rsqrt.spvtxt b/ptx/src/test/spirv_run/rsqrt.spvtxt deleted file mode 100644 index fc1a7e1..0000000 --- a/ptx/src/test/spirv_run/rsqrt.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_double %12 - %11 = OpLoad %double %17 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/s64_min.ll b/ptx/src/test/spirv_run/s64_min.ll new file mode 100644 index 0000000..3f741e7 --- /dev/null +++ b/ptx/src/test/spirv_run/s64_min.ll @@ -0,0 +1,25 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @s64_min(ptr addrspace(4) byref(i64) %"13", ptr addrspace(4) byref(i64) %"14") #0 { +"16": + %"6" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"6", align 1 + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"8" = load i64, ptr addrspace(4) %"14", align 8 + store i64 %"8", ptr addrspace(5) %"4", align 8 + %0 = alloca i64, align 8, addrspace(5) + store i64 -9223372036854775808, ptr addrspace(5) %0, align 8 + %"9" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"9", ptr addrspace(5) %"5", align 8 + %"10" = load i64, ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(5) %"5", align 8 + %"15" = inttoptr i64 %"10" to ptr + store i64 %"11", ptr %"15", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/s64_min.ptx b/ptx/src/test/spirv_run/s64_min.ptx new file mode 100644 index 0000000..fd4505b --- /dev/null +++ b/ptx/src/test/spirv_run/s64_min.ptx @@ -0,0 +1,17 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry s64_min( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .s64 min; + + ld.param.u64 out_addr, [output]; + mov.s64 min, -9223372036854775808; + st.s64 [out_addr], min; + ret; +} diff --git a/ptx/src/test/spirv_run/selp.ll b/ptx/src/test/spirv_run/selp.ll new file mode 100644 index 0000000..6124887 --- /dev/null +++ b/ptx/src/test/spirv_run/selp.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @selp(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"29": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i16, align 2, addrspace(5) + %"7" = alloca i16, align 2, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"13" to ptr + %"12" = load i16, ptr %"26", align 2 + store i16 %"12", ptr addrspace(5) %"6", align 2 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"15" to ptr + %"31" = getelementptr inbounds i8, ptr %"27", i64 2 + %"14" = load i16, ptr %"31", align 2 + store i16 %"14", ptr addrspace(5) %"7", align 2 + %"17" = load i16, ptr addrspace(5) %"6", align 2 + %"18" = load i16, ptr addrspace(5) %"7", align 2 + %"16" = select i1 false, i16 %"17", i16 %"18" + store i16 %"16", ptr addrspace(5) %"6", align 2 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i16, ptr addrspace(5) %"6", align 2 + %"28" = inttoptr i64 %"19" to ptr + store i16 %"20", ptr %"28", align 2 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/selp.spvtxt b/ptx/src/test/spirv_run/selp.spvtxt deleted file mode 100644 index 9798758..0000000 --- a/ptx/src/test/spirv_run/selp.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ushort %13 - %12 = OpLoad %ushort %24 Aligned 2 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_2 - %25 = OpConvertUToPtr %_ptr_Generic_ushort %22 - %14 = OpLoad %ushort %25 Aligned 2 - 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 Aligned 2 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/selp_true.ll b/ptx/src/test/spirv_run/selp_true.ll new file mode 100644 index 0000000..283eb81 --- /dev/null +++ b/ptx/src/test/spirv_run/selp_true.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @selp_true(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"29": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i16, align 2, addrspace(5) + %"7" = alloca i16, align 2, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"13" to ptr + %"12" = load i16, ptr %"26", align 2 + store i16 %"12", ptr addrspace(5) %"6", align 2 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"15" to ptr + %"31" = getelementptr inbounds i8, ptr %"27", i64 2 + %"14" = load i16, ptr %"31", align 2 + store i16 %"14", ptr addrspace(5) %"7", align 2 + %"17" = load i16, ptr addrspace(5) %"6", align 2 + %"18" = load i16, ptr addrspace(5) %"7", align 2 + %"16" = select i1 true, i16 %"17", i16 %"18" + store i16 %"16", ptr addrspace(5) %"6", align 2 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i16, ptr addrspace(5) %"6", align 2 + %"28" = inttoptr i64 %"19" to ptr + store i16 %"20", ptr %"28", align 2 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/selp_true.spvtxt b/ptx/src/test/spirv_run/selp_true.spvtxt deleted file mode 100644 index f7038e0..0000000 --- a/ptx/src/test/spirv_run/selp_true.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ushort %13 - %12 = OpLoad %ushort %24 Aligned 2 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_2 - %25 = OpConvertUToPtr %_ptr_Generic_ushort %22 - %14 = OpLoad %ushort %25 Aligned 2 - 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 Aligned 2 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp.ll b/ptx/src/test/spirv_run/setp.ll new file mode 100644 index 0000000..a54f8f6 --- /dev/null +++ b/ptx/src/test/spirv_run/setp.ll @@ -0,0 +1,62 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp(ptr addrspace(4) byref(i64) %"35", ptr addrspace(4) byref(i64) %"36") #0 { +"40": + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"16", ptr addrspace(5) %"4", align 8 + %"17" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"17", ptr addrspace(5) %"5", align 8 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"19" to ptr + %"18" = load i64, ptr %"37", align 8 + store i64 %"18", ptr addrspace(5) %"6", align 8 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"38" = inttoptr i64 %"21" to ptr + %"42" = getelementptr inbounds i8, ptr %"38", i64 8 + %"20" = load i64, ptr %"42", align 8 + store i64 %"20", ptr addrspace(5) %"7", align 8 + %"23" = load i64, ptr addrspace(5) %"6", align 8 + %"24" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = icmp ult i64 %"23", %"24" + store i1 %"22", ptr addrspace(5) %"9", align 1 + %"25" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"25", label %"10", label %"11" + +"10": ; preds = %"40" + %0 = alloca i64, align 8, addrspace(5) + store i64 1, ptr addrspace(5) %0, align 8 + %"26" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"26", ptr addrspace(5) %"8", align 8 + br label %"11" + +"11": ; preds = %"10", %"40" + %"27" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"27", label %"13", label %"12" + +"12": ; preds = %"11" + %1 = alloca i64, align 8, addrspace(5) + store i64 2, ptr addrspace(5) %1, align 8 + %"28" = load i64, ptr addrspace(5) %1, align 8 + store i64 %"28", ptr addrspace(5) %"8", align 8 + br label %"13" + +"13": ; preds = %"12", %"11" + %"29" = load i64, ptr addrspace(5) %"5", align 8 + %"30" = load i64, ptr addrspace(5) %"8", align 8 + %"39" = inttoptr i64 %"29" to ptr + store i64 %"30", ptr %"39", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp.spvtxt b/ptx/src/test/spirv_run/setp.spvtxt deleted file mode 100644 index c3129e3..0000000 --- a/ptx/src/test/spirv_run/setp.spvtxt +++ /dev/null @@ -1,73 +0,0 @@ - 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 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_ulong %19 - %18 = OpLoad %ulong %35 Aligned 8 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %32 = OpIAdd %ulong %21 %ulong_8 - %36 = OpConvertUToPtr %_ptr_Generic_ulong %32 - %20 = OpLoad %ulong %36 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_bool.ll b/ptx/src/test/spirv_run/setp_bool.ll new file mode 100644 index 0000000..1707a3d --- /dev/null +++ b/ptx/src/test/spirv_run/setp_bool.ll @@ -0,0 +1,80 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_bool(ptr addrspace(4) byref(i64) %"45", ptr addrspace(4) byref(i64) %"46") #0 { +"51": + %"16" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"16", align 1 + %"17" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"17", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"10" = alloca i1, align 1, addrspace(5) + %"11" = alloca i1, align 1, addrspace(5) + %"18" = load i64, ptr addrspace(4) %"45", align 8 + store i64 %"18", ptr addrspace(5) %"4", align 8 + %"19" = load i64, ptr addrspace(4) %"46", align 8 + store i64 %"19", ptr addrspace(5) %"5", align 8 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"47" = inttoptr i64 %"21" to ptr + %"20" = load float, ptr %"47", align 4 + store float %"20", ptr addrspace(5) %"6", align 4 + %"23" = load i64, ptr addrspace(5) %"4", align 8 + %"48" = inttoptr i64 %"23" to ptr + %"53" = getelementptr inbounds i8, ptr %"48", i64 4 + %"22" = load float, ptr %"53", align 4 + store float %"22", ptr addrspace(5) %"7", align 4 + %"25" = load i64, ptr addrspace(5) %"4", align 8 + %"49" = inttoptr i64 %"25" to ptr + %"55" = getelementptr inbounds i8, ptr %"49", i64 8 + %"24" = load float, ptr %"55", align 4 + store float %"24", ptr addrspace(5) %"8", align 4 + %0 = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %0, align 1 + %"26" = load i1, ptr addrspace(5) %0, align 1 + store i1 %"26", ptr addrspace(5) %"9", align 1 + %"29" = load float, ptr addrspace(5) %"6", align 4 + %"30" = load float, ptr addrspace(5) %"7", align 4 + %"31" = load i1, ptr addrspace(5) %"9", align 1 + %1 = fcmp ogt float %"29", %"30" + %2 = xor i1 %1, true + %"27" = and i1 %1, %"31" + %"28" = and i1 %2, %"31" + store i1 %"27", ptr addrspace(5) %"10", align 1 + store i1 %"28", ptr addrspace(5) %"11", align 1 + %"32" = load i1, ptr addrspace(5) %"10", align 1 + br i1 %"32", label %"12", label %"13" + +"12": ; preds = %"51" + %"34" = load float, ptr addrspace(5) %"6", align 4 + %3 = alloca float, align 4, addrspace(5) + store float %"34", ptr addrspace(5) %3, align 4 + %"33" = load float, ptr addrspace(5) %3, align 4 + store float %"33", ptr addrspace(5) %"8", align 4 + br label %"13" + +"13": ; preds = %"12", %"51" + %"35" = load i1, ptr addrspace(5) %"11", align 1 + br i1 %"35", label %"14", label %"15" + +"14": ; preds = %"13" + %"37" = load float, ptr addrspace(5) %"7", align 4 + %4 = alloca float, align 4, addrspace(5) + store float %"37", ptr addrspace(5) %4, align 4 + %"36" = load float, ptr addrspace(5) %4, align 4 + store float %"36", ptr addrspace(5) %"8", align 4 + br label %"15" + +"15": ; preds = %"14", %"13" + %"38" = load i64, ptr addrspace(5) %"5", align 8 + %"39" = load float, ptr addrspace(5) %"8", align 4 + %"50" = inttoptr i64 %"38" to ptr + store float %"39", ptr %"50", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_bool.ptx b/ptx/src/test/spirv_run/setp_bool.ptx new file mode 100644 index 0000000..96d7bf2 --- /dev/null +++ b/ptx/src/test/spirv_run/setp_bool.ptx @@ -0,0 +1,31 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry setp_bool( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 r1; + .reg .f32 r2; + .reg .f32 r3; + .reg .pred temp; + .reg .pred p1; + .reg .pred p2; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.f32 r1, [in_addr]; + ld.f32 r2, [in_addr + 4]; + ld.f32 r3, [in_addr + 8]; + mov.pred temp, 0; + setp.gt.and.ftz.f32 p1|p2, r1, r2, temp; + @p1 mov.f32 r3, r1; + @p2 mov.f32 r3, r2; + st.f32 [out_addr], r3; + ret; +} diff --git a/ptx/src/test/spirv_run/setp_gt.ll b/ptx/src/test/spirv_run/setp_gt.ll new file mode 100644 index 0000000..0aa4831 --- /dev/null +++ b/ptx/src/test/spirv_run/setp_gt.ll @@ -0,0 +1,64 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_gt(ptr addrspace(4) byref(i64) %"35", ptr addrspace(4) byref(i64) %"36") #0 { +"40": + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"16", ptr addrspace(5) %"4", align 8 + %"17" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"17", ptr addrspace(5) %"5", align 8 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"19" to ptr + %"18" = load float, ptr %"37", align 4 + store float %"18", ptr addrspace(5) %"6", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"38" = inttoptr i64 %"21" to ptr + %"42" = getelementptr inbounds i8, ptr %"38", i64 4 + %"20" = load float, ptr %"42", align 4 + store float %"20", ptr addrspace(5) %"7", align 4 + %"23" = load float, ptr addrspace(5) %"6", align 4 + %"24" = load float, ptr addrspace(5) %"7", align 4 + %"22" = fcmp ogt float %"23", %"24" + store i1 %"22", ptr addrspace(5) %"9", align 1 + %"25" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"25", label %"10", label %"11" + +"10": ; preds = %"40" + %"27" = load float, ptr addrspace(5) %"6", align 4 + %0 = alloca float, align 4, addrspace(5) + store float %"27", ptr addrspace(5) %0, align 4 + %"26" = load float, ptr addrspace(5) %0, align 4 + store float %"26", ptr addrspace(5) %"8", align 4 + br label %"11" + +"11": ; preds = %"10", %"40" + %"28" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"28", label %"13", label %"12" + +"12": ; preds = %"11" + %"30" = load float, ptr addrspace(5) %"7", align 4 + %1 = alloca float, align 4, addrspace(5) + store float %"30", ptr addrspace(5) %1, align 4 + %"29" = load float, ptr addrspace(5) %1, align 4 + store float %"29", ptr addrspace(5) %"8", align 4 + br label %"13" + +"13": ; preds = %"12", %"11" + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load float, ptr addrspace(5) %"8", align 4 + %"39" = inttoptr i64 %"31" to ptr + store float %"32", ptr %"39", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_gt.spvtxt b/ptx/src/test/spirv_run/setp_gt.spvtxt deleted file mode 100644 index 77f6546..0000000 --- a/ptx/src/test/spirv_run/setp_gt.spvtxt +++ /dev/null @@ -1,75 +0,0 @@ - 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_gt" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %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_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_float %19 - %18 = OpLoad %float %35 Aligned 4 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %34 = OpIAdd %ulong %21 %ulong_4 - %36 = OpConvertUToPtr %_ptr_Generic_float %34 - %20 = OpLoad %float %36 Aligned 4 - OpStore %7 %20 - %23 = OpLoad %float %6 - %24 = OpLoad %float %7 - %22 = OpFOrdGreaterThan %bool %23 %24 - OpStore %9 %22 - %25 = OpLoad %bool %9 - OpBranchConditional %25 %10 %11 - %10 = OpLabel - %27 = OpLoad %float %6 - %26 = OpCopyObject %float %27 - OpStore %8 %26 - OpBranch %11 - %11 = OpLabel - %28 = OpLoad %bool %9 - OpBranchConditional %28 %13 %12 - %12 = OpLabel - %30 = OpLoad %float %7 - %29 = OpCopyObject %float %30 - OpStore %8 %29 - OpBranch %13 - %13 = OpLabel - %31 = OpLoad %ulong %5 - %32 = OpLoad %float %8 - %37 = OpConvertUToPtr %_ptr_Generic_float %31 - OpStore %37 %32 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_leu.ll b/ptx/src/test/spirv_run/setp_leu.ll new file mode 100644 index 0000000..4105d59 --- /dev/null +++ b/ptx/src/test/spirv_run/setp_leu.ll @@ -0,0 +1,64 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_leu(ptr addrspace(4) byref(i64) %"35", ptr addrspace(4) byref(i64) %"36") #0 { +"40": + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"35", align 8 + store i64 %"16", ptr addrspace(5) %"4", align 8 + %"17" = load i64, ptr addrspace(4) %"36", align 8 + store i64 %"17", ptr addrspace(5) %"5", align 8 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"37" = inttoptr i64 %"19" to ptr + %"18" = load float, ptr %"37", align 4 + store float %"18", ptr addrspace(5) %"6", align 4 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"38" = inttoptr i64 %"21" to ptr + %"42" = getelementptr inbounds i8, ptr %"38", i64 4 + %"20" = load float, ptr %"42", align 4 + store float %"20", ptr addrspace(5) %"7", align 4 + %"23" = load float, ptr addrspace(5) %"6", align 4 + %"24" = load float, ptr addrspace(5) %"7", align 4 + %"22" = fcmp ule float %"23", %"24" + store i1 %"22", ptr addrspace(5) %"9", align 1 + %"25" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"25", label %"10", label %"11" + +"10": ; preds = %"40" + %"27" = load float, ptr addrspace(5) %"6", align 4 + %0 = alloca float, align 4, addrspace(5) + store float %"27", ptr addrspace(5) %0, align 4 + %"26" = load float, ptr addrspace(5) %0, align 4 + store float %"26", ptr addrspace(5) %"8", align 4 + br label %"11" + +"11": ; preds = %"10", %"40" + %"28" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"28", label %"13", label %"12" + +"12": ; preds = %"11" + %"30" = load float, ptr addrspace(5) %"7", align 4 + %1 = alloca float, align 4, addrspace(5) + store float %"30", ptr addrspace(5) %1, align 4 + %"29" = load float, ptr addrspace(5) %1, align 4 + store float %"29", ptr addrspace(5) %"8", align 4 + br label %"13" + +"13": ; preds = %"12", %"11" + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load float, ptr addrspace(5) %"8", align 4 + %"39" = inttoptr i64 %"31" to ptr + store float %"32", ptr %"39", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_leu.spvtxt b/ptx/src/test/spirv_run/setp_leu.spvtxt deleted file mode 100644 index f80880a..0000000 --- a/ptx/src/test/spirv_run/setp_leu.spvtxt +++ /dev/null @@ -1,75 +0,0 @@ - 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_leu" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %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_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_float %19 - %18 = OpLoad %float %35 Aligned 4 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %34 = OpIAdd %ulong %21 %ulong_4 - %36 = OpConvertUToPtr %_ptr_Generic_float %34 - %20 = OpLoad %float %36 Aligned 4 - OpStore %7 %20 - %23 = OpLoad %float %6 - %24 = OpLoad %float %7 - %22 = OpFUnordLessThanEqual %bool %23 %24 - OpStore %9 %22 - %25 = OpLoad %bool %9 - OpBranchConditional %25 %10 %11 - %10 = OpLabel - %27 = OpLoad %float %6 - %26 = OpCopyObject %float %27 - OpStore %8 %26 - OpBranch %11 - %11 = OpLabel - %28 = OpLoad %bool %9 - OpBranchConditional %28 %13 %12 - %12 = OpLabel - %30 = OpLoad %float %7 - %29 = OpCopyObject %float %30 - OpStore %8 %29 - OpBranch %13 - %13 = OpLabel - %31 = OpLoad %ulong %5 - %32 = OpLoad %float %8 - %37 = OpConvertUToPtr %_ptr_Generic_float %31 - OpStore %37 %32 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_nan.ll b/ptx/src/test/spirv_run/setp_nan.ll new file mode 100644 index 0000000..da9c62a --- /dev/null +++ b/ptx/src/test/spirv_run/setp_nan.ll @@ -0,0 +1,191 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_nan(ptr addrspace(4) byref(i64) %"116", ptr addrspace(4) byref(i64) %"117") #0 { +"130": + %"32" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"32", align 1 + %"33" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"33", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca float, align 4, addrspace(5) + %"10" = alloca float, align 4, addrspace(5) + %"11" = alloca float, align 4, addrspace(5) + %"12" = alloca float, align 4, addrspace(5) + %"13" = alloca float, align 4, addrspace(5) + %"14" = alloca i32, align 4, addrspace(5) + %"15" = alloca i1, align 1, addrspace(5) + %"34" = load i64, ptr addrspace(4) %"116", align 8 + store i64 %"34", ptr addrspace(5) %"4", align 8 + %"35" = load i64, ptr addrspace(4) %"117", align 8 + store i64 %"35", ptr addrspace(5) %"5", align 8 + %"37" = load i64, ptr addrspace(5) %"4", align 8 + %"118" = inttoptr i64 %"37" to ptr + %"36" = load float, ptr %"118", align 4 + store float %"36", ptr addrspace(5) %"6", align 4 + %"39" = load i64, ptr addrspace(5) %"4", align 8 + %"119" = inttoptr i64 %"39" to ptr + %"132" = getelementptr inbounds i8, ptr %"119", i64 4 + %"38" = load float, ptr %"132", align 4 + store float %"38", ptr addrspace(5) %"7", align 4 + %"41" = load i64, ptr addrspace(5) %"4", align 8 + %"120" = inttoptr i64 %"41" to ptr + %"134" = getelementptr inbounds i8, ptr %"120", i64 8 + %"40" = load float, ptr %"134", align 4 + store float %"40", ptr addrspace(5) %"8", align 4 + %"43" = load i64, ptr addrspace(5) %"4", align 8 + %"121" = inttoptr i64 %"43" to ptr + %"136" = getelementptr inbounds i8, ptr %"121", i64 12 + %"42" = load float, ptr %"136", align 4 + store float %"42", ptr addrspace(5) %"9", align 4 + %"45" = load i64, ptr addrspace(5) %"4", align 8 + %"122" = inttoptr i64 %"45" to ptr + %"138" = getelementptr inbounds i8, ptr %"122", i64 16 + %"44" = load float, ptr %"138", align 4 + store float %"44", ptr addrspace(5) %"10", align 4 + %"47" = load i64, ptr addrspace(5) %"4", align 8 + %"123" = inttoptr i64 %"47" to ptr + %"140" = getelementptr inbounds i8, ptr %"123", i64 20 + %"46" = load float, ptr %"140", align 4 + store float %"46", ptr addrspace(5) %"11", align 4 + %"49" = load i64, ptr addrspace(5) %"4", align 8 + %"124" = inttoptr i64 %"49" to ptr + %"142" = getelementptr inbounds i8, ptr %"124", i64 24 + %"48" = load float, ptr %"142", align 4 + store float %"48", ptr addrspace(5) %"12", align 4 + %"51" = load i64, ptr addrspace(5) %"4", align 8 + %"125" = inttoptr i64 %"51" to ptr + %"144" = getelementptr inbounds i8, ptr %"125", i64 28 + %"50" = load float, ptr %"144", align 4 + store float %"50", ptr addrspace(5) %"13", align 4 + %"53" = load float, ptr addrspace(5) %"6", align 4 + %"54" = load float, ptr addrspace(5) %"7", align 4 + %"52" = fcmp uno float %"53", %"54" + store i1 %"52", ptr addrspace(5) %"15", align 1 + %"55" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"55", label %"16", label %"17" + +"16": ; preds = %"130" + %0 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %0, align 4 + %"56" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"56", ptr addrspace(5) %"14", align 4 + br label %"17" + +"17": ; preds = %"16", %"130" + %"57" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"57", label %"19", label %"18" + +"18": ; preds = %"17" + %1 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %1, align 4 + %"58" = load i32, ptr addrspace(5) %1, align 4 + store i32 %"58", ptr addrspace(5) %"14", align 4 + br label %"19" + +"19": ; preds = %"18", %"17" + %"59" = load i64, ptr addrspace(5) %"5", align 8 + %"60" = load i32, ptr addrspace(5) %"14", align 4 + %"126" = inttoptr i64 %"59" to ptr + store i32 %"60", ptr %"126", align 4 + %"62" = load float, ptr addrspace(5) %"8", align 4 + %"63" = load float, ptr addrspace(5) %"9", align 4 + %"61" = fcmp uno float %"62", %"63" + store i1 %"61", ptr addrspace(5) %"15", align 1 + %"64" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"64", label %"20", label %"21" + +"20": ; preds = %"19" + %2 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %2, align 4 + %"65" = load i32, ptr addrspace(5) %2, align 4 + store i32 %"65", ptr addrspace(5) %"14", align 4 + br label %"21" + +"21": ; preds = %"20", %"19" + %"66" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"66", label %"23", label %"22" + +"22": ; preds = %"21" + %3 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %3, align 4 + %"67" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"67", ptr addrspace(5) %"14", align 4 + br label %"23" + +"23": ; preds = %"22", %"21" + %"68" = load i64, ptr addrspace(5) %"5", align 8 + %"69" = load i32, ptr addrspace(5) %"14", align 4 + %"127" = inttoptr i64 %"68" to ptr + %"146" = getelementptr inbounds i8, ptr %"127", i64 4 + store i32 %"69", ptr %"146", align 4 + %"71" = load float, ptr addrspace(5) %"10", align 4 + %"72" = load float, ptr addrspace(5) %"11", align 4 + %"70" = fcmp uno float %"71", %"72" + store i1 %"70", ptr addrspace(5) %"15", align 1 + %"73" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"73", label %"24", label %"25" + +"24": ; preds = %"23" + %4 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %4, align 4 + %"74" = load i32, ptr addrspace(5) %4, align 4 + store i32 %"74", ptr addrspace(5) %"14", align 4 + br label %"25" + +"25": ; preds = %"24", %"23" + %"75" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"75", label %"27", label %"26" + +"26": ; preds = %"25" + %5 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %5, align 4 + %"76" = load i32, ptr addrspace(5) %5, align 4 + store i32 %"76", ptr addrspace(5) %"14", align 4 + br label %"27" + +"27": ; preds = %"26", %"25" + %"77" = load i64, ptr addrspace(5) %"5", align 8 + %"78" = load i32, ptr addrspace(5) %"14", align 4 + %"128" = inttoptr i64 %"77" to ptr + %"148" = getelementptr inbounds i8, ptr %"128", i64 8 + store i32 %"78", ptr %"148", align 4 + %"80" = load float, ptr addrspace(5) %"12", align 4 + %"81" = load float, ptr addrspace(5) %"13", align 4 + %"79" = fcmp uno float %"80", %"81" + store i1 %"79", ptr addrspace(5) %"15", align 1 + %"82" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"82", label %"28", label %"29" + +"28": ; preds = %"27" + %6 = alloca i32, align 4, addrspace(5) + store i32 1, ptr addrspace(5) %6, align 4 + %"83" = load i32, ptr addrspace(5) %6, align 4 + store i32 %"83", ptr addrspace(5) %"14", align 4 + br label %"29" + +"29": ; preds = %"28", %"27" + %"84" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"84", label %"31", label %"30" + +"30": ; preds = %"29" + %7 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %7, align 4 + %"85" = load i32, ptr addrspace(5) %7, align 4 + store i32 %"85", ptr addrspace(5) %"14", align 4 + br label %"31" + +"31": ; preds = %"30", %"29" + %"86" = load i64, ptr addrspace(5) %"5", align 8 + %"87" = load i32, ptr addrspace(5) %"14", align 4 + %"129" = inttoptr i64 %"86" to ptr + %"150" = getelementptr inbounds i8, ptr %"129", i64 12 + store i32 %"87", ptr %"150", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_nan.ptx b/ptx/src/test/spirv_run/setp_nan.ptx new file mode 100644 index 0000000..6a9951e --- /dev/null +++ b/ptx/src/test/spirv_run/setp_nan.ptx @@ -0,0 +1,51 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry setp_nan( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 pair1_1; + .reg .f32 pair1_2; + .reg .f32 pair2_1; + .reg .f32 pair2_2; + .reg .f32 pair3_1; + .reg .f32 pair3_2; + .reg .f32 pair4_1; + .reg .f32 pair4_2; + .reg .u32 temp; + .reg .pred pred; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.f32 pair1_1, [in_addr]; + ld.f32 pair1_2, [in_addr + 4]; + ld.f32 pair2_1, [in_addr + 8]; + ld.f32 pair2_2, [in_addr + 12]; + ld.f32 pair3_1, [in_addr + 16]; + ld.f32 pair3_2, [in_addr + 20]; + ld.f32 pair4_1, [in_addr + 24]; + ld.f32 pair4_2, [in_addr + 28]; + setp.nan.f32 pred, pair1_1, pair1_2; + @pred mov.u32 temp, 1; + @!pred mov.u32 temp, 0; + st.u32 [out_addr], temp; + setp.nan.f32 pred, pair2_1, pair2_2; + @pred mov.u32 temp, 1; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 4], temp; + setp.nan.f32 pred, pair3_1, pair3_2; + @pred mov.u32 temp, 1; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 8], temp; + setp.nan.f32 pred, pair4_1, pair4_2; + @pred mov.u32 temp, 1; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 12], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/setp_num.ll b/ptx/src/test/spirv_run/setp_num.ll new file mode 100644 index 0000000..07cf161 --- /dev/null +++ b/ptx/src/test/spirv_run/setp_num.ll @@ -0,0 +1,191 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_num(ptr addrspace(4) byref(i64) %"116", ptr addrspace(4) byref(i64) %"117") #0 { +"130": + %"32" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"32", align 1 + %"33" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"33", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca float, align 4, addrspace(5) + %"10" = alloca float, align 4, addrspace(5) + %"11" = alloca float, align 4, addrspace(5) + %"12" = alloca float, align 4, addrspace(5) + %"13" = alloca float, align 4, addrspace(5) + %"14" = alloca i32, align 4, addrspace(5) + %"15" = alloca i1, align 1, addrspace(5) + %"34" = load i64, ptr addrspace(4) %"116", align 8 + store i64 %"34", ptr addrspace(5) %"4", align 8 + %"35" = load i64, ptr addrspace(4) %"117", align 8 + store i64 %"35", ptr addrspace(5) %"5", align 8 + %"37" = load i64, ptr addrspace(5) %"4", align 8 + %"118" = inttoptr i64 %"37" to ptr + %"36" = load float, ptr %"118", align 4 + store float %"36", ptr addrspace(5) %"6", align 4 + %"39" = load i64, ptr addrspace(5) %"4", align 8 + %"119" = inttoptr i64 %"39" to ptr + %"132" = getelementptr inbounds i8, ptr %"119", i64 4 + %"38" = load float, ptr %"132", align 4 + store float %"38", ptr addrspace(5) %"7", align 4 + %"41" = load i64, ptr addrspace(5) %"4", align 8 + %"120" = inttoptr i64 %"41" to ptr + %"134" = getelementptr inbounds i8, ptr %"120", i64 8 + %"40" = load float, ptr %"134", align 4 + store float %"40", ptr addrspace(5) %"8", align 4 + %"43" = load i64, ptr addrspace(5) %"4", align 8 + %"121" = inttoptr i64 %"43" to ptr + %"136" = getelementptr inbounds i8, ptr %"121", i64 12 + %"42" = load float, ptr %"136", align 4 + store float %"42", ptr addrspace(5) %"9", align 4 + %"45" = load i64, ptr addrspace(5) %"4", align 8 + %"122" = inttoptr i64 %"45" to ptr + %"138" = getelementptr inbounds i8, ptr %"122", i64 16 + %"44" = load float, ptr %"138", align 4 + store float %"44", ptr addrspace(5) %"10", align 4 + %"47" = load i64, ptr addrspace(5) %"4", align 8 + %"123" = inttoptr i64 %"47" to ptr + %"140" = getelementptr inbounds i8, ptr %"123", i64 20 + %"46" = load float, ptr %"140", align 4 + store float %"46", ptr addrspace(5) %"11", align 4 + %"49" = load i64, ptr addrspace(5) %"4", align 8 + %"124" = inttoptr i64 %"49" to ptr + %"142" = getelementptr inbounds i8, ptr %"124", i64 24 + %"48" = load float, ptr %"142", align 4 + store float %"48", ptr addrspace(5) %"12", align 4 + %"51" = load i64, ptr addrspace(5) %"4", align 8 + %"125" = inttoptr i64 %"51" to ptr + %"144" = getelementptr inbounds i8, ptr %"125", i64 28 + %"50" = load float, ptr %"144", align 4 + store float %"50", ptr addrspace(5) %"13", align 4 + %"53" = load float, ptr addrspace(5) %"6", align 4 + %"54" = load float, ptr addrspace(5) %"7", align 4 + %"52" = fcmp ord float %"53", %"54" + store i1 %"52", ptr addrspace(5) %"15", align 1 + %"55" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"55", label %"16", label %"17" + +"16": ; preds = %"130" + %0 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %0, align 4 + %"56" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"56", ptr addrspace(5) %"14", align 4 + br label %"17" + +"17": ; preds = %"16", %"130" + %"57" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"57", label %"19", label %"18" + +"18": ; preds = %"17" + %1 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %1, align 4 + %"58" = load i32, ptr addrspace(5) %1, align 4 + store i32 %"58", ptr addrspace(5) %"14", align 4 + br label %"19" + +"19": ; preds = %"18", %"17" + %"59" = load i64, ptr addrspace(5) %"5", align 8 + %"60" = load i32, ptr addrspace(5) %"14", align 4 + %"126" = inttoptr i64 %"59" to ptr + store i32 %"60", ptr %"126", align 4 + %"62" = load float, ptr addrspace(5) %"8", align 4 + %"63" = load float, ptr addrspace(5) %"9", align 4 + %"61" = fcmp ord float %"62", %"63" + store i1 %"61", ptr addrspace(5) %"15", align 1 + %"64" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"64", label %"20", label %"21" + +"20": ; preds = %"19" + %2 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %2, align 4 + %"65" = load i32, ptr addrspace(5) %2, align 4 + store i32 %"65", ptr addrspace(5) %"14", align 4 + br label %"21" + +"21": ; preds = %"20", %"19" + %"66" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"66", label %"23", label %"22" + +"22": ; preds = %"21" + %3 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %3, align 4 + %"67" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"67", ptr addrspace(5) %"14", align 4 + br label %"23" + +"23": ; preds = %"22", %"21" + %"68" = load i64, ptr addrspace(5) %"5", align 8 + %"69" = load i32, ptr addrspace(5) %"14", align 4 + %"127" = inttoptr i64 %"68" to ptr + %"146" = getelementptr inbounds i8, ptr %"127", i64 4 + store i32 %"69", ptr %"146", align 4 + %"71" = load float, ptr addrspace(5) %"10", align 4 + %"72" = load float, ptr addrspace(5) %"11", align 4 + %"70" = fcmp ord float %"71", %"72" + store i1 %"70", ptr addrspace(5) %"15", align 1 + %"73" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"73", label %"24", label %"25" + +"24": ; preds = %"23" + %4 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %4, align 4 + %"74" = load i32, ptr addrspace(5) %4, align 4 + store i32 %"74", ptr addrspace(5) %"14", align 4 + br label %"25" + +"25": ; preds = %"24", %"23" + %"75" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"75", label %"27", label %"26" + +"26": ; preds = %"25" + %5 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %5, align 4 + %"76" = load i32, ptr addrspace(5) %5, align 4 + store i32 %"76", ptr addrspace(5) %"14", align 4 + br label %"27" + +"27": ; preds = %"26", %"25" + %"77" = load i64, ptr addrspace(5) %"5", align 8 + %"78" = load i32, ptr addrspace(5) %"14", align 4 + %"128" = inttoptr i64 %"77" to ptr + %"148" = getelementptr inbounds i8, ptr %"128", i64 8 + store i32 %"78", ptr %"148", align 4 + %"80" = load float, ptr addrspace(5) %"12", align 4 + %"81" = load float, ptr addrspace(5) %"13", align 4 + %"79" = fcmp ord float %"80", %"81" + store i1 %"79", ptr addrspace(5) %"15", align 1 + %"82" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"82", label %"28", label %"29" + +"28": ; preds = %"27" + %6 = alloca i32, align 4, addrspace(5) + store i32 2, ptr addrspace(5) %6, align 4 + %"83" = load i32, ptr addrspace(5) %6, align 4 + store i32 %"83", ptr addrspace(5) %"14", align 4 + br label %"29" + +"29": ; preds = %"28", %"27" + %"84" = load i1, ptr addrspace(5) %"15", align 1 + br i1 %"84", label %"31", label %"30" + +"30": ; preds = %"29" + %7 = alloca i32, align 4, addrspace(5) + store i32 0, ptr addrspace(5) %7, align 4 + %"85" = load i32, ptr addrspace(5) %7, align 4 + store i32 %"85", ptr addrspace(5) %"14", align 4 + br label %"31" + +"31": ; preds = %"30", %"29" + %"86" = load i64, ptr addrspace(5) %"5", align 8 + %"87" = load i32, ptr addrspace(5) %"14", align 4 + %"129" = inttoptr i64 %"86" to ptr + %"150" = getelementptr inbounds i8, ptr %"129", i64 12 + store i32 %"87", ptr %"150", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_num.ptx b/ptx/src/test/spirv_run/setp_num.ptx new file mode 100644 index 0000000..d83ea4e --- /dev/null +++ b/ptx/src/test/spirv_run/setp_num.ptx @@ -0,0 +1,51 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry setp_num( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 pair1_1; + .reg .f32 pair1_2; + .reg .f32 pair2_1; + .reg .f32 pair2_2; + .reg .f32 pair3_1; + .reg .f32 pair3_2; + .reg .f32 pair4_1; + .reg .f32 pair4_2; + .reg .u32 temp; + .reg .pred pred; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.f32 pair1_1, [in_addr]; + ld.f32 pair1_2, [in_addr + 4]; + ld.f32 pair2_1, [in_addr + 8]; + ld.f32 pair2_2, [in_addr + 12]; + ld.f32 pair3_1, [in_addr + 16]; + ld.f32 pair3_2, [in_addr + 20]; + ld.f32 pair4_1, [in_addr + 24]; + ld.f32 pair4_2, [in_addr + 28]; + setp.num.f32 pred, pair1_1, pair1_2; + @pred mov.u32 temp, 2; + @!pred mov.u32 temp, 0; + st.u32 [out_addr], temp; + setp.num.f32 pred, pair2_1, pair2_2; + @pred mov.u32 temp, 2; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 4], temp; + setp.num.f32 pred, pair3_1, pair3_2; + @pred mov.u32 temp, 2; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 8], temp; + setp.num.f32 pred, pair4_1, pair4_2; + @pred mov.u32 temp, 2; + @!pred mov.u32 temp, 0; + st.u32 [out_addr + 12], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/setp_pred2.ll b/ptx/src/test/spirv_run/setp_pred2.ll new file mode 100644 index 0000000..9ce8135 --- /dev/null +++ b/ptx/src/test/spirv_run/setp_pred2.ll @@ -0,0 +1,67 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @setp_pred2(ptr addrspace(4) byref(i64) %"37", ptr addrspace(4) byref(i64) %"38") #0 { +"42": + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"16" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"16", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"7" = alloca float, align 4, addrspace(5) + %"8" = alloca float, align 4, addrspace(5) + %"9" = alloca i1, align 1, addrspace(5) + %"10" = alloca i1, align 1, addrspace(5) + %"17" = load i64, ptr addrspace(4) %"37", align 8 + store i64 %"17", ptr addrspace(5) %"4", align 8 + %"18" = load i64, ptr addrspace(4) %"38", align 8 + store i64 %"18", ptr addrspace(5) %"5", align 8 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"39" = inttoptr i64 %"20" to ptr + %"19" = load float, ptr %"39", align 4 + store float %"19", ptr addrspace(5) %"6", align 4 + %"22" = load i64, ptr addrspace(5) %"4", align 8 + %"40" = inttoptr i64 %"22" to ptr + %"44" = getelementptr inbounds i8, ptr %"40", i64 4 + %"21" = load float, ptr %"44", align 4 + store float %"21", ptr addrspace(5) %"7", align 4 + %"25" = load float, ptr addrspace(5) %"6", align 4 + %"26" = load float, ptr addrspace(5) %"7", align 4 + %"23" = fcmp ogt float %"25", %"26" + %"24" = xor i1 %"23", true + store i1 %"23", ptr addrspace(5) %"9", align 1 + store i1 %"24", ptr addrspace(5) %"10", align 1 + %"27" = load i1, ptr addrspace(5) %"9", align 1 + br i1 %"27", label %"11", label %"12" + +"11": ; preds = %"42" + %"29" = load float, ptr addrspace(5) %"6", align 4 + %0 = alloca float, align 4, addrspace(5) + store float %"29", ptr addrspace(5) %0, align 4 + %"28" = load float, ptr addrspace(5) %0, align 4 + store float %"28", ptr addrspace(5) %"8", align 4 + br label %"12" + +"12": ; preds = %"11", %"42" + %"30" = load i1, ptr addrspace(5) %"10", align 1 + br i1 %"30", label %"13", label %"14" + +"13": ; preds = %"12" + %"32" = load float, ptr addrspace(5) %"7", align 4 + %1 = alloca float, align 4, addrspace(5) + store float %"32", ptr addrspace(5) %1, align 4 + %"31" = load float, ptr addrspace(5) %1, align 4 + store float %"31", ptr addrspace(5) %"8", align 4 + br label %"14" + +"14": ; preds = %"13", %"12" + %"33" = load i64, ptr addrspace(5) %"5", align 8 + %"34" = load float, ptr addrspace(5) %"8", align 4 + %"41" = inttoptr i64 %"33" to ptr + store float %"34", ptr %"41", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/setp_pred2.ptx b/ptx/src/test/spirv_run/setp_pred2.ptx new file mode 100644 index 0000000..4f7475f --- /dev/null +++ b/ptx/src/test/spirv_run/setp_pred2.ptx @@ -0,0 +1,28 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry setp_pred2( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .f32 r1; + .reg .f32 r2; + .reg .f32 r3; + .reg .pred yes; + .reg .pred no; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.f32 r1, [in_addr]; + ld.f32 r2, [in_addr + 4]; + setp.gt.ftz.f32 yes|no, r1, r2; + @yes mov.f32 r3, r1; + @no mov.f32 r3, r2; + st.f32 [out_addr], r3; + ret; +} diff --git a/ptx/src/test/spirv_run/shared_ptr_32.ll b/ptx/src/test/spirv_run/shared_ptr_32.ll new file mode 100644 index 0000000..a132a58 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_ptr_32.ll @@ -0,0 +1,45 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@"4" = private addrspace(3) global [128 x i8] undef, align 4 + +define protected amdgpu_kernel void @shared_ptr_32(ptr addrspace(4) byref(i64) %"25", ptr addrspace(4) byref(i64) %"26") #0 { +"32": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"13", ptr addrspace(5) %"6", align 8 + %0 = alloca i32, align 4, addrspace(5) + store i32 ptrtoint (ptr addrspace(3) @"4" to i32), ptr addrspace(5) %0, align 4 + %"14" = load i32, ptr addrspace(5) %0, align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = inttoptr i64 %"16" to ptr addrspace(1) + %"15" = load i64, ptr addrspace(1) %"28", align 8 + store i64 %"15", ptr addrspace(5) %"8", align 8 + %"17" = load i32, ptr addrspace(5) %"7", align 4 + %"18" = load i64, ptr addrspace(5) %"8", align 8 + %"29" = inttoptr i32 %"17" to ptr addrspace(3) + store i64 %"18", ptr addrspace(3) %"29", align 8 + %"20" = load i32, ptr addrspace(5) %"7", align 4 + %"30" = inttoptr i32 %"20" to ptr addrspace(3) + %"34" = getelementptr inbounds i8, ptr addrspace(3) %"30", i64 0 + %"19" = load i64, ptr addrspace(3) %"34", align 8 + store i64 %"19", ptr addrspace(5) %"9", align 8 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load i64, ptr addrspace(5) %"9", align 8 + %"31" = inttoptr i64 %"21" to ptr addrspace(1) + store i64 %"22", ptr addrspace(1) %"31", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_ptr_32.spvtxt b/ptx/src/test/spirv_run/shared_ptr_32.spvtxt deleted file mode 100644 index 2ea964c..0000000 --- a/ptx/src/test/spirv_run/shared_ptr_32.spvtxt +++ /dev/null @@ -1,66 +0,0 @@ - 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 Aligned 8 - OpStore %5 %12 - %13 = OpLoad %ulong %3 Aligned 8 - 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 Aligned 8 - OpStore %8 %15 - %17 = OpLoad %uint %7 - %18 = OpLoad %ulong %8 - %27 = OpConvertUToPtr %_ptr_Workgroup_ulong %17 - OpStore %27 %18 Aligned 8 - %20 = OpLoad %uint %7 - %24 = OpIAdd %uint %20 %uint_0 - %28 = OpConvertUToPtr %_ptr_Workgroup_ulong %24 - %19 = OpLoad %ulong %28 Aligned 8 - OpStore %9 %19 - %21 = OpLoad %ulong %6 - %22 = OpLoad %ulong %9 - %29 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %21 - OpStore %29 %22 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_ptr_take_address.ll b/ptx/src/test/spirv_run/shared_ptr_take_address.ll new file mode 100644 index 0000000..a3d3e5d --- /dev/null +++ b/ptx/src/test/spirv_run/shared_ptr_take_address.ll @@ -0,0 +1,44 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_mem = external hidden addrspace(3) global [0 x i8], align 4 + +define protected amdgpu_kernel void @shared_ptr_take_address(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"30": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"9" = alloca i64, align 8, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"13", ptr addrspace(5) %"6", align 8 + %0 = alloca i64, align 8, addrspace(5) + store i64 ptrtoint (ptr addrspace(3) @shared_mem to i64), ptr addrspace(5) %0, align 8 + %"14" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"26" = inttoptr i64 %"16" to ptr addrspace(1) + %"15" = load i64, ptr addrspace(1) %"26", align 8 + store i64 %"15", ptr addrspace(5) %"8", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"18" = load i64, ptr addrspace(5) %"8", align 8 + %"27" = inttoptr i64 %"17" to ptr addrspace(3) + store i64 %"18", ptr addrspace(3) %"27", align 8 + %"20" = load i64, ptr addrspace(5) %"7", align 8 + %"28" = inttoptr i64 %"20" to ptr addrspace(3) + %"19" = load i64, ptr addrspace(3) %"28", align 8 + store i64 %"19", ptr addrspace(5) %"9", align 8 + %"21" = load i64, ptr addrspace(5) %"6", align 8 + %"22" = load i64, ptr addrspace(5) %"9", align 8 + %"29" = inttoptr i64 %"21" to ptr addrspace(1) + store i64 %"22", ptr addrspace(1) %"29", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt b/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt deleted file mode 100644 index 19d5a5a..0000000 --- a/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt +++ /dev/null @@ -1,68 +0,0 @@ - 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 Aligned 8 - OpStore %5 %12 - %13 = OpLoad %ulong %4 Aligned 8 - 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 Aligned 8 - OpStore %8 %16 - %18 = OpLoad %ulong %7 - %19 = OpLoad %ulong %8 - %26 = OpConvertUToPtr %_ptr_Workgroup_ulong %18 - OpStore %26 %19 Aligned 8 - %21 = OpLoad %ulong %7 - %27 = OpConvertUToPtr %_ptr_Workgroup_ulong %21 - %20 = OpLoad %ulong %27 Aligned 8 - OpStore %9 %20 - %22 = OpLoad %ulong %6 - %23 = OpLoad %ulong %9 - %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %22 - OpStore %28 %23 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_unify_decl.ll b/ptx/src/test/spirv_run/shared_unify_decl.ll new file mode 100644 index 0000000..1079e59 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_decl.ll @@ -0,0 +1,80 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_ex = external hidden addrspace(3) global [0 x i32] +@shared_mod = private addrspace(3) global [4 x i32] undef + +define private i64 @"3"(ptr addrspace(3) %"69", ptr addrspace(3) %"70") #0 { +"62": + %"8" = alloca i64, align 8, addrspace(5) + %"20" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"20", align 1 + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"26" = load i64, ptr addrspace(3) %"70", align 8 + store i64 %"26", ptr addrspace(5) %"9", align 8 + %"27" = load i64, ptr addrspace(3) %"69", align 8 + store i64 %"27", ptr addrspace(5) %"10", align 8 + %"29" = load i64, ptr addrspace(5) %"10", align 8 + %"30" = load i64, ptr addrspace(5) %"9", align 8 + %"53" = add i64 %"29", %"30" + store i64 %"53", ptr addrspace(5) %"8", align 8 + %"31" = load i64, ptr addrspace(5) %"8", align 8 + ret i64 %"31" +} + +define private i64 @"5"(i64 %"32", ptr addrspace(3) %"71", ptr addrspace(3) %"72") #0 { +"63": + %"12" = alloca i64, align 8, addrspace(5) + %"11" = alloca i64, align 8, addrspace(5) + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"23" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"23", align 1 + store i64 %"32", ptr addrspace(5) %"12", align 8 + %"33" = load i64, ptr addrspace(5) %"12", align 8 + store i64 %"33", ptr addrspace(3) %"71", align 8 + %"34" = call i64 @"3"(ptr addrspace(3) %"71", ptr addrspace(3) %"72") + store i64 %"34", ptr addrspace(5) %"11", align 8 + %"35" = load i64, ptr addrspace(5) %"11", align 8 + ret i64 %"35" +} + +define protected amdgpu_kernel void @shared_unify_decl(ptr addrspace(4) byref(i64) %"49", ptr addrspace(4) byref(i64) %"50") #0 { +"64": + %"24" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"24", align 1 + %"25" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"25", align 1 + %"16" = alloca i64, align 8, addrspace(5) + %"17" = alloca i64, align 8, addrspace(5) + %"18" = alloca i64, align 8, addrspace(5) + %"19" = alloca i64, align 8, addrspace(5) + %"36" = load i64, ptr addrspace(4) %"49", align 8 + store i64 %"36", ptr addrspace(5) %"16", align 8 + %"37" = load i64, ptr addrspace(4) %"50", align 8 + store i64 %"37", ptr addrspace(5) %"17", align 8 + %"39" = load i64, ptr addrspace(5) %"16", align 8 + %"56" = inttoptr i64 %"39" to ptr addrspace(1) + %"38" = load i64, ptr addrspace(1) %"56", align 8 + store i64 %"38", ptr addrspace(5) %"18", align 8 + %"41" = load i64, ptr addrspace(5) %"16", align 8 + %"57" = inttoptr i64 %"41" to ptr addrspace(1) + %"74" = getelementptr inbounds i8, ptr addrspace(1) %"57", i64 8 + %"40" = load i64, ptr addrspace(1) %"74", align 8 + store i64 %"40", ptr addrspace(5) %"19", align 8 + %"42" = load i64, ptr addrspace(5) %"19", align 8 + store i64 %"42", ptr addrspace(3) @shared_mod, align 8 + %"44" = load i64, ptr addrspace(5) %"18", align 8 + %"59" = call i64 @"5"(i64 %"44", ptr addrspace(3) @shared_ex, ptr addrspace(3) @shared_mod) + store i64 %"59", ptr addrspace(5) %"19", align 8 + %"45" = load i64, ptr addrspace(5) %"17", align 8 + %"46" = load i64, ptr addrspace(5) %"19", align 8 + %"61" = inttoptr i64 %"45" to ptr + store i64 %"46", ptr %"61", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_unify_decl.ptx b/ptx/src/test/spirv_run/shared_unify_decl.ptx new file mode 100644 index 0000000..a859bd9 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_decl.ptx @@ -0,0 +1,47 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.extern .shared .b32 shared_ex[]; +.shared .b32 shared_mod[4]; + +.func (.reg .b64 out) add(); +.func (.reg .b64 out) set_shared_temp1(.reg .b64 temp1_3); + +.func (.reg .b64 out) add() +{ + .reg .u64 temp1_2; + .reg .u64 temp2; + ld.shared.u64 temp1_2, [shared_mod]; + ld.shared.u64 temp2, [shared_ex]; + add.u64 out, temp2, temp1_2; + ret; +} + +.func (.reg .b64 out) set_shared_temp1(.reg .b64 temp1_1) +{ + st.shared.u64 [shared_ex], temp1_1; + call (out), add; + ret; +} + +.visible .entry shared_unify_decl( + .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.global.u64 temp1, [in_addr]; + ld.global.u64 temp2, [in_addr+8]; + st.shared.u64 [shared_mod], temp2; + call (temp2), set_shared_temp1, (temp1); + st.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/shared_unify_extern.ll b/ptx/src/test/spirv_run/shared_unify_extern.ll new file mode 100644 index 0000000..d83ea7a --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_extern.ll @@ -0,0 +1,80 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_ex = external hidden addrspace(3) global [0 x i32] +@shared_mod = private addrspace(3) global [4 x i32] undef + +define private i64 @"3"(ptr addrspace(3) %"62", ptr addrspace(3) %"63") #0 { +"59": + %"4" = alloca i64, align 8, addrspace(5) + %"17" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"17", align 1 + %"18" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"18", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"23" = load i64, ptr addrspace(3) %"63", align 8 + store i64 %"23", ptr addrspace(5) %"5", align 8 + %"24" = load i64, ptr addrspace(3) %"62", align 8 + store i64 %"24", ptr addrspace(5) %"6", align 8 + %"26" = load i64, ptr addrspace(5) %"6", align 8 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"50" = add i64 %"26", %"27" + store i64 %"50", ptr addrspace(5) %"4", align 8 + %"28" = load i64, ptr addrspace(5) %"4", align 8 + ret i64 %"28" +} + +define private i64 @"7"(i64 %"29", ptr addrspace(3) %"64", ptr addrspace(3) %"65") #0 { +"60": + %"9" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"19" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"19", align 1 + %"20" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"20", align 1 + store i64 %"29", ptr addrspace(5) %"9", align 8 + %"30" = load i64, ptr addrspace(5) %"9", align 8 + store i64 %"30", ptr addrspace(3) %"64", align 8 + %"31" = call i64 @"3"(ptr addrspace(3) %"64", ptr addrspace(3) %"65") + store i64 %"31", ptr addrspace(5) %"8", align 8 + %"32" = load i64, ptr addrspace(5) %"8", align 8 + ret i64 %"32" +} + +define protected amdgpu_kernel void @shared_unify_extern(ptr addrspace(4) byref(i64) %"46", ptr addrspace(4) byref(i64) %"47") #0 { +"61": + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"13" = alloca i64, align 8, addrspace(5) + %"14" = alloca i64, align 8, addrspace(5) + %"15" = alloca i64, align 8, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + %"33" = load i64, ptr addrspace(4) %"46", align 8 + store i64 %"33", ptr addrspace(5) %"13", align 8 + %"34" = load i64, ptr addrspace(4) %"47", align 8 + store i64 %"34", ptr addrspace(5) %"14", align 8 + %"36" = load i64, ptr addrspace(5) %"13", align 8 + %"53" = inttoptr i64 %"36" to ptr addrspace(1) + %"35" = load i64, ptr addrspace(1) %"53", align 8 + store i64 %"35", ptr addrspace(5) %"15", align 8 + %"38" = load i64, ptr addrspace(5) %"13", align 8 + %"54" = inttoptr i64 %"38" to ptr addrspace(1) + %"67" = getelementptr inbounds i8, ptr addrspace(1) %"54", i64 8 + %"37" = load i64, ptr addrspace(1) %"67", align 8 + store i64 %"37", ptr addrspace(5) %"16", align 8 + %"39" = load i64, ptr addrspace(5) %"16", align 8 + store i64 %"39", ptr addrspace(3) @shared_mod, align 8 + %"41" = load i64, ptr addrspace(5) %"15", align 8 + %"56" = call i64 @"7"(i64 %"41", ptr addrspace(3) @shared_ex, ptr addrspace(3) @shared_mod) + store i64 %"56", ptr addrspace(5) %"16", align 8 + %"42" = load i64, ptr addrspace(5) %"14", align 8 + %"43" = load i64, ptr addrspace(5) %"16", align 8 + %"58" = inttoptr i64 %"42" to ptr + store i64 %"43", ptr %"58", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_unify_extern.ptx b/ptx/src/test/spirv_run/shared_unify_extern.ptx new file mode 100644 index 0000000..075b984 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_extern.ptx @@ -0,0 +1,47 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.extern .shared .b32 shared_ex[]; +.shared .b32 shared_mod[4]; + + + + +.func (.reg .b64 out) add() +{ + .reg .u64 temp1; + .reg .u64 temp2; + ld.shared.u64 temp1, [shared_mod]; + ld.shared.u64 temp2, [shared_ex]; + add.u64 out, temp2, temp1; + ret; +} + +.func (.reg .b64 out) set_shared_temp1(.reg .b64 temp1) +{ + st.shared.u64 [shared_ex], temp1; + call (out), add; + ret; +} + +.visible .entry shared_unify_extern( + .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.global.u64 temp1, [in_addr]; + ld.global.u64 temp2, [in_addr+8]; + st.shared.u64 [shared_mod], temp2; + call (temp2), set_shared_temp1, (temp1); + st.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/shared_unify_local.ll b/ptx/src/test/spirv_run/shared_unify_local.ll new file mode 100644 index 0000000..e3a1db7 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_local.ll @@ -0,0 +1,85 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@shared_ex = external hidden addrspace(3) global [0 x i32] +@"5" = private addrspace(3) global i64 undef, align 4 + +define private i64 @"2"(i64 %"24", ptr addrspace(3) %"65", ptr addrspace(3) %"66") #0 { +"62": + %"4" = alloca i64, align 8, addrspace(5) + %"3" = alloca i64, align 8, addrspace(5) + %"18" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"18", align 1 + %"19" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"19", align 1 + %"6" = alloca i64, align 8, addrspace(5) + store i64 %"24", ptr addrspace(5) %"4", align 8 + %"25" = load i64, ptr addrspace(5) %"4", align 8 + store i64 %"25", ptr addrspace(3) %"66", align 8 + %"26" = load i64, ptr addrspace(3) %"66", align 8 + store i64 %"26", ptr addrspace(5) %"6", align 8 + %"27" = load i64, ptr addrspace(3) %"65", align 8 + store i64 %"27", ptr addrspace(5) %"4", align 8 + %"29" = load i64, ptr addrspace(5) %"4", align 8 + %"30" = load i64, ptr addrspace(5) %"6", align 8 + %"54" = add i64 %"29", %"30" + store i64 %"54", ptr addrspace(5) %"3", align 8 + %"31" = load i64, ptr addrspace(5) %"3", align 8 + ret i64 %"31" +} + +define private i64 @"7"(i64 %"32", i64 %"33", ptr addrspace(3) %"67", ptr addrspace(3) %"68") #0 { +"63": + %"9" = alloca i64, align 8, addrspace(5) + %"10" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"20" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"20", align 1 + %"21" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"21", align 1 + store i64 %"32", ptr addrspace(5) %"9", align 8 + store i64 %"33", ptr addrspace(5) %"10", align 8 + %"34" = load i64, ptr addrspace(5) %"9", align 8 + store i64 %"34", ptr addrspace(3) %"67", align 8 + %"36" = load i64, ptr addrspace(5) %"10", align 8 + %"35" = call i64 @"2"(i64 %"36", ptr addrspace(3) %"67", ptr addrspace(3) %"68") + store i64 %"35", ptr addrspace(5) %"8", align 8 + %"37" = load i64, ptr addrspace(5) %"8", align 8 + ret i64 %"37" +} + +define protected amdgpu_kernel void @shared_unify_local(ptr addrspace(4) byref(i64) %"51", ptr addrspace(4) byref(i64) %"52") #0 { +"64": + %"22" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"22", align 1 + %"23" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"23", align 1 + %"14" = alloca i64, align 8, addrspace(5) + %"15" = alloca i64, align 8, addrspace(5) + %"16" = alloca i64, align 8, addrspace(5) + %"17" = alloca i64, align 8, addrspace(5) + %"38" = load i64, ptr addrspace(4) %"51", align 8 + store i64 %"38", ptr addrspace(5) %"14", align 8 + %"39" = load i64, ptr addrspace(4) %"52", align 8 + store i64 %"39", ptr addrspace(5) %"15", align 8 + %"41" = load i64, ptr addrspace(5) %"14", align 8 + %"57" = inttoptr i64 %"41" to ptr addrspace(1) + %"40" = load i64, ptr addrspace(1) %"57", align 8 + store i64 %"40", ptr addrspace(5) %"16", align 8 + %"43" = load i64, ptr addrspace(5) %"14", align 8 + %"58" = inttoptr i64 %"43" to ptr addrspace(1) + %"70" = getelementptr inbounds i8, ptr addrspace(1) %"58", i64 8 + %"42" = load i64, ptr addrspace(1) %"70", align 8 + store i64 %"42", ptr addrspace(5) %"17", align 8 + %"45" = load i64, ptr addrspace(5) %"16", align 8 + %"46" = load i64, ptr addrspace(5) %"17", align 8 + %"59" = call i64 @"7"(i64 %"45", i64 %"46", ptr addrspace(3) @shared_ex, ptr addrspace(3) @"5") + store i64 %"59", ptr addrspace(5) %"17", align 8 + %"47" = load i64, ptr addrspace(5) %"15", align 8 + %"48" = load i64, ptr addrspace(5) %"17", align 8 + %"61" = inttoptr i64 %"47" to ptr + store i64 %"48", ptr %"61", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_unify_local.ptx b/ptx/src/test/spirv_run/shared_unify_local.ptx new file mode 100644 index 0000000..84f3a50 --- /dev/null +++ b/ptx/src/test/spirv_run/shared_unify_local.ptx @@ -0,0 +1,43 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.extern .shared .b32 shared_ex[]; + +.func (.reg .b64 out) add(.reg .u64 temp2) +{ + .shared .align 4 .u64 shared_mod; + .reg .u64 temp1; + st.shared.u64 [shared_mod], temp2; + ld.shared.u64 temp1, [shared_mod]; + ld.shared.u64 temp2, [shared_ex]; + add.u64 out, temp2, temp1; + ret; +} + +.func (.reg .b64 out) set_shared_temp1(.reg .b64 temp1, .reg .u64 temp2) +{ + st.shared.u64 [shared_ex], temp1; + call (out), add, (temp2); + ret; +} + +.visible .entry shared_unify_local( + .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.global.u64 temp1, [in_addr]; + ld.global.u64 temp2, [in_addr+8]; + call (temp2), set_shared_temp1, (temp1, temp2); + st.u64 [out_addr], temp2; + ret; +} diff --git a/ptx/src/test/spirv_run/shared_variable.ll b/ptx/src/test/spirv_run/shared_variable.ll new file mode 100644 index 0000000..2c2678a --- /dev/null +++ b/ptx/src/test/spirv_run/shared_variable.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +@"4" = private addrspace(3) global [128 x i8] undef, align 4 + +define protected amdgpu_kernel void @shared_variable(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"25": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i64, align 8, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = inttoptr i64 %"14" to ptr addrspace(1) + %"13" = load i64, ptr addrspace(1) %"21", align 8 + store i64 %"13", ptr addrspace(5) %"7", align 8 + %"15" = load i64, ptr addrspace(5) %"7", align 8 + store i64 %"15", ptr addrspace(3) @"4", align 8 + %"16" = load i64, ptr addrspace(3) @"4", align 8 + store i64 %"16", ptr addrspace(5) %"8", align 8 + %"17" = load i64, ptr addrspace(5) %"6", align 8 + %"18" = load i64, ptr addrspace(5) %"8", align 8 + %"24" = inttoptr i64 %"17" to ptr addrspace(1) + store i64 %"18", ptr addrspace(1) %"24", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shared_variable.spvtxt b/ptx/src/test/spirv_run/shared_variable.spvtxt deleted file mode 100644 index 49278a8..0000000 --- a/ptx/src/test/spirv_run/shared_variable.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - 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 Aligned 8 - OpStore %5 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %14 - %13 = OpLoad %ulong %19 Aligned 8 - OpStore %7 %13 - %15 = OpLoad %ulong %7 - %20 = OpBitcast %_ptr_Workgroup_ulong %4 - OpStore %20 %15 Aligned 8 - %21 = OpBitcast %_ptr_Workgroup_ulong %4 - %16 = OpLoad %ulong %21 Aligned 8 - OpStore %8 %16 - %17 = OpLoad %ulong %6 - %18 = OpLoad %ulong %8 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17 - OpStore %22 %18 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shf.ll b/ptx/src/test/spirv_run/shf.ll new file mode 100644 index 0000000..6eb5aa0 --- /dev/null +++ b/ptx/src/test/spirv_run/shf.ll @@ -0,0 +1,43 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @shf(ptr addrspace(4) byref(i64) %"25", ptr addrspace(4) byref(i64) %"26") #0 { +"33": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"26", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"14" to ptr + %"13" = load i32, ptr %"27", align 4 + store i32 %"13", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"28" = inttoptr i64 %"16" to ptr + %"35" = getelementptr inbounds i8, ptr %"28", i64 4 + %"15" = load i32, ptr %"35", align 4 + store i32 %"15", ptr addrspace(5) %"7", align 4 + %"18" = load i32, ptr addrspace(5) %"6", align 4 + %"19" = load i32, ptr addrspace(5) %"7", align 4 + %"29" = call i32 @llvm.fshl.i32(i32 %"19", i32 %"18", i32 14) + store i32 %"29", ptr addrspace(5) %"8", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i32, ptr addrspace(5) %"8", align 4 + %"32" = inttoptr i64 %"20" to ptr + store i32 %"21", ptr %"32", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.fshl.i32(i32, i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/shf.ptx b/ptx/src/test/spirv_run/shf.ptx new file mode 100644 index 0000000..4f211e3 --- /dev/null +++ b/ptx/src/test/spirv_run/shf.ptx @@ -0,0 +1,24 @@ +.version 6.5 +.target sm_32 +.address_size 64 + +.visible .entry shf( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp1; + .reg .u32 temp2; + .reg .u32 result; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp1, [in_addr]; + ld.u32 temp2, [in_addr+4]; + shf.l.wrap.b32 result, temp1, temp2, 14; + st.u32 [out_addr], result; + ret; +} diff --git a/ptx/src/test/spirv_run/shfl.ptx b/ptx/src/test/spirv_run/shfl.ptx new file mode 100644 index 0000000..d7b0dd6 --- /dev/null +++ b/ptx/src/test/spirv_run/shfl.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry shfl( + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u32 tid; + .reg .u64 tid_64; + .reg .u32 result; + + ld.param.u64 out_addr, [output]; + + mov.b32 tid, %tid.x; + cvt.u64.u32 tid_64, tid; + shfl.sync.down.b32 result, tid, 1, 31, -1; + mad.lo.u64 out_addr, tid_64, 4, out_addr; + st.u32 [out_addr], result; + ret; +} diff --git a/ptx/src/test/spirv_run/shl.ll b/ptx/src/test/spirv_run/shl.ll new file mode 100644 index 0000000..a353e07 --- /dev/null +++ b/ptx/src/test/spirv_run/shl.ll @@ -0,0 +1,33 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @shl(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"25": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %0 = shl i64 %"15", 2 + %"22" = select i1 false, i64 0, i64 %0 + store i64 %"22", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"24" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"24", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shl.spvtxt b/ptx/src/test/spirv_run/shl.spvtxt deleted file mode 100644 index 2a1249e..0000000 --- a/ptx/src/test/spirv_run/shl.spvtxt +++ /dev/null @@ -1,51 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shl_link_hack.ll b/ptx/src/test/spirv_run/shl_link_hack.ll new file mode 100644 index 0000000..8d695ad --- /dev/null +++ b/ptx/src/test/spirv_run/shl_link_hack.ll @@ -0,0 +1,41 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__atom_relaxed_gpu_generic_inc(ptr, i32) #0 + +define protected amdgpu_kernel void @shl_link_hack(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #1 { +"30": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"5", align 8 + %"25" = inttoptr i64 %"14" to ptr + %"13" = call i32 @__zluda_ptx_impl__atom_relaxed_gpu_generic_inc(ptr %"25", i32 2000000) + store i32 %"13", ptr addrspace(5) %"8", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"16" to ptr + %"15" = load i64, ptr %"26", align 8 + store i64 %"15", ptr addrspace(5) %"6", align 8 + %"18" = load i64, ptr addrspace(5) %"6", align 8 + %0 = shl i64 %"18", 2 + %"27" = select i1 false, i64 0, i64 %0 + store i64 %"27", ptr addrspace(5) %"7", align 8 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i64, ptr addrspace(5) %"7", align 8 + %"29" = inttoptr i64 %"19" to ptr + store i64 %"20", ptr %"29", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shl_link_hack.spvtxt b/ptx/src/test/spirv_run/shl_link_hack.spvtxt deleted file mode 100644 index 7e53af8..0000000 --- a/ptx/src/test/spirv_run/shl_link_hack.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - 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 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - 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 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shl_overflow.ll b/ptx/src/test/spirv_run/shl_overflow.ll new file mode 100644 index 0000000..0213149 --- /dev/null +++ b/ptx/src/test/spirv_run/shl_overflow.ll @@ -0,0 +1,75 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @shl_overflow(ptr addrspace(4) byref(i64) %"48", ptr addrspace(4) byref(i64) %"49") #0 { +"63": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"48", align 8 + store i64 %"13", ptr addrspace(5) %"4", align 8 + %"14" = load i64, ptr addrspace(4) %"49", align 8 + store i64 %"14", ptr addrspace(5) %"5", align 8 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"50" = inttoptr i64 %"16" to ptr + %"15" = load i32, ptr %"50", align 4 + store i32 %"15", ptr addrspace(5) %"6", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"51" = inttoptr i64 %"18" to ptr + %"65" = getelementptr inbounds i8, ptr %"51", i64 4 + %"17" = load i32, ptr %"65", align 4 + store i32 %"17", ptr addrspace(5) %"8", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"52" = inttoptr i64 %"20" to ptr + %"67" = getelementptr inbounds i8, ptr %"52", i64 8 + %"19" = load i32, ptr %"67", align 4 + store i32 %"19", ptr addrspace(5) %"9", align 4 + %"22" = load i64, ptr addrspace(5) %"4", align 8 + %"53" = inttoptr i64 %"22" to ptr + %"69" = getelementptr inbounds i8, ptr %"53", i64 12 + %"21" = load i32, ptr %"69", align 4 + store i32 %"21", ptr addrspace(5) %"10", align 4 + %"24" = load i32, ptr addrspace(5) %"6", align 4 + %"25" = load i32, ptr addrspace(5) %"8", align 4 + %0 = icmp ugt i32 %"25", 31 + %1 = shl i32 %"24", %"25" + %"54" = select i1 %0, i32 0, i32 %1 + store i32 %"54", ptr addrspace(5) %"7", align 4 + %"26" = load i64, ptr addrspace(5) %"5", align 8 + %"27" = load i32, ptr addrspace(5) %"7", align 4 + %"56" = inttoptr i64 %"26" to ptr + store i32 %"27", ptr %"56", align 4 + %"29" = load i32, ptr addrspace(5) %"6", align 4 + %"30" = load i32, ptr addrspace(5) %"9", align 4 + %2 = icmp ugt i32 %"30", 31 + %3 = shl i32 %"29", %"30" + %"57" = select i1 %2, i32 0, i32 %3 + store i32 %"57", ptr addrspace(5) %"7", align 4 + %"31" = load i64, ptr addrspace(5) %"5", align 8 + %"32" = load i32, ptr addrspace(5) %"7", align 4 + %"59" = inttoptr i64 %"31" to ptr + %"71" = getelementptr inbounds i8, ptr %"59", i64 4 + store i32 %"32", ptr %"71", align 4 + %"34" = load i32, ptr addrspace(5) %"6", align 4 + %"35" = load i32, ptr addrspace(5) %"10", align 4 + %4 = icmp ugt i32 %"35", 31 + %5 = shl i32 %"34", %"35" + %"60" = select i1 %4, i32 0, i32 %5 + store i32 %"60", ptr addrspace(5) %"7", align 4 + %"36" = load i64, ptr addrspace(5) %"5", align 8 + %"37" = load i32, ptr addrspace(5) %"7", align 4 + %"62" = inttoptr i64 %"36" to ptr + %"73" = getelementptr inbounds i8, ptr %"62", i64 8 + store i32 %"37", ptr %"73", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shl_overflow.ptx b/ptx/src/test/spirv_run/shl_overflow.ptx new file mode 100644 index 0000000..5f19256 --- /dev/null +++ b/ptx/src/test/spirv_run/shl_overflow.ptx @@ -0,0 +1,32 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry shl_overflow( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 input_value; + .reg .u32 value; + .reg .u32 shift1; + .reg .u32 shift2; + .reg .u32 shift3; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 input_value, [in_addr]; + ld.u32 shift1, [in_addr+4]; + ld.u32 shift2, [in_addr+8]; + ld.u32 shift3, [in_addr+12]; + shl.b32 value, input_value, shift1; + st.u32 [out_addr], value; + shl.b32 value, input_value, shift2; + st.u32 [out_addr+4], value; + shl.b32 value, input_value, shift3; + st.u32 [out_addr+8], value; + ret; +} diff --git a/ptx/src/test/spirv_run/shr.spvtxt b/ptx/src/test/spirv_run/shr.spvtxt deleted file mode 100644 index 249e71a..0000000 --- a/ptx/src/test/spirv_run/shr.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %18 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shr_s32.ll b/ptx/src/test/spirv_run/shr_s32.ll new file mode 100644 index 0000000..7bc5489 --- /dev/null +++ b/ptx/src/test/spirv_run/shr_s32.ll @@ -0,0 +1,40 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @shr_s32(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"29": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"31" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"31", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %0 = icmp ugt i32 %"18", 31 + %1 = ashr i32 %"17", %"18" + %"16" = select i1 %0, i32 -1, i32 %1 + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"28" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"28", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shr_s32.ptx b/ptx/src/test/spirv_run/shr_s32.ptx new file mode 100644 index 0000000..94838f0 --- /dev/null +++ b/ptx/src/test/spirv_run/shr_s32.ptx @@ -0,0 +1,23 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry shr_s32( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .s32 temp; + .reg .b32 shift_amount; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.s32 temp, [in_addr]; + ld.b32 shift_amount, [in_addr+4]; + shr.s32 temp, temp, shift_amount; + st.s32 [out_addr], temp; + ret; +} diff --git a/ptx/src/test/spirv_run/shr_u32.ll b/ptx/src/test/spirv_run/shr_u32.ll new file mode 100644 index 0000000..f337c1b --- /dev/null +++ b/ptx/src/test/spirv_run/shr_u32.ll @@ -0,0 +1,59 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @shr_u32(ptr addrspace(4) byref(i64) %"37", ptr addrspace(4) byref(i64) %"38") #0 { +"46": + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"12" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"12", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"13" = load i64, ptr addrspace(4) %"37", align 8 + store i64 %"13", ptr addrspace(5) %"4", align 8 + %"14" = load i64, ptr addrspace(4) %"38", align 8 + store i64 %"14", ptr addrspace(5) %"5", align 8 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"39" = inttoptr i64 %"16" to ptr + %"15" = load i32, ptr %"39", align 4 + store i32 %"15", ptr addrspace(5) %"6", align 4 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"40" = inttoptr i64 %"18" to ptr + %"48" = getelementptr inbounds i8, ptr %"40", i64 4 + %"17" = load i32, ptr %"48", align 4 + store i32 %"17", ptr addrspace(5) %"7", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"41" = inttoptr i64 %"20" to ptr + %"50" = getelementptr inbounds i8, ptr %"41", i64 8 + %"19" = load i32, ptr %"50", align 4 + store i32 %"19", ptr addrspace(5) %"8", align 4 + %"22" = load i32, ptr addrspace(5) %"6", align 4 + %"23" = load i32, ptr addrspace(5) %"7", align 4 + %0 = icmp ugt i32 %"23", 31 + %1 = lshr i32 %"22", %"23" + %"21" = select i1 %0, i32 0, i32 %1 + store i32 %"21", ptr addrspace(5) %"9", align 4 + %"25" = load i32, ptr addrspace(5) %"6", align 4 + %"26" = load i32, ptr addrspace(5) %"8", align 4 + %2 = icmp ugt i32 %"26", 31 + %3 = lshr i32 %"25", %"26" + %"24" = select i1 %2, i32 0, i32 %3 + store i32 %"24", ptr addrspace(5) %"10", align 4 + %"27" = load i64, ptr addrspace(5) %"5", align 8 + %"28" = load i32, ptr addrspace(5) %"9", align 4 + %"44" = inttoptr i64 %"27" to ptr + store i32 %"28", ptr %"44", align 4 + %"29" = load i64, ptr addrspace(5) %"5", align 8 + %"30" = load i32, ptr addrspace(5) %"10", align 4 + %"45" = inttoptr i64 %"29" to ptr + %"52" = getelementptr inbounds i8, ptr %"45", i64 4 + store i32 %"30", ptr %"52", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/shr_u32.ptx b/ptx/src/test/spirv_run/shr_u32.ptx new file mode 100644 index 0000000..3a13c9e --- /dev/null +++ b/ptx/src/test/spirv_run/shr_u32.ptx @@ -0,0 +1,31 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry shr_u32( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp; + .reg .b32 shift_amount1; + .reg .b32 shift_amount2; + .reg .u32 result1; + .reg .u32 result2; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp, [in_addr]; + ld.b32 shift_amount1, [in_addr+4]; + ld.b32 shift_amount2, [in_addr+8]; + + shr.u32 result1, temp, shift_amount1; + shr.u32 result2, temp, shift_amount2; + + st.u32 [out_addr], result1; + st.u32 [out_addr+4], result2; + ret; +} diff --git a/ptx/src/test/spirv_run/sign_extend.ll b/ptx/src/test/spirv_run/sign_extend.ll new file mode 100644 index 0000000..bb72576 --- /dev/null +++ b/ptx/src/test/spirv_run/sign_extend.ll @@ -0,0 +1,29 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @sign_extend(ptr addrspace(4) byref(i64) %"15", ptr addrspace(4) byref(i64) %"16") #0 { +"20": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"15", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"16", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"18" = inttoptr i64 %"12" to ptr + %"17" = load i16, ptr %"18", align 2 + %"11" = sext i16 %"17" to i32 + store i32 %"11", ptr addrspace(5) %"6", align 4 + %"13" = load i64, ptr addrspace(5) %"5", align 8 + %"14" = load i32, ptr addrspace(5) %"6", align 4 + %"19" = inttoptr i64 %"13" to ptr + store i32 %"14", ptr %"19", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/sign_extend.ptx b/ptx/src/test/spirv_run/sign_extend.ptx new file mode 100644 index 0000000..d3af0d5 --- /dev/null +++ b/ptx/src/test/spirv_run/sign_extend.ptx @@ -0,0 +1,20 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry sign_extend( + .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.s16 temp, [in_addr]; + st.s32 [out_addr], temp; + ret; +} \ No newline at end of file diff --git a/ptx/src/test/spirv_run/sin.ll b/ptx/src/test/spirv_run/sin.ll new file mode 100644 index 0000000..40ce553 --- /dev/null +++ b/ptx/src/test/spirv_run/sin.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @sin(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"19", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call afn float @llvm.sin.f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sin.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/sin.spvtxt b/ptx/src/test/spirv_run/sin.spvtxt deleted file mode 100644 index 618d5f2..0000000 --- a/ptx/src/test/spirv_run/sin.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sqrt.ll b/ptx/src/test/spirv_run/sqrt.ll new file mode 100644 index 0000000..332f67a --- /dev/null +++ b/ptx/src/test/spirv_run/sqrt.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @sqrt(ptr addrspace(4) byref(i64) %"17", ptr addrspace(4) byref(i64) %"18") #0 { +"21": + %"7" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"7", align 1 + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca float, align 4, addrspace(5) + %"9" = load i64, ptr addrspace(4) %"17", align 8 + store i64 %"9", ptr addrspace(5) %"4", align 8 + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"5", align 8 + %"12" = load i64, ptr addrspace(5) %"4", align 8 + %"19" = inttoptr i64 %"12" to ptr + %"11" = load float, ptr %"19", align 4 + store float %"11", ptr addrspace(5) %"6", align 4 + %"14" = load float, ptr addrspace(5) %"6", align 4 + %"13" = call afn float @llvm.sqrt.f32(float %"14") + store float %"13", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"5", align 8 + %"16" = load float, ptr addrspace(5) %"6", align 4 + %"20" = inttoptr i64 %"15" to ptr + store float %"16", ptr %"20", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare float @llvm.sqrt.f32(float) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/sqrt.spvtxt b/ptx/src/test/spirv_run/sqrt.spvtxt deleted file mode 100644 index 17f223d..0000000 --- a/ptx/src/test/spirv_run/sqrt.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/st_f16x2.ll b/ptx/src/test/spirv_run/st_f16x2.ll new file mode 100644 index 0000000..69fd33b --- /dev/null +++ b/ptx/src/test/spirv_run/st_f16x2.ll @@ -0,0 +1,43 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @st_f16x2(ptr addrspace(4) byref(i64) %"24", ptr addrspace(4) byref(i64) %"25") #0 { +"34": + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca <2 x half>, align 4, addrspace(5) + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"4", align 8 + %"12" = load i64, ptr addrspace(4) %"25", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"14" = load i64, ptr addrspace(5) %"4", align 8 + %"27" = inttoptr i64 %"14" to ptr + %"26" = load i32, ptr %"27", align 4 + store i32 %"26", ptr addrspace(5) %"6", align 4 + %"16" = load i64, ptr addrspace(5) %"4", align 8 + %"28" = inttoptr i64 %"16" to ptr + %"36" = getelementptr inbounds i8, ptr %"28", i64 4 + %"29" = load i32, ptr %"36", align 4 + store i32 %"29", ptr addrspace(5) %"7", align 4 + %"18" = load i32, ptr addrspace(5) %"6", align 4 + %"19" = load i32, ptr addrspace(5) %"7", align 4 + %"31" = bitcast i32 %"18" to <2 x half> + %"32" = bitcast i32 %"19" to <2 x half> + %0 = fcmp ugt <2 x half> %"31", %"32" + %1 = sext <2 x i1> %0 to <2 x i16> + %"30" = bitcast <2 x i16> %1 to i32 + store i32 %"30", ptr addrspace(5) %"6", align 4 + %"20" = load i64, ptr addrspace(5) %"5", align 8 + %"21" = load i32, ptr addrspace(5) %"6", align 4 + %"33" = inttoptr i64 %"20" to ptr + store i32 %"21", ptr %"33", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/st_f16x2.ptx b/ptx/src/test/spirv_run/st_f16x2.ptx new file mode 100644 index 0000000..b386f68 --- /dev/null +++ b/ptx/src/test/spirv_run/st_f16x2.ptx @@ -0,0 +1,24 @@ +.version 6.5 +.target sm_53 +.address_size 64 + +.visible .entry st_f16x2( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 temp0; + .reg .b32 temp1; + .reg .f16x2 sela; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp0, [in_addr]; + ld.u32 temp1, [in_addr+4]; + set.gtu.u32.f16x2 temp0, temp0, temp1; + st.b32 [out_addr], temp0; + ret; +} diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx b/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx deleted file mode 100644 index 1fc37d1..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx +++ /dev/null @@ -1,31 +0,0 @@ -.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 deleted file mode 100644 index 33812f6..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt +++ /dev/null @@ -1,91 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %50 = 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 - %57 = 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 %57 - %20 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %21 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %48 = 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 - %44 = OpLoad %ulong %13 Aligned 8 - %12 = OpCopyObject %ulong %44 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %12 - OpStore %10 %22 - %15 = OpBitcast %_ptr_Function_ulong %3 - %45 = OpLoad %ulong %15 Aligned 8 - %14 = OpCopyObject %ulong %45 - %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 - %62 = OpLoad %v3ulong %gl_LocalInvocationID - %43 = OpCompositeExtract %ulong %62 0 - %63 = OpBitcast %ulong %43 - %29 = OpUConvert %uint %63 - %28 = OpCopyObject %uint %29 - OpStore %6 %28 - %31 = OpLoad %uint %6 - %64 = OpBitcast %uint %31 - %30 = OpUConvert %ulong %64 - OpStore %7 %30 - %33 = OpLoad %_ptr_CrossWorkgroup_uchar %10 - %34 = OpLoad %ulong %7 - %65 = OpBitcast %_ptr_CrossWorkgroup_uchar %33 - %66 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %65 %34 - %32 = OpBitcast %_ptr_CrossWorkgroup_uchar %66 - OpStore %10 %32 - %36 = OpLoad %_ptr_CrossWorkgroup_uchar %11 - %37 = OpLoad %ulong %7 - %67 = OpBitcast %_ptr_CrossWorkgroup_uchar %36 - %68 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %67 %37 - %35 = OpBitcast %_ptr_CrossWorkgroup_uchar %68 - OpStore %11 %35 - %39 = OpLoad %_ptr_CrossWorkgroup_uchar %10 - %46 = OpBitcast %_ptr_CrossWorkgroup_ulong %39 - %38 = OpLoad %ulong %46 Aligned 8 - OpStore %8 %38 - %40 = OpLoad %_ptr_CrossWorkgroup_uchar %11 - %41 = OpLoad %ulong %8 - %47 = OpBitcast %_ptr_CrossWorkgroup_ulong %40 - OpStore %47 %41 Aligned 8 - 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 deleted file mode 100644 index ef7645d..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx +++ /dev/null @@ -1,35 +0,0 @@ -.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 deleted file mode 100644 index cb77d14..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt +++ /dev/null @@ -1,95 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %58 = 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 - %65 = 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 %65 - %28 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %29 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %56 = 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 - %52 = OpLoad %ulong %21 Aligned 8 - %20 = OpCopyObject %ulong %52 - %30 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %20 - OpStore %14 %30 - %23 = OpBitcast %_ptr_Function_ulong %3 - %53 = OpLoad %ulong %23 Aligned 8 - %22 = OpCopyObject %ulong %53 - %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 - %70 = OpLoad %v3ulong %gl_LocalInvocationID - %51 = OpCompositeExtract %ulong %70 0 - %71 = OpBitcast %ulong %51 - %37 = OpUConvert %uint %71 - %36 = OpCopyObject %uint %37 - OpStore %10 %36 - %39 = OpLoad %uint %10 - %72 = OpBitcast %uint %39 - %38 = OpUConvert %ulong %72 - OpStore %11 %38 - %41 = OpLoad %_ptr_CrossWorkgroup_uchar %15 - %42 = OpLoad %ulong %11 - %73 = OpBitcast %_ptr_CrossWorkgroup_uchar %41 - %74 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %73 %42 - %40 = OpBitcast %_ptr_CrossWorkgroup_uchar %74 - OpStore %16 %40 - %44 = OpLoad %_ptr_CrossWorkgroup_uchar %18 - %45 = OpLoad %ulong %11 - %75 = OpBitcast %_ptr_CrossWorkgroup_uchar %44 - %76 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %75 %45 - %43 = OpBitcast %_ptr_CrossWorkgroup_uchar %76 - OpStore %19 %43 - %47 = OpLoad %_ptr_CrossWorkgroup_uchar %16 - %54 = OpBitcast %_ptr_CrossWorkgroup_ulong %47 - %46 = OpLoad %ulong %54 Aligned 8 - OpStore %12 %46 - %48 = OpLoad %_ptr_CrossWorkgroup_uchar %19 - %49 = OpLoad %ulong %12 - %55 = OpBitcast %_ptr_CrossWorkgroup_ulong %48 - OpStore %55 %49 Aligned 8 - 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 deleted file mode 100644 index 018918c..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx +++ /dev/null @@ -1,35 +0,0 @@ -.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 deleted file mode 100644 index 1d0fdfc..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt +++ /dev/null @@ -1,107 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %66 = 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 - %73 = 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 %73 - %30 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %31 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %64 = 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 - %58 = OpLoad %ulong %21 Aligned 8 - %20 = OpCopyObject %ulong %58 - %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %20 - OpStore %14 %32 - %23 = OpBitcast %_ptr_Function_ulong %3 - %59 = OpLoad %ulong %23 Aligned 8 - %22 = OpCopyObject %ulong %59 - %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 - %78 = OpLoad %v3ulong %gl_LocalInvocationID - %53 = OpCompositeExtract %ulong %78 0 - %79 = OpBitcast %ulong %53 - %39 = OpUConvert %uint %79 - %38 = OpCopyObject %uint %39 - OpStore %10 %38 - %41 = OpLoad %uint %10 - %80 = OpBitcast %uint %41 - %40 = OpUConvert %ulong %80 - OpStore %11 %40 - %42 = OpLoad %ulong %11 - %60 = OpCopyObject %ulong %42 - %28 = OpSNegate %ulong %60 - %44 = OpLoad %_ptr_CrossWorkgroup_uchar %15 - %81 = OpBitcast %_ptr_CrossWorkgroup_uchar %44 - %82 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %81 %28 - %43 = OpBitcast %_ptr_CrossWorkgroup_uchar %82 - OpStore %16 %43 - %45 = OpLoad %ulong %11 - %61 = OpCopyObject %ulong %45 - %29 = OpSNegate %ulong %61 - %47 = OpLoad %_ptr_CrossWorkgroup_uchar %18 - %83 = OpBitcast %_ptr_CrossWorkgroup_uchar %47 - %84 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %83 %29 - %46 = OpBitcast %_ptr_CrossWorkgroup_uchar %84 - OpStore %19 %46 - %49 = OpLoad %_ptr_CrossWorkgroup_uchar %16 - %62 = OpBitcast %_ptr_CrossWorkgroup_ulong %49 - %86 = OpBitcast %_ptr_CrossWorkgroup_uchar %62 - %87 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %86 %ulong_0 - %55 = OpBitcast %_ptr_CrossWorkgroup_ulong %87 - %48 = OpLoad %ulong %55 Aligned 8 - OpStore %12 %48 - %50 = OpLoad %_ptr_CrossWorkgroup_uchar %19 - %51 = OpLoad %ulong %12 - %63 = OpBitcast %_ptr_CrossWorkgroup_ulong %50 - %88 = OpBitcast %_ptr_CrossWorkgroup_uchar %63 - %89 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %88 %ulong_0_0 - %57 = OpBitcast %_ptr_CrossWorkgroup_ulong %89 - OpStore %57 %51 Aligned 8 - 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 deleted file mode 100644 index 5650ada..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_simple.ptx +++ /dev/null @@ -1,25 +0,0 @@ -.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 deleted file mode 100644 index 7a142b7..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - 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 Aligned 8 - %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %13 - OpStore %9 %23 - %16 = OpBitcast %_ptr_Function_ulong %3 - %15 = OpLoad %ulong %16 Aligned 8 - %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 Aligned 8 - OpStore %8 %29 - %31 = OpLoad %_ptr_CrossWorkgroup_uchar %12 - %32 = OpLoad %ulong %8 - %38 = OpBitcast %_ptr_CrossWorkgroup_ulong %31 - OpStore %38 %32 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sub.ll b/ptx/src/test/spirv_run/sub.ll new file mode 100644 index 0000000..2383be0 --- /dev/null +++ b/ptx/src/test/spirv_run/sub.ll @@ -0,0 +1,32 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @sub(ptr addrspace(4) byref(i64) %"19", ptr addrspace(4) byref(i64) %"20") #0 { +"23": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i64, align 8, addrspace(5) + %"7" = alloca i64, align 8, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"20", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"21" = inttoptr i64 %"13" to ptr + %"12" = load i64, ptr %"21", align 8 + store i64 %"12", ptr addrspace(5) %"6", align 8 + %"15" = load i64, ptr addrspace(5) %"6", align 8 + %"14" = sub i64 %"15", 1 + store i64 %"14", ptr addrspace(5) %"7", align 8 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i64, ptr addrspace(5) %"7", align 8 + %"22" = inttoptr i64 %"16" to ptr + store i64 %"17", ptr %"22", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/sub.spvtxt b/ptx/src/test/spirv_run/sub.spvtxt deleted file mode 100644 index 05656dd..0000000 --- a/ptx/src/test/spirv_run/sub.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/subc_cc.ll b/ptx/src/test/spirv_run/subc_cc.ll new file mode 100644 index 0000000..9a08872 --- /dev/null +++ b/ptx/src/test/spirv_run/subc_cc.ll @@ -0,0 +1,90 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @subc_cc(ptr addrspace(4) byref(i64) %"54", ptr addrspace(4) byref(i64) %"55") #0 { +"69": + %"13" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"13", align 1 + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"12" = alloca i32, align 4, addrspace(5) + %"15" = load i64, ptr addrspace(4) %"54", align 8 + store i64 %"15", ptr addrspace(5) %"4", align 8 + %"16" = load i64, ptr addrspace(4) %"55", align 8 + store i64 %"16", ptr addrspace(5) %"5", align 8 + %"18" = load i64, ptr addrspace(5) %"4", align 8 + %"57" = inttoptr i64 %"18" to ptr + %"56" = load i32, ptr %"57", align 4 + store i32 %"56", ptr addrspace(5) %"9", align 4 + %"20" = load i64, ptr addrspace(5) %"4", align 8 + %"58" = inttoptr i64 %"20" to ptr + %"71" = getelementptr inbounds i8, ptr %"58", i64 4 + %"59" = load i32, ptr %"71", align 4 + store i32 %"59", ptr addrspace(5) %"10", align 4 + %"22" = load i64, ptr addrspace(5) %"4", align 8 + %"60" = inttoptr i64 %"22" to ptr + %"73" = getelementptr inbounds i8, ptr %"60", i64 8 + %"21" = load i32, ptr %"73", align 4 + store i32 %"21", ptr addrspace(5) %"11", align 4 + %"24" = load i64, ptr addrspace(5) %"4", align 8 + %"61" = inttoptr i64 %"24" to ptr + %"75" = getelementptr inbounds i8, ptr %"61", i64 12 + %"23" = load i32, ptr %"75", align 4 + store i32 %"23", ptr addrspace(5) %"12", align 4 + %"27" = load i32, ptr addrspace(5) %"9", align 4 + %"28" = load i32, ptr addrspace(5) %"10", align 4 + %0 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %"27", i32 %"28") + %"25" = extractvalue { i32, i1 } %0, 0 + %"26" = extractvalue { i32, i1 } %0, 1 + store i32 %"25", ptr addrspace(5) %"6", align 4 + store i1 %"26", ptr addrspace(5) %"14", align 1 + %"31" = load i1, ptr addrspace(5) %"14", align 1 + %"32" = load i32, ptr addrspace(5) %"6", align 4 + %"33" = load i32, ptr addrspace(5) %"11", align 4 + %1 = zext i1 %"31" to i32 + %2 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %"32", i32 %"33") + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %5 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %3, i32 %1) + %"29" = extractvalue { i32, i1 } %5, 0 + %6 = extractvalue { i32, i1 } %5, 1 + %"30" = xor i1 %4, %6 + store i32 %"29", ptr addrspace(5) %"7", align 4 + store i1 %"30", ptr addrspace(5) %"14", align 1 + %"35" = load i1, ptr addrspace(5) %"14", align 1 + %"36" = load i32, ptr addrspace(5) %"7", align 4 + %"37" = load i32, ptr addrspace(5) %"12", align 4 + %7 = zext i1 %"35" to i32 + %8 = sub i32 %"36", %"37" + %"34" = sub i32 %8, %7 + store i32 %"34", ptr addrspace(5) %"8", align 4 + %"38" = load i64, ptr addrspace(5) %"5", align 8 + %"39" = load i32, ptr addrspace(5) %"6", align 4 + %"66" = inttoptr i64 %"38" to ptr + store i32 %"39", ptr %"66", align 4 + %"40" = load i64, ptr addrspace(5) %"5", align 8 + %"41" = load i32, ptr addrspace(5) %"7", align 4 + %"67" = inttoptr i64 %"40" to ptr + %"77" = getelementptr inbounds i8, ptr %"67", i64 4 + store i32 %"41", ptr %"77", align 4 + %"42" = load i64, ptr addrspace(5) %"5", align 8 + %"43" = load i32, ptr addrspace(5) %"8", align 4 + %"68" = inttoptr i64 %"42" to ptr + %"79" = getelementptr inbounds i8, ptr %"68", i64 8 + store i32 %"43", ptr %"79", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/subc_cc.ptx b/ptx/src/test/spirv_run/subc_cc.ptx new file mode 100644 index 0000000..8234b64 --- /dev/null +++ b/ptx/src/test/spirv_run/subc_cc.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry subc_cc( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .s32 dst1; + .reg .s32 dst2; + .reg .s32 dst3; + .reg .b32 src1; + .reg .b32 src2; + .reg .b32 src3; + .reg .b32 src4; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.s32 src1, [in_addr]; + ld.s32 src2, [in_addr+4]; + ld.b32 src3, [in_addr+8]; + ld.b32 src4, [in_addr+12]; + sub.cc.s32 dst1, src1, src2; + subc.cc.s32 dst2, dst1, src3; + subc.s32 dst3, dst2, src4; + st.s32 [out_addr], dst1; + st.s32 [out_addr+4], dst2; + st.s32 [out_addr+8], dst3; + ret; +} diff --git a/ptx/src/test/spirv_run/subc_cc2.ll b/ptx/src/test/spirv_run/subc_cc2.ll new file mode 100644 index 0000000..aded371 --- /dev/null +++ b/ptx/src/test/spirv_run/subc_cc2.ll @@ -0,0 +1,127 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @subc_cc2(ptr addrspace(4) byref(i64) %"86", ptr addrspace(4) byref(i64) %"87") #0 { +"112": + %"14" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"14", align 1 + %"15" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"15", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"10" = alloca i32, align 4, addrspace(5) + %"11" = alloca i32, align 4, addrspace(5) + %"12" = alloca i32, align 4, addrspace(5) + %"13" = alloca i32, align 4, addrspace(5) + %"16" = load i64, ptr addrspace(4) %"87", align 8 + store i64 %"16", ptr addrspace(5) %"5", align 8 + %0 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 1) + %"88" = extractvalue { i32, i1 } %0, 0 + %"18" = extractvalue { i32, i1 } %0, 1 + store i32 %"88", ptr addrspace(5) %"6", align 4 + store i1 %"18", ptr addrspace(5) %"15", align 1 + %"21" = load i1, ptr addrspace(5) %"15", align 1 + %1 = zext i1 %"21" to i32 + %2 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 -1) + %3 = extractvalue { i32, i1 } %2, 0 + %4 = extractvalue { i32, i1 } %2, 1 + %5 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %3, i32 %1) + %"89" = extractvalue { i32, i1 } %5, 0 + %6 = extractvalue { i32, i1 } %5, 1 + %"20" = xor i1 %4, %6 + store i32 %"89", ptr addrspace(5) %"7", align 4 + store i1 %"20", ptr addrspace(5) %"15", align 1 + %"23" = load i1, ptr addrspace(5) %"15", align 1 + %7 = zext i1 %"23" to i32 + %"90" = sub i32 2, %7 + store i32 %"90", ptr addrspace(5) %"8", align 4 + %"25" = load i1, ptr addrspace(5) %"14", align 1 + %8 = zext i1 %"25" to i32 + %"91" = add i32 0, %8 + store i32 %"91", ptr addrspace(5) %"9", align 4 + %9 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 1) + %"92" = extractvalue { i32, i1 } %9, 0 + %"27" = extractvalue { i32, i1 } %9, 1 + store i32 %"92", ptr addrspace(5) %"6", align 4 + store i1 %"27", ptr addrspace(5) %"15", align 1 + %"30" = load i1, ptr addrspace(5) %"15", align 1 + %10 = zext i1 %"30" to i32 + %11 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 0) + %12 = extractvalue { i32, i1 } %11, 0 + %13 = extractvalue { i32, i1 } %11, 1 + %14 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %12, i32 %10) + %"93" = extractvalue { i32, i1 } %14, 0 + %15 = extractvalue { i32, i1 } %14, 1 + %"29" = xor i1 %13, %15 + store i32 %"93", ptr addrspace(5) %"10", align 4 + store i1 %"29", ptr addrspace(5) %"15", align 1 + %"32" = load i1, ptr addrspace(5) %"15", align 1 + %16 = zext i1 %"32" to i32 + %"94" = sub i32 2, %16 + store i32 %"94", ptr addrspace(5) %"11", align 4 + %17 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 0) + %"95" = extractvalue { i32, i1 } %17, 0 + %"34" = extractvalue { i32, i1 } %17, 1 + store i32 %"95", ptr addrspace(5) %"6", align 4 + store i1 %"34", ptr addrspace(5) %"15", align 1 + %"37" = load i1, ptr addrspace(5) %"15", align 1 + %18 = zext i1 %"37" to i32 + %19 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 1) + %20 = extractvalue { i32, i1 } %19, 0 + %21 = extractvalue { i32, i1 } %19, 1 + %22 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %20, i32 %18) + %"96" = extractvalue { i32, i1 } %22, 0 + %23 = extractvalue { i32, i1 } %22, 1 + %"36" = xor i1 %21, %23 + store i32 %"96", ptr addrspace(5) %"12", align 4 + store i1 %"36", ptr addrspace(5) %"15", align 1 + %"39" = load i1, ptr addrspace(5) %"15", align 1 + %24 = zext i1 %"39" to i32 + %"97" = sub i32 2, %24 + store i32 %"97", ptr addrspace(5) %"13", align 4 + %"40" = load i64, ptr addrspace(5) %"5", align 8 + %"41" = load i32, ptr addrspace(5) %"7", align 4 + %"98" = inttoptr i64 %"40" to ptr + store i32 %"41", ptr %"98", align 4 + %"42" = load i64, ptr addrspace(5) %"5", align 8 + %"43" = load i32, ptr addrspace(5) %"8", align 4 + %"100" = inttoptr i64 %"42" to ptr + %"114" = getelementptr inbounds i8, ptr %"100", i64 4 + store i32 %"43", ptr %"114", align 4 + %"44" = load i64, ptr addrspace(5) %"5", align 8 + %"45" = load i32, ptr addrspace(5) %"9", align 4 + %"102" = inttoptr i64 %"44" to ptr + %"116" = getelementptr inbounds i8, ptr %"102", i64 8 + store i32 %"45", ptr %"116", align 4 + %"46" = load i64, ptr addrspace(5) %"5", align 8 + %"47" = load i32, ptr addrspace(5) %"10", align 4 + %"104" = inttoptr i64 %"46" to ptr + %"118" = getelementptr inbounds i8, ptr %"104", i64 12 + store i32 %"47", ptr %"118", align 4 + %"48" = load i64, ptr addrspace(5) %"5", align 8 + %"49" = load i32, ptr addrspace(5) %"11", align 4 + %"106" = inttoptr i64 %"48" to ptr + %"120" = getelementptr inbounds i8, ptr %"106", i64 16 + store i32 %"49", ptr %"120", align 4 + %"50" = load i64, ptr addrspace(5) %"5", align 8 + %"51" = load i32, ptr addrspace(5) %"12", align 4 + %"108" = inttoptr i64 %"50" to ptr + %"122" = getelementptr inbounds i8, ptr %"108", i64 20 + store i32 %"51", ptr %"122", align 4 + %"52" = load i64, ptr addrspace(5) %"5", align 8 + %"53" = load i32, ptr addrspace(5) %"13", align 4 + %"110" = inttoptr i64 %"52" to ptr + %"124" = getelementptr inbounds i8, ptr %"110", i64 24 + store i32 %"53", ptr %"124", align 4 + ret void +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #1 + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/ptx/src/test/spirv_run/subc_cc2.ptx b/ptx/src/test/spirv_run/subc_cc2.ptx new file mode 100644 index 0000000..2c776a4 --- /dev/null +++ b/ptx/src/test/spirv_run/subc_cc2.ptx @@ -0,0 +1,55 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry subc_cc2( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 unused; + + .reg .b32 result_1; + .reg .b32 carry_out_1_1; + .reg .b32 carry_out_1_2; + .reg .b32 result_2; + .reg .b32 carry_out_2; + .reg .b32 result_3; + .reg .b32 carry_out_3; + + ld.param.u64 out_addr, [output]; + + // set carry=1 + sub.cc.s32 unused, 0, 1; + // overflow (b + CC.CF), no underflow in whole operation + subc.cc.s32 result_1, 0, 4294967295; + // write carry + subc.s32 carry_out_1_1, 2, 0; + // make sure the overflow in (b + CC.CF) is not detected by addc + addc.s32 carry_out_1_2, 0, 0; + + // set carry=1 + sub.cc.s32 unused, 0, 1; + // underflow in substraction, underflow in whole operation + subc.cc.s32 result_2, 0, 0; + // write carry + subc.s32 carry_out_2, 2, 0; + + // set carry=0 + sub.cc.s32 unused, 0, 0; + // same operation as bove, but 0-1-0 instead of 0-0-1 + subc.cc.s32 result_3, 0, 1; + // write carry + subc.s32 carry_out_3, 2, 0; + + st.s32 [out_addr], result_1; + st.s32 [out_addr+4], carry_out_1_1; + st.s32 [out_addr+8], carry_out_1_2; + st.s32 [out_addr+12], result_2; + st.s32 [out_addr+16], carry_out_2; + st.s32 [out_addr+20], result_3; + st.s32 [out_addr+24], carry_out_3; + ret; +} diff --git a/ptx/src/test/spirv_run/vector.ll b/ptx/src/test/spirv_run/vector.ll new file mode 100644 index 0000000..a53904e --- /dev/null +++ b/ptx/src/test/spirv_run/vector.ll @@ -0,0 +1,96 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define private <2 x i32> @"1"(<2 x i32> %"20") #0 { +"52": + %"3" = alloca <2 x i32>, align 8, addrspace(5) + %"2" = alloca <2 x i32>, align 8, addrspace(5) + %"16" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"16", align 1 + %"17" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"17", align 1 + %"4" = alloca <2 x i32>, align 8, addrspace(5) + %"5" = alloca i32, align 4, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + store <2 x i32> %"20", ptr addrspace(5) %"3", align 8 + %0 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"3", i32 0, i32 0 + %"22" = load i32, ptr addrspace(5) %0, align 4 + %1 = alloca i32, align 4, addrspace(5) + store i32 %"22", ptr addrspace(5) %1, align 4 + %"21" = load i32, ptr addrspace(5) %1, align 4 + store i32 %"21", ptr addrspace(5) %"5", align 4 + %2 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"3", i32 0, i32 1 + %"24" = load i32, ptr addrspace(5) %2, align 4 + %3 = alloca i32, align 4, addrspace(5) + store i32 %"24", ptr addrspace(5) %3, align 4 + %"23" = load i32, ptr addrspace(5) %3, align 4 + store i32 %"23", ptr addrspace(5) %"6", align 4 + %"26" = load i32, ptr addrspace(5) %"5", align 4 + %"27" = load i32, ptr addrspace(5) %"6", align 4 + %"25" = add i32 %"26", %"27" + store i32 %"25", ptr addrspace(5) %"6", align 4 + %"29" = load i32, ptr addrspace(5) %"6", align 4 + %4 = alloca i32, align 4, addrspace(5) + store i32 %"29", ptr addrspace(5) %4, align 4 + %"28" = load i32, ptr addrspace(5) %4, align 4 + %5 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"4", i32 0, i32 0 + store i32 %"28", ptr addrspace(5) %5, align 4 + %"31" = load i32, ptr addrspace(5) %"6", align 4 + %6 = alloca i32, align 4, addrspace(5) + store i32 %"31", ptr addrspace(5) %6, align 4 + %"30" = load i32, ptr addrspace(5) %6, align 4 + %7 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"4", i32 0, i32 1 + store i32 %"30", ptr addrspace(5) %7, align 4 + %8 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"4", i32 0, i32 1 + %"33" = load i32, ptr addrspace(5) %8, align 4 + %9 = alloca i32, align 4, addrspace(5) + store i32 %"33", ptr addrspace(5) %9, align 4 + %"32" = load i32, ptr addrspace(5) %9, align 4 + %10 = getelementptr inbounds <2 x i32>, ptr addrspace(5) %"4", i32 0, i32 0 + store i32 %"32", ptr addrspace(5) %10, align 4 + %"35" = load <2 x i32>, ptr addrspace(5) %"4", align 8 + %11 = alloca <2 x i32>, align 8, addrspace(5) + store <2 x i32> %"35", ptr addrspace(5) %11, align 8 + %"34" = load <2 x i32>, ptr addrspace(5) %11, align 8 + store <2 x i32> %"34", ptr addrspace(5) %"2", align 8 + %"36" = load <2 x i32>, ptr addrspace(5) %"2", align 8 + ret <2 x i32> %"36" +} + +define protected amdgpu_kernel void @vector(ptr addrspace(4) byref(i64) %"47", ptr addrspace(4) byref(i64) %"48") #0 { +"53": + %"18" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"18", align 1 + %"19" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"19", align 1 + %"10" = alloca i64, align 8, addrspace(5) + %"11" = alloca i64, align 8, addrspace(5) + %"12" = alloca <2 x i32>, align 8, addrspace(5) + %"13" = alloca i32, align 4, addrspace(5) + %"14" = alloca i32, align 4, addrspace(5) + %"15" = alloca i64, align 8, addrspace(5) + %"37" = load i64, ptr addrspace(4) %"47", align 8 + store i64 %"37", ptr addrspace(5) %"10", align 8 + %"38" = load i64, ptr addrspace(4) %"48", align 8 + store i64 %"38", ptr addrspace(5) %"11", align 8 + %"40" = load i64, ptr addrspace(5) %"10", align 8 + %"49" = inttoptr i64 %"40" to ptr + %"39" = load <2 x i32>, ptr %"49", align 8 + store <2 x i32> %"39", ptr addrspace(5) %"12", align 8 + %"42" = load <2 x i32>, ptr addrspace(5) %"12", align 8 + %"41" = call <2 x i32> @"1"(<2 x i32> %"42") + store <2 x i32> %"41", ptr addrspace(5) %"12", align 8 + %"44" = load <2 x i32>, ptr addrspace(5) %"12", align 8 + %"50" = bitcast <2 x i32> %"44" to i64 + %0 = alloca i64, align 8, addrspace(5) + store i64 %"50", ptr addrspace(5) %0, align 8 + %"43" = load i64, ptr addrspace(5) %0, align 8 + store i64 %"43", ptr addrspace(5) %"15", align 8 + %"45" = load i64, ptr addrspace(5) %"11", align 8 + %"46" = load <2 x i32>, ptr addrspace(5) %"12", align 8 + %"51" = inttoptr i64 %"45" to ptr + store <2 x i32> %"46", ptr %"51", align 8 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/vector.spvtxt b/ptx/src/test/spirv_run/vector.spvtxt deleted file mode 100644 index ecf2858..0000000 --- a/ptx/src/test/spirv_run/vector.spvtxt +++ /dev/null @@ -1,99 +0,0 @@ - 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 Aligned 8 - OpStore %28 %36 - %37 = OpLoad %ulong %27 Aligned 8 - OpStore %29 %37 - %39 = OpLoad %ulong %28 - %46 = OpConvertUToPtr %_ptr_Generic_v2uint %39 - %38 = OpLoad %v2uint %46 Aligned 8 - 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 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/vector4.ll b/ptx/src/test/spirv_run/vector4.ll new file mode 100644 index 0000000..53187f7 --- /dev/null +++ b/ptx/src/test/spirv_run/vector4.ll @@ -0,0 +1,35 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @vector4(ptr addrspace(4) byref(i64) %"18", ptr addrspace(4) byref(i64) %"19") #0 { +"24": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca <4 x i32>, align 16, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"18", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"19", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"20" = inttoptr i64 %"13" to ptr + %"12" = load <4 x i32>, ptr %"20", align 16 + store <4 x i32> %"12", ptr addrspace(5) %"6", align 16 + %0 = getelementptr inbounds <4 x i32>, ptr addrspace(5) %"6", i32 0, i32 3 + %"15" = load i32, ptr addrspace(5) %0, align 4 + %1 = alloca i32, align 4, addrspace(5) + store i32 %"15", ptr addrspace(5) %1, align 4 + %"21" = load i32, ptr addrspace(5) %1, align 4 + store i32 %"21", ptr addrspace(5) %"7", align 4 + %"16" = load i64, ptr addrspace(5) %"5", align 8 + %"17" = load i32, ptr addrspace(5) %"7", align 4 + %"23" = inttoptr i64 %"16" to ptr + store i32 %"17", ptr %"23", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/vector4.ptx b/ptx/src/test/spirv_run/vector4.ptx new file mode 100644 index 0000000..d010b70 --- /dev/null +++ b/ptx/src/test/spirv_run/vector4.ptx @@ -0,0 +1,22 @@ +.version 6.5 +.target sm_60 +.address_size 64 + +.visible .entry vector4( + .param .u64 input_p, + .param .u64 output_p +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .v4 .u32 temp; + .reg .u32 temp_scalar; + + ld.param.u64 in_addr, [input_p]; + ld.param.u64 out_addr, [output_p]; + + ld.v4.u32 temp, [in_addr]; + mov.b32 temp_scalar, temp.w; + st.u32 [out_addr], temp_scalar; + ret; +} \ No newline at end of file diff --git a/ptx/src/test/spirv_run/vector_extract.ll b/ptx/src/test/spirv_run/vector_extract.ll new file mode 100644 index 0000000..bceac42 --- /dev/null +++ b/ptx/src/test/spirv_run/vector_extract.ll @@ -0,0 +1,97 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @vector_extract(ptr addrspace(4) byref(i64) %"49", ptr addrspace(4) byref(i64) %"50") #0 { +"61": + %"17" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"17", align 1 + %"18" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"18", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i16, align 2, addrspace(5) + %"7" = alloca i16, align 2, addrspace(5) + %"8" = alloca i16, align 2, addrspace(5) + %"9" = alloca i16, align 2, addrspace(5) + %"10" = alloca <4 x i16>, align 8, addrspace(5) + %"19" = load i64, ptr addrspace(4) %"49", align 8 + store i64 %"19", ptr addrspace(5) %"4", align 8 + %"20" = load i64, ptr addrspace(4) %"50", align 8 + store i64 %"20", ptr addrspace(5) %"5", align 8 + %"21" = load i64, ptr addrspace(5) %"4", align 8 + %"51" = inttoptr i64 %"21" to ptr addrspace(1) + %"11" = load <4 x i8>, ptr addrspace(1) %"51", align 4 + %"52" = extractelement <4 x i8> %"11", i32 0 + %"53" = extractelement <4 x i8> %"11", i32 1 + %"54" = extractelement <4 x i8> %"11", i32 2 + %"55" = extractelement <4 x i8> %"11", i32 3 + %"22" = zext i8 %"52" to i16 + %"23" = zext i8 %"53" to i16 + %"24" = zext i8 %"54" to i16 + %"25" = zext i8 %"55" to i16 + store i16 %"22", ptr addrspace(5) %"6", align 2 + store i16 %"23", ptr addrspace(5) %"7", align 2 + store i16 %"24", ptr addrspace(5) %"8", align 2 + store i16 %"25", ptr addrspace(5) %"9", align 2 + %"26" = load i16, ptr addrspace(5) %"7", align 2 + %"27" = load i16, ptr addrspace(5) %"8", align 2 + %"28" = load i16, ptr addrspace(5) %"9", align 2 + %"29" = load i16, ptr addrspace(5) %"6", align 2 + %0 = insertelement <4 x i16> undef, i16 %"26", i32 0 + %1 = insertelement <4 x i16> %0, i16 %"27", i32 1 + %2 = insertelement <4 x i16> %1, i16 %"28", i32 2 + %"12" = insertelement <4 x i16> %2, i16 %"29", i32 3 + %3 = alloca <4 x i16>, align 8, addrspace(5) + store <4 x i16> %"12", ptr addrspace(5) %3, align 8 + %"30" = load <4 x i16>, ptr addrspace(5) %3, align 8 + store <4 x i16> %"30", ptr addrspace(5) %"10", align 8 + %"31" = load <4 x i16>, ptr addrspace(5) %"10", align 8 + %4 = alloca <4 x i16>, align 8, addrspace(5) + store <4 x i16> %"31", ptr addrspace(5) %4, align 8 + %"13" = load <4 x i16>, ptr addrspace(5) %4, align 8 + %"32" = extractelement <4 x i16> %"13", i32 0 + %"33" = extractelement <4 x i16> %"13", i32 1 + %"34" = extractelement <4 x i16> %"13", i32 2 + %"35" = extractelement <4 x i16> %"13", i32 3 + store i16 %"32", ptr addrspace(5) %"8", align 2 + store i16 %"33", ptr addrspace(5) %"9", align 2 + store i16 %"34", ptr addrspace(5) %"6", align 2 + store i16 %"35", ptr addrspace(5) %"7", align 2 + %"36" = load i16, ptr addrspace(5) %"8", align 2 + %"37" = load i16, ptr addrspace(5) %"9", align 2 + %"38" = load i16, ptr addrspace(5) %"6", align 2 + %"39" = load i16, ptr addrspace(5) %"7", align 2 + %5 = insertelement <4 x i16> undef, i16 %"36", i32 0 + %6 = insertelement <4 x i16> %5, i16 %"37", i32 1 + %7 = insertelement <4 x i16> %6, i16 %"38", i32 2 + %"15" = insertelement <4 x i16> %7, i16 %"39", i32 3 + %8 = alloca <4 x i16>, align 8, addrspace(5) + store <4 x i16> %"15", ptr addrspace(5) %8, align 8 + %"14" = load <4 x i16>, ptr addrspace(5) %8, align 8 + %"40" = extractelement <4 x i16> %"14", i32 0 + %"41" = extractelement <4 x i16> %"14", i32 1 + %"42" = extractelement <4 x i16> %"14", i32 2 + %"43" = extractelement <4 x i16> %"14", i32 3 + store i16 %"40", ptr addrspace(5) %"9", align 2 + store i16 %"41", ptr addrspace(5) %"6", align 2 + store i16 %"42", ptr addrspace(5) %"7", align 2 + store i16 %"43", ptr addrspace(5) %"8", align 2 + %"44" = load i16, ptr addrspace(5) %"6", align 2 + %"45" = load i16, ptr addrspace(5) %"7", align 2 + %"46" = load i16, ptr addrspace(5) %"8", align 2 + %"47" = load i16, ptr addrspace(5) %"9", align 2 + %"56" = trunc i16 %"44" to i8 + %"57" = trunc i16 %"45" to i8 + %"58" = trunc i16 %"46" to i8 + %"59" = trunc i16 %"47" to i8 + %9 = insertelement <4 x i8> undef, i8 %"56", i32 0 + %10 = insertelement <4 x i8> %9, i8 %"57", i32 1 + %11 = insertelement <4 x i8> %10, i8 %"58", i32 2 + %"16" = insertelement <4 x i8> %11, i8 %"59", i32 3 + %"48" = load i64, ptr addrspace(5) %"5", align 8 + %"60" = inttoptr i64 %"48" to ptr addrspace(1) + store <4 x i8> %"16", ptr addrspace(1) %"60", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/vector_extract.spvtxt b/ptx/src/test/spirv_run/vector_extract.spvtxt deleted file mode 100644 index 802c69b..0000000 --- a/ptx/src/test/spirv_run/vector_extract.spvtxt +++ /dev/null @@ -1,125 +0,0 @@ - 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 Aligned 8 - OpStore %4 %19 - %20 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %20 - %21 = OpLoad %ulong %4 - %49 = OpConvertUToPtr %_ptr_CrossWorkgroup_v4uchar %21 - %11 = OpLoad %v4uchar %49 Aligned 4 - %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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/verify.py b/ptx/src/test/spirv_run/verify.py new file mode 100644 index 0000000..4ef6465 --- /dev/null +++ b/ptx/src/test/spirv_run/verify.py @@ -0,0 +1,21 @@ +import os, sys, subprocess + +def main(path): + dirs = sorted(os.listdir(path)) + for file in dirs: + if not file.endswith(".spvtxt"): + continue + full_file = os.path.join(path, file) + print(file) + spv_file = f"/tmp/{file}.spv" + # We nominally emit spv1.3, but use spv1.4 feature (OpEntryPoint interface changes in 1.4) + proc1 = subprocess.run(["spirv-as", "--target-env", "spv1.4", full_file, "-o", spv_file]) + proc2 = subprocess.run(["spirv-dis", spv_file, "-o", f"{spv_file}.dis.txt"]) + proc3 = subprocess.run(["spirv-val", spv_file ]) + if proc1.returncode != 0 or proc2.returncode != 0 or proc3.returncode != 0: + print(proc1.returncode) + print(proc2.returncode) + print(proc3.returncode) + +if __name__ == "__main__": + main(sys.argv[1]) diff --git a/ptx/src/test/spirv_run/vote_ballot.ll b/ptx/src/test/spirv_run/vote_ballot.ll new file mode 100644 index 0000000..200eccc --- /dev/null +++ b/ptx/src/test/spirv_run/vote_ballot.ll @@ -0,0 +1,52 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +declare i32 @__zluda_ptx_impl__vote_sync_ballot_b32_32(i1, i32) #0 + +define protected amdgpu_kernel void @vote_ballot(ptr addrspace(4) byref(i64) %"41", ptr addrspace(4) byref(i64) %"42") #1 { +"51": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"42", align 8 + store i64 %"12", ptr addrspace(5) %"5", align 8 + %"43" = call i32 @__zluda_ptx_impl__vote_sync_ballot_b32_32(i1 true, i32 1) + store i32 %"43", ptr addrspace(5) %"6", align 4 + %"44" = call i32 @__zluda_ptx_impl__vote_sync_ballot_b32_32(i1 false, i32 16777215) + store i32 %"44", ptr addrspace(5) %"7", align 4 + %"45" = call i32 @__zluda_ptx_impl__vote_sync_ballot_b32_32(i1 true, i32 2) + store i32 %"45", ptr addrspace(5) %"8", align 4 + %"46" = call i32 @__zluda_ptx_impl__vote_sync_ballot_b32_32(i1 true, i32 3) + store i32 %"46", ptr addrspace(5) %"9", align 4 + %"17" = load i64, ptr addrspace(5) %"5", align 8 + %"18" = load i32, ptr addrspace(5) %"6", align 4 + %"47" = inttoptr i64 %"17" to ptr + %"57" = getelementptr inbounds i8, ptr %"47", i64 0 + store i32 %"18", ptr %"57", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"7", align 4 + %"48" = inttoptr i64 %"19" to ptr + %"59" = getelementptr inbounds i8, ptr %"48", i64 4 + store i32 %"20", ptr %"59", align 4 + %"21" = load i64, ptr addrspace(5) %"5", align 8 + %"22" = load i32, ptr addrspace(5) %"8", align 4 + %"49" = inttoptr i64 %"21" to ptr + %"61" = getelementptr inbounds i8, ptr %"49", i64 8 + store i32 %"22", ptr %"61", align 4 + %"23" = load i64, ptr addrspace(5) %"5", align 8 + %"24" = load i32, ptr addrspace(5) %"9", align 4 + %"50" = inttoptr i64 %"23" to ptr + %"63" = getelementptr inbounds i8, ptr %"50", i64 12 + store i32 %"24", ptr %"63", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "no-trapping-math"="true" "uniform-work-group-size"="true" } +attributes #1 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/vote_ballot.ptx b/ptx/src/test/spirv_run/vote_ballot.ptx new file mode 100644 index 0000000..160c452 --- /dev/null +++ b/ptx/src/test/spirv_run/vote_ballot.ptx @@ -0,0 +1,29 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry vote_ballot( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp1; + .reg .u32 temp2; + .reg .u32 temp3; + .reg .u32 temp4; + + ld.param.u64 out_addr, [output]; + + vote.sync.ballot.b32 temp1, 1, 1; + vote.sync.ballot.b32 temp2, 0, 0xffffff; + vote.sync.ballot.b32 temp3, 1, 2; + vote.sync.ballot.b32 temp4, 1, 3; + + st.u32 [out_addr+0], temp1; + st.u32 [out_addr+4], temp2; + st.u32 [out_addr+8], temp3; + st.u32 [out_addr+12], temp4; + ret; +} diff --git a/ptx/src/test/spirv_run/vshr.ll b/ptx/src/test/spirv_run/vshr.ll new file mode 100644 index 0000000..e3b6b5e --- /dev/null +++ b/ptx/src/test/spirv_run/vshr.ll @@ -0,0 +1,49 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @vshr(ptr addrspace(4) byref(i64) %"30", ptr addrspace(4) byref(i64) %"31") #0 { +"39": + %"10" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"10", align 1 + %"11" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"11", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"8" = alloca i32, align 4, addrspace(5) + %"9" = alloca i32, align 4, addrspace(5) + %"12" = load i64, ptr addrspace(4) %"30", align 8 + store i64 %"12", ptr addrspace(5) %"4", align 8 + %"13" = load i64, ptr addrspace(4) %"31", align 8 + store i64 %"13", ptr addrspace(5) %"5", align 8 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"33" = inttoptr i64 %"15" to ptr + %"32" = load i32, ptr %"33", align 4 + store i32 %"32", ptr addrspace(5) %"7", align 4 + %"17" = load i64, ptr addrspace(5) %"4", align 8 + %"34" = inttoptr i64 %"17" to ptr + %"41" = getelementptr inbounds i8, ptr %"34", i64 4 + %"35" = load i32, ptr %"41", align 4 + store i32 %"35", ptr addrspace(5) %"8", align 4 + %"19" = load i64, ptr addrspace(5) %"4", align 8 + %"36" = inttoptr i64 %"19" to ptr + %"43" = getelementptr inbounds i8, ptr %"36", i64 8 + %"37" = load i32, ptr %"43", align 4 + store i32 %"37", ptr addrspace(5) %"9", align 4 + %"21" = load i32, ptr addrspace(5) %"7", align 4 + %"22" = load i32, ptr addrspace(5) %"8", align 4 + %"23" = load i32, ptr addrspace(5) %"9", align 4 + %0 = icmp ugt i32 %"22", 31 + %1 = lshr i32 %"21", %"22" + %2 = select i1 %0, i32 0, i32 %1 + %"20" = add i32 %2, %"23" + store i32 %"20", ptr addrspace(5) %"6", align 4 + %"24" = load i64, ptr addrspace(5) %"5", align 8 + %"25" = load i32, ptr addrspace(5) %"6", align 4 + %"38" = inttoptr i64 %"24" to ptr + store i32 %"25", ptr %"38", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/vshr.ptx b/ptx/src/test/spirv_run/vshr.ptx new file mode 100644 index 0000000..3f0f0a9 --- /dev/null +++ b/ptx/src/test/spirv_run/vshr.ptx @@ -0,0 +1,27 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry vshr( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 temp1; + .reg .u32 temp2; + .reg .u32 temp3; + .reg .u32 temp4; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + ld.b32 temp2, [in_addr]; + ld.b32 temp3, [in_addr+4]; + ld.b32 temp4, [in_addr+8]; + + vshr.u32.u32.u32.clamp.add temp1, temp2, temp3, temp4; + + st.u32 [out_addr], temp1; + ret; +} diff --git a/ptx/src/test/spirv_run/xor.ll b/ptx/src/test/spirv_run/xor.ll new file mode 100644 index 0000000..7181bd1 --- /dev/null +++ b/ptx/src/test/spirv_run/xor.ll @@ -0,0 +1,38 @@ +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7" +target triple = "amdgcn-amd-amdhsa" + +define protected amdgpu_kernel void @xor(ptr addrspace(4) byref(i64) %"23", ptr addrspace(4) byref(i64) %"24") #0 { +"28": + %"8" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"8", align 1 + %"9" = alloca i1, align 1, addrspace(5) + store i1 false, ptr addrspace(5) %"9", align 1 + %"4" = alloca i64, align 8, addrspace(5) + %"5" = alloca i64, align 8, addrspace(5) + %"6" = alloca i32, align 4, addrspace(5) + %"7" = alloca i32, align 4, addrspace(5) + %"10" = load i64, ptr addrspace(4) %"23", align 8 + store i64 %"10", ptr addrspace(5) %"4", align 8 + %"11" = load i64, ptr addrspace(4) %"24", align 8 + store i64 %"11", ptr addrspace(5) %"5", align 8 + %"13" = load i64, ptr addrspace(5) %"4", align 8 + %"25" = inttoptr i64 %"13" to ptr + %"12" = load i32, ptr %"25", align 4 + store i32 %"12", ptr addrspace(5) %"6", align 4 + %"15" = load i64, ptr addrspace(5) %"4", align 8 + %"26" = inttoptr i64 %"15" to ptr + %"30" = getelementptr inbounds i8, ptr %"26", i64 4 + %"14" = load i32, ptr %"30", align 4 + store i32 %"14", ptr addrspace(5) %"7", align 4 + %"17" = load i32, ptr addrspace(5) %"6", align 4 + %"18" = load i32, ptr addrspace(5) %"7", align 4 + %"16" = xor i32 %"17", %"18" + store i32 %"16", ptr addrspace(5) %"6", align 4 + %"19" = load i64, ptr addrspace(5) %"5", align 8 + %"20" = load i32, ptr addrspace(5) %"6", align 4 + %"27" = inttoptr i64 %"19" to ptr + store i32 %"20", ptr %"27", align 4 + ret void +} + +attributes #0 = { "amdgpu-unsafe-fp-atomics"="true" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "no-trapping-math"="true" "uniform-work-group-size"="true" } diff --git a/ptx/src/test/spirv_run/xor.spvtxt b/ptx/src/test/spirv_run/xor.spvtxt deleted file mode 100644 index 4cc8968..0000000 --- a/ptx/src/test/spirv_run/xor.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - 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 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %22 = OpIAdd %ulong %15 %ulong_4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %22 - %14 = OpLoad %uint %24 Aligned 4 - 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 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/translate.rs b/ptx/src/translate.rs index 18d750f..041c690 100644 --- a/ptx/src/translate.rs +++ b/ptx/src/translate.rs @@ -1,1899 +1,1218 @@ -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 crate::llvm::Message; +use crate::{ast, emit, llvm, raytracing}; +use bit_vec::BitVec; +use hip_common::raytracing::VariablesBlock; +use hip_common::{kernel_metadata, CompilationMode}; +use paste::paste; +pub use raytracing::Module as RaytracingModule; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::alloc::Layout; +use std::cell::RefCell; +use std::collections::{btree_map, hash_map, BTreeMap}; +use std::ffi::{CStr, CString}; +use std::num::NonZeroU32; +use std::{borrow::Cow, collections::BTreeSet, hash::Hash, iter, mem, rc::Rc}; +use zluda_llvm::bit_writer::*; +use zluda_llvm::core::LLVMPrintModuleToString; -use rspirv::binary::Assemble; +static ZLUDA_PTX_IMPL_AMD: &'static [u8] = include_bytes!("../lib/zluda_ptx_impl.bc"); +const ZLUDA_PTX_PREFIX: &'static str = "__zluda_ptx_impl__"; -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) +macro_rules! derive_error { + (enum $type_:ident { + $( $variant:ident $(($underlying:ty))? ),+ + }) => { + #[derive(Debug)] + pub enum $type_ { + $( + $variant $(($underlying))? , + )+ } - 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), - Pointer(Box, spirv::StorageClass), - Func(Option>, Vec), - Struct(Vec), -} - -impl SpirvType { - fn new_pointer(t: ast::Type, sc: spirv::StorageClass) -> Self { - let key = t.into(); - SpirvType::Pointer(Box::new(key), sc) - } -} - -impl From 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 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 { - 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 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 for SpirvType { - fn from(t: ast::ScalarType) -> Self { - SpirvType::Base(t.into()) - } -} - -struct TypeWordMap { - void: spirv::Word, - complex: HashMap, - 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 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::::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) + impl $type_ { + $( + paste! { + #[allow(dead_code)] + pub(crate) fn [<$variant:snake>] ( $(x: $underlying)? ) -> Self { + let result = Self :: $variant $((x as $underlying))?; + if cfg!(debug_assertions) { + panic!("{:?}", result); + } else { + result + } } - 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::>(); - *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::>(); - *self - .complex - .entry(t) - .or_insert_with(|| b.type_struct(underlying_ids)) + } + )+ + } + + impl std::fmt::Display for $type_ { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "{:?}", self) } } } +} - fn get_or_add_fn( +derive_error! { + enum TranslateError { + UnknownSymbol, + UntypedSymbol, + MismatchedType, + LLVM(llvm::Message), + Unreachable, + Todo, + UnexpectedPattern, + SymbolRedefinition + } +} + +impl std::error::Error for TranslateError {} + +pub struct Module<'input> { + pub(crate) llvm_module: llvm::Module, + pub(crate) _llvm_context: llvm::Context, + pub kernel_arguments: FxHashMap>, + pub bitcode_modules: Vec<&'static [u8]>, + pub metadata: Metadata<'input>, + pub compilation_mode: CompilationMode, +} + +impl<'input> Module<'input> { + pub fn get_bitcode_main(&self) -> llvm::MemoryBuffer { + unsafe { + llvm::MemoryBuffer::from_ffi(LLVMWriteBitcodeToMemoryBuffer(self.llvm_module.get())) + } + } + + pub fn get_llvm_text(&self) -> Message { + unsafe { llvm::Message::from_ffi(LLVMPrintModuleToString(self.llvm_module.get())) } + } + + pub fn get_bitcode_all<'a>( + &'a self, + ) -> impl Iterator + '_ { + unsafe { + let main_bc = llvm::MemoryBuffer::from_ffi(LLVMWriteBitcodeToMemoryBuffer( + self.llvm_module.get(), + )); + let main_name = CStr::from_bytes_with_nul_unchecked(b"main\0"); + iter::once((main_bc, main_name)).chain(self.bitcode_modules.iter().map(|ptx_impl| { + ( + llvm::MemoryBuffer::create_no_copy(ptx_impl, false), + CStr::from_bytes_with_nul_unchecked(b"ptx_impl\0"), + ) + })) + } + } + + pub fn get_bitcode_multi<'a>( + mods: impl Iterator>, + ) -> Vec<(llvm::MemoryBuffer, CString)> + where + 'input: 'a, + { + unsafe { + let mut main_bcs = Vec::new(); + let mut bitcode_mods = Vec::new(); + for (idx, mod_) in mods.enumerate() { + let main_bc = llvm::MemoryBuffer::from_ffi(LLVMWriteBitcodeToMemoryBuffer( + mod_.llvm_module.get(), + )); + main_bcs.push(( + main_bc, + CString::from_vec_unchecked(format!("main_{}\0", idx).into_bytes()), + )); + for (sub_idx, bitcode) in mod_.bitcode_modules.iter().enumerate() { + bitcode_mods.push(( + llvm::MemoryBuffer::create_no_copy(bitcode, false), + CString::from_vec_unchecked( + format!("ptx_impl_{}_{}\0", idx, sub_idx).into_bytes(), + ), + )); + } + } + main_bcs.extend(bitcode_mods); + main_bcs + } + } +} + +pub struct Metadata<'input> { + sm_version: u32, + kernel_metadata: Vec<(Cow<'input, str>, Option, Option)>, +} + +impl<'input> Metadata<'input> { + pub fn empty() -> Self { + Self { + sm_version: 0, + kernel_metadata: Vec::new(), + } + } + + pub fn join(self, other: &Self) -> Self { + let sm_version = self.sm_version.max(other.sm_version); + let mut kernel_metadata = self.kernel_metadata; + kernel_metadata.extend(other.kernel_metadata.iter().cloned()); + Self { + sm_version, + kernel_metadata, + } + } + + pub fn to_elf_section(&self) -> Vec { + let mut result = Vec::new(); + let metadata = kernel_metadata::zluda::write( + self.sm_version, + self.kernel_metadata + .iter() + .map(|(name, min, max)| (&**name, *min, *max)), + ); + emit::emit_section( + hip_common::kernel_metadata::zluda::SECTION_STR, + &metadata, + &mut result, + ); + result + } +} + +pub(crate) struct TranslationModule<'input, P: ast::ArgParams> { + pub(crate) sm_version: u32, + pub(crate) compilation_mode: CompilationMode, + pub(crate) id_defs: IdNameMapBuilder<'input>, + pub(crate) ptx_impl_imports: BTreeMap>>>, + pub(crate) directives: Vec>, +} + +impl<'input, P: ast::ArgParams> TranslationModule<'input, P> { + fn new(compilation_mode: CompilationMode) -> Self { + let id_defs = IdNameMapBuilder::new(IdGenerator::new()); + let ptx_impl_imports = BTreeMap::new(); + let directives = Vec::new(); + Self { + compilation_mode, + sm_version: 0, + id_defs, + ptx_impl_imports, + directives, + } + } +} + +// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#system-calls +// There is a bunch of functions like __assertfail and vprintf that must be +// replaced by imports from ZLUDA PTX implementation library +fn extract_builtin_functions<'input>( + mut module: TranslationModule<'input, NormalizedArgParams>, +) -> TranslationModule<'input, NormalizedArgParams> { + for directive in module.directives.iter_mut() { + if let TranslationDirective::Method(TranslationMethod { + source_name: Some(name), + body: None, + is_kernel: false, + .. + }) = directive + { + if is_builtin_function_name(&*name) { + *name = Cow::Owned([ZLUDA_PTX_PREFIX, name].concat()); + } + } + } + module +} + +fn is_builtin_function_name(name: &str) -> bool { + match name { + "__assertfail" | "malloc" | "free" | "vprintf" => true, + _ => false, + } +} + +// PTX linking rules are fairly convoluted. Here's my understanding: +// * For normal data (.global, .const) and non-kernel functions (.func) +// * Symbol occurences must be equivalent under following rules: +// * For data, symbol occurences must be of the same size. Alignment is ignored +// * For functions, symbol occurences are strictly type-checked. +// Number, type and alignmnt of input and return parameters must all match +// * There are 3 classes of directives: +// * Declarations. Only valid on functions +// .func foobar(); +// * Definitions (complete definitions). Either data or functions +// .func foobar() { ret; } +// .global foobar .u32; +// Both .global and .const are *always* initialized. If no explicit +// initializer is present, they are zero-initialized +// * Incomplete definitions. Data definitions using incomplete type. Only +// known incomplete type is an array with at least one zero dimension +// .extern .global foobar .b8 []; +// Incomplete definitions *must* have an .extern linking specifier +// * There can be only one definition (normal or incomplete) of a symbol +// in a module +// * There can be multiple declarations of a symbol in a module +// * Declarations must all be the same: same linking specifier, +// same argument list, same return list +// * Data (.global and .const) is alwas accessible by cuModuleGetGlobal(...), +// no matter the linking specifier. So this definition: +// .global .u32 foobar1[1] = {1} +// is not visible to othe modules during linking, but is accessible +// by CUDA runtime after linking +// * Non-kernel functions are never accessible by cuModuleGetGlobal(...) +// * There are are four linking specifiers: +// * (empty): static linking, a symbol is only visible inside a module +// * For functions; separate functions with the same name in multiple, separate modules behave as expected +// * For data, compiler selects the first symbol with the given name for access from cuModuleGetGlobal(...) +// * This is only allowed linking specifier for local globals (globals defined inside function body), +// which are not visible through cuModuleGetGlobal(...) +// * .extern: means that symbol is completely-defined strictly in another module. +// If the same symbol is completely-defined in the same module it's an error +// It's legal to not resolve the declaration if it's unused +// .extern is legal for: +// * declarations and incomplete definitions +// * normal definitions if all are true: +// * it's a data definition +// * it's a non-linking compilation +// * initializer is not present +// * .visible: symbol is strong (overrides .weak) and globally visible. +// Multiple .visible symbol occurences during linking compilation are illegal +// * .weak: symbol is weak and globally visible. +// If there's no strong symbol occurence, first weak symbol occurence gets selected +// * .common: symbol is strong (overrides .weak) and globally visible with some additional rules: +// * applies only to .global +// * selects the first occurence from the largest symbol occurences +// * explicit initializer is only allowed on symbol occurences with the largest size +fn resolve_linking<'a, 'input>( + ast_modules: &'a [ast::Module<'input>], + is_raytracing: bool, +) -> Result, TranslateError> { + let mut resolver = LinkingResolver::new(is_raytracing); + for ast_module in ast_modules { + resolver.start_module()?; + for (index, directive) in ast_module.directives.iter().enumerate() { + match directive { + ast::Directive::Variable(linking, multivar) => { + resolver.on_data( + index, + *linking, + Cow::Borrowed(multivar.variable.name), + multivar.variable.state_space, + &multivar.variable.type_, + )?; + } + ast::Directive::Method(linking, method) => { + resolver.on_function( + index, + method.body.is_some(), + *linking, + &method.func_directive, + )?; + } + } + } + } + resolver.close() +} + +struct LinkingResolver<'a, 'input> { + explicit_globals: FxHashMap, SymbolState<'a, 'input>>, + implicit_globals: FxHashMap, (usize, usize)>, + local_definitions: LocalDirectives<'a, 'input>, + module_index: usize, + is_raytracing: bool, +} + +impl<'a, 'input> LinkingResolver<'a, 'input> { + fn new(is_raytracing: bool) -> Self { + Self { + explicit_globals: FxHashMap::default(), + implicit_globals: FxHashMap::default(), + local_definitions: LocalDirectives::new(), + module_index: 0, + is_raytracing, + } + } + + fn start_module(&mut self) -> Result<(), TranslateError> { + self.module_index += 1; + mem::replace(&mut self.local_definitions, LocalDirectives::new()).check() + } + + fn on_data( &mut self, - b: &mut dr::Builder, - in_params: impl ExactSizeIterator, - mut out_params: impl ExactSizeIterator, - ) -> (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!() + location: usize, + linking: ast::LinkingDirective, + name: Cow<'input, str>, + space: ast::StateSpace, + type_: &ast::Type, + ) -> Result<(), TranslateError> { + if linking == ast::LinkingDirective::Common && space != ast::StateSpace::Global { + return Err(TranslateError::SymbolRedefinition); + } + self.local_definitions.on_data(name.clone())?; + let symbol = GlobalSymbol::Data { + size: type_.layout().size(), + space, + type_: type_.clone(), }; - ( - out_spirv_type, - self.get_or_add(b, SpirvType::Func(out_args, in_params.collect::>())), + self.update_global_symbol( + location, + linking, + name, + symbol, + space != ast::StateSpace::Shared, ) } - fn get_or_add_constant( + fn on_function( &mut self, - b: &mut dr::Builder, - typ: &ast::Type, - init: &[u8], - ) -> Result { - Ok(match typ { - ast::Type::Scalar(t) => match t { - ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => self - .get_or_add_constant_single::( - 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::( - 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::( - 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::( - 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::( - 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::( - 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::( - 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::( - 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::, _>>()?; - b.constant_composite(result_type, None, &components) + location: usize, + is_definition: bool, + linking: ast::LinkingDirective, + decl: &'a ast::MethodDeclaration<'input, &'input str>, + ) -> Result<(), TranslateError> { + // Common is legal only on .global + if linking == ast::LinkingDirective::Common { + return Err(TranslateError::SymbolRedefinition); + } + if is_definition { + self.local_definitions + .on_function_definition(linking, decl)?; + } else { + self.local_definitions + .on_function_declaration(linking, decl)?; + } + let symbol = GlobalSymbol::Method { + kernel: decl.name.is_kernel(), + declaration: !is_definition, + return_arguments: &decl.return_arguments, + input_arguments: &decl.input_arguments, + }; + self.update_global_symbol( + location, + linking, + Cow::Borrowed(decl.name()), + symbol, + decl.name.is_kernel(), + ) + } + + fn update_global_symbol( + &mut self, + new_location: usize, + new_linking: ast::LinkingDirective, + name: Cow<'input, str>, + new_symbol: GlobalSymbol<'a, 'input>, + implicit_global: bool, + ) -> Result<(), TranslateError> { + if new_linking == ast::LinkingDirective::None { + if implicit_global { + let will_be_shadowed = if let Some(global) = self.explicit_globals.get(&name) { + match global.symbol { + GlobalSymbol::Data { .. } + | GlobalSymbol::Method { + declaration: false, .. + } => true, + GlobalSymbol::Method { + declaration: true, .. + } => false, + } + } else { + false + }; + if !will_be_shadowed { + if let hash_map::Entry::Vacant(entry) = self.implicit_globals.entry(name) { + entry.insert((self.module_index, new_location)); + } + } } - 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::, _>>()?; - b.constant_composite(result_type, None, &components) + return Ok(()); + } + let is_function_declaration = matches!( + new_symbol, + GlobalSymbol::Method { + declaration: true, + .. + } + ); + if !is_function_declaration { + self.implicit_globals.remove(&name); + } + match self.explicit_globals.entry(name) { + hash_map::Entry::Occupied(mut entry) => { + let SymbolState { + module, + location, + linking, + symbol, + } = entry.get_mut(); + let override_global = match (new_linking, *linking) { + (ast::LinkingDirective::None, _) | (_, ast::LinkingDirective::None) => { + return Err(TranslateError::unreachable()) + } + (ast::LinkingDirective::Extern, _) => false, + (ast::LinkingDirective::Common, ast::LinkingDirective::Visible) + | (ast::LinkingDirective::Visible, ast::LinkingDirective::Common) => { + return Err(TranslateError::SymbolRedefinition); + } + (ast::LinkingDirective::Visible, ast::LinkingDirective::Visible) => { + // If it is in another module + if *module != self.module_index { + return Err(TranslateError::SymbolRedefinition); + } else { + !is_function_declaration + } + } + ( + ast::LinkingDirective::Visible | ast::LinkingDirective::Common, + ast::LinkingDirective::Weak | ast::LinkingDirective::Extern, + ) => true, + (ast::LinkingDirective::Common, ast::LinkingDirective::Common) => { + if let ( + GlobalSymbol::Data { + size, + space: ast::StateSpace::Global, + type_, + }, + GlobalSymbol::Data { + size: new_size, + space: ast::StateSpace::Global, + type_: new_type, + }, + ) = (symbol, new_symbol) + { + if new_size > *size { + *type_ = new_type; + *size = new_size; + *module = self.module_index; + *location = new_location; + *linking = new_linking; + } + return Ok(()); + } else { + return Err(TranslateError::SymbolRedefinition); + } + } + (ast::LinkingDirective::Weak, ast::LinkingDirective::Extern) => true, + (ast::LinkingDirective::Weak, ast::LinkingDirective::Visible) + | (ast::LinkingDirective::Weak, ast::LinkingDirective::Common) => false, + (ast::LinkingDirective::Weak, ast::LinkingDirective::Weak) => match symbol { + GlobalSymbol::Method { + declaration: true, .. + } => { + if let GlobalSymbol::Method { + declaration: false, .. + } = new_symbol + { + true + } else { + false + } + } + _ => false, + }, + }; + if !new_symbol.is_compatible(symbol) { + return Err(TranslateError::SymbolRedefinition); } - [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::, _>>()?; - b.constant_composite(result_type, None, &components) + if override_global { + *symbol = new_symbol; + *module = self.module_index; + *location = new_location; + *linking = new_linking; + } + } + hash_map::Entry::Vacant(entry) => { + entry.insert(SymbolState { + module: self.module_index, + location: new_location, + linking: new_linking, + symbol: new_symbol, + }); + } + } + Ok(()) + } + + fn close(self) -> Result, TranslateError> { + self.local_definitions.check()?; + for (_, state) in self.explicit_globals.iter() { + if state.linking == ast::LinkingDirective::Extern { + match state.symbol { + GlobalSymbol::Data { + space: ast::StateSpace::Shared, + .. + } + | GlobalSymbol::Method { .. } => {} + GlobalSymbol::Data { size, .. } if size != 0 && self.module_index == 1 => {} + _ => return Err(TranslateError::SymbolRedefinition), + } + } else if !self.is_raytracing { + if matches!( + state.symbol, + GlobalSymbol::Method { + declaration: true, + .. + } + ) { + return Err(TranslateError::SymbolRedefinition); + } + } + } + let explicit_globals = self + .explicit_globals + .into_iter() + .map(|(name, symbol)| { + let type_ = match symbol.symbol { + GlobalSymbol::Data { type_, .. } => Some(type_), + GlobalSymbol::Method { .. } => None, + }; + (name, (symbol.module, symbol.location, type_)) + }) + .collect(); + Ok(ResolvedLinking { + explicit_globals, + implicit_globals: self.implicit_globals, + }) + } +} + +struct ResolvedLinking<'input> { + explicit_globals: FxHashMap, (usize, usize, Option)>, + implicit_globals: FxHashMap, (usize, usize)>, +} + +impl<'input> ResolvedLinking<'input> { + fn get_adjustment( + &mut self, + module: usize, + directive: usize, + name: Cow<'input, str>, + linking: ast::LinkingDirective, + explicit_initializer: bool, + ) -> Result { + if linking == ast::LinkingDirective::None { + if self.implicit_globals.get(&name).copied() == Some((module, directive)) { + Ok(VisibilityAdjustment::Global) + } else { + Ok(VisibilityAdjustment::Module) + } + } else { + if let Some((global_module, global_directive, type_)) = self.explicit_globals.get(&name) + { + if module == *global_module && directive == *global_directive { + Ok(VisibilityAdjustment::Global) + } else { + match linking { + ast::LinkingDirective::Extern + | ast::LinkingDirective::Weak + // Visible is possible and valid in case of function same-module declarations + | ast::LinkingDirective::Visible => { + Ok(VisibilityAdjustment::GlobalDeclaration(type_.clone())) + } + ast::LinkingDirective::Common => { + if explicit_initializer { + return Err(TranslateError::SymbolRedefinition); + } + Ok(VisibilityAdjustment::GlobalDeclaration(type_.clone())) + } + ast::LinkingDirective::None => { + Err(TranslateError::unreachable()) + } + } + } + } else { + Err(TranslateError::unreachable()) + } + } + } +} + +enum VisibilityAdjustment { + Global, + Module, + GlobalDeclaration(Option), +} + +struct LocalDirectives<'a, 'input> { + directives: FxHashMap, LocalSymbol<'a, 'input>>, +} + +impl<'a, 'input> LocalDirectives<'a, 'input> { + fn new() -> Self { + Self { + directives: FxHashMap::default(), + } + } + + fn on_data(&mut self, name: Cow<'input, str>) -> Result<(), TranslateError> { + match self.directives.entry(name) { + hash_map::Entry::Occupied(_) => return Err(TranslateError::SymbolRedefinition), + hash_map::Entry::Vacant(entry) => { + entry.insert(LocalSymbol::Data); + } + } + Ok(()) + } + + fn on_function_definition( + &mut self, + decl_linking: ast::LinkingDirective, + decl: &'a ast::MethodDeclaration<'input, &'input str>, + ) -> Result<(), TranslateError> { + match self.directives.entry(Cow::Borrowed(decl.name())) { + hash_map::Entry::Occupied(mut entry) => match entry.get_mut() { + LocalSymbol::Data + | LocalSymbol::Function { + has_definition: true, + .. + } => return Err(TranslateError::SymbolRedefinition), + LocalSymbol::Function { + kernel, + ref mut has_definition, + return_arguments, + input_arguments, + linking, + } => { + if *kernel == decl.name.is_kernel() && decl_linking != *linking + || !is_variable_list_equivalent(&*decl.return_arguments, return_arguments) + || !is_variable_list_equivalent(&*decl.input_arguments, *input_arguments) + { + return Err(TranslateError::SymbolRedefinition); + } + *has_definition = true; } }, - 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(), + hash_map::Entry::Vacant(entry) => { + entry.insert(LocalSymbol::Function { + kernel: decl.name.is_kernel(), + has_definition: true, + linking: decl_linking, + return_arguments: &decl.return_arguments, + input_arguments: &decl.input_arguments, + }); + } + } + Ok(()) + } + + fn on_function_declaration( + &mut self, + decl_linking: ast::LinkingDirective, + decl: &'a ast::MethodDeclaration<'input, &'input str>, + ) -> Result<(), TranslateError> { + match self.directives.entry(Cow::Borrowed(decl.name())) { + hash_map::Entry::Occupied(entry) => match entry.get() { + LocalSymbol::Data => return Err(TranslateError::SymbolRedefinition), + LocalSymbol::Function { + kernel, + has_definition: _, + linking, + return_arguments, + input_arguments, + } => { + if *kernel == decl.name.is_kernel() && *linking != decl_linking + || !is_variable_list_equivalent(&*decl.return_arguments, return_arguments) + || !is_variable_list_equivalent(&*decl.input_arguments, *input_arguments) + { + return Err(TranslateError::SymbolRedefinition); + } + } + }, + hash_map::Entry::Vacant(entry) => { + entry.insert(LocalSymbol::Function { + kernel: decl.name.is_kernel(), + has_definition: false, + linking: decl_linking, + return_arguments: &decl.return_arguments, + input_arguments: &decl.input_arguments, + }); + } + } + Ok(()) + } + + // At a first glance this looks incomplete, but: + // * Unresolved declarations at the global level are checked later, + // when we have symbols from all the modules + // * We don't check unresolved data with incomplete definitions, because + // they are invalid anyway, if data is incomplete it must be extern + // and hence checked at the global level + fn check(self) -> Result<(), TranslateError> { + for (_, symbol) in self.directives { + match symbol { + LocalSymbol::Data => {} + LocalSymbol::Function { + has_definition, + linking, + .. + } => { + if linking == ast::LinkingDirective::None && !has_definition { + return Err(TranslateError::SymbolRedefinition); + } + } + } + } + Ok(()) + } +} + +// Used to type-check declarations inside a module +enum LocalSymbol<'a, 'input> { + Data, + Function { + kernel: bool, + has_definition: bool, + linking: ast::LinkingDirective, + return_arguments: &'a [ast::VariableDeclaration<&'input str>], + input_arguments: &'a [ast::VariableDeclaration<&'input str>], + }, +} + +struct SymbolState<'a, 'input> { + module: usize, + location: usize, + linking: ast::LinkingDirective, + symbol: GlobalSymbol<'a, 'input>, +} + +enum GlobalSymbol<'a, 'input> { + Data { + size: usize, + space: ast::StateSpace, + type_: ast::Type, + }, + Method { + kernel: bool, + declaration: bool, + return_arguments: &'a [ast::VariableDeclaration<&'input str>], + input_arguments: &'a [ast::VariableDeclaration<&'input str>], + }, +} + +impl<'a, 'input> GlobalSymbol<'a, 'input> { + fn is_compatible(&self, old_symbol: &GlobalSymbol<'a, 'input>) -> bool { + match (self, old_symbol) { + ( + GlobalSymbol::Data { + size, + space, + type_: _, + }, + GlobalSymbol::Data { + size: old_size, + space: old_space, + type_: _, + }, + ) => (*size == *old_size || *old_size == 0 || *size == 0) && (space == old_space), + ( + GlobalSymbol::Method { + kernel, + declaration: _, + return_arguments, + input_arguments, + }, + GlobalSymbol::Method { + kernel: old_kernel, + declaration: _, + return_arguments: old_return_arguments, + input_arguments: old_input_arguments, + }, + ) => { + *kernel == *old_kernel + && is_variable_list_equivalent(return_arguments, old_return_arguments) + && is_variable_list_equivalent(input_arguments, old_input_arguments) + } + _ => false, + } + } +} + +fn is_variable_list_equivalent<'a>( + left: &[ast::VariableDeclaration<&'a str>], + right: &[ast::VariableDeclaration<&'a str>], +) -> bool { + fn equivalent_arguments<'a>( + ast::VariableDeclaration { + type_: l_type_, + state_space: l_state_space, + align: _, + name: _, + }: &ast::VariableDeclaration<&'a str>, + ast::VariableDeclaration { + type_: r_type_, + state_space: r_state_space, + align: _, + name: _, + }: &ast::VariableDeclaration<&'a str>, + ) -> bool { + l_type_ == r_type_ && l_state_space == r_state_space + } + let mut left = left.iter(); + let mut right = right.iter(); + loop { + match (left.next(), right.next()) { + (None, None) => break, + (None, Some(_)) => return false, + (Some(_), None) => return false, + (Some(left), Some(right)) => { + if !equivalent_arguments(left, right) { + return false; + } + } + } + } + true +} + +// This is actually three transformations in one: +// * Merge modules (linking-aware) +// * Replace all string identifiers with numeric identifiers +// * Convert predicates to branches +// After those two conversions we can start inserting and removing additional +// instructions freely +fn link_and_normalize_modules<'input>( + asts: Vec>, + module: TranslationModule<'input, NormalizedArgParams>, + mut linking_resolver: ResolvedLinking<'input>, +) -> Result< + ( + TranslationModule<'input, NormalizedArgParams>, + FxHashMap< + Id, + ( + Vec>, + Vec>, + ), + >, + ), + TranslateError, +> { + let mut functions = get_existing_methods(&*module.directives); + let mut id_defs = module.id_defs; + let ptx_impl_imports = module.ptx_impl_imports; + let mut directives = module.directives; + let mut sm_version = 0; + let mut string_resolver = StringIdResolver::new(&mut id_defs, &directives)?; + for (mut module_index, ast) in asts.into_iter().enumerate() { + module_index += 1; + sm_version = sm_version.max(ast.sm_version); + let mut module_scope = string_resolver.start_module(); + for (directive_index, directive) in ast.directives.into_iter().enumerate() { + match directive { + ast::Directive::Method(linking_directive, method) => { + directives.push(TranslationDirective::Method(normalize_method( + &mut linking_resolver, + &mut functions, + (module_index, directive_index), + &mut module_scope, + linking_directive, + method, + )?)); + } + ast::Directive::Variable(mut linking_directive, vars) => { + expand_multivariable2( + &mut module_scope, + iter::once(vars), + |scope, align, type_, space, name, mut initializer| { + let linking_adjustment = linking_resolver.get_adjustment( + module_index, + directive_index, + name.clone(), + linking_directive, + initializer.is_some(), + )?; + let (has_global_name, has_body, type_override) = + match linking_adjustment { + VisibilityAdjustment::Global => (true, true, None), + VisibilityAdjustment::Module => (false, true, None), + VisibilityAdjustment::GlobalDeclaration(type_override) => { + (true, false, type_override) + } + }; + let type_ = type_override.unwrap_or_else(|| type_.clone()); + let compiled_name = if has_global_name { + Some(name.clone()) + } else { + None + }; + if !has_body { + linking_directive = ast::LinkingDirective::Extern; + initializer = None; + } + directives.push(TranslationDirective::Variable( + linking_directive, + compiled_name, + scope.add_or_get_module_variable( + name, + has_global_name, + type_, + space, + align, + initializer, + )?, + )); + Ok(()) + }, + )?; + } + } + } + } + Ok(( + TranslationModule { + compilation_mode: module.compilation_mode, + sm_version, + id_defs, + ptx_impl_imports, + directives, + }, + functions, + )) +} + +fn get_existing_methods<'input, P: ast::ArgParams>( + directives: &[TranslationDirective<'input, P>], +) -> FxHashMap< + Id, + ( + Vec>, + Vec>, + ), +> { + let mut result = FxHashMap::default(); + for directive in directives { + match directive { + TranslationDirective::Variable(..) => continue, + TranslationDirective::Method(method) => { + result.insert( + method.name, + ( + method.return_arguments.clone(), + method.input_arguments.clone(), ), ); - 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, - pub should_link_ptx_impl: Option<&'static [u8]>, - pub build_options: CString, -} -impl Module { - pub fn assemble(&self) -> Vec { - self.spirv.assemble() - } -} - -pub struct KernelInfo { - pub arguments_sizes: Vec, - pub uses_shared_mem: bool, -} - -pub fn to_spirv_module<'a>(ast: ast::Module<'a>) -> Result { - 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::, _>>()?; - 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::>(); - 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>, - denorm_information: &HashMap>, -) -> CString { - let denorm_counts = denorm_information - .iter() - .map(|(method, meth_denorm)| { - let f16_count = meth_denorm - .get(&(mem::size_of::() as u8)) - .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0)) - .1; - let f32_count = meth_denorm - .get(&(mem::size_of::() as u8)) - .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0)) - .1; - (method, (f16_count + f32_count)) - }) - .collect::>(); - 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, HashMap>, - call_map: &HashMap<&'input str, HashSet>, - directives: Vec, - kernel_info: &mut HashMap, -) -> 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> { - 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, spirv::Word>, - visited: &mut HashSet, - 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); +fn normalize_method<'a, 'b, 'input>( + linking_resolver: &mut ResolvedLinking<'input>, + function_decls: &mut FxHashMap< + Id, + ( + Vec>, + Vec>, + ), + >, + (module, directive): (usize, usize), + module_scope: &mut StringIdResolverScope<'a, 'b, 'input>, + linking_directive: ast::LinkingDirective, + method: ast::Function<'input, &'input str, ast::Statement>>, +) -> Result, TranslateError> { + let is_kernel = method.func_directive.name.is_kernel(); + let linking_adjustment = linking_resolver.get_adjustment( + module, + directive, + Cow::Borrowed(method.func_directive.name()), + linking_directive, + false, + )?; + let (has_global_name, has_body) = match linking_adjustment { + VisibilityAdjustment::Global => (true, true), + VisibilityAdjustment::Module => (false, true), + VisibilityAdjustment::GlobalDeclaration(_) => (true, false), + }; + let name = + module_scope.add_or_get_at_module_level(method.func_directive.name(), has_global_name)?; + let mut fn_scope = module_scope.start_scope(); + let return_arguments = + normalize_method_params(&mut fn_scope, &*method.func_directive.return_arguments)?; + let input_arguments = + normalize_method_params(&mut fn_scope, &*method.func_directive.input_arguments)?; + if !is_kernel { + if let hash_map::Entry::Vacant(entry) = function_decls.entry(name) { + entry.insert((return_arguments.clone(), input_arguments.clone())); } } + let source_name = if has_global_name { + Some(Cow::Borrowed(method.func_directive.name())) + } else { + None + }; + let body = if has_body { + method + .body + .map(|body| { + let body = normalize_identifiers2(&mut fn_scope, body)?; + normalize_predicates2(&mut fn_scope, body) + }) + .transpose()? + } else { + None + }; + Ok(TranslationMethod { + return_arguments, + name, + input_arguments, + body, + tuning: method.tuning, + is_kernel, + source_name, + special_raytracing_linking: false, + }) } -type MultiHashMap = HashMap>; - -fn multi_hash_map_append(m: &mut MultiHashMap, 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>, - new_id: &mut impl FnMut() -> spirv::Word, -) -> Vec> { - 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::>(); - // 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::>() -} - -fn replace_uses_of_shared_memory<'a>( - result: &mut Vec, - new_id: &mut impl FnMut() -> spirv::Word, - extern_shared_decls: &HashMap, - methods_using_extern_shared: &mut HashSet>, - shared_id_param: spirv::Word, - shared_var_id: spirv::Word, - statements: Vec, -) { - 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>, - directly_called_by: &MultiHashMap>, -) { - 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::>(); - 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>, - directly_called_by: &MultiHashMap>, - 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 = HashMap; - -fn denorm_count_map_update(map: &mut DenormCountMap, 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( - map: &mut DenormCountMap, - 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, HashMap> { - 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) +fn normalize_method_params<'a, 'b, 'input>( + fn_scope: &mut StringIdResolverScope<'a, 'b, 'input>, + args: &[ast::VariableDeclaration<&'input str>], +) -> Result>, TranslateError> { + args.iter() + .map(|a| { + Ok(ast::VariableDeclaration { + name: fn_scope.add_variable_checked( + a.name, + a.type_.clone(), + a.state_space, + a.align, + )?, + type_: a.type_.clone(), + state_space: a.state_space, + align: a.align, + }) }) .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 normalize_identifiers2<'a, 'b, 'input>( + scope: &mut StringIdResolverScope<'a, 'b, 'input>, + func: Vec>>, +) -> Result, TranslateError> { + gather_labels_in_scope(scope, &func)?; + let mut result = Vec::with_capacity(func.len()); + for statement in func { + match statement { + ast::Statement::Block(block) => { + let mut scope = scope.start_scope(); + result.extend(normalize_identifiers2(&mut scope, block)?); + } + ast::Statement::Label(name) => { + result.push(Statement::Label(scope.get_id_in_function_scopes(name)?)) + } + ast::Statement::Instruction(p, i) => result.push(Statement::Instruction(( + p.map(|p| p.map_variable(&mut |id| scope.get_id_in_module_scopes(id))) + .transpose()?, + i.map_variable(&mut |id| scope.get_id_in_module_scopes(id))?, + ))), + ast::Statement::Variable(vars) => { + expand_multivariable2( + scope, + vars.into_iter(), + |scope, align, type_, space, name, initializer| { + result.push(Statement::Variable(scope.register_variable( + name, + type_.clone(), + space, + align, + initializer, + )?)); + Ok(()) + }, + )?; + } + ast::Statement::Callprototype(proto) => { + let name = scope.add_untyped_checked(proto.name)?; + scope.0.module.globals.function_prototypes.insert( + name, + Callprototype { + return_arguments: proto.return_arguments, + input_arguments: proto.input_arguments, + }, + ); + } } } + Ok(result) } -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], - func_decl: &SpirvMethodDecl<'a>, - _denorm_information: &HashMap, HashMap>, - call_map: &HashMap<&'a str, HashSet>, - direcitves: &[Directive], - kernel_info: &mut HashMap, +fn expand_multivariable2<'a, 'b, 'input>( + scope: &mut StringIdResolverScope<'a, 'b, 'input>, + vars: impl Iterator>, + mut inserter: impl FnMut( + &mut StringIdResolverScope<'a, 'b, 'input>, + Option, + &ast::Type, + ast::StateSpace, + Cow<'input, str>, + Option>, + ) -> Result<(), TranslateError>, ) -> 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::>(); - 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); - } - } - } - _ => {} + for var in vars { + let initializer = match var.suffix { + Some(ast::DeclarationSuffix::Count(count)) => { + for offset in 0..count { + let name = Cow::Owned(format!("{}{}", var.variable.name, offset)); + inserter( + scope, + var.variable.align, + &var.variable.type_, + var.variable.state_space, + name, + None, + )?; } + return Ok(()); } - 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); + Some(ast::DeclarationSuffix::Initializer(init)) => { + Some(expand_initializer2(scope, init)?) + } + None => None, + }; + let name = Cow::Borrowed(var.variable.name); + inserter( + scope, + var.variable.align, + &var.variable.type_, + var.variable.state_space, + name, + initializer, + )?; } 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>, - d: ast::Directive<'input, ast::ParsedArgParams<'input>>, -) -> Result>, 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 expand_initializer2<'a, 'b, 'input>( + scope: &mut StringIdResolverScope<'a, 'b, 'input>, + init: ast::Initializer<&'input str>, +) -> Result, TranslateError> { + Ok(match init { + ast::Initializer::Constant(c) => ast::Initializer::Constant(c), + ast::Initializer::Global(g, type_) => { + ast::Initializer::Global(scope.get_id_in_module_scope(g)?, type_) } + ast::Initializer::GenericGlobal(g, type_) => { + ast::Initializer::GenericGlobal(scope.get_id_in_module_scope(g)?, type_) + } + ast::Initializer::Add(add) => { + let (init1, init2) = *add; + ast::Initializer::Add(Box::new(( + expand_initializer2(scope, init1)?, + expand_initializer2(scope, init2)?, + ))) + } + ast::Initializer::Array(array) => ast::Initializer::Array( + array + .into_iter() + .map(|init| expand_initializer2(scope, init)) + .collect::, _>>()?, + ), }) } -fn translate_variable<'a>( - id_defs: &mut GlobalStringIdResolver<'a>, - var: ast::Variable, -) -> Result, 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>, - f: ast::ParsedFunction<'a>, -) -> Result>, 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>, -) -> Result>, 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::>() -} - -fn expand_fn_params<'a, 'b>( - fn_resolver: &mut FnStringIdResolver<'a, 'b>, - args: impl Iterator>, -) -> Result>, 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, - mut id_defs: FnStringIdResolver<'input, 'b>, - fn_defs: GlobalFnDeclResolver<'input, 'b>, - f_args: ast::MethodDecl<'input, spirv::Word>, - f_body: Option>>>, -) -> Result, 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, - numeric_id_defs: &mut NumericIdResolver, -) -> Result, 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, - ptx_impl_imports: &mut HashMap, - id_def: &mut NumericIdResolver, -) -> ( - Vec, - Vec>, -) { - 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) { - 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, - fn_defs: &GlobalFnDeclResolver, - id_defs: &mut NumericIdResolver, -) -> Result, TranslateError> { - let mut result = Vec::::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, - id_def: &'b mut NumericIdResolver<'a>, - post_stmts: Option, -} - -impl<'a, 'b> VectorRepackVisitor<'a, 'b> { - fn new(func: &'b mut Vec, 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, - ) -> Result { - // 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 - for VectorRepackVisitor<'a, 'b> -{ - fn id( - &mut self, - desc: ArgumentDescriptor, - _: Option<&ast::Type>, - ) -> Result { - Ok(desc.op) - } - - fn operand( - &mut self, - desc: ArgumentDescriptor>, - typ: &ast::Type, - ) -> Result { - 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, - details: ast::AtomDetails, - arg: ast::Arg3, - 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::( - 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, - typ: ast::IntType, - arg: ast::Arg4, -) -> 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::( - 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( - params: Vec, - params_decl: &[ast::FnArgumentType], -) -> Vec<(T, ast::FnArgumentType)> { - params - .into_iter() - .zip(params_decl.iter()) - .map(|(id, typ)| (id, typ.clone())) - .collect::>() -} - -fn normalize_labels( - func: Vec, - id_def: &mut NumericIdResolver, -) -> Vec { - 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::>() -} - -fn normalize_predicates( +fn normalize_predicates2<'a, 'b, 'input>( + scope: &mut StringIdResolverScope<'a, 'b, 'input>, func: Vec, - id_def: &mut NumericIdResolver, ) -> Result, TranslateError> { let mut result = Vec::with_capacity(func.len()); for s in func { @@ -1901,8 +1220,8 @@ fn normalize_predicates( 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 if_true = scope.new_untyped(); + let if_false = scope.new_untyped(); let folded_bra = match &inst { ast::Instruction::Bra(_, arg) => Some(arg.src), _ => None, @@ -1927,99 +1246,982 @@ fn normalize_predicates( } Statement::Variable(var) => result.push(Statement::Variable(var)), // Blocks are flattened when resolving ids - _ => return Err(error_unreachable()), + _ => return Err(TranslateError::unreachable()), } } Ok(result) } -fn insert_mem_ssa_statements<'a, 'b>( - func: Vec, - id_def: &mut NumericIdResolver, - ast_fn_decl: &'a ast::MethodDecl<'b, spirv::Word>, - fn_decl: &mut SpirvMethodDecl, +// Instructions can reference labels that are declared later on so +// we gather ids of labels ahead of time +fn gather_labels_in_scope<'a, 'b, 'input>( + scope: &mut StringIdResolverScope<'a, 'b, 'input>, + func: &[ast::Statement>], +) -> Result<(), TranslateError> { + for s in func.iter() { + // Instructions can reference labels that are declared later so + // we gather ids of labels ahead of time + if let ast::Statement::Label(id) = s { + scope.add_untyped_checked(*id)?; + } + } + Ok(()) +} + +fn resolve_instruction_types<'input>( + mut module: TranslationModule<'input, NormalizedArgParams>, + function_decls: FxHashMap< + Id, + ( + Vec>, + Vec>, + ), + >, +) -> Result, TranslateError> { + let id_defs = &mut module.id_defs; + let directives = module + .directives + .into_iter() + .map(|directive| { + Ok(match directive { + TranslationDirective::Variable(linking, compiled_name, var) => { + TranslationDirective::Variable( + linking, + compiled_name, + resolve_initializers(id_defs, var)?, + ) + } + TranslationDirective::Method(method) => { + let body = match method.body { + Some(body) => Some(resolve_instruction_types_method( + id_defs, + &function_decls, + body, + )?), + None => None, + }; + TranslationDirective::Method(TranslationMethod { + return_arguments: method.return_arguments, + name: method.name, + input_arguments: method.input_arguments, + body, + tuning: method.tuning, + is_kernel: method.is_kernel, + source_name: method.source_name, + special_raytracing_linking: method.special_raytracing_linking, + }) + } + }) + }) + .collect::, _>>()?; + Ok(TranslationModule { + compilation_mode: module.compilation_mode, + sm_version: module.sm_version, + directives, + id_defs: module.id_defs, + ptx_impl_imports: module.ptx_impl_imports, + }) +} + +fn resolve_instruction_types_method<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + function_decls: &FxHashMap< + Id, + ( + Vec>, + Vec>, + ), + >, + fn_body: Vec, ) -> Result, 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, + let mut result = Vec::::with_capacity(fn_body.len()); + let mut constants = KernelConstantsVisitor::new(); + for statement in fn_body { + match statement { + Statement::Instruction(inst) => match inst { + // TODO: Replace this with proper constant propagation + ast::Instruction::PrmtSlow { control, arg } => { + let inst = if let Some(control) = constants.try_get_constant(control) { + ast::Instruction::Prmt { control, arg } + } else { + ast::Instruction::PrmtSlow { control, arg } + }; + let mut visitor = + VectorRepackVisitor::new(&mut constants, &mut result, id_defs); + let reresolved_call = inst.visit(&mut visitor)?; + visitor.func.push(reresolved_call); + visitor.func.extend(visitor.post_stmts); + } + ast::Instruction::Sust(mut details, args) => { + if let ast::Operand::Reg(image) = args.image { + let (image_type, _, _, _) = id_defs.get_typed(image)?; + if matches!(image_type, ast::Type::Surfref) { + details.direct = true; + } + } + let mut visitor = + VectorRepackVisitor::new(&mut constants, &mut result, id_defs); + let reresolved_call = + ast::Instruction::Sust(details, args).visit(&mut visitor)?; + visitor.func.push(reresolved_call); + visitor.func.extend(visitor.post_stmts); + } + ast::Instruction::Suld(mut details, args) => { + if let ast::Operand::Reg(image) = args.image { + let (image_type, _, _, _) = id_defs.get_typed(image)?; + if matches!(image_type, ast::Type::Surfref) { + details.direct = true; + } + } + let mut visitor = + VectorRepackVisitor::new(&mut constants, &mut result, id_defs); + let reresolved_call = + ast::Instruction::Suld(details, args).visit(&mut visitor)?; + visitor.func.push(reresolved_call); + visitor.func.extend(visitor.post_stmts); + } + ast::Instruction::Tex(mut details, args) => { + if let ast::Operand::Reg(image) = args.image { + let (image_type, _, _, _) = id_defs.get_typed(image)?; + if matches!(image_type, ast::Type::Texref) { + details.direct = true; + } + } + let mut visitor = + VectorRepackVisitor::new(&mut constants, &mut result, id_defs); + let reresolved_call = + ast::Instruction::Tex(details, args).visit(&mut visitor)?; + visitor.func.push(reresolved_call); + visitor.func.extend(visitor.post_stmts); + } + ast::Instruction::Mov( + mov, + ast::Arg2Mov { + dst: ast::Operand::Reg(dst_reg), + src: ast::Operand::Reg(src_reg), }, - typ, - member_index: None, - })); - spirv_arg.name = new_id; + ) if function_decls.contains_key(&src_reg) => { + if mov.typ != ast::Type::Scalar(ast::ScalarType::U64) { + return Err(TranslateError::mismatched_type()); + } + result.push(TypedStatement::FunctionPointer(FunctionPointerDetails { + dst: dst_reg, + src: src_reg, + })); + } + ast::Instruction::Mov( + ast::MovDetails { + typ: ast::Type::Scalar(type_), + .. + }, + ast::Arg2Mov { + dst: ast::Operand::Reg(dst_reg), + src: ast::Operand::Imm(src), + }, + ) if type_.size_of() >= 2 && type_.is_integer() => { + constants.insert( + dst_reg, + Some(src.as_u16().ok_or_else(TranslateError::unreachable)?), + )?; + let mut noop_visitor = PassthroughVisitor; + let mut visitor = + VectorRepackVisitor::new(&mut noop_visitor, &mut result, id_defs); + let instruction = Statement::Instruction(inst.map(&mut visitor)?); + visitor.func.push(instruction); + visitor.func.extend(visitor.post_stmts); + } + ast::Instruction::Call(call) => { + let resolved_call = match function_decls.get(&call.func) { + Some((return_args, input_args)) => { + ResolvedCall::from_declaration(call, return_args, input_args)? + } + None => { + let callproto_name = + call.prototype.ok_or_else(TranslateError::unreachable)?; + let callproto = id_defs + .globals + .function_prototypes + .get(&callproto_name) + .ok_or_else(TranslateError::unreachable)?; + ResolvedCall::from_callprototype(call, callproto)? + } + }; + let mut visitor = + VectorRepackVisitor::new(&mut constants, &mut result, id_defs); + let reresolved_call = resolved_call.visit(&mut visitor)?; + visitor.func.push(reresolved_call); + visitor.func.extend(visitor.post_stmts); + } + inst => { + let mut visitor = + VectorRepackVisitor::new(&mut constants, &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(resolve_initializers(id_defs, v)?)) } - None => {} + Statement::Conditional(c) => result.push(Statement::Conditional(c)), + _ => return Err(TranslateError::unreachable()), } } - for s in func { + Ok(result) +} + +fn resolve_initializers<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + mut v: Variable, +) -> Result { + fn resolve_initializer_impl<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + init: &mut ast::Initializer, + ) -> Result<(), TranslateError> { + match init { + ast::Initializer::Constant(_) => {} + ast::Initializer::Global(name, type_) + | ast::Initializer::GenericGlobal(name, type_) => { + let (src_type, _, _, _) = id_defs.get_typed(*name)?; + *type_ = src_type; + } + ast::Initializer::Add(subinit) => { + resolve_initializer_impl(id_defs, &mut (*subinit).0)?; + resolve_initializer_impl(id_defs, &mut (*subinit).1)?; + } + ast::Initializer::Array(inits) => { + for init in inits.iter_mut() { + resolve_initializer_impl(id_defs, init)?; + } + } + } + Ok(()) + } + if let Some(ref mut init) = v.initializer { + resolve_initializer_impl(id_defs, init)?; + } + Ok(v) +} + +// TODO: All this garbage should be replaced with proper constant propagation or +// at least ability to visit statements without moving them +struct KernelConstantsVisitor { + constant_candidates: FxHashMap, +} + +struct ConstantCandidate { + value: u16, + used: bool, + not_const: bool, +} + +impl KernelConstantsVisitor { + fn new() -> Self { + Self { + constant_candidates: FxHashMap::default(), + } + } + + fn insert(&mut self, id: Id, value: Option) -> Result<(), TranslateError> { + match self.constant_candidates.entry(id) { + hash_map::Entry::Occupied(mut entry) => { + let candidate = entry.get_mut(); + if candidate.used { + return Err(TranslateError::unexpected_pattern()); + } + candidate.not_const = true; + } + hash_map::Entry::Vacant(entry) => { + entry.insert(ConstantCandidate { + value: value.unwrap_or(u16::MAX), + used: false, + not_const: value.is_none(), + }); + } + } + Ok(()) + } + + fn try_get_constant(&mut self, id: Id) -> Option { + self.constant_candidates.get_mut(&id).and_then(|candidate| { + if candidate.not_const { + return None; + } + candidate.used = true; + Some(candidate.value) + }) + } +} + +impl ArgumentMapVisitor for KernelConstantsVisitor { + fn id( + &mut self, + desc: ArgumentDescriptor, + _: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + if desc.is_dst { + self.insert(desc.op, None)?; + } + Ok(desc.op) + } + + fn operand( + &mut self, + desc: ArgumentDescriptor, + _: &ast::Type, + _: ast::StateSpace, + ) -> Result { + if desc.is_dst { + if let TypedOperand::Reg(op) = desc.op { + self.insert(op, None)?; + } + } + Ok(desc.op) + } +} + +struct PassthroughVisitor; + +impl ArgumentMapVisitor for PassthroughVisitor { + fn id( + &mut self, + desc: ArgumentDescriptor, + _: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + Ok(desc.op) + } + + fn operand( + &mut self, + desc: ArgumentDescriptor, + _: &ast::Type, + _: ast::StateSpace, + ) -> Result { + Ok(desc.op) + } +} + +fn convert_methods<'input, From: ast::ArgParams, To: ast::ArgParams>( + mut module: TranslationModule<'input, From>, + mut mapper: impl FnMut( + CompilationMode, + &mut IdNameMapBuilder<'input>, + &mut AdditionalFunctionDeclarations, + &mut [ast::VariableDeclaration], + &mut [ast::VariableDeclaration], + bool, + Vec, From>>, + ) -> Result, To>>, TranslateError>, +) -> Result, TranslateError> { + let compilation_mode = module.compilation_mode; + let id_defs = &mut module.id_defs; + let mut additional_declarations = AdditionalFunctionDeclarations::new(); + let post_declarations_directives = module + .directives + .into_iter() + .map(|directive| { + Ok(match directive { + TranslationDirective::Method(mut method) => { + let body = match method.body { + Some(body) => Some(mapper( + compilation_mode, + id_defs, + &mut additional_declarations, + &mut method.return_arguments, + &mut method.input_arguments, + method.is_kernel, + body, + )?), + None => None, + }; + TranslationDirective::Method(TranslationMethod { + return_arguments: method.return_arguments, + name: method.name, + input_arguments: method.input_arguments, + body, + tuning: method.tuning, + is_kernel: method.is_kernel, + source_name: method.source_name, + special_raytracing_linking: method.special_raytracing_linking, + }) + } + TranslationDirective::Variable(linking, compiled_name, var) => { + TranslationDirective::Variable(linking, compiled_name, var) + } + }) + }) + .collect::, TranslateError>>()?; + let mut directives = Vec::with_capacity(post_declarations_directives.len()); + additional_declarations.flush(&mut directives); + directives.extend(post_declarations_directives); + Ok(TranslationModule { + compilation_mode: module.compilation_mode, + sm_version: module.sm_version, + directives: directives, + id_defs: module.id_defs, + ptx_impl_imports: module.ptx_impl_imports, + }) +} + +fn convert_methods_simple<'input, From: ast::ArgParams, To: ast::ArgParams>( + module: TranslationModule<'input, From>, + mut mapper: impl FnMut( + &mut IdNameMapBuilder<'input>, + Vec, From>>, + ) -> Result, To>>, TranslateError>, +) -> Result, TranslateError> { + convert_methods(module, |_, id_defs, _, _, _, _, body| mapper(id_defs, body)) +} + +// NVIDIA PTX compiler emits methods that are declared like this: +// .visible .func (.param .b8 retval[12]) foobar(.param .b64 arg1, .param .b64 arg2); +// This pass converts them to a regular form: +// .visible .func (.reg .b8 retval[12]) foobar(.reg .b64 arg1, .reg .b64 arg2); +// and does appropriate adjustments to function calls +fn deparamize_function_declarations<'input>( + mut module: TranslationModule<'input, TypedArgParams>, +) -> Result, TranslateError> { + let id_defs = &mut module.id_defs; + let mut delayed_deparamization = FxHashMap::default(); + let directives = module + .directives + .into_iter() + .map(|directive| deparamize_directive(id_defs, directive, &mut delayed_deparamization)) + .collect::, _>>()?; + Ok(TranslationModule { + directives, + ..module + }) +} + +fn deparamize_directive<'input>( + id_defs: &mut IdNameMapBuilder, + directive: TranslationDirective<'input, TypedArgParams>, + delayed_deparamization: &mut FxHashMap, +) -> Result, TranslateError> { + Ok(match directive { + var @ TranslationDirective::Variable(..) => var, + TranslationDirective::Method(mut method) => { + let deparamized_args = get_deparamized_arguments(&method, delayed_deparamization); + deparamize_function_body(id_defs, &mut method, deparamized_args)?; + TranslationDirective::Method(method) + } + }) +} + +fn get_deparamized_arguments<'a, 'input, T: ast::ArgParams>( + method: &TranslationMethod<'input, T>, + delayed_deparamization: &'a mut FxHashMap, +) -> Option<&'a (BitVec, BitVec)> { + if method.is_kernel { + return None; + } + Some( + delayed_deparamization + .entry(method.name) + .or_insert_with(|| { + let return_deparams = get_deparamize_arg_list(&method.return_arguments[..]); + let input_deparams = get_deparamize_arg_list(&method.input_arguments[..]); + (return_deparams, input_deparams) + }), + ) +} + +fn get_deparamize_arg_list(args: &[ast::VariableDeclaration]) -> BitVec { + let mut deparams = BitVec::from_elem(args.len(), false); + for (index, arg) in args.iter().enumerate() { + if arg.state_space == ast::StateSpace::Param { + deparams.set(index, true); + } + } + deparams +} + +fn deparamize_function_body<'input>( + id_defs: &mut IdNameMapBuilder, + method: &mut TranslationMethod<'input, TypedArgParams>, + deparams: Option<&(BitVec, BitVec)>, +) -> Result<(), TranslateError> { + let mut result = Vec::with_capacity(method.body.as_ref().map(|body| body.len()).unwrap_or(0)); + let has_body = method.body.is_some(); + let mut return_args_flush: hash_map::HashMap< + Id, + Id, + std::hash::BuildHasherDefault, + > = FxHashMap::default(); + if let Some((return_deparams, input_deparams)) = deparams { + for (index, return_arg) in method.return_arguments.iter_mut().enumerate() { + if !return_deparams + .get(index) + .ok_or_else(TranslateError::unreachable)? + { + continue; + } + if has_body { + let original_name = return_arg.name; + *return_arg = id_defs.register_variable_decl( + return_arg.align, + return_arg.type_.clone(), + ast::StateSpace::Reg, + ); + return_args_flush.insert(return_arg.name, original_name); + result.push(Statement::Variable(Variable { + align: return_arg.align, + type_: return_arg.type_.clone(), + state_space: ast::StateSpace::Param, + name: original_name, + initializer: None, + })); + } else { + return_arg.state_space = ast::StateSpace::Reg; + } + } + for (index, input_arg) in method.input_arguments.iter_mut().enumerate() { + if !input_deparams + .get(index) + .ok_or_else(TranslateError::unreachable)? + { + continue; + } + if has_body { + let original_name = input_arg.name; + *input_arg = id_defs.register_variable_decl( + input_arg.align, + input_arg.type_.clone(), + ast::StateSpace::Reg, + ); + result.push(Statement::Variable(Variable { + align: input_arg.align, + type_: input_arg.type_.clone(), + state_space: ast::StateSpace::Param, + name: original_name, + initializer: None, + })); + result.push(Statement::Instruction(ast::Instruction::St( + ast::StData { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Param, + caching: ast::StCacheOperator::Writeback, + typ: input_arg.type_.clone(), + }, + ast::Arg2St { + src1: TypedOperand::Reg(original_name), + src2: TypedOperand::Reg(input_arg.name), + }, + ))); + } else { + input_arg.state_space = ast::StateSpace::Reg; + } + } + } + let body = if let Some(ref mut body) = method.body { + std::mem::replace(body, Vec::new()) + } else { + return Ok(()); + }; + for statement in body { + match statement { + Statement::Instruction(ast::Instruction::Exit) => { + deparamize_instruction_ret( + deparams, + &method.return_arguments, + &return_args_flush, + &mut result, + ast::Instruction::Exit, + )?; + } + Statement::Instruction(ast::Instruction::Ret(ret)) => { + deparamize_instruction_ret( + deparams, + &method.return_arguments, + &return_args_flush, + &mut result, + ast::Instruction::Ret(ret), + )?; + } + Statement::Call(call) => { + deparamize_single_function_call(id_defs, &mut result, call)?; + } + statement => result.push(statement), + } + } + method.body = Some(result); + Ok(()) +} + +fn deparamize_instruction_ret( + deparams: Option<&(BitVec, BitVec)>, + return_arguments: &[ast::VariableDeclaration], + return_args_flush: &std::collections::HashMap< + Id, + Id, + std::hash::BuildHasherDefault, + >, + result: &mut Vec, TypedArgParams>>, + ret: ast::Instruction, +) -> Result<(), TranslateError> { + if let Some((return_deparams, _)) = deparams { + for (index, return_arg) in return_arguments.iter().enumerate() { + if !return_deparams + .get(index) + .ok_or_else(TranslateError::unreachable)? + { + continue; + } + let src = return_args_flush[&return_arg.name]; + result.push(Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Param, + caching: ast::LdCacheOperator::Cached, + typ: return_arg.type_.clone(), + non_coherent: false, + }, + ast::Arg2Ld { + dst: TypedOperand::Reg(return_arg.name), + src: TypedOperand::Reg(src), + }, + ))); + } + } + result.push(Statement::Instruction(ret)); + Ok(()) +} + +fn deparamize_single_function_call( + id_defs: &mut IdNameMapBuilder, + result: &mut Vec, + call: ResolvedCall, +) -> Result<(), TranslateError> { + let input_arguments = call + .input_arguments + .into_iter() + .map(|(operand, type_, space)| match space { + ast::StateSpace::Param => { + let arg_id = + id_defs.register_intermediate(Some((type_.clone(), ast::StateSpace::Reg))); + result.push(Statement::Instruction(ast::Instruction::Ld( + ast::LdDetails { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Param, + caching: ast::LdCacheOperator::Cached, + typ: type_.clone(), + non_coherent: false, + }, + ast::Arg2Ld { + dst: TypedOperand::Reg(arg_id), + src: operand, + }, + ))); + (TypedOperand::Reg(arg_id), type_, ast::StateSpace::Reg) + } + space => (operand, type_, space), + }) + .collect::>(); + let mut post_statements = Vec::new(); + let return_arguments = call + .return_arguments + .into_iter() + .map(|(operand, type_, state_space)| { + Ok(match state_space { + ast::StateSpace::Reg => (operand, type_, state_space), + ast::StateSpace::Param => { + let arg_id = + id_defs.register_intermediate(Some((type_.clone(), ast::StateSpace::Reg))); + post_statements.push(Statement::Instruction(ast::Instruction::St( + ast::StData { + qualifier: ast::LdStQualifier::Weak, + state_space: ast::StateSpace::Param, + caching: ast::StCacheOperator::Writeback, + typ: type_.clone(), + }, + ast::Arg2St { + src1: TypedOperand::Reg(operand), + src2: TypedOperand::Reg(arg_id), + }, + ))); + (arg_id, type_, ast::StateSpace::Reg) + } + _ => return Err(TranslateError::unreachable()), + }) + }) + .collect::, _>>()?; + result.push(Statement::Call(ResolvedCall { + input_arguments, + return_arguments, + ..call + })); + result.extend(post_statements); + Ok(()) +} + +fn insert_hardware_registers<'input>( + module: TranslationModule<'input, TypedArgParams>, +) -> Result, TranslateError> { + convert_methods_simple(module, insert_hardware_registers_impl) +} + +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#extended-precision-integer-arithmetic-instructions +// NVIDIA documentation is misleading. In fact there is no single CC.CF, +// but separate registers for overflow (`add` and `mad`) and underflow (`sub`) +// For reference check the .ptx tests +fn insert_hardware_registers_impl<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + typed_statements: Vec, +) -> Result, TranslateError> { + let mut result = Vec::with_capacity(typed_statements.len()); + let overflow_flag_var = id_defs.register_variable_def( + None, + ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + Some(ast::Initializer::Constant(ast::ImmediateValue::U64(0))), + ); + let underflow_flag_var = id_defs.register_variable_def( + None, + ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + Some(ast::Initializer::Constant(ast::ImmediateValue::U64(0))), + ); + let overflow_flag = overflow_flag_var.name; + let underflow_flag = underflow_flag_var.name; + result.push(Statement::Variable(overflow_flag_var)); + result.push(Statement::Variable(underflow_flag_var)); + for statement in typed_statements { + match statement { + Statement::Instruction(ast::Instruction::MadC { + type_, + is_hi, + arg, + carry_out, + }) => result.push(Statement::MadC(MadCDetails { + type_, + is_hi, + arg: Arg4CarryIn::new(arg, carry_out, TypedOperand::Reg(overflow_flag)), + })), + Statement::Instruction(ast::Instruction::MadCC { type_, arg }) => { + result.push(Statement::MadCC(MadCCDetails { + type_, + arg: Arg4CarryOut::new(arg, TypedOperand::Reg(overflow_flag)), + })) + } + Statement::Instruction(ast::Instruction::AddC(details, args)) => { + result.push(Statement::AddC( + details.type_, + Arg3CarryIn::new(args, details.carry_out, TypedOperand::Reg(overflow_flag)), + )) + } + Statement::Instruction(ast::Instruction::AddCC(details, args)) => { + result.push(Statement::AddCC( + details, + Arg3CarryOut::new(args, TypedOperand::Reg(overflow_flag)), + )) + } + Statement::Instruction(ast::Instruction::SubC(details, args)) => { + result.push(Statement::SubC( + details.type_, + Arg3CarryIn::new(args, details.carry_out, TypedOperand::Reg(underflow_flag)), + )) + } + Statement::Instruction(ast::Instruction::SubCC(details, args)) => { + result.push(Statement::SubCC( + details, + Arg3CarryOut::new(args, TypedOperand::Reg(underflow_flag)), + )) + } + s => result.push(s), + } + } + Ok(result) +} + +fn fix_special_registers<'input>( + module: TranslationModule<'input, TypedArgParams>, +) -> Result, TranslateError> { + convert_methods(module, fix_special_registers_impl) +} + +fn fix_special_registers_impl<'input>( + _: CompilationMode, + id_defs: &mut IdNameMapBuilder<'input>, + ptx_imports: &mut AdditionalFunctionDeclarations, + _: &mut [ast::VariableDeclaration], + _: &mut [ast::VariableDeclaration], + _: bool, + typed_statements: Vec, +) -> Result, TranslateError> { + let result = Vec::with_capacity(typed_statements.len()); + let mut sreg_sresolver = SpecialRegisterResolver { + ptx_imports, + id_defs, + result, + }; + for s in typed_statements { match s { + Statement::Call(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::Instruction(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::Conditional(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::Conversion(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::PtrAccess(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::RepackVector(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::MadC(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::MadCC(details) => { + let new_statement = details.visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::AddC(details, arg) => { + let new_statement = VisitAddC(details, arg).visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::AddCC(type_, arg) => { + let new_statement = VisitAddCC(type_, arg).visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::SubC(details, arg) => { + let new_statement = VisitSubC(details, arg).visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + Statement::SubCC(type_, arg) => { + let new_statement = VisitSubCC(type_, arg).visit(&mut sreg_sresolver)?; + sreg_sresolver.result.push(new_statement); + } + s @ Statement::Variable(_) + | s @ Statement::Constant(_) + | s @ Statement::Label(_) + | s @ Statement::FunctionPointer(_) => sreg_sresolver.result.push(s), + _ => return Err(TranslateError::unreachable()), + } + } + Ok(sreg_sresolver.result) +} + +struct AdditionalFunctionDeclarations( + BTreeMap< + String, + ( + Vec>, + Id, + Vec>, + ), + >, +); + +impl AdditionalFunctionDeclarations { + fn new() -> Self { + Self(BTreeMap::new()) + } + + fn add_or_get_declaration<'a>( + &mut self, + id_defs: &mut IdNameMapBuilder, + name: String, + return_arguments: impl Iterator, + input_arguments: impl Iterator, + ) -> Result { + Ok(match self.0.entry(name) { + btree_map::Entry::Vacant(entry) => { + let fn_id = id_defs.register_intermediate(None); + let return_arguments = fn_arguments_to_variables(id_defs, return_arguments); + let input_arguments = fn_arguments_to_variables(id_defs, input_arguments); + entry.insert((return_arguments, fn_id, input_arguments)); + fn_id + } + btree_map::Entry::Occupied(entry) => entry.get().1, + }) + } + + fn flush<'input, P: ast::ArgParams>( + self, + directives: &mut Vec>, + ) { + for (name, (return_arguments, id, input_arguments)) in self.0 { + directives.push(TranslationDirective::Method(TranslationMethod { + return_arguments, + name: id, + input_arguments, + body: None, + tuning: Vec::new(), + is_kernel: false, + source_name: Some(Cow::Owned(name)), + special_raytracing_linking: false, + })); + } + } +} + +fn insert_mem_ssa_statements<'input>( + module: TranslationModule<'input, TypedArgParams>, +) -> Result, TranslateError> { + convert_methods(module, insert_mem_ssa_statements_impl) +} + +fn insert_mem_ssa_statements_impl<'input>( + _: CompilationMode, + id_def: &mut IdNameMapBuilder<'input>, + _: &mut AdditionalFunctionDeclarations, + return_arguments: &mut [ast::VariableDeclaration], + input_arguments: &mut [ast::VariableDeclaration], + is_kernel: bool, + typed_statements: Vec, +) -> Result, TranslateError> { + let mut result = Vec::with_capacity(typed_statements.len()); + if !is_kernel { + for arg in input_arguments.iter_mut() { + insert_mem_ssa_argument(id_def, &mut result, arg); + } + } + for arg in return_arguments.iter() { + insert_mem_ssa_argument_reg_return(&mut result, arg); + } + for statement in typed_statements { + match statement { Statement::Call(call) => { insert_mem_ssa_statement_default(id_def, &mut result, call.cast())? } Statement::Instruction(inst) => match inst { + ast::Instruction::Exit => { + insert_mma_ssa_statement_ret( + return_arguments, + &mut result, + ast::Instruction::Exit, + ast::RetData { uniform: false }, + id_def, + ); + } 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))) - } + insert_mma_ssa_statement_ret( + return_arguments, + &mut result, + ast::Instruction::Ret(d), + d, + id_def, + ); } 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::Conditional(bra) => { + insert_mem_ssa_statement_default(id_def, &mut result, bra)? } Statement::Conversion(conv) => { insert_mem_ssa_statement_default(id_def, &mut result, conv)? @@ -2030,412 +2232,180 @@ fn insert_mem_ssa_statements<'a, 'b>( 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()), + Statement::FunctionPointer(func_ptr) => { + insert_mem_ssa_statement_default(id_def, &mut result, func_ptr)? + } + Statement::MadC(madc) => insert_mem_ssa_statement_default(id_def, &mut result, madc)?, + Statement::MadCC(madcc) => { + insert_mem_ssa_statement_default(id_def, &mut result, madcc)? + } + Statement::AddC(details, arg) => { + insert_mem_ssa_statement_default(id_def, &mut result, VisitAddC(details, arg))? + } + Statement::AddCC(type_, arg) => { + insert_mem_ssa_statement_default(id_def, &mut result, VisitAddCC(type_, arg))? + } + Statement::SubC(details, arg) => { + insert_mem_ssa_statement_default(id_def, &mut result, VisitSubC(details, arg))? + } + Statement::SubCC(type_, arg) => { + insert_mem_ssa_statement_default(id_def, &mut result, VisitSubCC(type_, arg))? + } + s @ Statement::Variable(_) | s @ Statement::Label(_) | s @ Statement::Constant(..) => { + result.push(s) + } + _ => return Err(TranslateError::unreachable()), } } Ok(result) } -fn type_to_variable_type( - t: &ast::Type, - is_func: bool, -) -> Result, 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: Sized { - fn visit( - self, - visitor: &mut impl ArgumentMapVisitor, - ) -> Result, To>, TranslateError>; -} - -struct VisitArgumentDescriptor< - 'a, - Ctor: FnOnce(spirv::Word) -> Statement, U>, - U: ArgParamsEx, -> { - desc: ArgumentDescriptor, - typ: &'a ast::Type, - stmt_ctor: Ctor, -} - -impl< - 'a, - Ctor: FnOnce(spirv::Word) -> Statement, U>, - T: ArgParamsEx, - U: ArgParamsEx, - > Visitable for VisitArgumentDescriptor<'a, Ctor, U> -{ - fn visit( - self, - visitor: &mut impl ArgumentMapVisitor, - ) -> Result, 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, - post_statements: Vec, -} - -impl<'a, 'input> InsertMemSSAVisitor<'a, 'input> { - fn symbol( - &mut self, - desc: ArgumentDescriptor<(spirv::Word, Option)>, - expected_type: Option<&ast::Type>, - ) -> Result { - 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 +fn insert_mma_ssa_statement_ret( + return_arguments: &mut [ast::VariableDeclaration], + result: &mut Vec, TypedArgParams>>, + zero_inst: ast::Instruction, + d: ast::RetData, + id_def: &mut IdNameMapBuilder<'_>, +) { + if return_arguments.len() == 0 { + result.push(Statement::Instruction(zero_inst)); + } else { + let return_ids = return_arguments + .iter() + .map(|return_reg| { + let new_id = id_def + .register_intermediate(Some((return_reg.type_.clone(), ast::StateSpace::Reg))); + result.push(Statement::LoadVar(LoadVarDetails { + arg: ast::Arg2 { + dst: new_id, + src: return_reg.name, }, - )) - } - 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), + // TODO: ret with stateful conversion + _state_space: ast::StateSpace::Reg, + typ: return_reg.type_.clone(), + member_index: None, })); - } - Ok(generated_id) + (new_id, return_reg.type_.clone()) + }) + .collect::>(); + result.push(Statement::RetValue(d, return_ids)); } } -impl<'a, 'input> ArgumentMapVisitor - for InsertMemSSAVisitor<'a, 'input> -{ - fn id( - &mut self, - desc: ArgumentDescriptor, - typ: Option<&ast::Type>, - ) -> Result { - self.symbol(desc.new_op((desc.op, None)), typ) - } - - fn operand( - &mut self, - desc: ArgumentDescriptor, - typ: &ast::Type, - ) -> Result { - 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 expand_arguments<'input>( + module: TranslationModule<'input, TypedArgParams>, +) -> Result, TranslateError> { + convert_methods_simple(module, expand_arguments2_impl) } -fn insert_mem_ssa_statement_default<'a, 'input, S: Visitable>( - id_def: &'a mut NumericIdResolver<'input>, - func: &'a mut Vec, - 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, - id_def: &'b mut MutableNumericIdResolver<'a>, +fn expand_arguments2_impl<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + fn_body: Vec, ) -> Result, TranslateError> { - let mut result = Vec::with_capacity(func.len()); - for s in func { - match s { + let mut result = Vec::with_capacity(fn_body.len()); + for statment in fn_body { + match statment { Statement::Call(call) => { - let mut visitor = FlattenArguments::new(&mut result, id_def); + let mut visitor = FlattenArguments::new(&mut result, id_defs); 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 mut visitor = FlattenArguments::new(&mut result, id_defs); 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 { + Statement::Variable(Variable { align, - v_type, + type_, + state_space, name, - array_init, - }) => result.push(Statement::Variable(ast::Variable { + initializer, + }) => result.push(Statement::Variable(Variable { align, - v_type, + type_, + state_space, name, - array_init, + initializer, })), Statement::PtrAccess(ptr_access) => { - let mut visitor = FlattenArguments::new(&mut result, id_def); + let mut visitor = FlattenArguments::new(&mut result, id_defs); 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 mut visitor = FlattenArguments::new(&mut result, id_defs); let (new_inst, post_stmts) = (repack.map(&mut visitor)?, visitor.post_stmts); result.push(Statement::RepackVector(new_inst)); result.extend(post_stmts); } + Statement::MadC(madc) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = (madc.visit(&mut visitor)?, visitor.post_stmts); + result.push(new_inst); + result.extend(post_stmts); + } + Statement::MadCC(madcc) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = (madcc.visit(&mut visitor)?, visitor.post_stmts); + result.push(new_inst); + result.extend(post_stmts); + } + Statement::AddC(details, arg) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = ( + VisitAddC(details, arg).visit(&mut visitor)?, + visitor.post_stmts, + ); + result.push(new_inst); + result.extend(post_stmts); + } + Statement::AddCC(type_, arg) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = ( + VisitAddCC(type_, arg).visit(&mut visitor)?, + visitor.post_stmts, + ); + result.push(new_inst); + result.extend(post_stmts); + } + Statement::SubC(details, arg) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = ( + VisitSubC(details, arg).visit(&mut visitor)?, + visitor.post_stmts, + ); + result.push(new_inst); + result.extend(post_stmts); + } + Statement::SubCC(type_, arg) => { + let mut visitor = FlattenArguments::new(&mut result, id_defs); + let (new_inst, post_stmts) = ( + VisitSubCC(type_, arg).visit(&mut visitor)?, + visitor.post_stmts, + ); + result.push(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()), + Statement::Constant(c) => result.push(Statement::Constant(c)), + Statement::FunctionPointer(d) => result.push(Statement::FunctionPointer(d)), + Statement::AsmVolatile { asm, constraints } => { + result.push(Statement::AsmVolatile { asm, constraints }) + } } } Ok(result) } -struct FlattenArguments<'a, 'b> { - func: &'b mut Vec, - id_def: &'b mut MutableNumericIdResolver<'a>, - post_stmts: Vec, -} - -impl<'a, 'b> FlattenArguments<'a, 'b> { - fn new( - func: &'b mut Vec, - id_def: &'b mut MutableNumericIdResolver<'a>, - ) -> Self { - FlattenArguments { - func, - id_def, - post_stmts: Vec::new(), - } - } - - fn reg( - &mut self, - desc: ArgumentDescriptor, - _: Option<&ast::Type>, - ) -> Result { - Ok(desc.op) - } - - fn reg_offset( - &mut self, - desc: ArgumentDescriptor<(spirv::Word, i32)>, - typ: &ast::Type, - ) -> Result { - 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::::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::::Add( - arith_detail, - ast::Arg3 { - dst: result_id, - src1: reg, - src2: id_constant_stmt, - }, - ), - )); - } - Ok(result_id) - } - - fn immediate( - &mut self, - desc: ArgumentDescriptor, - typ: &ast::Type, - ) -> Result { - 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 for FlattenArguments<'a, 'b> { - fn id( - &mut self, - desc: ArgumentDescriptor, - t: Option<&ast::Type>, - ) -> Result { - self.reg(desc, t) - } - - fn operand( - &mut self, - desc: ArgumentDescriptor, - typ: &ast::Type, - ) -> Result { - 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 @@ -2449,87 +2419,51 @@ impl<'a, 'b> ArgumentMapVisitor for FlattenAr 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 + * and many more */ -fn insert_implicit_conversions( - func: Vec, - id_def: &mut MutableNumericIdResolver, +fn insert_implicit_conversions<'input>( + module: TranslationModule<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + convert_methods_simple(module, insert_implicit_conversions2_impl) +} + +fn insert_implicit_conversions2_impl<'input>( + id_def: &mut IdNameMapBuilder<'input>, + fn_body: Vec, ) -> Result, 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, - )?, + let mut result = Vec::with_capacity(fn_body.len()); + for statement in fn_body { + match statement { + Statement::Call(call) => { + insert_implicit_conversions_impl(&mut result, id_def, call)?; + } 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, - )?; + insert_implicit_conversions_impl(&mut result, id_def, inst)?; } - 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::PtrAccess(access) => { + insert_implicit_conversions_impl(&mut result, id_def, access)?; + } + Statement::RepackVector(repack) => { + insert_implicit_conversions_impl(&mut result, id_def, repack)?; + } + Statement::MadC(madc) => { + insert_implicit_conversions_impl(&mut result, id_def, madc)?; + } + Statement::MadCC(madcc) => { + insert_implicit_conversions_impl(&mut result, id_def, madcc)?; + } + Statement::AddC(details, arg) => { + insert_implicit_conversions_impl(&mut result, id_def, VisitAddC(details, arg))?; + } + Statement::AddCC(type_, arg) => { + insert_implicit_conversions_impl(&mut result, id_def, VisitAddCC(type_, arg))?; + } + Statement::SubC(details, arg) => { + insert_implicit_conversions_impl(&mut result, id_def, VisitSubC(details, arg))?; + } + Statement::SubCC(type_, arg) => { + insert_implicit_conversions_impl(&mut result, id_def, VisitSubCC(type_, arg))?; } - 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(_) @@ -2537,2174 +2471,2481 @@ fn insert_implicit_conversions( | s @ Statement::Variable(_) | s @ Statement::LoadVar(..) | s @ Statement::StoreVar(..) - | s @ Statement::RetValue(_, _) => result.push(s), + | s @ Statement::RetValue(..) + | s @ Statement::AsmVolatile { .. } + | s @ Statement::FunctionPointer(..) => result.push(s), } } Ok(result) } -fn insert_implicit_conversions_impl( - func: &mut Vec, - id_def: &mut MutableNumericIdResolver, - stmt: impl Visitable, - default_conversion_fn: for<'a> fn( - &'a ast::Type, - &'a ast::Type, - Option, - ) -> Result, TranslateError>, - state_space: Option, -) -> Result<(), TranslateError> { - let mut post_conv = Vec::new(); - let statement = stmt.visit( - &mut |desc: ArgumentDescriptor, 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 normalize_labels<'input>( + module: TranslationModule<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + convert_methods_simple(module, normalize_labels2_impl) } -fn get_function_type( - builder: &mut dr::Builder, - map: &mut TypeWordMap, - spirv_input: &[ast::Variable], - spirv_output: &[ast::Variable], -) -> (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 normalize_labels2_impl<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + fn_body: Vec, +) -> Result, TranslateError> { + let mut labels_in_use = FxHashSet::default(); + for statement in fn_body.iter() { + match statement { + 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(..) + | Statement::MadC(..) + | Statement::MadCC(..) + | Statement::AddC(..) + | Statement::AddCC(..) + | Statement::SubC(..) + | Statement::SubCC(..) + | Statement::AsmVolatile { .. } + | Statement::FunctionPointer(..) => {} + } + } + Ok( + iter::once(Statement::Label(id_defs.register_intermediate(None))) + .chain(fn_body.into_iter().filter(|s| match s { + Statement::Label(i) => labels_in_use.contains(i), + _ => true, + })) + .collect::>(), ) } -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::>(); - 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 { - 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, - op1: spirv::Word, - op2: spirv::Word, -) -> Result { - 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, -) -> 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, -) -> 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, -} - -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, -) -> 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, -) -> 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: T) -> Vec { - let mut result = vec![0; mem::size_of::()]; - 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) { - 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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, -) -> 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 +fn hoist_globals<'input, P: ast::ArgParams>( + module: TranslationModule<'input, P>, +) -> TranslationModule<'input, P> { + let mut directives = Vec::with_capacity(module.directives.len()); + for directive in module.directives { + match directive { + var @ TranslationDirective::Variable(..) => directives.push(var), + TranslationDirective::Method(method) => { + let body = method.body.map(|body| { + body.into_iter() + .filter_map(|statement| match statement { + Statement::Variable( + var @ Variable { + state_space: ast::StateSpace::Shared, + .. + }, + ) + | Statement::Variable( + var @ Variable { + state_space: ast::StateSpace::Global, + .. + }, + ) => { + directives.push(TranslationDirective::Variable( + ast::LinkingDirective::None, + None, + var, + )); + None + } + statement => Some(statement), + }) + .collect::>() }); - 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 conversion_fn = if from_parts.scalar_kind == ScalarKind::Signed - && to_parts.scalar_kind == ScalarKind::Signed - { - dr::Builder::s_convert - } else { - dr::Builder::u_convert - }; - let wide_bit_value = - conversion_fn(builder, 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, + directives.push(TranslationDirective::Method(TranslationMethod { + body, + ..method + })) + } + } + } + { + TranslationModule { + directives, + ..module + } + } +} + +fn replace_instructions_with_builtins<'input>( + module: TranslationModule<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + convert_methods(module, replace_instructions_with_builtins_impl) +} + +fn replace_instructions_with_builtins_impl<'input>( + compilation_mode: CompilationMode, + id_def: &mut IdNameMapBuilder<'input>, + ptx_impl_imports: &mut AdditionalFunctionDeclarations, + _: &mut [ast::VariableDeclaration], + _: &mut [ast::VariableDeclaration], + _: bool, + fn_body: Vec, +) -> Result, TranslateError> { + let mut statements = Vec::with_capacity(fn_body.len()); + for statement in fn_body { + match statement { + Statement::Instruction(ast::Instruction::Nanosleep(arg)) => { + let fn_name = [ZLUDA_PTX_PREFIX, "nanosleep_u32"].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Nanosleep(arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::MatchAny(arg)) => { + let fn_name = [ZLUDA_PTX_PREFIX, "match_any_sync_b32"].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::MatchAny(arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Dp4a(type_, arg)) => { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "dp4a_", + type_.to_ptx_name(), + "_", + type_.to_ptx_name(), + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Dp4a(type_, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::BarRed(op, arg3)) => { + let op_name = match op { + ast::ReductionOp::And => "and", + ast::ReductionOp::Or => "or", + ast::ReductionOp::Popc => "popc", + }; + let dst_type = op.dst_type().to_ptx_name(); + let fn_name = [ZLUDA_PTX_PREFIX, "bar_red_", op_name, "_", dst_type].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::BarRed(op, arg3), + fn_name, + )?); + } + // We dispatch vote_sync_... by compilation mode suffix + // because LLVM crashes if there are both calls to `llvm.amdgcn.ballot.i32` and + // `llvm.amdgcn.ballot.i64` inside same function (even if only one of them can be called) + Statement::Instruction(ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::Any, + negate_pred, + }, + arg, + )) => { + let instr_suffix = if negate_pred { "_negate" } else { "" }; + let mode_suffix = compilation_mode_suffix(compilation_mode); + let fn_name = [ + ZLUDA_PTX_PREFIX, + "vote_sync_any_pred", + instr_suffix, + mode_suffix, + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::Any, + negate_pred, }, - )?; - } - } - } - (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, + arg, ), - ) - } 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>>, -) -> Result, TranslateError> { - for s in func.iter() { - match s { - ast::Statement::Label(id) => { - id_defs.add_def(*id, None, false); + fn_name, + )?); } - _ => (), + Statement::Instruction(ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::All, + negate_pred, + }, + arg, + )) => { + let instr_suffix = if negate_pred { "_negate" } else { "" }; + let mode_suffix = compilation_mode_suffix(compilation_mode); + let fn_name = [ + ZLUDA_PTX_PREFIX, + "vote_sync_all_pred", + instr_suffix, + mode_suffix, + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::All, + negate_pred, + }, + arg, + ), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::Ballot, + negate_pred, + }, + arg, + )) => { + let instr_suffix = if negate_pred { "_negate" } else { "" }; + let mode_suffix = compilation_mode_suffix(compilation_mode); + let fn_name = [ + ZLUDA_PTX_PREFIX, + "vote_sync_ballot_b32", + instr_suffix, + mode_suffix, + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Vote( + ast::VoteDetails { + mode: ast::VoteMode::Ballot, + negate_pred, + }, + arg, + ), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Bar(details, arg)) => { + let fn_name = [ZLUDA_PTX_PREFIX, "barrier_sync"].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Bar(details, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Bfe { typ, arg }) => { + let fn_name = [ZLUDA_PTX_PREFIX, "bfe_", typ.to_ptx_name()].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Bfe { typ, arg }, + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Bfi { typ, arg }) => { + let fn_name = [ZLUDA_PTX_PREFIX, "bfi_", typ.to_ptx_name()].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Bfi { typ, arg }, + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Activemask { arg }) => { + let fn_name = [ZLUDA_PTX_PREFIX, "activemask"].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Activemask { arg }, + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Tex(tex, arg)) => { + let geometry = tex.geometry.as_ptx(); + let fn_name = [ + ZLUDA_PTX_PREFIX, + "tex", + tex.suffix(), + "_", + geometry, + "_v4", + "_", + tex.channel_type.to_ptx_name(), + "_", + tex.coordinate_type.to_ptx_name(), + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Tex(tex, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Shfl(shfl_mode, arg)) + if arg.dst2.is_none() => + { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "shfl_", + shfl_mode.to_ptx_name(), + "_b32_slow", + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Shfl(shfl_mode, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Shfl(shfl_mode, arg)) + if arg.dst2.is_some() => + { + replace_shfl_with_pred(id_def, ptx_impl_imports, &mut statements, shfl_mode, arg)?; + } + Statement::Instruction(ast::Instruction::Cvt( + ast::CvtDetails::FloatFromFloat(ast::CvtDesc { + saturate: true, + src, + dst, + rounding, + flush_to_zero, + }), + arg, + )) if src == dst => { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "cvt_sat_", + dst.to_ptx_name(), + "_", + dst.to_ptx_name(), + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Cvt( + ast::CvtDetails::FloatFromFloat(ast::CvtDesc { + saturate: true, + src, + dst, + rounding, + flush_to_zero, + }), + arg, + ), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Shf( + ast::FunnelShift { + direction, + mode: ast::ShiftNormalization::Clamp, + }, + arg, + )) => { + let direction_str = match direction { + ast::FunnelDirection::Left => "l", + ast::FunnelDirection::Right => "r", + }; + let fn_name = [ZLUDA_PTX_PREFIX, "shf_", direction_str, "_clamp_b32"].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Shf( + ast::FunnelShift { + direction, + mode: ast::ShiftNormalization::Clamp, + }, + arg, + ), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Suld(suld, arg)) => { + let geometry = suld.geometry.as_ptx(); + let vector = suld.vector_ptx()?; + let fn_name = [ + ZLUDA_PTX_PREFIX, + "suld_b_", + suld.suffix(), + geometry, + vector, + "_", + suld.type_.to_ptx_name(), + "_trap", + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Suld(suld, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Sust(sust, arg)) => { + let geometry = sust.geometry.as_ptx(); + let vector = sust.vector_ptx()?; + let fn_name = [ + ZLUDA_PTX_PREFIX, + "sust_b_", + sust.suffix(), + geometry, + vector, + "_", + sust.type_.to_ptx_name(), + "_trap", + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Sust(sust, arg), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Atom( + details @ ast::AtomDetails { + inner: + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Inc, + .. + }, + .. + }, + args, + )) => { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "atom_", + details.semantics.to_ptx_name(), + "_", + details.scope.to_ptx_name(), + "_", + details.space.to_ptx_name(), + "_inc", + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Atom(details, args), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Atom( + details @ ast::AtomDetails { + inner: + ast::AtomInnerDetails::Unsigned { + op: ast::AtomUIntOp::Dec, + .. + }, + .. + }, + args, + )) => { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "atom_", + details.semantics.to_ptx_name(), + "_", + details.scope.to_ptx_name(), + "_", + details.space.to_ptx_name(), + "_dec", + ] + .concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Atom(details, args), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Cvt( + ast::CvtDetails::FloatFromInt(desc), + args, + )) => extract_global_cvt( + &mut statements, + ptx_impl_imports, + id_def, + desc.clone(), + ast::Instruction::Cvt(ast::CvtDetails::FloatFromInt(desc), args), + )?, + Statement::Instruction(ast::Instruction::Cvt( + ast::CvtDetails::IntFromFloat(desc), + args, + )) => extract_global_cvt( + &mut statements, + ptx_impl_imports, + id_def, + desc.clone(), + ast::Instruction::Cvt(ast::CvtDetails::IntFromFloat(desc), args), + )?, + Statement::Instruction(ast::Instruction::Cvt( + ast::CvtDetails::FloatFromFloat(desc), + args, + )) if desc.dst.size_of() < desc.src.size_of() => extract_global_cvt( + &mut statements, + ptx_impl_imports, + id_def, + desc.clone(), + ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(desc), args), + )?, + Statement::Instruction(ast::Instruction::Mul( + ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + )) + | Statement::Instruction(ast::Instruction::Mul( + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + )) if typ == ast::ScalarType::U64 || typ == ast::ScalarType::S64 => { + let fn_name = [ZLUDA_PTX_PREFIX, "mul_hi_", typ.to_ptx_name()].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Mul( + ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + ), + fn_name, + )?); + } + Statement::Instruction(ast::Instruction::Mad( + ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + )) + | Statement::Instruction(ast::Instruction::Mad( + ast::MulDetails::Unsigned(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + )) if typ == ast::ScalarType::U64 || typ == ast::ScalarType::S64 => { + let fn_name = [ZLUDA_PTX_PREFIX, "mad_hi_", typ.to_ptx_name()].concat(); + statements.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + ast::Instruction::Mad( + ast::MulDetails::Signed(ast::MulInt { + control: ast::MulIntControl::High, + typ, + }), + args, + ), + fn_name, + )?); + } + s => statements.push(s), } } - let mut result = Vec::new(); - for s in func { - expand_map_variables(id_defs, fn_defs, &mut result, s)?; + Ok(statements) +} + +fn compilation_mode_suffix(compilation_mode: CompilationMode) -> &'static str { + match compilation_mode { + CompilationMode::Wave32 => "_32", + CompilationMode::Wave32OnWave64 => "_32on64", + CompilationMode::DoubleWave32OnWave64 => "_double32on64", + } +} + +fn replace_shfl_with_pred<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + ptx_impl_imports: &mut AdditionalFunctionDeclarations, + statements: &mut Vec, + shfl_mode: ast::ShflMode, + arg: ast::Arg5Shfl, +) -> Result<(), TranslateError> { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "shfl_", + shfl_mode.to_ptx_name(), + "_b32_pred_slow", + ] + .concat(); + let inst = ast::Instruction::Shfl(shfl_mode, arg); + let mut arguments = Vec::new(); + inst.visit( + &mut |desc: ArgumentDescriptor, typ: Option<(&ast::Type, ast::StateSpace)>| { + let (typ, space) = match typ { + Some((typ, space)) => (typ.clone(), space), + None => return Err(TranslateError::unreachable()), + }; + let result = desc.op; + arguments.push((desc, typ, space)); + Ok(result) + }, + )?; + let return_arguments_count = arguments + .iter() + .position(|(desc, _, _)| !desc.is_dst) + .unwrap_or(arguments.len()); + let (original_return_arguments, input_arguments) = + arguments.split_at_mut(return_arguments_count); + // Builtin call returns <2 x i32>, we have to unpack the vector and insert + // conversion for predicate + let call_return_arguments = [( + id_defs.register_intermediate(Some(( + ast::Type::Vector(ast::ScalarType::U32, 2), + ast::StateSpace::Reg, + ))), + ast::Type::Vector(ast::ScalarType::U32, 2), + ast::StateSpace::Reg, + )]; + let fn_id = ptx_impl_imports.add_or_get_declaration( + id_defs, + fn_name, + call_return_arguments + .iter() + .map(|(_, typ, state)| (typ, *state)), + input_arguments.iter().map(|(_, typ, state)| (typ, *state)), + )?; + statements.push(Statement::Call(ResolvedCall { + uniform: false, + name: fn_id, + return_arguments: call_return_arguments.to_vec(), + input_arguments: arguments_to_resolved_arguments(input_arguments), + is_indirect: false, + })); + let unpacked_elements = [ + original_return_arguments[0].0.op, + id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + ))), + ]; + statements.push(Statement::RepackVector(RepackVectorDetails { + is_extract: true, + typ: ast::ScalarType::U32, + packed: call_return_arguments[0].0, + unpacked: unpacked_elements.to_vec(), + non_default_implicit_conversion: None, + })); + let constant_1 = id_defs.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + ))); + statements.push(Statement::Constant(ConstantDefinition { + dst: constant_1, + typ: ast::ScalarType::U32, + value: ast::ImmediateValue::U64(1), + })); + statements.push(Statement::Instruction(ast::Instruction::Setp( + ast::SetpData { + typ: ast::ScalarType::U32, + flush_to_zero: None, + cmp_op: ast::SetpCompareOp::Eq, + }, + ast::Arg4Setp { + dst1: original_return_arguments[1].0.op, + dst2: None, + src1: unpacked_elements[1], + src2: constant_1, + }, + ))); + Ok(()) +} + +// 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 LLVM has no +// such capability, so instead we guesstimate which use is more common in a +// method and emit suitable attributes +fn compute_denorm_statistics<'input, P: ast::ArgParams>( + module: &TranslationModule<'input, P>, +) -> FxHashMap { + let mut denorm_methods = FxHashMap::default(); + for directive in module.directives.iter() { + match directive { + TranslationDirective::Variable(..) + | TranslationDirective::Method(TranslationMethod { body: None, .. }) => {} + TranslationDirective::Method(TranslationMethod { + name, + body: Some(statements), + .. + }) => { + let mut fp32_flush_count = 0isize; + let mut nonfp32_flush_count = 0isize; + for statement in statements { + match statement { + Statement::Instruction(inst) => match inst.flush_to_zero() { + Some((flush, 4)) => { + fp32_flush_count += if flush { 1 } else { -1 }; + } + Some((flush, _)) => { + nonfp32_flush_count += if flush { 1 } else { -1 }; + } + None => {} + }, + Statement::LoadVar(..) => {} + Statement::StoreVar(..) => {} + Statement::Call(_) => {} + Statement::Conditional(_) => {} + Statement::Conversion(_) => {} + Statement::Constant(_) => {} + Statement::RetValue(_, _) => {} + Statement::Label(_) => {} + Statement::Variable(_) => {} + Statement::PtrAccess { .. } => {} + Statement::RepackVector(_) => {} + Statement::FunctionPointer(_) => {} + Statement::MadC(_) => {} + Statement::MadCC(_) => {} + Statement::AddC(..) => {} + Statement::AddCC(..) => {} + Statement::SubC(..) => {} + Statement::SubCC(..) => {} + Statement::AsmVolatile { .. } => {} + } + } + let summary = DenormSummary { + f32: if fp32_flush_count > 0 { + FPDenormMode::FlushToZero + } else { + FPDenormMode::Preserve + }, + f16f64: if nonfp32_flush_count > 0 { + FPDenormMode::FlushToZero + } else { + FPDenormMode::Preserve + }, + }; + denorm_methods.insert(*name, summary); + } + } + } + denorm_methods +} + +#[derive(Copy, Clone)] +pub(crate) struct DenormSummary { + pub(crate) f32: FPDenormMode, + pub(crate) f16f64: FPDenormMode, +} + +pub fn to_llvm_module<'input>( + compilation_mode: CompilationMode, + ast: Vec>, +) -> Result { + to_llvm_module_impl2(compilation_mode, ast, None) +} + +pub fn to_llvm_module_for_raytracing<'input>( + ast: ast::Module<'input>, + raytracing_fn: &str, + cumulative_attribute_variables: &VariablesBlock, +) -> Result, TranslateError> { + let mut raytracing_state = + RaytracingTranslationState::new(raytracing_fn, cumulative_attribute_variables); + let compilation_module = to_llvm_module_impl2( + CompilationMode::Wave32, + vec![ast], + Some(&mut raytracing_state), + )?; + let entry_point_kind: RaytracingEntryPointKind = raytracing_state.entry_point_kind.unwrap(); + let rt_section = hip_common::kernel_metadata::zluda_rt6::write( + &raytracing_state.new_attribute_variables, + &raytracing_state.variables, + entry_point_kind == RaytracingEntryPointKind::Callable, + ); + let mut linker_module = Vec::new(); + emit::emit_section( + hip_common::kernel_metadata::zluda_rt6::SECTION_STR, + &rt_section, + &mut linker_module, + ); + Ok(RaytracingModule::new( + raytracing_state.kernel_name, + compilation_module, + raytracing_state.variables, + entry_point_kind, + raytracing_state.new_attribute_variables, + linker_module, + )) +} + +pub(crate) struct RaytracingTranslationState<'a, 'input> { + pub(crate) entry_point_str: &'a str, + pub(crate) entry_point_id: Option, + pub(crate) entry_point_kind: Option, + pub(crate) kernel_name: String, + pub(crate) buffers: FxHashMap>, + pub(crate) variables: VariablesBlock, + pub(crate) old_attribute_variables: &'a VariablesBlock, + pub(crate) new_attribute_variables: VariablesBlock, + pub(crate) reachable_user_functions: FxHashSet, +} + +impl<'a, 'input> RaytracingTranslationState<'a, 'input> { + fn new(entry_point_str: &'a str, cumulative_attribute_variables: &'a VariablesBlock) -> Self { + Self { + entry_point_str, + old_attribute_variables: cumulative_attribute_variables, + entry_point_id: None, + entry_point_kind: None, + kernel_name: String::new(), + buffers: FxHashMap::default(), + variables: VariablesBlock::empty(), + new_attribute_variables: VariablesBlock::empty(), + reachable_user_functions: FxHashSet::default(), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq)] +pub(crate) enum RaytracingEntryPointKind { + BoundingBox, + Intersection, + Callable, + // Closest hit, any hit, attribute, ray generation, exception, miss + Unknown, +} + +fn to_llvm_module_impl2<'a, 'input>( + compilation_mode: CompilationMode, + asts: Vec>, + mut raytracing: Option<&mut RaytracingTranslationState<'a, 'input>>, +) -> Result, TranslateError> { + let empty_module = if raytracing.is_some() { + raytracing::create_module_with_builtins() + } else { + TranslationModule::new(compilation_mode) + }; + let linking = resolve_linking(&*asts, raytracing.is_some())?; + let (mut translation_module, functions) = + link_and_normalize_modules(asts, empty_module, linking)?; + if let Some(ref mut raytracing_state) = raytracing { + translation_module = raytracing::run_on_normalized(translation_module, raytracing_state)?; + } + let translation_module = extract_builtin_functions(translation_module); + let translation_module = resolve_instruction_types(translation_module, functions)?; + let mut translation_module = restructure_function_return_types(translation_module)?; + if let Some(ref mut raytracing_state) = raytracing { + translation_module = raytracing::run_on_typed(translation_module, raytracing_state)?; + } + let translation_module = deparamize_function_declarations(translation_module)?; + let translation_module = insert_hardware_registers(translation_module)?; + let translation_module = fix_special_registers(translation_module)?; + let translation_module = insert_mem_ssa_statements(translation_module)?; + let translation_module = expand_arguments(translation_module)?; + let mut translation_module = deparamize_variable_declarations(translation_module)?; + if let Some(ref mut raytracing_state) = raytracing { + // raytracing passes rely heavily on particular PTX patterns, they must run before implicit conversions + translation_module = raytracing::postprocess(translation_module, raytracing_state)?; + } + let translation_module = insert_implicit_conversions(translation_module)?; + let translation_module = insert_compilation_mode_prologue(translation_module); + let translation_module = normalize_labels(translation_module)?; + let translation_module = hoist_globals(translation_module); + let translation_module = move_variables_to_start(translation_module)?; + let mut translation_module = replace_instructions_with_builtins(translation_module)?; + if raytracing.is_some() { + translation_module = raytracing::replace_tex_builtins_hack(translation_module)?; + } + let call_graph = CallGraph::new(&translation_module.directives); + let translation_module = convert_dynamic_shared_memory_usage(translation_module, &call_graph)?; + let denorm_statistics = compute_denorm_statistics(&translation_module); + let kernel_arguments = get_kernel_arguments(&translation_module.directives)?; + let mut bitcode_modules = vec![ZLUDA_PTX_IMPL_AMD]; + if raytracing.is_some() { + bitcode_modules.push(raytracing::bitcode()); + } + let metadata = create_metadata(&translation_module); + let (llvm_context, llvm_module) = unsafe { + emit::emit_llvm_bitcode_and_linker_module(translation_module, denorm_statistics)? + }; + Ok(Module { + metadata, + compilation_mode, + llvm_module, + kernel_arguments, + _llvm_context: llvm_context, + bitcode_modules, + }) +} + +// From "Performance Tips for Frontend Authors" (https://llvm.org/docs/Frontend/PerformanceTips.html): +// "The SROA (Scalar Replacement Of Aggregates) and Mem2Reg passes only attempt to eliminate alloca +// instructions that are in the entry basic block. Given SSA is the canonical form expected by much +// of the optimizer; if allocas can not be eliminated by Mem2Reg or SROA, the optimizer is likely to +// be less effective than it could be." +// Empirically, this is true. Moving allocas to the start gives us less spill-happy assembly +fn move_variables_to_start<'input, P: ast::ArgParams>( + module: TranslationModule<'input, P>, +) -> Result, TranslateError> { + convert_methods_simple(module, move_variables_to_start_impl) +} + +fn move_variables_to_start_impl<'input, P: ast::ArgParams>( + _: &mut IdNameMapBuilder<'input>, + fn_body: Vec, P>>, +) -> Result, P>>, TranslateError> { + if fn_body.is_empty() { + return Ok(fn_body); + } + let mut result = (0..fn_body.len()) + .into_iter() + .map(|_| mem::MaybeUninit::<_>::uninit()) + .collect::>(); + let variables_count = fn_body.iter().fold(0, |acc, statement| { + acc + matches!(statement, Statement::Variable(..)) as usize + }); + let mut variable = 1usize; + let mut non_variable = variables_count + 1; + // methods always start with an entry label + let mut statements = fn_body.into_iter(); + let start_label = statements.next().ok_or_else(TranslateError::unreachable)?; + unsafe { result.get_unchecked_mut(0).write(start_label) }; + for statement in statements { + let index = match statement { + Statement::Variable(_) => &mut variable, + _ => &mut non_variable, + }; + unsafe { result.get_unchecked_mut(*index).write(statement) }; + *index += 1; + } + Ok(unsafe { mem::transmute(result) }) +} + +// PTX definition of param state space does not translate cleanly into AMDGPU notion of an address space: +//  .param in kernel arguments matches AMDGPU constant address space +// .param in function arguments and variables matches AMDGPU private address space +// This pass converts all instances of declarations in .param state space into constant or local state space appropriately +// Previously we used AMDPGU generic address space for params and left it for LLVM to infer the right non-generic space, +// but this made LLVM crash on some inputs (e.g. test alloca_call.ptx) +fn deparamize_variable_declarations<'input>( + mut module: TranslationModule<'input, ExpandedArgParams>, +) -> Result, TranslateError> { + let id_def = &mut module.id_defs; + for directive in module.directives.iter_mut() { + match directive { + TranslationDirective::Variable(..) => {} + TranslationDirective::Method(method) => { + let mut new_space = FxHashMap::default(); + if method.is_kernel { + let input_arguments: Vec> = + mem::replace(&mut method.input_arguments, Vec::new()); + let input_arguments = input_arguments + .into_iter() + .map(|arg| { + if arg.state_space == ast::StateSpace::Param { + let new_arg = id_def.register_variable_decl( + arg.align, + arg.type_.clone(), + ast::StateSpace::Const, + ); + new_space.insert(arg.name, (new_arg.name, ast::StateSpace::Const)); + new_arg + } else { + arg + } + }) + .collect::>(); + method.input_arguments = input_arguments; + } + method.body = method + .body + .take() + .map(|old_body| { + deparamize_variable_declarations_convert_body(id_def, new_space, old_body) + }) + .transpose()?; + } + } + } + Ok(module) +} + +fn deparamize_variable_declarations_convert_body<'input>( + id_def: &mut IdNameMapBuilder<'input>, + mut new_space: FxHashMap, + fn_body: Vec, +) -> Result, TranslateError> { + let mut result = Vec::with_capacity(fn_body.len()); + for statement in fn_body { + match statement { + Statement::Instruction(ast::Instruction::Mov(details, mut args)) => { + if let Some((new_name, _)) = new_space.get(&args.src) { + args.src = *new_name; + } + result.push(Statement::Instruction(ast::Instruction::Mov(details, args))); + } + Statement::Variable( + var @ Variable { + state_space: ast::StateSpace::Param, + .. + }, + ) => { + let old_name = var.name; + let new_var = id_def.register_variable_def( + var.align, + var.type_, + ast::StateSpace::Local, + var.initializer, + ); + new_space.insert(old_name, (new_var.name, ast::StateSpace::Local)); + result.push(Statement::Variable(new_var)); + } + Statement::PtrAccess( + mut ptr @ PtrAccess { + state_space: ast::StateSpace::Param, + .. + }, + ) => { + if let Some((new_name, new_space)) = new_space.get(&ptr.ptr_src) { + ptr.state_space = *new_space; + ptr.ptr_src = *new_name; + } else { + ptr.state_space = ast::StateSpace::Const; + } + let old_name = ptr.dst; + ptr.dst = id_def + .register_intermediate(Some((ptr.underlying_type.clone(), ptr.state_space))); + new_space.insert(old_name, (ptr.dst, ptr.state_space)); + result.push(Statement::PtrAccess(ptr)); + } + Statement::Instruction(ast::Instruction::St( + mut details @ ast::StData { + state_space: ast::StateSpace::Param, + .. + }, + mut args, + )) => { + if let Some((new_name, new_space)) = new_space.get(&args.src1) { + details.state_space = *new_space; + args.src1 = *new_name; + } else { + details.state_space = ast::StateSpace::Const; + } + result.push(Statement::Instruction(ast::Instruction::St(details, args))); + } + Statement::Instruction(ast::Instruction::Ld( + mut details @ ast::LdDetails { + state_space: ast::StateSpace::Param, + .. + }, + mut args, + )) => { + if let Some((new_name, new_space)) = new_space.get(&args.src) { + details.state_space = *new_space; + args.src = *new_name; + } else { + details.state_space = ast::StateSpace::Const; + } + result.push(Statement::Instruction(ast::Instruction::Ld(details, args))); + } + s => result.push(s), + } } Ok(result) } -fn expand_map_variables<'a, 'b>( - id_defs: &mut FnStringIdResolver<'a, 'b>, - fn_defs: &GlobalFnDeclResolver<'a, 'b>, - result: &mut Vec, - s: ast::Statement>, -) -> 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 +fn create_metadata<'input>( + translation_module: &TranslationModule<'input, ExpandedArgParams>, +) -> Metadata<'input> { + let mut kernel_metadata = Vec::new(); + for directive in translation_module.directives.iter() { + match directive { + TranslationDirective::Method(method) => { + if method.tuning.is_empty() { + continue; } - 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)? + let name = match method.source_name { + Some(ref name) => name.clone(), + None => continue, + }; + for tuning in method.tuning.iter().copied() { + match tuning { + // TODO: measure + ast::TuningDirective::MaxNReg(_) + | ast::TuningDirective::MinNCtaPerSm(_) => {} + ast::TuningDirective::MaxNtid(x, y, z) => { + let size = x as u64 * y as u64 * z as u64; + kernel_metadata.push(( + name.clone(), + None, + NonZeroU32::new(size as u32), + )); + } + ast::TuningDirective::ReqNtid(x, y, z) => { + let size = x as u64 * y as u64 * z as u64; + kernel_metadata.push(( + name.clone(), + NonZeroU32::new(size as u32), + NonZeroU32::new(size as u32), + )); + } } } - 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, - })); - } } + TranslationDirective::Variable(..) => {} } - }; - Ok(()) + } + Metadata { + sm_version: translation_module.sm_version, + kernel_metadata, + } } -// 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, - id_defs: &mut NumericIdResolver<'a>, -) -> Result, 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::>(); - 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); - } - } - } - _ => {} - } +fn insert_compilation_mode_prologue<'input>( + mut translation_module: TranslationModule<'input, ExpandedArgParams>, +) -> TranslationModule<'input, ExpandedArgParams> { + if translation_module.compilation_mode != CompilationMode::Wave32OnWave64 { + return translation_module; } - 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); + for directive in translation_module.directives.iter_mut() { + match directive { + TranslationDirective::Method(TranslationMethod { + is_kernel, + body: Some(body), + tuning, + .. + }) => { + for t in tuning.iter_mut() { + match t { + ast::TuningDirective::MaxNReg(_) + | ast::TuningDirective::MinNCtaPerSm(_) => {} + ast::TuningDirective::MaxNtid(_, _, z) => { + *z *= 2; } - } else if let (TypedOperand::Reg(dst), Some(src2)) = - (arg.dst, arg.src2.upcast().underlying()) + ast::TuningDirective::ReqNtid(_, _, z) => { + *z *= 2; + } + } + } + if !*is_kernel { + continue; + } + let old_body = mem::replace(body, Vec::new()); + let mut new_body = Vec::with_capacity(old_body.len() + 1); + // I'd rather use early exit on laneid like a normal person, + // but that leads to miscompilations, so here's the next best thing + let asm = "s_bcnt1_i32_b64 exec_lo, exec\ns_lshr_b32 exec_lo, exec_lo, 1\ns_bfm_b64 exec, exec_lo, 0"; + let constraints = "~{scc}"; + new_body.push(Statement::AsmVolatile { asm, constraints }); + new_body.extend(old_body.into_iter()); + *body = new_body; + } + TranslationDirective::Method(..) | TranslationDirective::Variable(..) => {} + } + } + translation_module +} + +// THIS PASS IS AN AWFUL HACK TO WORK AROUND LLVM BUG +// In certain situations LLVM will miscompile AMDGPU +// binaries if the return type of a function is .b8 array. +// For example, if the return of the function is float3 NVIDIA +// frontend compiler will compile it to .b8[12]. +// Turns out if the return type is a .b8 array, then LLVM will +// sometimes be unable to remove the alloca. +// Which is fine, but for some reason AMDGPU has a bug +// where it does not deallocate alloca +// Our """solution""" is to convert all b8[] into b32[] +fn restructure_function_return_types( + mut module: TranslationModule, +) -> Result, TranslateError> { + let id_defs = &mut module.id_defs; + module.directives = module + .directives + .into_iter() + .map(|directive| avoid_byte_array_returns(id_defs, directive)) + .collect::, _>>()?; + Ok(module) +} + +fn avoid_byte_array_returns<'input>( + id_defs: &mut IdNameMapBuilder<'input>, + mut directive: TranslationDirective<'input, TypedArgParams>, +) -> Result, TranslateError> { + match directive { + TranslationDirective::Method(ref mut method) => { + if !method.is_kernel { + let return_arguments = &mut method.return_arguments; + let input_arguments = &mut method.input_arguments; + for arg in return_arguments + .iter_mut() + .chain(input_arguments.iter_mut()) + { + if let ( + ast::Type::Array( + ref mut scalar_type @ ast::ScalarType::B8, + ref mut dimensions, + ), + _, + ) = (&mut arg.type_, arg.state_space) { - if regs_ptr_current.contains(src2) && !regs_ptr_seen.contains(src2) { - regs_ptr_new.insert(dst); + if dimensions.len() > 1 { + return Err(TranslateError::unexpected_pattern()); + } + *scalar_type = ast::ScalarType::B32; + dimensions[0] = div_positive_round_up(dimensions[0], 4); + id_defs.change_type( + arg.name, + ast::Type::Array(ast::ScalarType::B32, dimensions.clone()), + )?; + } + } + } + for statement in method.body.iter_mut().flatten() { + if let Statement::Call(call) = statement { + let return_arguments = &mut call.return_arguments; + let input_arguments = &mut call.input_arguments; + for (type_, space) in return_arguments + .iter_mut() + .map(|(_, t, s)| (t, s)) + .chain(input_arguments.iter_mut().map(|(_, t, s)| (t, s))) + { + if let ( + ast::Type::Array( + ref mut scalar_type @ ast::ScalarType::B8, + ref mut dimensions, + ), + _, + ) = (type_, space) + { + if dimensions.len() > 1 { + return Err(TranslateError::unexpected_pattern()); + } + *scalar_type = ast::ScalarType::B32; + dimensions[0] = div_positive_round_up(dimensions[0], 4); + } + } + } + if let Statement::Variable(Variable { + state_space: ast::StateSpace::Param, + type_: + ast::Type::Array(ref mut scalar_type @ ast::ScalarType::B8, ref mut dimensions), + .. + }) = statement + { + if dimensions.len() > 1 { + return Err(TranslateError::unexpected_pattern()); + } + *scalar_type = ast::ScalarType::B32; + dimensions[0] = div_positive_round_up(dimensions[0], 4); + } + } + Ok(directive) + } + TranslationDirective::Variable(..) => Ok(directive), + } +} + +fn div_positive_round_up(dividend: u32, divisor: u32) -> u32 { + let mut result = dividend / divisor; + if (dividend % divisor) != 0 { + result += 1; + } + result +} + +fn get_kernel_arguments( + directives: &[Directive], +) -> Result>, TranslateError> { + let mut result = FxHashMap::default(); + for directive in directives.iter() { + match directive { + Directive::Method(TranslationMethod { + is_kernel: true, + source_name, + input_arguments, + .. + }) => { + let name = match source_name { + Some(name) => name, + None => continue, + }; + let layout = input_arguments + .iter() + .map(|var| var.layout()) + .collect::>(); + result.insert(name.to_string(), layout); + } + _ => continue, + } + } + Ok(result) +} + +pub(crate) struct CallGraph { + pub(crate) all_callees: FxHashMap>, +} + +// TODO: resolve declarations +impl CallGraph { + pub(crate) fn new<'input, P: ast::ArgParams>( + module: &[TranslationDirective<'input, P>], + ) -> Self { + let mut has_body = FxHashSet::default(); + let mut direct_callees = FxHashMap::default(); + for directive in module { + match directive { + TranslationDirective::Method(TranslationMethod { + name, + body: Some(statements), + .. + }) => { + let call_key = *name; + has_body.insert(call_key); + if let hash_map::Entry::Vacant(entry) = direct_callees.entry(call_key) { + entry.insert(Vec::new()); + } + for statement in statements { + match statement { + Statement::Call(ResolvedCall { + name, + is_indirect: false, + .. + }) => { + multi_hash_map_append(&mut direct_callees, call_key, *name); + } + _ => {} } } } _ => {} } } - 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)); + let mut result = FxHashMap::default(); + for (&method_key, children) in direct_callees.iter() { + let mut visited = FxHashSet::default(); + for child in children { + if !has_body.contains(child) { + continue; } + Self::add_call_map_single(&has_body, &direct_callees, &mut visited, *child); } - 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, - 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, - 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, - 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()), + result.insert(method_key, visited); + } + CallGraph { + all_callees: result, } } - 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, - ); + + fn add_call_map_single( + has_body: &FxHashSet, + directly_called_by: &FxHashMap>, + visited: &mut FxHashSet, + current: Id, + ) { + if !visited.insert(current) { + return; + } + if let Some(children) = directly_called_by.get(¤t) { + for child in children { + if !has_body.contains(child) { + continue; + } + Self::add_call_map_single(has_body, directly_called_by, visited, *child); + } } } - Ok(result) + + fn methods(&self) -> impl Iterator)> { + self.all_callees + .iter() + .map(|(method, children)| (*method, children)) + } } -fn convert_to_stateful_memory_access_postprocess( - id_defs: &mut NumericIdResolver, - remapped_ids: &HashMap, - func_args_ptr: &HashSet, - result: &mut Vec, - post_statements: &mut Vec, - arg_desc: ArgumentDescriptor, - expected_type: Option<&ast::Type>, -) -> Result { - 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 - } +fn multi_hash_map_append< + K: Eq + std::hash::Hash, + V, + Collection: std::iter::Extend + std::default::Default, +>( + m: &mut FxHashMap, + key: K, + value: V, +) { + match m.entry(key) { + hash_map::Entry::Occupied(mut entry) => { + entry.get_mut().extend(iter::once(value)); } - 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 + hash_map::Entry::Vacant(entry) => { + entry.insert(Default::default()).extend(iter::once(value)); + } + } +} + +/* + PTX represents dynamically allocated shared local memory as + .extern .shared .b32 shared_mem[]; + In SPIRV/OpenCL world this is expressed as an additional argument to the kernel + And in AMD compilation + This pass looks for all uses of .extern .shared and converts them to + an additional method argument + The question is how this artificial argument should be expressed. There are + several options: + * Straight conversion: + .shared .b32 shared_mem[] + * Introduce .param_shared statespace: + .param_shared .b32 shared_mem + or + .param_shared .b32 shared_mem[] + * Introduce .shared_ptr type: + .param .shared_ptr .b32 shared_mem + * Reuse .ptr hint: + .param .u64 .ptr shared_mem + This is the most tempting, but also the most nonsensical, .ptr is just a + hint, which has no semantical meaning (and the output of our + transformation has a semantical meaning - we emit additional + "OpFunctionParameter ..." with type "OpTypePointer Workgroup ...") +*/ +fn convert_dynamic_shared_memory_usage<'input>( + mut module: TranslationModule<'input, ExpandedArgParams>, + kernels_methods_call_map: &CallGraph, +) -> Result, TranslateError> { + let mut globals_shared = FxHashMap::default(); + for dir in module.directives.iter() { + match dir { + Directive::Variable( + _, + _, + Variable { + state_space: ast::StateSpace::Shared, + name, + type_, + .. + }, + ) => { + globals_shared.insert(*name, type_.clone()); } - None => arg_desc.op, - }, + _ => {} + } + } + if globals_shared.len() == 0 { + return Ok(module); + } + let mut methods_to_directly_used_shared_globals = FxHashMap::<_, FxHashSet>::default(); + let remapped_directives = module + .directives + .into_iter() + .map(|directive| match directive { + Directive::Method(TranslationMethod { + return_arguments, + name, + input_arguments, + body: Some(statements), + tuning, + is_kernel, + source_name, + special_raytracing_linking: raytracing_linking, + }) => { + let call_key = name; + let statements = statements + .into_iter() + .map(|statement| { + statement.map_id(&mut |id, _| { + if globals_shared.get(&id).is_some() { + methods_to_directly_used_shared_globals + .entry(call_key) + .or_insert_with(FxHashSet::default) + .insert(id); + } + id + }) + }) + .collect(); + Directive::Method(TranslationMethod { + return_arguments, + name, + input_arguments, + body: Some(statements), + tuning, + is_kernel, + source_name, + special_raytracing_linking: raytracing_linking, + }) + } + directive => directive, + }) + .collect::>(); + // If there's a chain `kernel` -> `fn1` -> `fn2`, where only `fn2` uses extern shared, + // make sure it gets propagated to `fn1` and `kernel` + let methods_to_indirectly_used_shared_globals = resolve_indirect_uses_of_globals_shared( + methods_to_directly_used_shared_globals, + kernels_methods_call_map, + ); + // now visit every method declaration and inject those additional arguments + let mut directives = Vec::with_capacity(remapped_directives.len()); + for directive in remapped_directives.into_iter() { + match directive { + Directive::Method(TranslationMethod { + return_arguments, + name, + mut input_arguments, + body, + tuning, + is_kernel, + source_name, + special_raytracing_linking: raytracing_linking, + }) => { + let statements: Option< + Vec, ExpandedArgParams>>, + > = { + insert_arguments_remap_statements( + &mut module.id_defs.id_gen, + &globals_shared, + &methods_to_indirectly_used_shared_globals, + name, + is_kernel, + &mut input_arguments, + body, + )? + }; + directives.push(Directive::Method(TranslationMethod { + return_arguments, + name, + input_arguments, + body: statements, + tuning, + is_kernel, + source_name, + special_raytracing_linking: raytracing_linking, + })); + } + directive => directives.push(directive), + } + } + Ok(TranslationModule { + directives, + ..module }) } -fn is_add_ptr_direct(remapped_ids: &HashMap, arg: &ast::Arg3) -> bool { - match arg.dst { - TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => { - return false +fn insert_arguments_remap_statements<'input>( + new_id: &mut IdGenerator, + globals_shared: &FxHashMap, + methods_to_indirectly_used_shared_globals: &FxHashMap>, + method_name: Id, + is_kernel: bool, + input_arguments: &mut Vec>, + statements: Option, ExpandedArgParams>>>, +) -> Result< + Option, ExpandedArgParams>>>, + TranslateError, +> { + let method_globals = match methods_to_indirectly_used_shared_globals.get(&method_name) { + Some(method_globals) => method_globals, + None => return Ok(statements), + }; + let remapped_globals_in_method = method_globals + .iter() + .map(|global| { + Ok(( + *global, + ( + if is_kernel { *global } else { new_id.next() }, + globals_shared + .get(&global) + .ok_or_else(TranslateError::todo)? + .clone(), + ), + )) + }) + .collect::, _>>()?; + if !is_kernel { + for (_, (new_shared_global_id, shared_global_type)) in remapped_globals_in_method.iter() { + input_arguments.push(ast::VariableDeclaration { + align: None, + type_: shared_global_type.clone(), + state_space: ast::StateSpace::Shared, + name: *new_shared_global_id, + }); } - TypedOperand::Reg(dst) => { - if !remapped_ids.contains_key(&dst) { - return false; + } + Ok(statements.map(|statements| { + replace_uses_of_shared_memory( + methods_to_indirectly_used_shared_globals, + statements, + remapped_globals_in_method, + ) + })) +} + +fn replace_uses_of_shared_memory<'input>( + methods_to_indirectly_used_shared_globals: &FxHashMap>, + statements: Vec, + remapped_globals_in_method: BTreeMap, +) -> Vec { + let mut result = Vec::with_capacity(statements.len()); + 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 let Some(shared_globals_used_by_callee) = + methods_to_indirectly_used_shared_globals.get(&call.name) + { + for &shared_global_used_by_callee in shared_globals_used_by_callee { + let (remapped_shared_id, type_) = remapped_globals_in_method + .get(&shared_global_used_by_callee) + .unwrap_or_else(|| todo!()); + call.input_arguments.push(( + *remapped_shared_id, + type_.clone(), + ast::StateSpace::Shared, + )); + } + } + result.push(Statement::Call(call)) } - match arg.src1.upcast().underlying() { - Some(src1) if remapped_ids.contains_key(src1) => true, - Some(src2) if remapped_ids.contains_key(src2) => true, - _ => false, + statement => { + let new_statement = statement.map_id(&mut |id, _| { + if let Some((remapped_shared_id, _)) = remapped_globals_in_method.get(&id) { + *remapped_shared_id + } else { + id + } + }); + result.push(new_statement); } } } + result +} + +// We need to compute two kinds of information: +// * If it's a kernel -> size of .shared globals in use (direct or indirect) +// * If it's a function -> does it use .shared global (directly or indirectly) +fn resolve_indirect_uses_of_globals_shared<'input>( + methods_use_of_globals_shared: FxHashMap>, + kernels_methods_call_map: &CallGraph, +) -> FxHashMap> { + let mut result = FxHashMap::default(); + for (method, callees) in kernels_methods_call_map.methods() { + let mut indirect_globals = methods_use_of_globals_shared + .get(&method) + .into_iter() + .flatten() + .copied() + .collect::>(); + for &callee in callees { + indirect_globals.extend( + methods_use_of_globals_shared + .get(&callee) + .into_iter() + .flatten() + .copied(), + ); + } + result.insert(method, indirect_globals); + } + result +} + +struct SpecialRegisterResolver<'a, 'input> { + id_defs: &'a mut IdNameMapBuilder<'input>, + ptx_imports: &'a mut AdditionalFunctionDeclarations, + result: Vec, +} + +impl<'a, 'input> SpecialRegisterResolver<'a, 'input> { + fn replace_sreg( + &mut self, + desc: ArgumentDescriptor, + vector_index: Option, + ) -> Result { + if let Some(sreg) = self.id_defs.globals.special_registers.get(desc.op) { + if desc.is_dst { + return Err(TranslateError::mismatched_type()); + } + let input_arguments = match (vector_index, sreg.get_function_input_type()) { + (Some(idx), Some(inp_type)) => { + if inp_type != ast::ScalarType::U8 { + return Err(TranslateError::unreachable()); + } + let constant = self.id_defs.register_intermediate(Some(( + ast::Type::Scalar(inp_type), + ast::StateSpace::Reg, + ))); + self.result.push(Statement::Constant(ConstantDefinition { + dst: constant, + typ: inp_type, + value: ast::ImmediateValue::U64(idx as u64), + })); + vec![( + TypedOperand::Reg(constant), + ast::Type::Scalar(inp_type), + ast::StateSpace::Reg, + )] + } + (None, None) => Vec::new(), + _ => return Err(TranslateError::mismatched_type()), + }; + let ocl_fn_name = [ZLUDA_PTX_PREFIX, sreg.get_unprefixed_function_name()].concat(); + let return_type = sreg.get_function_return_type(); + let fn_result = self.id_defs.register_intermediate(Some(( + ast::Type::Scalar(return_type), + ast::StateSpace::Reg, + ))); + let return_arguments = vec![( + fn_result, + ast::Type::Scalar(return_type), + ast::StateSpace::Reg, + )]; + let fn_call = self.ptx_imports.add_or_get_declaration( + self.id_defs, + ocl_fn_name.to_string(), + return_arguments.iter().map(|(_, typ, space)| (typ, *space)), + input_arguments.iter().map(|(_, typ, space)| (typ, *space)), + )?; + self.result.push(Statement::Call(ResolvedCall { + uniform: false, + return_arguments, + name: fn_call, + input_arguments, + is_indirect: false, + })); + Ok(fn_result) + } else { + Ok(desc.op) + } + } } -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, +impl<'a, 'input> ArgumentMapVisitor + for SpecialRegisterResolver<'a, 'input> +{ + fn id( + &mut self, + desc: ArgumentDescriptor, + _: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + self.replace_sreg(desc, None) } + + fn operand( + &mut self, + desc: ArgumentDescriptor, + _typ: &ast::Type, + _state_space: ast::StateSpace, + ) -> Result { + Ok(match desc.op { + TypedOperand::Reg(reg) => TypedOperand::Reg(self.replace_sreg(desc.new_op(reg), None)?), + op @ TypedOperand::RegOffset(_, _) => op, + op @ TypedOperand::Imm(_) => op, + TypedOperand::VecMember(reg, idx) => { + TypedOperand::VecMember(self.replace_sreg(desc.new_op(reg), Some(idx))?, idx) + } + }) + } +} + +fn extract_global_cvt<'input>( + local: &mut Vec, + ptx_impl_imports: &mut AdditionalFunctionDeclarations, + id_def: &mut IdNameMapBuilder<'input>, + desc: ast::CvtDesc, + inst: ast::Instruction, +) -> Result<(), TranslateError> { + let fn_name = [ + ZLUDA_PTX_PREFIX, + "cvt_", + rounding_to_ptx_name(desc.rounding), + "_", + desc.dst.to_ptx_name(), + "_", + desc.src.to_ptx_name(), + ] + .concat(); + local.push(instruction_to_fn_call( + id_def, + ptx_impl_imports, + inst, + fn_name, + )?); + Ok(()) +} + +fn rounding_to_ptx_name(this: Option) -> &'static str { + match this { + None | Some(ast::RoundingMode::NearestEven) => "rn", + Some(ast::RoundingMode::Zero) => "rz", + Some(ast::RoundingMode::NegativeInf) => "rm", + Some(ast::RoundingMode::PositiveInf) => "rp", + } +} + +impl ast::AtomSemantics { + fn to_ptx_name(self) -> &'static str { + match self { + ast::AtomSemantics::Relaxed => "relaxed", + ast::AtomSemantics::Acquire => "acquire", + ast::AtomSemantics::Release => "release", + ast::AtomSemantics::AcquireRelease => "acq_rel", + } + } +} + +impl ast::MemScope { + fn to_ptx_name(self) -> &'static str { + match self { + ast::MemScope::Cta => "cta", + ast::MemScope::Gpu => "gpu", + ast::MemScope::Sys => "sys", + } + } +} + +impl ast::StateSpace { + fn to_ptx_name(self) -> &'static str { + match self { + ast::StateSpace::Generic => "generic", + ast::StateSpace::Global => "global", + ast::StateSpace::Shared => "shared", + ast::StateSpace::Reg => "reg", + ast::StateSpace::Const => "const", + ast::StateSpace::Local => "local", + ast::StateSpace::Param => "param", + ast::StateSpace::Sreg => "sreg", + } + } +} + +impl ast::ShflMode { + fn to_ptx_name(self) -> &'static str { + match self { + ast::ShflMode::Up => "up", + ast::ShflMode::Down => "down", + ast::ShflMode::Bfly => "bfly", + ast::ShflMode::Idx => "idx", + } + } +} +struct VectorRepackVisitor<'a, 'input, V> { + extra_vistor: &'a mut V, + func: &'a mut Vec, + id_def: &'a mut IdNameMapBuilder<'input>, + post_stmts: Option, +} + +impl<'a, 'input, V> VectorRepackVisitor<'a, 'input, V> { + fn new( + extra_vistor: &'a mut V, + func: &'a mut Vec, + id_def: &'a mut IdNameMapBuilder<'input>, + ) -> Self { + VectorRepackVisitor { + extra_vistor, + func, + id_def, + post_stmts: None, + } + } + + fn convert_vector( + &mut self, + is_dst: bool, + non_default_implicit_conversion: Option< + fn( + (ast::StateSpace, &ast::Type), + (ast::StateSpace, &ast::Type), + ) -> Result, TranslateError>, + >, + typ: &ast::Type, + state_space: ast::StateSpace, + idx: Vec>, + ) -> Result { + let scalar_t = match typ { + // mov.v2.u32 foobar, {a,b}; + ast::Type::Vector(scalar_t, _) => *scalar_t, + // mov.b64 foobar, {a,b}; + ast::Type::Scalar(scalar_t) => { + if scalar_t.kind() == ast::ScalarKind::Bit { + let total_size_of = scalar_t.size_of() as usize; + let scalar_size_of = total_size_of / idx.len(); + if idx.len() * scalar_size_of == total_size_of { + ast::ScalarType::from_parts(scalar_size_of as u8, ast::ScalarKind::Bit) + } else { + return Err(TranslateError::mismatched_type()); + } + } else { + return Err(TranslateError::mismatched_type()); + } + } + _ => return Err(TranslateError::mismatched_type()), + }; + let temp_vec = self + .id_def + .register_intermediate(Some((typ.clone(), state_space))); + let vector_members = idx + .into_iter() + .map(|vector_member| match vector_member { + ast::RegOrImmediate::Reg(reg) => reg, + ast::RegOrImmediate::Imm(immediate) => { + let (id, statement) = FlattenArguments::immediate_impl( + self.id_def, + immediate, + &ast::Type::Scalar(scalar_t), + ast::StateSpace::Reg, + ); + self.func.push(statement); + id + } + }) + .collect::>(); + let statement = Statement::RepackVector(RepackVectorDetails { + is_extract: is_dst, + typ: scalar_t, + packed: temp_vec, + unpacked: vector_members, + non_default_implicit_conversion, + }); + if is_dst { + self.post_stmts = Some(statement); + } else { + self.func.push(statement); + } + Ok(temp_vec) + } +} + +impl<'a, 'b, V: ArgumentMapVisitor> + ArgumentMapVisitor for VectorRepackVisitor<'a, 'b, V> +{ + fn id( + &mut self, + desc: ArgumentDescriptor, + type_: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + self.extra_vistor.id(desc, type_) + } + + fn operand( + &mut self, + desc: ArgumentDescriptor>, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> Result { + Ok(match desc.op { + ast::Operand::Reg(reg) => { + self.extra_vistor + .operand(desc.new_op(TypedOperand::Reg(reg)), typ, state_space)? + } + 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.non_default_implicit_conversion, + typ, + state_space, + vec, + )?), + }) + } +} + +fn instruction_to_fn_call<'input>( + id_defs: &mut IdNameMapBuilder, + ptx_impl_imports: &mut AdditionalFunctionDeclarations, + inst: ast::Instruction, + fn_name: String, +) -> Result { + let mut arguments = Vec::new(); + inst.visit( + &mut |desc: ArgumentDescriptor, typ: Option<(&ast::Type, ast::StateSpace)>| { + let (typ, space) = match typ { + Some((typ, space)) => (typ.clone(), space), + None => return Err(TranslateError::unreachable()), + }; + let result = desc.op; + arguments.push((desc, typ, space)); + Ok(result) + }, + )?; + let return_arguments_count = arguments + .iter() + .position(|(desc, _, _)| !desc.is_dst) + .unwrap_or(arguments.len()); + let (return_arguments, input_arguments) = arguments.split_at(return_arguments_count); + let fn_id = ptx_impl_imports.add_or_get_declaration( + id_defs, + fn_name, + return_arguments.iter().map(|(_, typ, state)| (typ, *state)), + input_arguments.iter().map(|(_, typ, state)| (typ, *state)), + )?; + Ok(Statement::Call(ResolvedCall { + uniform: false, + name: fn_id, + return_arguments: arguments_to_resolved_arguments(return_arguments), + input_arguments: arguments_to_resolved_arguments(input_arguments), + is_indirect: false, + })) +} + +fn fn_arguments_to_variables<'a>( + id_defs: &mut IdNameMapBuilder, + args: impl Iterator, +) -> Vec> { + args.map(|(typ, space)| ast::VariableDeclaration { + align: None, + type_: typ.clone(), + state_space: space, + name: id_defs.register_intermediate(None), + }) + .collect::>() +} + +fn arguments_to_resolved_arguments( + args: &[(ArgumentDescriptor, ast::Type, ast::StateSpace)], +) -> Vec<(Id, ast::Type, ast::StateSpace)> { + args.iter() + .map(|(desc, typ, space)| (desc.op, typ.clone(), *space)) + .collect::>() +} + +fn insert_mem_ssa_argument<'input>( + id_def: &mut IdNameMapBuilder<'input>, + func: &mut Vec, + arg: &mut ast::VariableDeclaration, +) { + let new_id = id_def.register_intermediate(Some((arg.type_.clone(), arg.state_space))); + func.push(Statement::Variable(Variable { + align: arg.align, + type_: arg.type_.clone(), + state_space: ast::StateSpace::Reg, + name: arg.name, + initializer: None, + })); + func.push(Statement::StoreVar(StoreVarDetails { + arg: ast::Arg2St { + src1: arg.name, + src2: new_id, + }, + type_: arg.type_.clone(), + member_index: None, + })); + arg.name = new_id; +} + +fn insert_mem_ssa_argument_reg_return( + func: &mut Vec, + arg: &ast::VariableDeclaration, +) { + func.push(Statement::Variable(Variable { + align: arg.align, + type_: arg.type_.clone(), + state_space: arg.state_space, + name: arg.name, + initializer: None, + })); +} + +pub(crate) trait Visitable: Sized { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, To>, TranslateError>; +} + +struct VisitArgumentDescriptor< + 'a, + Ctor: FnOnce(Id) -> Statement, U>, + U: ArgParamsEx, +> { + desc: ArgumentDescriptor, + typ: &'a ast::Type, + state_space: ast::StateSpace, + stmt_ctor: Ctor, +} + +impl< + 'a, + Ctor: FnOnce(Id) -> Statement, U>, + T: ArgParamsEx, + U: ArgParamsEx, + > Visitable for VisitArgumentDescriptor<'a, Ctor, U> +{ + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok((self.stmt_ctor)( + visitor.id(self.desc, Some((self.typ, self.state_space)))?, + )) + } +} + +struct InsertMemSSAVisitor<'a, 'input> { + id_def: &'a mut IdNameMapBuilder<'input>, + func: &'a mut Vec, + post_statements: Vec, +} + +impl<'a, 'input> InsertMemSSAVisitor<'a, 'input> { + fn symbol( + &mut self, + desc: ArgumentDescriptor<(Id, Option)>, + expected: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + let symbol = desc.op.0; + if expected.is_none() { + return Ok(symbol); + }; + let (mut var_type, var_space, _, is_variable) = self.id_def.get_typed(symbol)?; + if !var_space.is_compatible(ast::StateSpace::Reg) || !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::mismatched_type()), + }; + Some((idx, vector_width)) + } + None => None, + }; + let generated_id = self + .id_def + .register_intermediate(Some((var_type.clone(), ast::StateSpace::Reg))); + if !desc.is_dst { + self.func.push(Statement::LoadVar(LoadVarDetails { + arg: Arg2 { + dst: generated_id, + src: symbol, + }, + _state_space: ast::StateSpace::Reg, + typ: var_type, + member_index, + })); + } else { + let (type_, member_index) = match member_index { + None => (var_type, None), + Some((idx, width)) => { + if let ast::Type::Scalar(scalar) = var_type { + (ast::Type::Vector(scalar, width), Some(idx)) + } else { + return Err(TranslateError::unreachable()); + } + } + }; + self.post_statements + .push(Statement::StoreVar(StoreVarDetails { + arg: Arg2St { + src1: symbol, + src2: generated_id, + }, + type_, + member_index, + })); + } + Ok(generated_id) + } +} + +impl<'a, 'input> ArgumentMapVisitor + for InsertMemSSAVisitor<'a, 'input> +{ + fn id( + &mut self, + desc: ArgumentDescriptor, + typ: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + self.symbol(desc.new_op((desc.op, None)), typ) + } + + fn operand( + &mut self, + desc: ArgumentDescriptor, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> Result { + Ok(match desc.op { + TypedOperand::Reg(reg) => { + TypedOperand::Reg(self.symbol(desc.new_op((reg, None)), Some((typ, state_space)))?) + } + TypedOperand::RegOffset(reg, offset) => TypedOperand::RegOffset( + self.symbol(desc.new_op((reg, None)), Some((typ, state_space)))?, + offset, + ), + op @ TypedOperand::Imm(..) => op, + TypedOperand::VecMember(symbol, index) => TypedOperand::Reg( + self.symbol(desc.new_op((symbol, Some(index))), Some((typ, state_space)))?, + ), + }) + } +} + +fn insert_mem_ssa_statement_default<'a, 'input, S: Visitable>( + id_def: &'a mut IdNameMapBuilder<'input>, + func: &'a mut Vec, + 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(()) +} + +struct FlattenArguments<'a, 'input, I, P: ast::ArgParams> { + func: &'a mut Vec>, + id_def: &'a mut IdNameMapBuilder<'input>, + post_stmts: Vec>, +} + +impl<'a, 'input, I, P: ast::ArgParams> FlattenArguments<'a, 'input, I, P> { + fn new(func: &'a mut Vec>, id_def: &'a mut IdNameMapBuilder<'input>) -> Self { + FlattenArguments { + func, + id_def, + post_stmts: Vec::new(), + } + } + + fn reg( + &mut self, + desc: ArgumentDescriptor, + _: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + Ok(desc.op) + } + + fn immediate( + &mut self, + desc: ArgumentDescriptor, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> Result { + let (id, statement) = Self::immediate_impl(self.id_def, desc.op, typ, state_space); + self.func.push(statement); + Ok(id) + } + + fn immediate_impl( + id_def: &mut IdNameMapBuilder<'input>, + immediate: ast::ImmediateValue, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> (Id, Statement) { + let scalar_t = if let ast::Type::Scalar(scalar) = typ { + *scalar + } else { + todo!() + }; + let id = id_def.register_intermediate(Some((ast::Type::Scalar(scalar_t), state_space))); + ( + id, + Statement::Constant(ConstantDefinition { + dst: id, + typ: scalar_t, + value: immediate, + }), + ) + } +} + +impl<'a, 'b> FlattenArguments<'a, 'b, ast::Instruction, ExpandedArgParams> { + fn reg_offset( + &mut self, + desc: ArgumentDescriptor<(Id, i64)>, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> Result { + let (reg, offset) = desc.op; + if !desc.is_memory_access { + let (reg_type, reg_space, ..) = self.id_def.get_typed(reg)?; + if !reg_space.is_compatible(ast::StateSpace::Reg) { + return Err(TranslateError::mismatched_type()); + } + let reg_scalar_type = match reg_type { + ast::Type::Scalar(underlying_type) => underlying_type, + _ => return Err(TranslateError::mismatched_type()), + }; + let id_constant_stmt = self + .id_def + .register_intermediate(Some((reg_type.clone(), ast::StateSpace::Reg))); + self.func.push(Statement::Constant(ConstantDefinition { + dst: id_constant_stmt, + typ: reg_scalar_type, + value: ast::ImmediateValue::S64(offset), + })); + let arith_details = match reg_scalar_type.kind() { + ast::ScalarKind::Signed => ast::ArithDetails::Signed(ast::ArithSInt { + typ: reg_scalar_type, + saturate: false, + }), + ast::ScalarKind::Unsigned | ast::ScalarKind::Bit => { + ast::ArithDetails::Unsigned(reg_scalar_type) + } + _ => return Err(TranslateError::unreachable()), + }; + let id_add_result = self + .id_def + .register_intermediate(Some((reg_type, state_space))); + self.func.push(Statement::Instruction(ast::Instruction::Add( + arith_details, + ast::Arg3 { + dst: id_add_result, + src1: reg, + src2: id_constant_stmt, + }, + ))); + Ok(id_add_result) + } else { + let id_constant_stmt = self.id_def.register_intermediate(Some(( + ast::Type::Scalar(ast::ScalarType::S64), + ast::StateSpace::Reg, + ))); + self.func.push(Statement::Constant(ConstantDefinition { + dst: id_constant_stmt, + typ: ast::ScalarType::S64, + value: ast::ImmediateValue::S64(offset), + })); + let dst = self + .id_def + .register_intermediate(Some((typ.clone(), state_space))); + self.func.push(Statement::PtrAccess(PtrAccess { + underlying_type: typ.clone(), + state_space: state_space, + dst, + ptr_src: reg, + offset_src: id_constant_stmt, + })); + Ok(dst) + } + } +} + +impl<'a, 'b> ArgumentMapVisitor + for FlattenArguments<'a, 'b, ast::Instruction, ExpandedArgParams> +{ + fn id( + &mut self, + desc: ArgumentDescriptor, + t: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { + self.reg(desc, t) + } + + fn operand( + &mut self, + desc: ArgumentDescriptor, + typ: &ast::Type, + state_space: ast::StateSpace, + ) -> Result { + match desc.op { + TypedOperand::Reg(r) => self.reg(desc.new_op(r), Some((typ, state_space))), + TypedOperand::Imm(x) => self.immediate(desc.new_op(x), typ, state_space), + TypedOperand::RegOffset(reg, offset) => { + self.reg_offset(desc.new_op((reg, offset)), typ, state_space) + } + TypedOperand::VecMember(..) => Err(TranslateError::unreachable()), + } + } +} + +fn insert_implicit_conversions_impl( + func: &mut Vec, + id_def: &mut IdNameMapBuilder, + stmt: impl Visitable, +) -> Result<(), TranslateError> { + let mut post_conv = Vec::new(); + let statement = + stmt.visit(&mut |desc: ArgumentDescriptor, + typ: Option<(&ast::Type, ast::StateSpace)>| { + let (instr_type, instruction_space) = match typ { + None => return Ok(desc.op), + Some(t) => t, + }; + let (operand_type, operand_space, ..) = id_def.get_typed(desc.op)?; + let conversion_fn = desc + .non_default_implicit_conversion + .unwrap_or(default_implicit_conversion); + match conversion_fn( + (operand_space, &operand_type), + (instruction_space, instr_type), + )? { + Some(conv_kind) => { + let conv_output = if desc.is_dst { + &mut post_conv + } else { + &mut *func + }; + let mut from_type = instr_type.clone(); + let mut from_space = instruction_space; + let mut to_type = operand_type; + let mut to_space = operand_space; + let mut src = + id_def.register_intermediate(Some((instr_type.clone(), instruction_space))); + let mut dst = desc.op; + let result = Ok(src); + if !desc.is_dst { + mem::swap(&mut src, &mut dst); + mem::swap(&mut from_type, &mut to_type); + mem::swap(&mut from_space, &mut to_space); + } + conv_output.push(Statement::Conversion(ImplicitConversion { + src, + dst, + from_type, + from_space, + to_type, + to_space, + kind: conv_kind, + })); + result + } + None => Ok(desc.op), + } + })?; + func.push(statement); + func.append(&mut post_conv); + Ok(()) } #[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone)] enum PtxSpecialRegister { Tid, - Tid64, Ntid, - Ntid64, Ctaid, - Ctaid64, Nctaid, - Nctaid64, + Clock, + LanemaskLt, + LanemaskLe, + LanemaskGe, + Laneid, + Clock64, } impl PtxSpecialRegister { @@ -4714,100 +4955,94 @@ impl PtxSpecialRegister { "%ntid" => Some(Self::Ntid), "%ctaid" => Some(Self::Ctaid), "%nctaid" => Some(Self::Nctaid), + "%clock" => Some(Self::Clock), + "%lanemask_lt" => Some(Self::LanemaskLt), + "%lanemask_le" => Some(Self::LanemaskLe), + "%lanemask_ge" => Some(Self::LanemaskGe), + "%laneid" => Some(Self::Laneid), + "%clock64" => Some(Self::Clock64), _ => 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), + PtxSpecialRegister::Tid + | PtxSpecialRegister::Ntid + | PtxSpecialRegister::Ctaid + | PtxSpecialRegister::Nctaid => ast::Type::Vector(self.get_function_return_type(), 4), + _ => ast::Type::Scalar(self.get_function_return_type()), } } - fn get_builtin(self) -> spirv::BuiltIn { + fn get_function_return_type(self) -> ast::ScalarType { 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 - } + PtxSpecialRegister::Tid + | PtxSpecialRegister::Ntid + | PtxSpecialRegister::Ctaid + | PtxSpecialRegister::Nctaid + | PtxSpecialRegister::Clock + | PtxSpecialRegister::LanemaskLt + | PtxSpecialRegister::LanemaskLe + | PtxSpecialRegister::LanemaskGe + | PtxSpecialRegister::Laneid => ast::ScalarType::U32, + PtxSpecialRegister::Clock64 => ast::ScalarType::U64, } } - fn normalized_sreg_and_type(self) -> Option<(PtxSpecialRegister, ast::ScalarType, u8)> { + fn get_function_input_type(self) -> Option { 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, + PtxSpecialRegister::Tid + | PtxSpecialRegister::Ntid + | PtxSpecialRegister::Ctaid + | PtxSpecialRegister::Nctaid => Some(ast::ScalarType::U8), + PtxSpecialRegister::Clock + | PtxSpecialRegister::Clock64 + | PtxSpecialRegister::LanemaskLt + | PtxSpecialRegister::LanemaskLe + | PtxSpecialRegister::LanemaskGe + | PtxSpecialRegister::Laneid => None, + } + } + + fn get_unprefixed_function_name(self) -> &'static str { + match self { + PtxSpecialRegister::Tid => "sreg_tid", + PtxSpecialRegister::Ntid => "sreg_ntid", + PtxSpecialRegister::Ctaid => "sreg_ctaid", + PtxSpecialRegister::Nctaid => "sreg_nctaid", + PtxSpecialRegister::Clock => "sreg_clock", + PtxSpecialRegister::Clock64 => "sreg_clock64", + PtxSpecialRegister::LanemaskLt => "sreg_lanemask_lt", + PtxSpecialRegister::LanemaskLe => "sreg_lanemask_le", + PtxSpecialRegister::LanemaskGe => "sreg_lanemask_ge", + PtxSpecialRegister::Laneid => "sreg_laneid", } } } struct SpecialRegistersMap { - reg_to_id: HashMap, - id_to_reg: HashMap, + reg_to_id: FxHashMap, + id_to_reg: FxHashMap, } impl SpecialRegistersMap { fn new() -> Self { SpecialRegistersMap { - reg_to_id: HashMap::new(), - id_to_reg: HashMap::new(), + reg_to_id: FxHashMap::default(), + id_to_reg: FxHashMap::default(), } } - fn builtins<'a>(&'a self) -> impl Iterator + '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 { - self.reg_to_id - .iter() - .filter_map(|(sreg, id)| { - if sreg.normalized_sreg_and_type().is_none() { - Some(*id) - } else { - None - } - }) - .collect::>() - } - - fn get(&self, id: spirv::Word) -> Option { + fn get(&self, id: Id) -> Option { self.id_to_reg.get(&id).copied() } - fn get_or_add(&mut self, current_id: &mut spirv::Word, reg: PtxSpecialRegister) -> spirv::Word { + fn get_or_add(&mut self, id_gen: &mut IdGenerator, reg: PtxSpecialRegister) -> Id { 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; + let numeric_id = id_gen.next(); e.insert(numeric_id); self.id_to_reg.insert(numeric_id, reg); numeric_id @@ -4816,278 +5051,541 @@ impl SpecialRegistersMap { } } -struct GlobalStringIdResolver<'input> { - current_id: spirv::Word, - variables: HashMap, spirv::Word>, - variables_type_check: HashMap>, - special_registers: SpecialRegistersMap, - fns: HashMap, +#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Id(NonZeroU32); + +impl Id { + pub(crate) fn get(self) -> u32 { + self.0.get() + } } -pub struct FnDecl { - ret_vals: Vec, - params: Vec, +pub(crate) struct IdGenerator { + pub(crate) next: NonZeroU32, } -impl<'a> GlobalStringIdResolver<'a> { - fn new(start_id: spirv::Word) -> Self { +impl IdGenerator { + pub(crate) fn new() -> Self { Self { - current_id: start_id, - variables: HashMap::new(), - variables_type_check: HashMap::new(), - special_registers: SpecialRegistersMap::new(), - fns: HashMap::new(), + next: unsafe { NonZeroU32::new_unchecked(1) }, } } - fn get_or_add_def(&mut self, id: &'a str) -> spirv::Word { - self.get_or_add_impl(id, None) + pub(crate) fn next(&mut self) -> Id { + self.reserve(1).next().unwrap() } - 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))) + // Returns first reserved id + pub(crate) fn reserve(&mut self, count: usize) -> impl ExactSizeIterator + Clone { + let value = self.next.get(); + unsafe { + self.next = NonZeroU32::new_unchecked(value + count as u32); + let start = Id(NonZeroU32::new_unchecked(value)); + let end = Id(self.next); + (start.0.get()..end.0.get()).map(|i| Id(NonZeroU32::new_unchecked(i))) + } } +} - 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 - } +pub(crate) struct IdNameMapBuilder<'input> { + pub(crate) id_gen: IdGenerator, + type_check: FxHashMap, bool)>>, + pub(crate) globals: GlobalsResolver<'input>, +} + +impl<'input> IdNameMapBuilder<'input> { + pub(crate) fn new(id_gen: IdGenerator) -> Self { + let globals = GlobalsResolver { + variables: FxHashMap::default(), + reverse_variables: FxHashMap::default(), + special_registers: SpecialRegistersMap::new(), + function_prototypes: FxHashMap::default(), }; - self.variables_type_check.insert(id, typ); + Self { + id_gen, + globals, + type_check: FxHashMap::default(), + } + } + + pub(crate) fn get_or_add_non_variable>>(&mut self, id: T) -> Id { + self.get_or_add_impl(id.into(), None) + } + + fn get_or_add_impl( + &mut self, + name: Cow<'input, str>, + type_: Option<(ast::Type, ast::StateSpace, Option)>, + ) -> Id { + let id = self.globals.get_or_add_impl(&mut self.id_gen, name.clone()); + if cfg!(debug_assertions) { + eprintln!("{}: {}", id.get(), name.to_owned()); + } + self.type_check + .insert(id, type_.map(|(t, ss, align)| (t, ss, align, true))); id } - fn get_id(&self, id: &str) -> Result { - 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, spirv::Word>, - fns: &'a HashMap, -} - -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, spirv::Word>, - global_type_check: &'b HashMap>, - special_registers: &'b mut SpecialRegistersMap, - variables: Vec, spirv::Word>>, - type_check: HashMap>, -} - -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 { - 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, 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( + pub(crate) fn register_intermediate( &mut self, - base_id: &'a str, - count: u32, - typ: ast::Type, - is_variable: bool, - ) -> impl Iterator { - 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))); + typ: Option<(ast::Type, ast::StateSpace)>, + ) -> Id { + let new_id = self.id_gen.next(); + self.type_check + .insert(new_id, typ.map(|(t, space)| (t, space, None, false))); + new_id + } + + // This is for identifiers which will be emitted later as OpVariable + // They are candidates for insertion of LoadVar/StoreVar + pub(crate) fn register_variable_decl( + &mut self, + align: Option, + type_: ast::Type, + state_space: ast::StateSpace, + ) -> ast::VariableDeclaration { + let name = self.id_gen.next(); + self.type_check + .insert(name, Some((type_.clone(), state_space, align, true))); + ast::VariableDeclaration { + align, + type_, + state_space, + name, } - *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>, - type_check: HashMap>, - special_registers: &'b mut SpecialRegistersMap, -} - -impl<'b> NumericIdResolver<'b> { - fn finish(self) -> MutableNumericIdResolver<'b> { - MutableNumericIdResolver { base: self } + pub(crate) fn register_variable_def( + &mut self, + align: Option, + type_: ast::Type, + state_space: ast::StateSpace, + initializer: Option>, + ) -> Variable { + let name = self.id_gen.next(); + self.type_check + .insert(name, Some((type_.clone(), state_space, align, true))); + Variable { + name, + align, + type_, + state_space, + initializer, + } } - fn get_typed(&self, id: spirv::Word) -> Result<(ast::Type, bool), TranslateError> { + pub(crate) fn get_typed( + &self, + id: Id, + ) -> Result<(ast::Type, ast::StateSpace, Option, 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(None) => Err(TranslateError::untyped_symbol()), + None => match self.globals.special_registers.get(id) { + Some(x) => Ok((x.get_type(), ast::StateSpace::Sreg, None, true)), + None => match self.type_check.get(&id) { Some(Some(result)) => Ok(result.clone()), - Some(None) | None => Err(TranslateError::UntypedSymbol), + Some(None) | None => Err(TranslateError::untyped_symbol()), }, }, } } - // 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) -> 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 + fn change_type(&mut self, id: Id, new_type: ast::Type) -> Result<(), TranslateError> { + Ok(match self.type_check.get_mut(&id) { + Some(Some((type_, ..))) => { + *type_ = new_type; + } + _ => return Err(TranslateError::unreachable()), + }) } } -struct MutableNumericIdResolver<'b> { - base: NumericIdResolver<'b>, +pub(crate) struct GlobalsResolver<'input> { + // Thos two fields below are only used by raytracing + // TODO: move to raytracing-specific structures + pub(crate) variables: FxHashMap, Id>, + pub(crate) reverse_variables: FxHashMap>, + special_registers: SpecialRegistersMap, + pub(crate) function_prototypes: FxHashMap, } -impl<'b> MutableNumericIdResolver<'b> { - fn unmut(self) -> NumericIdResolver<'b> { - self.base - } - - fn get_typed(&self, id: spirv::Word) -> Result { - 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)) +impl<'input> GlobalsResolver<'input> { + fn get_or_add_impl(&mut self, id_gen: &mut IdGenerator, id: Cow<'input, str>) -> Id { + let id = match self.variables.entry(id) { + hash_map::Entry::Occupied(e) => *(e.get()), + hash_map::Entry::Vacant(e) => { + let new_id = id_gen.next(); + self.reverse_variables.insert(new_id, e.key().clone()); + e.insert(new_id); + new_id + } + }; + id } } -enum Statement { - Label(u32), - Variable(ast::Variable), +pub struct Callprototype { + pub return_arguments: Vec<(ast::Type, ast::StateSpace)>, + pub input_arguments: Vec<(ast::Type, ast::StateSpace)>, +} + +pub(crate) struct StringIdResolver<'a, 'input> { + module: &'a mut IdNameMapBuilder<'input>, + scopes: Vec, Id>>, +} + +impl<'a, 'input> StringIdResolver<'a, 'input> { + fn new>( + module_resolver: &'a mut IdNameMapBuilder<'input>, + existing_directives: &[TranslationDirective<'input, P>], + ) -> Result { + let mut result = Self { + module: module_resolver, + scopes: vec![FxHashMap::default(), FxHashMap::default()], + }; + for directive in existing_directives { + match directive { + TranslationDirective::Variable(..) => return Err(TranslateError::unreachable()), + TranslationDirective::Method(method) => { + let string_name = result + .module + .globals + .reverse_variables + .get(&method.name) + .ok_or_else(TranslateError::unreachable)?; + result.scopes[StringIdResolverScope::IMPLICIT_GLOBALS] + .insert(string_name.clone(), method.name); + } + } + } + Ok(result) + } + + fn start_module<'b>(&'b mut self) -> StringIdResolverScope<'a, 'b, 'input> { + self.scopes.push(FxHashMap::default()); + StringIdResolverScope(self) + } +} + +pub(crate) struct StringIdResolverScope<'a, 'b, 'input>(&'b mut StringIdResolver<'a, 'input>); + +impl<'a, 'b, 'input> StringIdResolverScope<'a, 'b, 'input> { + // Items with visible, weak, etc. visibility. Accessible only by items + // taking part in cross-module linking (so items with visible, weak, etc. visibility) + const CROSS_MODULE: usize = 0; + // Some items are not explicitly declared, but are anyway visible inside a module. + // Currently this is the scope for raytracing function declarations + // TOOD: refactor special registers (activemask, etc.) to use this scope + const IMPLICIT_GLOBALS: usize = 1; + const CURRENT_MODULE: usize = 2; + + fn start_scope<'x>(&'x mut self) -> StringIdResolverScope<'a, 'x, 'input> { + self.0.scopes.push(FxHashMap::default()); + StringIdResolverScope(self.0) + } + + fn get_id_in_module_scope(&self, name: &str) -> Result { + self.0.scopes[Self::CURRENT_MODULE] + .get(name) + .copied() + .ok_or_else(TranslateError::unknown_symbol) + } + + fn get_id_in_function_scopes(&self, name: &str) -> Result { + let func_scopes_count = self.0.scopes.len() - (Self::CURRENT_MODULE + 1); + self.0 + .scopes + .iter() + .rev() + .take(func_scopes_count) + .find_map(|scope| scope.get(name)) + .copied() + .ok_or_else(TranslateError::unknown_symbol) + } + + fn get_id_in_module_scopes(&mut self, name: &str) -> Result { + // Scope 0 is global scope + let func_scopes_count = self.0.scopes.len() - (Self::CROSS_MODULE + 1); + PtxSpecialRegister::try_parse(name) + .map(|sreg| { + self.0 + .module + .globals + .special_registers + .get_or_add(&mut self.0.module.id_gen, sreg) + }) + .or_else(|| { + self.0 + .scopes + .iter() + .rev() + .take(func_scopes_count) + .find_map(|scope| scope.get(name)) + .copied() + }) + .ok_or_else(TranslateError::unknown_symbol) + } + + fn add_or_get_at_module_level( + &mut self, + name: &'input str, + use_global_scope: bool, + ) -> Result { + debug_assert!(self.0.scopes.len() == 3); + if self.0.scopes[Self::IMPLICIT_GLOBALS].get(name).is_some() { + return Err(TranslateError::symbol_redefinition()); + } + if use_global_scope { + let id = Self::get_or_add_untyped_in_scope( + &mut self.0.module, + &mut self.0.scopes[Self::CROSS_MODULE], + Cow::Borrowed(name), + None, + ); + match self.0.scopes[Self::CURRENT_MODULE].entry(Cow::Borrowed(name)) { + hash_map::Entry::Occupied(existing_id) => { + if *existing_id.get() != id { + return Err(TranslateError::unreachable()); + } + } + hash_map::Entry::Vacant(entry) => { + entry.insert(id); + } + } + Ok(id) + } else { + Ok(Self::get_or_add_untyped_in_scope( + &mut self.0.module, + &mut self.0.scopes[Self::CURRENT_MODULE], + Cow::Borrowed(name), + None, + )) + } + } + + fn get_or_add_untyped_in_scope( + id_def: &mut IdNameMapBuilder<'input>, + scope: &mut FxHashMap, Id>, + name: Cow<'input, str>, + type_: Option<(ast::Type, ast::StateSpace, Option, bool)>, + ) -> Id { + match scope.entry(name) { + hash_map::Entry::Occupied(entry) => *entry.get(), + hash_map::Entry::Vacant(entry) => { + let id = id_def.id_gen.next(); + if cfg!(debug_assertions) { + eprintln!("{}: {}", id.get(), entry.key().to_owned()); + } + id_def.type_check.insert(id, type_); + entry.insert(id); + id + } + } + } + + fn add_untyped_checked(&mut self, name: &'input str) -> Result { + let (id, overwrite) = self.add_untyped_impl(name); + if overwrite { + Err(TranslateError::SymbolRedefinition) + } else { + Ok(id) + } + } + + fn add_variable_checked( + &mut self, + name: &'input str, + type_: ast::Type, + space: ast::StateSpace, + align: Option, + ) -> Result { + let id = self.0.module.id_gen.next(); + self.0 + .module + .type_check + .insert(id, Some((type_, space, align, true))); + let old = self + .0 + .scopes + .last_mut() + .unwrap() + .insert(Cow::Borrowed(name), id); + if old.is_some() { + Err(TranslateError::SymbolRedefinition) + } else { + Ok(id) + } + } + + fn add_untyped_impl(&mut self, name: &'input str) -> (Id, bool) { + let id = self.0.module.id_gen.next(); + self.0.module.type_check.insert(id, None); + let old = self + .0 + .scopes + .last_mut() + .unwrap() + .insert(Cow::Borrowed(name), id); + (id, old.is_some()) + } + + fn add_or_get_module_variable( + &mut self, + name: Cow<'input, str>, + use_global_scope: bool, + type_: ast::Type, + state_space: ast::StateSpace, + align: Option, + initializer: Option>, + ) -> Result { + let id = if use_global_scope { + let id = Self::get_or_add_untyped_in_scope( + &mut self.0.module, + &mut self.0.scopes[Self::CROSS_MODULE], + name.clone(), + Some((type_.clone(), state_space, align, true)), + ); + if self.0.scopes[Self::CURRENT_MODULE] + .insert(name.clone(), id) + .is_some() + { + return Err(TranslateError::unreachable()); + } + id + } else { + Self::get_or_add_untyped_in_scope( + &mut self.0.module, + &mut self.0.scopes[Self::CURRENT_MODULE], + name.clone(), + Some((type_.clone(), state_space, align, true)), + ) + }; + self.0.module.globals.variables.insert(name.clone(), id); + self.0.module.globals.reverse_variables.insert(id, name); + Ok(Variable { + align, + type_, + state_space, + name: id, + initializer, + }) + } + + fn register_variable( + &mut self, + name: Cow<'input, str>, + type_: ast::Type, + state_space: ast::StateSpace, + align: Option, + initializer: Option>, + ) -> Result { + let id = self.0.module.id_gen.next(); + self.0 + .module + .type_check + .insert(id, Some((type_.clone(), state_space, align, true))); + let old = self.0.scopes.last_mut().unwrap().insert(name, id); + if old.is_some() { + Err(TranslateError::SymbolRedefinition) + } else { + Ok(Variable { + align, + type_: type_, + state_space, + name: id, + initializer, + }) + } + } + + fn new_untyped(&mut self) -> Id { + let id = self.0.module.id_gen.next(); + self.0.module.type_check.insert(id, None); + id + } +} + +impl<'a, 'b, 'input> Drop for StringIdResolverScope<'a, 'b, 'input> { + fn drop(&mut self) { + self.0.scopes.pop(); + } +} + +pub(crate) struct FunctionPointerDetails { + pub(crate) dst: Id, + pub(crate) src: Id, +} + +impl, U: ArgParamsEx> Visitable for FunctionPointerDetails { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::FunctionPointer(FunctionPointerDetails { + dst: visitor.id( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + Some(( + &ast::Type::Scalar(ast::ScalarType::U64), + ast::StateSpace::Reg, + )), + )?, + src: visitor.id( + ArgumentDescriptor { + op: self.src, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + None, + )?, + })) + } +} + +pub(crate) struct MadCDetails { + pub(crate) type_: ast::ScalarType, + pub(crate) is_hi: bool, + pub(crate) arg: Arg4CarryIn

, +} + +impl, U: ArgParamsEx> Visitable for MadCDetails { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::MadC(MadCDetails { + type_: self.type_, + is_hi: self.is_hi, + arg: self.arg.map(visitor, self.type_)?, + })) + } +} + +pub(crate) struct MadCCDetails { + pub(crate) type_: ast::ScalarType, + pub(crate) arg: Arg4CarryOut

, +} + +impl, U: ArgParamsEx> Visitable for MadCCDetails { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::MadCC(MadCCDetails { + type_: self.type_, + arg: self.arg.map(visitor, self.type_)?, + })) + } +} + +pub(crate) enum Statement { + Label(Id), + Variable(Variable), Instruction(I), // SPIR-V compatible replacement for PTX predicates Conditional(BrachCondition), @@ -5096,13 +5594,24 @@ enum Statement { StoreVar(StoreVarDetails), Conversion(ImplicitConversion), Constant(ConstantDefinition), - RetValue(ast::RetData, spirv::Word), + RetValue(ast::RetData, Vec<(Id, ast::Type)>), PtrAccess(PtrAccess

), RepackVector(RepackVectorDetails), + FunctionPointer(FunctionPointerDetails), + MadC(MadCDetails

), + MadCC(MadCCDetails

), + AddC(ast::ScalarType, Arg3CarryIn

), + AddCC(ast::ScalarType, Arg3CarryOut

), + SubC(ast::ScalarType, Arg3CarryIn

), + SubCC(ast::ScalarType, Arg3CarryOut

), + AsmVolatile { + asm: &'static str, + constraints: &'static str, + }, } impl ExpandedStatement { - fn map_id(self, f: &mut impl FnMut(spirv::Word, bool) -> spirv::Word) -> ExpandedStatement { + pub(crate) fn map_id(self, f: &mut impl FnMut(Id, bool) -> Id) -> ExpandedStatement { match self { Statement::Label(id) => Statement::Label(f(id, false)), Statement::Variable(mut var) => { @@ -5110,7 +5619,8 @@ impl ExpandedStatement { Statement::Variable(var) } Statement::Instruction(inst) => inst - .visit(&mut |arg: ArgumentDescriptor<_>, _: Option<&ast::Type>| { + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { Ok(f(arg.op, arg.is_dst)) }) .unwrap(), @@ -5125,16 +5635,17 @@ impl ExpandedStatement { 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, + for (id, _, space) in call.return_arguments.iter_mut() { + let is_dst = match space { + ast::StateSpace::Reg => true, + ast::StateSpace::Param => false, + ast::StateSpace::Shared => false, + _ => todo!(), }; *id = f(*id, is_dst); } - call.func = f(call.func, false); - for (id, _) in call.param_list.iter_mut() { + call.name = f(call.name, false); + for (id, _, _) in call.input_arguments.iter_mut() { *id = f(*id, false); } Statement::Call(call) @@ -5154,9 +5665,12 @@ impl ExpandedStatement { constant.dst = f(constant.dst, true); Statement::Constant(constant) } - Statement::RetValue(data, id) => { - let id = f(id, false); - Statement::RetValue(data, id) + Statement::RetValue(data, ids) => { + let ids = ids + .into_iter() + .map(|(id, type_)| (f(id, false), type_)) + .collect(); + Statement::RetValue(data, ids) } Statement::PtrAccess(PtrAccess { underlying_type, @@ -5189,39 +5703,86 @@ impl ExpandedStatement { ..repack }) } + Statement::FunctionPointer(FunctionPointerDetails { dst, src }) => { + Statement::FunctionPointer(FunctionPointerDetails { + dst: f(dst, true), + src: f(src, false), + }) + } + Statement::MadC(madc) => madc + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::MadCC(madcc) => madcc + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::AddC(details, arg) => VisitAddC(details, arg) + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::AddCC(details, arg) => VisitAddCC(details, arg) + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::SubC(details, arg) => VisitSubC(details, arg) + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::SubCC(details, arg) => VisitSubCC(details, arg) + .visit(&mut |arg: ArgumentDescriptor<_>, + _: Option<(&ast::Type, ast::StateSpace)>| { + Ok(f(arg.op, arg.is_dst)) + }) + .unwrap(), + Statement::AsmVolatile { asm, constraints } => { + Statement::AsmVolatile { asm, constraints } + } } } } -struct LoadVarDetails { - arg: ast::Arg2, - typ: ast::Type, +pub(crate) struct LoadVarDetails { + pub(crate) arg: ast::Arg2, + pub(crate) typ: ast::Type, + pub(crate) _state_space: ast::StateSpace, // (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)>, + pub(crate) member_index: Option<(u8, u8)>, } -struct StoreVarDetails { - arg: ast::Arg2St, - typ: ast::Type, - member_index: Option, +pub(crate) struct StoreVarDetails { + pub(crate) arg: ast::Arg2St, + pub(crate) type_: ast::Type, + pub(crate) member_index: Option, } -struct RepackVectorDetails { - is_extract: bool, - typ: ast::ScalarType, - packed: spirv::Word, - unpacked: Vec, - vector_sema: ArgumentSemantics, +pub(crate) struct RepackVectorDetails { + pub(crate) is_extract: bool, + pub(crate) typ: ast::ScalarType, + pub(crate) packed: Id, + pub(crate) unpacked: Vec, + pub(crate) non_default_implicit_conversion: Option< + fn( + (ast::StateSpace, &ast::Type), + (ast::StateSpace, &ast::Type), + ) -> Result, TranslateError>, + >, } impl RepackVectorDetails { fn map< - From: ArgParamsEx, - To: ArgParamsEx, + From: ArgParamsEx, + To: ArgParamsEx, V: ArgumentMapVisitor, >( self, @@ -5231,13 +5792,17 @@ impl RepackVectorDetails { ArgumentDescriptor { op: self.packed, is_dst: !self.is_extract, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ast::Type::Vector(self.typ, self.unpacked.len() as u8)), + Some(( + &ast::Type::Vector(self.typ, self.unpacked.len() as u8), + ast::StateSpace::Reg, + )), )?; let scalar_type = self.typ; let is_extract = self.is_extract; - let vector_sema = self.vector_sema; + let non_default_implicit_conversion = self.non_default_implicit_conversion; let vector = self .unpacked .into_iter() @@ -5246,9 +5811,10 @@ impl RepackVectorDetails { ArgumentDescriptor { op: id, is_dst: is_extract, - sema: vector_sema, + is_memory_access: false, + non_default_implicit_conversion, }, - Some(&ast::Type::Scalar(scalar_type)), + Some((&ast::Type::Scalar(scalar_type), ast::StateSpace::Reg)), ) }) .collect::>()?; @@ -5257,14 +5823,12 @@ impl RepackVectorDetails { typ: self.typ, packed: scalar, unpacked: vector, - vector_sema, + non_default_implicit_conversion, }) } } -impl, U: ArgParamsEx> Visitable - for RepackVectorDetails -{ +impl, U: ArgParamsEx> Visitable for RepackVectorDetails { fn visit( self, visitor: &mut impl ArgumentMapVisitor, @@ -5273,79 +5837,160 @@ impl, U: ArgParamsEx> Visitab } } -struct ResolvedCall { +pub(crate) struct ResolvedCall { pub uniform: bool, - pub ret_params: Vec<(P::Id, ast::FnArgumentType)>, - pub func: P::Id, - pub param_list: Vec<(P::Operand, ast::FnArgumentType)>, + pub return_arguments: Vec<(P::Id, ast::Type, ast::StateSpace)>, + pub name: P::Id, + pub input_arguments: Vec<(P::Operand, ast::Type, ast::StateSpace)>, + pub is_indirect: bool, } impl ResolvedCall { + fn from_declaration<'input>( + call: ast::CallInst, + return_arguments: &[ast::VariableDeclaration], + input_arguments: &[ast::VariableDeclaration], + ) -> Result { + if call.ret_params.len() != return_arguments.len() + || call.param_list.len() != input_arguments.len() + { + return Err(TranslateError::mismatched_type()); + } + let return_arguments = call + .ret_params + .into_iter() + .zip(return_arguments.iter()) + .map(|(id, var_decl)| (id, var_decl.type_.clone(), var_decl.state_space)) + .collect::>(); + let input_arguments = call + .param_list + .into_iter() + .zip(input_arguments.iter()) + .map(|(id, var_decl)| (id, var_decl.type_.clone(), var_decl.state_space)) + .collect::>(); + Ok(Self { + return_arguments, + input_arguments, + uniform: call.uniform, + name: call.func, + is_indirect: false, + }) + } + + fn from_callprototype<'input>( + call: ast::CallInst, + proto: &Callprototype, + ) -> Result { + if call.ret_params.len() != proto.return_arguments.len() + || call.param_list.len() != proto.input_arguments.len() + { + return Err(TranslateError::mismatched_type()); + } + let return_arguments = call + .ret_params + .into_iter() + .zip(proto.return_arguments.iter()) + .map(|(id, (type_, state_space))| (id, type_.clone(), *state_space)) + .collect::>(); + let input_arguments = call + .param_list + .into_iter() + .zip(proto.input_arguments.iter()) + .map(|(id, (type_, state_space))| (id, type_.clone(), *state_space)) + .collect::>(); + Ok(Self { + return_arguments, + input_arguments, + uniform: call.uniform, + name: call.func, + is_indirect: true, + }) + } + fn cast>(self) -> ResolvedCall { ResolvedCall { uniform: self.uniform, - ret_params: self.ret_params, - func: self.func, - param_list: self.param_list, + return_arguments: self.return_arguments, + name: self.name, + input_arguments: self.input_arguments, + is_indirect: self.is_indirect, } } } -impl> ResolvedCall { - fn map, V: ArgumentMapVisitor>( +impl> ResolvedCall { + fn map, V: ArgumentMapVisitor>( self, visitor: &mut V, ) -> Result, TranslateError> { - let ret_params = self - .ret_params + let return_arguments = self + .return_arguments .into_iter() - .map::, _>(|(id, typ)| { + .map::, _>(|(id, typ, space)| { let new_id = visitor.id( ArgumentDescriptor { op: id, - is_dst: !typ.is_param(), - sema: typ.semantics(), + is_dst: space != ast::StateSpace::Param, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&typ.to_func_type()), + Some((&typ, space)), )?; - Ok((new_id, typ)) + Ok((new_id, typ, space)) }) .collect::, _>>()?; - let func = visitor.id( - ArgumentDescriptor { - op: self.func, - is_dst: false, - sema: ArgumentSemantics::Default, - }, - None, - )?; - let param_list = self - .param_list + let func = if self.is_indirect { + visitor.id( + ArgumentDescriptor { + op: self.name, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + Some(( + &ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + )), + ) + } else { + visitor.id( + ArgumentDescriptor { + op: self.name, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + None, + ) + }?; + let input_arguments = self + .input_arguments .into_iter() - .map::, _>(|(id, typ)| { + .map::, _>(|(id, typ, space)| { let new_id = visitor.operand( ArgumentDescriptor { op: id, is_dst: false, - sema: typ.semantics(), + is_memory_access: false, + non_default_implicit_conversion: None, }, - &typ.to_func_type(), + &typ, + space, )?; - Ok((new_id, typ)) + Ok((new_id, typ, space)) }) .collect::, _>>()?; Ok(ResolvedCall { uniform: self.uniform, - ret_params, - func, - param_list, + return_arguments, + name: func, + input_arguments, + is_indirect: self.is_indirect, }) } } -impl, U: ArgParamsEx> Visitable - for ResolvedCall -{ +impl, U: ArgParamsEx> Visitable for ResolvedCall { fn visit( self, visitor: &mut impl ArgumentMapVisitor, @@ -5354,44 +5999,38 @@ impl, U: ArgParamsEx> Visitab } } -impl> PtrAccess

{ - fn map, V: ArgumentMapVisitor>( +impl> PtrAccess

{ + fn map, V: ArgumentMapVisitor>( self, visitor: &mut V, ) -> Result, 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, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ptr_type), + Some((&self.underlying_type, self.state_space)), )?; let new_ptr_src = visitor.id( ArgumentDescriptor { op: self.ptr_src, is_dst: false, - sema, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ptr_type), + Some((&self.underlying_type, self.state_space)), )?; let new_constant_src = visitor.operand( ArgumentDescriptor { op: self.offset_src, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(ast::ScalarType::S64), + ast::StateSpace::Reg, )?; Ok(PtrAccess { underlying_type: self.underlying_type, @@ -5403,9 +6042,7 @@ impl> PtrAccess

{ } } -impl, U: ArgParamsEx> Visitable - for PtrAccess -{ +impl, U: ArgParamsEx> Visitable for PtrAccess { fn visit( self, visitor: &mut impl ArgumentMapVisitor, @@ -5414,41 +6051,22 @@ impl, U: ArgParamsEx> Visitab } } -pub trait ArgParamsEx: ast::ArgParams + Sized { - fn get_fn_decl<'x, 'b>( - id: &Self::Id, - decl: &'b GlobalFnDeclResolver<'x, 'b>, - ) -> Result<&'b FnDecl, TranslateError>; -} +pub trait ArgParamsEx: ast::ArgParams + Sized {} -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) - } -} +impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {} -enum NormalizedArgParams {} +pub(crate) enum NormalizedArgParams {} impl ast::ArgParams for NormalizedArgParams { - type Id = spirv::Word; - type Operand = ast::Operand; + type Id = Id; + type Operand = ast::Operand; } -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) - } -} +impl ArgParamsEx for NormalizedArgParams {} type NormalizedStatement = Statement< ( - Option>, + Option>, ast::Instruction, ), NormalizedArgParams, @@ -5456,119 +6074,112 @@ type NormalizedStatement = Statement< type UnconditionalStatement = Statement, NormalizedArgParams>; -enum TypedArgParams {} +pub(crate) enum TypedArgParams {} impl ast::ArgParams for TypedArgParams { - type Id = spirv::Word; + type Id = Id; 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) - } -} +impl ArgParamsEx for TypedArgParams {} #[derive(Copy, Clone)] -enum TypedOperand { - Reg(spirv::Word), - RegOffset(spirv::Word, i32), +pub(crate) enum TypedOperand { + Reg(Id), + RegOffset(Id, i64), Imm(ast::ImmediateValue), - VecMember(spirv::Word, u8), -} - -impl TypedOperand { - fn upcast(self) -> ast::Operand { - 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), - } - } + VecMember(Id, u8), } type TypedStatement = Statement, TypedArgParams>; -enum ExpandedArgParams {} -type ExpandedStatement = Statement, ExpandedArgParams>; +pub(crate) enum ExpandedArgParams {} +pub(crate) type ExpandedStatement = + Statement, ExpandedArgParams>; impl ast::ArgParams for ExpandedArgParams { - type Id = spirv::Word; - type Operand = spirv::Word; + type Id = Id; + type Operand = Id; } -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) - } +impl ArgParamsEx for ExpandedArgParams {} + +pub(crate) type Directive<'input> = TranslationDirective<'input, ExpandedArgParams>; + +pub(crate) enum TranslationDirective<'input, P: ast::ArgParams> { + Variable(ast::LinkingDirective, Option>, Variable), + Method(TranslationMethod<'input, P>), } -enum Directive<'input> { - Variable(ast::Variable), - Method(Function<'input>), +pub(crate) struct Variable { + pub align: Option, + pub type_: ast::Type, + pub state_space: ast::StateSpace, + pub name: Id, + pub initializer: Option>, } -struct Function<'input> { - pub func_decl: ast::MethodDecl<'input, spirv::Word>, - pub spirv_decl: SpirvMethodDecl<'input>, - pub globals: Vec>, - pub body: Option>, - import_as: Option, +pub(crate) type Function<'input> = TranslationMethod<'input, ExpandedArgParams>; + +pub(crate) struct TranslationMethod<'input, P: ast::ArgParams> { + pub(crate) return_arguments: Vec>, + pub(crate) name: P::Id, + pub(crate) input_arguments: Vec>, + pub(crate) body: Option, P>>>, + pub(crate) tuning: Vec, + pub(crate) is_kernel: bool, + pub(crate) source_name: Option>, + pub(crate) special_raytracing_linking: bool, } -pub trait ArgumentMapVisitor { +pub(crate) trait ArgumentMapVisitor { fn id( &mut self, desc: ArgumentDescriptor, - typ: Option<&ast::Type>, + typ: Option<(&ast::Type, ast::StateSpace)>, ) -> Result; fn operand( &mut self, desc: ArgumentDescriptor, typ: &ast::Type, + state_space: ast::StateSpace, ) -> Result; } impl ArgumentMapVisitor for T where T: FnMut( - ArgumentDescriptor, - Option<&ast::Type>, - ) -> Result, + ArgumentDescriptor, + Option<(&ast::Type, ast::StateSpace)>, + ) -> Result, { fn id( &mut self, - desc: ArgumentDescriptor, - t: Option<&ast::Type>, - ) -> Result { + desc: ArgumentDescriptor, + t: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { self(desc, t) } fn operand( &mut self, - desc: ArgumentDescriptor, + desc: ArgumentDescriptor, typ: &ast::Type, - ) -> Result { - self(desc, Some(typ)) + state_space: ast::StateSpace, + ) -> Result { + self(desc, Some((typ, state_space))) } } impl<'a, T> ArgumentMapVisitor, NormalizedArgParams> for T where - T: FnMut(&str) -> Result, + T: FnMut(&str) -> Result, { fn id( &mut self, desc: ArgumentDescriptor<&str>, - _: Option<&ast::Type>, - ) -> Result { + _: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { self(desc.op) } @@ -5576,7 +6187,8 @@ where &mut self, desc: ArgumentDescriptor>, typ: &ast::Type, - ) -> Result, TranslateError> { + state_space: ast::StateSpace, + ) -> Result, 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), @@ -5584,39 +6196,37 @@ where 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))) + .map(|id_or_immediate| { + Ok::<_, TranslateError>(match id_or_immediate { + ast::RegOrImmediate::Reg(reg) => ast::RegOrImmediate::Reg( + self.id(desc.new_op(reg), Some((typ, state_space)))?, + ), + ast::RegOrImmediate::Imm(imm) => ast::RegOrImmediate::Imm(*imm), + }) + }) .collect::, _>>()?, ), }) } } -pub struct ArgumentDescriptor { - op: Op, - is_dst: bool, - sema: ArgumentSemantics, +pub(crate) struct ArgumentDescriptor { + pub(crate) op: Op, + pub(crate) is_dst: bool, + pub(crate) is_memory_access: bool, + pub(crate) non_default_implicit_conversion: Option< + fn( + (ast::StateSpace, &ast::Type), + (ast::StateSpace, &ast::Type), + ) -> Result, TranslateError>, + >, } - -pub struct PtrAccess { - 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, +pub(crate) struct PtrAccess { + pub(crate) underlying_type: ast::Type, + pub(crate) state_space: ast::StateSpace, + pub(crate) dst: Id, + pub(crate) ptr_src: Id, + pub(crate) offset_src: P::Operand, } impl ArgumentDescriptor { @@ -5624,7 +6234,8 @@ impl ArgumentDescriptor { ArgumentDescriptor { op: u, is_dst: self.is_dst, - sema: self.sema, + is_memory_access: self.is_memory_access, + non_default_implicit_conversion: self.non_default_implicit_conversion, } } } @@ -5639,7 +6250,7 @@ impl ast::Instruction { 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::Call(_) => return Err(TranslateError::unreachable()), ast::Instruction::Ld(d, a) => { let new_args = a.map(visitor, &d)?; ast::Instruction::Ld(d, new_args) @@ -5651,53 +6262,44 @@ impl ast::Instruction { 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::Mul(d, a.map_generic(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)?) + let inst_type = ast::Type::Scalar(d.get_type()); + ast::Instruction::Add(d, a.map_generic(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; + let inst_type = d.base.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::Not(t, a) => { + ast::Instruction::Not(t, a.map(visitor, &ast::Type::Scalar(t))?) + } 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()), - ), + let (dst_t, src_t, int_to_int) = match &d { + ast::CvtDetails::FloatFromFloat(desc) => (desc.dst, desc.src, false), + ast::CvtDetails::FloatFromInt(desc) => (desc.dst, desc.src, false), + ast::CvtDetails::IntFromFloat(desc) => (desc.dst, desc.src, false), + ast::CvtDetails::IntFromInt(desc) => (desc.dst, desc.src, true), }; - ast::Instruction::Cvt(d, a.map_different_types(visitor, &dst_t, &src_t)?) + ast::Instruction::Cvt(d, a.map_cvt(visitor, dst_t, src_t, int_to_int)?) } ast::Instruction::Shl(t, a) => { - ast::Instruction::Shl(t, a.map_shift(visitor, &t.to_type())?) + ast::Instruction::Shl(t, a.map_shift(visitor, &ast::Type::Scalar(t))?) } 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)?; + let new_args = a.map(visitor, &d.typ, d.state_space)?; ast::Instruction::St(d, new_args) } - ast::Instruction::Bra(d, a) => ast::Instruction::Bra(d, a.map(visitor, None)?), + ast::Instruction::Bra(d, a) => ast::Instruction::Bra(d, a.map(visitor, false, None)?), + ast::Instruction::Exit => ast::Instruction::Exit, ast::Instruction::Ret(d) => ast::Instruction::Ret(d), ast::Instruction::Cvta(d, a) => { let inst_type = ast::Type::Scalar(ast::ScalarType::B64); @@ -5708,36 +6310,37 @@ impl ast::Instruction { let is_wide = d.is_wide(); ast::Instruction::Mad(d, a.map(visitor, &inst_type, is_wide)?) } + ast::Instruction::Fma(d, a) => { + let inst_type = ast::Type::Scalar(d.typ); + ast::Instruction::Fma(d, a.map(visitor, &inst_type, false)?) + } ast::Instruction::Or(t, a) => ast::Instruction::Or( t, - a.map_non_shift(visitor, &ast::Type::Scalar(t.into()), false)?, + a.map_generic(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)?) + let typ = ast::Type::Scalar(d.get_type()); + ast::Instruction::Sub(d, a.map_generic(visitor, &typ, false)?) } ast::Instruction::Min(d, a) => { - let typ = d.get_type(); - ast::Instruction::Min(d, a.map_non_shift(visitor, &typ, false)?) + let typ = ast::Type::Scalar(d.get_type()); + ast::Instruction::Min(d, a.map_generic(visitor, &typ, false)?) } ast::Instruction::Max(d, a) => { - let typ = d.get_type(); - ast::Instruction::Max(d, a.map_non_shift(visitor, &typ, false)?) + let typ = ast::Type::Scalar(d.get_type()); + ast::Instruction::Max(d, a.map_generic(visitor, &typ, false)?) } ast::Instruction::Rcp(d, a) => { - let typ = ast::Type::Scalar(if d.is_f64 { - ast::ScalarType::F64 - } else { - ast::ScalarType::F32 - }); + let typ = ast::Type::Scalar(d.type_); 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)?, + a.map_generic(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::BarWarp(d, a) => ast::Instruction::BarWarp(d, a.map(visitor)?), ast::Instruction::Atom(d, a) => { ast::Instruction::Atom(d, a.map_atom(visitor, d.inner.get_type(), d.space)?) } @@ -5745,10 +6348,11 @@ impl ast::Instruction { 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::Div(d, a.map_generic(visitor, &d.get_type(), false)?) } ast::Instruction::Sqrt(d, a) => { - ast::Instruction::Sqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?) + let type_ = ast::Type::Scalar(d.type_); + ast::Instruction::Sqrt(d, a.map(visitor, &type_)?) } ast::Instruction::Rsqrt(d, a) => { ast::Instruction::Rsqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?) @@ -5792,6 +6396,14 @@ impl ast::Instruction { arg: arg.map_different_types(visitor, &dst_type, &src_type)?, } } + ast::Instruction::Bfind(details, arg) => { + let dst_type = ast::Type::Scalar(ast::ScalarType::B32); + let src_type = ast::Type::Scalar(details.type_); + ast::Instruction::Bfind( + details, + 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 { @@ -5811,7 +6423,7 @@ impl ast::Instruction { let full_type = ast::Type::Scalar(typ.into()); ast::Instruction::Xor { typ, - arg: arg.map_non_shift(visitor, &full_type, false)?, + arg: arg.map_generic(visitor, &full_type, false)?, } } ast::Instruction::Bfe { typ, arg } => { @@ -5821,13 +6433,167 @@ impl ast::Instruction { arg: arg.map_bfe(visitor, &full_type)?, } } + ast::Instruction::Bfi { typ, arg } => { + let full_type = ast::Type::Scalar(typ.into()); + ast::Instruction::Bfi { + typ, + arg: arg.map_bfi(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)?, + arg: arg.map_generic(visitor, &full_type, false)?, } } + ast::Instruction::Prmt { control, arg } => ast::Instruction::Prmt { + control, + arg: arg.map_prmt(visitor)?, + }, + ast::Instruction::PrmtSlow { control, arg } => ast::Instruction::PrmtSlow { + arg: arg.map_prmt(visitor)?, + control: ast::Arg1 { src: control } + .map( + visitor, + false, + Some(( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )), + )? + .src, + }, + ast::Instruction::Activemask { arg } => ast::Instruction::Activemask { + arg: arg.map( + visitor, + true, + Some(( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )), + )?, + }, + ast::Instruction::Membar { level } => ast::Instruction::Membar { level }, + ast::Instruction::MadC { + type_, + arg, + is_hi, + carry_out, + } => ast::Instruction::MadC { + type_, + is_hi, + carry_out, + arg: arg.map(visitor, &ast::Type::Scalar(type_), false)?, + }, + ast::Instruction::MadCC { type_, arg } => ast::Instruction::MadCC { + type_, + arg: arg.map(visitor, &ast::Type::Scalar(type_), false)?, + }, + ast::Instruction::Tex(details, arg) => { + let image_type_space = if details.direct { + (ast::Type::Texref, ast::StateSpace::Global) + } else { + ( + ast::Type::Scalar(ast::ScalarType::B64), + ast::StateSpace::Reg, + ) + }; + let arg = arg.map( + visitor, + image_type_space, + details.geometry, + ast::Type::Vector(details.channel_type, 4), + details.coordinate_type, + )?; + ast::Instruction::Tex(details, arg) + } + ast::Instruction::Suld(details, arg) => { + let arg = arg.map( + visitor, + (ast::Type::Surfref, ast::StateSpace::Global), + details.geometry, + details.value_type(), + ast::ScalarType::B32, + )?; + ast::Instruction::Suld(details, arg) + } + ast::Instruction::Sust(details, arg) => { + let arg = arg.map(visitor, &details)?; + ast::Instruction::Sust(details, arg) + } + ast::Instruction::Shfl(mode, arg) => { + let arg = arg.map(visitor)?; + ast::Instruction::Shfl(mode, arg) + } + ast::Instruction::Shf(details, arg) => { + let arg = arg.map(visitor, &ast::Type::Scalar(ast::ScalarType::B32), false)?; + ast::Instruction::Shf(details, arg) + } + ast::Instruction::Vote(details, arg) => { + let arg = arg.map_vote(visitor, details.mode)?; + ast::Instruction::Vote(details, arg) + } + ast::Instruction::BarRed(details, arg) => { + let arg = arg.map_bar_red(visitor, details)?; + ast::Instruction::BarRed(details, arg) + } + ast::Instruction::Trap => ast::Instruction::Trap, + ast::Instruction::Brkpt => ast::Instruction::Brkpt, + ast::Instruction::AddC(details, arg) => { + let arg = arg.map_generic(visitor, &ast::Type::Scalar(details.type_), false)?; + ast::Instruction::AddC(details, arg) + } + ast::Instruction::AddCC(type_, arg) => { + let arg = arg.map_generic(visitor, &ast::Type::Scalar(type_), false)?; + ast::Instruction::AddCC(type_, arg) + } + ast::Instruction::SubC(details, arg) => { + let arg = arg.map_generic(visitor, &ast::Type::Scalar(details.type_), false)?; + ast::Instruction::SubC(details, arg) + } + ast::Instruction::SubCC(type_, arg) => { + let arg = arg.map_generic(visitor, &ast::Type::Scalar(type_), false)?; + ast::Instruction::SubCC(type_, arg) + } + ast::Instruction::Vshr(arg) => ast::Instruction::Vshr(arg.map( + visitor, + &ast::Type::Scalar(ast::ScalarType::U32), + false, + )?), + ast::Instruction::Set(details, arg) => { + let arg = arg.map_different_types( + visitor, + &ast::Type::Scalar(details.dst_type), + &ast::Type::Scalar(details.src_type), + )?; + ast::Instruction::Set(details, arg) + } + ast::Instruction::Dp4a(type_, arg) => { + let arg = arg.map(visitor, &ast::Type::Scalar(type_), false)?; + ast::Instruction::Dp4a(type_, arg) + } + ast::Instruction::MatchAny(arg) => { + let arg = + arg.map_generic(visitor, &ast::Type::Scalar(ast::ScalarType::B32), false)?; + ast::Instruction::MatchAny(arg) + } + ast::Instruction::Red(details, args) => { + let args = args.map( + visitor, + &ast::Type::Scalar(details.inner.get_type()), + details.space, + )?; + ast::Instruction::Red(details, args) + } + ast::Instruction::Nanosleep(a) => ast::Instruction::Nanosleep(a.map( + visitor, + false, + Some(( + &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + )), + )?), }) } } @@ -5842,11 +6608,7 @@ impl Visitable for ast::Instruction { } impl ImplicitConversion { - fn map< - T: ArgParamsEx, - U: ArgParamsEx, - V: ArgumentMapVisitor, - >( + fn map, U: ArgParamsEx, V: ArgumentMapVisitor>( self, visitor: &mut V, ) -> Result, U>, TranslateError> { @@ -5854,17 +6616,19 @@ impl ImplicitConversion { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: self.dst_sema, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&self.to), + Some((&self.to_type, self.to_space)), )?; let new_src = visitor.id( ArgumentDescriptor { op: self.src, is_dst: false, - sema: self.src_sema, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&self.from), + Some((&self.from_type, self.from_space)), )?; Ok(Statement::Conversion({ ImplicitConversion { @@ -5876,7 +6640,13 @@ impl ImplicitConversion { } } -impl, To: ArgParamsEx> Visitable +#[derive(Copy, Clone)] +pub(crate) enum FPDenormMode { + FlushToZero, + Preserve, +} + +impl, To: ArgParamsEx> Visitable for ImplicitConversion { fn visit( @@ -5890,15 +6660,15 @@ impl, To: ArgParamsEx> Vis impl ArgumentMapVisitor for T where T: FnMut( - ArgumentDescriptor, - Option<&ast::Type>, - ) -> Result, + ArgumentDescriptor, + Option<(&ast::Type, ast::StateSpace)>, + ) -> Result, { fn id( &mut self, - desc: ArgumentDescriptor, - t: Option<&ast::Type>, - ) -> Result { + desc: ArgumentDescriptor, + t: Option<(&ast::Type, ast::StateSpace)>, + ) -> Result { self(desc, t) } @@ -5906,106 +6676,101 @@ where &mut self, desc: ArgumentDescriptor, typ: &ast::Type, + state_space: ast::StateSpace, ) -> Result { Ok(match desc.op { - TypedOperand::Reg(id) => TypedOperand::Reg(self(desc.new_op(id), Some(typ))?), + TypedOperand::Reg(id) => { + TypedOperand::Reg(self(desc.new_op(id), Some((typ, state_space)))?) + } TypedOperand::Imm(imm) => TypedOperand::Imm(imm), TypedOperand::RegOffset(id, imm) => { - TypedOperand::RegOffset(self(desc.new_op(id), Some(typ))?, imm) + TypedOperand::RegOffset(self(desc.new_op(id), Some((typ, state_space)))?, imm) } TypedOperand::VecMember(reg, index) => { let scalar_type = match typ { ast::Type::Scalar(scalar_t) => *scalar_t, - _ => return Err(error_unreachable()), + _ => return Err(TranslateError::unreachable()), }; let vec_type = ast::Type::Vector(scalar_type, index + 1); - TypedOperand::VecMember(self(desc.new_op(reg), Some(&vec_type))?, index) + TypedOperand::VecMember( + self(desc.new_op(reg), Some((&vec_type, state_space)))?, + index, + ) } }) } } impl ast::Type { - fn widen(self) -> Result { + pub(crate) fn widen(self) -> Result { 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()), + ast::Type::Scalar(scalar) => Ok(ast::Type::Scalar(scalar.widen()?)), + _ => Err(TranslateError::unreachable()), } } - fn to_parts(&self) -> TypeParts { + pub(crate) fn to_parts(&self) -> TypeParts { + let width = self.layout().size() as u8; match self { ast::Type::Scalar(scalar) => TypeParts { kind: TypeKind::Scalar, + state_space: ast::StateSpace::Reg, scalar_kind: scalar.kind(), - width: scalar.size_of(), components: Vec::new(), - state_space: ast::LdStateSpace::Global, + width, }, ast::Type::Vector(scalar, components) => TypeParts { kind: TypeKind::Vector, + state_space: ast::StateSpace::Reg, scalar_kind: scalar.kind(), - width: scalar.size_of(), components: vec![*components as u32], - state_space: ast::LdStateSpace::Global, + width, }, ast::Type::Array(scalar, components) => TypeParts { kind: TypeKind::Array, + state_space: ast::StateSpace::Reg, scalar_kind: scalar.kind(), - width: scalar.size_of(), components: components.clone(), - state_space: ast::LdStateSpace::Global, + width, }, - ast::Type::Pointer(ast::PointerType::Scalar(scalar), state_space) => TypeParts { - kind: TypeKind::PointerScalar, + ast::Type::Pointer(scalar, space) => TypeParts { + kind: TypeKind::Pointer, + state_space: *space, scalar_kind: scalar.kind(), - width: scalar.size_of(), components: Vec::new(), - state_space: *state_space, + width, }, - 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::Texref => TypeParts { + kind: TypeKind::Texref, + state_space: ast::StateSpace::Global, + scalar_kind: ast::ScalarKind::Bit, + components: Vec::new(), + width, }, - ast::Type::Pointer(ast::PointerType::Array(scalar, components), state_space) => { + ast::Type::Surfref => TypeParts { + kind: TypeKind::Surfref, + state_space: ast::StateSpace::Global, + scalar_kind: ast::ScalarKind::Bit, + components: Vec::new(), + width, + }, + ast::Type::Struct(fields) => { + let components = fields + .iter() + .map(|field| unsafe { mem::transmute::<_, u16>(*field) as u32 }) + .collect(); 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, + kind: TypeKind::Struct, + state_space: ast::StateSpace::Reg, + scalar_kind: ast::ScalarKind::Bit, + components, + width, } } } } - fn from_parts(t: TypeParts) -> Self { + pub(crate) fn from_parts(t: TypeParts) -> Self { match t.kind { TypeKind::Scalar => { ast::Type::Scalar(ast::ScalarType::from_parts(t.width, t.scalar_kind)) @@ -6018,77 +6783,106 @@ impl ast::Type { 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)), + TypeKind::Pointer => ast::Type::Pointer( + 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, + TypeKind::Texref => ast::Type::Texref, + TypeKind::Surfref => ast::Type::Surfref, + TypeKind::Struct => ast::Type::Struct( + t.components + .into_iter() + .map(|component| unsafe { mem::transmute(component as u16) }) + .collect(), ), } } - pub fn size_of(&self) -> usize { + pub(crate) fn layout(&self) -> Layout { 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::(), + ast::Type::Scalar(typ) => { + let size_of = typ.size_of() as usize; + unsafe { Layout::from_size_align_unchecked(size_of, size_of) } + } + ast::Type::Vector(typ, len) => { + let size_of = typ.size_of() as usize * (*len) as usize; + unsafe { Layout::from_size_align_unchecked(size_of, size_of) } + } + ast::Type::Array(typ, len) => { + let scalar_size_of = typ.size_of() as usize; + let len = len + .iter() + .fold(typ.size_of() as usize, |x, y| (x as usize) * (*y as usize)); + unsafe { Layout::from_size_align_unchecked(scalar_size_of * len, scalar_size_of) } + } + ast::Type::Struct(fields) => { + let mut layout = Layout::new::<()>(); + for field in fields { + layout = layout.extend(field.to_type().layout()).unwrap().0 + } + layout.pad_to_align() + } + ast::Type::Pointer(..) => Layout::new::<*const ()>(), + ast::Type::Texref | ast::Type::Surfref => Layout::new::(), } } } #[derive(Eq, PartialEq, Clone)] -struct TypeParts { - kind: TypeKind, - scalar_kind: ScalarKind, - width: u8, - components: Vec, - state_space: ast::LdStateSpace, +pub(crate) struct TypeParts { + pub(crate) kind: TypeKind, + pub(crate) scalar_kind: ast::ScalarKind, + pub(crate) width: u8, + pub(crate) state_space: ast::StateSpace, + pub(crate) components: Vec, } #[derive(Eq, PartialEq, Copy, Clone)] -enum TypeKind { +pub(crate) enum TypeKind { Scalar, Vector, Array, - PointerScalar, - PointerVector, - PointerArray, - PointerPointer, + Pointer, + Texref, + Surfref, + Struct, } -impl ast::Instruction { - fn jump_target(&self) -> Option { +impl> ast::Instruction { + fn jump_target(&self) -> Option { match self { ast::Instruction::Bra(_, a) => Some(a.src), _ => None, } } +} +impl ast::Instruction { // .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)> { + fn scalar_size_of(type_: ast::ScalarType) -> u8 { + match type_ { + ast::ScalarType::U8 => 1, + ast::ScalarType::S8 => 1, + ast::ScalarType::B8 => 1, + ast::ScalarType::U16 => 2, + ast::ScalarType::S16 => 2, + ast::ScalarType::B16 => 2, + ast::ScalarType::F16 => 2, + ast::ScalarType::U32 => 4, + ast::ScalarType::S32 => 4, + ast::ScalarType::B32 => 4, + ast::ScalarType::F32 => 4, + ast::ScalarType::U64 => 8, + ast::ScalarType::S64 => 8, + ast::ScalarType::B64 => 8, + ast::ScalarType::F64 => 8, + ast::ScalarType::F16x2 => 2, + ast::ScalarType::Pred => 1, + } + } + match self { ast::Instruction::Ld(_, _) => None, ast::Instruction::St(_, _) => None, @@ -6098,14 +6892,29 @@ impl ast::Instruction { ast::Instruction::Shl(_, _) => None, ast::Instruction::Shr(_, _) => None, ast::Instruction::Ret(_) => None, + ast::Instruction::Exit => None, + ast::Instruction::Trap => None, + ast::Instruction::Brkpt => 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::BarWarp(_, _) => None, ast::Instruction::Atom(_, _) => None, + ast::Instruction::Red(_, _) => None, ast::Instruction::AtomCas(_, _) => None, + ast::Instruction::MadC { .. } => None, + ast::Instruction::MadCC { .. } => None, + ast::Instruction::BarRed { .. } => None, + ast::Instruction::AddC { .. } => None, + ast::Instruction::AddCC { .. } => None, + ast::Instruction::SubC { .. } => None, + ast::Instruction::SubCC { .. } => None, + ast::Instruction::Vshr { .. } => None, + ast::Instruction::Dp4a { .. } => None, + ast::Instruction::MatchAny { .. } => None, ast::Instruction::Sub(ast::ArithDetails::Signed(_), _) => None, ast::Instruction::Sub(ast::ArithDetails::Unsigned(_), _) => None, ast::Instruction::Add(ast::ArithDetails::Signed(_), _) => None, @@ -6123,33 +6932,58 @@ impl ast::Instruction { ast::Instruction::Div(ast::DivDetails::Unsigned(_), _) => None, ast::Instruction::Div(ast::DivDetails::Signed(_), _) => None, ast::Instruction::Clz { .. } => None, + ast::Instruction::Bfind(..) => None, ast::Instruction::Brev { .. } => None, ast::Instruction::Popc { .. } => None, ast::Instruction::Xor { .. } => None, ast::Instruction::Bfe { .. } => None, + ast::Instruction::Bfi { .. } => None, ast::Instruction::Rem { .. } => None, + ast::Instruction::Prmt { .. } => None, + ast::Instruction::PrmtSlow { .. } => None, + ast::Instruction::Activemask { .. } => None, + ast::Instruction::Membar { .. } => None, + ast::Instruction::Tex(..) => None, + ast::Instruction::Suld(..) => None, + ast::Instruction::Sust(..) => None, + ast::Instruction::Shfl(..) => None, + ast::Instruction::Shf(..) => None, + ast::Instruction::Vote(..) => None, + ast::Instruction::Nanosleep(..) => 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::Mad(ast::MulDetails::Float(float_control), _) => { + float_control.flush_to_zero.map(|ftz| { + ( + ftz, + scalar_size_of(ast::ScalarType::from(float_control.typ)), + ) + }) + } + ast::Instruction::Fma(d, _) => d.flush_to_zero.map(|ftz| (ftz, scalar_size_of(d.typ))), ast::Instruction::Setp(details, _) => details .flush_to_zero - .map(|ftz| (ftz, details.typ.size_of())), + .map(|ftz| (ftz, scalar_size_of(details.typ))), ast::Instruction::SetpBool(details, _) => details + .base .flush_to_zero - .map(|ftz| (ftz, details.typ.size_of())), + .map(|ftz| (ftz, scalar_size_of(details.base.typ))), ast::Instruction::Abs(details, _) => details .flush_to_zero - .map(|ftz| (ftz, details.typ.size_of())), + .map(|ftz| (ftz, scalar_size_of(details.typ))), 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::Max(ast::MinMaxDetails::Float(float_control), _) => { + float_control.flush_to_zero.map(|ftz| { + ( + ftz, + scalar_size_of(ast::ScalarType::from(float_control.typ)), + ) + }) + } ast::Instruction::Rcp(details, _) => details .flush_to_zero - .map(|ftz| (ftz, if details.is_f64 { 8 } else { 4 })), + .map(|ftz| (ftz, scalar_size_of(details.type_))), // 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( @@ -6162,23 +6996,31 @@ impl ast::Instruction { ) => 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())), + .map(|ftz| (ftz, scalar_size_of(ast::ScalarType::from(details.typ)))), ast::Instruction::Sqrt(details, _) => details .flush_to_zero - .map(|ftz| (ftz, ast::ScalarType::from(details.typ).size_of())), + .map(|ftz| (ftz, scalar_size_of(details.type_))), ast::Instruction::Rsqrt(details, _) => Some(( details.flush_to_zero, - ast::ScalarType::from(details.typ).size_of(), + scalar_size_of(ast::ScalarType::from(details.typ)), )), ast::Instruction::Neg(details, _) => details .flush_to_zero - .map(|ftz| (ftz, details.typ.size_of())), + .map(|ftz| (ftz, scalar_size_of(details.typ))), 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::() as u8)) } + ast::Instruction::Set( + ast::SetData { + flush_to_zero, + src_type, + .. + }, + _, + ) => Some((*flush_to_zero, scalar_size_of(*src_type))), } } } @@ -6186,37 +7028,64 @@ impl ast::Instruction { type Arg2 = ast::Arg2; type Arg2St = ast::Arg2St; -struct ConstantDefinition { - pub dst: spirv::Word, +pub(crate) struct ConstantDefinition { + pub dst: Id, pub typ: ast::ScalarType, pub value: ast::ImmediateValue, } -struct BrachCondition { - predicate: spirv::Word, - if_true: spirv::Word, - if_false: spirv::Word, +pub(crate) struct BrachCondition { + pub(crate) predicate: Id, + pub(crate) if_true: Id, + pub(crate) if_false: Id, +} + +impl, To: ArgParamsEx> Visitable for BrachCondition { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, To>, TranslateError> { + let predicate = visitor.id( + ArgumentDescriptor { + op: self.predicate, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), + )?; + let if_true = self.if_true; + let if_false = self.if_false; + Ok(Statement::Conditional(BrachCondition { + predicate, + if_true, + if_false, + })) + } } #[derive(Clone)] -struct ImplicitConversion { - src: spirv::Word, - dst: spirv::Word, - from: ast::Type, - to: ast::Type, - kind: ConversionKind, - src_sema: ArgumentSemantics, - dst_sema: ArgumentSemantics, +pub(crate) struct ImplicitConversion { + pub(crate) src: Id, + pub(crate) dst: Id, + pub(crate) from_type: ast::Type, + pub(crate) to_type: ast::Type, + pub(crate) from_space: ast::StateSpace, + pub(crate) to_space: ast::StateSpace, + pub(crate) kind: ConversionKind, } -#[derive(PartialEq, Copy, Clone)] -enum ConversionKind { +#[derive(PartialEq, Clone)] +pub(crate) enum ConversionKind { Default, // zero-extend/chop/bitcast depending on types SignExtend, - BitToPtr(ast::LdStateSpace), - PtrToBit(ast::UIntType), - PtrToPtr { spirv_ptr: bool }, + BitToPtr, + PtrToPtr, + AddressOf, } impl ast::PredAt { @@ -6233,10 +7102,13 @@ impl ast::PredAt { } impl<'a> ast::Instruction> { - fn map_variable Result>( + fn map_variable( self, f: &mut F, - ) -> Result, TranslateError> { + ) -> Result, TranslateError> + where + F: for<'x> FnMut(&'x str) -> Result, + { match self { ast::Instruction::Call(call) => { let call_inst = ast::CallInst { @@ -6252,6 +7124,7 @@ impl<'a> ast::Instruction> { .into_iter() .map(|p| p.map_variable(f)) .collect::>()?, + prototype: call.prototype.map(f).transpose()?, }; Ok(ast::Instruction::Call(call_inst)) } @@ -6260,17 +7133,419 @@ impl<'a> ast::Instruction> { } } +pub(crate) struct Arg4CarryOut { + pub dst: P::Operand, + pub carry_out: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, + pub src3: P::Operand, +} + +impl Arg4CarryOut { + fn map>( + self, + visitor: &mut V, + type_: ast::ScalarType, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let carry_out = visitor.operand( + ArgumentDescriptor { + op: self.carry_out, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src3 = visitor.operand( + ArgumentDescriptor { + op: self.src3, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + Ok(Arg4CarryOut { + dst, + src1, + src2, + src3, + carry_out, + }) + } + + fn new(arg: ast::Arg4, carry_flag: T::Operand) -> Arg4CarryOut { + Arg4CarryOut { + dst: arg.dst, + src1: arg.src1, + src2: arg.src2, + src3: arg.src3, + carry_out: carry_flag, + } + } +} + +pub(crate) struct Arg4CarryIn { + pub dst: P::Operand, + pub carry_out: Option, + pub carry_in: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, + pub src3: P::Operand, +} + +impl Arg4CarryIn { + fn map>( + self, + visitor: &mut V, + type_: ast::ScalarType, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let carry_out = self + .carry_out + .map(|carry_out| { + visitor.operand( + ArgumentDescriptor { + op: carry_out, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + ) + }) + .transpose()?; + let carry_in = visitor.operand( + ArgumentDescriptor { + op: self.carry_in, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src3 = visitor.operand( + ArgumentDescriptor { + op: self.src3, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + Ok(Arg4CarryIn { + dst, + src1, + src2, + src3, + carry_in, + carry_out, + }) + } +} + +impl Arg4CarryIn +where + T::Operand: Copy, +{ + fn new(arg: ast::Arg4, carry_out: bool, carry_flag: T::Operand) -> Arg4CarryIn { + Arg4CarryIn { + dst: arg.dst, + src1: arg.src1, + src2: arg.src2, + src3: arg.src3, + carry_in: carry_flag, + carry_out: if carry_out { Some(carry_flag) } else { None }, + } + } +} + +pub(crate) struct Arg3CarryOut { + pub dst: P::Operand, + pub carry_flag: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, +} + +impl Arg3CarryOut

{ + fn map>( + self, + visitor: &mut V, + type_: ast::ScalarType, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let carry_flag = visitor.operand( + ArgumentDescriptor { + op: self.carry_flag, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + Ok(Arg3CarryOut { + dst, + carry_flag, + src1, + src2, + }) + } + + fn new(args: ast::Arg3

, carry_flag: P::Operand) -> Arg3CarryOut

{ + Self { + dst: args.dst, + carry_flag, + src1: args.src1, + src2: args.src2, + } + } +} + +pub(crate) struct Arg3CarryIn { + pub dst: P::Operand, + pub carry_out: Option, + pub carry_in: P::Operand, + pub src1: P::Operand, + pub src2: P::Operand, +} + +impl Arg3CarryIn

{ + fn map>( + self, + visitor: &mut V, + type_: ast::ScalarType, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let carry_out = self + .carry_out + .map(|carry_out| { + visitor.operand( + ArgumentDescriptor { + op: carry_out, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + ) + }) + .transpose()?; + let carry_in = visitor.operand( + ArgumentDescriptor { + op: self.carry_in, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(type_), + ast::StateSpace::Reg, + )?; + Ok(Arg3CarryIn { + dst, + carry_in, + carry_out, + src1, + src2, + }) + } +} + +impl Arg3CarryIn

+where + P::Operand: Copy, +{ + fn new(args: ast::Arg3

, carry_out: bool, carry_flag: P::Operand) -> Arg3CarryIn

{ + Arg3CarryIn { + dst: args.dst, + carry_in: carry_flag, + carry_out: if carry_out { Some(carry_flag) } else { None }, + src1: args.src1, + src2: args.src2, + } + } +} + +pub(crate) struct VisitAddC(pub ast::ScalarType, pub Arg3CarryIn

); + +impl, U: ArgParamsEx> Visitable for VisitAddC { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::AddC(self.0, self.1.map(visitor, self.0)?)) + } +} + +pub(crate) struct VisitAddCC(pub ast::ScalarType, pub Arg3CarryOut

); + +impl, U: ArgParamsEx> Visitable for VisitAddCC { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::AddCC(self.0, self.1.map(visitor, self.0)?)) + } +} + +pub(crate) struct VisitSubC(pub ast::ScalarType, pub Arg3CarryIn

); + +impl, U: ArgParamsEx> Visitable for VisitSubC { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::SubC(self.0, self.1.map(visitor, self.0)?)) + } +} + +pub(crate) struct VisitSubCC(pub ast::ScalarType, pub Arg3CarryOut

); + +impl, U: ArgParamsEx> Visitable for VisitSubCC { + fn visit( + self, + visitor: &mut impl ArgumentMapVisitor, + ) -> Result, U>, TranslateError> { + Ok(Statement::SubCC(self.0, self.1.map(visitor, self.0)?)) + } +} + impl ast::Arg1 { fn map>( self, visitor: &mut V, - t: Option<&ast::Type>, + is_dst: bool, + t: Option<(&ast::Type, ast::StateSpace)>, ) -> Result, TranslateError> { let new_src = visitor.id( ArgumentDescriptor { op: self.src, - is_dst: false, - sema: ArgumentSemantics::Default, + is_dst, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, )?; @@ -6287,9 +7562,11 @@ impl ast::Arg1Bar { ArgumentDescriptor { op: self.src, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, )?; Ok(ast::Arg1Bar { src: new_src }) } @@ -6305,17 +7582,21 @@ impl ast::Arg2 { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let new_src = visitor.operand( ArgumentDescriptor { op: self.src, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; Ok(ast::Arg2 { dst: new_dst, @@ -6323,6 +7604,44 @@ impl ast::Arg2 { }) } + fn map_cvt>( + self, + visitor: &mut V, + dst_t: ast::ScalarType, + src_t: ast::ScalarType, + is_int_to_int: bool, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: if is_int_to_int { + Some(should_convert_relaxed_dst_wrapper) + } else { + None + }, + }, + &ast::Type::Scalar(dst_t), + ast::StateSpace::Reg, + )?; + let src = visitor.operand( + ArgumentDescriptor { + op: self.src, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: if is_int_to_int { + Some(should_convert_relaxed_src_wrapper) + } else { + None + }, + }, + &ast::Type::Scalar(src_t), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg2 { dst, src }) + } + fn map_different_types>( self, visitor: &mut V, @@ -6333,17 +7652,21 @@ impl ast::Arg2 { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, dst_t, + ast::StateSpace::Reg, )?; let src = visitor.operand( ArgumentDescriptor { op: self.src, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, src_t, + ast::StateSpace::Reg, )?; Ok(ast::Arg2 { dst, src }) } @@ -6359,26 +7682,21 @@ impl ast::Arg2Ld { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::DefaultRelaxed, + is_memory_access: false, + non_default_implicit_conversion: Some(should_convert_relaxed_dst_wrapper), }, &ast::Type::from(details.typ.clone()), + ast::StateSpace::Reg, )?; - 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 - }, + is_memory_access: true, + non_default_implicit_conversion: None, }, - &ast::Type::Pointer( - ast::PointerType::from(details.typ.clone()), - details.state_space, - ), + &details.typ, + details.state_space, )?; Ok(ast::Arg2Ld { dst, src }) } @@ -6388,32 +7706,28 @@ impl ast::Arg2St { fn map>( self, visitor: &mut V, - details: &ast::StData, + type_: &ast::Type, + state_space: ast::StateSpace, ) -> Result, 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 - }, + is_memory_access: true, + non_default_implicit_conversion: None, }, - &ast::Type::Pointer( - ast::PointerType::from(details.typ.clone()), - details.state_space.to_ld_ss(), - ), + &type_, + state_space, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::DefaultRelaxed, + is_memory_access: false, + non_default_implicit_conversion: Some(should_convert_relaxed_src_wrapper), }, - &details.typ.clone().into(), + &type_.clone().into(), + ast::StateSpace::Reg, )?; Ok(ast::Arg2St { src1, src2 }) } @@ -6429,28 +7743,28 @@ impl ast::Arg2Mov { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &details.typ.clone().into(), + ast::StateSpace::Reg, )?; let src = visitor.operand( ArgumentDescriptor { op: self.src, is_dst: false, - sema: if details.src_is_address { - ArgumentSemantics::Address - } else { - ArgumentSemantics::Default - }, + is_memory_access: false, + non_default_implicit_conversion: Some(implicit_conversion_mov), }, &details.typ.clone().into(), + ast::StateSpace::Reg, )?; Ok(ast::Arg2Mov { dst, src }) } } impl ast::Arg3 { - fn map_non_shift>( + fn map_generic>( self, visitor: &mut V, typ: &ast::Type, @@ -6465,25 +7779,70 @@ impl ast::Arg3 { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, wide_type.as_ref().unwrap_or(typ), + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, typ, + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, typ, + ast::StateSpace::Reg, + )?; + Ok(ast::Arg3 { dst, src1, src2 }) + } + + fn map_different_types>( + self, + visitor: &mut V, + dst_type: &ast::Type, + src_type: &ast::Type, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + dst_type, + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + src_type, + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + src_type, + ast::StateSpace::Reg, )?; Ok(ast::Arg3 { dst, src1, src2 }) } @@ -6497,25 +7856,31 @@ impl ast::Arg3 { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, )?; Ok(ast::Arg3 { dst, src1, src2 }) } @@ -6524,38 +7889,322 @@ impl ast::Arg3 { self, visitor: &mut V, t: ast::ScalarType, - state_space: ast::AtomSpace, + state_space: ast::StateSpace, ) -> Result, TranslateError> { let scalar_type = ast::ScalarType::from(t); let dst = visitor.operand( ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(scalar_type), + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::PhysicalPointer, + is_memory_access: true, + non_default_implicit_conversion: None, }, - &ast::Type::Pointer( - ast::PointerType::Scalar(scalar_type), - state_space.to_ld_ss(), - ), + &ast::Type::Scalar(scalar_type), + state_space, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(scalar_type), + ast::StateSpace::Reg, )?; Ok(ast::Arg3 { dst, src1, src2 }) } + + fn map_prmt>( + self, + visitor: &mut V, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg3 { dst, src1, src2 }) + } + + fn map_vote>( + self, + visitor: &mut V, + mode: ast::VoteMode, + ) -> Result, TranslateError> { + let dst_type = match mode { + ast::VoteMode::Ballot => ast::ScalarType::B32, + ast::VoteMode::All | ast::VoteMode::Any | ast::VoteMode::Uni => ast::ScalarType::Pred, + }; + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(dst_type), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg3 { dst, src1, src2 }) + } + + fn map_bar_red>( + self, + visitor: &mut V, + op: ast::ReductionOp, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(op.dst_type()), + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg3 { dst, src1, src2 }) + } +} + +fn texture_geometry_to_vec_length(geometry: ast::TextureGeometry) -> u8 { + match geometry { + ast::TextureGeometry::OneD | ast::TextureGeometry::Array1D => 1u8, + ast::TextureGeometry::TwoD | ast::TextureGeometry::Array2D => 2, + ast::TextureGeometry::ThreeD => 4, + } +} + +impl ast::Arg4Tex { + fn map>( + self, + visitor: &mut V, + (image_type, image_space): (ast::Type, ast::StateSpace), + geometry: ast::TextureGeometry, + value_type: ast::Type, + coordinate_type: ast::ScalarType, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: Some(should_convert_relaxed_dst_wrapper), + }, + &value_type, + ast::StateSpace::Reg, + )?; + let image = visitor.operand( + ArgumentDescriptor { + op: self.image, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &image_type, + image_space, + )?; + let layer = self + .layer + .map(|layer| { + visitor.operand( + ArgumentDescriptor { + op: layer, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + ) + }) + .transpose()?; + let coord_length = texture_geometry_to_vec_length(geometry); + let coordinates = visitor.operand( + ArgumentDescriptor { + op: self.coordinates, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Vector(coordinate_type, coord_length), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg4Tex { + dst, + image, + layer, + coordinates, + }) + } +} + +impl ast::Arg4Sust { + pub(crate) fn map>( + self, + visitor: &mut V, + details: &ast::SurfaceDetails, + ) -> Result, TranslateError> { + let image = visitor.operand( + ArgumentDescriptor { + op: self.image, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Surfref, + ast::StateSpace::Global, + )?; + let layer = self + .layer + .map(|layer| { + visitor.operand( + ArgumentDescriptor { + op: layer, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + ) + }) + .transpose()?; + let coord_length = texture_geometry_to_vec_length(details.geometry); + let coordinates = visitor.operand( + ArgumentDescriptor { + op: self.coordinates, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Vector(ast::ScalarType::B32, coord_length), + ast::StateSpace::Reg, + )?; + let value_type = details.value_type(); + let value = visitor.operand( + ArgumentDescriptor { + op: self.value, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: Some(should_convert_relaxed_src_wrapper), + }, + &value_type, + ast::StateSpace::Reg, + )?; + Ok(ast::Arg4Sust { + image, + coordinates, + layer, + value, + }) + } +} + +impl ast::TextureGeometry { + fn as_ptx(self) -> &'static str { + match self { + ast::TextureGeometry::OneD => "1d", + ast::TextureGeometry::TwoD => "2d", + ast::TextureGeometry::ThreeD => "3d", + ast::TextureGeometry::Array1D => "a1d", + ast::TextureGeometry::Array2D => "a2d", + } + } +} + +impl ast::SurfaceDetails { + fn value_type(&self) -> ast::Type { + match self.vector { + Some(vec_length) => ast::Type::Vector(self.type_, vec_length), + None => ast::Type::Scalar(self.type_), + } + } + + fn vector_ptx(&self) -> Result<&'static str, TranslateError> { + Ok(match self.vector { + Some(2) => "_v2", + Some(4) => "_v4", + Some(_) => return Err(TranslateError::unreachable()), + None => "", + }) + } } impl ast::Arg4 { @@ -6566,41 +8215,49 @@ impl ast::Arg4 { is_wide: bool, ) -> Result, TranslateError> { let wide_type = if is_wide { - Some(t.clone().widen()?) + t.clone().widen()? } else { - None + t.clone() }; let dst = visitor.operand( ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - wide_type.as_ref().unwrap_or(t), + &wide_type, + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src3 = visitor.operand( ArgumentDescriptor { op: self.src3, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - t, + &wide_type, + ast::StateSpace::Reg, )?; Ok(ast::Arg4 { dst, @@ -6613,39 +8270,47 @@ impl ast::Arg4 { fn map_selp>( self, visitor: &mut V, - t: ast::SelpType, + t: ast::ScalarType, ) -> Result, TranslateError> { let dst = visitor.operand( ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(t.into()), + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(t.into()), + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(t.into()), + ast::StateSpace::Reg, )?; let src3 = visitor.operand( ArgumentDescriptor { op: self.src3, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, )?; Ok(ast::Arg4 { dst, @@ -6658,44 +8323,49 @@ impl ast::Arg4 { fn map_atom>( self, visitor: &mut V, - t: ast::BitType, - state_space: ast::AtomSpace, + t: ast::ScalarType, + state_space: ast::StateSpace, ) -> Result, TranslateError> { let scalar_type = ast::ScalarType::from(t); let dst = visitor.operand( ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(scalar_type), + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::PhysicalPointer, + is_memory_access: true, + non_default_implicit_conversion: None, }, - &ast::Type::Pointer( - ast::PointerType::Scalar(scalar_type), - state_space.to_ld_ss(), - ), + &ast::Type::Scalar(scalar_type), + state_space, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(scalar_type), + ast::StateSpace::Reg, )?; let src3 = visitor.operand( ArgumentDescriptor { op: self.src3, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(scalar_type), + ast::StateSpace::Reg, )?; Ok(ast::Arg4 { dst, @@ -6714,34 +8384,42 @@ impl ast::Arg4 { ArgumentDescriptor { op: self.dst, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, typ, + ast::StateSpace::Reg, )?; let src1 = visitor.operand( ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, typ, + ast::StateSpace::Reg, )?; let u32_type = ast::Type::Scalar(ast::ScalarType::U32); let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &u32_type, + ast::StateSpace::Reg, )?; let src3 = visitor.operand( ArgumentDescriptor { op: self.src3, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &u32_type, + ast::StateSpace::Reg, )?; Ok(ast::Arg4 { dst, @@ -6762,9 +8440,13 @@ impl ast::Arg4Setp { ArgumentDescriptor { op: self.dst1, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ast::Type::Scalar(ast::ScalarType::Pred)), + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), )?; let dst2 = self .dst2 @@ -6773,9 +8455,13 @@ impl ast::Arg4Setp { ArgumentDescriptor { op: dst2, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ast::Type::Scalar(ast::ScalarType::Pred)), + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), ) }) .transpose()?; @@ -6783,17 +8469,21 @@ impl ast::Arg4Setp { ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; Ok(ast::Arg4Setp { dst1, @@ -6804,6 +8494,72 @@ impl ast::Arg4Setp { } } +impl ast::Arg5 { + fn map_bfi>( + self, + visitor: &mut V, + base_type: &ast::Type, + ) -> Result, TranslateError> { + let dst = visitor.operand( + ArgumentDescriptor { + op: self.dst, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + base_type, + ast::StateSpace::Reg, + )?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + base_type, + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + base_type, + ast::StateSpace::Reg, + )?; + let src3 = visitor.operand( + ArgumentDescriptor { + op: self.src3, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + )?; + let src4 = visitor.operand( + ArgumentDescriptor { + op: self.src4, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::U32), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg5 { + dst, + src1, + src2, + src3, + src4, + }) + } +} + impl ast::Arg5Setp { fn map>( self, @@ -6814,9 +8570,13 @@ impl ast::Arg5Setp { ArgumentDescriptor { op: self.dst1, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ast::Type::Scalar(ast::ScalarType::Pred)), + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), )?; let dst2 = self .dst2 @@ -6825,9 +8585,13 @@ impl ast::Arg5Setp { ArgumentDescriptor { op: dst2, is_dst: true, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, - Some(&ast::Type::Scalar(ast::ScalarType::Pred)), + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), ) }) .transpose()?; @@ -6835,25 +8599,31 @@ impl ast::Arg5Setp { ArgumentDescriptor { op: self.src1, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src2 = visitor.operand( ArgumentDescriptor { op: self.src2, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, t, + ast::StateSpace::Reg, )?; let src3 = visitor.operand( ArgumentDescriptor { op: self.src3, is_dst: false, - sema: ArgumentSemantics::Default, + is_memory_access: false, + non_default_implicit_conversion: None, }, &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, )?; Ok(ast::Arg5Setp { dst1, @@ -6865,6 +8635,80 @@ impl ast::Arg5Setp { } } +impl ast::Arg5Shfl { + fn map>( + self, + visitor: &mut V, + ) -> Result, TranslateError> { + let dst1 = visitor.id( + ArgumentDescriptor { + op: self.dst1, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + Some(( + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )), + )?; + let dst2 = self + .dst2 + .map(|dst2| { + visitor.id( + ArgumentDescriptor { + op: dst2, + is_dst: true, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + Some(( + &ast::Type::Scalar(ast::ScalarType::Pred), + ast::StateSpace::Reg, + )), + ) + }) + .transpose()?; + let src1 = visitor.operand( + ArgumentDescriptor { + op: self.src1, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + let src2 = visitor.operand( + ArgumentDescriptor { + op: self.src2, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + let src3 = visitor.operand( + ArgumentDescriptor { + op: self.src3, + is_dst: false, + is_memory_access: false, + non_default_implicit_conversion: None, + }, + &ast::Type::Scalar(ast::ScalarType::B32), + ast::StateSpace::Reg, + )?; + Ok(ast::Arg5Shfl { + dst1, + dst2, + src1, + src2, + src3, + }) + } +} + impl ast::Operand { fn map_variable Result>( self, @@ -6875,142 +8719,79 @@ impl ast::Operand { 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::>()?) - } + ast::Operand::VecPack(vec) => ast::Operand::VecPack( + vec.into_iter() + .map(|reg_or_immediate| { + Ok::<_, TranslateError>(match reg_or_immediate { + ast::RegOrImmediate::Reg(reg) => ast::RegOrImmediate::Reg(f(reg)?), + ast::RegOrImmediate::Imm(imm) => ast::RegOrImmediate::Imm(imm), + }) + }) + .collect::>()?, + ), }) } } -impl ast::Operand { - fn unwrap_reg(&self) -> Result { - 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, + pub(crate) fn widen(self) -> Result { + let kind = self.kind(); + let width = self.size_of(); + if (kind != ast::ScalarKind::Signed + && kind != ast::ScalarKind::Unsigned + && kind != ast::ScalarKind::Bit) + || (width == 8) + { + return Err(TranslateError::mismatched_type()); } + Ok(ast::ScalarType::from_parts(width * 2, kind)) } - fn from_parts(width: u8, kind: ScalarKind) -> Self { + pub(crate) fn from_parts(width: u8, kind: ast::ScalarKind) -> Self { match kind { - ScalarKind::Float => match width { + ast::ScalarKind::Float => match width { 2 => ast::ScalarType::F16, 4 => ast::ScalarType::F32, 8 => ast::ScalarType::F64, _ => unreachable!(), }, - ScalarKind::Bit => match width { + ast::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 { + ast::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 { + ast::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 { + ast::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, + ast::ScalarKind::Pred => ast::ScalarType::Pred, } } } 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(), - }) + pub(crate) fn get_type(&self) -> ast::ScalarType { + match self { + ast::ArithDetails::Unsigned(t) => *t, + ast::ArithDetails::Signed(d) => d.typ, + ast::ArithDetails::Float(d) => d.typ, + } } } @@ -7025,12 +8806,12 @@ impl ast::MulDetails { } 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(), - }) + pub(crate) fn get_type(&self) -> ast::ScalarType { + match self { + ast::MinMaxDetails::Signed(t) => *t, + ast::MinMaxDetails::Unsigned(t) => *t, + ast::MinMaxDetails::Float(d) => d.typ, + } } } @@ -7055,60 +8836,35 @@ impl ast::AtomInnerDetails { } } -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::StateSpace { + fn is_compatible(self, other: ast::StateSpace) -> bool { + self == other + || self == ast::StateSpace::Reg && other == ast::StateSpace::Sreg + || self == ast::StateSpace::Sreg && other == ast::StateSpace::Reg } -} -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 { + fn coerces_to_generic(self) -> bool { 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, + ast::StateSpace::Global + | ast::StateSpace::Const + | ast::StateSpace::Local + | ast::StateSpace::Shared => true, + ast::StateSpace::Reg + | ast::StateSpace::Param + | ast::StateSpace::Generic + | ast::StateSpace::Sreg => false, } } -} -impl From 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 ast::Operand { - fn underlying(&self) -> Option<&T> { + fn is_addressable(self) -> bool { 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, + ast::StateSpace::Const + | ast::StateSpace::Generic + | ast::StateSpace::Global + | ast::StateSpace::Local + | ast::StateSpace::Shared + | ast::StateSpace::Param => true, + ast::StateSpace::Reg | ast::StateSpace::Sreg => false, } } } @@ -7123,140 +8879,115 @@ impl ast::MulDetails { } } -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::SurfaceDetails { + fn suffix(&self) -> &'static str { + match self.direct { + true => "", + false => "indirect_", } } } -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::TexDetails { + fn suffix(&self) -> &'static str { + match self.direct { + true => "", + false => "_indirect", } } } -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, +fn default_implicit_conversion( + (operand_space, operand_type): (ast::StateSpace, &ast::Type), + (instruction_space, instruction_type): (ast::StateSpace, &ast::Type), ) -> Result, TranslateError> { - bitcast_physical_pointer(operand_type, instr_type, ss) + if !instruction_space.is_compatible(operand_space) { + default_implicit_conversion_space( + (operand_space, operand_type), + (instruction_space, instruction_type), + ) + } else if instruction_type != operand_type { + default_implicit_conversion_type(instruction_space, operand_type, instruction_type) + } else { + Ok(None) + } } -fn bitcast_physical_pointer( - operand_type: &ast::Type, - instr_type: &ast::Type, - ss: Option, +// Space is different +fn default_implicit_conversion_space( + (operand_space, operand_type): (ast::StateSpace, &ast::Type), + (instruction_space, instruction_type): (ast::StateSpace, &ast::Type), ) -> Result, 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 })) - } + if (instruction_space == ast::StateSpace::Generic && operand_space.coerces_to_generic()) + || (operand_space == ast::StateSpace::Generic && instruction_space.coerces_to_generic()) + { + Ok(Some(ConversionKind::PtrToPtr)) + } else if operand_space.is_compatible(ast::StateSpace::Reg) { + match operand_type { + ast::Type::Pointer(operand_ptr_type, operand_ptr_space) + if *operand_ptr_space == instruction_space => + { + if instruction_type != &ast::Type::Scalar(*operand_ptr_type) { + Ok(Some(ConversionKind::PtrToPtr)) } else { - if ss == Some(ast::LdStateSpace::Generic) - || *instr_space == ast::LdStateSpace::Generic - { - Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false })) - } else { - Err(TranslateError::MismatchedType) - } + Ok(None) } - } else { - Err(TranslateError::MismatchedType) } + // TODO: 32 bit + ast::Type::Scalar(ast::ScalarType::B64) + | ast::Type::Scalar(ast::ScalarType::U64) + | ast::Type::Scalar(ast::ScalarType::S64) => match instruction_space { + ast::StateSpace::Global + | ast::StateSpace::Generic + | ast::StateSpace::Const + | ast::StateSpace::Local + | ast::StateSpace::Param + | ast::StateSpace::Shared => Ok(Some(ConversionKind::BitToPtr)), + _ => Err(TranslateError::mismatched_type()), + }, + ast::Type::Scalar(ast::ScalarType::B32) + | ast::Type::Scalar(ast::ScalarType::U32) + | ast::Type::Scalar(ast::ScalarType::S32) => match instruction_space { + ast::StateSpace::Const | ast::StateSpace::Local | ast::StateSpace::Shared => { + Ok(Some(ConversionKind::BitToPtr)) + } + _ => Err(TranslateError::mismatched_type()), + }, + _ => Err(TranslateError::mismatched_type()), } - 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 instruction_space.is_compatible(ast::StateSpace::Reg) { + match instruction_type { + ast::Type::Pointer(instruction_ptr_type, instruction_ptr_space) + if operand_space == *instruction_ptr_space => + { + if operand_type != &ast::Type::Scalar(*instruction_ptr_type) { + Ok(Some(ConversionKind::PtrToPtr)) } else { - if *op_space == ast::LdStateSpace::Generic - || *instr_space == ast::LdStateSpace::Generic - { - Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false })) - } else { - Err(TranslateError::MismatchedType) - } + Ok(None) } - } else { - Err(TranslateError::MismatchedType) } + _ => Err(TranslateError::mismatched_type()), } - _ => Err(TranslateError::MismatchedType), + } else { + Err(TranslateError::mismatched_type()) } } -fn force_bitcast_ptr_to_bit( - _: &ast::Type, - instr_type: &ast::Type, - _: Option, +// Space is same, but type is different +fn default_implicit_conversion_type( + space: ast::StateSpace, + operand_type: &ast::Type, + instruction_type: &ast::Type, ) -> Result, 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))); + if space.is_compatible(ast::StateSpace::Reg) { + if should_bitcast(instruction_type, operand_type) { + Ok(Some(ConversionKind::Default)) + } else { + Err(TranslateError::mismatched_type()) } + } else { + Ok(Some(ConversionKind::PtrToPtr)) } - Err(TranslateError::MismatchedType) } fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool { @@ -7266,18 +8997,28 @@ fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool { 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 + ast::ScalarKind::Bit => operand.kind() != ast::ScalarKind::Bit, + ast::ScalarKind::Float => operand.kind() == ast::ScalarKind::Bit, + ast::ScalarKind::Signed => { + operand.kind() == ast::ScalarKind::Bit + || operand.kind() == ast::ScalarKind::Unsigned } - ScalarKind::Unsigned => { - operand.kind() == ScalarKind::Bit || operand.kind() == ScalarKind::Signed + ast::ScalarKind::Unsigned => { + operand.kind() == ast::ScalarKind::Bit + || operand.kind() == ast::ScalarKind::Signed + || operand.kind() == ast::ScalarKind::Float2 } - ScalarKind::Float2 => false, - ScalarKind::Pred => false, + ast::ScalarKind::Float2 => { + operand.kind() == ast::ScalarKind::Bit + || operand.kind() == ast::ScalarKind::Unsigned + } + ast::ScalarKind::Pred => false, } } + (ast::Type::Scalar(scalar), ast::Type::Vector(vector, width)) + | (ast::Type::Vector(vector, width), ast::Type::Scalar(scalar)) => { + scalar.kind() == ast::ScalarKind::Bit && *width * vector.size_of() == scalar.size_of() + } (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)) @@ -7286,49 +9027,61 @@ fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool { } } -fn should_bitcast_packed( - operand: &ast::Type, - instr: &ast::Type, - ss: Option, +fn implicit_conversion_mov( + (operand_space, operand_type): (ast::StateSpace, &ast::Type), + (instruction_space, instruction_type): (ast::StateSpace, &ast::Type), ) -> Result, 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) + // instruction_space is always reg + if operand_space.is_compatible(ast::StateSpace::Reg) { + if let (ast::Type::Vector(vec_underlying_type, vec_len), ast::Type::Scalar(scalar)) = + (operand_type, instruction_type) { - return Ok(Some(ConversionKind::Default)); + if scalar.kind() == ast::ScalarKind::Bit + && scalar.size_of() == (vec_underlying_type.size_of() * vec_len) + { + return Ok(Some(ConversionKind::Default)); + } } + // TODO: verify .params addressability: + // * kernel arg + // * func arg + // * variable } - should_bitcast_wrapper(operand, instr, ss) + if is_addressable(operand_type, operand_space) { + return Ok(Some(ConversionKind::AddressOf)); + } + default_implicit_conversion( + (operand_space, operand_type), + (instruction_space, instruction_type), + ) } -fn should_bitcast_wrapper( - operand: &ast::Type, - instr: &ast::Type, - _: Option, -) -> Result, TranslateError> { - if instr == operand { - return Ok(None); +fn is_addressable(type_: &ast::Type, state_space: ast::StateSpace) -> bool { + if state_space.is_addressable() { + return true; } - if should_bitcast(instr, operand) { - Ok(Some(ConversionKind::Default)) - } else { - Err(TranslateError::MismatchedType) + if !state_space.is_compatible(ast::StateSpace::Reg) { + return false; + } + match type_ { + ast::Type::Pointer(_, space) => space.is_addressable(), + _ => false, } } fn should_convert_relaxed_src_wrapper( - src_type: &ast::Type, - instr_type: &ast::Type, - _: Option, + (operand_space, operand_type): (ast::StateSpace, &ast::Type), + (instruction_space, instruction_type): (ast::StateSpace, &ast::Type), ) -> Result, TranslateError> { - if src_type == instr_type { + if !operand_space.is_compatible(instruction_space) { + return Err(TranslateError::mismatched_type()); + } + if operand_type == instruction_type { return Ok(None); } - match should_convert_relaxed_src(src_type, instr_type) { + match should_convert_relaxed_src(operand_type, instruction_type) { conv @ Some(_) => Ok(conv), - None => Err(TranslateError::MismatchedType), + None => Err(TranslateError::mismatched_type()), } } @@ -7342,32 +9095,33 @@ fn should_convert_relaxed_src( } match (src_type, instr_type) { (ast::Type::Scalar(src_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() { - ScalarKind::Bit => { + ast::ScalarKind::Bit => { if instr_type.size_of() <= src_type.size_of() { Some(ConversionKind::Default) } else { None } } - ScalarKind::Signed | ScalarKind::Unsigned => { + ast::ScalarKind::Signed | ast::ScalarKind::Unsigned => { if instr_type.size_of() <= src_type.size_of() - && src_type.kind() != ScalarKind::Float + && src_type.kind() != ast::ScalarKind::Float { Some(ConversionKind::Default) } else { None } } - ScalarKind::Float => { - if instr_type.size_of() <= src_type.size_of() && src_type.kind() == ScalarKind::Bit + ast::ScalarKind::Float => { + if instr_type.size_of() <= src_type.size_of() + && src_type.kind() == ast::ScalarKind::Bit { Some(ConversionKind::Default) } else { None } } - ScalarKind::Float2 => todo!(), - ScalarKind::Pred => None, + ast::ScalarKind::Float2 => todo!(), + ast::ScalarKind::Pred => None, }, (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _)) | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => { @@ -7381,16 +9135,18 @@ fn should_convert_relaxed_src( } fn should_convert_relaxed_dst_wrapper( - dst_type: &ast::Type, - instr_type: &ast::Type, - _: Option, + (operand_space, operand_type): (ast::StateSpace, &ast::Type), + (instruction_space, instruction_type): (ast::StateSpace, &ast::Type), ) -> Result, TranslateError> { - if dst_type == instr_type { + if !operand_space.is_compatible(instruction_space) { + return Err(TranslateError::mismatched_type()); + } + if operand_type == instruction_type { return Ok(None); } - match should_convert_relaxed_dst(dst_type, instr_type) { + match should_convert_relaxed_dst(operand_type, instruction_type) { conv @ Some(_) => Ok(conv), - None => Err(TranslateError::MismatchedType), + None => Err(TranslateError::mismatched_type()), } } @@ -7404,15 +9160,15 @@ fn should_convert_relaxed_dst( } match (dst_type, instr_type) { (ast::Type::Scalar(dst_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() { - ScalarKind::Bit => { + ast::ScalarKind::Bit => { if instr_type.size_of() <= dst_type.size_of() { Some(ConversionKind::Default) } else { None } } - ScalarKind::Signed => { - if dst_type.kind() != ScalarKind::Float { + ast::ScalarKind::Signed => { + if dst_type.kind() != ast::ScalarKind::Float { if instr_type.size_of() == dst_type.size_of() { Some(ConversionKind::Default) } else if instr_type.size_of() < dst_type.size_of() { @@ -7424,25 +9180,26 @@ fn should_convert_relaxed_dst( None } } - ScalarKind::Unsigned => { + ast::ScalarKind::Unsigned => { if instr_type.size_of() <= dst_type.size_of() - && dst_type.kind() != ScalarKind::Float + && dst_type.kind() != ast::ScalarKind::Float { Some(ConversionKind::Default) } else { None } } - ScalarKind::Float => { - if instr_type.size_of() <= dst_type.size_of() && dst_type.kind() == ScalarKind::Bit + ast::ScalarKind::Float => { + if instr_type.size_of() <= dst_type.size_of() + && dst_type.kind() == ast::ScalarKind::Bit { Some(ConversionKind::Default) } else { None } } - ScalarKind::Float2 => todo!(), - ScalarKind::Pred => None, + ast::ScalarKind::Float2 => todo!(), + ast::ScalarKind::Pred => None, }, (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _)) | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => { @@ -7455,77 +9212,35 @@ fn should_convert_relaxed_dst( } } -impl<'a> ast::MethodDecl<'a, &'a str> { +impl<'a> ast::MethodDeclaration<'a, &'a str> { fn name(&self) -> &'a str { - match self { - ast::MethodDecl::Kernel { name, .. } => name, - ast::MethodDecl::Func(_, name, _) => name, + match self.name { + ast::MethodName::Kernel(name) => name, + ast::MethodName::Func(name) => name, } } } -struct SpirvMethodDecl<'input> { - input: Vec>, - output: Vec>, - name: MethodName<'input>, - uses_shared_mem: bool, +#[derive(Copy, Clone)] +pub(crate) enum ConstType<'a> { + Type(&'a ast::Type), + ArraySubtype(ast::ScalarType, &'a [u32]), } -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, +impl ast::ScalarType { + pub fn is_integer(self) -> bool { + match self.kind() { + ast::ScalarKind::Unsigned | ast::ScalarKind::Signed | ast::ScalarKind::Bit => true, + ast::ScalarKind::Float | ast::ScalarKind::Float2 | ast::ScalarKind::Pred => false, + } + } +} + +impl ast::ReductionOp { + fn dst_type(self) -> ast::ScalarType { + match self { + ast::ReductionOp::And | ast::ReductionOp::Or => ast::ScalarType::Pred, + ast::ReductionOp::Popc => ast::ScalarType::U32, } } } @@ -7639,4 +9354,39 @@ mod tests { fn should_convert_relaxed_dst_all_combinations() { assert_conversion_table(RELAXED_DST_CONVERSION_TABLE, should_convert_relaxed_dst); } + + #[test] + fn returns_correct_layout_for_array_params() { + use crate::{ModuleParser, ModuleParserExt}; + + let ptx = r#" + .version 6.5 + .target sm_30 + .address_size 64 + + .visible .entry kernel(.param .align 8 .b8 kernel_param[72]) + { + ret; + }"#; + + let ast = ModuleParser::parse_checked(ptx).unwrap(); + if let ast::Directive::Method( + _, + ast::Function { + func_directive: + ast::MethodDeclaration { + input_arguments, .. + }, + .. + }, + ) = &ast.directives[0] + { + assert_eq!(input_arguments.len(), 1); + assert_eq!(input_arguments[0].layout(), unsafe { + Layout::from_size_align_unchecked(72, 8) + }); + } else { + panic!() + } + } } diff --git a/rocblas-sys/Cargo.toml b/rocblas-sys/Cargo.toml new file mode 100644 index 0000000..d3623db --- /dev/null +++ b/rocblas-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rocblas-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "rocblas" + +[lib] diff --git a/rocblas-sys/README b/rocblas-sys/README new file mode 100644 index 0000000..e6e0567 --- /dev/null +++ b/rocblas-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/rocblas/rocblas.h -o src/rocblas.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --allowlist-function "rocblas_.*" --allowlist-var "ROCBLAS_*" --must-use-type rocblas_status -- -I/opt/rocm/include \ No newline at end of file diff --git a/rocblas-sys/build.rs b/rocblas-sys/build.rs new file mode 100644 index 0000000..cd0dd1b --- /dev/null +++ b/rocblas-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=rocblas"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/rocblas-sys/src/lib.rs b/rocblas-sys/src/lib.rs new file mode 100644 index 0000000..dff261c --- /dev/null +++ b/rocblas-sys/src/lib.rs @@ -0,0 +1,3 @@ +#![allow(warnings)] +mod rocblas; +pub use rocblas::*; \ No newline at end of file diff --git a/rocblas-sys/src/rocblas.rs b/rocblas-sys/src/rocblas.rs new file mode 100644 index 0000000..6fba5d2 --- /dev/null +++ b/rocblas-sys/src/rocblas.rs @@ -0,0 +1,10099 @@ +/* automatically generated by rust-bindgen 0.64.0 */ + +#[doc = " \\brief Struct to represent a 16 bit Brain floating-point number."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_bfloat16 { + pub data: u16, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocblas_handle { + _unused: [u8; 0], +} +#[doc = " \\brief rocblas_handle is a structure holding the rocblas library context.\n It must be initialized using rocblas_create_handle(),\n and the returned handle must be passed\n to all subsequent library function calls.\n It should be destroyed at the end using rocblas_destroy_handle()."] +pub type rocblas_handle = *mut _rocblas_handle; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +#[doc = " \\brief Forward declaration of hipStream_t"] +pub type hipStream_t = *mut ihipStream_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipEvent_t { + _unused: [u8; 0], +} +#[doc = " \\brief Forward declaration of hipEvent_t"] +pub type hipEvent_t = *mut ihipEvent_t; +#[doc = " \\brief Opaque base class for device memory allocation"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_device_malloc_base { + _unused: [u8; 0], +} +pub type rocblas_int = i32; +pub type rocblas_stride = i64; +#[doc = " \\brief Structure definition for rocblas_half"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_half { + pub data: u16, +} +#[doc = " \\brief Struct to represent a complex number with single precision real and imaginary parts."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_float_complex { + pub x: f32, + pub y: f32, +} +#[doc = " \\brief Struct to represent a complex number with double precision real and imaginary parts."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_double_complex { + pub x: f64, + pub y: f64, +} +impl rocblas_operation_ { + #[doc = "< Operate with the matrix."] + pub const rocblas_operation_none: rocblas_operation_ = rocblas_operation_(111); +} +impl rocblas_operation_ { + #[doc = "< Operate with the transpose of the matrix."] + pub const rocblas_operation_transpose: rocblas_operation_ = rocblas_operation_(112); +} +impl rocblas_operation_ { + pub const rocblas_operation_conjugate_transpose: rocblas_operation_ = rocblas_operation_(113); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify whether the matrix is to be transposed or not."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_operation_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify whether the matrix is to be transposed or not."] +pub use self::rocblas_operation_ as rocblas_operation; +impl rocblas_fill_ { + #[doc = "< Upper triangle."] + pub const rocblas_fill_upper: rocblas_fill_ = rocblas_fill_(121); +} +impl rocblas_fill_ { + #[doc = "< Lower triangle."] + pub const rocblas_fill_lower: rocblas_fill_ = rocblas_fill_(122); +} +impl rocblas_fill_ { + pub const rocblas_fill_full: rocblas_fill_ = rocblas_fill_(123); +} +#[repr(transparent)] +#[doc = " \\brief Used by the Hermitian, symmetric and triangular matrix\n routines to specify whether the upper, or lower triangle is being referenced."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_fill_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used by the Hermitian, symmetric and triangular matrix\n routines to specify whether the upper, or lower triangle is being referenced."] +pub use self::rocblas_fill_ as rocblas_fill; +impl rocblas_diagonal_ { + #[doc = "< Non-unit triangular."] + pub const rocblas_diagonal_non_unit: rocblas_diagonal_ = rocblas_diagonal_(131); +} +impl rocblas_diagonal_ { + #[doc = "< Unit triangular."] + pub const rocblas_diagonal_unit: rocblas_diagonal_ = rocblas_diagonal_(132); +} +#[repr(transparent)] +#[doc = " \\brief It is used by the triangular matrix routines to specify whether the\n matrix is unit triangular."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_diagonal_(pub ::std::os::raw::c_uint); +#[doc = " \\brief It is used by the triangular matrix routines to specify whether the\n matrix is unit triangular."] +pub use self::rocblas_diagonal_ as rocblas_diagonal; +impl rocblas_side_ { + #[doc = "< Multiply general matrix by symmetric,\nHermitian, or triangular matrix on the left."] + pub const rocblas_side_left: rocblas_side_ = rocblas_side_(141); +} +impl rocblas_side_ { + #[doc = "< Multiply general matrix by symmetric,\nHermitian, or triangular matrix on the right."] + pub const rocblas_side_right: rocblas_side_ = rocblas_side_(142); +} +impl rocblas_side_ { + pub const rocblas_side_both: rocblas_side_ = rocblas_side_(143); +} +#[repr(transparent)] +#[doc = " \\brief Indicates the side matrix A is located relative to matrix B during multiplication."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_side_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates the side matrix A is located relative to matrix B during multiplication."] +pub use self::rocblas_side_ as rocblas_side; +impl rocblas_datatype_ { + #[doc = "< 16-bit floating point, real"] + pub const rocblas_datatype_f16_r: rocblas_datatype_ = rocblas_datatype_(150); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit floating point, real"] + pub const rocblas_datatype_f32_r: rocblas_datatype_ = rocblas_datatype_(151); +} +impl rocblas_datatype_ { + #[doc = "< 64-bit floating point, real"] + pub const rocblas_datatype_f64_r: rocblas_datatype_ = rocblas_datatype_(152); +} +impl rocblas_datatype_ { + #[doc = "< 16-bit floating point, complex"] + pub const rocblas_datatype_f16_c: rocblas_datatype_ = rocblas_datatype_(153); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit floating point, complex"] + pub const rocblas_datatype_f32_c: rocblas_datatype_ = rocblas_datatype_(154); +} +impl rocblas_datatype_ { + #[doc = "< 64-bit floating point, complex"] + pub const rocblas_datatype_f64_c: rocblas_datatype_ = rocblas_datatype_(155); +} +impl rocblas_datatype_ { + #[doc = "< 8-bit signed integer, real"] + pub const rocblas_datatype_i8_r: rocblas_datatype_ = rocblas_datatype_(160); +} +impl rocblas_datatype_ { + #[doc = "< 8-bit unsigned integer, real"] + pub const rocblas_datatype_u8_r: rocblas_datatype_ = rocblas_datatype_(161); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit signed integer, real"] + pub const rocblas_datatype_i32_r: rocblas_datatype_ = rocblas_datatype_(162); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit unsigned integer, real"] + pub const rocblas_datatype_u32_r: rocblas_datatype_ = rocblas_datatype_(163); +} +impl rocblas_datatype_ { + #[doc = "< 8-bit signed integer, complex"] + pub const rocblas_datatype_i8_c: rocblas_datatype_ = rocblas_datatype_(164); +} +impl rocblas_datatype_ { + #[doc = "< 8-bit unsigned integer, complex"] + pub const rocblas_datatype_u8_c: rocblas_datatype_ = rocblas_datatype_(165); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit signed integer, complex"] + pub const rocblas_datatype_i32_c: rocblas_datatype_ = rocblas_datatype_(166); +} +impl rocblas_datatype_ { + #[doc = "< 32-bit unsigned integer, complex"] + pub const rocblas_datatype_u32_c: rocblas_datatype_ = rocblas_datatype_(167); +} +impl rocblas_datatype_ { + #[doc = "< 16-bit bfloat, real"] + pub const rocblas_datatype_bf16_r: rocblas_datatype_ = rocblas_datatype_(168); +} +impl rocblas_datatype_ { + #[doc = "< 16-bit bfloat, complex"] + pub const rocblas_datatype_bf16_c: rocblas_datatype_ = rocblas_datatype_(169); +} +impl rocblas_datatype_ { + #[doc = "< Invalid datatype value, do not use"] + pub const rocblas_datatype_invalid: rocblas_datatype_ = rocblas_datatype_(255); +} +#[repr(transparent)] +#[doc = " \\brief Indicates the precision width of data stored in a blas type."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_datatype_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates the precision width of data stored in a blas type."] +pub use self::rocblas_datatype_ as rocblas_datatype; +impl rocblas_status_ { + #[doc = "< Success"] + pub const rocblas_status_success: rocblas_status_ = rocblas_status_(0); +} +impl rocblas_status_ { + #[doc = "< Handle not initialized, invalid or null"] + pub const rocblas_status_invalid_handle: rocblas_status_ = rocblas_status_(1); +} +impl rocblas_status_ { + #[doc = "< Function is not implemented"] + pub const rocblas_status_not_implemented: rocblas_status_ = rocblas_status_(2); +} +impl rocblas_status_ { + #[doc = "< Invalid pointer argument"] + pub const rocblas_status_invalid_pointer: rocblas_status_ = rocblas_status_(3); +} +impl rocblas_status_ { + #[doc = "< Invalid size argument"] + pub const rocblas_status_invalid_size: rocblas_status_ = rocblas_status_(4); +} +impl rocblas_status_ { + #[doc = "< Failed internal memory allocation, copy or dealloc"] + pub const rocblas_status_memory_error: rocblas_status_ = rocblas_status_(5); +} +impl rocblas_status_ { + #[doc = "< Other internal library failure"] + pub const rocblas_status_internal_error: rocblas_status_ = rocblas_status_(6); +} +impl rocblas_status_ { + #[doc = "< Performance degraded due to low device memory"] + pub const rocblas_status_perf_degraded: rocblas_status_ = rocblas_status_(7); +} +impl rocblas_status_ { + #[doc = "< Unmatched start/stop size query"] + pub const rocblas_status_size_query_mismatch: rocblas_status_ = rocblas_status_(8); +} +impl rocblas_status_ { + #[doc = "< Queried device memory size increased"] + pub const rocblas_status_size_increased: rocblas_status_ = rocblas_status_(9); +} +impl rocblas_status_ { + #[doc = "< Queried device memory size unchanged"] + pub const rocblas_status_size_unchanged: rocblas_status_ = rocblas_status_(10); +} +impl rocblas_status_ { + #[doc = "< Passed argument not valid"] + pub const rocblas_status_invalid_value: rocblas_status_ = rocblas_status_(11); +} +impl rocblas_status_ { + #[doc = "< Nothing preventing function to proceed"] + pub const rocblas_status_continue: rocblas_status_ = rocblas_status_(12); +} +impl rocblas_status_ { + pub const rocblas_status_check_numerics_fail: rocblas_status_ = rocblas_status_(13); +} +#[repr(transparent)] +#[doc = " @brief rocblas status codes definition"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_status_(pub ::std::os::raw::c_uint); +#[doc = " @brief rocblas status codes definition"] +pub use self::rocblas_status_ as rocblas_status; +impl rocblas_pointer_mode_ { + #[doc = " \\brief Scalar values affected by this variable are located on the host."] + pub const rocblas_pointer_mode_host: rocblas_pointer_mode_ = rocblas_pointer_mode_(0); +} +impl rocblas_pointer_mode_ { + #[doc = " \\brief Scalar values affected by this variable are located on the device."] + pub const rocblas_pointer_mode_device: rocblas_pointer_mode_ = rocblas_pointer_mode_(1); +} +#[repr(transparent)] +#[doc = " \\brief Indicates if scalar pointers are on host or device. This is used for\n scalars alpha and beta and for scalar function return values."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_pointer_mode_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates if scalar pointers are on host or device. This is used for\n scalars alpha and beta and for scalar function return values."] +pub use self::rocblas_pointer_mode_ as rocblas_pointer_mode; +impl rocblas_atomics_mode_ { + #[doc = " \\brief Algorithms will refrain from atomics where applicable"] + pub const rocblas_atomics_not_allowed: rocblas_atomics_mode_ = rocblas_atomics_mode_(0); +} +impl rocblas_atomics_mode_ { + #[doc = " \\brief Algorithms will take advantage of atomics where applicable"] + pub const rocblas_atomics_allowed: rocblas_atomics_mode_ = rocblas_atomics_mode_(1); +} +#[repr(transparent)] +#[doc = " \\brief Indicates if atomics operations are allowed. Not allowing atomic operations\n may generally improve determinism and repeatability of results at a cost of performance"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_atomics_mode_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates if atomics operations are allowed. Not allowing atomic operations\n may generally improve determinism and repeatability of results at a cost of performance"] +pub use self::rocblas_atomics_mode_ as rocblas_atomics_mode; +impl rocblas_performance_metric_ { + #[doc = " \\brief Use Tensile's default performance metric for solution selection"] + pub const rocblas_default_performance_metric: rocblas_performance_metric_ = + rocblas_performance_metric_(0); +} +impl rocblas_performance_metric_ { + #[doc = " \\brief Select the solution with the highest GFlops across all compute units"] + pub const rocblas_device_efficiency_performance_metric: rocblas_performance_metric_ = + rocblas_performance_metric_(1); +} +impl rocblas_performance_metric_ { + #[doc = " \\brief Select the solution with the highest GFlops per compute unit it uses. This\n may be useful when running multiple small gemm problems simultaneously"] + pub const rocblas_cu_efficiency_performance_metric: rocblas_performance_metric_ = + rocblas_performance_metric_(2); +} +#[repr(transparent)] +#[doc = " \\brief Indicates which performance metric Tensile uses when selecting the optimal\n solution for gemm problems."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_performance_metric_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates which performance metric Tensile uses when selecting the optimal\n solution for gemm problems."] +pub use self::rocblas_performance_metric_ as rocblas_performance_metric; +impl rocblas_gemm_algo_ { + pub const rocblas_gemm_algo_standard: rocblas_gemm_algo_ = rocblas_gemm_algo_(0); +} +#[repr(transparent)] +#[doc = " \\brief Indicates if layer is active with bitmask"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_gemm_algo_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates if layer is active with bitmask"] +pub use self::rocblas_gemm_algo_ as rocblas_gemm_algo; +impl rocblas_gemm_flags_ { + #[doc = " \\brief Default empty flags"] + pub const rocblas_gemm_flags_none: rocblas_gemm_flags_ = rocblas_gemm_flags_(0); +} +impl rocblas_gemm_flags_ { + #[doc = " \\brief Before ROCm 4.2, this flags is not implemented and rocblas uses packed-Int8x4 by default.\n After ROCm 4.2, set flag is neccesary if we want packed-Int8x4. Default (0x0) uses unpacked."] + pub const rocblas_gemm_flags_pack_int8x4: rocblas_gemm_flags_ = rocblas_gemm_flags_(1); +} +impl rocblas_gemm_flags_ { + #[doc = " \\brief Select the gemm problem with the highest efficiency per compute unit used. Useful for running multiple smaller problems\n simultaneously. This takes precedence over the performance metric set in rocblas_handle and currently only works for\n gemm_*_ex problems."] + pub const rocblas_gemm_flags_use_cu_efficiency: rocblas_gemm_flags_ = rocblas_gemm_flags_(2); +} +impl rocblas_gemm_flags_ { + #[doc = " \\brief Select an alternate implementation for the MI200 FP16 HPA\n (High Precision Accumulate) GEMM kernel utilizing the BF16 matrix\n instructions with reduced accuracy in cases where computation cannot\n tolerate the FP16 matrix instructions flushing subnormal FP16\n input/output data to zero. See the \"MI200 (gfx90a) Considerations\"\n section for more details."] + pub const rocblas_gemm_flags_fp16_alt_impl: rocblas_gemm_flags_ = rocblas_gemm_flags_(4); +} +#[repr(transparent)] +#[doc = " \\brief Control flags passed into gemm algorithms invoked by Tensile Host"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_gemm_flags_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Control flags passed into gemm algorithms invoked by Tensile Host"] +pub use self::rocblas_gemm_flags_ as rocblas_gemm_flags; +impl rocblas_int8_type_for_hipblas_ { + pub const rocblas_int8_type_for_hipblas_default: rocblas_int8_type_for_hipblas_ = + rocblas_int8_type_for_hipblas_(0); +} +impl rocblas_int8_type_for_hipblas_ { + pub const rocblas_int8_type_for_hipblas_int8: rocblas_int8_type_for_hipblas_ = + rocblas_int8_type_for_hipblas_(1); +} +impl rocblas_int8_type_for_hipblas_ { + pub const rocblas_int8_type_for_hipblas_pack_int8x4: rocblas_int8_type_for_hipblas_ = + rocblas_int8_type_for_hipblas_(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_int8_type_for_hipblas_(pub ::std::os::raw::c_uint); +pub use self::rocblas_int8_type_for_hipblas_ as rocblas_int8_type_for_hipblas; +extern "C" { + #[must_use] + #[doc = " \\brief Create handle"] + pub fn rocblas_create_handle(handle: *mut rocblas_handle) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Destroy handle"] + pub fn rocblas_destroy_handle(handle: rocblas_handle) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Set stream for handle"] + pub fn rocblas_set_stream(handle: rocblas_handle, stream: hipStream_t) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Get stream [0] from handle"] + pub fn rocblas_get_stream(handle: rocblas_handle, stream: *mut hipStream_t) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Set rocblas_pointer_mode"] + pub fn rocblas_set_pointer_mode( + handle: rocblas_handle, + pointer_mode: rocblas_pointer_mode, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Get rocblas_pointer_mode"] + pub fn rocblas_get_pointer_mode( + handle: rocblas_handle, + pointer_mode: *mut rocblas_pointer_mode, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Set rocblas_int8_type_for_hipblas"] + pub fn rocblas_set_int8_type_for_hipblas( + handle: rocblas_handle, + int8_type: rocblas_int8_type_for_hipblas, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Get rocblas_int8_type_for_hipblas"] + pub fn rocblas_get_int8_type_for_hipblas( + handle: rocblas_handle, + int8_type: *mut rocblas_int8_type_for_hipblas, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Set rocblas_atomics_mode"] + pub fn rocblas_set_atomics_mode( + handle: rocblas_handle, + atomics_mode: rocblas_atomics_mode, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Get rocblas_atomics_mode"] + pub fn rocblas_get_atomics_mode( + handle: rocblas_handle, + atomics_mode: *mut rocblas_atomics_mode, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Query the preferable supported int8 input layout for gemm\n\\details\nIndicates the supported int8 input layout for gemm according to the device.\nIf the device supports packed-int8x4 (1) only, output flag is rocblas_gemm_flags_pack_int8x4\nand users must bitwise-or your flag with rocblas_gemm_flags_pack_int8x4.\nIf output flag is rocblas_gemm_flags_none (0), then unpacked int8 is preferable and suggested.\n@param[in]\nhandle [rocblas_handle]\nthe handle of device\n@param[out]\nflag pointer to rocblas_gemm_flags"] + pub fn rocblas_query_int8_layout_flag( + handle: rocblas_handle, + flag: *mut rocblas_gemm_flags, + ) -> rocblas_status; +} +extern "C" { + #[doc = " \\brief Indicates whether the pointer is on the host or device."] + pub fn rocblas_pointer_to_mode(ptr: *mut ::std::os::raw::c_void) -> rocblas_pointer_mode; +} +extern "C" { + #[must_use] + #[doc = " \\brief Copy vector from host to device\n@param[in]\nn [rocblas_int]\nnumber of elements in the vector\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\nx pointer to vector on the host\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[out]\ny pointer to vector on the device\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of the vector"] + pub fn rocblas_set_vector( + n: rocblas_int, + elem_size: rocblas_int, + x: *const ::std::os::raw::c_void, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Copy vector from device to host\n@param[in]\nn [rocblas_int]\nnumber of elements in the vector\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\nx pointer to vector on the device\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[out]\ny pointer to vector on the host\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of the vector"] + pub fn rocblas_get_vector( + n: rocblas_int, + elem_size: rocblas_int, + x: *const ::std::os::raw::c_void, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Copy matrix from host to device\n@param[in]\nrows [rocblas_int]\nnumber of rows in matrices\n@param[in]\ncols [rocblas_int]\nnumber of columns in matrices\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\na pointer to matrix on the host\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A, lda >= rows\n@param[out]\nb pointer to matrix on the GPU\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B, ldb >= rows"] + pub fn rocblas_set_matrix( + rows: rocblas_int, + cols: rocblas_int, + elem_size: rocblas_int, + a: *const ::std::os::raw::c_void, + lda: rocblas_int, + b: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Copy matrix from device to host\n@param[in]\nrows [rocblas_int]\nnumber of rows in matrices\n@param[in]\ncols [rocblas_int]\nnumber of columns in matrices\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\na pointer to matrix on the GPU\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A, lda >= rows\n@param[out]\nb pointer to matrix on the host\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B, ldb >= rows"] + pub fn rocblas_get_matrix( + rows: rocblas_int, + cols: rocblas_int, + elem_size: rocblas_int, + a: *const ::std::os::raw::c_void, + lda: rocblas_int, + b: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Asynchronously copy vector from host to device\n\\details\nrocblas_set_vector_async copies a vector from pinned host memory to device memory asynchronously.\nMemory on the host must be allocated with hipHostMalloc or the transfer will be synchronous.\n@param[in]\nn [rocblas_int]\nnumber of elements in the vector\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\nx pointer to vector on the host\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[out]\ny pointer to vector on the device\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[in]\nstream specifies the stream into which this transfer request is queued"] + pub fn rocblas_set_vector_async( + n: rocblas_int, + elem_size: rocblas_int, + x: *const ::std::os::raw::c_void, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + incy: rocblas_int, + stream: hipStream_t, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Asynchronously copy vector from device to host\n\\details\nrocblas_get_vector_async copies a vector from pinned host memory to device memory asynchronously.\nMemory on the host must be allocated with hipHostMalloc or the transfer will be synchronous.\n@param[in]\nn [rocblas_int]\nnumber of elements in the vector\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\nx pointer to vector on the device\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[out]\ny pointer to vector on the host\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of the vector\n@param[in]\nstream specifies the stream into which this transfer request is queued"] + pub fn rocblas_get_vector_async( + n: rocblas_int, + elem_size: rocblas_int, + x: *const ::std::os::raw::c_void, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + incy: rocblas_int, + stream: hipStream_t, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Asynchronously copy matrix from host to device\n\\details\nrocblas_set_matrix_async copies a matrix from pinned host memory to device memory asynchronously.\nMemory on the host must be allocated with hipHostMalloc or the transfer will be synchronous.\n@param[in]\nrows [rocblas_int]\nnumber of rows in matrices\n@param[in]\ncols [rocblas_int]\nnumber of columns in matrices\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\na pointer to matrix on the host\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A, lda >= rows\n@param[out]\nb pointer to matrix on the GPU\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B, ldb >= rows\n@param[in]\nstream specifies the stream into which this transfer request is queued"] + pub fn rocblas_set_matrix_async( + rows: rocblas_int, + cols: rocblas_int, + elem_size: rocblas_int, + a: *const ::std::os::raw::c_void, + lda: rocblas_int, + b: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + stream: hipStream_t, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief asynchronously copy matrix from device to host\n\\details\nrocblas_get_matrix_async copies a matrix from device memory to pinned host memory asynchronously.\nMemory on the host must be allocated with hipHostMalloc or the transfer will be synchronous.\n@param[in]\nrows [rocblas_int]\nnumber of rows in matrices\n@param[in]\ncols [rocblas_int]\nnumber of columns in matrices\n@param[in]\nelem_size [rocblas_int]\nnumber of bytes per element in the matrix\n@param[in]\na pointer to matrix on the GPU\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A, lda >= rows\n@param[out]\nb pointer to matrix on the host\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B, ldb >= rows\n@param[in]\nstream specifies the stream into which this transfer request is queued"] + pub fn rocblas_get_matrix_async( + rows: rocblas_int, + cols: rocblas_int, + elem_size: rocblas_int, + a: *const ::std::os::raw::c_void, + lda: rocblas_int, + b: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + stream: hipStream_t, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " Function to set start/stop event handlers (for internal use only)"] + pub fn rocblas_set_start_stop_events( + handle: rocblas_handle, + startEvent: hipEvent_t, + stopEvent: hipEvent_t, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_set_solution_fitness_query( + handle: rocblas_handle, + fitness: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief specifies the performance metric that solution selection uses\n\\details\nDetermines which performance metric will be used by Tensile when selecting the optimal solution\nfor gemm problems. If a valid solution benchmarked for this performance metric does not exist\nfor a problem, Tensile will default to a solution benchmarked for overall performance instead.\n@param[in]\nhandle [rocblas_handle]\nthe handle of device\n@param[in]\nmetric [rocblas_performance_metric]\nthe performance metric to be used"] + pub fn rocblas_set_performance_metric( + handle: rocblas_handle, + metric: rocblas_performance_metric, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief returns the performance metric being used for solution selection\n\\details\nReturns the performance metric used by Tensile to select the optimal solution for gemm problems.\n@param[in]\nhandle [rocblas_handle]\nthe handle of device\n@param[out]\nmetric [rocblas_performance_metric*]\npointer to where the metric will be stored"] + pub fn rocblas_get_performance_metric( + handle: rocblas_handle, + metric: *mut rocblas_performance_metric, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nscal scales each element of vector x with scalar alpha:\n\nx := alpha * x\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nalpha device pointer or host pointer for the scalar alpha.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n\n"] + pub fn rocblas_sscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdscal( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nscal_batched scales each element of vector x_i with scalar alpha, for i = 1, ... , batch_count:\n\nx_i := alpha * x_i,\nwhere (x_i) is the i-th instance of the batch.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i.\n@param[in]\nalpha host pointer or device pointer for the scalar alpha.\n@param[inout]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of batches in x."] + pub fn rocblas_sscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdscal_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nscal_strided_batched scales each element of vector x_i with scalar alpha, for i = 1, ... , batch_count:\n\nx_i := alpha * x_i,\nwhere (x_i) is the i-th instance of the batch.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i.\n@param[in]\nalpha host pointer or device pointer for the scalar alpha.\n@param[inout]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size, for a typical\ncase this means stride_x >= n * incx.\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of batches in x."] + pub fn rocblas_sscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdscal_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ncopy copies each element x[i] into y[i], for i = 1 , ... , n:\n\ny := x\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x to be copied to y.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[out]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_scopy( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dcopy( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ccopy( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zcopy( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ncopy_batched copies each element x_i[j] into y_i[j], for j = 1 , ... , n; i = 1 , ... , batch_count:\n\ny_i := x_i,\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i to be copied to y_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[out]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_scopy_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dcopy_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ccopy_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zcopy_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ncopy_strided_batched copies each element x_i[j] into y_i[j], for j = 1 , ... , n; i = 1 , ... , batch_count:\n\ny_i := x_i,\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i to be copied to y_i.\n@param[in]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increments for the elements of vectors x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, the user should\ntake care to ensure that stride_x is of appropriate size. For a typical\ncase, this means stride_x >= n * incx.\n@param[out]\ny device pointer to the first vector (y_1) in the batch.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of vectors y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stride_y, However, ensure that stride_y is of appropriate size, for a typical\ncase this means stride_y >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_scopy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dcopy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ccopy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zcopy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ndot(u) performs the dot product of vectors x and y:\n\nresult = x * y;\n\ndotc performs the dot product of the conjugate of complex vector x and complex vector y.\n\nresult = conjugate (x) * y;\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresult\ndevice pointer or host pointer to store the dot product.\nreturn is 0.0 if n <= 0.\n"] + pub fn rocblas_sdot( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + y: *const f32, + incy: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddot( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + y: *const f64, + incy: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hdot( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_half, + incx: rocblas_int, + y: *const rocblas_half, + incy: rocblas_int, + result: *mut rocblas_half, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_bfdot( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_bfloat16, + incx: rocblas_int, + y: *const rocblas_bfloat16, + incy: rocblas_int, + result: *mut rocblas_bfloat16, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotu( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotu( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotc( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotc( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ndot_batched(u) performs a batch of dot products of vectors x and y:\n\nresult_i = x_i * y_i;\n\ndotc_batched performs a batch of dot products of the conjugate of complex vector x and complex vector y\n\nresult_i = conjugate (x_i) * y_i;\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[inout]\nresult\ndevice array or host array of batch_count size to store the dot products of each batch.\nreturn 0.0 for each element if n <= 0.\n"] + pub fn rocblas_sdot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + y: *const *const f32, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + y: *const *const f64, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hdot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_half, + incx: rocblas_int, + y: *const *const rocblas_half, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_half, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_bfdot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_bfloat16, + incx: rocblas_int, + y: *const *const rocblas_bfloat16, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_bfloat16, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotu_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotu_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotc_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotc_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\ndot_strided_batched(u) performs a batch of dot products of vectors x and y:\n\nresult_i = x_i * y_i;\n\ndotc_strided_batched performs a batch of dot products of the conjugate of complex vector x and complex vector y\n\nresult_i = conjugate (x_i) * y_i;\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\ny device pointer to the first vector (y_1) in the batch.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[inout]\nresult\ndevice array or host array of batch_count size to store the dot products of each batch.\nreturn 0.0 for each element if n <= 0.\n"] + pub fn rocblas_sdot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hdot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_half, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_half, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_half, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_bfdot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_bfloat16, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_bfloat16, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_bfloat16, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotu_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotu_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdotc_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdotc_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nswap interchanges vectors x and y:\n\ny := x;\nx := y\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_sswap( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dswap( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cswap( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zswap( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nswap_batched interchanges vectors x_i and y_i, for i = 1 , ... , batch_count:\n\ny_i := x_i;\nx_i := y_i\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[inout]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sswap_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dswap_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cswap_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zswap_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nswap_strided_batched interchanges vectors x_i and y_i, for i = 1 , ... , batch_count:\n\ny_i := x_i;\nx_i := y_i\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[inout]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. For a typical\ncase this means stride_x >= n * incx.\n@param[inout]\ny device pointer to the first vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_y is of appropriate size. For a typical\ncase this means stride_y >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sswap_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dswap_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cswap_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zswap_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\naxpy computes constant alpha multiplied by vector x, plus vector y:\n\ny := alpha * x + y\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[in]\nalpha device pointer or host pointer to specify the scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[out]\ny device pointer storing vector y.\n@param[inout]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_saxpy( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_daxpy( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_haxpy( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_half, + x: *const rocblas_half, + incx: rocblas_int, + y: *mut rocblas_half, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_caxpy( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zaxpy( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\naxpy_batched compute y := alpha * x + y over a set of batched vectors.\n\n@param[in]\nhandle rocblas_handle\nhandle to the rocblas library context queue.\n@param[in]\nn rocblas_int\n@param[in]\nalpha specifies the scalar alpha.\n@param[in]\nx pointer storing vector x on the GPU.\n@param[in]\nincx rocblas_int\nspecifies the increment for the elements of x.\n@param[out]\ny pointer storing vector y on the GPU.\n@param[inout]\nincy rocblas_int\nspecifies the increment for the elements of y.\n\n@param[in]\nbatch_count rocblas_int\nnumber of instances in the batch.\n"] + pub fn rocblas_haxpy_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_half, + x: *const *const rocblas_half, + incx: rocblas_int, + y: *const *mut rocblas_half, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_saxpy_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_daxpy_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_caxpy_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zaxpy_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\naxpy_strided_batched compute y := alpha * x + y over a set of strided batched vectors.\n\n@param[in]\nhandle rocblas_handle\nhandle to the rocblas library context queue.\n@param[in]\nn rocblas_int.\n@param[in]\nalpha specifies the scalar alpha.\n@param[in]\nx pointer storing vector x on the GPU.\n@param[in]\nincx rocblas_int\nspecifies the increment for the elements of x.\n@param[in]\nstridex rocblas_stride\nspecifies the increment between vectors of x.\n@param[out]\ny pointer storing vector y on the GPU.\n@param[inout]\nincy rocblas_int\nspecifies the increment for the elements of y.\n@param[in]\nstridey rocblas_stride\nspecifies the increment between vectors of y.\n\n@param[in]\nbatch_count rocblas_int\nnumber of instances in the batch.\n"] + pub fn rocblas_haxpy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_half, + x: *const rocblas_half, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_half, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_saxpy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_daxpy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_caxpy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zaxpy_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nasum computes the sum of the magnitudes of elements of a real vector x,\nor the sum of magnitudes of the real and imaginary parts of elements if x is a complex vector.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x. incx must be > 0.\n@param[inout]\nresult\ndevice pointer or host pointer to store the asum product.\nreturn is 0.0 if n <= 0.\n"] + pub fn rocblas_sasum( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dasum( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scasum( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dzasum( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nasum_batched computes the sum of the magnitudes of the elements in a batch of real vectors x_i,\nor the sum of magnitudes of the real and imaginary parts of elements if x_i is a complex\nvector, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[out]\nresults\ndevice array or host array of batch_count size for results.\nreturn is 0.0 if n, incx<=0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sasum_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dasum_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scasum_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dzasum_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nasum_strided_batched computes the sum of the magnitudes of elements of a real vectors x_i,\nor the sum of magnitudes of the real and imaginary parts of elements if x_i is a complex\nvector, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. For a typical\ncase this means stride_x >= n * incx.\n@param[out]\nresults\ndevice pointer or host pointer to array for storing contiguous batch_count results.\nreturn is 0.0 if n, incx<=0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sasum_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dasum_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scasum_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dzasum_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nnrm2 computes the euclidean norm of a real or complex vector:\n\nresult := sqrt( x'*x ) for real vectors\nresult := sqrt( x**H*x ) for complex vectors\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresult\ndevice pointer or host pointer to store the nrm2 product.\nreturn is 0.0 if n, incx<=0."] + pub fn rocblas_snrm2( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dnrm2( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scnrm2( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + result: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dznrm2( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + result: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nnrm2_batched computes the euclidean norm over a batch of real or complex vectors:\n\nresult := sqrt( x_i'*x_i ) for real vectors x, for i = 1, ..., batch_count\nresult := sqrt( x_i**H*x_i ) for complex vectors x, for i = 1, ..., batch_count\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresults\ndevice pointer or host pointer to array of batch_count size for nrm2 results.\nreturn is 0.0 for each element if n <= 0, incx<=0.\n"] + pub fn rocblas_snrm2_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dnrm2_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scnrm2_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dznrm2_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nnrm2_strided_batched computes the euclidean norm over a batch of real or complex vectors:\n\nresult := sqrt( x_i'*x_i ) for real vectors x, for i = 1, ..., batch_count\nresult := sqrt( x_i**H*x_i ) for complex vectors, for i = 1, ..., batch_count\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. For a typical\ncase this means stride_x >= n * incx.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresults\ndevice pointer or host pointer to array for storing contiguous batch_count results.\nreturn is 0.0 for each element if n <= 0, incx<=0.\n"] + pub fn rocblas_snrm2_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dnrm2_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_scnrm2_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dznrm2_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + results: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namax finds the first index of the element of maximum magnitude of a vector x.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresult\ndevice pointer or host pointer to store the amax index.\nreturn is 0.0 if n, incx<=0."] + pub fn rocblas_isamax( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamax( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamax( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamax( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namax_batched finds the first index of the element of maximum magnitude of each vector x_i in a batch, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch. Must be > 0.\n@param[out]\nresult\ndevice or host array of pointers of batch_count size for results.\nreturn is 0 if n, incx<=0."] + pub fn rocblas_isamax_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamax_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamax_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamax_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namax_strided_batched finds the first index of the element of maximum magnitude of each vector x_i in a batch, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nstridex [rocblas_stride]\nspecifies the pointer increment between one x_i and the next x_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresult\ndevice or host pointer for storing contiguous batch_count results.\nreturn is 0 if n <= 0, incx<=0.\n"] + pub fn rocblas_isamax_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamax_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamax_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamax_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namin finds the first index of the element of minimum magnitude of a vector x.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresult\ndevice pointer or host pointer to store the amin index.\nreturn is 0.0 if n, incx<=0."] + pub fn rocblas_isamin( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamin( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamin( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamin( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namin_batched finds the first index of the element of minimum magnitude of each vector x_i in a batch, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch. Must be > 0.\n@param[out]\nresult\ndevice or host pointers to array of batch_count size for results.\nreturn is 0 if n, incx<=0."] + pub fn rocblas_isamin_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamin_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamin_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamin_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\namin_strided_batched finds the first index of the element of minimum magnitude of each vector x_i in a batch, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each vector x_i.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nstridex [rocblas_stride]\nspecifies the pointer increment between one x_i and the next x_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresult\ndevice or host pointer to array for storing contiguous batch_count results.\nreturn is 0 if n <= 0, incx<=0.\n"] + pub fn rocblas_isamin_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_idamin_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_icamin_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_izamin_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + result: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrot applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to vectors x and y.\nScalars c and s may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in the x and y vectors.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of x.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of y.\n@param[in]\nc device pointer or host pointer storing scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer storing scalar sine component of the rotation matrix.\n"] + pub fn rocblas_srot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + y: *mut f32, + incy: rocblas_int, + c: *const f32, + s: *const f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + y: *mut f64, + incy: rocblas_int, + c: *const f64, + s: *const f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + y: *mut rocblas_float_complex, + incy: rocblas_int, + c: *const f32, + s: *const rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csrot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + y: *mut rocblas_float_complex, + incy: rocblas_int, + c: *const f32, + s: *const f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + y: *mut rocblas_double_complex, + incy: rocblas_int, + c: *const f64, + s: *const rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdrot( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + y: *mut rocblas_double_complex, + incy: rocblas_int, + c: *const f64, + s: *const f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrot_batched applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to batched vectors x_i and y_i, for i = 1, ..., batch_count.\nScalars c and s may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i and y_i vectors.\n@param[inout]\nx device array of deivce pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nc device pointer or host pointer to scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer to scalar sine component of the rotation matrix.\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, i.e. the number of batches.\n"] + pub fn rocblas_srot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + y: *const *mut f32, + incy: rocblas_int, + c: *const f32, + s: *const f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + y: *const *mut f64, + incy: rocblas_int, + c: *const f64, + s: *const f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + c: *const f32, + s: *const rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csrot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + c: *const f32, + s: *const f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + c: *const f64, + s: *const rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdrot_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + c: *const f64, + s: *const f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrot_strided_batched applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to strided batched vectors x_i and y_i, for i = 1, ..., batch_count.\nScalars c and s may be stored in either host or device memory, location is specified by calling rocblas_set_pointer_mode.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i and y_i vectors.\n@param[inout]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nspecifies the increment from the beginning of x_i to the beginning of x_(i+1).\n@param[inout]\ny device pointer to the first vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nspecifies the increment from the beginning of y_i to the beginning of y_(i+1)\n@param[in]\nc device pointer or host pointer to scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer to scalar sine component of the rotation matrix.\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, i.e. the number of batches.\n"] + pub fn rocblas_srot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut f32, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f32, + s: *const f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut f64, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f64, + s: *const f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f32, + s: *const rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csrot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f32, + s: *const f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f64, + s: *const rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdrot_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const f64, + s: *const f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotg creates the Givens rotation matrix for the vector (a b).\nScalars c and s and arrays a and b may be stored in either host or device memory, location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\na device pointer or host pointer to input vector element, overwritten with r.\n@param[inout]\nb device pointer or host pointer to input vector element, overwritten with z.\n@param[inout]\nc device pointer or host pointer to cosine element of Givens rotation.\n@param[inout]\ns device pointer or host pointer sine element of Givens rotation.\n"] + pub fn rocblas_srotg( + handle: rocblas_handle, + a: *mut f32, + b: *mut f32, + c: *mut f32, + s: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotg( + handle: rocblas_handle, + a: *mut f64, + b: *mut f64, + c: *mut f64, + s: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crotg( + handle: rocblas_handle, + a: *mut rocblas_float_complex, + b: *mut rocblas_float_complex, + c: *mut f32, + s: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrotg( + handle: rocblas_handle, + a: *mut rocblas_double_complex, + b: *mut rocblas_double_complex, + c: *mut f64, + s: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotg_batched creates the Givens rotation matrix for the batched vectors (a_i b_i), for i = 1, ..., batch_count.\na, b, c, and s may be stored in either host or device memory, location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\na device array of device pointers storing each single input vector element a_i, overwritten with r_i.\n@param[inout]\nb device array of device pointers storing each single input vector element b_i, overwritten with z_i.\n@param[inout]\nc device array of device pointers storing each cosine element of Givens rotation for the batch.\n@param[inout]\ns device array of device pointers storing each sine element of Givens rotation for the batch.\n@param[in]\nbatch_count [rocblas_int]\nnumber of batches (length of arrays a, b, c, and s).\n"] + pub fn rocblas_srotg_batched( + handle: rocblas_handle, + a: *const *mut f32, + b: *const *mut f32, + c: *const *mut f32, + s: *const *mut f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotg_batched( + handle: rocblas_handle, + a: *const *mut f64, + b: *const *mut f64, + c: *const *mut f64, + s: *const *mut f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crotg_batched( + handle: rocblas_handle, + a: *const *mut rocblas_float_complex, + b: *const *mut rocblas_float_complex, + c: *const *mut f32, + s: *const *mut rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrotg_batched( + handle: rocblas_handle, + a: *const *mut rocblas_double_complex, + b: *const *mut rocblas_double_complex, + c: *const *mut f64, + s: *const *mut rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotg_strided_batched creates the Givens rotation matrix for the strided batched vectors (a_i b_i), for i = 1, ..., batch_count.\na, b, c, and s may be stored in either host or device memory, location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\na device strided_batched pointer or host strided_batched pointer to first single input vector element a_1, overwritten with r.\n@param[in]\nstride_a [rocblas_stride]\ndistance between elements of a in batch (distance between a_i and a_(i + 1)).\n@param[inout]\nb device strided_batched pointer or host strided_batched pointer to first single input vector element b_1, overwritten with z.\n@param[in]\nstride_b [rocblas_stride]\ndistance between elements of b in batch (distance between b_i and b_(i + 1)).\n@param[inout]\nc device strided_batched pointer or host strided_batched pointer to first cosine element of Givens rotations c_1.\n@param[in]\nstride_c [rocblas_stride]\ndistance between elements of c in batch (distance between c_i and c_(i + 1)).\n@param[inout]\ns device strided_batched pointer or host strided_batched pointer to sine element of Givens rotations s_1.\n@param[in]\nstride_s [rocblas_stride]\ndistance between elements of s in batch (distance between s_i and s_(i + 1)).\n@param[in]\nbatch_count [rocblas_int]\nnumber of batches (length of arrays a, b, c, and s).\n"] + pub fn rocblas_srotg_strided_batched( + handle: rocblas_handle, + a: *mut f32, + stride_a: rocblas_stride, + b: *mut f32, + stride_b: rocblas_stride, + c: *mut f32, + stride_c: rocblas_stride, + s: *mut f32, + stride_s: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotg_strided_batched( + handle: rocblas_handle, + a: *mut f64, + stride_a: rocblas_stride, + b: *mut f64, + stride_b: rocblas_stride, + c: *mut f64, + stride_c: rocblas_stride, + s: *mut f64, + stride_s: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_crotg_strided_batched( + handle: rocblas_handle, + a: *mut rocblas_float_complex, + stride_a: rocblas_stride, + b: *mut rocblas_float_complex, + stride_b: rocblas_stride, + c: *mut f32, + stride_c: rocblas_stride, + s: *mut rocblas_float_complex, + stride_s: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zrotg_strided_batched( + handle: rocblas_handle, + a: *mut rocblas_double_complex, + stride_a: rocblas_stride, + b: *mut rocblas_double_complex, + stride_b: rocblas_stride, + c: *mut f64, + stride_c: rocblas_stride, + s: *mut rocblas_double_complex, + stride_s: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotm applies the modified Givens rotation matrix defined by param to vectors x and y.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in the x and y vectors.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of x.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of y.\n@param[in]\nparam device vector or host vector of 5 elements defining the rotation.\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\n\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may be stored in either host or device memory,\nlocation is specified by calling rocblas_set_pointer_mode.\n"] + pub fn rocblas_srotm( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + y: *mut f32, + incy: rocblas_int, + param: *const f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotm( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + y: *mut f64, + incy: rocblas_int, + param: *const f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotm_batched applies the modified Givens rotation matrix defined by param_i to batched vectors x_i and y_i, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in the x and y vectors.\n@param[inout]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[inout]\ny device array of device pointers storing each vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nparam device array of device vectors of 5 elements defining the rotation.\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\n\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may ONLY be stored on the device for the batched version of this function.\n\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, i.e. the number of batches.\n"] + pub fn rocblas_srotm_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + y: *const *mut f32, + incy: rocblas_int, + param: *const *const f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotm_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + y: *const *mut f64, + incy: rocblas_int, + param: *const *const f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotm_strided_batched applies the modified Givens rotation matrix defined by param_i to strided batched vectors x_i and y_i, for i = 1, ..., batch_count\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in the x and y vectors.\n@param[inout]\nx device pointer pointing to first strided batched vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nspecifies the increment between the beginning of x_i and x_(i + 1)\n@param[inout]\ny device pointer pointing to first strided batched vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nspecifies the increment between the beginning of y_i and y_(i + 1).\n@param[in]\nparam device pointer pointing to first array of 5 elements defining the rotation (param_1).\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\n\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may ONLY be stored on the device for the strided_batched\nversion of this function.\n\n@param[in]\nstride_param [rocblas_stride]\nspecifies the increment between the beginning of param_i and param_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, i.e. the number of batches.\n"] + pub fn rocblas_srotm_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut f32, + incy: rocblas_int, + stride_y: rocblas_stride, + param: *const f32, + stride_param: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotm_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut f64, + incy: rocblas_int, + stride_y: rocblas_stride, + param: *const f64, + stride_param: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotmg creates the modified Givens rotation matrix for the vector (d1 * x1, d2 * y1).\nParameters may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\nd1 device pointer or host pointer to input scalar that is overwritten.\n@param[inout]\nd2 device pointer or host pointer to input scalar that is overwritten.\n@param[inout]\nx1 device pointer or host pointer to input scalar that is overwritten.\n@param[in]\ny1 device pointer or host pointer to input scalar.\n@param[out]\nparam device vector or host vector of five elements defining the rotation.\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\n\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may be stored in either host or device memory.\nLocation is specified by calling rocblas_set_pointer_mode.\n"] + pub fn rocblas_srotmg( + handle: rocblas_handle, + d1: *mut f32, + d2: *mut f32, + x1: *mut f32, + y1: *const f32, + param: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotmg( + handle: rocblas_handle, + d1: *mut f64, + d2: *mut f64, + x1: *mut f64, + y1: *const f64, + param: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotmg_batched creates the modified Givens rotation matrix for the batched vectors (d1_i * x1_i, d2_i * y1_i), for i = 1, ..., batch_count.\nParameters may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\nd1 device batched array or host batched array of input scalars that is overwritten.\n@param[inout]\nd2 device batched array or host batched array of input scalars that is overwritten.\n@param[inout]\nx1 device batched array or host batched array of input scalars that is overwritten.\n@param[in]\ny1 device batched array or host batched array of input scalars.\n@param[out]\nparam device batched array or host batched array of vectors of 5 elements defining the rotation.\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\n\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may be stored in either host or device memory.\nLocation is specified by calling rocblas_set_pointer_mode.\n\n@param[in]\nbatch_count [rocblas_int]\nthe number of instances in the batch.\n"] + pub fn rocblas_srotmg_batched( + handle: rocblas_handle, + d1: *const *mut f32, + d2: *const *mut f32, + x1: *const *mut f32, + y1: *const *const f32, + param: *const *mut f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotmg_batched( + handle: rocblas_handle, + d1: *const *mut f64, + d2: *const *mut f64, + x1: *const *mut f64, + y1: *const *const f64, + param: *const *mut f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrotmg_strided_batched creates the modified Givens rotation matrix for the strided batched vectors (d1_i * x1_i, d2_i * y1_i), for i = 1, ..., batch_count.\nParameters may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode:\n\n- If the pointer mode is set to rocblas_pointer_mode_host, then this function blocks the CPU until the GPU has finished and the results are available in host memory.\n- If the pointer mode is set to rocblas_pointer_mode_device, then this function returns immediately and synchronization is required to read the results.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[inout]\nd1 device strided_batched array or host strided_batched array of input scalars that is overwritten.\n@param[in]\nstride_d1 [rocblas_stride]\nspecifies the increment between the beginning of d1_i and d1_(i+1).\n@param[inout]\nd2 device strided_batched array or host strided_batched array of input scalars that is overwritten.\n@param[in]\nstride_d2 [rocblas_stride]\nspecifies the increment between the beginning of d2_i and d2_(i+1).\n@param[inout]\nx1 device strided_batched array or host strided_batched array of input scalars that is overwritten.\n@param[in]\nstride_x1 [rocblas_stride]\nspecifies the increment between the beginning of x1_i and x1_(i+1).\n@param[in]\ny1 device strided_batched array or host strided_batched array of input scalars.\n@param[in]\nstride_y1 [rocblas_stride]\nspecifies the increment between the beginning of y1_i and y1_(i+1).\n@param[out]\nparam device strided_batched array or host strided_batched array of vectors of 5 elements defining the rotation.\n\nparam[0] = flag\nparam[1] = H11\nparam[2] = H21\nparam[3] = H12\nparam[4] = H22\nThe flag parameter defines the form of H:\n\nflag = -1 => H = ( H11 H12 H21 H22 )\nflag = 0 => H = ( 1.0 H12 H21 1.0 )\nflag = 1 => H = ( H11 1.0 -1.0 H22 )\nflag = -2 => H = ( 1.0 0.0 0.0 1.0 )\n\nparam may be stored in either host or device memory.\nLocation is specified by calling rocblas_set_pointer_mode.\n\n@param[in]\nstride_param [rocblas_stride]\nspecifies the increment between the beginning of param_i and param_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nthe number of instances in the batch.\n"] + pub fn rocblas_srotmg_strided_batched( + handle: rocblas_handle, + d1: *mut f32, + stride_d1: rocblas_stride, + d2: *mut f32, + stride_d2: rocblas_stride, + x1: *mut f32, + stride_x1: rocblas_stride, + y1: *const f32, + stride_y1: rocblas_stride, + param: *mut f32, + stride_param: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_drotmg_strided_batched( + handle: rocblas_handle, + d1: *mut f64, + stride_d1: rocblas_stride, + d2: *mut f64, + stride_d2: rocblas_stride, + x1: *mut f64, + stride_x1: rocblas_stride, + y1: *const f64, + stride_y1: rocblas_stride, + param: *mut f64, + stride_param: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngbmv performs one of the matrix-vector operations:\n\ny := alpha*A*x + beta*y, or\ny := alpha*A**T*x + beta*y, or\ny := alpha*A**H*x + beta*y,\nwhere alpha and beta are scalars, x and y are vectors and A is an\nm by n banded matrix with kl sub-diagonals and ku super-diagonals.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrix A is tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of matrix A.\n@param[in]\nn [rocblas_int]\nnumber of columns of matrix A.\n@param[in]\nkl [rocblas_int]\nnumber of sub-diagonals of A.\n@param[in]\nku [rocblas_int]\nnumber of super-diagonals of A.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer storing banded matrix A.\nLeading (kl + ku + 1) by n part of the matrix contains the coefficients\nof the banded matrix. The leading diagonal resides in row (ku + 1) with\nthe first super-diagonal above on the RHS of row ku. The first sub-diagonal\nresides below on the LHS of row ku + 2. This propagates up and down across\nsub/super-diagonals.\n\nEx: (m = n = 7; ku = 2, kl = 2)\n1 2 3 0 0 0 0 0 0 3 3 3 3 3\n4 1 2 3 0 0 0 0 2 2 2 2 2 2\n5 4 1 2 3 0 0 ----> 1 1 1 1 1 1 1\n0 5 4 1 2 3 0 4 4 4 4 4 4 0\n0 0 5 4 1 2 0 5 5 5 5 5 0 0\n0 0 0 5 4 1 2 0 0 0 0 0 0 0\n0 0 0 0 5 4 1 0 0 0 0 0 0 0\n\nNote that the empty elements which do not correspond to data will not\nbe referenced.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. Must be >= (kl + ku + 1).\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_sgbmv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + x: *const f32, + incx: rocblas_int, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgbmv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + x: *const f64, + incx: rocblas_int, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgbmv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgbmv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngbmv_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i, or\ny_i := alpha*A_i**T*x_i + beta*y_i, or\ny_i := alpha*A_i**H*x_i + beta*y_i,\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nm by n banded matrix with kl sub-diagonals and ku super-diagonals,\nfor i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrix A is tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of each matrix A_i.\n@param[in]\nn [rocblas_int]\nnumber of columns of each matrix A_i.\n@param[in]\nkl [rocblas_int]\nnumber of sub-diagonals of each A_i.\n@param[in]\nku [rocblas_int]\nnumber of super-diagonals of each A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each banded matrix A_i.\nLeading (kl + ku + 1) by n part of the matrix contains the coefficients\nof the banded matrix. The leading diagonal resides in row (ku + 1) with\nthe first super-diagonal above on the RHS of row ku. The first sub-diagonal\nresides below on the LHS of row ku + 2. This propagates up and down across\nsub/super-diagonals.\n\nEx: (m = n = 7; ku = 2, kl = 2)\n1 2 3 0 0 0 0 0 0 3 3 3 3 3\n4 1 2 3 0 0 0 0 2 2 2 2 2 2\n5 4 1 2 3 0 0 ----> 1 1 1 1 1 1 1\n0 5 4 1 2 3 0 4 4 4 4 4 4 0\n0 0 5 4 1 2 0 5 5 5 5 5 0 0\n0 0 0 5 4 1 2 0 0 0 0 0 0 0\n0 0 0 0 5 4 1 0 0 0 0 0 0 0\n\nNote that the empty elements which do not correspond to data will not\nbe referenced.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. Must be >= (kl + ku + 1)\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of instances in the batch.\n"] + pub fn rocblas_sgbmv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + beta: *const f32, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgbmv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + beta: *const f64, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgbmv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgbmv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngbmv_strided_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i, or\ny_i := alpha*A_i**T*x_i + beta*y_i, or\ny_i := alpha*A_i**H*x_i + beta*y_i,\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nm by n banded matrix with kl sub-diagonals and ku super-diagonals,\nfor i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrix A is tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of matrix A.\n@param[in]\nn [rocblas_int]\nnumber of columns of matrix A.\n@param[in]\nkl [rocblas_int]\nnumber of sub-diagonals of A.\n@param[in]\nku [rocblas_int]\nnumber of super-diagonals of A.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer to first banded matrix (A_1).\nLeading (kl + ku + 1) by n part of the matrix contains the coefficients\nof the banded matrix. The leading diagonal resides in row (ku + 1) with\nthe first super-diagonal above on the RHS of row ku. The first sub-diagonal\nresides below on the LHS of row ku + 2. This propagates up and down across\nsub/super-diagonals.\n\nEx: (m = n = 7; ku = 2, kl = 2)\n1 2 3 0 0 0 0 0 0 3 3 3 3 3\n4 1 2 3 0 0 0 0 2 2 2 2 2 2\n5 4 1 2 3 0 0 ----> 1 1 1 1 1 1 1\n0 5 4 1 2 3 0 4 4 4 4 4 4 0\n0 0 5 4 1 2 0 5 5 5 5 5 0 0\n0 0 0 5 4 1 2 0 0 0 0 0 0 0\n0 0 0 0 5 4 1 0 0 0 0 0 0 0\n\nNote that the empty elements which do not correspond to data will not\nbe referenced.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. Must be >= (kl + ku + 1).\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx device pointer to first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer to first vector (y_1).\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (x_i+1).\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of instances in the batch.\n"] + pub fn rocblas_sgbmv_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgbmv_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgbmv_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgbmv_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + kl: rocblas_int, + ku: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngemv performs one of the matrix-vector operations:\n\ny := alpha*A*x + beta*y, or\ny := alpha*A**T*x + beta*y, or\ny := alpha*A**H*x + beta*y,\nwhere alpha and beta are scalars, x and y are vectors and A is an\nm by n matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrix A is tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of matrix A.\n@param[in]\nn [rocblas_int]\nnumber of columns of matrix A.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_sgemv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + x: *const f32, + incx: rocblas_int, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + x: *const f64, + incx: rocblas_int, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemv( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngemv_batched performs a batch of matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i, or\ny_i := alpha*A_i**T*x_i + beta*y_i, or\ny_i := alpha*A_i**H*x_i + beta*y_i,\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nm by n matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrices A_i are tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of each matrix A_i.\n@param[in]\nn [rocblas_int]\nnumber of columns of each matrix A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each matrix A_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sgemv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + beta: *const f32, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + beta: *const f64, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemv_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ngemv_strided_batched performs a batch of matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i, or\ny_i := alpha*A_i**T*x_i + beta*y_i, or\ny_i := alpha*A_i**H*x_i + beta*y_i,\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nm by n matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nindicates whether matrices A_i are tranposed (conjugated) or not.\n@param[in]\nm [rocblas_int]\nnumber of rows of matrices A_i.\n@param[in]\nn [rocblas_int]\nnumber of columns of matrices A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer to the first matrix (A_1) in the batch.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of matrices A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of vectors x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. When trans equals rocblas_operation_none\nthis typically means stride_x >= n * incx, otherwise stride_x >= m * incx.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer to the first vector (y_1) in the batch.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of vectors y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stride_y. However, ensure that stride_y is of appropriate size. When trans equals rocblas_operation_none\nthis typically means stride_y >= m * incy, otherwise stride_y >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sgemv_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemv_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemv_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemv_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhbmv performs the matrix-vector operations:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and A is an\nn by n Hermitian band matrix, with k super-diagonals.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: The upper triangular part of A is being supplied.\n- rocblas_fill_lower: The lower triangular part of A is being supplied.\n@param[in]\nn [rocblas_int]\nthe order of the matrix A.\n@param[in]\nk [rocblas_int]\nthe number of super-diagonals of the matrix A. Must be >= 0.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer storing matrix A. Of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe leading (k + 1) by n part of A must contain the upper\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (k + 1), the first super-diagonal on the RHS\nof row k, etc.\nThe top left k by x triangle of A will not be referenced.\nEx (upper, lda = n = 4, k = 1):\nA Represented matrix\n(0,0) (5,9) (6,8) (7,7) (1, 0) (5, 9) (0, 0) (0, 0)\n(1,0) (2,0) (3,0) (4,0) (5,-9) (2, 0) (6, 8) (0, 0)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (6,-8) (3, 0) (7, 7)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (0, 0) (7,-7) (4, 0)\n\nif uplo == rocblas_fill_lower:\nThe leading (k + 1) by n part of A must contain the lower\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (1), the first sub-diagonal on the LHS of\nrow 2, etc.\nThe bottom right k by k triangle of A will not be referenced.\nEx (lower, lda = 2, n = 4, k = 1):\nA Represented matrix\n(1,0) (2,0) (3,0) (4,0) (1, 0) (5,-9) (0, 0) (0, 0)\n(5,9) (6,8) (7,7) (0,0) (5, 9) (2, 0) (6,-8) (0, 0)\n(0, 0) (6, 8) (3, 0) (7,-7)\n(0, 0) (0, 0) (7, 7) (4, 0)\n\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof A will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. must be >= k + 1.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_chbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhbmv_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian band matrix with k super-diagonals, for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: The upper triangular part of each A_i is being supplied.\n- rocblas_fill_lower: The lower triangular part of each A_i is being supplied.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nk [rocblas_int]\nthe number of super-diagonals of each matrix A_i. Must be >= 0.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe leading (k + 1) by n part of each A_i must contain the upper\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (k + 1), the first super-diagonal on the RHS\nof row k, etc.\nThe top left k by x triangle of each A_i will not be referenced.\nEx (upper, lda = n = 4, k = 1):\nA Represented matrix\n(0,0) (5,9) (6,8) (7,7) (1, 0) (5, 9) (0, 0) (0, 0)\n(1,0) (2,0) (3,0) (4,0) (5,-9) (2, 0) (6, 8) (0, 0)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (6,-8) (3, 0) (7, 7)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (0, 0) (7,-7) (4, 0)\n\nif uplo == rocblas_fill_lower:\nThe leading (k + 1) by n part of each A_i must contain the lower\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (1), the first sub-diagonal on the LHS of\nrow 2, etc.\nThe bottom right k by k triangle of each A_i will not be referenced.\nEx (lower, lda = 2, n = 4, k = 1):\nA Represented matrix\n(1,0) (2,0) (3,0) (4,0) (1, 0) (5,-9) (0, 0) (0, 0)\n(5,9) (6,8) (7,7) (0,0) (5, 9) (2, 0) (6,-8) (0, 0)\n(0, 0) (6, 8) (3, 0) (7,-7)\n(0, 0) (0, 0) (7, 7) (4, 0)\n\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof each A_i will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. must be >= max(1, n).\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhbmv_strided_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian band matrix with k super-diagonals, for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: The upper triangular part of each A_i is being supplied.\n- rocblas_fill_lower: The lower triangular part of each A_i is being supplied.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nk [rocblas_int]\nthe number of super-diagonals of each matrix A_i. Must be >= 0.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array pointing to the first matrix A_1. Each A_i is of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe leading (k + 1) by n part of each A_i must contain the upper\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (k + 1), the first super-diagonal on the RHS\nof row k, etc.\nThe top left k by x triangle of each A_i will not be referenced.\nEx (upper, lda = n = 4, k = 1):\nA Represented matrix\n(0,0) (5,9) (6,8) (7,7) (1, 0) (5, 9) (0, 0) (0, 0)\n(1,0) (2,0) (3,0) (4,0) (5,-9) (2, 0) (6, 8) (0, 0)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (6,-8) (3, 0) (7, 7)\n(0,0) (0,0) (0,0) (0,0) (0, 0) (0, 0) (7,-7) (4, 0)\n\nif uplo == rocblas_fill_lower:\nThe leading (k + 1) by n part of each A_i must contain the lower\ntriangular band part of the Hermitian matrix, with the leading\ndiagonal in row (1), the first sub-diagonal on the LHS of\nrow 2, etc.\nThe bottom right k by k triangle of each A_i will not be referenced.\nEx (lower, lda = 2, n = 4, k = 1):\nA Represented matrix\n(1,0) (2,0) (3,0) (4,0) (1, 0) (5,-9) (0, 0) (0, 0)\n(5,9) (6,8) (7,7) (0,0) (5, 9) (2, 0) (6,-8) (0, 0)\n(0, 0) (6, 8) (3, 0) (7,-7)\n(0, 0) (0, 0) (7, 7) (4, 0)\n\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof each A_i will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. must be >= max(1, n).\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx device array pointing to the first vector y_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array pointing to the first vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhemv performs one of the matrix-vector operations:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and A is an\nn by n Hermitian matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of the Hermitian matrix A is supplied.\n- rocblas_fill_lower: the lower triangular part of the Hermitian matrix A is supplied.\n@param[in]\nn [rocblas_int]\nthe order of the matrix A.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device pointer storing matrix A. Of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular part of A must contain\nthe upper triangular part of a Hermitian matrix. The lower\ntriangular part of A will not be referenced.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular part of A must contain\nthe lower triangular part of a Hermitian matrix. The upper\ntriangular part of A will not be referenced.\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof A will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. must be >= max(1, n).\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_chemv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhemv_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian matrix, for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of the Hermitian matrix A is supplied.\n- rocblas_fill_lower: the lower triangular part of the Hermitian matrix A is supplied.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular part of each A_i must contain\nthe upper triangular part of a Hermitian matrix. The lower\ntriangular part of each A_i will not be referenced.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular part of each A_i must contain\nthe lower triangular part of a Hermitian matrix. The upper\ntriangular part of each A_i will not be referenced.\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof each A_i will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. must be >= max(1, n).\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chemv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhemv_strided_batched performs one of the matrix-vector operations:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian matrix, for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of the Hermitian matrix A is supplied.\n- rocblas_fill_lower: the lower triangular part of the Hermitian matrix A is supplied.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i of dimension (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular part of each A_i must contain\nthe upper triangular part of a Hermitian matrix. The lower\ntriangular part of each A_i will not be referenced.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular part of each A_i must contain\nthe lower triangular part of a Hermitian matrix. The upper\ntriangular part of each A_i will not be referenced.\nAs a Hermitian matrix, the imaginary part of the main diagonal\nof each A_i will not be referenced and is assumed to be == 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. must be >= max(1, n).\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) to the next (A_i+1).\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chemv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher performs the matrix-vector operations:\n\nA := A + alpha*x*x**H\nwhere alpha is a real scalar, x is a vector, and A is an\nn by n Hermitian matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied in A.\n- rocblas_fill_lower: The lower triangular part of A is supplied in A.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\nA device pointer storing the specified triangular portion of the Hermitian matrix A. Of size (lda * n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the Hermitian matrix A is supplied.\nThe lower triangluar portion will not be touched.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the Hermitian matrix A is supplied.\nThe upper triangular portion will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. Must be at least max(1, n)."] + pub fn rocblas_cher( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const rocblas_float_complex, + incx: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const rocblas_double_complex, + incx: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**H\nwhere alpha is a real scalar, x_i is a vector, and A_i is an\nn by n symmetric matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in A.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in A.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\nA device array of device pointers storing the specified triangular portion of\neach Hermitian matrix A_i of at least size ((n * (n + 1)) / 2). Array is of at least size batch_count.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe lower triangular portion of each A_i will not be touched.\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe upper triangular portion of each A_i will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. Must be at least max(1, n).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_cher_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**H\nwhere alpha is a real scalar, x_i is a vector, and A_i is an\nn by n Hermitian matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in A.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in A.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[inout]\nA device array of device pointers storing the specified triangular portion of\neach Hermitian matrix A_i. Points to the first matrix (A_1).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe lower triangular portion of each A_i will not be touched.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe upper triangular portion of each A_i will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_cher_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher2 performs the matrix-vector operations:\n\nA := A + alpha*x*y**H + conj(alpha)*y*x**H\nwhere alpha is a complex scalar, x and y are vectors, and A is an\nn by n Hermitian matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied.\n- rocblas_fill_lower: The lower triangular part of A is supplied.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nA device pointer storing the specified triangular portion of\nthe Hermitian matrix A. Of size (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the Hermitian matrix A is supplied.\nThe lower triangular portion of A will not be touched.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the Hermitian matrix A is supplied.\nThe upper triangular portion of A will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. Must be at least max(lda, 1)."] + pub fn rocblas_cher2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher2_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*y_i**H + conj(alpha)*y_i*x_i**H\nwhere alpha is a complex scalar, x_i and y_i are vectors, and A_i is an\nn by n Hermitian matrix for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[inout]\nA device array of device pointers storing the specified triangular portion of\neach Hermitian matrix A_i of size (lda, n).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe lower triangular portion of each A_i will not be touched.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe upper triangular portion of each A_i will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. Must be at least max(lda, 1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_cher2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nher2_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*y_i**H + conj(alpha)*y_i*x_i**H\nwhere alpha is a complex scalar, x_i and y_i are vectors, and A_i is an\nn by n Hermitian matrix for each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nspecifies the stride between the beginning of one vector (x_i) and the next (x_i+1).\n@param[in]\ny device pointer pointing to the first vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nspecifies the stride between the beginning of one vector (y_i) and the next (y_i+1).\n@param[inout]\nA device pointer pointing to the first matrix (A_1). Stores the specified triangular portion of\neach Hermitian matrix A_i.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe lower triangular portion of each A_i will not be touched.\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe upper triangular portion of each A_i will not be touched.\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. Must be at least max(lda, 1).\n@param[in]\nstride_A [rocblas_stride]\nspecifies the stride between the beginning of one matrix (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_cher2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpmv performs the matrix-vector operation:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and A is an\nn by n Hermitian matrix, supplied in packed form (see description below).\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of the Hermitian matrix A is supplied in AP.\n- rocblas_fill_lower: the lower triangular part of the Hermitian matrix A is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe order of the matrix A. Must be >= 0.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nAP device pointer storing the packed version of the specified triangular portion of\nthe Hermitian matrix A. Of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,1),(4,0),(3,2),(5,-1),(6,0)]\n(3,-2) (5, 1) (6, 0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,-1),(3,-2),(4,0),(5,1),(6,0)]\n(3,-2) (5, 1) (6, 0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_chpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + AP: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + AP: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpmv_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian matrix, supplied in packed form (see description below),\nfor each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of each Hermitian matrix A_i is supplied in AP.\n- rocblas_fill_lower: the lower triangular part of each Hermitian matrix A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nAP device pointer of device pointers storing the packed version of the specified triangular\nportion of each Hermitian matrix A_i. Each A_i is of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that each AP_i contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,1),(4,0),(3,2),(5,-1),(6,0)]\n(3,-2) (5, 1) (6, 0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that each AP_i contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,-1),(3,-2),(4,0),(5,1),(6,0)]\n(3,-2) (5, 1) (6, 0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + AP: *const *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + AP: *const *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpmv_strided_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere alpha and beta are scalars, x_i and y_i are n element vectors and A_i is an\nn by n Hermitian matrix, supplied in packed form (see description below),\nfor each batch in i = [1, batch_count].\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: the upper triangular part of each Hermitian matrix A_i is supplied in AP.\n- rocblas_fill_lower: the lower triangular part of each Hermitian matrix A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe order of each matrix A_i.\n@param[in]\nalpha device pointer or host pointer to scalar alpha.\n@param[in]\nAP device pointer pointing to the beginning of the first matrix (AP_1). Stores the packed\nversion of the specified triangular portion of each Hermitian matrix AP_i of size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that each AP_i contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,1),(4,0),(3,2),(5,-1),(6,0)]\n(3,-2) (5, 1) (6, 0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that each AP_i contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (3, 2)\n(2,-1) (4, 0) (5,-1) ---> [(1,0),(2,-1),(3,-2),(4,0),(5,1),(6,0)]\n(3,-2) (5, 1) (6, 0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (AP_i) and the next one (AP_i+1).\n@param[in]\nx device array pointing to the beginning of the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[inout]\ny device array pointing to the beginning of the first vector (y_1).\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + AP: *const rocblas_float_complex, + stride_A: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + AP: *const rocblas_double_complex, + stride_A: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr performs the matrix-vector operations:\n\nA := A + alpha*x*x**H\nwhere alpha is a real scalar, x is a vector, and A is an\nn by n Hermitian matrix, supplied in packed form.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of A is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\nthe Hermitian matrix A. Of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0."] + pub fn rocblas_chpr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const rocblas_float_complex, + incx: rocblas_int, + AP: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const rocblas_double_complex, + incx: rocblas_int, + AP: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**H\nwhere alpha is a real scalar, x_i is a vector, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach Hermitian matrix A_i of at least size ((n * (n + 1)) / 2). Array is of at least size batch_count.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_chpr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + AP: *const *mut rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + AP: *const *mut rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**H\nwhere alpha is a real scalar, x_i is a vector, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach Hermitian matrix A_i. Points to the first matrix (A_1).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_chpr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut rocblas_float_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut rocblas_double_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr2 performs the matrix-vector operations:\n\nA := A + alpha*x*y**H + conj(alpha)*y*x**H\nwhere alpha is a complex scalar, x and y are vectors, and A is an\nn by n Hermitian matrix, supplied in packed form.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of A is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\nthe Hermitian matrix A. Of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the Hermitian matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0."] + pub fn rocblas_chpr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + AP: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + AP: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr2_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*y_i**H + conj(alpha)*y_i*x_i**H\nwhere alpha is a complex scalar, x_i and y_i are vectors, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach Hermitian matrix A_i of at least size ((n * (n + 1)) / 2). Array is of at least size batch_count.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) --> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_chpr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + AP: *const *mut rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + AP: *const *mut rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nhpr2_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*y_i**H + conj(alpha)*y_i*x_i**H\nwhere alpha is a complex scalar, x_i and y_i are vectors, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\ny device pointer pointing to the first vector (y_1).\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach Hermitian matrix A_i. Points to the first matrix (A_1).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,1),(3,0),(4,9),(5,3),(6,0)]\n(4,-9) (5,-3) (6,0)\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each Hermitian matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 3)\n(1, 0) (2, 1) (4,9)\n(2,-1) (3, 0) (5,3) ---> [(1,0),(2,-1),(4,-9),(3,0),(5,-3),(6,0)]\n(4,-9) (5,-3) (6,0)\nNote that the imaginary part of the diagonal elements are not accessed\nand are assumed to be 0.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_chpr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + AP: *mut rocblas_float_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhpr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stride_y: rocblas_stride, + AP: *mut rocblas_double_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrmv performs one of the matrix-vector operations:\n\nx = A*x or\nx = A**T*x,\nwhere x is an n element vector and A is an n by n unit, or non-unit, upper or lower triangular matrix.\nThe vector x is overwritten.\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of A. m >= 0.\n\n@param[in]\nA device pointer storing matrix A,\nof dimension ( lda, m ).\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\nlda = max( 1, m ).\n\n@param[in]\nx device pointer storing vector x.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n"] + pub fn rocblas_strmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + lda: rocblas_int, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + lda: rocblas_int, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrmv_batched performs one of the matrix-vector operations:\n\nx_i = A_i*x_i or\nx_i = A**T*x_i, 0 < i < batch_count\nwhere x_i is an n element vector and A_i is an n by n (unit, or non-unit, upper or lower triangular matrix)\nThe vectors x_i are overwritten.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of matrices A_i. m >= 0.\n\n@param[in]\nA device pointer storing pointer of matrices A_i,\nof dimension ( lda, m )\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A_i.\nlda >= max( 1, m ).\n\n@param[in]\nx device pointer storing vectors x_i.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of vectors x_i.\n\n@param[in]\nbatch_count [rocblas_int]\nThe number of batched matrices/vectors.\n\n"] + pub fn rocblas_strmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrmv_strided_batched performs one of the matrix-vector operations:\n\nx_i = A_i*x_i or\nx_i = A**T*x_i, 0 < i < batch_count\nwhere x_i is an n element vector and A_i is an n by n (unit, or non-unit, upper or lower triangular matrix)\nwith strides specifying how to retrieve $x_i$ (resp. $A_i$) from $x_{i-1}$ (resp. $A_i$).\n\nThe vectors x_i are overwritten.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of matrices A_i. m >= 0.\n\n@param[in]\nA device pointer of the matrix A_0,\nof dimension ( lda, m ).\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A_i.\nlda >= max( 1, m ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one A_i matrix to the next A_{i + 1}.\n\n@param[in]\nx device pointer storing the vector x_0.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of one vector x.\n\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one x_i vector to the next x_{i + 1}.\n\n@param[in]\nbatch_count [rocblas_int]\nThe number of batched matrices/vectors.\n\n"] + pub fn rocblas_strmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpmv performs one of the matrix-vector operations:\n\nx = A*x or\nx = A**T*x,\nwhere x is an n element vector and A is an n by n unit, or non-unit,\nupper or lower triangular matrix, supplied in the pack form.\nThe vector x is overwritten.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of A. m >= 0.\n\n@param[in]\nA device pointer storing matrix A,\nof dimension at leat ( m * ( m + 1 ) / 2 ).\n- Before entry with uplo = rocblas_fill_upper, the array A\nmust contain the upper triangular matrix packed sequentially,\ncolumn by column, so that\nA[0] contains a_{0,0}, A[1] and A[2] contain\na_{0,1} and a_{1, 1}, respectively, and so on.\n\n- Before entry with uplo = rocblas_fill_lower, the array A\nmust contain the lower triangular matrix packed sequentially,\ncolumn by column, so that\nA[0] contains a_{0,0}, A[1] and A[2] contain\na_{1,0} and a_{2,0}, respectively, and so on.\n\nNote that when DIAG = rocblas_diagonal_unit, the diagonal elements of A are\nnot referenced, but are assumed to be unity.\n\n@param[in]\nx device pointer storing vector x.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x. incx must not be zero.\n"] + pub fn rocblas_stpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpmv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpmv_batched performs one of the matrix-vector operations:\n\nx_i = A_i*x_i or\nx_i = A**T*x_i, 0 < i < batch_count\nwhere x_i is an n element vector and A_i is an n by n (unit, or non-unit, upper or lower triangular matrix)\nThe vectors x_i are overwritten.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of matrices A_i. m >= 0.\n\n@param[in]\nA device pointer storing pointer of matrices A_i,\nof dimension ( lda, m ).\n\n@param[in]\nx device pointer storing vectors x_i.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of vectors x_i.\n\n@param[in]\nbatch_count [rocblas_int]\nThe number of batched matrices/vectors.\n\n"] + pub fn rocblas_stpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f32, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f64, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_float_complex, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_double_complex, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpmv_strided_batched performs one of the matrix-vector operations:\n\nx_i = A_i*x_i or\nx_i = A**T*x_i, 0 < i < batch_count\nwhere x_i is an n element vector and A_i is an n by n (unit, or non-unit, upper or lower triangular matrix)\nwith strides specifying how to retrieve $x_i$ (resp. $A_i$) from $x_{i-1}$ (resp. $A_i$).\nThe vectors x_i are overwritten.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of matrices A_i. m >= 0.\n\n@param[in]\nA device pointer of the matrix A_0,\nof dimension ( lda, m )\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one A_i matrix to the next A_{i + 1}.\n\n@param[in]\nx device pointer storing the vector x_0.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of one vector x.\n\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one x_i vector to the next x_{i + 1}.\n\n@param[in]\nbatch_count [rocblas_int]\nThe number of batched matrices/vectors.\n\n"] + pub fn rocblas_stpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbmv performs one of the matrix-vector operations:\n\nx := A*x or\nx := A**T*x or\nx := A**H*x,\nx is a vectors and A is a banded m by m matrix (see description below).\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper banded triangular matrix.\n- rocblas_fill_lower: A is a lower banded triangular matrix.\n@param[in]\ntrans [rocblas_operation]\nindicates whether matrix A is tranposed (conjugated) or not.\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: The main diagonal of A is assumed to consist of only\n1's and is not referenced.\n- rocblas_diagonal_non_unit: No assumptions are made of A's main diagonal.\n@param[in]\nm [rocblas_int]\nthe number of rows and columns of the matrix represented by A.\n@param[in]\nk [rocblas_int]\n\nif uplo == rocblas_fill_upper, k specifies the number of super-diagonals\nof the matrix A.\n\nif uplo == rocblas_fill_lower, k specifies the number of sub-diagonals\nof the matrix A.\nk must satisfy k > 0 && k < lda.\n@param[in]\nA device pointer storing banded triangular matrix A.\n\nif uplo == rocblas_fill_upper:\nThe matrix represented is an upper banded triangular matrix\nwith the main diagonal and k super-diagonals, everything\nelse can be assumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the k'th\nrow, the first super diagonal resides on the RHS of the k-1'th row, etc,\nwith the k'th diagonal on the RHS of the 0'th row.\nEx: (rocblas_fill_upper; m = 5; k = 2)\n1 6 9 0 0 0 0 9 8 7\n0 2 7 8 0 0 6 7 8 9\n0 0 3 8 7 ----> 1 2 3 4 5\n0 0 0 4 9 0 0 0 0 0\n0 0 0 0 5 0 0 0 0 0\n\nif uplo == rocblas_fill_lower:\nThe matrix represnted is a lower banded triangular matrix\nwith the main diagonal and k sub-diagonals, everything else can be\nassumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the 0'th row,\nworking up to the k'th diagonal residing on the LHS of the k'th row.\nEx: (rocblas_fill_lower; m = 5; k = 2)\n1 0 0 0 0 1 2 3 4 5\n6 2 0 0 0 6 7 8 9 0\n9 7 3 0 0 ----> 9 8 7 0 0\n0 8 8 4 0 0 0 0 0 0\n0 0 7 9 5 0 0 0 0 0\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A. lda must satisfy lda > k.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n"] + pub fn rocblas_stbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const f32, + lda: rocblas_int, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const f64, + lda: rocblas_int, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbmv_batched performs one of the matrix-vector operations:\n\nx_i := A_i*x_i or\nx_i := A_i**T*x_i or\nx_i := A_i**H*x_i,\nwhere (A_i, x_i) is the i-th instance of the batch.\nx_i is a vector and A_i is an m by m matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper banded triangular matrix.\n- rocblas_fill_lower: each A_i is a lower banded triangular matrix.\n@param[in]\ntrans [rocblas_operation]\nindicates whether each matrix A_i is tranposed (conjugated) or not.\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: The main diagonal of each A_i is assumed to consist of only\n1's and is not referenced.\n- rocblas_diagonal_non_unit: No assumptions are made of each A_i's main diagonal.\n@param[in]\nm [rocblas_int]\nthe number of rows and columns of the matrix represented by each A_i.\n@param[in]\nk [rocblas_int]\n\nif uplo == rocblas_fill_upper, k specifies the number of super-diagonals\nof each matrix A_i.\n\nif uplo == rocblas_fill_lower, k specifies the number of sub-diagonals\nof each matrix A_i.\nk must satisfy k > 0 && k < lda.\n@param[in]\nA device array of device pointers storing each banded triangular matrix A_i.\n\nif uplo == rocblas_fill_upper:\nThe matrix represented is an upper banded triangular matrix\nwith the main diagonal and k super-diagonals, everything\nelse can be assumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the k'th\nrow, the first super diagonal resides on the RHS of the k-1'th row, etc,\nwith the k'th diagonal on the RHS of the 0'th row.\nEx: (rocblas_fill_upper; m = 5; k = 2)\n1 6 9 0 0 0 0 9 8 7\n0 2 7 8 0 0 6 7 8 9\n0 0 3 8 7 ----> 1 2 3 4 5\n0 0 0 4 9 0 0 0 0 0\n0 0 0 0 5 0 0 0 0 0\n\nif uplo == rocblas_fill_lower:\nThe matrix represnted is a lower banded triangular matrix\nwith the main diagonal and k sub-diagonals, everything else can be\nassumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the 0'th row,\nworking up to the k'th diagonal residing on the LHS of the k'th row.\nEx: (rocblas_fill_lower; m = 5; k = 2)\n1 0 0 0 0 1 2 3 4 5\n6 2 0 0 0 6 7 8 9 0\n9 7 3 0 0 ----> 9 8 7 0 0\n0 8 8 4 0 0 0 0 0 0\n0 0 7 9 5 0 0 0 0 0\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. lda must satisfy lda > k.\n@param[inout]\nx device array of device pointer storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_stbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbmv_strided_batched performs one of the matrix-vector operations:\n\nx_i := A_i*x_i or\nx_i := A_i**T*x_i or\nx_i := A_i**H*x_i,\nwhere (A_i, x_i) is the i-th instance of the batch.\nx_i is a vector and A_i is an m by m matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper banded triangular matrix.\n- rocblas_fill_lower: each A_i is a lower banded triangular matrix.\n@param[in]\ntrans [rocblas_operation]\nindicates whether each matrix A_i is tranposed (conjugated) or not.\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: The main diagonal of each A_i is assumed to consist of only\n1's and is not referenced.\n- rocblas_diagonal_non_unit: No assumptions are made of each A_i's main diagonal.\n@param[in]\nm [rocblas_int]\nthe number of rows and columns of the matrix represented by each A_i.\n@param[in]\nk [rocblas_int]\n\nif uplo == rocblas_fill_upper, k specifies the number of super-diagonals\nof each matrix A_i.\n\nif uplo == rocblas_fill_lower, k specifies the number of sub-diagonals\nof each matrix A_i.\nk must satisfy k > 0 && k < lda.\n@param[in]\nA device array to the first matrix A_i of the batch. Stores each banded triangular matrix A_i.\n\nif uplo == rocblas_fill_upper:\nThe matrix represented is an upper banded triangular matrix\nwith the main diagonal and k super-diagonals, everything\nelse can be assumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the k'th\nrow, the first super diagonal resides on the RHS of the k-1'th row, etc,\nwith the k'th diagonal on the RHS of the 0'th row.\nEx: (rocblas_fill_upper; m = 5; k = 2)\n1 6 9 0 0 0 0 9 8 7\n0 2 7 8 0 0 6 7 8 9\n0 0 3 8 7 ----> 1 2 3 4 5\n0 0 0 4 9 0 0 0 0 0\n0 0 0 0 5 0 0 0 0 0\n\nif uplo == rocblas_fill_lower:\nThe matrix represnted is a lower banded triangular matrix\nwith the main diagonal and k sub-diagonals, everything else can be\nassumed to be 0.\nThe matrix is compacted so that the main diagonal resides on the 0'th row,\nworking up to the k'th diagonal residing on the LHS of the k'th row.\nEx: (rocblas_fill_lower; m = 5; k = 2)\n1 0 0 0 0 1 2 3 4 5\n6 2 0 0 0 6 7 8 9 0\n9 7 3 0 0 ----> 9 8 7 0 0\n0 8 8 4 0 0 0 0 0 0\n0 0 7 9 5 0 0 0 0 0\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i. lda must satisfy lda > k.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one A_i matrix to the next A_(i + 1).\n@param[inout]\nx device array to the first vector x_i of the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one x_i matrix to the next x_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_stbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + k: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbsv solves:\n\nA*x = b or\nA**T*x = b or\nA**H*x = b\nwhere x and b are vectors and A is a banded triangular matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A*x = b\n- rocblas_operation_transpose: Solves A**T*x = b\n- rocblas_operation_conjugate_transpose: Solves A**H*x = b\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular (i.e. the diagonal elements\nof A are not used in computations).\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of b. n >= 0.\n@param[in]\nk [rocblas_int]\n\nif(uplo == rocblas_fill_upper)\nk specifies the number of super-diagonals of A.\nif(uplo == rocblas_fill_lower)\nk specifies the number of sub-diagonals of A.\nk >= 0.\n\n@param[in]\nA device pointer storing the matrix A in banded format.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\nlda >= (k + 1).\n\n@param[inout]\nx device pointer storing input vector b. Overwritten by the output vector x.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n"] + pub fn rocblas_stbsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const f32, + lda: rocblas_int, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const f64, + lda: rocblas_int, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbsv_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i or\nA_i**H*x_i = b_i\nwhere x_i and b_i are vectors and A_i is a banded triangular matrix,\nfor i = [1, batch_count].\n\nThe input vectors b_i are overwritten by the output vectors x_i.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A_i*x_i = b_i\n- rocblas_operation_transpose: Solves A_i**T*x_i = b_i\n- rocblas_operation_conjugate_transpose: Solves A_i**H*x_i = b_i\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular (i.e. the diagonal elements\nof each A_i are not used in computations).\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of each b_i. n >= 0.\n@param[in]\nk [rocblas_int]\n\nif(uplo == rocblas_fill_upper)\nk specifies the number of super-diagonals of each A_i.\nif(uplo == rocblas_fill_lower)\nk specifies the number of sub-diagonals of each A_i.\nk >= 0.\n\n@param[in]\nA device vector of device pointers storing each matrix A_i in banded format.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\nlda >= (k + 1).\n\n@param[inout]\nx device vector of device pointers storing each input vector b_i. Overwritten by each output\nvector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_stbsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntbsv_strided_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i or\nA_i**H*x_i = b_i\nwhere x_i and b_i are vectors and A_i is a banded triangular matrix,\nfor i = [1, batch_count].\n\nThe input vectors b_i are overwritten by the output vectors x_i.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix.\n- rocblas_fill_lower: A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A_i*x_i = b_i\n- rocblas_operation_transpose: Solves A_i**T*x_i = b_i\n- rocblas_operation_conjugate_transpose: Solves A_i**H*x_i = b_i\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular (i.e. the diagonal elements\nof each A_i are not used in computations).\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of each b_i. n >= 0.\n@param[in]\nk [rocblas_int]\n\nif(uplo == rocblas_fill_upper)\nk specifies the number of super-diagonals of each A_i.\nif(uplo == rocblas_fill_lower)\nk specifies the number of sub-diagonals of each A_i.\nk >= 0.\n\n@param[in]\nA device pointer pointing to the first banded matrix A_1.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\nlda >= (k + 1).\n@param[in]\nstride_A [rocblas_stride]\nspecifies the distance between the start of one matrix (A_i) and the next (A_i+1).\n\n@param[inout]\nx device pointer pointing to the first input vector b_1. Overwritten by output vectors x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nspecifies the distance between the start of one vector (x_i) and the next (x_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_stbsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtbsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctbsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztbsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + k: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrsv solves:\n\nA*x = b or\nA**T*x = b\nwhere x and b are vectors and A is a triangular matrix.\nThe vector x is overwritten on b.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of b. m >= 0.\n\n@param[in]\nA device pointer storing matrix A,\nof dimension ( lda, m )\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\nlda = max( 1, m ).\n\n@param[in]\nx device pointer storing vector x.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n"] + pub fn rocblas_strsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + lda: rocblas_int, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + lda: rocblas_int, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrsv_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i\nwhere (A_i, x_i, b_i) is the i-th instance of the batch.\nx_i and b_i are vectors and A_i is an\nm by m triangular matrix.\n\nThe vector x is overwritten on b.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of b. m >= 0.\n\n@param[in]\nA device array of device pointers storing each matrix A_i.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\nlda = max(1, m)\n\n@param[in]\nx device array of device pointers storing each vector x_i.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_strsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntrsv_strided_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i\nwhere (A_i, x_i, b_i) is the i-th instance of the batch.\nx_i and b_i are vectors and A_i is an m by m triangular matrix, for i = 1, ..., batch_count.\n\nThe vector x is overwritten on b.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of each b_i. m >= 0.\n\n@param[in]\nA device pointer to the first matrix (A_1) in the batch, of dimension ( lda, m ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one A_i matrix to the next A_(i + 1).\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\nlda = max( 1, m ).\n\n@param[in, out]\nx device pointer to the first vector (x_1) in the batch.\n\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one x_i vector to the next x_(i + 1)\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_strsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpsv solves:\n\nA*x = b or\nA**T*x = b or\nA**H*x = b\nwhere x and b are vectors and A is a triangular matrix stored in the packed format.\n\nThe input vector b is overwritten by the output vector x.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A*x = b\n- rocblas_operation_transpose: Solves A**T*x = b\n- rocblas_operation_conjugate_transpose: Solves A**H*x = b\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular (i.e. the diagonal elements\nof A are not used in computations).\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of b. n >= 0.\n\n@param[in]\nAP device pointer storing the packed version of matrix A,\nof dimension >= (n * (n + 1) / 2).\n\n@param[inout]\nx device pointer storing vector b on input, overwritten by x on output.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n"] + pub fn rocblas_stpsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const f32, + x: *mut f32, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const f64, + x: *mut f64, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const rocblas_float_complex, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpsv( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const rocblas_double_complex, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpsv_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i or\nA_i**H*x_i = b_i\nwhere x_i and b_i are vectors and A_i is a triangular matrix stored in the packed format,\nfor i in [1, batch_count].\n\nThe input vectors b_i are overwritten by the output vectors x_i.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A*x = b\n- rocblas_operation_transpose: Solves A**T*x = b\n- rocblas_operation_conjugate_transpose: Solves A**H*x = b\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: Each A_i is assumed to be unit triangular (i.e. the diagonal elements\nof each A_i are not used in computations).\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of each b_i. n >= 0.\n\n@param[in]\nAP device array of device pointers storing the packed versions of each matrix A_i,\nof dimension >= (n * (n + 1) / 2).\n\n@param[inout]\nx device array of device pointers storing each input vector b_i, overwritten by x_i on output.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of instances in the batch.\n"] + pub fn rocblas_stpsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const *const f32, + x: *const *mut f32, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const *const f64, + x: *const *mut f64, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const *const rocblas_float_complex, + x: *const *mut rocblas_float_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpsv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const *const rocblas_double_complex, + x: *const *mut rocblas_double_complex, + incx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\ntpsv_strided_batched solves:\n\nA_i*x_i = b_i or\nA_i**T*x_i = b_i or\nA_i**H*x_i = b_i\nwhere x_i and b_i are vectors and A_i is a triangular matrix stored in the packed format,\nfor i in [1, batch_count].\n\nThe input vectors b_i are overwritten by the output vectors x_i.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_none: Solves A*x = b\n- rocblas_operation_transpose: Solves A**T*x = b\n- rocblas_operation_conjugate_transpose: Solves A**H*x = b\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular (i.e. the diagonal elements\nof each A_i are not used in computations).\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows of each b_i. n >= 0.\n\n@param[in]\nAP device pointer pointing to the first packed matrix A_1,\nof dimension >= (n * (n + 1) / 2).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the beginning of one packed matrix (AP_i) and the next (AP_i+1).\n\n@param[inout]\nx device pointer pointing to the first input vector b_1. Overwritten by each x_i on output.\n\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the beginning of one vector (x_i) and the next (x_i+1).\n@param[in]\nbatch_count [rocblas_int]\nspecifies the number of instances in the batch.\n"] + pub fn rocblas_stpsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const f32, + stride_A: rocblas_stride, + x: *mut f32, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtpsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const f64, + stride_A: rocblas_stride, + x: *mut f64, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctpsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const rocblas_float_complex, + stride_A: rocblas_stride, + x: *mut rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztpsv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + n: rocblas_int, + AP: *const rocblas_double_complex, + stride_A: rocblas_stride, + x: *mut rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsymv performs the matrix-vector operation:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and\nA should contain an upper or lower triangular n by n symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced.\n- if rocblas_fill_lower, the upper part of A is not referenced.\n@param[in]\nn [rocblas_int]\n@param[in]\nalpha\nspecifies the scalar alpha.\n@param[in]\nA pointer storing matrix A on the GPU\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nx pointer storing vector x on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta specifies the scalar beta\n@param[out]\ny pointer storing vector y on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_ssymv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + x: *const f32, + incx: rocblas_int, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + x: *const f64, + incx: rocblas_int, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsymv_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric matrix, for i = 1, ..., batch_count.\nA a should contain an upper or lower triangular symmetric matrix\nand the opposing triangular part of A is not referenced.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced.\n- if rocblas_fill_lower, the upper part of A is not referenced.\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each matrix A_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssymv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + beta: *const f32, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + beta: *const f64, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + beta: *const rocblas_float_complex, + y: *const *mut rocblas_float_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + beta: *const rocblas_double_complex, + y: *const *mut rocblas_double_complex, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsymv_strided_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric matrix, for i = 1, ..., batch_count.\nA a should contain an upper or lower triangular symmetric matrix\nand the opposing triangular part of A is not referenced.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each matrix A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx Device pointer to the first vector x_1 on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stridex is of appropriate size.\nThis typically means stridex >= n * incx. stridex should be non zero.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny Device pointer to the first vector y_1 on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stride_y. However, ensure that stridey is of appropriate size.\nThis typically means stridey >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssymv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const rocblas_float_complex, + y: *mut rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const rocblas_double_complex, + y: *mut rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspmv performs the matrix-vector operation:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and\nA should contain an upper or lower triangular n by n packed symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo rocblas_fill\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\n@param[in]\nalpha\nspecifies the scalar alpha.\n@param[in]\nA pointer storing matrix A on the GPU.\n@param[in]\nx pointer storing vector x on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta specifies the scalar beta.\n@param[out]\ny pointer storing vector y on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_sspmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + x: *const f32, + incx: rocblas_int, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + x: *const f64, + incx: rocblas_int, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspmv_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric matrix, for i = 1, ..., batch_count.\nA should contain an upper or lower triangular n by n packed symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sspmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + x: *const *const f32, + incx: rocblas_int, + beta: *const f32, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + x: *const *const f64, + incx: rocblas_int, + beta: *const f64, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspmv_strided_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric matrix, for i = 1, ..., batch_count.\nA should contain an upper or lower triangular n by n packed symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx Device pointer to the first vector x_1 on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stridex. However, ensure that stridex is of appropriate size.\nThis typically means stridex >= n * incx. stridex should be non zero.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny Device pointer to the first vector y_1 on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stridey. However, ensure that stridey is of appropriate size.\nThis typically means stridey >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sspmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + strideA: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + strideA: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsbmv performs the matrix-vector operation:\n\ny := alpha*A*x + beta*y\nwhere alpha and beta are scalars, x and y are n element vectors and\nA should contain an upper or lower triangular n by n symmetric banded matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo rocblas_fill\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\n@param[in]\nk [rocblas_int]\nspecifies the number of sub- and super-diagonals.\n@param[in]\nalpha\nspecifies the scalar alpha.\n@param[in]\nA pointer storing matrix A on the GPU.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of matrix A.\n@param[in]\nx pointer storing vector x on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nbeta specifies the scalar beta.\n@param[out]\ny pointer storing vector y on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n"] + pub fn rocblas_ssbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + x: *const f32, + incx: rocblas_int, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsbmv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + x: *const f64, + incx: rocblas_int, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsbmv_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric banded matrix, for i = 1, ..., batch_count.\nA should contain an upper or lower triangular n by n symmetric banded matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nk [rocblas_int]\nspecifies the number of sub- and super-diagonals.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each matrix A_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_dsbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + beta: *const f64, + y: *const *mut f64, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ssbmv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + beta: *const f32, + y: *const *mut f32, + incy: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsbmv_strided_batched performs the matrix-vector operation:\n\ny_i := alpha*A_i*x_i + beta*y_i\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha and beta are scalars, x_i and y_i are vectors and A_i is an\nn by n symmetric banded matrix, for i = 1, ..., batch_count.\nA should contain an upper or lower triangular n by n symmetric banded matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nnumber of rows and columns of each matrix A_i.\n@param[in]\nk [rocblas_int]\nspecifies the number of sub- and super-diagonals.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each matrix A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx Device pointer to the first vector x_1 on the GPU.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stridex. However, ensure that stridex is of appropriate size.\nThis typically means stridex >= n * incx. stridex should be non zero.\n@param[in]\nbeta device pointer or host pointer to scalar beta.\n@param[out]\ny Device pointer to the first vector y_1 on the GPU.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stridey. However, ensure that stridey is of appropriate size.\nThis typically means stridey >= n * incy. stridey should be non zero.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f32, + y: *mut f32, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsbmv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + strideA: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + beta: *const f64, + y: *mut f64, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nger,geru,gerc performs the matrix-vector operations:\n\nA := A + alpha*x*y**T , OR\nA := A + alpha*x*y**H for gerc\nwhere alpha is a scalar, x and y are vectors, and A is an\nm by n matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nm [rocblas_int]\nthe number of rows of the matrix A.\n@param[in]\nn [rocblas_int]\nthe number of columns of the matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n"] + pub fn rocblas_sger( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + y: *const f32, + incy: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dger( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + y: *const f64, + incy: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeru( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeru( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgerc( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgerc( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nger_batched,geru_batched,gerc_batched perform a batch of the matrix-vector operations:\n\nA := A + alpha*x*y**T , OR\nA := A + alpha*x*y**H for gerc\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha is a scalar, x_i and y_i are vectors and A_i is an\nm by n matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nm [rocblas_int]\nthe number of rows of each matrix A_i.\n@param[in]\nn [rocblas_int]\nthe number of columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each vector x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[inout]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sger_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + y: *const *const f32, + incy: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dger_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + y: *const *const f64, + incy: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeru_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeru_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgerc_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgerc_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nger_strided_batched,geru_strided_batched,gerc_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*y_i**T, OR\nA_i := A_i + alpha*x_i*y_i**H for gerc\nwhere (A_i, x_i, y_i) is the i-th instance of the batch.\nalpha is a scalar, x_i and y_i are vectors and A_i is an\nm by n matrix, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nm [rocblas_int]\nthe number of rows of each matrix A_i.\n@param[in]\nn [rocblas_int]\nthe number of columns of each matrix A_i.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nincx [rocblas_int]\nspecifies the increments for the elements of each vector x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. For a typical\ncase this means stride_x >= m * incx.\n@param[inout]\ny device pointer to the first vector (y_1) in the batch.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each vector y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\nThere are no restrictions placed on stride_y. However, ensure that stride_y is of appropriate size. For a typical\ncase this means stride_y >= n * incy.\n@param[inout]\nA device pointer to the first matrix (A_1) in the batch.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1)\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sger_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f32, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dger_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f64, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeru_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeru_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgerc_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgerc_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr performs the matrix-vector operations:\n\nA := A + alpha*x*x**T\nwhere alpha is a scalar, x is a vector, and A is an\nn by n symmetric matrix, supplied in packed form.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of A is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\nthe symmetric matrix A. Of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the symmetric matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the symmetric matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0"] + pub fn rocblas_sspr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + AP: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + AP: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cspr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + AP: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zspr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + AP: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**T\nwhere alpha is a scalar, x_i is a vector, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach symmetric matrix A_i of at least size ((n * (n + 1)) / 2). Array is of at least size batch_count.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sspr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + AP: *const *mut f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + AP: *const *mut f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cspr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + AP: *const *mut rocblas_float_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zspr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + AP: *const *mut rocblas_double_complex, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr_strided_batched performs the matrix-vector operations:\n\nA_i := A_i + alpha*x_i*x_i**T\nwhere alpha is a scalar, x_i is a vector, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\neach symmetric matrix A_i. Points to the first A_1.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(2) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sspr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut f32, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut f64, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cspr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut rocblas_float_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zspr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + AP: *mut rocblas_double_complex, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr2 performs the matrix-vector operation:\n\nA := A + alpha*x*y**T + alpha*y*x**T\nwhere alpha is a scalar, x and y are vectors, and A is an\nn by n symmetric matrix, supplied in packed form.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of A is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of A is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\nthe symmetric matrix A. Of at least size ((n * (n + 1)) / 2).\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of the symmetric matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of the symmetric matrix A is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(n) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0"] + pub fn rocblas_sspr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + y: *const f32, + incy: rocblas_int, + AP: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + y: *const f64, + incy: rocblas_int, + AP: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr2_batched performs the matrix-vector operation:\n\nA_i := A_i + alpha*x_i*y_i**T + alpha*y_i*x_i**T\nwhere alpha is a scalar, x_i and y_i are vectors, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[inout]\nAP device array of device pointers storing the packed version of the specified triangular portion of\neach symmetric matrix A_i of at least size ((n * (n + 1)) / 2). Array is of at least size batch_count.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(n) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sspr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + y: *const *const f32, + incy: rocblas_int, + AP: *const *mut f32, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + y: *const *const f64, + incy: rocblas_int, + AP: *const *mut f64, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nspr2_strided_batched performs the matrix-vector operation:\n\nA_i := A_i + alpha*x_i*y_i**T + alpha*y_i*x_i**T\nwhere alpha is a scalar, x_i and y_i are vectors, and A_i is an\nn by n symmetric matrix, supplied in packed form, for i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- rocblas_fill_upper: The upper triangular part of each A_i is supplied in AP.\n- rocblas_fill_lower: The lower triangular part of each A_i is supplied in AP.\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A_i. Must be at least 0.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer pointing to the first vector (x_1).\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\n@param[in]\ny device pointer pointing to the first vector (y_1).\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1).\n@param[inout]\nAP device pointer storing the packed version of the specified triangular portion of\neach symmetric matrix A_i. Points to the first A_1.\n\nif uplo == rocblas_fill_upper:\nThe upper triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(0,1)\nAP(2) = A(1,1), etc.\nEx: (rocblas_fill_upper; n = 4)\n1 2 4 7\n2 3 5 8 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n4 5 6 9\n7 8 9 0\n\nif uplo == rocblas_fill_lower:\nThe lower triangular portion of each symmetric matrix A_i is supplied.\nThe matrix is compacted so that AP contains the triangular portion\ncolumn-by-column\nso that:\nAP(0) = A(0,0)\nAP(1) = A(1,0)\nAP(n) = A(2,1), etc.\nEx: (rocblas_fill_lower; n = 4)\n1 2 3 4\n2 5 6 7 -----> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n3 6 8 9\n4 7 9 0\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one (A_i) and the next (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch."] + pub fn rocblas_sspr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const f32, + incy: rocblas_int, + stride_y: rocblas_stride, + AP: *mut f32, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dspr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const f64, + incy: rocblas_int, + stride_y: rocblas_stride, + AP: *mut f64, + stride_A: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr performs the matrix-vector operations:\n\nA := A + alpha*x*x**T\nwhere alpha is a scalar, x is a vector, and A is an\nn by n symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n"] + pub fn rocblas_ssyr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr_batched performs a batch of matrix-vector operations:\n\nA[i] := A[i] + alpha*x[i]*x[i]**T\nwhere alpha is a scalar, x is an array of vectors, and A is an array of\nn by n symmetric matrices, for i = 1 , ... , batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr_strided_batched performs the matrix-vector operations:\n\nA[i] := A[i] + alpha*x[i]*x[i]**T\nwhere alpha is a scalar, vectors, and A is an array of\nn by n symmetric matrices, for i = 1 , ... , batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstridex [rocblas_stride]\nspecifies the pointer increment between vectors (x_i) and (x_i+1).\n@param[inout]\nA device pointer to the first matrix A_1.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr2 performs the matrix-vector operations:\n\nA := A + alpha*x*y**T + alpha*y*x**T\nwhere alpha is a scalar, x and y are vectors, and A is an\nn by n symmetric matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\ny device pointer storing vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n"] + pub fn rocblas_ssyr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + y: *const f32, + incy: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + y: *const f64, + incy: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + y: *const rocblas_float_complex, + incy: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + y: *const rocblas_double_complex, + incy: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr2_batched performs a batch of matrix-vector operations:\n\nA[i] := A[i] + alpha*x[i]*y[i]**T + alpha*y[i]*x[i]**T\nwhere alpha is a scalar, x[i] and y[i] are vectors, and A[i] is a\nn by n symmetric matrix, for i = 1 , ... , batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[inout]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const *const f32, + incx: rocblas_int, + y: *const *const f32, + incy: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const *const f64, + incx: rocblas_int, + y: *const *const f64, + incy: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + y: *const *const rocblas_float_complex, + incy: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + y: *const *const rocblas_double_complex, + incy: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 2 API \n\n\\details\nsyr2_strided_batched the matrix-vector operations:\n\nA[i] := A[i] + alpha*x[i]*y[i]**T + alpha*y[i]*x[i]**T\nwhere alpha is a scalar, x[i] and y[i] are vectors, and A[i] is a\nn by n symmetric matrices, for i = 1 , ... , batch_count\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n- if rocblas_fill_upper, the lower part of A is not referenced\n- if rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\nn [rocblas_int]\nthe number of rows and columns of each matrix A.\n@param[in]\nalpha\ndevice pointer or host pointer to scalar alpha.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstridex [rocblas_stride]\nspecifies the pointer increment between vectors (x_i) and (x_i+1).\n@param[in]\ny device pointer to the first vector y_1.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstridey [rocblas_stride]\nspecifies the pointer increment between vectors (y_i) and (y_i+1).\n@param[inout]\nA device pointer to the first matrix A_1.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstrideA [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f32, + x: *const f32, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f32, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const f64, + x: *const f64, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const f64, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_float_complex, + x: *const rocblas_float_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_float_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + alpha: *const rocblas_double_complex, + x: *const rocblas_double_complex, + incx: rocblas_int, + stridex: rocblas_stride, + y: *const rocblas_double_complex, + incy: rocblas_int, + stridey: rocblas_stride, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nhemm performs one of the matrix-matrix operations:\n\nC := alpha*A*B + beta*C if side == rocblas_side_left,\nC := alpha*B*A + beta*C if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B and C are m by n matrices, and\nA is a Hermitian matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C := alpha*A*B + beta*C\n- rocblas_side_right: C := alpha*B*A + beta*C\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix\n- rocblas_fill_lower: A is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B and C. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B and C. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A and B are not referenced.\n\n@param[in]\nA pointer storing matrix A on the GPU.\n- A is m by m if side == rocblas_side_left\n- A is n by n if side == rocblas_side_right\nOnly the upper/lower triangular part is accessed.\nThe imaginary component of the diagonal elements is not used.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m ).\n"] + pub fn rocblas_chemm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nhemm_batched performs a batch of the matrix-matrix operations:\n\nC_i := alpha*A_i*B_i + beta*C_i if side == rocblas_side_left,\nC_i := alpha*B_i*A_i + beta*C_i if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B_i and C_i are m by n matrices, and\nA_i is a Hermitian matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C_i := alpha*A_i*B_i + beta*C_i\n- rocblas_side_right: C_i := alpha*B_i*A_i + beta*C_i\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix\n- rocblas_fill_lower: A_i is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i and C_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i and C_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i and B_i are not referenced.\n\n@param[in]\nA device array of device pointers storing each matrix A_i on the GPU.\n- A_i is m by m if side == rocblas_side_left\n- A_i is n by n if side == rocblas_side_right\nOnly the upper/lower triangular part is accessed.\nThe imaginary component of the diagonal elements is not used.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nB device array of device pointers storing each matrix B_i on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C_i need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C_i. ldc >= max( 1, m ).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chemm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nhemm_strided_batched performs a batch of the matrix-matrix operations:\n\nC_i := alpha*A_i*B_i + beta*C_i if side == rocblas_side_left,\nC_i := alpha*B_i*A_i + beta*C_i if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B_i and C_i are m by n matrices, and\nA_i is a Hermitian matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C_i := alpha*A_i*B_i + beta*C_i\n- rocblas_side_right: C_i := alpha*B_i*A_i + beta*C_i\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix\n- rocblas_fill_lower: A_i is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i and C_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i and C_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i and B_i are not referenced.\n\n@param[in]\nA device pointer to first matrix A_1\n- A_i is m by m if side == rocblas_side_left\n- A_i is n by n if side == rocblas_side_right\nOnly the upper/lower triangular part is accessed.\nThe imaginary component of the diagonal elements is not used.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nB device pointer to first matrix B_1 of dimension (ldb, n) on the GPU\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif side = rocblas_operation_none, ldb >= max( 1, m ),\notherwise ldb >= max( 1, n ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device pointer to first matrix C_1 of dimension (ldc, n) on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_chemm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zhemm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherk performs one of the matrix-matrix operations for a Hermitian rank-k update:\n\nC := alpha*op( A )*op( A )^H + beta*C,\n\nwhere alpha and beta are scalars, op(A) is an n by k matrix, and\nC is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A ) = A, and A is n by k if transA == rocblas_operation_none\nop( A ) = A^H and A is k by n if transA == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n- rocblas_operation_none: op(A) = A\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if transA = rocblas_operation_none, otherwise (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_cherk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const rocblas_float_complex, + lda: rocblas_int, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const rocblas_double_complex, + lda: rocblas_int, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherk_batched performs a batch of the matrix-matrix operations for a Hermitian rank-k update:\n\nC_i := alpha*op( A_i )*op( A_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A) is an n by k matrix, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A_i ) = A_i, and A_i is n by k if transA == rocblas_operation_none\nop( A_i ) = A_i^H and A_i is k by n if transA == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n- rocblas_operation_none: op(A) = A\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen transA is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cherk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + beta: *const f32, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + beta: *const f64, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherk_strided_batched performs a batch of the matrix-matrix operations for a Hermitian rank-k update:\n\nC_i := alpha*op( A_i )*op( A_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A) is an n by k matrix, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A_i ) = A_i, and A_i is n by k if transA == rocblas_operation_none\nop( A_i ) = A_i^H and A_i is k by n if transA == rocblas_operation_conjugate_transpose\n\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n- rocblas_operation_none: op(A) = A\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen transA is rocblas_operation_none, otherwise of dimension (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cherk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nher2k performs one of the matrix-matrix operations for a Hermitian rank-2k update:\n\nC := alpha*op( A )*op( B )^H + conj(alpha)*op( B )*op( A )^H + beta*C,\n\nwhere alpha and beta are scalars, op(A) and op(B) are n by k matrices, and\nC is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A ) = A, op( B ) = B, and A and B are n by k if trans == rocblas_operation_none\nop( A ) = A^H, op( B ) = B^H, and A and B are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op( A ) = A^H, op( B ) = B^H\n- rocblas_operation_none: op( A ) = A, op( B ) = B\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if trans = rocblas_operation_none, otherwise (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is ( ldb, k ) when if trans = rocblas_operation_none, otherwise (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_cher2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nher2k_batched performs a batch of the matrix-matrix operations for a Hermitian rank-2k update:\n\nC_i := alpha*op( A_i )*op( B_i )^H + conj(alpha)*op( B_i )*op( A_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrices, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^H, op( B_i ) = B_i^H, and A_i and B_i are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n- rocblas_operation_none: op(A) = A\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n@param[in]\nB device array of device pointers storing each matrix_i B of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n).\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cher2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nher2k_strided_batched performs a batch of the matrix-matrix operations for a Hermitian rank-2k update:\n\nC_i := alpha*op( A_i )*op( B_i )^H + conj(alpha)*op( B_i )*op( A_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrices, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^H, op( B_i ) = B_i^H, and A_i and B_i are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^H, op( B_i ) = B_i^H\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nB Device pointer to the first matrix B_1 on the GPU of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n).\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cher2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zher2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherkx performs one of the matrix-matrix operations for a Hermitian rank-k update:\n\nC := alpha*op( A )*op( B )^H + beta*C,\n\nwhere alpha and beta are scalars, op(A) and op(B) are n by k matrices, and\nC is a n x n Hermitian matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A )*op( B )^T will be Hermitian.\n\nop( A ) = A, op( B ) = B, and A and B are n by k if trans == rocblas_operation_none\nop( A ) = A^H, op( B ) = B^H, and A and B are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op( A ) = A^H, op( B ) = B^H\n- rocblas_operation_none: op( A ) = A, op( B ) = B\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if trans = rocblas_operation_none, otherwise (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is ( ldb, k ) when if trans = rocblas_operation_none, otherwise (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_cherkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherkx_batched performs a batch of the matrix-matrix operations for a Hermitian rank-k update:\n\nC_i := alpha*op( A_i )*op( B_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrices, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A )*op( B )^T will be Hermitian.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^H, op( B_i ) = B_i^H, and A_i and B_i are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n- rocblas_operation_none: op(A) = A\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nB device array of device pointers storing each matrix_i B of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cherkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nherkx_strided_batched performs a batch of the matrix-matrix operations for a Hermitian rank-k update:\n\nC_i := alpha*op( A_i )*op( B_i )^H + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrices, and\nC_i is a n x n Hermitian matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A )*op( B )^T will be Hermitian.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^H, op( B_i ) = B_i^H, and A_i and B_i are k by n if trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^H, op( B_i ) = B_i^H\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1)\n\n@param[in]\nB Device pointer to the first matrix B_1 on the GPU of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n).\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1)\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU.\nThe imaginary component of the diagonal elements are not used but are set to zero unless quick return.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_cherkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zherkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsymm performs one of the matrix-matrix operations:\n\nC := alpha*A*B + beta*C if side == rocblas_side_left,\nC := alpha*B*A + beta*C if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B and C are m by n matrices, and\nA is a symmetric matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C := alpha*A*B + beta*C\n- rocblas_side_right: C := alpha*B*A + beta*C\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix\n- rocblas_fill_lower: A is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B and C. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B and C. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A and B are not referenced.\n\n@param[in]\nA pointer storing matrix A on the GPU.\n- A is m by m if side == rocblas_side_left\n- A is n by n if side == rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m ).\n"] + pub fn rocblas_ssymm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsymm_batched performs a batch of the matrix-matrix operations:\n\nC_i := alpha*A_i*B_i + beta*C_i if side == rocblas_side_left,\nC_i := alpha*B_i*A_i + beta*C_i if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B_i and C_i are m by n matrices, and\nA_i is a symmetric matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C_i := alpha*A_i*B_i + beta*C_i\n- rocblas_side_right: C_i := alpha*B_i*A_i + beta*C_i\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix\n- rocblas_fill_lower: A_i is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i and C_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i and C_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i and B_i are not referenced.\n\n@param[in]\nA device array of device pointers storing each matrix A_i on the GPU.\n- A_i is m by m if side == rocblas_side_left\n- A_i is n by n if side == rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nB device array of device pointers storing each matrix B_i on the GPU.\nMatrix dimension is m by n\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C_i need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nMatrix dimension is m by n.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C_i. ldc >= max( 1, m ).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssymm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsymm_strided_batched performs a batch of the matrix-matrix operations:\n\nC_i := alpha*A_i*B_i + beta*C_i if side == rocblas_side_left,\nC_i := alpha*B_i*A_i + beta*C_i if side == rocblas_side_right,\n\nwhere alpha and beta are scalars, B_i and C_i are m by n matrices, and\nA_i is a symmetric matrix stored as either upper or lower.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: C_i := alpha*A_i*B_i + beta*C_i\n- rocblas_side_right: C_i := alpha*B_i*A_i + beta*C_i\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A_i is an upper triangular matrix\n- rocblas_fill_lower: A_i is a lower triangular matrix\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i and C_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i and C_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i and B_i are not referenced.\n\n@param[in]\nA device pointer to first matrix A_1\n- A_i is m by m if side == rocblas_side_left\n- A_i is n by n if side == rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\notherwise lda >= max( 1, n ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nB device pointer to first matrix B_1 of dimension (ldb, n) on the GPU.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device pointer to first matrix C_1 of dimension (ldc, n) on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssymm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsymm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csymm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsymm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrk performs one of the matrix-matrix operations for a symmetric rank-k update:\n\nC := alpha*op( A )*op( A )^T + beta*C,\n\nwhere alpha and beta are scalars, op(A) is an n by k matrix, and\nC is a symmetric n x n matrix stored as either upper or lower.\n\nop( A ) = A, and A is n by k if transA == rocblas_operation_none\nop( A ) = A^T and A is k by n if transA == rocblas_operation_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_none: op(A) = A\n- rocblas_operation_conjugate_transpose: op(A) = A^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types. See cherk\nand zherk.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if transA = rocblas_operation_none, otherwise (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_ssyrk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrk( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrk_batched performs a batch of the matrix-matrix operations for a symmetric rank-k update:\n\nC_i := alpha*op( A_i )*op( A_i )^T + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) is an n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nop( A_i ) = A_i, and A_i is n by k if transA == rocblas_operation_none\nop( A_i ) = A_i^T and A_i is k by n if transA == rocblas_operation_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_none: op(A) = A\n- rocblas_operation_conjugate_transpose: op(A) = A^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types. See cherk\nand zherk.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen transA is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyrk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + beta: *const f32, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + beta: *const f64, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrk_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrk_strided_batched performs a batch of the matrix-matrix operations for a symmetric rank-k update:\n\nC_i := alpha*op( A_i )*op( A_i )^T + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) is an n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nop( A_i ) = A_i, and A_i is n by k if transA == rocblas_operation_none\nop( A_i ) = A_i^T and A_i is k by n if transA == rocblas_operation_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_none: op(A) = A\n- rocblas_operation_conjugate_transpose: op(A) = A^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types. See cherk\nand zherk.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen transA is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif transA = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU. on the GPU.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1)\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyrk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrk_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + transA: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyr2k performs one of the matrix-matrix operations for a symmetric rank-2k update:\n\nC := alpha*(op( A )*op( B )^T + op( B )*op( A )^T) + beta*C,\n\nwhere alpha and beta are scalars, op(A) and op(B) are n by k matrix, and\nC is a symmetric n x n matrix stored as either upper or lower.\n\nop( A ) = A, op( B ) = B, and A and B are n by k if trans == rocblas_operation_none\nop( A ) = A^T, op( B ) = B^T, and A and B are k by n if trans == rocblas_operation_transpose\nor for ssyr2k and dsyr2k when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A ) = A^T, op( B ) = B^T\n- rocblas_operation_none: op( A ) = A, op( B ) = B\n- rocblas_operation_conjugate_transpose: op( A ) = A^T, op( B ) = B^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyr2k and zsyr2k.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A) and op(B). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if trans = rocblas_operation_none, otherwise (lda, n)\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is ( ldb, k ) when if trans = rocblas_operation_none, otherwise (ldb, n)\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_ssyr2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2k( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyr2k_batched performs a batch of the matrix-matrix operations for a symmetric rank-2k update:\n\nC_i := alpha*(op( A_i )*op( B_i )^T + op( B_i )*op( A_i )^T) + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^T, op( B_i ) = B_i^T, and A_i and B_i are k by n if trans == rocblas_operation_transpose\nor for ssyr2k_batched and dsyr2k_batched when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyr2k_batched and zsyr2k_batched.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n@param[in]\nB device array of device pointers storing each matrix_i B of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n).\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2k_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyr2k_strided_batched performs a batch of the matrix-matrix operations for a symmetric rank-2k update:\n\nC_i := alpha*(op( A_i )*op( B_i )^T + op( B_i )*op( A_i )^T) + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^T, op( B_i ) = B_i^T, and A_i and B_i are k by n if trans == rocblas_operation_transpose\nor for ssyr2k_strided_batched and dsyr2k_strided_batched when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyr2k_strided_batched and zsyr2k_strided_batched.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n).\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1)\n\n@param[in]\nB Device pointer to the first matrix B_1 on the GPU of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1)\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyr2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyr2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyr2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyr2k_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrkx performs one of the matrix-matrix operations for a symmetric rank-k update:\n\nC := alpha*op( A )*op( B )^T + beta*C,\n\nwhere alpha and beta are scalars, op(A) and op(B) are n by k matrix, and\nC is a symmetric n x n matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A )*op( B )^T will be symmetric.\n\nop( A ) = A, op( B ) = B, and A and B are n by k if trans == rocblas_operation_none\nop( A ) = A^T, op( B ) = B^T, and A and B are k by n if trans == rocblas_operation_transpose\nor for ssyrkx and dsyrkx when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C is an upper triangular matrix\n- rocblas_fill_lower: C is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A ) = A^T, op( B ) = B^T\n- rocblas_operation_none: op( A ) = A, op( B ) = B\n- rocblas_operation_conjugate_transpose: op( A ) = A^T, op( B ) = B^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyrkx and zsyrkx.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A) and op(B). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA pointer storing matrix A on the GPU.\nMatrix dimension is ( lda, k ) when if trans = rocblas_operation_none, otherwise (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nB pointer storing matrix B on the GPU.\nMatrix dimension is ( ldb, k ) when if trans = rocblas_operation_none, otherwise (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC pointer storing matrix C on the GPU.\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n"] + pub fn rocblas_ssyrkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrkx( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrkx_batched performs a batch of the matrix-matrix operations for a symmetric rank-k update:\n\nC_i := alpha*op( A_i )*op( B_i )^T + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A_i )*op( B_i )^T will be symmetric.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^T, op( B_i ) = B_i^T, and A_i and B_i are k by n if trans == rocblas_operation_transpose\nor for ssyrkx_batched and dsyrkx_batched when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyrkx_batched and zsyrkx_batched.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA device array of device pointers storing each matrix_i A of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nB device array of device pointers storing each matrix_i B of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n)\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC device array of device pointers storing each matrix C_i on the GPU.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyrkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrkx_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\nsyrkx_strided_batched performs a batch of the matrix-matrix operations for a symmetric rank-k update:\n\nC_i := alpha*op( A_i )*op( B_i )^T + beta*C_i,\n\nwhere alpha and beta are scalars, op(A_i) and op(B_i) are n by k matrix, and\nC_i is a symmetric n x n matrix stored as either upper or lower.\n\nThis routine should only be used when the caller can guarantee that the result of op( A_i )*op( B_i )^T will be symmetric.\n\nop( A_i ) = A_i, op( B_i ) = B_i, and A_i and B_i are n by k if trans == rocblas_operation_none\nop( A_i ) = A_i^T, op( B_i ) = B_i^T, and A_i and B_i are k by n if trans == rocblas_operation_transpose\nor for ssyrkx_strided_batched and dsyrkx_strided_batched when trans == rocblas_operation_conjugate_transpose\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: C_i is an upper triangular matrix\n- rocblas_fill_lower: C_i is a lower triangular matrix\n\n@param[in]\ntrans [rocblas_operation]\n- rocblas_operation_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n- rocblas_operation_none: op( A_i ) = A_i, op( B_i ) = B_i\n- rocblas_operation_conjugate_transpose: op( A_i ) = A_i^T, op( B_i ) = B_i^T\n\nrocblas_operation_conjugate_transpose is not supported for complex types in csyrkx_strided_batched and zsyrkx_strided_batched.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of rows and columns of C_i. n >= 0.\n\n@param[in]\nk [rocblas_int]\nk specifies the number of columns of op(A). k >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and A need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_1 on the GPU of dimension (lda, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (lda, n)\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A_i.\n\nif trans = rocblas_operation_none, lda >= max( 1, n ),\notherwise lda >= max( 1, k ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nB Device pointer to the first matrix B_1 on the GPU of dimension (ldb, k)\nwhen trans is rocblas_operation_none, otherwise of dimension (ldb, n).\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i.\n\nif trans = rocblas_operation_none, ldb >= max( 1, n ),\notherwise ldb >= max( 1, k ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n\n@param[in]\nbeta\nbeta specifies the scalar beta. When beta is\nzero then C need not be set before entry.\n\n@param[in]\nC Device pointer to the first matrix C_1 on the GPU.\nonly the upper/lower triangular part of each C_i is accessed.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, n ).\n\n@param[inout]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_ssyrkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dsyrkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_csyrkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zsyrkx_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + trans: rocblas_operation, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm performs one of the matrix-matrix operations:\n\nB := alpha*op( A )*B, or\nB := alpha*B*op( A ),\n\nwhere alpha is a scalar, B is an m by n matrix, A is a unit, or\nnon-unit, upper or lower triangular matrix and op( A ) is one of\n\nop( A ) = A or\nop( A ) = A^T or\nop( A ) = A^H.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced. Here k is m when side == rocblas_side_left\nand is n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced. Here k is m when side == rocblas_side_left\nand is n when side == rocblas_side_right.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA are not referenced either, but are assumed to be unity.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A) multiplies B from the left or right as follows:\n- rocblas_side_left: B := alpha*op( A )*B\n- rocblas_side_right: B := alpha*B*op( A )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A) = A\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A is unit triangular as follows:\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and B need not be set before\nentry.\n\n@param[in]\nA Device pointer to matrix A on the GPU.\nA has dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[inout]\nB Device pointer to the first matrix B_0 on the GPU.\nOn entry, the leading m by n part of the array B must\ncontain the matrix B, and on exit is overwritten by the\ntransformed matrix.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n"] + pub fn rocblas_strmm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm_batched performs one of the batched matrix-matrix operations:\n\nB_i := alpha*op( A_i )*B_i, or\nB_i := alpha*B_i*op( A_i ) for i = 0, 1, ... batch_count -1,\n\nwhere alpha is a scalar, B_i is an m by n matrix, A_i is a unit, or\nnon-unit, upper or lower triangular matrix and op( A_i ) is one of\n\nop( A_i ) = A_i or op( A_i ) = A_i^T or op( A_i ) = A_i^H.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A_i) multiplies B_i from the left or right as follows:\n- rocblas_side_left: B_i := alpha*op( A_i )*B_i\n- rocblas_side_right: B_i := alpha*B_i*op( A_i )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A_i) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A_i) = A_i\n- rocblas_operation_transpose: op(A_i) = A_i^T\n- rocblas_operation_conjugate_transpose: op(A_i) = A_i^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A_i is unit triangular as follows:\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i is not referenced and B_i need not be set before\nentry.\n\n@param[in]\nA Device array of device pointers storing each matrix A_i on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA_i are not referenced either, but are assumed to be unity.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[inout]\nB device array of device pointers storing each matrix B_i on the GPU.\nOn entry, the leading m by n part of the array B_i must\ncontain the matrix B_i, and on exit is overwritten by the\ntransformed matrix.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch."] + pub fn rocblas_strmm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm_strided_batched performs one of the strided_batched matrix-matrix operations:\n\nB_i := alpha*op( A_i )*B_i, or\nB_i := alpha*B_i*op( A_i ) for i = 0, 1, ... batch_count -1,\n\nwhere alpha is a scalar, B_i is an m by n matrix, A_i is a unit, or\nnon-unit, upper or lower triangular matrix and op( A_i ) is one of\n\nop( A_i ) = A_i or\nop( A_i ) = A_i^T or\nop( A_i ) = A_i^H.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A_i) multiplies B_i from the left or right as follows:\n- rocblas_side_left: B_i := alpha*op( A_i )*B_i\n- rocblas_side_right: B_i := alpha*B_i*op( A_i )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix\n- rocblas_fill_lower: A is a lower triangular matrix\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A_i) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A_i) = A_i\n- rocblas_operation_transpose: op(A_i) = A_i^T\n- rocblas_operation_conjugate_transpose: op(A_i) = A_i^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A_i is unit triangular as follows:\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i is not referenced and B_i need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_0 on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA_i are not referenced either, but are assumed to be unity.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[inout]\nB Device pointer to the first matrix B_0 on the GPU.\nOn entry, the leading m by n part of the array B_i must\ncontain the matrix B_i, and on exit is overwritten by the\ntransformed matrix.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch."] + pub fn rocblas_strmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm_outofplace performs one of the matrix-matrix operations:\n\nC := alpha*op( A )*B, or\nC := alpha*B*op( A ),\n\nwhere alpha is a scalar, B and C are m by n matrices, A is a unit, or\nnon-unit, upper or lower triangular matrix and op( A ) is one of\n\nop( A ) = A or\nop( A ) = A^T or\nop( A ) = A^H.\n\nNote that trmm_outofplace can provide in-place functionality in the same way as trmm\nby passing in the same address for both matrices B and C.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A) multiplies B from the left or right as follows:\n- rocblas_side_left: C := alpha*op( A )*B\n- rocblas_side_right: C := alpha*B*op( A )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A) = A\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A is unit triangular as follows:\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A is not referenced and B need not be set before\nentry.\n\n@param[in]\nA Device pointer to matrix A on the GPU.\nA has dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA are not referenced either, but are assumed to be unity.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[in]\nB Device pointer to the matrix B on the GPU.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n\n@param[out]\nC Device pointer to the matrix C on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m).\nIf B and C pointers are to the same matrix then ldc must equal ldb or\nrocblas_status_invalid_size will be returned.\n"] + pub fn rocblas_strmm_outofplace( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *const f32, + ldb: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm_outofplace( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *const f64, + ldb: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm_outofplace( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm_outofplace( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm_outofplace_batched performs one of the batched matrix-matrix operations:\n\nC_i := alpha*op( A_i )*B_i, or\nC_i := alpha*B_i*op( A_i ) for i = 0, 1, ... batch_count -1,\n\nwhere alpha is a scalar, B_i is an m by n matrix, A_i is a unit, or\nnon-unit, upper or lower triangular matrix and op( A_i ) is one of\n\nop( A_i ) = A_i or\nop( A_i ) = A_i^T or\nop( A_i ) = A_i^H.\n\nNote that trmm_outofplace_batched can provide in-place functionality in the same way as trmm_batched\nby passing in the same address for both matrices B and C.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A_i) multiplies B_i from the left or right as follows:\n- rocblas_side_left: C_i := alpha*op( A_i )*B_i\n- rocblas_side_right: C_i := alpha*B_i*op( A_i )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A_i) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A_i) = A_i\n- rocblas_operation_transpose: op(A_i) = A_i^T\n- rocblas_operation_conjugate_transpose: op(A_i) = A_i^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A_i is unit triangular as follows:\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i is not referenced and B_i need not be set before\nentry.\n\n@param[in]\nA Device array of device pointers storing each matrix A_i on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA_i are not referenced either, but are assumed to be unity.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[in]\nB device array of device pointers storing each matrix B_i on the GPU.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[out]\nC device array of device pointers storing each matrix C_i on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C. ldc >= max( 1, m).\nIf B and C pointers are to the same matrix then ldc must equal ldb or\nrocblas_status_invalid_size will be returned.\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch."] + pub fn rocblas_strmm_outofplace_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *const f32, + ldb: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm_outofplace_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *const f64, + ldb: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm_outofplace_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm_outofplace_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrmm_outofplace_strided_batched performs one of the strided_batched matrix-matrix operations:\n\nC_i := alpha*op( A_i )*B_i, or\nC_i := alpha*B_i*op( A_i ) for i = 0, 1, ... batch_count -1,\n\nwhere alpha is a scalar, B_i is an m by n matrix, A_i is a unit, or\nnon-unit, upper or lower triangular matrix and op( A_i ) is one of\n\nop( A_i ) = A_i or\nop( A_i ) = A_i^T or\nop( A_i ) = A_i^H.\n\nNote that trmm_outofplace_strided_batched can provide in-place functionality in the same way as trmm_strided_batched\nby passing in the same address for both matrices B and C.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\nSpecifies whether op(A_i) multiplies B_i from the left or right as follows:\n- rocblas_side_left: C_i := alpha*op( A_i )*B_i\n- rocblas_side_right: C_i := alpha*B_i*op( A_i )\n\n@param[in]\nuplo [rocblas_fill]\nSpecifies whether the matrix A is an upper or lower triangular matrix as follows:\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\nSpecifies the form of op(A_i) to be used in the matrix multiplication as follows:\n- rocblas_operation_none: op(A_i) = A_i\n- rocblas_operation_transpose: op(A_i) = A_i^T\n- rocblas_operation_conjugate_transpose: op(A_i) = A_i^H\n\n@param[in]\ndiag [rocblas_diagonal]\nSpecifies whether or not A_i is unit triangular as follows:\n- rocblas_diagonal_unit: A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B_i. n >= 0.\n\n@param[in]\nalpha\nalpha specifies the scalar alpha. When alpha is\nzero then A_i is not referenced and B_i need not be set before\nentry.\n\n@param[in]\nA Device pointer to the first matrix A_0 on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen side == rocblas_side_left and\nis n when side == rocblas_side_right.\n\nWhen uplo == rocblas_fill_upper the leading k by k\nupper triangular part of the array A must contain the upper\ntriangular matrix and the strictly lower triangular part of\nA is not referenced.\n\nWhen uplo == rocblas_fill_lower the leading k by k\nlower triangular part of the array A must contain the lower\ntriangular matrix and the strictly upper triangular part of\nA is not referenced.\n\nNote that when diag == rocblas_diagonal_unit the diagonal elements of\nA_i are not referenced either, but are assumed to be unity.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side == rocblas_side_left, lda >= max( 1, m ),\nif side == rocblas_side_right, lda >= max( 1, n ).\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nB Device pointer to the first matrix B_0 on the GPU.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B_i. ldb >= max( 1, m ).\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1).\n\n@param[out]\nC Device pointer to the first matrix C_0 on the GPU.\n\n@param[in]\nldc [rocblas_int]\nldc specifies the first dimension of C_i. ldc >= max( 1, m).\nIf B and C pointers are to the same matrix then ldc must equal ldb or\nrocblas_status_invalid_size will be returned.\n\n@param[in]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch."] + pub fn rocblas_strmm_outofplace_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrmm_outofplace_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrmm_outofplace_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrmm_outofplace_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrtri compute the inverse of a matrix A, namely, invA\nand write the result into invA;\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n\nif rocblas_fill_upper, the lower part of A is not referenced\nif rocblas_fill_lower, the upper part of A is not referenced\n@param[in]\ndiag [rocblas_diagonal]\n- 'rocblas_diagonal_non_unit', A is non-unit triangular;\n- 'rocblas_diagonal_unit', A is unit triangular;\n@param[in]\nn [rocblas_int]\nsize of matrix A and invA.\n@param[in]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[out]\ninvA device pointer storing matrix invA.\n@param[in]\nldinvA [rocblas_int]\nspecifies the leading dimension of invA."] + pub fn rocblas_strtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const f32, + lda: rocblas_int, + invA: *mut f32, + ldinvA: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const f64, + lda: rocblas_int, + invA: *mut f64, + ldinvA: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + invA: *mut rocblas_float_complex, + ldinvA: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + invA: *mut rocblas_double_complex, + ldinvA: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrtri_batched compute the inverse of A_i and write into invA_i where\nA_i and invA_i are the i-th matrices in the batch,\nfor i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n@param[in]\ndiag [rocblas_diagonal]\n- 'rocblas_diagonal_non_unit', A is non-unit triangular;\n- 'rocblas_diagonal_unit', A is unit triangular;\n@param[in]\nn [rocblas_int]\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[out]\ninvA device array of device pointers storing the inverse of each matrix A_i.\nPartial inplace operation is supported. See below:\n-If UPLO = 'U', the leading N-by-N upper triangular part of the invA will store\nthe inverse of the upper triangular matrix, and the strictly lower\ntriangular part of invA is cleared.\n- If UPLO = 'L', the leading N-by-N lower triangular part of the invA will store\nthe inverse of the lower triangular matrix, and the strictly upper\ntriangular part of invA is cleared.\n@param[in]\nldinvA [rocblas_int]\nspecifies the leading dimension of each invA_i.\n@param[in]\nbatch_count [rocblas_int]\nnumbers of matrices in the batch."] + pub fn rocblas_strtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + invA: *const *mut f32, + ldinvA: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + invA: *const *mut f64, + ldinvA: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + invA: *const *mut rocblas_float_complex, + ldinvA: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + invA: *const *mut rocblas_double_complex, + ldinvA: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrtri_strided_batched compute the inverse of A_i and write into invA_i where\nA_i and invA_i are the i-th matrices in the batch,\nfor i = 1, ..., batch_count.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nuplo [rocblas_fill]\nspecifies whether the upper 'rocblas_fill_upper' or lower 'rocblas_fill_lower'\n@param[in]\ndiag [rocblas_diagonal]\n- 'rocblas_diagonal_non_unit', A is non-unit triangular;\n- 'rocblas_diagonal_unit', A is unit triangular;\n@param[in]\nn [rocblas_int]\n@param[in]\nA device pointer pointing to address of first matrix A_1.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A.\n@param[in]\nstride_a [rocblas_stride]\n\"batch stride a\": stride from the start of one A_i matrix to the next A_(i + 1).\n@param[out]\ninvA device pointer storing the inverses of each matrix A_i.\nPartial inplace operation is supported. See below:\n\n- If UPLO = 'U', the leading N-by-N upper triangular part of the invA will store\nthe inverse of the upper triangular matrix, and the strictly lower\ntriangular part of invA is cleared.\n\n- If UPLO = 'L', the leading N-by-N lower triangular part of the invA will store\nthe inverse of the lower triangular matrix, and the strictly upper\ntriangular part of invA is cleared.\n@param[in]\nldinvA [rocblas_int]\nspecifies the leading dimension of each invA_i.\n@param[in]\nstride_invA [rocblas_stride]\n\"batch stride invA\": stride from the start of one invA_i matrix to the next invA_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nnumbers of matrices in the batch."] + pub fn rocblas_strtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_a: rocblas_stride, + invA: *mut f32, + ldinvA: rocblas_int, + stride_invA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_a: rocblas_stride, + invA: *mut f64, + ldinvA: rocblas_int, + stride_invA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + invA: *mut rocblas_float_complex, + ldinvA: rocblas_int, + stride_invA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + invA: *mut rocblas_double_complex, + ldinvA: rocblas_int, + stride_invA: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrsm solves:\n\nop(A)*X = alpha*B or X*op(A) = alpha*B,\n\nwhere alpha is a scalar, X and B are m by n matrices,\n\nA is triangular matrix and op(A) is one of\n\nop( A ) = A or op( A ) = A^T or op( A ) = A^H.\n\nThe matrix X is overwritten on B.\n\nNote about memory allocation:\nWhen trsm is launched with a k evenly divisible by the internal block size of 128,\nand is no larger than 10 of these blocks, the API takes advantage of utilizing pre-allocated\nmemory found in the handle to increase overall performance. This memory can be managed by using\nthe environment variable WORKBUF_TRSM_B_CHNK. When this variable is not set the device memory\nused for temporary storage will default to 1 MB and may result in chunking, which in turn may\nreduce performance. Under these circumstances it is recommended that WORKBUF_TRSM_B_CHNK be set\nto the desired chunk of right hand sides to be used at a time\n(where k is m when rocblas_side_left and is n when rocblas_side_right).\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B\n- rocblas_side_right: X*op(A) = alpha*B\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A.\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B. n >= 0.\n\n@param[in]\nalpha\ndevice pointer or host pointer specifying the scalar alpha. When alpha is\n&zero then A is not referenced and B need not be set before\nentry.\n\n@param[in]\nA device pointer storing matrix A.\nof dimension ( lda, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\nif side = rocblas_side_right, lda >= max( 1, n ).\n\n@param[in,out]\nB device pointer storing matrix B.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n"] + pub fn rocblas_strsm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsm( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrsm_batched performs the following batched operation:\n\nop(A_i)*X_i = alpha*B_i or\nX_i*op(A_i) = alpha*B_i, for i = 1, ..., batch_count,\n\nwhere alpha is a scalar, X and B are batched m by n matrices,\n\nA is triangular batched matrix and op(A) is one of\n\nop( A ) = A or\nop( A ) = A^T or\nop( A ) = A^H.\n\nEach matrix X_i is overwritten on B_i for i = 1, ..., batch_count.\n\nNote about memory allocation:\nWhen trsm is launched with a k evenly divisible by the internal block size of 128,\nand is no larger than 10 of these blocks, the API takes advantage of utilizing pre-allocated\nmemory found in the handle to increase overall performance. This memory can be managed by using\nthe environment variable WORKBUF_TRSM_B_CHNK. When this variable is not set the device memory\nused for temporary storage will default to 1 MB and may result in chunking, which in turn may\nreduce performance. Under these circumstances it is recommended that WORKBUF_TRSM_B_CHNK be set\nto the desired chunk of right hand sides to be used at a time\n(where k is m when rocblas_side_left and is n when rocblas_side_right).\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B\n- rocblas_side_right: X*op(A) = alpha*B\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of each B_i. m >= 0.\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of each B_i. n >= 0.\n@param[in]\nalpha\ndevice pointer or host pointer specifying the scalar alpha. When alpha is\n&zero then A is not referenced and B need not be set before\nentry.\n@param[in]\nA device array of device pointers storing each matrix A_i on the GPU.\nMatricies are of dimension ( lda, k ), where k is m\nwhen rocblas_side_left and is n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of each A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\nif side = rocblas_side_right, lda >= max( 1, n ).\n@param[in,out]\nB device array of device pointers storing each matrix B_i on the GPU.\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of each B_i. ldb >= max( 1, m ).\n@param[in]\nbatch_count [rocblas_int]\nnumber of trsm operatons in the batch."] + pub fn rocblas_strsm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsm_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ntrsm_srided_batched performs the following strided batched operation:\n\nop(A_i)*X_i = alpha*B_i or\nX_i*op(A_i) = alpha*B_i, for i = 1, ..., batch_count,\n\nwhere alpha is a scalar, X and B are strided batched m by n matrices,\n\nA is triangular strided batched matrix and op(A) is one of\n\nop( A ) = A or\nop( A ) = A^T or\nop( A ) = A^H.\n\nEach matrix X_i is overwritten on B_i for i = 1, ..., batch_count.\n\nNote about memory allocation:\nWhen trsm is launched with a k evenly divisible by the internal block size of 128,\nand is no larger than 10 of these blocks, the API takes advantage of utilizing pre-allocated\nmemory found in the handle to increase overall performance. This memory can be managed by using\nthe environment variable WORKBUF_TRSM_B_CHNK. When this variable is not set the device memory\nused for temporary storage will default to 1 MB and may result in chunking, which in turn may\nreduce performance. Under these circumstances it is recommended that WORKBUF_TRSM_B_CHNK be set\nto the desired chunk of right hand sides to be used at a time\n(where k is m when rocblas_side_left and is n when rocblas_side_right).\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B.\n- rocblas_side_right: X*op(A) = alpha*B.\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A.\n- rocblas_operation_transpose: op(A) = A^T.\n- rocblas_operation_conjugate_transpose: op(A) = A^H.\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of each B_i. m >= 0.\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of each B_i. n >= 0.\n@param[in]\nalpha\ndevice pointer or host pointer specifying the scalar alpha. When alpha is\n&zero then A is not referenced and B need not be set before\nentry.\n@param[in]\nA device pointer pointing to the first matrix A_1.\nof dimension ( lda, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of each A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ).\nif side = rocblas_side_right, lda >= max( 1, n ).\n@param[in]\nstride_a [rocblas_stride]\nstride from the start of one A_i matrix to the next A_(i + 1).\n@param[in,out]\nB device pointer pointing to the first matrix B_1.\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of each B_i. ldb >= max( 1, m ).\n@param[in]\nstride_b [rocblas_stride]\nstride from the start of one B_i matrix to the next B_(i + 1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of trsm operatons in the batch."] + pub fn rocblas_strsm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + stride_b: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dtrsm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + stride_b: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ctrsm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + stride_b: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ztrsm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + stride_b: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngemm performs one of the matrix-matrix operations:\n\nC = alpha*op( A )*op( B ) + beta*C,\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B and C are matrices, with\nop( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nnumber or rows of matrices op( A ) and C.\n@param[in]\nn [rocblas_int]\nnumber of columns of matrices op( B ) and C.\n@param[in]\nk [rocblas_int]\nnumber of columns of matrix op( A ) and number of rows of matrix op( B ).\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n@param[in]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nB device pointer storing matrix B.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B.\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n@param[in, out]\nC device pointer storing matrix C on the GPU.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n"] + pub fn rocblas_sgemm( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + B: *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemm( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + B: *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hgemm( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_half, + A: *const rocblas_half, + lda: rocblas_int, + B: *const rocblas_half, + ldb: rocblas_int, + beta: *const rocblas_half, + C: *mut rocblas_half, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemm( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + B: *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemm( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + B: *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngemm_batched performs one of the batched matrix-matrix operations:\n\nC_i = alpha*op( A_i )*op( B_i ) + beta*C_i, for i = 1, ..., batch_count,\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B and C are strided batched matrices, with\n\nop( A ) an m by k by batch_count strided_batched matrix,\nop( B ) an k by n by batch_count strided_batched matrix and\nC an m by n by batch_count strided_batched matrix.\n\n@param[in]\nhandle [rocblas_handle\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimention m.\n@param[in]\nn [rocblas_int]\nmatrix dimention n.\n@param[in]\nk [rocblas_int]\nmatrix dimention k.\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nB device array of device pointers storing each matrix B_i.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of each B_i.\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n@param[in, out]\nC device array of device pointers storing each matrix C_i.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of each C_i.\n@param[in]\nbatch_count\n[rocblas_int]\nnumber of gemm operations in the batch."] + pub fn rocblas_sgemm_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + B: *const *const f32, + ldb: rocblas_int, + beta: *const f32, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemm_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + B: *const *const f64, + ldb: rocblas_int, + beta: *const f64, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hgemm_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_half, + A: *const *const rocblas_half, + lda: rocblas_int, + B: *const *const rocblas_half, + ldb: rocblas_int, + beta: *const rocblas_half, + C: *const *mut rocblas_half, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemm_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + beta: *const rocblas_float_complex, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemm_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + beta: *const rocblas_double_complex, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngemm_strided_batched performs one of the strided batched matrix-matrix operations:\n\nC_i = alpha*op( A_i )*op( B_i ) + beta*C_i, for i = 1, ..., batch_count,\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B and C are strided batched matrices, with\nop( A ) an m by k by batch_count strided_batched matrix,\nop( B ) an k by n by batch_count strided_batched matrix and\nC an m by n by batch_count strided_batched matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimention m.\n@param[in]\nn [rocblas_int]\nmatrix dimention n.\n@param[in]\nk [rocblas_int]\nmatrix dimention k.\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n@param[in]\nA device pointer pointing to the first matrix A_1.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstride_a [rocblas_stride]\nstride from the start of one A_i matrix to the next A_(i + 1).\n@param[in]\nB device pointer pointing to the first matrix B_1.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of each B_i.\n@param[in]\nstride_b [rocblas_stride]\nstride from the start of one B_i matrix to the next B_(i + 1).\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n@param[in, out]\nC device pointer pointing to the first matrix C_1.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of each C_i.\n@param[in]\nstride_c [rocblas_stride]\nstride from the start of one C_i matrix to the next C_(i + 1).\n@param[in]\nbatch_count\n[rocblas_int]\nnumber of gemm operatons in the batch.\n"] + pub fn rocblas_sgemm_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemm_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hgemm_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_half, + A: *const rocblas_half, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const rocblas_half, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const rocblas_half, + C: *mut rocblas_half, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_hgemm_kernel_name( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_half, + A: *const rocblas_half, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const rocblas_half, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const rocblas_half, + C: *mut rocblas_half, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_sgemm_kernel_name( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const f32, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const f32, + C: *mut f32, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgemm_kernel_name( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const f64, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const f64, + C: *mut f64, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgemm_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgemm_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_a: rocblas_stride, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_c: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ndgmm performs one of the matrix-matrix operations:\n\nC = A * diag(x) if side == rocblas_side_right\nC = diag(x) * A if side == rocblas_side_left\n\nwhere C and A are m by n dimensional matrices. diag( x ) is a diagonal matrix\nand x is vector of dimension n if side == rocblas_side_right and dimension m\nif side == rocblas_side_left.\n\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nside [rocblas_side]\nspecifies the side of diag(x).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between values of x\n@param[in, out]\nC device pointer storing matrix C.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n"] + pub fn rocblas_sdgmm( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const f32, + lda: rocblas_int, + x: *const f32, + incx: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddgmm( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const f64, + lda: rocblas_int, + x: *const f64, + incx: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdgmm( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + x: *const rocblas_float_complex, + incx: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdgmm( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + x: *const rocblas_double_complex, + incx: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ndgmm_batched performs one of the batched matrix-matrix operations:\n\nC_i = A_i * diag(x_i) for i = 0, 1, ... batch_count-1 if side == rocblas_side_right\nC_i = diag(x_i) * A_i for i = 0, 1, ... batch_count-1 if side == rocblas_side_left,\n\nwhere C_i and A_i are m by n dimensional matrices. diag(x_i) is a diagonal matrix\nand x_i is vector of dimension n if side == rocblas_side_right and dimension m\nif side == rocblas_side_left.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nside [rocblas_side]\nspecifies the side of diag(x).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nA device array of device pointers storing each matrix A_i on the GPU.\nEach A_i is of dimension ( lda, n ).\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A_i.\n@param[in]\nx device array of device pointers storing each vector x_i on the GPU.\nEach x_i is of dimension n if side == rocblas_side_right and dimension\nm if side == rocblas_side_left.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between values of x_i.\n@param[in, out]\nC device array of device pointers storing each matrix C_i on the GPU.\nEach C_i is of dimension ( ldc, n ).\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n"] + pub fn rocblas_sdgmm_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const *const f32, + lda: rocblas_int, + x: *const *const f32, + incx: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddgmm_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const *const f64, + lda: rocblas_int, + x: *const *const f64, + incx: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdgmm_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + x: *const *const rocblas_float_complex, + incx: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdgmm_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + x: *const *const rocblas_double_complex, + incx: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ndgmm_strided_batched performs one of the batched matrix-matrix operations:\n\nC_i = A_i * diag(x_i) if side == rocblas_side_right for i = 0, 1, ... batch_count-1\nC_i = diag(x_i) * A_i if side == rocblas_side_left for i = 0, 1, ... batch_count-1,\n\nwhere C_i and A_i are m by n dimensional matrices. diag(x_i) is a diagonal matrix\nand x_i is vector of dimension n if side == rocblas_side_right and dimension m\nif side == rocblas_side_left.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nside [rocblas_side]\nspecifies the side of diag(x).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nA device pointer to the first matrix A_0 on the GPU.\nEach A_i is of dimension ( lda, n ).\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n@param[in]\nx pointer to the first vector x_0 on the GPU.\nEach x_i is of dimension n if side == rocblas_side_right and dimension\nm if side == rocblas_side_left.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between values of x.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector(x_i) and the next one (x_i+1).\n@param[in, out]\nC device pointer to the first matrix C_0 on the GPU.\nEach C_i is of dimension ( ldc, n ).\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n@param[in]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch.\n"] + pub fn rocblas_sdgmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const f32, + incx: rocblas_int, + stride_x: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_ddgmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const f64, + incx: rocblas_int, + stride_x: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cdgmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_float_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zdgmm_strided_batched( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + x: *const rocblas_double_complex, + incx: rocblas_int, + stride_x: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngeam performs one of the matrix-matrix operations:\n\nC = alpha*op( A ) + beta*op( B ),\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B and C are matrices, with\nop( A ) an m by n matrix, op( B ) an m by n matrix, and C an m by n matrix.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n@param[in]\nA device pointer storing matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n@param[in]\nB device pointer storing matrix B.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B.\n@param[in, out]\nC device pointer storing matrix C.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n"] + pub fn rocblas_sgeam( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + beta: *const f32, + B: *const f32, + ldb: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgeam( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + beta: *const f64, + B: *const f64, + ldb: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeam( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + beta: *const rocblas_float_complex, + B: *const rocblas_float_complex, + ldb: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeam( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + beta: *const rocblas_double_complex, + B: *const rocblas_double_complex, + ldb: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngeam_batched performs one of the batched matrix-matrix operations:\n\nC_i = alpha*op( A_i ) + beta*op( B_i ) for i = 0, 1, ... batch_count - 1,\n\nwhere alpha and beta are scalars, and op(A_i), op(B_i) and C_i are m by n matrices\nand op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n@param[in]\nA device array of device pointers storing each matrix A_i on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen transA == rocblas_operation_none and\nis n when transA == rocblas_operation_transpose.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n@param[in]\nB device array of device pointers storing each matrix B_i on the GPU.\nEach B_i is of dimension ( ldb, k ), where k is m\nwhen transB == rocblas_operation_none and\nis n when transB == rocblas_operation_transpose.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B.\n@param[in, out]\nC device array of device pointers storing each matrix C_i on the GPU.\nEach C_i is of dimension ( ldc, n ).\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch.\n"] + pub fn rocblas_sgeam_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const *const f32, + lda: rocblas_int, + beta: *const f32, + B: *const *const f32, + ldb: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgeam_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const *const f64, + lda: rocblas_int, + beta: *const f64, + B: *const *const f64, + ldb: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeam_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const *const rocblas_float_complex, + lda: rocblas_int, + beta: *const rocblas_float_complex, + B: *const *const rocblas_float_complex, + ldb: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeam_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const *const rocblas_double_complex, + lda: rocblas_int, + beta: *const rocblas_double_complex, + B: *const *const rocblas_double_complex, + ldb: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 3 API \n\n\\details\ngeam_strided_batched performs one of the batched matrix-matrix operations:\n\nC_i = alpha*op( A_i ) + beta*op( B_i ) for i = 0, 1, ... batch_count - 1,\n\nwhere alpha and beta are scalars, and op(A_i), op(B_i) and C_i are m by n matrices\nand op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n\n@param[in]\nalpha device pointer or host pointer specifying the scalar alpha.\n\n@param[in]\nA device pointer to the first matrix A_0 on the GPU.\nEach A_i is of dimension ( lda, k ), where k is m\nwhen transA == rocblas_operation_none and\nis n when transA == rocblas_operation_transpose.\n\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n\n@param[in]\nstride_A [rocblas_stride]\nstride from the start of one matrix (A_i) and the next one (A_i+1).\n\n@param[in]\nbeta device pointer or host pointer specifying the scalar beta.\n\n@param[in]\nB pointer to the first matrix B_0 on the GPU.\nEach B_i is of dimension ( ldb, k ), where k is m\nwhen transB == rocblas_operation_none and\nis n when transB == rocblas_operation_transpose.\n\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B.\n\n@param[in]\nstride_B [rocblas_stride]\nstride from the start of one matrix (B_i) and the next one (B_i+1)\n\n@param[in, out]\nC pointer to the first matrix C_0 on the GPU.\nEach C_i is of dimension ( ldc, n ).\n\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n\n@param[in]\nstride_C [rocblas_stride]\nstride from the start of one matrix (C_i) and the next one (C_i+1).\n\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances i in the batch.\n"] + pub fn rocblas_sgeam_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f32, + A: *const f32, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f32, + B: *const f32, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dgeam_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const f64, + A: *const f64, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const f64, + B: *const f64, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_cgeam_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_float_complex, + A: *const rocblas_float_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const rocblas_float_complex, + B: *const rocblas_float_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_zgeam_strided_batched( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + alpha: *const rocblas_double_complex, + A: *const rocblas_double_complex, + lda: rocblas_int, + stride_A: rocblas_stride, + beta: *const rocblas_double_complex, + B: *const rocblas_double_complex, + ldb: rocblas_int, + stride_B: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + stride_C: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ngemm_ex performs one of the matrix-matrix operations:\n\nD = alpha*op( A )*op( B ) + beta*C,\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B, C, and D are matrices, with\nop( A ) an m by k matrix, op( B ) a k by n matrix and C and D are m by n matrices.\nC and D may point to the same matrix if their parameters are identical.\n\nSupported types are as follows:\n- rocblas_datatype_f64_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f32_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_f16_r = a_type = b_type; rocblas_datatype_f32_r = c_type = d_type =\ncompute_type\n- rocblas_datatype_bf16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_bf16_r = a_type = b_type; rocblas_datatype_f32_r = c_type = d_type =\ncompute_type\n- rocblas_datatype_i8_r = a_type = b_type; rocblas_datatype_i32_r = c_type = d_type =\ncompute_type\n- rocblas_datatype_f32_c = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f64_c = a_type = b_type = c_type = d_type = compute_type\n\nTwo int8 datatypes are supported: int8_t and rocblas_int8x4. int8_t is the C99 signed\n8 bit integer. The default is int8_t and it is recommended int8_t be used. rocblas_int8x4\nis a packed datatype. The packed int 8 datatype occurs if the user sets:\n\n@code\nflags |= rocblas_gemm_flags_pack_int8x4;\n@endcode\n\nFor this packed int8 datatype matrices A and B are packed into int8x4 in the k dimension.\nThis will impose the following size restrictions on A or B:\n\n- k must be a multiple of 4\n- if transA == rocblas_operation_transpose then lda must be a multiple of 4\n- if transB == rocblas_operation_none then ldb must be a multiple of 4\n- if transA == rocblas_operation_none the matrix A must have each 4 consecutive\nvalues in the k dimension packed\n- if transB == rocblas_operation_transpose the matrix B must have each 4\nconsecutive values in the k dimension packed.\n\nThis packing can be achieved with the following pseudo-code. The code assumes the\noriginal matrices are in A and B, and the packed matrices are A_packed and B_packed.\nThe size of the A_packed and B_packed are the same as the size of the A and B respectively.\n\n@code\nif(transA == rocblas_operation_none)\n{\nint nb = 4;\nfor(int i_m = 0; i_m < m; i_m++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nA_packed[i_k % nb + (i_m + (i_k / nb) * lda) * nb] = A[i_m + i_k * lda];\n}\n}\n}\nelse\n{\nA_packed = A;\n}\nif(transB == rocblas_operation_transpose)\n{\nint nb = 4;\nfor(int i_n = 0; i_n < m; i_n++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nB_packed[i_k % nb + (i_n + (i_k / nb) * ldb) * nb] = B[i_n + i_k * ldb];\n}\n}\n}\nelse\n{\nB_packed = B;\n}\n@endcode\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nk [rocblas_int]\nmatrix dimension k.\n@param[in]\nalpha [const void *]\ndevice pointer or host pointer specifying the scalar alpha. Same datatype as compute_type.\n@param[in]\na [void *]\ndevice pointer storing matrix A.\n@param[in]\na_type [rocblas_datatype]\nspecifies the datatype of matrix A.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of A.\n@param[in]\nb [void *]\ndevice pointer storing matrix B.\n@param[in]\nb_type [rocblas_datatype]\nspecifies the datatype of matrix B.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of B.\n@param[in]\nbeta [const void *]\ndevice pointer or host pointer specifying the scalar beta. Same datatype as compute_type.\n@param[in]\nc [void *]\ndevice pointer storing matrix C.\n@param[in]\nc_type [rocblas_datatype]\nspecifies the datatype of matrix C.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of C.\n@param[out]\nd [void *]\ndevice pointer storing matrix D.\nIf d and c pointers are to the same matrix then d_type must equal c_type and ldd must equal ldc\nor the respective invalid status will be returned.\n@param[in]\nd_type [rocblas_datatype]\nspecifies the datatype of matrix D.\n@param[in]\nldd [rocblas_int]\nspecifies the leading dimension of D.\n@param[in]\ncompute_type\n[rocblas_datatype]\nspecifies the datatype of computation.\n@param[in]\nalgo [rocblas_gemm_algo]\nenumerant specifying the algorithm type.\n@param[in]\nsolution_index\n[int32_t]\nreserved for future use.\n@param[in]\nflags [uint32_t]\noptional gemm flags.\n"] + pub fn rocblas_gemm_ex( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const ::std::os::raw::c_void, + a: *const ::std::os::raw::c_void, + a_type: rocblas_datatype, + lda: rocblas_int, + b: *const ::std::os::raw::c_void, + b_type: rocblas_datatype, + ldb: rocblas_int, + beta: *const ::std::os::raw::c_void, + c: *const ::std::os::raw::c_void, + c_type: rocblas_datatype, + ldc: rocblas_int, + d: *mut ::std::os::raw::c_void, + d_type: rocblas_datatype, + ldd: rocblas_int, + compute_type: rocblas_datatype, + algo: rocblas_gemm_algo, + solution_index: i32, + flags: u32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ngemm_batched_ex performs one of the batched matrix-matrix operations:\nD_i = alpha*op(A_i)*op(B_i) + beta*C_i, for i = 1, ..., batch_count.\nwhere op( X ) is one of\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\nalpha and beta are scalars, and A, B, C, and D are batched pointers to matrices, with\nop( A ) an m by k by batch_count batched matrix,\nop( B ) a k by n by batch_count batched matrix and\nC and D are m by n by batch_count batched matrices.\nThe batched matrices are an array of pointers to matrices.\nThe number of pointers to matrices is batch_count.\nC and D may point to the same matrices if their parameters are identical.\n\nSupported types are as follows:\n- rocblas_datatype_f64_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f32_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_bf16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_i8_r = a_type = b_type; rocblas_datatype_i32_r = c_type = d_type =\ncompute_type\n- rocblas_datatype_f32_c = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f64_c = a_type = b_type = c_type = d_type = compute_type\n\nTwo int8 datatypes are supported: int8_t and rocblas_int8x4. int8_t is the C99 signed\n8 bit integer. The default is int8_t and it is recommended int8_t be used. rocblas_int8x4\nis a packed datatype. The packed int 8 datatype occurs if the user sets:\n\n@code\nflags |= rocblas_gemm_flags_pack_int8x4;\n@endcode\n\nFor this packed int8 datatype matrices A and B are packed into int8x4 in the k dimension.\nThis will impose the following size restrictions on A or B:\n\n- k must be a multiple of 4\n- if transA == rocblas_operation_transpose then lda must be a multiple of 4\n- if transB == rocblas_operation_none then ldb must be a multiple of 4\n- if transA == rocblas_operation_none the matrix A must have each 4 consecutive\nvalues in the k dimension packed\n- if transB == rocblas_operation_transpose the matrix B must have each 4\nconsecutive values in the k dimension packed.\n\nThis packing can be achieved with the following pseudo-code. The code assumes the\noriginal matrices are in A and B, and the packed matrices are A_packed and B_packed.\nThe size of the A_packed and B_packed are the same as the size of the A and B respectively.\n\n@code\nif(transA == rocblas_operation_none)\n{\nint nb = 4;\nfor(int i_m = 0; i_m < m; i_m++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nA_packed[i_k % nb + (i_m + (i_k / nb) * lda) * nb] = A[i_m + i_k * lda];\n}\n}\n}\nelse\n{\nA_packed = A;\n}\nif(transB == rocblas_operation_transpose)\n{\nint nb = 4;\nfor(int i_n = 0; i_n < m; i_n++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nB_packed[i_k % nb + (i_n + (i_k / nb) * ldb) * nb] = B[i_n + i_k * ldb];\n}\n}\n}\nelse\n{\nB_packed = B;\n}\n@endcode\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nk [rocblas_int]\nmatrix dimension k.\n@param[in]\nalpha [const void *]\ndevice pointer or host pointer specifying the scalar alpha. Same datatype as compute_type.\n@param[in]\na [void *]\ndevice pointer storing array of pointers to each matrix A_i.\n@param[in]\na_type [rocblas_datatype]\nspecifies the datatype of each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nb [void *]\ndevice pointer storing array of pointers to each matrix B_i.\n@param[in]\nb_type [rocblas_datatype]\nspecifies the datatype of each matrix B_i.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of each B_i.\n@param[in]\nbeta [const void *]\ndevice pointer or host pointer specifying the scalar beta. Same datatype as compute_type.\n@param[in]\nc [void *]\ndevice array of device pointers to each matrix C_i.\n@param[in]\nc_type [rocblas_datatype]\nspecifies the datatype of each matrix C_i.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of each C_i.\n@param[out]\nd [void *]\ndevice array of device pointers to each matrix D_i.\nIf d and c are the same array of matrix pointers then d_type must equal c_type and ldd must equal ldc\nor the respective invalid status will be returned.\n@param[in]\nd_type [rocblas_datatype]\nspecifies the datatype of each matrix D_i.\n@param[in]\nldd [rocblas_int]\nspecifies the leading dimension of each D_i.\n@param[in]\nbatch_count\n[rocblas_int]\nnumber of gemm operations in the batch.\n@param[in]\ncompute_type\n[rocblas_datatype]\nspecifies the datatype of computation.\n@param[in]\nalgo [rocblas_gemm_algo]\nenumerant specifying the algorithm type.\n@param[in]\nsolution_index\n[int32_t]\nreserved for future use.\n@param[in]\nflags [uint32_t]\noptional gemm flags.\n"] + pub fn rocblas_gemm_batched_ex( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const ::std::os::raw::c_void, + a: *const ::std::os::raw::c_void, + a_type: rocblas_datatype, + lda: rocblas_int, + b: *const ::std::os::raw::c_void, + b_type: rocblas_datatype, + ldb: rocblas_int, + beta: *const ::std::os::raw::c_void, + c: *const ::std::os::raw::c_void, + c_type: rocblas_datatype, + ldc: rocblas_int, + d: *mut ::std::os::raw::c_void, + d_type: rocblas_datatype, + ldd: rocblas_int, + batch_count: rocblas_int, + compute_type: rocblas_datatype, + algo: rocblas_gemm_algo, + solution_index: i32, + flags: u32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ngemm_strided_batched_ex performs one of the strided_batched matrix-matrix operations:\n\nD_i = alpha*op(A_i)*op(B_i) + beta*C_i, for i = 1, ..., batch_count\n\nwhere op( X ) is one of\n\nop( X ) = X or\nop( X ) = X**T or\nop( X ) = X**H,\n\nalpha and beta are scalars, and A, B, C, and D are strided_batched matrices, with\nop( A ) an m by k by batch_count strided_batched matrix,\nop( B ) a k by n by batch_count strided_batched matrix and\nC and D are m by n by batch_count strided_batched matrices.\nC and D may point to the same matrices if their parameters are identical.\n\nThe strided_batched matrices are multiple matrices separated by a constant stride.\nThe number of matrices is batch_count.\n\nSupported types are as follows:\n- rocblas_datatype_f64_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f32_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_bf16_r = a_type = b_type = c_type = d_type; rocblas_datatype_f32_r =\ncompute_type\n- rocblas_datatype_i8_r = a_type = b_type; rocblas_datatype_i32_r = c_type = d_type =\ncompute_type\n- rocblas_datatype_f32_c = a_type = b_type = c_type = d_type = compute_type\n- rocblas_datatype_f64_c = a_type = b_type = c_type = d_type = compute_type\n\nTwo int8 datatypes are supported: int8_t and rocblas_int8x4. int8_t is the C99 signed\n8 bit integer. The default is int8_t and it is recommended int8_t be used. rocblas_int8x4\nis a packed datatype. The packed int 8 datatype occurs if the user sets:\n\n@code\nflags |= rocblas_gemm_flags_pack_int8x4;\n@endcode\n\nFor this packed int8 datatype matrices A and B are packed into int8x4 in the k dimension.\nThis will impose the following size restrictions on A or B:\n\n- k must be a multiple of 4\n- if transA == rocblas_operation_transpose then lda must be a multiple of 4\n- if transB == rocblas_operation_none then ldb must be a multiple of 4\n- if transA == rocblas_operation_none the matrix A must have each 4 consecutive\nvalues in the k dimension packed\n- if transB == rocblas_operation_transpose the matrix B must have each 4\nconsecutive values in the k dimension packed.\n\nThis packing can be achieved with the following pseudo-code. The code assumes the\noriginal matrices are in A and B, and the packed matrices are A_packed and B_packed.\nThe size of the A_packed and B_packed are the same as the size of the A and B respectively.\n\n@code\nif(transA == rocblas_operation_none)\n{\nint nb = 4;\nfor(int i_m = 0; i_m < m; i_m++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nA_packed[i_k % nb + (i_m + (i_k / nb) * lda) * nb] = A[i_m + i_k * lda];\n}\n}\n}\nelse\n{\nA_packed = A;\n}\nif(transB == rocblas_operation_transpose)\n{\nint nb = 4;\nfor(int i_n = 0; i_n < m; i_n++)\n{\nfor(int i_k = 0; i_k < k; i_k++)\n{\nB_packed[i_k % nb + (i_n + (i_k / nb) * ldb) * nb] = B[i_n + i_k * ldb];\n}\n}\n}\nelse\n{\nB_packed = B;\n}\n@endcode\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\ntransA [rocblas_operation]\nspecifies the form of op( A ).\n@param[in]\ntransB [rocblas_operation]\nspecifies the form of op( B ).\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nk [rocblas_int]\nmatrix dimension k.\n@param[in]\nalpha [const void *]\ndevice pointer or host pointer specifying the scalar alpha. Same datatype as compute_type.\n@param[in]\na [void *]\ndevice pointer pointing to first matrix A_1.\n@param[in]\na_type [rocblas_datatype]\nspecifies the datatype of each matrix A_i.\n@param[in]\nlda [rocblas_int]\nspecifies the leading dimension of each A_i.\n@param[in]\nstride_a [rocblas_stride]\nspecifies stride from start of one A_i matrix to the next A_(i + 1).\n@param[in]\nb [void *]\ndevice pointer pointing to first matrix B_1.\n@param[in]\nb_type [rocblas_datatype]\nspecifies the datatype of each matrix B_i.\n@param[in]\nldb [rocblas_int]\nspecifies the leading dimension of each B_i.\n@param[in]\nstride_b [rocblas_stride]\nspecifies stride from start of one B_i matrix to the next B_(i + 1).\n@param[in]\nbeta [const void *]\ndevice pointer or host pointer specifying the scalar beta. Same datatype as compute_type.\n@param[in]\nc [void *]\ndevice pointer pointing to first matrix C_1.\n@param[in]\nc_type [rocblas_datatype]\nspecifies the datatype of each matrix C_i.\n@param[in]\nldc [rocblas_int]\nspecifies the leading dimension of each C_i.\n@param[in]\nstride_c [rocblas_stride]\nspecifies stride from start of one C_i matrix to the next C_(i + 1).\n@param[out]\nd [void *]\ndevice pointer storing each matrix D_i.\nIf d and c pointers are to the same matrix then d_type must equal c_type and ldd must equal ldc\nand stride_d must equal stride_c or the respective invalid status will be returned.\n@param[in]\nd_type [rocblas_datatype]\nspecifies the datatype of each matrix D_i.\n@param[in]\nldd [rocblas_int]\nspecifies the leading dimension of each D_i.\n@param[in]\nstride_d [rocblas_stride]\nspecifies stride from start of one D_i matrix to the next D_(i + 1).\n@param[in]\nbatch_count\n[rocblas_int]\nnumber of gemm operations in the batch.\n@param[in]\ncompute_type\n[rocblas_datatype]\nspecifies the datatype of computation.\n@param[in]\nalgo [rocblas_gemm_algo]\nenumerant specifying the algorithm type.\n@param[in]\nsolution_index\n[int32_t]\nreserved for future use.\n@param[in]\nflags [uint32_t]\noptional gemm flags.\n"] + pub fn rocblas_gemm_strided_batched_ex( + handle: rocblas_handle, + transA: rocblas_operation, + transB: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const ::std::os::raw::c_void, + a: *const ::std::os::raw::c_void, + a_type: rocblas_datatype, + lda: rocblas_int, + stride_a: rocblas_stride, + b: *const ::std::os::raw::c_void, + b_type: rocblas_datatype, + ldb: rocblas_int, + stride_b: rocblas_stride, + beta: *const ::std::os::raw::c_void, + c: *const ::std::os::raw::c_void, + c_type: rocblas_datatype, + ldc: rocblas_int, + stride_c: rocblas_stride, + d: *mut ::std::os::raw::c_void, + d_type: rocblas_datatype, + ldd: rocblas_int, + stride_d: rocblas_stride, + batch_count: rocblas_int, + compute_type: rocblas_datatype, + algo: rocblas_gemm_algo, + solution_index: i32, + flags: u32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ngemm_ext2 performs the matrix-matrix operations:\n\nD = alpha * A * B + beta * C,\n\nalpha and beta are scalars, and A, B, C, and D are matrices, with A a m by k\nmatrtix, B a k by n matrix, and C and D are m by n matrices. Each matrix A, B, C, D\nhas independent row and column strides.\n\nThis is a beta feature.\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nm [rocblas_int]\nmatrix dimension m.\n@param[in]\nn [rocblas_int]\nmatrix dimension n.\n@param[in]\nk [rocblas_int]\nmatrix dimension k.\n@param[in]\nalpha [const void *]\ndevice pointer or host pointer specifying the scalar alpha. Same datatype as compute_type.\n@param[in]\na [void *]\ndevice pointer storing matrix A.\n@param[in]\na_type [rocblas_datatype]\nspecifies the datatype of matrix A.\n@param[in]\nrow_stride_a [rocblas_int]\nspecifies the row stride of A.\n@param[in]\ncol_stride_a [rocblas_int]\nspecifies the column stride of A.\n@param[in]\nb [void *]\ndevice pointer storing matrix B.\n@param[in]\nb_type [rocblas_datatype]\nspecifies the datatype of matrix B.\n@param[in]\nrow_stride_b [rocblas_int]\nspecifies the row stride of B.\n@param[in]\ncol_stride_b [rocblas_int]\nspecifies the column stride of B.\n@param[in]\nbeta [const void *]\ndevice pointer or host pointer specifying the scalar beta. Same datatype as compute_type.\n@param[in]\nc [void *]\ndevice pointer storing matrix C.\n@param[in]\nc_type [rocblas_datatype]\nspecifies the datatype of matrix C.\n@param[in]\nrow_stride_c [rocblas_int]\nspecifies the row stride of C.\n@param[in]\ncol_stride_c [rocblas_int]\nspecifies the column stride of C.\n@param[out]\nd [void *]\ndevice pointer storing matrix D.\n@param[in]\nd_type [rocblas_datatype]\nspecifies the datatype of matrix D.\n@param[in]\nrow_stride_d [rocblas_int]\nspecifies the row stride of D.\n@param[in]\ncol_stride_d [rocblas_int]\nspecifies the column stride of D.\n@param[in]\ncompute_type\n[rocblas_datatype]\nspecifies the datatype of computation.\n@param[in]\nalgo [rocblas_gemm_algo]\nenumerant specifying the algorithm type.\n@param[in]\nsolution_index\n[int32_t]\nreserved for future use.\n@param[in]\nflags [uint32_t]\noptional gemm flags.\n"] + pub fn rocblas_gemm_ext2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + alpha: *const ::std::os::raw::c_void, + a: *const ::std::os::raw::c_void, + a_type: rocblas_datatype, + row_stride_a: rocblas_stride, + col_stride_a: rocblas_stride, + b: *const ::std::os::raw::c_void, + b_type: rocblas_datatype, + row_stride_b: rocblas_stride, + col_stride_b: rocblas_stride, + beta: *const ::std::os::raw::c_void, + c: *const ::std::os::raw::c_void, + c_type: rocblas_datatype, + row_stride_c: rocblas_stride, + col_stride_c: rocblas_stride, + d: *mut ::std::os::raw::c_void, + d_type: rocblas_datatype, + row_stride_d: rocblas_stride, + col_stride_d: rocblas_stride, + compute_type: rocblas_datatype, + algo: rocblas_gemm_algo, + solution_index: i32, + flags: u32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ntrsm_ex solves:\n\nop(A)*X = alpha*B or X*op(A) = alpha*B,\n\nwhere alpha is a scalar, X and B are m by n matrices,\nA is triangular matrix and op(A) is one of\n\nop( A ) = A or op( A ) = A^T or op( A ) = A^H.\n\nThe matrix X is overwritten on B.\n\nThis function gives the user the ability to reuse the invA matrix between runs.\nIf invA == NULL, rocblas_trsm_ex will automatically calculate invA on every run.\n\nSetting up invA:\nThe accepted invA matrix consists of the packed 128x128 inverses of the diagonal blocks of\nmatrix A, followed by any smaller diagonal block that remains.\nTo set up invA it is recommended that rocblas_trtri_batched be used with matrix A as the input.\n\nDevice memory of size 128 x k should be allocated for invA ahead of time, where k is m when\nrocblas_side_left and is n when rocblas_side_right. The actual number of elements in invA\nshould be passed as invA_size.\n\nTo begin, rocblas_trtri_batched must be called on the full 128x128-sized diagonal blocks of\nmatrix A. Below are the restricted parameters:\n- n = 128\n- ldinvA = 128\n- stride_invA = 128x128\n- batch_count = k / 128,\n\nThen any remaining block may be added:\n- n = k % 128\n- invA = invA + stride_invA * previous_batch_count\n- ldinvA = 128\n- batch_count = 1\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B\n- rocblas_side_right: X*op(A) = alpha*B\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: A is an upper triangular matrix.\n- rocblas_fill_lower: A is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A.\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: A is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: A is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of B. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of B. n >= 0.\n\n@param[in]\nalpha [void *]\ndevice pointer or host pointer specifying the scalar alpha. When alpha is\n&zero then A is not referenced, and B need not be set before\nentry.\n\n@param[in]\nA [void *]\ndevice pointer storing matrix A.\nof dimension ( lda, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\nif side = rocblas_side_right, lda >= max( 1, n ).\n\n@param[in, out]\nB [void *]\ndevice pointer storing matrix B.\nB is of dimension ( ldb, n ).\nBefore entry, the leading m by n part of the array B must\ncontain the right-hand side matrix B, and on exit is\noverwritten by the solution matrix X.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of B. ldb >= max( 1, m ).\n\n@param[in]\ninvA [void *]\ndevice pointer storing the inverse diagonal blocks of A.\ninvA is of dimension ( ld_invA, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right.\nld_invA must be equal to 128.\n\n@param[in]\ninvA_size [rocblas_int]\ninvA_size specifies the number of elements of device memory in invA.\n\n@param[in]\ncompute_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_trsm_ex( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + lda: rocblas_int, + B: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + invA: *const ::std::os::raw::c_void, + invA_size: rocblas_int, + compute_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ntrsm_batched_ex solves:\n\nop(A_i)*X_i = alpha*B_i or X_i*op(A_i) = alpha*B_i,\n\nfor i = 1, ..., batch_count; and where alpha is a scalar, X and B are arrays of m by n matrices,\nA is an array of triangular matrix and each op(A_i) is one of\n\nop( A_i ) = A_i or op( A_i ) = A_i^T or op( A_i ) = A_i^H.\n\nEach matrix X_i is overwritten on B_i.\n\nThis function gives the user the ability to reuse the invA matrix between runs.\nIf invA == NULL, rocblas_trsm_batched_ex will automatically calculate each invA_i on every run.\n\nSetting up invA:\nEach accepted invA_i matrix consists of the packed 128x128 inverses of the diagonal blocks of\nmatrix A_i, followed by any smaller diagonal block that remains.\nTo set up each invA_i it is recommended that rocblas_trtri_batched be used with matrix A_i as the input.\ninvA is an array of pointers of batch_count length holding each invA_i.\n\nDevice memory of size 128 x k should be allocated for each invA_i ahead of time, where k is m when\nrocblas_side_left and is n when rocblas_side_right. The actual number of elements in each invA_i\nshould be passed as invA_size.\n\nTo begin, rocblas_trtri_batched must be called on the full 128x128-sized diagonal blocks of each\nmatrix A_i. Below are the restricted parameters:\n- n = 128\n- ldinvA = 128\n- stride_invA = 128x128\n- batch_count = k / 128,\n\nThen any remaining block may be added:\n- n = k % 128\n- invA = invA + stride_invA * previous_batch_count\n- ldinvA = 128\n- batch_count = 1\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B\n- rocblas_side_right: X*op(A) = alpha*B\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A.\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of each B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of each B_i. n >= 0.\n\n@param[in]\nalpha [void *]\ndevice pointer or host pointer alpha specifying the scalar alpha. When alpha is\n&zero then A is not referenced, and B need not be set before\nentry.\n\n@param[in]\nA [void *]\ndevice array of device pointers storing each matrix A_i.\neach A_i is of dimension ( lda, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of each A_i.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\nif side = rocblas_side_right, lda >= max( 1, n ).\n\n@param[in, out]\nB [void *]\ndevice array of device pointers storing each matrix B_i.\neach B_i is of dimension ( ldb, n ).\nBefore entry, the leading m by n part of the array B_i must\ncontain the right-hand side matrix B_i, and on exit is\noverwritten by the solution matrix X_i\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of each B_i. ldb >= max( 1, m ).\n\n@param[in]\nbatch_count [rocblas_int]\nspecifies how many batches.\n\n@param[in]\ninvA [void *]\ndevice array of device pointers storing the inverse diagonal blocks of each A_i.\neach invA_i is of dimension ( ld_invA, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right.\nld_invA must be equal to 128.\n\n@param[in]\ninvA_size [rocblas_int]\ninvA_size specifies the number of elements of device memory in each invA_i.\n\n@param[in]\ncompute_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_trsm_batched_ex( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + lda: rocblas_int, + B: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + batch_count: rocblas_int, + invA: *const ::std::os::raw::c_void, + invA_size: rocblas_int, + compute_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ntrsm_strided_batched_ex solves:\n\nop(A_i)*X_i = alpha*B_i or X_i*op(A_i) = alpha*B_i,\n\nfor i = 1, ..., batch_count; and where alpha is a scalar, X and B are strided batched m by n matrices,\nA is a strided batched triangular matrix and op(A_i) is one of\n\nop( A_i ) = A_i or op( A_i ) = A_i^T or op( A_i ) = A_i^H.\n\nEach matrix X_i is overwritten on B_i.\n\nThis function gives the user the ability to reuse each invA_i matrix between runs.\nIf invA == NULL, rocblas_trsm_batched_ex will automatically calculate each invA_i on every run.\n\nSetting up invA:\nEach accepted invA_i matrix consists of the packed 128x128 inverses of the diagonal blocks of\nmatrix A_i, followed by any smaller diagonal block that remains.\nTo set up invA_i it is recommended that rocblas_trtri_batched be used with matrix A_i as the input.\ninvA is a contiguous piece of memory holding each invA_i.\n\nDevice memory of size 128 x k should be allocated for each invA_i ahead of time, where k is m when\nrocblas_side_left and is n when rocblas_side_right. The actual number of elements in each invA_i\nshould be passed as invA_size.\n\nTo begin, rocblas_trtri_batched must be called on the full 128x128-sized diagonal blocks of each\nmatrix A_i. Below are the restricted parameters:\n- n = 128\n- ldinvA = 128\n- stride_invA = 128x128\n- batch_count = k / 128\n\nThen any remaining block may be added:\n- n = k % 128\n- invA = invA + stride_invA * previous_batch_count\n- ldinvA = 128\n- batch_count = 1\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n\n@param[in]\nside [rocblas_side]\n- rocblas_side_left: op(A)*X = alpha*B\n- rocblas_side_right: X*op(A) = alpha*B\n\n@param[in]\nuplo [rocblas_fill]\n- rocblas_fill_upper: each A_i is an upper triangular matrix.\n- rocblas_fill_lower: each A_i is a lower triangular matrix.\n\n@param[in]\ntransA [rocblas_operation]\n- transB: op(A) = A.\n- rocblas_operation_transpose: op(A) = A^T\n- rocblas_operation_conjugate_transpose: op(A) = A^H\n\n@param[in]\ndiag [rocblas_diagonal]\n- rocblas_diagonal_unit: each A_i is assumed to be unit triangular.\n- rocblas_diagonal_non_unit: each A_i is not assumed to be unit triangular.\n\n@param[in]\nm [rocblas_int]\nm specifies the number of rows of each B_i. m >= 0.\n\n@param[in]\nn [rocblas_int]\nn specifies the number of columns of each B_i. n >= 0.\n\n@param[in]\nalpha [void *]\ndevice pointer or host pointer specifying the scalar alpha. When alpha is\n&zero then A is not referenced, and B need not be set before\nentry.\n\n@param[in]\nA [void *]\ndevice pointer storing matrix A.\nof dimension ( lda, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right\nonly the upper/lower triangular part is accessed.\n\n@param[in]\nlda [rocblas_int]\nlda specifies the first dimension of A.\n\nif side = rocblas_side_left, lda >= max( 1, m ),\nif side = rocblas_side_right, lda >= max( 1, n ).\n\n@param[in]\nstride_A [rocblas_stride]\nThe stride between each A matrix.\n\n@param[in, out]\nB [void *]\ndevice pointer pointing to first matrix B_i.\neach B_i is of dimension ( ldb, n ).\nBefore entry, the leading m by n part of each array B_i must\ncontain the right-hand side of matrix B_i, and on exit is\noverwritten by the solution matrix X_i.\n\n@param[in]\nldb [rocblas_int]\nldb specifies the first dimension of each B_i. ldb >= max( 1, m ).\n\n@param[in]\nstride_B [rocblas_stride]\nThe stride between each B_i matrix.\n\n@param[in]\nbatch_count [rocblas_int]\nspecifies how many batches.\n\n@param[in]\ninvA [void *]\ndevice pointer storing the inverse diagonal blocks of each A_i.\ninvA points to the first invA_1.\neach invA_i is of dimension ( ld_invA, k ), where k is m\nwhen rocblas_side_left and\nis n when rocblas_side_right.\nld_invA must be equal to 128.\n\n@param[in]\ninvA_size [rocblas_int]\ninvA_size specifies the number of elements of device memory in each invA_i.\n\n@param[in]\nstride_invA [rocblas_stride]\nThe stride between each invA matrix.\n\n@param[in]\ncompute_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_trsm_strided_batched_ex( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + transA: rocblas_operation, + diag: rocblas_diagonal, + m: rocblas_int, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + lda: rocblas_int, + stride_A: rocblas_stride, + B: *mut ::std::os::raw::c_void, + ldb: rocblas_int, + stride_B: rocblas_stride, + batch_count: rocblas_int, + invA: *const ::std::os::raw::c_void, + invA_size: rocblas_int, + stride_invA: rocblas_stride, + compute_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\naxpy_ex computes constant alpha multiplied by vector x, plus vector y.\n\ny := alpha * x + y\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------------------\n| alpha_type | x_type | y_type | execution_type |\n|------------|--------|--------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n-------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[in]\nalpha device pointer or host pointer to specify the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_axpy_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\naxpy_batched_ex computes constant alpha multiplied by vector x, plus vector y over\na set of batched vectors.\n\ny := alpha * x + y\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------------------\n| alpha_type | x_type | y_type | execution_type |\n|------------|--------|--------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n-------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nalpha device pointer or host pointer to specify the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_axpy_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\naxpy_strided_batched_ex computes constant alpha multiplied by vector x, plus vector y over\na set of strided batched vectors.\n\ny := alpha * x + y\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------------------\n| alpha_type | x_type | y_type | execution_type |\n|------------|--------|--------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n-------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nalpha device pointer or host pointer to specify the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) to the next one (x_i+1).\nThere are no restrictions placed on stridex. However, ensure that stridex is of appropriate size. For a typical\ncase this means stridex >= n * incx.\n@param[inout]\ny device pointer to the first vector y_1.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstridey [rocblas_stride]\nstride from the start of one vector (y_i) to the next one (y_i+1).\nThere are no restrictions placed on stridey. However, ensure that stridey is of appropriate size. For a typical\ncase this means stridey >= n * incy.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_axpy_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stridex: rocblas_stride, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + stridey: rocblas_stride, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ndot_ex performs the dot product of vectors x and y.\n\nresult = x * y;\n\ndotc_ex performs the dot product of the conjugate of complex vector x and complex vector y\n\nresult = conjugate (x) * y;\n\nCurrently supported datatypes are as follows:\n\n--------------------------------------------------\n| x_type | y_type | result_type | execution_type |\n|--------|--------|-------------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n--------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x and y.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[in]\ny device pointer storing vector y.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresult\ndevice pointer or host pointer to store the dot product.\nreturn is 0.0 if n <= 0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_dot_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dotc_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ndot_batched_ex performs a batch of dot products of vectors x and y.\n\nresult_i = x_i * y_i;\n\ndotc_batched_ex performs a batch of dot products of the conjugate of complex vector x and complex vector y\n\nresult_i = conjugate (x_i) * y_i;\n\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors, for i = 1, ..., batch_count\n\nCurrently supported datatypes are as follows:\n\n--------------------------------------------------\n| x_type | y_type | result_type | execution_type |\n|--------|--------|-------------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n--------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\ny device array of device pointers storing each vector y_i.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[inout]\nresult\ndevice array or host array of batch_count size to store the dot products of each batch.\nreturn 0.0 for each element if n <= 0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_dot_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dotc_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + batch_count: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\ndot_strided_batched_ex performs a batch of dot products of vectors x and y.\n\nresult_i = x_i * y_i;\n\ndotc_strided_batched_ex performs a batch of dot products of the conjugate of complex vector x and complex vector y\n\nresult_i = conjugate (x_i) * y_i;\n\nwhere (x_i, y_i) is the i-th instance of the batch.\nx_i and y_i are vectors, for i = 1, ..., batch_count\n\nCurrently supported datatypes are as follows:\n\n--------------------------------------------------\n| x_type | y_type | result_type | execution_type |\n|--------|--------|-------------|----------------|\n| f16_r | f16_r | f16_r | f16_r |\n| f16_r | f16_r | f16_r | f32_r |\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n--------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in each x_i and y_i.\n@param[in]\nx device pointer to the first vector (x_1) in the batch.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1)\n@param[in]\ny device pointer to the first vector (y_1) in the batch.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment for the elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nstride from the start of one vector (y_i) and the next one (y_i+1)\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[inout]\nresult\ndevice array or host array of batch_count size to store the dot products of each batch.\nreturn 0.0 for each element if n <= 0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_dot_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_dotc_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *const ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + stride_y: rocblas_stride, + batch_count: rocblas_int, + result: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS_EX API\n\n\\details\nnrm2_ex computes the euclidean norm of a real or complex vector.\n\nresult := sqrt( x'*x ) for real vectors\nresult := sqrt( x**H*x ) for complex vectors\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------\n| x_type | result | execution_type |\n|---------|--------|----------------|\n| f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_r | f32_r |\n| f64_c | f64_r | f64_r |\n-------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nx device pointer storing vector x.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of the vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of y.\n@param[inout]\nresults\ndevice pointer or host pointer to store the nrm2 product.\nreturn is 0.0 if n, incx<=0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation."] + pub fn rocblas_nrm2_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + results: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS_EX API\n\n\\details\nnrm2_batched_ex computes the euclidean norm over a batch of real or complex vectors.\n\nresult := sqrt( x_i'*x_i ) for real vectors x, for i = 1, ..., batch_count\nresult := sqrt( x_i**H*x_i ) for complex vectors x, for i = 1, ..., batch_count\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------\n| x_type | result | execution_type |\n|---------|--------|----------------|\n| f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_r | f32_r |\n| f64_c | f64_r | f64_r |\n-------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i.\n@param[in]\nx device array of device pointers storing each vector x_i.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresults\ndevice pointer or host pointer to array of batch_count size for nrm2 results.\nreturn is 0.0 for each element if n <= 0, incx<=0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_nrm2_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + batch_count: rocblas_int, + results: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS_EX API\n\n\\details\nnrm2_strided_batched_ex computes the euclidean norm over a batch of real or complex vectors.\n\nresult := sqrt( x_i'*x_i ) for real vectors x, for i = 1, ..., batch_count\nresult := sqrt( x_i**H*x_i ) for complex vectors, for i = 1, ..., batch_count\n\nCurrently supported datatypes are as follows:\n\n-------------------------------------\n| x_type | result | execution_type |\n|---------|--------|----------------|\n| f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_r | f32_r |\n| f64_c | f64_r | f64_r |\n-------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i.\n@param[in]\nx device pointer to the first vector x_1.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i. incx must be > 0.\n@param[in]\nstride_x [rocblas_stride]\nstride from the start of one vector (x_i) and the next one (x_i+1).\nThere are no restrictions placed on stride_x. However, ensure that stride_x is of appropriate size. For a typical\ncase this means stride_x >= n * incx.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[out]\nresults\ndevice pointer or host pointer to array for storing contiguous batch_count results.\nreturn is 0.0 for each element if n <= 0, incx<=0.\n@param[in]\nresult_type [rocblas_datatype]\nspecifies the datatype of the result.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_nrm2_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *const ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stride_x: rocblas_stride, + batch_count: rocblas_int, + results: *mut ::std::os::raw::c_void, + result_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\nrot_ex applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to vectors x and y.\nScalars c and s may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode.\n\nIn the case where cs_type is real:\n\nx := c * x + s * y\ny := c * y - s * x\n\nIn the case where cs_type is complex, the imaginary part of c is ignored:\n\nx := real(c) * x + s * y\ny := real(c) * y - conj(s) * x\n\nCurrently supported datatypes are as follows:\n\n------------------------------------------------\n| x_type | y_type | cs_type | execution_type |\n|---------|---------|---------|----------------|\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f32_c | f32_c | f32_r | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n| f64_c | f64_c | f64_r | f64_c |\n------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in the x and y vectors.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of x.\n@param[inout]\ny device pointer storing vector y.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of vector y.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of y.\n@param[in]\nc device pointer or host pointer storing scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer storing scalar sine component of the rotation matrix.\n@param[in]\ncs_type [rocblas_datatype]\nspecifies the datatype of c and s.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_rot_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + c: *const ::std::os::raw::c_void, + s: *const ::std::os::raw::c_void, + cs_type: rocblas_datatype, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\nrot_batched_ex applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to batched vectors x_i and y_i, for i = 1, ..., batch_count.\nScalars c and s may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode.\n\nIn the case where cs_type is real:\n\nx := c * x + s * y\ny := c * y - s * x\n\nIn the case where cs_type is complex, the imaginary part of c is ignored:\n\nx := real(c) * x + s * y\ny := real(c) * y - conj(s) * x\n\nCurrently supported datatypes are as follows:\n\n------------------------------------------------\n| x_type | y_type | cs_type | execution_type |\n|---------|---------|---------|----------------|\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f32_c | f32_c | f32_r | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n| f64_c | f64_c | f64_r | f64_c |\n------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i and y_i vectors.\n@param[inout]\nx device array of deivce pointers storing each vector x_i.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[inout]\ny device array of device pointers storing each vector y_i.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nc device pointer or host pointer to scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer to scalar sine component of the rotation matrix.\n@param[in]\ncs_type [rocblas_datatype]\nspecifies the datatype of c and s.\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, the number of batches.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_rot_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + c: *const ::std::os::raw::c_void, + s: *const ::std::os::raw::c_void, + cs_type: rocblas_datatype, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS Level 1 API \n\n\\details\nrot_strided_batched_ex applies the Givens rotation matrix defined by c=cos(alpha) and s=sin(alpha) to strided batched vectors x_i and y_i, for i = 1, ..., batch_count.\nScalars c and s may be stored in either host or device memory. Location is specified by calling rocblas_set_pointer_mode.\n\nIn the case where cs_type is real:\n\nx := c * x + s * y\ny := c * y - s * x\n\nIn the case where cs_type is complex, the imaginary part of c is ignored:\n\nx := real(c) * x + s * y\ny := real(c) * y - conj(s) * x\n\nCurrently supported datatypes are as follows:\n\n------------------------------------------------\n| x_type | y_type | cs_type | execution_type |\n|---------|---------|---------|----------------|\n| bf16_r | bf16_r | bf16_r | f32_r |\n| f16_r | f16_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c | f32_c |\n| f32_c | f32_c | f32_r | f32_c |\n| f64_c | f64_c | f64_c | f64_c |\n| f64_c | f64_c | f64_r | f64_c |\n------------------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nnumber of elements in each x_i and y_i vectors.\n@param[inout]\nx device pointer to the first vector x_1.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment between elements of each x_i.\n@param[in]\nstride_x [rocblas_stride]\nspecifies the increment from the beginning of x_i to the beginning of x_(i+1)\n@param[inout]\ny device pointer to the first vector y_1.\n@param[in]\ny_type [rocblas_datatype]\nspecifies the datatype of each vector y_i.\n@param[in]\nincy [rocblas_int]\nspecifies the increment between elements of each y_i.\n@param[in]\nstride_y [rocblas_stride]\nspecifies the increment from the beginning of y_i to the beginning of y_(i+1)\n@param[in]\nc device pointer or host pointer to scalar cosine component of the rotation matrix.\n@param[in]\ns device pointer or host pointer to scalar sine component of the rotation matrix.\n@param[in]\ncs_type [rocblas_datatype]\nspecifies the datatype of c and s.\n@param[in]\nbatch_count [rocblas_int]\nthe number of x and y arrays, the number of batches.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_rot_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stride_x: rocblas_stride, + y: *mut ::std::os::raw::c_void, + y_type: rocblas_datatype, + incy: rocblas_int, + stride_y: rocblas_stride, + c: *const ::std::os::raw::c_void, + s: *const ::std::os::raw::c_void, + cs_type: rocblas_datatype, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\nscal_ex scales each element of vector x with scalar alpha.\n\nx := alpha * x\n\nCurrently supported datatypes are as follows:\n\n----------------------------------------\n| alpha_type | x_type | execution_type |\n|------------|--------|----------------|\n| f16_r | f16_r | f16_r |\n| f16_r | f16_r | f32_r |\n| f32_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c |\n| f32_r | f32_c | f32_c |\n| f64_r | f64_c | f64_c |\n----------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nalpha device pointer or host pointer for the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[inout]\nx device pointer storing vector x.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of vector x.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of x.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_scal_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\nscal_batched_ex scales each element of each vector x_i with scalar alpha.\n\nx_i := alpha * x_i\n\nCurrently supported datatypes are as follows:\n\n----------------------------------------\n| alpha_type | x_type | execution_type |\n|------------|--------|----------------|\n| f16_r | f16_r | f16_r |\n| f16_r | f16_r | f32_r |\n| f32_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c |\n| f32_r | f32_c | f32_c |\n| f64_r | f64_c | f64_c |\n----------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nalpha device pointer or host pointer for the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[inout]\nx device array of device pointers storing each vector x_i.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_scal_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BLAS EX API \n\n\\details\nscal_strided_batched_ex scales each element of vector x with scalar alpha over a set\nof strided batched vectors.\n\nx := alpha * x\n\nCurrently supported datatypes are as follows:\n\n----------------------------------------\n| alpha_type | x_type | execution_type |\n|------------|--------|----------------|\n| f16_r | f16_r | f16_r |\n| f16_r | f16_r | f32_r |\n| f32_r | f16_r | f32_r |\n| f32_r | f32_r | f32_r |\n| f64_r | f64_r | f64_r |\n| f32_c | f32_c | f32_c |\n| f64_c | f64_c | f64_c |\n| f32_r | f32_c | f32_c |\n| f64_r | f64_c | f64_c |\n----------------------------------------\n\n@param[in]\nhandle [rocblas_handle]\nhandle to the rocblas library context queue.\n@param[in]\nn [rocblas_int]\nthe number of elements in x.\n@param[in]\nalpha device pointer or host pointer for the scalar alpha.\n@param[in]\nalpha_type [rocblas_datatype]\nspecifies the datatype of alpha.\n@param[inout]\nx device pointer to the first vector x_1.\n@param[in]\nx_type [rocblas_datatype]\nspecifies the datatype of each vector x_i.\n@param[in]\nincx [rocblas_int]\nspecifies the increment for the elements of each x_i.\n@param[in]\nstridex [rocblas_stride]\nstride from the start of one vector (x_i) to the next one (x_i+1).\nThere are no restrictions placed on stridex. However, ensure that stridex is of appropriate size. For a typical\ncase this means stridex >= n * incx.\n@param[in]\nbatch_count [rocblas_int]\nnumber of instances in the batch.\n@param[in]\nexecution_type [rocblas_datatype]\nspecifies the datatype of computation.\n"] + pub fn rocblas_scal_strided_batched_ex( + handle: rocblas_handle, + n: rocblas_int, + alpha: *const ::std::os::raw::c_void, + alpha_type: rocblas_datatype, + x: *mut ::std::os::raw::c_void, + x_type: rocblas_datatype, + incx: rocblas_int, + stridex: rocblas_stride, + batch_count: rocblas_int, + execution_type: rocblas_datatype, + ) -> rocblas_status; +} +extern "C" { + #[doc = " BLAS Auxiliary API\n\n\\details\nrocblas_status_to_string\n\nReturns string representing rocblas_status value\n\n@param[in]\nstatus [rocblas_status]\nrocBLAS status to convert to string"] + pub fn rocblas_status_to_string(status: rocblas_status) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " \\brief Initialize rocBLAS on the current HIP device, to avoid costly startup time at the first call on that device.\n\\details\n\nCalling `rocblas_initialize()` allows upfront initialization including device specific kernel setup.\nOtherwise this function is automatically called on the first function call that requires these initializations (mainly GEMM).\n"] + pub fn rocblas_initialize(); +} +extern "C" { + #[must_use] + #[doc = " \\brief Loads char* buf with the rocblas library version. size_t len\nis the maximum length of char* buf.\n\\details\n\n@param[in, out]\nbuf pointer to buffer for version string\n\n@param[in]\nlen length of buf\n"] + pub fn rocblas_get_version_string( + buf: *mut ::std::os::raw::c_char, + len: usize, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief Queries the minimum buffer size for a successful call to\n\\ref rocblas_get_version_string\n\\details\n\n@param[out]\nlen pointer to size_t for storing the length\n"] + pub fn rocblas_get_version_string_size(len: *mut usize) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief\n\\details\nIndicates that subsequent rocBLAS kernel calls should collect the optimal device memory size in bytes for their given kernel arguments\nand keep track of the maximum.\nEach kernel call can reuse temporary device memory on the same stream so the maximum is collected.\nReturns rocblas_status_size_query_mismatch if another size query is already in progress; returns rocblas_status_success otherwise\n@param[in]\nhandle rocblas handle"] + pub fn rocblas_start_device_memory_size_query(handle: rocblas_handle) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief\n\\details\nStops collecting optimal device memory size information.\nReturns rocblas_status_size_query_mismatch if a collection is not underway; rocblas_status_invalid_handle if handle is nullptr;\nrocblas_status_invalid_pointer if size is nullptr; rocblas_status_success otherwise\n@param[in]\nhandle rocblas handle\n@param[out]\nsize maximum of the optimal sizes collected"] + pub fn rocblas_stop_device_memory_size_query( + handle: rocblas_handle, + size: *mut usize, + ) -> rocblas_status; +} +extern "C" { + pub fn rocblas_is_device_memory_size_query(handle: rocblas_handle) -> bool; +} +extern "C" { + #[must_use] + pub fn rocblas_set_optimal_device_memory_size_impl( + handle: rocblas_handle, + count: usize, + ... + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_device_malloc_alloc( + handle: rocblas_handle, + res: *mut *mut rocblas_device_malloc_base, + count: usize, + ... + ) -> rocblas_status; +} +extern "C" { + pub fn rocblas_device_malloc_success(ptr: *mut rocblas_device_malloc_base) -> bool; +} +extern "C" { + #[must_use] + pub fn rocblas_device_malloc_ptr( + ptr: *mut rocblas_device_malloc_base, + res: *mut *mut ::std::os::raw::c_void, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_device_malloc_get( + ptr: *mut rocblas_device_malloc_base, + index: usize, + res: *mut *mut ::std::os::raw::c_void, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocblas_device_malloc_free(ptr: *mut rocblas_device_malloc_base) -> rocblas_status; +} +extern "C" { + pub fn rocblas_device_malloc_set_default_memory_size(size: usize); +} +extern "C" { + #[must_use] + #[doc = " \\brief\n\\details\nGets the current device memory size for the handle.\nReturns rocblas_status_invalid_handle if handle is nullptr; rocblas_status_invalid_pointer if size is nullptr; rocblas_status_success otherwise\n@param[in]\nhandle rocblas handle\n@param[out]\nsize current device memory size for the handle"] + pub fn rocblas_get_device_memory_size( + handle: rocblas_handle, + size: *mut usize, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief\n\\details\nChanges the size of allocated device memory at runtime.\n\nAny previously allocated device memory managed by the handle is freed.\n\nIf size > 0 sets the device memory size to the specified size (in bytes).\nIf size == 0, frees the memory allocated so far, and lets rocBLAS manage device memory in the future, expanding it when necessary.\nReturns rocblas_status_invalid_handle if handle is nullptr; rocblas_status_invalid_pointer if size is nullptr; rocblas_status_success otherwise\n@param[in]\nhandle rocblas handle\n@param[in]\nsize size of allocated device memory"] + pub fn rocblas_set_device_memory_size(handle: rocblas_handle, size: usize) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief\n\\details\nSets the device workspace for the handle to use.\n\nAny previously allocated device memory managed by the handle is freed.\n\nReturns rocblas_status_invalid_handle if handle is nullptr; rocblas_status_success otherwise\n@param[in]\nhandle rocblas handle\n@param[in]\naddr address of workspace memory\n@param[in]\nsize size of workspace memory\n"] + pub fn rocblas_set_workspace( + handle: rocblas_handle, + addr: *mut ::std::os::raw::c_void, + size: usize, + ) -> rocblas_status; +} +extern "C" { + #[doc = " \\brief\n\\details\nReturns true when device memory in handle is managed by rocBLAS\n@param[in]\nhandle rocblas handle"] + pub fn rocblas_is_managing_device_memory(handle: rocblas_handle) -> bool; +} +extern "C" { + #[doc = " \\brief\n\\details\nReturns true when device memory in handle is managed by the user\n@param[in]\nhandle rocblas handle"] + pub fn rocblas_is_user_managing_device_memory(handle: rocblas_handle) -> bool; +} +extern "C" { + pub fn rocblas_abort() -> !; +} diff --git a/rocm_smi-sys/Cargo.toml b/rocm_smi-sys/Cargo.toml new file mode 100644 index 0000000..fb533cf --- /dev/null +++ b/rocm_smi-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rocm_smi-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "rocm_smi64" + +[lib] diff --git a/rocm_smi-sys/README b/rocm_smi-sys/README new file mode 100644 index 0000000..16d3c5b --- /dev/null +++ b/rocm_smi-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/rocm_smi/rocm_smi.h -o src/rocm_smi.rs --no-layout-tests --size_t-is-usize --default-enum-style=newtype --no-derive-debug --allowlist-function "rsmi_.*" --allowlist-var "RSMI.*" --must-use-type rsmi_status_t -- -I/opt/rocm/include \ No newline at end of file diff --git a/rocm_smi-sys/build.rs b/rocm_smi-sys/build.rs new file mode 100644 index 0000000..fb677c5 --- /dev/null +++ b/rocm_smi-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=rocm_smi64"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/rocm_smi-sys/src/lib.rs b/rocm_smi-sys/src/lib.rs new file mode 100644 index 0000000..a7c3b29 --- /dev/null +++ b/rocm_smi-sys/src/lib.rs @@ -0,0 +1,5 @@ +#[allow(non_camel_case_types)] +#[allow(non_snake_case)] +#[allow(non_upper_case_globals)] +mod rocm_smi; +pub use rocm_smi::*; diff --git a/rocm_smi-sys/src/rocm_smi.rs b/rocm_smi-sys/src/rocm_smi.rs new file mode 100644 index 0000000..797a922 --- /dev/null +++ b/rocm_smi-sys/src/rocm_smi.rs @@ -0,0 +1,1720 @@ +/* automatically generated by rust-bindgen 0.63.0 */ + +pub const RSMI_MAX_NUM_FREQUENCIES: u32 = 32; +pub const RSMI_MAX_FAN_SPEED: u32 = 255; +pub const RSMI_NUM_VOLTAGE_CURVE_POINTS: u32 = 3; +pub const RSMI_GPU_METRICS_API_FORMAT_VER: u32 = 1; +pub const RSMI_GPU_METRICS_API_CONTENT_VER_1: u32 = 1; +pub const RSMI_GPU_METRICS_API_CONTENT_VER_2: u32 = 2; +pub const RSMI_GPU_METRICS_API_CONTENT_VER_3: u32 = 3; +pub const RSMI_NUM_HBM_INSTANCES: u32 = 4; +pub const RSMI_DEFAULT_VARIANT: i32 = -1; +impl rsmi_status_t { + #[doc = "!< Operation was successful"] + pub const RSMI_STATUS_SUCCESS: rsmi_status_t = rsmi_status_t(0); +} +impl rsmi_status_t { + #[doc = "!< Passed in arguments are not valid"] + pub const RSMI_STATUS_INVALID_ARGS: rsmi_status_t = rsmi_status_t(1); +} +impl rsmi_status_t { + #[doc = "!< The requested information or\n!< action is not available for the\n!< given input, on the given system"] + pub const RSMI_STATUS_NOT_SUPPORTED: rsmi_status_t = rsmi_status_t(2); +} +impl rsmi_status_t { + #[doc = "!< Problem accessing a file. This\n!< may because the operation is not\n!< supported by the Linux kernel\n!< version running on the executing\n!< machine"] + pub const RSMI_STATUS_FILE_ERROR: rsmi_status_t = rsmi_status_t(3); +} +impl rsmi_status_t { + #[doc = "!< Permission denied/EACCESS file\n!< error. Many functions require\n!< root access to run."] + pub const RSMI_STATUS_PERMISSION: rsmi_status_t = rsmi_status_t(4); +} +impl rsmi_status_t { + #[doc = "!< Unable to acquire memory or other\n!< resource"] + pub const RSMI_STATUS_OUT_OF_RESOURCES: rsmi_status_t = rsmi_status_t(5); +} +impl rsmi_status_t { + #[doc = "!< An internal exception was caught"] + pub const RSMI_STATUS_INTERNAL_EXCEPTION: rsmi_status_t = rsmi_status_t(6); +} +impl rsmi_status_t { + #[doc = "!< The provided input is out of\n!< allowable or safe range"] + pub const RSMI_STATUS_INPUT_OUT_OF_BOUNDS: rsmi_status_t = rsmi_status_t(7); +} +impl rsmi_status_t { + #[doc = "!< An error occurred when rsmi\n!< initializing internal data\n!< structures"] + pub const RSMI_STATUS_INIT_ERROR: rsmi_status_t = rsmi_status_t(8); +} +impl rsmi_status_t { + pub const RSMI_INITIALIZATION_ERROR: rsmi_status_t = rsmi_status_t(8); +} +impl rsmi_status_t { + #[doc = "!< The requested function has not\n!< yet been implemented in the\n!< current system for the current\n!< devices"] + pub const RSMI_STATUS_NOT_YET_IMPLEMENTED: rsmi_status_t = rsmi_status_t(9); +} +impl rsmi_status_t { + #[doc = "!< An item was searched for but not\n!< found"] + pub const RSMI_STATUS_NOT_FOUND: rsmi_status_t = rsmi_status_t(10); +} +impl rsmi_status_t { + #[doc = "!< Not enough resources were\n!< available for the operation"] + pub const RSMI_STATUS_INSUFFICIENT_SIZE: rsmi_status_t = rsmi_status_t(11); +} +impl rsmi_status_t { + #[doc = "!< An interrupt occurred during\n!< execution of function"] + pub const RSMI_STATUS_INTERRUPT: rsmi_status_t = rsmi_status_t(12); +} +impl rsmi_status_t { + #[doc = "!< An unexpected amount of data\n!< was read"] + pub const RSMI_STATUS_UNEXPECTED_SIZE: rsmi_status_t = rsmi_status_t(13); +} +impl rsmi_status_t { + #[doc = "!< No data was found for a given\n!< input"] + pub const RSMI_STATUS_NO_DATA: rsmi_status_t = rsmi_status_t(14); +} +impl rsmi_status_t { + #[doc = "!< The data read or provided to\n!< function is not what was expected"] + pub const RSMI_STATUS_UNEXPECTED_DATA: rsmi_status_t = rsmi_status_t(15); +} +impl rsmi_status_t { + #[doc = "!< A resource or mutex could not be\n!< acquired because it is already\n!< being used"] + pub const RSMI_STATUS_BUSY: rsmi_status_t = rsmi_status_t(16); +} +impl rsmi_status_t { + #[doc = "!< An internal reference counter\n!< exceeded INT32_MAX"] + pub const RSMI_STATUS_REFCOUNT_OVERFLOW: rsmi_status_t = rsmi_status_t(17); +} +impl rsmi_status_t { + #[doc = "!< An unknown error occurred"] + pub const RSMI_STATUS_UNKNOWN_ERROR: rsmi_status_t = rsmi_status_t(4294967295); +} +#[repr(transparent)] +#[doc = " @brief Error codes retured by rocm_smi_lib functions"] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_status_t(pub ::std::os::raw::c_uint); +impl rsmi_dev_perf_level_t { + #[doc = "!< Performance level is \"auto\""] + pub const RSMI_DEV_PERF_LEVEL_AUTO: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(0); +} +impl rsmi_dev_perf_level_t { + pub const RSMI_DEV_PERF_LEVEL_FIRST: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(0); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Keep PowerPlay levels \"low\",\n!< regardless of workload"] + pub const RSMI_DEV_PERF_LEVEL_LOW: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(1); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Keep PowerPlay levels \"high\",\n!< regardless of workload"] + pub const RSMI_DEV_PERF_LEVEL_HIGH: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(2); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Only use values defined by manually\n!< setting the RSMI_CLK_TYPE_SYS speed"] + pub const RSMI_DEV_PERF_LEVEL_MANUAL: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(3); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Stable power state with profiling\n!< clocks"] + pub const RSMI_DEV_PERF_LEVEL_STABLE_STD: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(4); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Stable power state with peak clocks"] + pub const RSMI_DEV_PERF_LEVEL_STABLE_PEAK: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(5); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Stable power state with minimum\n!< memory clock"] + pub const RSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(6); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Stable power state with minimum\n!< system clock"] + pub const RSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(7); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Performance determinism state"] + pub const RSMI_DEV_PERF_LEVEL_DETERMINISM: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(8); +} +impl rsmi_dev_perf_level_t { + pub const RSMI_DEV_PERF_LEVEL_LAST: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(8); +} +impl rsmi_dev_perf_level_t { + #[doc = "!< Unknown performance level"] + pub const RSMI_DEV_PERF_LEVEL_UNKNOWN: rsmi_dev_perf_level_t = rsmi_dev_perf_level_t(256); +} +#[repr(transparent)] +#[doc = " @brief PowerPlay performance levels"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_dev_perf_level_t(pub ::std::os::raw::c_uint); +impl rsmi_sw_component_t { + pub const RSMI_SW_COMP_FIRST: rsmi_sw_component_t = rsmi_sw_component_t(0); +} +impl rsmi_sw_component_t { + #[doc = "!< Driver"] + pub const RSMI_SW_COMP_DRIVER: rsmi_sw_component_t = rsmi_sw_component_t(0); +} +impl rsmi_sw_component_t { + pub const RSMI_SW_COMP_LAST: rsmi_sw_component_t = rsmi_sw_component_t(0); +} +#[repr(transparent)] +#[doc = " @brief Software components"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_sw_component_t(pub ::std::os::raw::c_uint); +#[doc = " @brief Handle to performance event counter"] +pub type rsmi_event_handle_t = usize; +impl rsmi_event_group_t { + #[doc = "!< Data Fabric (XGMI) related events"] + pub const RSMI_EVNT_GRP_XGMI: rsmi_event_group_t = rsmi_event_group_t(0); +} +impl rsmi_event_group_t { + #[doc = "!< XGMI Outbound data"] + pub const RSMI_EVNT_GRP_XGMI_DATA_OUT: rsmi_event_group_t = rsmi_event_group_t(10); +} +impl rsmi_event_group_t { + pub const RSMI_EVNT_GRP_INVALID: rsmi_event_group_t = rsmi_event_group_t(4294967295); +} +#[repr(transparent)] +#[doc = " Event Groups\n\n @brief Enum denoting an event group. The value of the enum is the\n base value for all the event enums in the group."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_event_group_t(pub ::std::os::raw::c_uint); +impl rsmi_event_type_t { + pub const RSMI_EVNT_FIRST: rsmi_event_type_t = rsmi_event_type_t(0); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_XGMI_FIRST: rsmi_event_type_t = rsmi_event_type_t(0); +} +impl rsmi_event_type_t { + #[doc = "!< NOPs sent to neighbor 0"] + pub const RSMI_EVNT_XGMI_0_NOP_TX: rsmi_event_type_t = rsmi_event_type_t(0); +} +impl rsmi_event_type_t { + #[doc = "!< Outgoing requests to\n!< neighbor 0"] + pub const RSMI_EVNT_XGMI_0_REQUEST_TX: rsmi_event_type_t = rsmi_event_type_t(1); +} +impl rsmi_event_type_t { + #[doc = "!< Outgoing responses to\n!< neighbor 0"] + pub const RSMI_EVNT_XGMI_0_RESPONSE_TX: rsmi_event_type_t = rsmi_event_type_t(2); +} +impl rsmi_event_type_t { + #[doc = " @brief\n\n Data beats sent to neighbor 0; Each beat represents 32 bytes.

\n\n XGMI throughput can be calculated by multiplying a BEATs event\n such as ::RSMI_EVNT_XGMI_0_BEATS_TX by 32 and dividing by\n the time for which event collection occurred,\n ::rsmi_counter_value_t.time_running (which is in nanoseconds). To get\n bytes per second, multiply this value by 109.
\n
\n Throughput = BEATS/time_running * 109 (bytes/second)
"] + pub const RSMI_EVNT_XGMI_0_BEATS_TX: rsmi_event_type_t = rsmi_event_type_t(3); +} +impl rsmi_event_type_t { + #[doc = "!< NOPs sent to neighbor 1"] + pub const RSMI_EVNT_XGMI_1_NOP_TX: rsmi_event_type_t = rsmi_event_type_t(4); +} +impl rsmi_event_type_t { + #[doc = "!< Outgoing requests to\n!< neighbor 1"] + pub const RSMI_EVNT_XGMI_1_REQUEST_TX: rsmi_event_type_t = rsmi_event_type_t(5); +} +impl rsmi_event_type_t { + #[doc = "!< Outgoing responses to\n!< neighbor 1"] + pub const RSMI_EVNT_XGMI_1_RESPONSE_TX: rsmi_event_type_t = rsmi_event_type_t(6); +} +impl rsmi_event_type_t { + #[doc = "!< Data beats sent to\n!< neighbor 1; Each beat\n!< represents 32 bytes"] + pub const RSMI_EVNT_XGMI_1_BEATS_TX: rsmi_event_type_t = rsmi_event_type_t(7); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_XGMI_LAST: rsmi_event_type_t = rsmi_event_type_t(7); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_XGMI_DATA_OUT_FIRST: rsmi_event_type_t = rsmi_event_type_t(10); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_XGMI_DATA_OUT_0: rsmi_event_type_t = rsmi_event_type_t(10); +} +impl rsmi_event_type_t { + #[doc = "!< Outbound beats to neighbor 1"] + pub const RSMI_EVNT_XGMI_DATA_OUT_1: rsmi_event_type_t = rsmi_event_type_t(11); +} +impl rsmi_event_type_t { + #[doc = "!< Outbound beats to neighbor 2"] + pub const RSMI_EVNT_XGMI_DATA_OUT_2: rsmi_event_type_t = rsmi_event_type_t(12); +} +impl rsmi_event_type_t { + #[doc = "!< Outbound beats to neighbor 3"] + pub const RSMI_EVNT_XGMI_DATA_OUT_3: rsmi_event_type_t = rsmi_event_type_t(13); +} +impl rsmi_event_type_t { + #[doc = "!< Outbound beats to neighbor 4"] + pub const RSMI_EVNT_XGMI_DATA_OUT_4: rsmi_event_type_t = rsmi_event_type_t(14); +} +impl rsmi_event_type_t { + #[doc = "!< Outbound beats to neighbor 5"] + pub const RSMI_EVNT_XGMI_DATA_OUT_5: rsmi_event_type_t = rsmi_event_type_t(15); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_XGMI_DATA_OUT_LAST: rsmi_event_type_t = rsmi_event_type_t(15); +} +impl rsmi_event_type_t { + pub const RSMI_EVNT_LAST: rsmi_event_type_t = rsmi_event_type_t(15); +} +#[repr(transparent)] +#[doc = " Event types\n @brief Event type enum. Events belonging to a particular event group\n ::rsmi_event_group_t should begin enumerating at the ::rsmi_event_group_t\n value for that group."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_event_type_t(pub ::std::os::raw::c_uint); +impl rsmi_counter_command_t { + #[doc = "!< Start the counter"] + pub const RSMI_CNTR_CMD_START: rsmi_counter_command_t = rsmi_counter_command_t(0); +} +impl rsmi_counter_command_t { + #[doc = "!< Stop the counter; note that this should not\n!< be used before reading."] + pub const RSMI_CNTR_CMD_STOP: rsmi_counter_command_t = rsmi_counter_command_t(1); +} +#[repr(transparent)] +#[doc = " Event counter commands"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_counter_command_t(pub ::std::os::raw::c_uint); +#[doc = " Counter value"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_counter_value_t { + #[doc = "!< Counter value"] + pub value: u64, + #[doc = "!< Time that the counter was enabled\n!< (in nanoseconds)"] + pub time_enabled: u64, + #[doc = "!< Time that the counter was running\n!< (in nanoseconds)"] + pub time_running: u64, +} +impl rsmi_evt_notification_type_t { + #[doc = "!< VM page fault"] + pub const RSMI_EVT_NOTIF_VMFAULT: rsmi_evt_notification_type_t = + rsmi_evt_notification_type_t(1); +} +impl rsmi_evt_notification_type_t { + pub const RSMI_EVT_NOTIF_FIRST: rsmi_evt_notification_type_t = rsmi_evt_notification_type_t(1); +} +impl rsmi_evt_notification_type_t { + pub const RSMI_EVT_NOTIF_THERMAL_THROTTLE: rsmi_evt_notification_type_t = + rsmi_evt_notification_type_t(2); +} +impl rsmi_evt_notification_type_t { + pub const RSMI_EVT_NOTIF_GPU_PRE_RESET: rsmi_evt_notification_type_t = + rsmi_evt_notification_type_t(3); +} +impl rsmi_evt_notification_type_t { + pub const RSMI_EVT_NOTIF_GPU_POST_RESET: rsmi_evt_notification_type_t = + rsmi_evt_notification_type_t(4); +} +impl rsmi_evt_notification_type_t { + pub const RSMI_EVT_NOTIF_LAST: rsmi_evt_notification_type_t = rsmi_evt_notification_type_t(4); +} +#[repr(transparent)] +#[doc = " Event notification event types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_evt_notification_type_t(pub ::std::os::raw::c_uint); +#[doc = " Event notification data returned from event notification API"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_evt_notification_data_t { + #[doc = "!< Index of device that corresponds to the event"] + pub dv_ind: u32, + #[doc = "!< Event type"] + pub event: rsmi_evt_notification_type_t, + #[doc = "!< Event message"] + pub message: [::std::os::raw::c_char; 64usize], +} +impl rsmi_clk_type_t { + #[doc = "!< System clock"] + pub const RSMI_CLK_TYPE_SYS: rsmi_clk_type_t = rsmi_clk_type_t(0); +} +impl rsmi_clk_type_t { + pub const RSMI_CLK_TYPE_FIRST: rsmi_clk_type_t = rsmi_clk_type_t(0); +} +impl rsmi_clk_type_t { + #[doc = "!< Data Fabric clock (for ASICs\n!< running on a separate clock)"] + pub const RSMI_CLK_TYPE_DF: rsmi_clk_type_t = rsmi_clk_type_t(1); +} +impl rsmi_clk_type_t { + #[doc = "!< Display Controller Engine clock"] + pub const RSMI_CLK_TYPE_DCEF: rsmi_clk_type_t = rsmi_clk_type_t(2); +} +impl rsmi_clk_type_t { + #[doc = "!< SOC clock"] + pub const RSMI_CLK_TYPE_SOC: rsmi_clk_type_t = rsmi_clk_type_t(3); +} +impl rsmi_clk_type_t { + #[doc = "!< Memory clock"] + pub const RSMI_CLK_TYPE_MEM: rsmi_clk_type_t = rsmi_clk_type_t(4); +} +impl rsmi_clk_type_t { + #[doc = "!< PCIE clock"] + pub const RSMI_CLK_TYPE_PCIE: rsmi_clk_type_t = rsmi_clk_type_t(5); +} +impl rsmi_clk_type_t { + pub const RSMI_CLK_TYPE_LAST: rsmi_clk_type_t = rsmi_clk_type_t(4); +} +impl rsmi_clk_type_t { + pub const RSMI_CLK_INVALID: rsmi_clk_type_t = rsmi_clk_type_t(4294967295); +} +#[repr(transparent)] +#[doc = " Clock types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_clk_type_t(pub ::std::os::raw::c_uint); +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature current value."] + pub const RSMI_TEMP_CURRENT: rsmi_temperature_metric_t = rsmi_temperature_metric_t(0); +} +impl rsmi_temperature_metric_t { + pub const RSMI_TEMP_FIRST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(0); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature max value."] + pub const RSMI_TEMP_MAX: rsmi_temperature_metric_t = rsmi_temperature_metric_t(1); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature min value."] + pub const RSMI_TEMP_MIN: rsmi_temperature_metric_t = rsmi_temperature_metric_t(2); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature hysteresis value for max limit.\n!< (This is an absolute temperature, not a\n!< delta)."] + pub const RSMI_TEMP_MAX_HYST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(3); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature hysteresis value for min limit.\n!< (This is an absolute temperature,\n!< not a delta)."] + pub const RSMI_TEMP_MIN_HYST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(4); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature critical max value, typically\n!< greater than corresponding temp_max values."] + pub const RSMI_TEMP_CRITICAL: rsmi_temperature_metric_t = rsmi_temperature_metric_t(5); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature hysteresis value for critical\n!< limit. (This is an absolute temperature,\n!< not a delta)."] + pub const RSMI_TEMP_CRITICAL_HYST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(6); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature emergency max value, for chips\n!< supporting more than two upper temperature\n!< limits. Must be equal or greater than\n!< corresponding temp_crit values."] + pub const RSMI_TEMP_EMERGENCY: rsmi_temperature_metric_t = rsmi_temperature_metric_t(7); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature hysteresis value for emergency\n!< limit. (This is an absolute temperature,\n!< not a delta)."] + pub const RSMI_TEMP_EMERGENCY_HYST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(8); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature critical min value, typically\n!< lower than corresponding temperature\n!< minimum values."] + pub const RSMI_TEMP_CRIT_MIN: rsmi_temperature_metric_t = rsmi_temperature_metric_t(9); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature hysteresis value for critical\n!< minimum limit. (This is an absolute\n!< temperature, not a delta)."] + pub const RSMI_TEMP_CRIT_MIN_HYST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(10); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Temperature offset which is added to the"] + pub const RSMI_TEMP_OFFSET: rsmi_temperature_metric_t = rsmi_temperature_metric_t(11); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Historical minimum temperature."] + pub const RSMI_TEMP_LOWEST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(12); +} +impl rsmi_temperature_metric_t { + #[doc = "!< Historical maximum temperature."] + pub const RSMI_TEMP_HIGHEST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(13); +} +impl rsmi_temperature_metric_t { + pub const RSMI_TEMP_LAST: rsmi_temperature_metric_t = rsmi_temperature_metric_t(13); +} +#[repr(transparent)] +#[doc = " @brief Temperature Metrics. This enum is used to identify various\n temperature metrics. Corresponding values will be in millidegress\n Celcius."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_temperature_metric_t(pub ::std::os::raw::c_uint); +impl rsmi_voltage_metric_t { + #[doc = "!< Voltage current value."] + pub const RSMI_VOLT_CURRENT: rsmi_voltage_metric_t = rsmi_voltage_metric_t(0); +} +impl rsmi_voltage_metric_t { + pub const RSMI_VOLT_FIRST: rsmi_voltage_metric_t = rsmi_voltage_metric_t(0); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Voltage max value."] + pub const RSMI_VOLT_MAX: rsmi_voltage_metric_t = rsmi_voltage_metric_t(1); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Voltage critical min value."] + pub const RSMI_VOLT_MIN_CRIT: rsmi_voltage_metric_t = rsmi_voltage_metric_t(2); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Voltage min value."] + pub const RSMI_VOLT_MIN: rsmi_voltage_metric_t = rsmi_voltage_metric_t(3); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Voltage critical max value."] + pub const RSMI_VOLT_MAX_CRIT: rsmi_voltage_metric_t = rsmi_voltage_metric_t(4); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Average voltage."] + pub const RSMI_VOLT_AVERAGE: rsmi_voltage_metric_t = rsmi_voltage_metric_t(5); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Historical minimum voltage."] + pub const RSMI_VOLT_LOWEST: rsmi_voltage_metric_t = rsmi_voltage_metric_t(6); +} +impl rsmi_voltage_metric_t { + #[doc = "!< Historical maximum voltage."] + pub const RSMI_VOLT_HIGHEST: rsmi_voltage_metric_t = rsmi_voltage_metric_t(7); +} +impl rsmi_voltage_metric_t { + pub const RSMI_VOLT_LAST: rsmi_voltage_metric_t = rsmi_voltage_metric_t(7); +} +#[repr(transparent)] +#[doc = " @brief Voltage Metrics. This enum is used to identify various\n Volatge metrics. Corresponding values will be in millivolt.\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_voltage_metric_t(pub ::std::os::raw::c_uint); +impl rsmi_voltage_type_t { + pub const RSMI_VOLT_TYPE_FIRST: rsmi_voltage_type_t = rsmi_voltage_type_t(0); +} +impl rsmi_voltage_type_t { + #[doc = "!< Vddgfx GPU\n!< voltage"] + pub const RSMI_VOLT_TYPE_VDDGFX: rsmi_voltage_type_t = rsmi_voltage_type_t(0); +} +impl rsmi_voltage_type_t { + pub const RSMI_VOLT_TYPE_LAST: rsmi_voltage_type_t = rsmi_voltage_type_t(0); +} +impl rsmi_voltage_type_t { + #[doc = "!< Invalid type"] + pub const RSMI_VOLT_TYPE_INVALID: rsmi_voltage_type_t = rsmi_voltage_type_t(4294967295); +} +#[repr(transparent)] +#[doc = " @brief This ennumeration is used to indicate which type of\n voltage reading should be obtained."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_voltage_type_t(pub ::std::os::raw::c_uint); +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< Custom Power Profile"] + pub const RSMI_PWR_PROF_PRST_CUSTOM_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(1); +} +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< Video Power Profile"] + pub const RSMI_PWR_PROF_PRST_VIDEO_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(2); +} +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< Power Saving Profile"] + pub const RSMI_PWR_PROF_PRST_POWER_SAVING_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(4); +} +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< Compute Saving Profile"] + pub const RSMI_PWR_PROF_PRST_COMPUTE_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(8); +} +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< VR Power Profile"] + pub const RSMI_PWR_PROF_PRST_VR_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(16); +} +impl rsmi_power_profile_preset_masks_t { + pub const RSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(32); +} +impl rsmi_power_profile_preset_masks_t { + #[doc = "!< Default Boot Up Profile"] + pub const RSMI_PWR_PROF_PRST_BOOTUP_DEFAULT: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(64); +} +impl rsmi_power_profile_preset_masks_t { + pub const RSMI_PWR_PROF_PRST_LAST: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(64); +} +impl rsmi_power_profile_preset_masks_t { + pub const RSMI_PWR_PROF_PRST_INVALID: rsmi_power_profile_preset_masks_t = + rsmi_power_profile_preset_masks_t(::std::os::raw::c_ulong::MAX); +} +#[repr(transparent)] +#[doc = " @brief Pre-set Profile Selections. These bitmasks can be AND'd with the\n ::rsmi_power_profile_status_t.available_profiles returned from\n ::rsmi_dev_power_profile_presets_get to determine which power profiles\n are supported by the system."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_power_profile_preset_masks_t(pub ::std::os::raw::c_ulong); +impl rsmi_gpu_block_t { + #[doc = "!< Used to indicate an\n!< invalid block"] + pub const RSMI_GPU_BLOCK_INVALID: rsmi_gpu_block_t = rsmi_gpu_block_t(0); +} +impl rsmi_gpu_block_t { + pub const RSMI_GPU_BLOCK_FIRST: rsmi_gpu_block_t = rsmi_gpu_block_t(1); +} +impl rsmi_gpu_block_t { + #[doc = "!< UMC block"] + pub const RSMI_GPU_BLOCK_UMC: rsmi_gpu_block_t = rsmi_gpu_block_t(1); +} +impl rsmi_gpu_block_t { + #[doc = "!< SDMA block"] + pub const RSMI_GPU_BLOCK_SDMA: rsmi_gpu_block_t = rsmi_gpu_block_t(2); +} +impl rsmi_gpu_block_t { + #[doc = "!< GFX block"] + pub const RSMI_GPU_BLOCK_GFX: rsmi_gpu_block_t = rsmi_gpu_block_t(4); +} +impl rsmi_gpu_block_t { + #[doc = "!< MMHUB block"] + pub const RSMI_GPU_BLOCK_MMHUB: rsmi_gpu_block_t = rsmi_gpu_block_t(8); +} +impl rsmi_gpu_block_t { + #[doc = "!< ATHUB block"] + pub const RSMI_GPU_BLOCK_ATHUB: rsmi_gpu_block_t = rsmi_gpu_block_t(16); +} +impl rsmi_gpu_block_t { + #[doc = "!< PCIE_BIF block"] + pub const RSMI_GPU_BLOCK_PCIE_BIF: rsmi_gpu_block_t = rsmi_gpu_block_t(32); +} +impl rsmi_gpu_block_t { + #[doc = "!< HDP block"] + pub const RSMI_GPU_BLOCK_HDP: rsmi_gpu_block_t = rsmi_gpu_block_t(64); +} +impl rsmi_gpu_block_t { + #[doc = "!< XGMI block"] + pub const RSMI_GPU_BLOCK_XGMI_WAFL: rsmi_gpu_block_t = rsmi_gpu_block_t(128); +} +impl rsmi_gpu_block_t { + #[doc = "!< DF block"] + pub const RSMI_GPU_BLOCK_DF: rsmi_gpu_block_t = rsmi_gpu_block_t(256); +} +impl rsmi_gpu_block_t { + #[doc = "!< SMN block"] + pub const RSMI_GPU_BLOCK_SMN: rsmi_gpu_block_t = rsmi_gpu_block_t(512); +} +impl rsmi_gpu_block_t { + #[doc = "!< SEM block"] + pub const RSMI_GPU_BLOCK_SEM: rsmi_gpu_block_t = rsmi_gpu_block_t(1024); +} +impl rsmi_gpu_block_t { + #[doc = "!< MP0 block"] + pub const RSMI_GPU_BLOCK_MP0: rsmi_gpu_block_t = rsmi_gpu_block_t(2048); +} +impl rsmi_gpu_block_t { + #[doc = "!< MP1 block"] + pub const RSMI_GPU_BLOCK_MP1: rsmi_gpu_block_t = rsmi_gpu_block_t(4096); +} +impl rsmi_gpu_block_t { + #[doc = "!< Fuse block"] + pub const RSMI_GPU_BLOCK_FUSE: rsmi_gpu_block_t = rsmi_gpu_block_t(8192); +} +impl rsmi_gpu_block_t { + #[doc = "!< The highest bit position\n!< for supported blocks"] + pub const RSMI_GPU_BLOCK_LAST: rsmi_gpu_block_t = rsmi_gpu_block_t(8192); +} +impl rsmi_gpu_block_t { + pub const RSMI_GPU_BLOCK_RESERVED: rsmi_gpu_block_t = + rsmi_gpu_block_t(::std::os::raw::c_ulong::MAX); +} +#[repr(transparent)] +#[doc = " @brief This enum is used to identify different GPU blocks."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_gpu_block_t(pub ::std::os::raw::c_ulong); +impl rsmi_ras_err_state_t { + #[doc = "!< No current errors"] + pub const RSMI_RAS_ERR_STATE_NONE: rsmi_ras_err_state_t = rsmi_ras_err_state_t(0); +} +impl rsmi_ras_err_state_t { + #[doc = "!< ECC is disabled"] + pub const RSMI_RAS_ERR_STATE_DISABLED: rsmi_ras_err_state_t = rsmi_ras_err_state_t(1); +} +impl rsmi_ras_err_state_t { + #[doc = "!< ECC errors present, but type unknown"] + pub const RSMI_RAS_ERR_STATE_PARITY: rsmi_ras_err_state_t = rsmi_ras_err_state_t(2); +} +impl rsmi_ras_err_state_t { + #[doc = "!< Single correctable error"] + pub const RSMI_RAS_ERR_STATE_SING_C: rsmi_ras_err_state_t = rsmi_ras_err_state_t(3); +} +impl rsmi_ras_err_state_t { + #[doc = "!< Multiple uncorrectable errors"] + pub const RSMI_RAS_ERR_STATE_MULT_UC: rsmi_ras_err_state_t = rsmi_ras_err_state_t(4); +} +impl rsmi_ras_err_state_t { + #[doc = "!< Firmware detected error and isolated\n!< page. Treat as uncorrectable."] + pub const RSMI_RAS_ERR_STATE_POISON: rsmi_ras_err_state_t = rsmi_ras_err_state_t(5); +} +impl rsmi_ras_err_state_t { + #[doc = "!< ECC is enabled"] + pub const RSMI_RAS_ERR_STATE_ENABLED: rsmi_ras_err_state_t = rsmi_ras_err_state_t(6); +} +impl rsmi_ras_err_state_t { + pub const RSMI_RAS_ERR_STATE_LAST: rsmi_ras_err_state_t = rsmi_ras_err_state_t(6); +} +impl rsmi_ras_err_state_t { + pub const RSMI_RAS_ERR_STATE_INVALID: rsmi_ras_err_state_t = rsmi_ras_err_state_t(4294967295); +} +#[repr(transparent)] +#[doc = " @brief The current ECC state"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_ras_err_state_t(pub ::std::os::raw::c_uint); +impl rsmi_memory_type_t { + pub const RSMI_MEM_TYPE_FIRST: rsmi_memory_type_t = rsmi_memory_type_t(0); +} +impl rsmi_memory_type_t { + #[doc = "!< VRAM memory"] + pub const RSMI_MEM_TYPE_VRAM: rsmi_memory_type_t = rsmi_memory_type_t(0); +} +impl rsmi_memory_type_t { + #[doc = "!< VRAM memory that is visible"] + pub const RSMI_MEM_TYPE_VIS_VRAM: rsmi_memory_type_t = rsmi_memory_type_t(1); +} +impl rsmi_memory_type_t { + #[doc = "!< GTT memory"] + pub const RSMI_MEM_TYPE_GTT: rsmi_memory_type_t = rsmi_memory_type_t(2); +} +impl rsmi_memory_type_t { + pub const RSMI_MEM_TYPE_LAST: rsmi_memory_type_t = rsmi_memory_type_t(2); +} +#[repr(transparent)] +#[doc = " @brief Types of memory"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_memory_type_t(pub ::std::os::raw::c_uint); +impl rsmi_freq_ind_t { + #[doc = "!< Index used for the minimum frequency value"] + pub const RSMI_FREQ_IND_MIN: rsmi_freq_ind_t = rsmi_freq_ind_t(0); +} +impl rsmi_freq_ind_t { + #[doc = "!< Index used for the maximum frequency value"] + pub const RSMI_FREQ_IND_MAX: rsmi_freq_ind_t = rsmi_freq_ind_t(1); +} +impl rsmi_freq_ind_t { + #[doc = "!< An invalid frequency index"] + pub const RSMI_FREQ_IND_INVALID: rsmi_freq_ind_t = rsmi_freq_ind_t(4294967295); +} +#[repr(transparent)] +#[doc = " @brief The values of this enum are used as frequency identifiers."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_freq_ind_t(pub ::std::os::raw::c_uint); +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_FIRST: rsmi_fw_block_t = rsmi_fw_block_t(0); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_ASD: rsmi_fw_block_t = rsmi_fw_block_t(0); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_CE: rsmi_fw_block_t = rsmi_fw_block_t(1); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_DMCU: rsmi_fw_block_t = rsmi_fw_block_t(2); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_MC: rsmi_fw_block_t = rsmi_fw_block_t(3); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_ME: rsmi_fw_block_t = rsmi_fw_block_t(4); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_MEC: rsmi_fw_block_t = rsmi_fw_block_t(5); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_MEC2: rsmi_fw_block_t = rsmi_fw_block_t(6); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_PFP: rsmi_fw_block_t = rsmi_fw_block_t(7); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_RLC: rsmi_fw_block_t = rsmi_fw_block_t(8); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_RLC_SRLC: rsmi_fw_block_t = rsmi_fw_block_t(9); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_RLC_SRLG: rsmi_fw_block_t = rsmi_fw_block_t(10); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_RLC_SRLS: rsmi_fw_block_t = rsmi_fw_block_t(11); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_SDMA: rsmi_fw_block_t = rsmi_fw_block_t(12); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_SDMA2: rsmi_fw_block_t = rsmi_fw_block_t(13); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_SMC: rsmi_fw_block_t = rsmi_fw_block_t(14); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_SOS: rsmi_fw_block_t = rsmi_fw_block_t(15); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_TA_RAS: rsmi_fw_block_t = rsmi_fw_block_t(16); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_TA_XGMI: rsmi_fw_block_t = rsmi_fw_block_t(17); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_UVD: rsmi_fw_block_t = rsmi_fw_block_t(18); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_VCE: rsmi_fw_block_t = rsmi_fw_block_t(19); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_VCN: rsmi_fw_block_t = rsmi_fw_block_t(20); +} +impl rsmi_fw_block_t { + pub const RSMI_FW_BLOCK_LAST: rsmi_fw_block_t = rsmi_fw_block_t(20); +} +#[repr(transparent)] +#[doc = " @brief The values of this enum are used to identify the various firmware\n blocks."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_fw_block_t(pub ::std::os::raw::c_uint); +impl rsmi_xgmi_status_t { + pub const RSMI_XGMI_STATUS_NO_ERRORS: rsmi_xgmi_status_t = rsmi_xgmi_status_t(0); +} +impl rsmi_xgmi_status_t { + pub const RSMI_XGMI_STATUS_ERROR: rsmi_xgmi_status_t = rsmi_xgmi_status_t(1); +} +impl rsmi_xgmi_status_t { + pub const RSMI_XGMI_STATUS_MULTIPLE_ERRORS: rsmi_xgmi_status_t = rsmi_xgmi_status_t(2); +} +#[repr(transparent)] +#[doc = " @brief XGMI Status"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_xgmi_status_t(pub ::std::os::raw::c_uint); +#[doc = " @brief Bitfield used in various RSMI calls"] +pub type rsmi_bit_field_t = u64; +impl rsmi_memory_page_status_t { + #[doc = "!< Reserved. This gpu page is reserved\n!< and not available for use"] + pub const RSMI_MEM_PAGE_STATUS_RESERVED: rsmi_memory_page_status_t = + rsmi_memory_page_status_t(0); +} +impl rsmi_memory_page_status_t { + #[doc = "!< Pending. This gpu page is marked\n!< as bad and will be marked reserved\n!< at the next window."] + pub const RSMI_MEM_PAGE_STATUS_PENDING: rsmi_memory_page_status_t = + rsmi_memory_page_status_t(1); +} +impl rsmi_memory_page_status_t { + #[doc = "!< Unable to reserve this page"] + pub const RSMI_MEM_PAGE_STATUS_UNRESERVABLE: rsmi_memory_page_status_t = + rsmi_memory_page_status_t(2); +} +#[repr(transparent)] +#[doc = " @brief Reserved Memory Page States"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rsmi_memory_page_status_t(pub ::std::os::raw::c_uint); +impl _RSMI_IO_LINK_TYPE { + #[doc = "!< unknown type."] + pub const RSMI_IOLINK_TYPE_UNDEFINED: _RSMI_IO_LINK_TYPE = _RSMI_IO_LINK_TYPE(0); +} +impl _RSMI_IO_LINK_TYPE { + #[doc = "!< PCI Express"] + pub const RSMI_IOLINK_TYPE_PCIEXPRESS: _RSMI_IO_LINK_TYPE = _RSMI_IO_LINK_TYPE(1); +} +impl _RSMI_IO_LINK_TYPE { + #[doc = "!< XGMI"] + pub const RSMI_IOLINK_TYPE_XGMI: _RSMI_IO_LINK_TYPE = _RSMI_IO_LINK_TYPE(2); +} +impl _RSMI_IO_LINK_TYPE { + #[doc = "!< Number of IO Link types"] + pub const RSMI_IOLINK_TYPE_NUMIOLINKTYPES: _RSMI_IO_LINK_TYPE = _RSMI_IO_LINK_TYPE(3); +} +impl _RSMI_IO_LINK_TYPE { + #[doc = "!< Max of IO Link types"] + pub const RSMI_IOLINK_TYPE_SIZE: _RSMI_IO_LINK_TYPE = _RSMI_IO_LINK_TYPE(4294967295); +} +#[repr(transparent)] +#[doc = " @brief Types for IO Link"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _RSMI_IO_LINK_TYPE(pub ::std::os::raw::c_uint); +#[doc = " @brief Types for IO Link"] +pub use self::_RSMI_IO_LINK_TYPE as RSMI_IO_LINK_TYPE; +impl RSMI_UTILIZATION_COUNTER_TYPE { + pub const RSMI_UTILIZATION_COUNTER_FIRST: RSMI_UTILIZATION_COUNTER_TYPE = + RSMI_UTILIZATION_COUNTER_TYPE(0); +} +impl RSMI_UTILIZATION_COUNTER_TYPE { + pub const RSMI_COARSE_GRAIN_GFX_ACTIVITY: RSMI_UTILIZATION_COUNTER_TYPE = + RSMI_UTILIZATION_COUNTER_TYPE(0); +} +impl RSMI_UTILIZATION_COUNTER_TYPE { + #[doc = "!< Memory Activity"] + pub const RSMI_COARSE_GRAIN_MEM_ACTIVITY: RSMI_UTILIZATION_COUNTER_TYPE = + RSMI_UTILIZATION_COUNTER_TYPE(1); +} +impl RSMI_UTILIZATION_COUNTER_TYPE { + pub const RSMI_UTILIZATION_COUNTER_LAST: RSMI_UTILIZATION_COUNTER_TYPE = + RSMI_UTILIZATION_COUNTER_TYPE(1); +} +#[repr(transparent)] +#[doc = " @brief The utilization counter type"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct RSMI_UTILIZATION_COUNTER_TYPE(pub ::std::os::raw::c_uint); +#[doc = " @brief The utilization counter data"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_utilization_counter_t { + #[doc = "!< Utilization counter type"] + pub type_: RSMI_UTILIZATION_COUNTER_TYPE, + #[doc = "!< Utilization counter value"] + pub value: u64, +} +#[doc = " @brief Reserved Memory Page Record"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_retired_page_record_t { + #[doc = "!< Start address of page"] + pub page_address: u64, + #[doc = "!< Page size"] + pub page_size: u64, + #[doc = "!< Page \"reserved\" status"] + pub status: rsmi_memory_page_status_t, +} +#[doc = " @brief This structure contains information about which power profiles are\n supported by the system for a given device, and which power profile is\n currently active."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_power_profile_status_t { + #[doc = " Which profiles are supported by this system"] + pub available_profiles: rsmi_bit_field_t, + #[doc = " Which power profile is currently active"] + pub current: rsmi_power_profile_preset_masks_t, + #[doc = " How many power profiles are available"] + pub num_profiles: u32, +} +#[doc = " @brief This structure holds information about clock frequencies."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_frequencies_t { + #[doc = " The number of supported frequencies"] + pub num_supported: u32, + #[doc = " The current frequency index"] + pub current: u32, + #[doc = " List of frequencies.\n Only the first num_supported frequencies are valid."] + pub frequency: [u64; 32usize], +} +#[doc = " @brief This structure holds information about the possible PCIe\n bandwidths. Specifically, the possible transfer rates and their\n associated numbers of lanes are stored here."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_pcie_bandwidth_t { + #[doc = " Transfer rates (T/s) that are possible"] + pub transfer_rate: rsmi_frequencies_t, + #[doc = " List of lanes for corresponding transfer rate.\n Only the first num_supported bandwidths are valid."] + pub lanes: [u32; 32usize], +} +#[doc = " @brief This structure holds version information."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_version_t { + #[doc = "!< Major version"] + pub major: u32, + #[doc = "!< Minor version"] + pub minor: u32, + #[doc = "!< Patch, build or stepping version"] + pub patch: u32, + #[doc = "!< Build string"] + pub build: *const ::std::os::raw::c_char, +} +#[doc = " \\endcond\n**\n* @brief This structure represents a range (e.g., frequencies or voltages).\n*/"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_range_t { + #[doc = "!< Lower bound of range"] + pub lower_bound: u64, + #[doc = "!< Upper bound of range"] + pub upper_bound: u64, +} +#[doc = " @brief This structure represents a point on the frequency-voltage plane."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_od_vddc_point_t { + #[doc = "!< Frequency coordinate (in Hz)"] + pub frequency: u64, + #[doc = "!< Voltage coordinate (in mV)"] + pub voltage: u64, +} +#[doc = " @brief This structure holds 2 ::rsmi_range_t's, one for frequency and one for\n voltage. These 2 ranges indicate the range of possible values for the\n corresponding ::rsmi_od_vddc_point_t."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_freq_volt_region_t { + #[doc = "!< The frequency range for this VDDC Curve point"] + pub freq_range: rsmi_range_t, + #[doc = "!< The voltage range for this VDDC Curve point"] + pub volt_range: rsmi_range_t, +} +#[doc = " ::RSMI_NUM_VOLTAGE_CURVE_POINTS number of ::rsmi_od_vddc_point_t's"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_od_volt_curve_t { + #[doc = " Array of ::RSMI_NUM_VOLTAGE_CURVE_POINTS ::rsmi_od_vddc_point_t's that\n make up the voltage frequency curve points."] + pub vc_points: [rsmi_od_vddc_point_t; 3usize], +} +#[doc = " @brief This structure holds the frequency-voltage values for a device."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_od_volt_freq_data_t { + #[doc = "!< The current SCLK frequency range"] + pub curr_sclk_range: rsmi_range_t, + #[doc = "!< The current MCLK frequency range;\n!< (upper bound only)"] + pub curr_mclk_range: rsmi_range_t, + #[doc = "!< The range possible of SCLK values"] + pub sclk_freq_limits: rsmi_range_t, + #[doc = "!< The range possible of MCLK values"] + pub mclk_freq_limits: rsmi_range_t, + #[doc = " @brief The current voltage curve"] + pub curve: rsmi_od_volt_curve_t, + #[doc = "!< The number of voltage curve regions"] + pub num_regions: u32, +} +#[doc = " @brief Size and version information of metrics data"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct metrics_table_header_t { + #[doc = " \\cond Ignore in docs."] + pub structure_size: u16, + pub format_revision: u8, + pub content_revision: u8, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_gpu_metrics_t { + #[doc = " \\cond Ignore in docs."] + pub common_header: metrics_table_header_t, + pub temperature_edge: u16, + pub temperature_hotspot: u16, + pub temperature_mem: u16, + pub temperature_vrgfx: u16, + pub temperature_vrsoc: u16, + pub temperature_vrmem: u16, + pub average_gfx_activity: u16, + pub average_umc_activity: u16, + pub average_mm_activity: u16, + pub average_socket_power: u16, + pub energy_accumulator: u64, + pub system_clock_counter: u64, + pub average_gfxclk_frequency: u16, + pub average_socclk_frequency: u16, + pub average_uclk_frequency: u16, + pub average_vclk0_frequency: u16, + pub average_dclk0_frequency: u16, + pub average_vclk1_frequency: u16, + pub average_dclk1_frequency: u16, + pub current_gfxclk: u16, + pub current_socclk: u16, + pub current_uclk: u16, + pub current_vclk0: u16, + pub current_dclk0: u16, + pub current_vclk1: u16, + pub current_dclk1: u16, + pub throttle_status: u32, + pub current_fan_speed: u16, + pub pcie_link_width: u16, + pub pcie_link_speed: u16, + pub padding: u16, + pub gfx_activity_acc: u32, + pub mem_actvity_acc: u32, + pub temperature_hbm: [u16; 4usize], +} +#[doc = " @brief This structure holds error counts."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_error_count_t { + #[doc = "!< Accumulated correctable errors"] + pub correctable_err: u64, + #[doc = "!< Accumulated uncorrectable errors"] + pub uncorrectable_err: u64, +} +#[doc = " @brief This structure contains information specific to a process."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_process_info_t { + #[doc = "!< Process ID"] + pub process_id: u32, + #[doc = "!< PASID"] + pub pasid: u32, + #[doc = "!< VRAM usage"] + pub vram_usage: u64, + #[doc = "!< SDMA usage in microseconds"] + pub sdma_usage: u64, + #[doc = "!< Compute Unit usage in percent"] + pub cu_occupancy: u32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rsmi_func_id_iter_handle { + _unused: [u8; 0], +} +#[doc = " @brief Opaque handle to function-support object"] +pub type rsmi_func_id_iter_handle_t = *mut rsmi_func_id_iter_handle; +#[doc = " @brief This union holds the value of an ::rsmi_func_id_iter_handle_t. The\n value may be a function name, or an ennumerated variant value of types\n such as ::rsmi_memory_type_t, ::rsmi_temperature_metric_t, etc."] +#[repr(C)] +#[derive(Copy, Clone)] +pub union id { + #[doc = "!< uint64_t representation of value"] + pub id: u64, + #[doc = "!< name string (applicable to functions only)"] + pub name: *const ::std::os::raw::c_char, + pub __bindgen_anon_1: id__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union id__bindgen_ty_1 { + pub memory_type: rsmi_memory_type_t, + pub temp_metric: rsmi_temperature_metric_t, + pub evnt_type: rsmi_event_type_t, + pub evnt_group: rsmi_event_group_t, + pub clk_type: rsmi_clk_type_t, + pub fw_block: rsmi_fw_block_t, + pub gpu_block_type: rsmi_gpu_block_t, +} +#[doc = " @brief This union holds the value of an ::rsmi_func_id_iter_handle_t. The\n value may be a function name, or an ennumerated variant value of types\n such as ::rsmi_memory_type_t, ::rsmi_temperature_metric_t, etc."] +pub type rsmi_func_id_value_t = id; +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup InitShutAdmin Initialization and Shutdown\n These functions are used for initialization of ROCm SMI and clean up when\n done.\n @{\n/\n/**\n @brief Initialize ROCm SMI.\n\n @details When called, this initializes internal data structures,\n including those corresponding to sources of information that SMI provides.\n\n @param[in] init_flags Bit flags that tell SMI how to initialze. Values of\n ::rsmi_init_flags_t may be OR'd together and passed through @p init_flags\n to modify how RSMI initializes.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call."] + pub fn rsmi_init(init_flags: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Shutdown ROCm SMI.\n\n @details Do any necessary clean up."] + pub fn rsmi_shut_down() -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup IDQuer Identifier Queries\n These functions provide identification information.\n @{\n/\n/**\n @brief Get the number of devices that have monitor information.\n\n @details The number of devices which have monitors is returned. Monitors\n are referenced by the index which can be between 0 and @p num_devices - 1.\n\n @param[inout] num_devices Caller provided pointer to uint32_t. Upon\n successful call, the value num_devices will contain the number of monitor\n devices.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call."] + pub fn rsmi_num_monitor_devices(num_devices: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the device id associated with the device with provided device\n index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p id,\n this function will write the device id value to the uint64_t pointed to by\n @p id. This ID is an identification of the type of device, so calling this\n function for different devices will give the same value if they are kind\n of device. Consequently, this function should not be used to distinguish\n one device from another. rsmi_dev_pci_id_get() should be used to get a\n unique identifier.\n\n @param[in] dv_ind a device index\n\n @param[inout] id a pointer to uint64_t to which the device id will be\n written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_id_get(dv_ind: u32, id: *mut u16) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the SKU for a desired device associated with the device with\n provided device index.\n\n @details Given a device index @p dv_ind and a pointer to a char @p sku,\n this function will attempt to obtain the SKU from the Product Information\n FRU chip, present on server ASICs. It will write the sku value to the\n char array pointed to by @p sku.\n\n @param[in] dv_ind a device index\n\n @param[inout] sku a pointer to char to which the sku will be written\n\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_sku_get(dv_ind: u32, sku: *mut ::std::os::raw::c_char) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the device vendor id associated with the device with provided\n device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p id,\n this function will write the device vendor id value to the uint64_t pointed\n to by @p id.\n\n @param[in] dv_ind a device index\n\n @param[inout] id a pointer to uint64_t to which the device vendor id will\n be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_vendor_id_get(dv_ind: u32, id: *mut u16) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the name string of a gpu device.\n\n @details Given a device index @p dv_ind, a pointer to a caller provided\n char buffer @p name, and a length of this buffer @p len, this function\n will write the name of the device (up to @p len characters) to the buffer\n @p name.\n\n If the integer ID associated with the device is not found in one of the\n system files containing device name information (e.g.\n /usr/share/misc/pci.ids), then this function will return the hex device ID\n as a string. Updating the system name files can be accompplished with\n \"sudo update-pciids\".\n\n @param[in] dv_ind a device index\n\n @param[inout] name a pointer to a caller provided char buffer to which the\n name will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len the length of the caller provided buffer @p name.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written.\n"] + pub fn rsmi_dev_name_get( + dv_ind: u32, + name: *mut ::std::os::raw::c_char, + len: usize, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the brand string of a gpu device.\n\n @details Given a device index @p dv_ind, a pointer to a caller provided\n char buffer @p brand, and a length of this buffer @p len, this function\n will write the brand of the device (up to @p len characters) to the buffer\n @p brand.\n\n If the sku associated with the device is not found as one of the values\n contained within rsmi_dev_brand_get, then this function will return the\n device marketing name as a string instead of the brand name.\n\n @param[in] dv_ind a device index\n\n @param[inout] brand a pointer to a caller provided char buffer to which the\n brand will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len the length of the caller provided buffer @p brand.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written.\n"] + pub fn rsmi_dev_brand_get( + dv_ind: u32, + brand: *mut ::std::os::raw::c_char, + len: u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the name string for a give vendor ID\n\n @details Given a device index @p dv_ind, a pointer to a caller provided\n char buffer @p name, and a length of this buffer @p len, this function will\n write the name of the vendor (up to @p len characters) buffer @p name. The\n @p id may be a device vendor or subsystem vendor ID.\n\n If the integer ID associated with the vendor is not found in one of the\n system files containing device name information (e.g.\n /usr/share/misc/pci.ids), then this function will return the hex vendor ID\n as a string. Updating the system name files can be accompplished with\n \"sudo update-pciids\".\n\n @param[in] dv_ind a device index\n\n @param[inout] name a pointer to a caller provided char buffer to which the\n name will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len the length of the caller provided buffer @p name.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written.\n"] + pub fn rsmi_dev_vendor_name_get( + dv_ind: u32, + name: *mut ::std::os::raw::c_char, + len: usize, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the vram vendor string of a gpu device.\n\n @details Given a device index @p dv_ind, a pointer to a caller provided\n char buffer @p brand, and a length of this buffer @p len, this function\n will write the vram vendor of the device (up to @p len characters) to the\n buffer @p brand.\n\n If the vram vendor for the device is not found as one of the values\n contained within rsmi_dev_vram_vendor_get, then this function will return\n the string 'unknown' instead of the vram vendor.\n\n @param[in] dv_ind a device index\n\n @param[inout] brand a pointer to a caller provided char buffer to which the\n vram vendor will be written\n\n @param[in] len the length of the caller provided buffer @p brand.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_vram_vendor_get( + dv_ind: u32, + brand: *mut ::std::os::raw::c_char, + len: u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the serial number string for a device\n\n @details Given a device index @p dv_ind, a pointer to a buffer of chars\n @p serial_num, and the length of the provided buffer @p len, this function\n will write the serial number string (up to @p len characters) to the buffer\n pointed to by @p serial_num.\n\n @param[in] dv_ind a device index\n\n @param[inout] serial_num a pointer to caller-provided memory to which the\n serial number will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len the length of the caller provided buffer @p serial_num.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written.\n"] + pub fn rsmi_dev_serial_number_get( + dv_ind: u32, + serial_num: *mut ::std::os::raw::c_char, + len: u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the subsystem device id associated with the device with\n provided device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p id,\n this function will write the subsystem device id value to the uint64_t\n pointed to by @p id.\n\n @param[in] dv_ind a device index\n\n @param[inout] id a pointer to uint64_t to which the subsystem device id\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_subsystem_id_get(dv_ind: u32, id: *mut u16) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the name string for the device subsytem\n\n @details Given a device index @p dv_ind, a pointer to a caller provided\n char buffer @p name, and a length of this buffer @p len, this function\n will write the name of the device subsystem (up to @p len characters)\n to the buffer @p name.\n\n If the integer ID associated with the sub-system is not found in one of the\n system files containing device name information (e.g.\n /usr/share/misc/pci.ids), then this function will return the hex sub-system\n ID as a string. Updating the system name files can be accompplished with\n \"sudo update-pciids\".\n\n @param[in] dv_ind a device index\n\n @param[inout] name a pointer to a caller provided char buffer to which the\n name will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len the length of the caller provided buffer @p name.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written.\n"] + pub fn rsmi_dev_subsystem_name_get( + dv_ind: u32, + name: *mut ::std::os::raw::c_char, + len: usize, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the drm minor number associated with this device\n\n @details Given a device index @p dv_ind, find its render device file\n /dev/dri/renderDN where N corresponds to its minor number.\n\n @param[in] dv_ind a device index\n\n @param[inout] minor a pointer to a uint32_t into which minor number will\n be copied\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_INIT_ERROR if failed to get minor number during\n initialization.\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_drm_render_minor_get(dv_ind: u32, minor: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the device subsystem vendor id associated with the device with\n provided device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p id,\n this function will write the device subsystem vendor id value to the\n uint64_t pointed to by @p id.\n\n @param[in] dv_ind a device index\n\n @param[inout] id a pointer to uint64_t to which the device subsystem vendor\n id will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_subsystem_vendor_id_get(dv_ind: u32, id: *mut u16) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get Unique ID\n\n @details Given a device index @p dv_ind and a pointer to a uint64_t @p\n id, this function will write the unique ID of the GPU pointed to @p\n id.\n\n @param[in] dv_ind a device index\n\n @param[inout] id a pointer to uint64_t to which the unique ID of the GPU\n is written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_unique_id_get(dv_ind: u32, id: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup PCIeQuer PCIe Queries\n These functions provide information about PCIe.\n @{\n/\n/**\n @brief Get the list of possible PCIe bandwidths that are available.\n\n @details Given a device index @p dv_ind and a pointer to a to an\n ::rsmi_pcie_bandwidth_t structure @p bandwidth, this function will fill in\n @p bandwidth with the possible T/s values and associated number of lanes,\n and indication of the current selection.\n\n @param[in] dv_ind a device index\n\n @param[inout] bandwidth a pointer to a caller provided\n ::rsmi_pcie_bandwidth_t structure to which the frequency information will be\n written\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_pci_bandwidth_get( + dv_ind: u32, + bandwidth: *mut rsmi_pcie_bandwidth_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the unique PCI device identifier associated for a device\n\n @details Give a device index @p dv_ind and a pointer to a uint64_t @p\n bdfid, this function will write the Bus/Device/Function PCI identifier\n (BDFID) associated with device @p dv_ind to the value pointed to by\n @p bdfid.\n\n The format of @p bdfid will be as follows:\n\n BDFID = ((DOMAIN & 0xffffffff) << 32) | ((BUS & 0xff) << 8) |\n ((DEVICE & 0x1f) <<3 ) | (FUNCTION & 0x7)\n\n | Name | Field |\n ---------- | ------- |\n | Domain | [64:32] |\n | Reserved | [31:16] |\n | Bus | [15: 8] |\n | Device | [ 7: 3] |\n | Function | [ 2: 0] |\n\n @param[in] dv_ind a device index\n\n @param[inout] bdfid a pointer to uint64_t to which the device bdfid value\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_pci_id_get(dv_ind: u32, bdfid: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the NUMA node associated with a device\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p\n numa_node, this function will retrieve the NUMA node value associated\n with device @p dv_ind and store the value at location pointed to by\n @p numa_node.\n\n @param[in] dv_ind a device index\n\n @param[inout] numa_node pointer to location where NUMA node value will\n be written.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_topo_numa_affinity_get(dv_ind: u32, numa_node: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get PCIe traffic information\n\n @details Give a device index @p dv_ind and pointers to a uint64_t's, @p\n sent, @p received and @p max_pkt_sz, this function will write the number\n of bytes sent and received in 1 second to @p sent and @p received,\n respectively. The maximum possible packet size will be written to\n @p max_pkt_sz.\n\n @param[in] dv_ind a device index\n\n @param[inout] sent a pointer to uint64_t to which the number of bytes sent\n will be written in 1 second. If pointer is NULL, it will be ignored.\n\n @param[inout] received a pointer to uint64_t to which the number of bytes\n received will be written. If pointer is NULL, it will be ignored.\n\n @param[inout] max_pkt_sz a pointer to uint64_t to which the maximum packet\n size will be written. If pointer is NULL, it will be ignored.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments"] + pub fn rsmi_dev_pci_throughput_get( + dv_ind: u32, + sent: *mut u64, + received: *mut u64, + max_pkt_sz: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get PCIe replay counter\n\n @details Given a device index @p dv_ind and a pointer to a uint64_t @p\n counter, this function will write the sum of the number of NAK's received\n by the GPU and the NAK's generated by the GPU to memory pointed to by @p\n counter.\n\n @param[in] dv_ind a device index\n\n @param[inout] counter a pointer to uint64_t to which the sum of the NAK's\n received and generated by the GPU is written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_pci_replay_counter_get(dv_ind: u32, counter: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Control the set of allowed PCIe bandwidths that can be used.\n\n @details Given a device index @p dv_ind and a 64 bit bitmask @p bw_bitmask,\n this function will limit the set of allowable bandwidths. If a bit in @p\n bw_bitmask has a value of 1, then the frequency (as ordered in an\n ::rsmi_frequencies_t returned by ::rsmi_dev_gpu_clk_freq_get()) corresponding\n to that bit index will be allowed.\n\n This function will change the performance level to\n ::RSMI_DEV_PERF_LEVEL_MANUAL in order to modify the set of allowable\n band_widths. Caller will need to set to ::RSMI_DEV_PERF_LEVEL_AUTO in order\n to get back to default state.\n\n All bits with indices greater than or equal to the value of the\n ::rsmi_frequencies_t::num_supported field of ::rsmi_pcie_bandwidth_t will be\n ignored.\n\n @param[in] dv_ind a device index\n\n @param[in] bw_bitmask A bitmask indicating the indices of the\n bandwidths that are to be enabled (1) and disabled (0). Only the lowest\n ::rsmi_frequencies_t::num_supported (of ::rsmi_pcie_bandwidth_t) bits of\n this mask are relevant.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_pci_bandwidth_set(dv_ind: u32, bw_bitmask: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup PowerQuer Power Queries\n These functions provide information about power usage.\n @{\n/\n/**\n @brief Get the average power consumption of the device with provided\n device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint64_t\n @p power, this function will write the current average power consumption\n (in microwatts) to the uint64_t pointed to by @p power.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] power a pointer to uint64_t to which the average power\n consumption will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_power_ave_get(dv_ind: u32, sensor_ind: u32, power: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the energy accumulator counter of the device with provided\n device index.\n\n @details Given a device index @p dv_ind, a pointer to a uint64_t\n @p power, and a pointer to a uint64_t @p timestamp, this function will write\n amount of energy consumed to the uint64_t pointed to by @p power,\n and the timestamp to the uint64_t pointed to by @p timestamp.\n The rsmi_dev_power_ave_get() is an average of a short time. This function\n accumulates all energy consumed.\n\n @param[in] dv_ind a device index\n @param[inout] counter_resolution resolution of the counter @p power in\n micro Joules\n\n @param[inout] power a pointer to uint64_t to which the energy\n counter will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[inout] timestamp a pointer to uint64_t to which the timestamp\n will be written. Resolution: 1 ns.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_energy_count_get( + dv_ind: u32, + power: *mut u64, + counter_resolution: *mut f32, + timestamp: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the cap on power which, when reached, causes the system to take\n action to reduce power.\n\n @details When power use rises above the value @p power, the system will\n take action to reduce power use. The power level returned through\n @p power will be in microWatts.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] cap a pointer to a uint64_t that indicates the power cap,\n in microwatts\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_power_cap_get(dv_ind: u32, sensor_ind: u32, cap: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the default power cap for the device specified by @p dv_ind.\n\n @details The maximum power cap be temporarily changed by the user. However,\n this function always returns the default reset power cap. The power level\n returned through @p power will be in microWatts.\n\n @param[in] dv_ind a device index\n\n @param[inout] default_cap a pointer to a uint64_t that indicates the default\n power cap, in microwatts\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_power_cap_default_get(dv_ind: u32, default_cap: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the range of valid values for the power cap\n\n @details This function will return the maximum possible valid power cap\n @p max and the minimum possible valid power cap @p min\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] max a pointer to a uint64_t that indicates the maximum\n possible power cap, in microwatts\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[inout] min a pointer to a uint64_t that indicates the minimum\n possible power cap, in microwatts\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_power_cap_range_get( + dv_ind: u32, + sensor_ind: u32, + max: *mut u64, + min: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup PowerCont Power Control\n These functions provide ways to control power usage.\n @{\n/\n/**\n @brief Set the power cap value\n\n @details This function will set the power cap to the provided value @p cap.\n @p cap must be between the minimum and maximum power cap values set by the\n system, which can be obtained from ::rsmi_dev_power_cap_range_get.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[in] cap a uint64_t that indicates the desired power cap, in\n microwatts\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_power_cap_set(dv_ind: u32, sensor_ind: u32, cap: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the power profile\n\n @details Given a device index @p dv_ind and a @p profile, this function will\n attempt to set the current profile to the provided profile. The provided\n profile must be one of the currently supported profiles, as indicated by a\n call to ::rsmi_dev_power_profile_presets_get()\n\n @param[in] dv_ind a device index\n\n @param[in] reserved Not currently used. Set to 0.\n\n @param[in] profile a ::rsmi_power_profile_preset_masks_t that hold the mask\n of the desired new power profile\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_power_profile_set( + dv_ind: u32, + reserved: u32, + profile: rsmi_power_profile_preset_masks_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the total amount of memory that exists\n\n @details Given a device index @p dv_ind, a type of memory @p mem_type, and\n a pointer to a uint64_t @p total, this function will write the total amount\n of @p mem_type memory that exists to the location pointed to by @p total.\n\n @param[in] dv_ind a device index\n\n @param[in] mem_type The type of memory for which the total amount will be\n found\n\n @param[inout] total a pointer to uint64_t to which the total amount of\n memory will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_memory_total_get( + dv_ind: u32, + mem_type: rsmi_memory_type_t, + total: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the current memory usage\n\n @details Given a device index @p dv_ind, a type of memory @p mem_type, and\n a pointer to a uint64_t @p usage, this function will write the amount of\n @p mem_type memory that that is currently being used to the location\n pointed to by @p used.\n\n @param[in] dv_ind a device index\n\n @param[in] mem_type The type of memory for which the amount being used will\n be found\n\n @param[inout] used a pointer to uint64_t to which the amount of memory\n currently being used will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_memory_usage_get( + dv_ind: u32, + mem_type: rsmi_memory_type_t, + used: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get percentage of time any device memory is being used\n\n @details Given a device index @p dv_ind, this function returns the\n percentage of time that any device memory is being used for the specified\n device.\n\n @param[in] dv_ind a device index\n\n @param[inout] busy_percent a pointer to the uint32_t to which the busy\n percent will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_memory_busy_percent_get(dv_ind: u32, busy_percent: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get information about reserved (\"retired\") memory pages\n\n @details Given a device index @p dv_ind, this function returns retired page\n information @p records corresponding to the device with the provided device\n index @p dv_ind. The number of retired page records is returned through @p\n num_pages. @p records may be NULL on input. In this case, the number of\n records available for retrieval will be returned through @p num_pages.\n\n @param[in] dv_ind a device index\n\n @param[inout] num_pages a pointer to a uint32. As input, the value passed\n through this parameter is the number of ::rsmi_retired_page_record_t's that\n may be safely written to the memory pointed to by @p records. This is the\n limit on how many records will be written to @p records. On return, @p\n num_pages will contain the number of records written to @p records, or the\n number of records that could have been written if enough memory had been\n provided.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[inout] records A pointer to a block of memory to which the\n ::rsmi_retired_page_record_t values will be written. This value may be NULL.\n In this case, this function can be used to query how many records are\n available to read.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if more records were available\n than allowed by the provided, allocated memory."] + pub fn rsmi_dev_memory_reserved_pages_get( + dv_ind: u32, + num_pages: *mut u32, + records: *mut rsmi_retired_page_record_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @defgroup PhysQuer Physical State Queries\n These functions provide information about the physical characteristics of\n the device.\n @{\n/\n/**\n @brief Get the fan speed in RPMs of the device with the specified device\n index and 0-based sensor index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t\n @p speed, this function will write the current fan speed in RPMs to the\n uint32_t pointed to by @p speed\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] speed a pointer to uint32_t to which the speed will be\n written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_fan_rpms_get(dv_ind: u32, sensor_ind: u32, speed: *mut i64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the fan speed for the specified device as a value relative to\n ::RSMI_MAX_FAN_SPEED\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t\n @p speed, this function will write the current fan speed (a value\n between 0 and the maximum fan speed, ::RSMI_MAX_FAN_SPEED) to the uint32_t\n pointed to by @p speed\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] speed a pointer to uint32_t to which the speed will be\n written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_fan_speed_get(dv_ind: u32, sensor_ind: u32, speed: *mut i64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the max. fan speed of the device with provided device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t\n @p max_speed, this function will write the maximum fan speed possible to\n the uint32_t pointed to by @p max_speed\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] max_speed a pointer to uint32_t to which the maximum speed\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_fan_speed_max_get( + dv_ind: u32, + sensor_ind: u32, + max_speed: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the temperature metric value for the specified metric, from the\n specified temperature sensor on the specified device.\n\n @details Given a device index @p dv_ind, a sensor type @p sensor_type, a\n ::rsmi_temperature_metric_t @p metric and a pointer to an int64_t @p\n temperature, this function will write the value of the metric indicated by\n @p metric and @p sensor_type to the memory location @p temperature.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_type part of device from which temperature should be\n obtained. This should come from the enum ::rsmi_temperature_type_t\n\n @param[in] metric enum indicated which temperature value should be\n retrieved\n\n @param[inout] temperature a pointer to int64_t to which the temperature\n will be written, in millidegrees Celcius.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_temp_metric_get( + dv_ind: u32, + sensor_type: u32, + metric: rsmi_temperature_metric_t, + temperature: *mut i64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the voltage metric value for the specified metric, from the\n specified voltage sensor on the specified device.\n\n @details Given a device index @p dv_ind, a sensor type @p sensor_type, a\n ::rsmi_voltage_metric_t @p metric and a pointer to an int64_t @p\n voltage, this function will write the value of the metric indicated by\n @p metric and @p sensor_type to the memory location @p voltage.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_type part of device from which voltage should be\n obtained. This should come from the enum ::rsmi_voltage_type_t\n\n @param[in] metric enum indicated which voltage value should be\n retrieved\n\n @param[inout] voltage a pointer to int64_t to which the voltage\n will be written, in millivolts.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_volt_metric_get( + dv_ind: u32, + sensor_type: rsmi_voltage_type_t, + metric: rsmi_voltage_metric_t, + voltage: *mut i64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = "/\n/** @defgroup PhysCont Physical State Control\n These functions provide control over the physical state of a device.\n @{\n/\n/**\n @brief Reset the fan to automatic driver control\n\n @details This function returns control of the fan to the system\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n"] + pub fn rsmi_dev_fan_reset(dv_ind: u32, sensor_ind: u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the fan speed for the specified device with the provided speed,\n in RPMs.\n\n @details Given a device index @p dv_ind and a integer value indicating\n speed @p speed, this function will attempt to set the fan speed to @p speed.\n An error will be returned if the specified speed is outside the allowable\n range for the device. The maximum value is 255 and the minimum is 0.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[in] speed the speed to which the function will attempt to set the fan\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_fan_speed_set(dv_ind: u32, sensor_ind: u32, speed: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get percentage of time device is busy doing any processing\n\n @details Given a device index @p dv_ind, this function returns the\n percentage of time that the specified device is busy. The device is\n considered busy if any one or more of its sub-blocks are working, and idle\n if none of the sub-blocks are working.\n\n @param[in] dv_ind a device index\n\n @param[inout] busy_percent a pointer to the uint32_t to which the busy\n percent will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_busy_percent_get(dv_ind: u32, busy_percent: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get coarse grain utilization counter of the specified device\n\n @details Given a device index @p dv_ind, the array of the utilization counters,\n the size of the array, this function returns the coarse grain utilization counters\n and timestamp.\n The counter is the accumulated percentages. Every milliseconds the firmware calculates\n % busy count and then accumulates that value in the counter. This provides minimally\n invasive coarse grain GPU usage information.\n\n @param[in] dv_ind a device index\n\n @param[inout] utilization_counters Multiple utilization counters can be retreived with a single\n call. The caller must allocate enough space to the utilization_counters array. The caller also\n needs to set valid RSMI_UTILIZATION_COUNTER_TYPE type for each element of the array.\n ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the provided arguments.\n\n If the function reutrns RSMI_STATUS_SUCCESS, the counter will be set in the value field of\n the rsmi_utilization_counter_t.\n\n @param[in] count The size of @utilization_counters array.\n\n @param[inout] timestamp The timestamp when the counter is retreived. Resolution: 1 ns.\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_utilization_count_get( + dv_ind: u32, + utilization_counters: *mut rsmi_utilization_counter_t, + count: u32, + timestamp: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the performance level of the device with provided\n device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p\n perf, this function will write the ::rsmi_dev_perf_level_t to the uint32_t\n pointed to by @p perf\n\n @param[in] dv_ind a device index\n\n @param[inout] perf a pointer to ::rsmi_dev_perf_level_t to which the\n performance level will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_perf_level_get(dv_ind: u32, perf: *mut rsmi_dev_perf_level_t) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Enter performance determinism mode with provided device index.\n\n @details Given a device index @p dv_ind and @p clkvalue this function\n will enable performance determinism mode, which enforces a GFXCLK frequency\n SoftMax limit per GPU set by the user. This prevents the GFXCLK PLL from\n stretching when running the same workload on different GPUS, making\n performance variation minimal. This call will result in the performance\n level ::rsmi_dev_perf_level_t of the device being\n ::RSMI_DEV_PERF_LEVEL_DETERMINISM.\n\n @param[in] dv_ind a device index\n\n @param[in] clkvalue Softmax value for GFXCLK in MHz.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_perf_determinism_mode_set(dv_ind: u32, clkvalue: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the overdrive percent associated with the device with provided\n device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p od,\n this function will write the overdrive percentage to the uint32_t pointed\n to by @p od\n\n @param[in] dv_ind a device index\n\n @param[inout] od a pointer to uint32_t to which the overdrive percentage\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_overdrive_level_get(dv_ind: u32, od: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the memory clock overdrive percent associated with the device\n with provided device index.\n\n @details Given a device index @p dv_ind and a pointer to a uint32_t @p od,\n this function will write the memory overdrive percentage to the uint32_t\n pointed to by @p od\n\n @param[in] dv_ind a device index\n\n @param[inout] od a pointer to uint32_t to which the overdrive percentage\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_mem_overdrive_level_get(dv_ind: u32, od: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the list of possible system clock speeds of device for a\n specified clock type.\n\n @details Given a device index @p dv_ind, a clock type @p clk_type, and a\n pointer to a to an ::rsmi_frequencies_t structure @p f, this function will\n fill in @p f with the possible clock speeds, and indication of the current\n clock speed selection.\n\n @param[in] dv_ind a device index\n\n @param[in] clk_type the type of clock for which the frequency is desired\n\n @param[inout] f a pointer to a caller provided ::rsmi_frequencies_t structure\n to which the frequency information will be written. Frequency values are in\n Hz.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n If multiple current frequencies are found, a warning is shown. If no\n current frequency is found, it is reflected as -1. If frequencies are not\n read from low to high a warning is shown as well.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_gpu_clk_freq_get( + dv_ind: u32, + clk_type: rsmi_clk_type_t, + f: *mut rsmi_frequencies_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reset the gpu associated with the device with provided device index\n\n @details Given a device index @p dv_ind, this function will reset the GPU\n\n @param[in] dv_ind a device index\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_gpu_reset(dv_ind: i32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function retrieves the voltage/frequency curve information\n\n @details Given a device index @p dv_ind and a pointer to a\n ::rsmi_od_volt_freq_data_t structure @p odv, this function will populate @p\n odv. See ::rsmi_od_volt_freq_data_t for more details.\n\n @param[in] dv_ind a device index\n\n @param[inout] odv a pointer to an ::rsmi_od_volt_freq_data_t structure\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_od_volt_info_get( + dv_ind: u32, + odv: *mut rsmi_od_volt_freq_data_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function retrieves the gpu metrics information\n\n @details Given a device index @p dv_ind and a pointer to a\n ::rsmi_gpu_metrics_t structure @p pgpu_metrics, this function will populate\n @p pgpu_metrics. See ::rsmi_gpu_metrics_t for more details.\n\n @param[in] dv_ind a device index\n\n @param[inout] pgpu_metrics a pointer to an ::rsmi_gpu_metrics_t structure\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_gpu_metrics_info_get( + dv_ind: u32, + pgpu_metrics: *mut rsmi_gpu_metrics_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function sets the clock range information\n\n @details Given a device index @p dv_ind, a minimum clock value @p minclkvalue,\n a maximum clock value @p maxclkvalue and a clock type @p clkType this function\n will set the sclk|mclk range\n\n @param[in] dv_ind a device index\n\n @param[in] minclkvalue value to apply to the clock range. Frequency values\n are in MHz.\n\n @param[in] maxclkvalue value to apply to the clock range. Frequency values\n are in MHz.\n\n @param[in] clkType RSMI_CLK_TYPE_SYS | RSMI_CLK_TYPE_MEM range type\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_clk_range_set( + dv_ind: u32, + minclkvalue: u64, + maxclkvalue: u64, + clkType: rsmi_clk_type_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function sets the clock frequency information\n\n @details Given a device index @p dv_ind, a frequency level @p level,\n a clock value @p clkvalue and a clock type @p clkType this function\n will set the sclk|mclk range\n\n @param[in] dv_ind a device index\n\n @param[in] level RSMI_FREQ_IND_MIN|RSMI_FREQ_IND_MAX to set the\n minimum (0) or maximum (1) speed.\n\n @param[in] clkvalue value to apply to the clock range. Frequency values\n are in MHz.\n\n @param[in] clkType RSMI_CLK_TYPE_SYS | RSMI_CLK_TYPE_MEM range type\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_od_clk_info_set( + dv_ind: u32, + level: rsmi_freq_ind_t, + clkvalue: u64, + clkType: rsmi_clk_type_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function sets 1 of the 3 voltage curve points.\n\n @details Given a device index @p dv_ind, a voltage point @p vpoint\n and a voltage value @p voltvalue this function will set voltage curve point\n\n @param[in] dv_ind a device index\n\n @param[in] vpoint voltage point [0|1|2] on the voltage curve\n\n @param[in] clkvalue clock value component of voltage curve point.\n Frequency values are in MHz.\n\n @param[in] voltvalue voltage value component of voltage curve point.\n Voltage is in mV.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_od_volt_info_set( + dv_ind: u32, + vpoint: u32, + clkvalue: u64, + voltvalue: u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief This function will retrieve the current valid regions in the\n frequency/voltage space.\n\n @details Given a device index @p dv_ind, a pointer to an unsigned integer\n @p num_regions and a buffer of ::rsmi_freq_volt_region_t structures, @p\n buffer, this function will populate @p buffer with the current\n frequency-volt space regions. The caller should assign @p buffer to memory\n that can be written to by this function. The caller should also\n indicate the number of ::rsmi_freq_volt_region_t structures that can safely\n be written to @p buffer in @p num_regions.\n\n The number of regions to expect this function provide (@p num_regions) can\n be obtained by calling ::rsmi_dev_od_volt_info_get().\n\n @param[in] dv_ind a device index\n\n @param[inout] num_regions As input, this is the number of\n ::rsmi_freq_volt_region_t structures that can be written to @p buffer. As\n output, this is the number of ::rsmi_freq_volt_region_t structures that were\n actually written.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[inout] buffer a caller provided buffer to which\n ::rsmi_freq_volt_region_t structures will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_od_volt_curve_regions_get( + dv_ind: u32, + num_regions: *mut u32, + buffer: *mut rsmi_freq_volt_region_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the list of available preset power profiles and an indication of\n which profile is currently active.\n\n @details Given a device index @p dv_ind and a pointer to a\n ::rsmi_power_profile_status_t @p status, this function will set the bits of\n the ::rsmi_power_profile_status_t.available_profiles bit field of @p status to\n 1 if the profile corresponding to the respective\n ::rsmi_power_profile_preset_masks_t profiles are enabled. For example, if both\n the VIDEO and VR power profiles are available selections, then\n ::RSMI_PWR_PROF_PRST_VIDEO_MASK AND'ed with\n ::rsmi_power_profile_status_t.available_profiles will be non-zero as will\n ::RSMI_PWR_PROF_PRST_VR_MASK AND'ed with\n ::rsmi_power_profile_status_t.available_profiles. Additionally,\n ::rsmi_power_profile_status_t.current will be set to the\n ::rsmi_power_profile_preset_masks_t of the profile that is currently active.\n\n @param[in] dv_ind a device index\n\n @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.\n If a device has more than one sensor, it could be greater than 0.\n\n @param[inout] status a pointer to ::rsmi_power_profile_status_t that will be\n populated by a call to this function\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_power_profile_presets_get( + dv_ind: u32, + sensor_ind: u32, + status: *mut rsmi_power_profile_status_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @defgroup PerfCont Clock, Power and Performance Control\n These functions provide control over clock frequencies, power and\n performance.\n @{\n/\n/**\n @brief Set the PowerPlay performance level associated with the device with\n provided device index with the provided value.\n\n @deprecated ::rsmi_dev_perf_level_set_v1() is preferred, with an\n interface that more closely matches the rest of the rocm_smi API.\n\n @details Given a device index @p dv_ind and an ::rsmi_dev_perf_level_t @p\n perf_level, this function will set the PowerPlay performance level for the\n device to the value @p perf_lvl.\n\n @param[in] dv_ind a device index\n\n @param[in] perf_lvl the value to which the performance level should be set\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_perf_level_set(dv_ind: i32, perf_lvl: rsmi_dev_perf_level_t) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the PowerPlay performance level associated with the device with\n provided device index with the provided value.\n\n @details Given a device index @p dv_ind and an ::rsmi_dev_perf_level_t @p\n perf_level, this function will set the PowerPlay performance level for the\n device to the value @p perf_lvl.\n\n @param[in] dv_ind a device index\n\n @param[in] perf_lvl the value to which the performance level should be set\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_perf_level_set_v1( + dv_ind: u32, + perf_lvl: rsmi_dev_perf_level_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the overdrive percent associated with the device with provided\n device index with the provided value. See details for WARNING.\n\n @deprecated This function is deprecated. ::rsmi_dev_overdrive_level_set_v1\n has the same functionaltiy, with an interface that more closely\n matches the rest of the rocm_smi API.\n\n @details Given a device index @p dv_ind and an overdrive level @p od,\n this function will set the overdrive level for the device to the value\n @p od. The overdrive level is an integer value between 0 and 20, inclusive,\n which represents the overdrive percentage; e.g., a value of 5 specifies\n an overclocking of 5%.\n\n The overdrive level is specific to the gpu system clock.\n\n The overdrive level is the percentage above the maximum Performance Level\n to which overclocking will be limited. The overclocking percentage does\n not apply to clock speeds other than the maximum. This percentage is\n limited to 20%.\n\n ******WARNING******\n Operating your AMD GPU outside of official AMD specifications or outside of\n factory settings, including but not limited to the conducting of\n overclocking (including use of this overclocking software, even if such\n software has been directly or indirectly provided by AMD or otherwise\n affiliated in any way with AMD), may cause damage to your AMD GPU, system\n components and/or result in system failure, as well as cause other problems.\n DAMAGES CAUSED BY USE OF YOUR AMD GPU OUTSIDE OF OFFICIAL AMD SPECIFICATIONS\n OR OUTSIDE OF FACTORY SETTINGS ARE NOT COVERED UNDER ANY AMD PRODUCT\n WARRANTY AND MAY NOT BE COVERED BY YOUR BOARD OR SYSTEM MANUFACTURER'S\n WARRANTY. Please use this utility with caution.\n\n @param[in] dv_ind a device index\n\n @param[in] od the value to which the overdrive level should be set\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_overdrive_level_set(dv_ind: i32, od: u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Set the overdrive percent associated with the device with provided\n device index with the provided value. See details for WARNING.\n\n @details Given a device index @p dv_ind and an overdrive level @p od,\n this function will set the overdrive level for the device to the value\n @p od. The overdrive level is an integer value between 0 and 20, inclusive,\n which represents the overdrive percentage; e.g., a value of 5 specifies\n an overclocking of 5%.\n\n The overdrive level is specific to the gpu system clock.\n\n The overdrive level is the percentage above the maximum Performance Level\n to which overclocking will be limited. The overclocking percentage does\n not apply to clock speeds other than the maximum. This percentage is\n limited to 20%.\n\n ******WARNING******\n Operating your AMD GPU outside of official AMD specifications or outside of\n factory settings, including but not limited to the conducting of\n overclocking (including use of this overclocking software, even if such\n software has been directly or indirectly provided by AMD or otherwise\n affiliated in any way with AMD), may cause damage to your AMD GPU, system\n components and/or result in system failure, as well as cause other problems.\n DAMAGES CAUSED BY USE OF YOUR AMD GPU OUTSIDE OF OFFICIAL AMD SPECIFICATIONS\n OR OUTSIDE OF FACTORY SETTINGS ARE NOT COVERED UNDER ANY AMD PRODUCT\n WARRANTY AND MAY NOT BE COVERED BY YOUR BOARD OR SYSTEM MANUFACTURER'S\n WARRANTY. Please use this utility with caution.\n\n @param[in] dv_ind a device index\n\n @param[in] od the value to which the overdrive level should be set\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_overdrive_level_set_v1(dv_ind: u32, od: u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Control the set of allowed frequencies that can be used for the\n specified clock.\n\n @details Given a device index @p dv_ind, a clock type @p clk_type, and a\n 64 bit bitmask @p freq_bitmask, this function will limit the set of\n allowable frequencies. If a bit in @p freq_bitmask has a value of 1, then\n the frequency (as ordered in an ::rsmi_frequencies_t returned by\n rsmi_dev_gpu_clk_freq_get()) corresponding to that bit index will be\n allowed.\n\n This function will change the performance level to\n ::RSMI_DEV_PERF_LEVEL_MANUAL in order to modify the set of allowable\n frequencies. Caller will need to set to ::RSMI_DEV_PERF_LEVEL_AUTO in order\n to get back to default state.\n\n All bits with indices greater than or equal to\n ::rsmi_frequencies_t::num_supported will be ignored.\n\n @param[in] dv_ind a device index\n\n @param[in] clk_type the type of clock for which the set of frequencies\n will be modified\n\n @param[in] freq_bitmask A bitmask indicating the indices of the\n frequencies that are to be enabled (1) and disabled (0). Only the lowest\n ::rsmi_frequencies_t.num_supported bits of this mask are relevant.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_gpu_clk_freq_set( + dv_ind: u32, + clk_type: rsmi_clk_type_t, + freq_bitmask: u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the build version information for the currently running build of\n RSMI.\n\n @details Get the major, minor, patch and build string for RSMI build\n currently in use through @p version\n\n @param[inout] version A pointer to an ::rsmi_version_t structure that will\n be updated with the version information upon return.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n"] + pub fn rsmi_version_get(version: *mut rsmi_version_t) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the driver version string for the current system.\n\n @details Given a software component @p component, a pointer to a char\n buffer, @p ver_str, this function will write the driver version string\n (up to @p len characters) for the current system to @p ver_str. The caller\n must ensure that it is safe to write at least @p len characters to @p\n ver_str.\n\n @param[in] component The component for which the version string is being\n requested\n\n @param[inout] ver_str A pointer to a buffer of char's to which the version\n of @p component will be written\n\n @param[in] len the length of the caller provided buffer @p name.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not\n large enough to hold the entire name. In this case, only @p len bytes will\n be written."] + pub fn rsmi_version_str_get( + component: rsmi_sw_component_t, + ver_str: *mut ::std::os::raw::c_char, + len: u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the VBIOS identifer string\n\n @details Given a device ID @p dv_ind, and a pointer to a char buffer,\n @p vbios, this function will write the VBIOS string (up to @p len\n characters) for device @p dv_ind to @p vbios. The caller must ensure that\n it is safe to write at least @p len characters to @p vbios.\n\n @param[in] dv_ind a device index\n\n @param[inout] vbios A pointer to a buffer of char's to which the VBIOS name\n will be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @param[in] len The number of char's pointed to by @p vbios which can safely\n be written to by this function.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_vbios_version_get( + dv_ind: u32, + vbios: *mut ::std::os::raw::c_char, + len: u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the firmware versions for a device\n\n @details Given a device ID @p dv_ind, and a pointer to a uint64_t,\n @p fw_version, this function will write the FW Versions as a string (up to @p len\n characters) for device @p dv_ind to @p vbios. The caller must ensure that\n it is safe to write at least @p len characters to @p vbios.\n\n @param[in] dv_ind a device index\n\n @param[in] block The firmware block for which the version is being requested\n\n @param[inout] fw_version The version for the firmware block\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_firmware_version_get( + dv_ind: u32, + block: rsmi_fw_block_t, + fw_version: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the error counts for a GPU block\n\n @details Given a device index @p dv_ind, an ::rsmi_gpu_block_t @p block and a\n pointer to an ::rsmi_error_count_t @p ec, this function will write the error\n count values for the GPU block indicated by @p block to memory pointed to by\n @p ec.\n\n @param[in] dv_ind a device index\n\n @param[in] block The block for which error counts should be retrieved\n\n @param[inout] ec A pointer to an ::rsmi_error_count_t to which the error\n counts should be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_ecc_count_get( + dv_ind: u32, + block: rsmi_gpu_block_t, + ec: *mut rsmi_error_count_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the enabled ECC bit-mask\n\n @details Given a device index @p dv_ind, and a pointer to a uint64_t @p\n enabled_mask, this function will write bits to memory pointed to by\n @p enabled_blocks. Upon a successful call, @p enabled_blocks can then be\n AND'd with elements of the ::rsmi_gpu_block_t ennumeration to determine if\n the corresponding block has ECC enabled. Note that whether a block has ECC\n enabled or not in the device is independent of whether there is kernel\n support for error counting for that block. Although a block may be enabled,\n but there may not be kernel support for reading error counters for that\n block.\n\n @param[in] dv_ind a device index\n\n @param[inout] enabled_blocks A pointer to a uint64_t to which the enabled\n blocks bits will be written.\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_dev_ecc_enabled_get(dv_ind: u32, enabled_blocks: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the ECC status for a GPU block\n\n @details Given a device index @p dv_ind, an ::rsmi_gpu_block_t @p block and\n a pointer to an ::rsmi_ras_err_state_t @p state, this function will write\n the current state for the GPU block indicated by @p block to memory pointed\n to by @p state.\n\n @param[in] dv_ind a device index\n\n @param[in] block The block for which error counts should be retrieved\n\n @param[inout] state A pointer to an ::rsmi_ras_err_state_t to which the\n ECC state should be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_ecc_status_get( + dv_ind: u32, + block: rsmi_gpu_block_t, + state: *mut rsmi_ras_err_state_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get a description of a provided RSMI error status\n\n @details Set the provided pointer to a const char *, @p status_string, to\n a string containing a description of the provided error code @p status.\n\n @param[in] status The error status for which a description is desired\n\n @param[inout] status_string A pointer to a const char * which will be made\n to point to a description of the provided error code\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n"] + pub fn rsmi_status_string( + status: rsmi_status_t, + status_string: *mut *const ::std::os::raw::c_char, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Tell if an event group is supported by a given device\n\n @details Given a device index @p dv_ind and an event group specifier @p\n group, tell if @p group type events are supported by the device associated\n with @p dv_ind\n\n @param[in] dv_ind device index of device being queried\n\n @param[in] group ::rsmi_event_group_t identifier of group for which support\n is being queried\n\n @retval ::RSMI_STATUS_SUCCESS if the device associatee with @p dv_ind\n support counting events of the type indicated by @p group.\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n group\n"] + pub fn rsmi_dev_counter_group_supported( + dv_ind: u32, + group: rsmi_event_group_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Create a performance counter object\n\n @details Create a performance counter object of type @p type for the device\n with a device index of @p dv_ind, and write a handle to the object to the\n memory location pointed to by @p evnt_handle. @p evnt_handle can be used\n with other performance event operations. The handle should be deallocated\n with ::rsmi_dev_counter_destroy() when no longer needed.\n\n @param[in] dv_ind a device index\n\n @param[in] type the ::rsmi_event_type_t of performance event to create\n\n @param[inout] evnt_handle A pointer to a ::rsmi_event_handle_t which will be\n associated with a newly allocated counter\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_OUT_OF_RESOURCES unable to allocate memory for counter\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_counter_create( + dv_ind: u32, + type_: rsmi_event_type_t, + evnt_handle: *mut rsmi_event_handle_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Deallocate a performance counter object\n\n @details Deallocate the performance counter object with the provided\n ::rsmi_event_handle_t @p evnt_handle\n\n @param[in] evnt_handle handle to event object to be deallocated\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_dev_counter_destroy(evnt_handle: rsmi_event_handle_t) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Issue performance counter control commands\n\n @details Issue a command @p cmd on the event counter associated with the\n provided handle @p evt_handle.\n\n @param[in] evt_handle an event handle\n\n @param[in] cmd The event counter command to be issued\n\n @param[inout] cmd_args Currently not used. Should be set to NULL.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_counter_control( + evt_handle: rsmi_event_handle_t, + cmd: rsmi_counter_command_t, + cmd_args: *mut ::std::os::raw::c_void, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Read the current value of a performance counter\n\n @details Read the current counter value of the counter associated with the\n provided handle @p evt_handle and write the value to the location pointed\n to by @p value.\n\n @param[in] evt_handle an event handle\n\n @param[inout] value pointer to memory of size of ::rsmi_counter_value_t to\n which the counter value will be written\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_PERMISSION function requires root access\n"] + pub fn rsmi_counter_read( + evt_handle: rsmi_event_handle_t, + value: *mut rsmi_counter_value_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the number of currently available counters\n\n @details Given a device index @p dv_ind, a performance event group @p grp,\n and a pointer to a uint32_t @p available, this function will write the\n number of @p grp type counters that are available on the device with index\n @p dv_ind to the memory that @p available points to.\n\n @param[in] dv_ind a device index\n\n @param[in] grp an event device group\n\n @param[inout] available A pointer to a uint32_t to which the number of\n available counters will be written\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_counter_available_counters_get( + dv_ind: u32, + grp: rsmi_event_group_t, + available: *mut u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get process information about processes currently using GPU\n\n @details Given a non-NULL pointer to an array @p procs of\n ::rsmi_process_info_t's, of length *@p num_items, this function will write\n up to *@p num_items instances of ::rsmi_process_info_t to the memory pointed\n to by @p procs. These instances contain information about each process\n utilizing a GPU. If @p procs is not NULL, @p num_items will be updated with\n the number of processes actually written. If @p procs is NULL, @p num_items\n will be updated with the number of processes for which there is current\n process information. Calling this function with @p procs being NULL is a way\n to determine how much memory should be allocated for when @p procs is not\n NULL.\n\n @param[inout] procs a pointer to memory provided by the caller to which\n process information will be written. This may be NULL in which case only @p\n num_items will be updated with the number of processes found.\n\n @param[inout] num_items A pointer to a uint32_t, which on input, should\n contain the amount of memory in ::rsmi_process_info_t's which have been\n provided by the @p procs argument. On output, if @p procs is non-NULL, this\n will be updated with the number ::rsmi_process_info_t structs actually\n written. If @p procs is NULL, this argument will be updated with the number\n processes for which there is information.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if there were more\n processes for which information was available, but not enough space was\n provided as indicated by @p procs and @p num_items, on input."] + pub fn rsmi_compute_process_info_get( + procs: *mut rsmi_process_info_t, + num_items: *mut u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get process information about a specific process\n\n @details Given a pointer to an ::rsmi_process_info_t @p proc and a process\n id\n @p pid, this function will write the process information for @p pid, if\n available, to the memory pointed to by @p proc.\n\n @param[in] pid The process ID for which process information is being\n requested\n\n @param[inout] proc a pointer to a ::rsmi_process_info_t to which\n process information for @p pid will be written if it is found.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_NOT_FOUND is returned if there was no process\n information\n found for the provided @p pid\n"] + pub fn rsmi_compute_process_info_by_pid_get( + pid: u32, + proc_: *mut rsmi_process_info_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the device indices currently being used by a process\n\n @details Given a process id @p pid, a non-NULL pointer to an array of\n uint32_t's @p dv_indices of length *@p num_devices, this function will\n write up to @p num_devices device indices to the memory pointed to by\n @p dv_indices. If @p dv_indices is not NULL, @p num_devices will be\n updated with the number of gpu's currently being used by process @p pid.\n If @p dv_indices is NULL, @p dv_indices will be updated with the number of\n gpus currently being used by @p pid. Calling this function with @p\n dv_indices being NULL is a way to determine how much memory is required\n for when @p dv_indices is not NULL.\n\n @param[in] pid The process id of the process for which the number of gpus\n currently being used is requested\n\n @param[inout] dv_indices a pointer to memory provided by the caller to\n which indices of devices currently being used by the process will be\n written. This may be NULL in which case only @p num_devices will be\n updated with the number of devices being used.\n\n @param[inout] num_devices A pointer to a uint32_t, which on input, should\n contain the amount of memory in uint32_t's which have been provided by the\n @p dv_indices argument. On output, if @p dv_indices is non-NULL, this will\n be updated with the number uint32_t's actually written. If @p dv_indices is\n NULL, this argument will be updated with the number devices being used.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if there were more\n gpu indices that could have been written, but not enough space was\n provided as indicated by @p dv_indices and @p num_devices, on input.\n"] + pub fn rsmi_compute_process_gpus_get( + pid: u32, + dv_indices: *mut u32, + num_devices: *mut u32, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the XGMI error status for a device\n\n @details Given a device index @p dv_ind, and a pointer to an\n ::rsmi_xgmi_status_t @p status, this function will write the current XGMI\n error state ::rsmi_xgmi_status_t for the device @p dv_ind to the memory\n pointed to by @p status.\n\n @param[in] dv_ind a device index\n\n @param[inout] status A pointer to an ::rsmi_xgmi_status_t to which the\n XGMI error state should be written\n If this parameter is nullptr, this function will return\n ::RSMI_STATUS_INVALID_ARGS if the function is supported with the provided,\n arguments and ::RSMI_STATUS_NOT_SUPPORTED if it is not supported with the\n provided arguments.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_xgmi_error_status( + dv_ind: u32, + status: *mut rsmi_xgmi_status_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Reset the XGMI error status for a device\n\n @details Given a device index @p dv_ind, this function will reset the\n current XGMI error state ::rsmi_xgmi_status_t for the device @p dv_ind to\n rsmi_xgmi_status_t::RSMI_XGMI_STATUS_NO_ERRORS\n\n @param[in] dv_ind a device index\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_xgmi_error_reset(dv_ind: u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the XGMI hive id for a device\n\n @details Given a device index @p dv_ind, and a pointer to an\n uint64_t @p hive_id, this function will write the current XGMI\n hive id for the device @p dv_ind to the memory pointed to by @p hive_id.\n\n @param[in] dv_ind a device index\n\n @param[inout] hive_id A pointer to an uint64_t to which the XGMI hive id\n should be written\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not\n support this function with the given arguments\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_dev_xgmi_hive_id_get(dv_ind: u32, hive_id: *mut u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the NUMA CPU node number for a device\n\n @details Given a device index @p dv_ind, and a pointer to an\n uint32_t @p numa_node, this function will write the\n node number of NUMA CPU for the device @p dv_ind to the memory\n pointed to by @p numa_node.\n\n @param[in] dv_ind a device index\n\n @param[inout] numa_node A pointer to an uint32_t to which the\n numa node number should be written.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_topo_get_numa_node_number(dv_ind: u32, numa_node: *mut u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the weight for a connection between 2 GPUs\n\n @details Given a source device index @p dv_ind_src and\n a destination device index @p dv_ind_dst, and a pointer to an\n uint64_t @p weight, this function will write the\n weight for the connection between the device @p dv_ind_src\n and @p dv_ind_dst to the memory pointed to by @p weight.\n\n @param[in] dv_ind_src the source device index\n\n @param[in] dv_ind_dst the destination device index\n\n @param[inout] weight A pointer to an uint64_t to which the\n weight for the connection should be written.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_topo_get_link_weight( + dv_ind_src: u32, + dv_ind_dst: u32, + weight: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retreive minimal and maximal io link bandwidth between 2 GPUs\n\n @details Given a source device index @p dv_ind_src and\n a destination device index @p dv_ind_dst, pointer to an\n uint64_t @p min_bandwidth, and a pointer to uint64_t @p max_bandiwidth,\n this function will write theoretical minimal and maximal bandwidth limits.\n API works if src and dst are connected via xgmi and have 1 hop distance.\n\n @param[in] dv_ind_src the source device index\n\n @param[in] dv_ind_dst the destination device index\n\n @param[inout] min_bandwidth A pointer to an uint64_t to which the\n minimal bandwidth for the connection should be written.\n\n @param[inout] max_bandwidth A pointer to an uint64_t to which the\n maximal bandwidth for the connection should be written.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid"] + pub fn rsmi_minmax_bandwidth_get( + dv_ind_src: u32, + dv_ind_dst: u32, + min_bandwidth: *mut u64, + max_bandwidth: *mut u64, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Retrieve the hops and the connection type between 2 GPUs\n\n @details Given a source device index @p dv_ind_src and\n a destination device index @p dv_ind_dst, and a pointer to an\n uint64_t @p hops and a pointer to an RSMI_IO_LINK_TYPE @p type,\n this function will write the number of hops and the connection type\n between the device @p dv_ind_src and @p dv_ind_dst to the memory\n pointed to by @p hops and @p type.\n\n @param[in] dv_ind_src the source device index\n\n @param[in] dv_ind_dst the destination device index\n\n @param[inout] hops A pointer to an uint64_t to which the\n hops for the connection should be written.\n\n @param[inout] type A pointer to an ::RSMI_IO_LINK_TYPE to which the\n type for the connection should be written.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_topo_get_link_type( + dv_ind_src: u32, + dv_ind_dst: u32, + hops: *mut u64, + type_: *mut RSMI_IO_LINK_TYPE, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Return P2P availability status between 2 GPUs\n\n @details Given a source device index @p dv_ind_src and\n a destination device index @p dv_ind_dst, and a pointer to a\n bool @accessible, this function will write the P2P connection status\n between the device @p dv_ind_src and @p dv_ind_dst to the memory\n pointed to by @p accessible.\n\n @param[in] dv_ind_src the source device index\n\n @param[in] dv_ind_dst the destination device index\n\n @param[inout] accessible A pointer to a bool to which the status for\n the P2P connection availablity should be written.\n\n @retval ::RSMI_STATUS_SUCCESS call was successful\n @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid\n"] + pub fn rsmi_is_P2P_accessible( + dv_ind_src: u32, + dv_ind_dst: u32, + accessible: *mut bool, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get a function name iterator of supported RSMI functions for a device\n\n @details Given a device index @p dv_ind, this function will write a function\n iterator handle to the caller-provided memory pointed to by @p handle. This\n handle can be used to iterate through all the supported functions.\n\n Note that although this function takes in @p dv_ind as an argument,\n ::rsmi_dev_supported_func_iterator_open itself will not be among the\n functions listed as supported. This is because\n ::rsmi_dev_supported_func_iterator_open does not depend on hardware or\n driver support and should always be supported.\n\n @param[in] dv_ind a device index of device for which support information is\n requested\n\n @param[inout] handle A pointer to caller-provided memory to which the\n function iterator will be written.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_supported_func_iterator_open( + dv_ind: u32, + handle: *mut rsmi_func_id_iter_handle_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get a variant iterator for a given handle\n\n @details Given a ::rsmi_func_id_iter_handle_t @p obj_h, this function will\n write a function iterator handle to the caller-provided memory pointed to\n by @p var_iter. This handle can be used to iterate through all the supported\n variants of the provided handle. @p obj_h may be a handle to a function\n object, as provided by a call to ::rsmi_dev_supported_func_iterator_open, or\n it may be a variant itself (from a call to\n ::rsmi_dev_supported_variant_iterator_open), it which case @p var_iter will\n be an iterator of the sub-variants of @p obj_h (e.g., monitors).\n\n This call allocates a small amount of memory to @p var_iter. To free this memory\n ::rsmi_dev_supported_func_iterator_close should be called on the returned\n iterator handle @p var_iter when it is no longer needed.\n\n @param[in] obj_h an iterator handle for which the variants are being requested\n\n @param[inout] var_iter A pointer to caller-provided memory to which the\n sub-variant iterator will be written.\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_supported_variant_iterator_open( + obj_h: rsmi_func_id_iter_handle_t, + var_iter: *mut rsmi_func_id_iter_handle_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Advance a function identifer iterator\n\n @details Given a function id iterator handle (::rsmi_func_id_iter_handle_t)\n @p handle, this function will increment the iterator to point to the next\n identifier. After a successful call to this function, obtaining the value\n of the iterator @p handle will provide the value of the next item in the\n list of functions/variants.\n\n If there are no more items in the list, ::RSMI_STATUS_NO_DATA is returned.\n\n @param[in] handle A pointer to an iterator handle to be incremented\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n @retval ::RSMI_STATUS_NO_DATA is returned when list of identifiers has been\n exhausted\n"] + pub fn rsmi_func_iter_next(handle: rsmi_func_id_iter_handle_t) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Close a variant iterator handle\n\n @details Given a pointer to an ::rsmi_func_id_iter_handle_t @p handle, this\n function will free the resources being used by the handle\n\n @param[in] handle A pointer to an iterator handle to be closed\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_dev_supported_func_iterator_close( + handle: *mut rsmi_func_id_iter_handle_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Get the value associated with a function/variant iterator\n\n @details Given an ::rsmi_func_id_iter_handle_t @p handle, this function\n will write the identifier of the function/variant to the user provided\n memory pointed to by @p value.\n\n @p value may point to a function name, a variant id, or a monitor/sensor\n index, depending on what kind of iterator @p handle is\n\n @param[in] handle An iterator for which the value is being requested\n\n @param[inout] value A pointer to an ::rsmi_func_id_value_t provided by the\n caller to which this function will write the value assocaited with @p handle\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.\n"] + pub fn rsmi_func_iter_value_get( + handle: rsmi_func_id_iter_handle_t, + value: *mut rsmi_func_id_value_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Prepare to collect event notifications for a GPU\n\n @details This function prepares to collect events for the GPU with device\n ID @p dv_ind, by initializing any required system parameters. This call\n may open files which will remain open until ::rsmi_event_notification_stop()\n is called.\n\n @param dv_ind a device index corresponding to the device on which to\n listen for events\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call."] + pub fn rsmi_event_notification_init(dv_ind: u32) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Specify which events to collect for a device\n\n @details Given a device index @p dv_ind and a @p mask consisting of\n elements of ::rsmi_evt_notification_type_t OR'd together, this function\n will listen for the events specified in @p mask on the device\n corresponding to @p dv_ind.\n\n @param dv_ind a device index corresponding to the device on which to\n listen for events\n\n @param mask Bitmask generated by OR'ing 1 or more elements of\n ::rsmi_evt_notification_type_t indicating which event types to listen for,\n where the rsmi_evt_notification_type_t value indicates the bit field, with\n bit position starting from 1.\n For example, if the mask field is 0x0000000000000003, which means first bit,\n bit 1 (bit position start from 1) and bit 2 are set, which indicate interest\n in receiving RSMI_EVT_NOTIF_VMFAULT (which has a value of 1) and\n RSMI_EVT_NOTIF_THERMAL_THROTTLE event (which has a value of 2).\n\n @retval ::RSMI_STATUS_INIT_ERROR is returned if\n ::rsmi_event_notification_init() has not been called before a call to this\n function\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call"] + pub fn rsmi_event_notification_mask_set(dv_ind: u32, mask: u64) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Collect event notifications, waiting a specified amount of time\n\n @details Given a time period @p timeout_ms in milliseconds and a caller-\n provided buffer of ::rsmi_evt_notification_data_t's @p data with a length\n (in ::rsmi_evt_notification_data_t's, also specified by the caller) in the\n memory location pointed to by @p num_elem, this function will collect\n ::rsmi_evt_notification_type_t events for up to @p timeout_ms milliseconds,\n and write up to *@p num_elem event items to @p data. Upon return @p num_elem\n is updated with the number of events that were actually written. If events\n are already present when this function is called, it will write the events\n to the buffer then poll for new events if there is still caller-provided\n buffer available to write any new events that would be found.\n\n This function requires prior calls to ::rsmi_event_notification_init() and\n ::rsmi_event_notification_mask_set(). This function polls for the\n occurrance of the events on the respective devices that were previously\n specified by ::rsmi_event_notification_mask_set().\n\n @param[in] timeout_ms number of milliseconds to wait for an event\n to occur\n\n @param[inout] num_elem pointer to uint32_t, provided by the caller. On\n input, this value tells how many ::rsmi_evt_notification_data_t elements\n are being provided by the caller with @p data. On output, the location\n pointed to by @p num_elem will contain the number of items written to\n the provided buffer.\n\n @param[out] data pointer to a caller-provided memory buffer of size\n @p num_elem ::rsmi_evt_notification_data_t to which this function may safely\n write. If there are events found, up to @p num_elem event items will be\n written to @p data.\n\n @retval ::RSMI_STATUS_SUCCESS The function ran successfully. The events\n that were found are written to @p data and @p num_elems is updated\n with the number of elements that were written.\n\n @retval ::RSMI_STATUS_NO_DATA No events were found to collect.\n"] + pub fn rsmi_event_notification_get( + timeout_ms: ::std::os::raw::c_int, + num_elem: *mut u32, + data: *mut rsmi_evt_notification_data_t, + ) -> rsmi_status_t; +} +extern "C" { + #[must_use] + #[doc = " @brief Close any file handles and free any resources used by event\n notification for a GPU\n\n @details Any resources used by event notification for the GPU with\n device index @p dv_ind will be free with this\n function. This includes freeing any memory and closing file handles. This\n should be called for every call to ::rsmi_event_notification_init()\n\n @param[in] dv_ind The device index of the GPU for which event\n notification resources will be free\n\n @retval ::RSMI_STATUS_INVALID_ARGS resources for the given device have\n either already been freed, or were never allocated by\n ::rsmi_event_notification_init()\n\n @retval ::RSMI_STATUS_SUCCESS is returned upon successful call"] + pub fn rsmi_event_notification_stop(dv_ind: u32) -> rsmi_status_t; +} diff --git a/rocsolver-sys/Cargo.toml b/rocsolver-sys/Cargo.toml new file mode 100644 index 0000000..057e27e --- /dev/null +++ b/rocsolver-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rocsolver-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "rocsolver" + +[lib] diff --git a/rocsolver-sys/README b/rocsolver-sys/README new file mode 100644 index 0000000..ef4a25a --- /dev/null +++ b/rocsolver-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/rocsolver/rocsolver.h -o src/rocsolver.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --allowlist-function "rocsolver_.*" --allowlist-var "ROCSOLVER_*" --must-use-type rocblas_status -- -I/opt/rocm/include \ No newline at end of file diff --git a/rocsolver-sys/build.rs b/rocsolver-sys/build.rs new file mode 100644 index 0000000..b44db89 --- /dev/null +++ b/rocsolver-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=rocsolver"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/rocsolver-sys/src/lib.rs b/rocsolver-sys/src/lib.rs new file mode 100644 index 0000000..40e8ce1 --- /dev/null +++ b/rocsolver-sys/src/lib.rs @@ -0,0 +1,3 @@ +#![allow(warnings)] +mod rocsolver; +pub use rocsolver::*; \ No newline at end of file diff --git a/rocsolver-sys/src/rocsolver.rs b/rocsolver-sys/src/rocsolver.rs new file mode 100644 index 0000000..3bc9285 --- /dev/null +++ b/rocsolver-sys/src/rocsolver.rs @@ -0,0 +1,11506 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[doc = " \\brief Used to specify the logging layer mode using a bitwise combination\nof rocblas_layer_mode values."] +pub type rocblas_layer_mode_flags = u32; +impl rocblas_direct_ { + #[doc = "< Householder matrices applied from the right."] + pub const rocblas_forward_direction: rocblas_direct_ = rocblas_direct_(171); +} +impl rocblas_direct_ { + #[doc = "< Householder matrices applied from the left."] + pub const rocblas_backward_direction: rocblas_direct_ = rocblas_direct_(172); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify the order in which multiple Householder matrices are\napplied together"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_direct_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify the order in which multiple Householder matrices are\napplied together"] +pub use self::rocblas_direct_ as rocblas_direct; +impl rocblas_storev_ { + #[doc = "< Householder vectors are stored in the columns of a matrix."] + pub const rocblas_column_wise: rocblas_storev_ = rocblas_storev_(181); +} +impl rocblas_storev_ { + #[doc = "< Householder vectors are stored in the rows of a matrix."] + pub const rocblas_row_wise: rocblas_storev_ = rocblas_storev_(182); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify how householder vectors are stored in a matrix of\nvectors"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_storev_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify how householder vectors are stored in a matrix of\nvectors"] +pub use self::rocblas_storev_ as rocblas_storev; +impl rocblas_svect_ { + #[doc = "< The entire associated orthogonal/unitary matrix is computed."] + pub const rocblas_svect_all: rocblas_svect_ = rocblas_svect_(191); +} +impl rocblas_svect_ { + #[doc = "< Only the singular vectors are computed and\nstored in output array."] + pub const rocblas_svect_singular: rocblas_svect_ = rocblas_svect_(192); +} +impl rocblas_svect_ { + #[doc = "< Only the singular vectors are computed and\noverwrite the input matrix."] + pub const rocblas_svect_overwrite: rocblas_svect_ = rocblas_svect_(193); +} +impl rocblas_svect_ { + #[doc = "< No singular vectors are computed."] + pub const rocblas_svect_none: rocblas_svect_ = rocblas_svect_(194); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify how the singular vectors are to be computed and\nstored"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_svect_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify how the singular vectors are to be computed and\nstored"] +pub use self::rocblas_svect_ as rocblas_svect; +impl rocblas_workmode_ { + #[doc = "< Out-of-place computations are allowed; this\nrequires extra device memory for workspace."] + pub const rocblas_outofplace: rocblas_workmode_ = rocblas_workmode_(201); +} +impl rocblas_workmode_ { + #[doc = "< If not enough memory is available, this forces in-place computations."] + pub const rocblas_inplace: rocblas_workmode_ = rocblas_workmode_(202); +} +#[repr(transparent)] +#[doc = " \\brief Used to enable the use of fast algorithms (with out-of-place\ncomputations) in some of the routines"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_workmode_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to enable the use of fast algorithms (with out-of-place\ncomputations) in some of the routines"] +pub use self::rocblas_workmode_ as rocblas_workmode; +impl rocblas_evect_ { + #[doc = "< Compute eigenvectors for the original symmetric/Hermitian\nmatrix."] + pub const rocblas_evect_original: rocblas_evect_ = rocblas_evect_(211); +} +impl rocblas_evect_ { + #[doc = "< Compute eigenvectors for the symmetric tridiagonal\nmatrix."] + pub const rocblas_evect_tridiagonal: rocblas_evect_ = rocblas_evect_(212); +} +impl rocblas_evect_ { + #[doc = "< No eigenvectors are computed."] + pub const rocblas_evect_none: rocblas_evect_ = rocblas_evect_(213); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify how the eigenvectors are to be computed"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_evect_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify how the eigenvectors are to be computed"] +pub use self::rocblas_evect_ as rocblas_evect; +impl rocblas_eform_ { + #[doc = "< The problem is \\f$Ax = \\lambda Bx\\f$."] + pub const rocblas_eform_ax: rocblas_eform_ = rocblas_eform_(221); +} +impl rocblas_eform_ { + #[doc = "< The problem is \\f$ABx = \\lambda x\\f$."] + pub const rocblas_eform_abx: rocblas_eform_ = rocblas_eform_(222); +} +impl rocblas_eform_ { + #[doc = "< The problem is \\f$BAx = \\lambda x\\f$."] + pub const rocblas_eform_bax: rocblas_eform_ = rocblas_eform_(223); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify the form of the generalized eigenproblem"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_eform_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify the form of the generalized eigenproblem"] +pub use self::rocblas_eform_ as rocblas_eform; +impl rocblas_erange_ { + #[doc = "< All eigenvalues will be found."] + pub const rocblas_erange_all: rocblas_erange_ = rocblas_erange_(231); +} +impl rocblas_erange_ { + #[doc = "< All eigenvalues in the half-open interval\n\\f$(vl, vu]\\f$ will be found."] + pub const rocblas_erange_value: rocblas_erange_ = rocblas_erange_(232); +} +impl rocblas_erange_ { + #[doc = "< The \\f$il\\f$-th through \\f$iu\\f$-th eigenvalues will be found."] + pub const rocblas_erange_index: rocblas_erange_ = rocblas_erange_(233); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify the type of range in which eigenvalues will be found\nin partial eigenvalue decompositions"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_erange_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify the type of range in which eigenvalues will be found\nin partial eigenvalue decompositions"] +pub use self::rocblas_erange_ as rocblas_erange; +impl rocblas_eorder_ { + #[doc = "< The computed eigenvalues will be grouped by split-off\nblocks and arranged in increasing order within each block."] + pub const rocblas_eorder_blocks: rocblas_eorder_ = rocblas_eorder_(241); +} +impl rocblas_eorder_ { + #[doc = "< All computed eigenvalues of the entire matrix will be\nordered from smallest to largest."] + pub const rocblas_eorder_entire: rocblas_eorder_ = rocblas_eorder_(242); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify whether the eigenvalues are grouped and ordered by blocks"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_eorder_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify whether the eigenvalues are grouped and ordered by blocks"] +pub use self::rocblas_eorder_ as rocblas_eorder; +impl rocblas_esort_ { + #[doc = "< The computed eigenvalues will not be sorted."] + pub const rocblas_esort_none: rocblas_esort_ = rocblas_esort_(251); +} +impl rocblas_esort_ { + #[doc = "< The computed eigenvalues will be sorted in ascending order."] + pub const rocblas_esort_ascending: rocblas_esort_ = rocblas_esort_(252); +} +#[repr(transparent)] +#[doc = " \\brief Used in the Jacobi methods to specify whether the eigenvalues are sorted\nin increasing order"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_esort_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used in the Jacobi methods to specify whether the eigenvalues are sorted\nin increasing order"] +pub use self::rocblas_esort_ as rocblas_esort; +impl rocblas_srange_ { + #[doc = "< All singular values will be found."] + pub const rocblas_srange_all: rocblas_srange_ = rocblas_srange_(261); +} +impl rocblas_srange_ { + #[doc = "< All singular values in the half-open interval\n\\f$(vl, vu]\\f$ will be found."] + pub const rocblas_srange_value: rocblas_srange_ = rocblas_srange_(262); +} +impl rocblas_srange_ { + #[doc = "< The \\f$il\\f$-th through \\f$iu\\f$-th singular values will be found."] + pub const rocblas_srange_index: rocblas_srange_ = rocblas_srange_(263); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify the type of range in which singular values will be found\nin partial singular value decompositions"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_srange_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify the type of range in which singular values will be found\nin partial singular value decompositions"] +pub use self::rocblas_srange_ as rocblas_srange; +#[doc = " \\brief Forward-declaration of opaque struct containing data used for the re-factorization interfaces."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocsolver_rfinfo_ { + _unused: [u8; 0], +} +#[doc = " \\brief A handle to a structure containing matrix descriptors and metadata required to interact\nwith rocSPARSE when using the rocSOLVER re-factorization functionality. It needs to be initialized\nwith \\ref rocsolver_create_rfinfo and destroyed with \\ref rocsolver_destroy_rfinfo."] +pub type rocsolver_rfinfo = *mut rocsolver_rfinfo_; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocblas_handle { + _unused: [u8; 0], +} +#[doc = " \\brief rocblas_handle is a structure holding the rocblas library context.\n It must be initialized using rocblas_create_handle(),\n and the returned handle must be passed\n to all subsequent library function calls.\n It should be destroyed at the end using rocblas_destroy_handle()."] +pub type rocblas_handle = *mut _rocblas_handle; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +#[doc = " \\brief Forward declaration of hipStream_t"] +pub type hipStream_t = *mut ihipStream_t; +pub type rocblas_int = i32; +pub type rocblas_stride = i64; +#[doc = " \\brief Struct to represent a complex number with single precision real and imaginary parts."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_float_complex { + pub x: f32, + pub y: f32, +} +#[doc = " \\brief Struct to represent a complex number with double precision real and imaginary parts."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocblas_double_complex { + pub x: f64, + pub y: f64, +} +impl rocblas_operation_ { + #[doc = "< Operate with the matrix."] + pub const rocblas_operation_none: rocblas_operation_ = rocblas_operation_(111); +} +impl rocblas_operation_ { + #[doc = "< Operate with the transpose of the matrix."] + pub const rocblas_operation_transpose: rocblas_operation_ = rocblas_operation_(112); +} +impl rocblas_operation_ { + pub const rocblas_operation_conjugate_transpose: rocblas_operation_ = rocblas_operation_(113); +} +#[repr(transparent)] +#[doc = " \\brief Used to specify whether the matrix is to be transposed or not."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_operation_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used to specify whether the matrix is to be transposed or not."] +pub use self::rocblas_operation_ as rocblas_operation; +impl rocblas_fill_ { + #[doc = "< Upper triangle."] + pub const rocblas_fill_upper: rocblas_fill_ = rocblas_fill_(121); +} +impl rocblas_fill_ { + #[doc = "< Lower triangle."] + pub const rocblas_fill_lower: rocblas_fill_ = rocblas_fill_(122); +} +impl rocblas_fill_ { + pub const rocblas_fill_full: rocblas_fill_ = rocblas_fill_(123); +} +#[repr(transparent)] +#[doc = " \\brief Used by the Hermitian, symmetric and triangular matrix\n routines to specify whether the upper, or lower triangle is being referenced."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_fill_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Used by the Hermitian, symmetric and triangular matrix\n routines to specify whether the upper, or lower triangle is being referenced."] +pub use self::rocblas_fill_ as rocblas_fill; +impl rocblas_diagonal_ { + #[doc = "< Non-unit triangular."] + pub const rocblas_diagonal_non_unit: rocblas_diagonal_ = rocblas_diagonal_(131); +} +impl rocblas_diagonal_ { + #[doc = "< Unit triangular."] + pub const rocblas_diagonal_unit: rocblas_diagonal_ = rocblas_diagonal_(132); +} +#[repr(transparent)] +#[doc = " \\brief It is used by the triangular matrix routines to specify whether the\n matrix is unit triangular."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_diagonal_(pub ::std::os::raw::c_uint); +#[doc = " \\brief It is used by the triangular matrix routines to specify whether the\n matrix is unit triangular."] +pub use self::rocblas_diagonal_ as rocblas_diagonal; +impl rocblas_side_ { + #[doc = "< Multiply general matrix by symmetric,\nHermitian, or triangular matrix on the left."] + pub const rocblas_side_left: rocblas_side_ = rocblas_side_(141); +} +impl rocblas_side_ { + #[doc = "< Multiply general matrix by symmetric,\nHermitian, or triangular matrix on the right."] + pub const rocblas_side_right: rocblas_side_ = rocblas_side_(142); +} +impl rocblas_side_ { + pub const rocblas_side_both: rocblas_side_ = rocblas_side_(143); +} +#[repr(transparent)] +#[doc = " \\brief Indicates the side matrix A is located relative to matrix B during multiplication."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_side_(pub ::std::os::raw::c_uint); +#[doc = " \\brief Indicates the side matrix A is located relative to matrix B during multiplication."] +pub use self::rocblas_side_ as rocblas_side; +impl rocblas_status_ { + #[doc = "< Success"] + pub const rocblas_status_success: rocblas_status_ = rocblas_status_(0); +} +impl rocblas_status_ { + #[doc = "< Handle not initialized, invalid or null"] + pub const rocblas_status_invalid_handle: rocblas_status_ = rocblas_status_(1); +} +impl rocblas_status_ { + #[doc = "< Function is not implemented"] + pub const rocblas_status_not_implemented: rocblas_status_ = rocblas_status_(2); +} +impl rocblas_status_ { + #[doc = "< Invalid pointer argument"] + pub const rocblas_status_invalid_pointer: rocblas_status_ = rocblas_status_(3); +} +impl rocblas_status_ { + #[doc = "< Invalid size argument"] + pub const rocblas_status_invalid_size: rocblas_status_ = rocblas_status_(4); +} +impl rocblas_status_ { + #[doc = "< Failed internal memory allocation, copy or dealloc"] + pub const rocblas_status_memory_error: rocblas_status_ = rocblas_status_(5); +} +impl rocblas_status_ { + #[doc = "< Other internal library failure"] + pub const rocblas_status_internal_error: rocblas_status_ = rocblas_status_(6); +} +impl rocblas_status_ { + #[doc = "< Performance degraded due to low device memory"] + pub const rocblas_status_perf_degraded: rocblas_status_ = rocblas_status_(7); +} +impl rocblas_status_ { + #[doc = "< Unmatched start/stop size query"] + pub const rocblas_status_size_query_mismatch: rocblas_status_ = rocblas_status_(8); +} +impl rocblas_status_ { + #[doc = "< Queried device memory size increased"] + pub const rocblas_status_size_increased: rocblas_status_ = rocblas_status_(9); +} +impl rocblas_status_ { + #[doc = "< Queried device memory size unchanged"] + pub const rocblas_status_size_unchanged: rocblas_status_ = rocblas_status_(10); +} +impl rocblas_status_ { + #[doc = "< Passed argument not valid"] + pub const rocblas_status_invalid_value: rocblas_status_ = rocblas_status_(11); +} +impl rocblas_status_ { + #[doc = "< Nothing preventing function to proceed"] + pub const rocblas_status_continue: rocblas_status_ = rocblas_status_(12); +} +impl rocblas_status_ { + pub const rocblas_status_check_numerics_fail: rocblas_status_ = rocblas_status_(13); +} +#[repr(transparent)] +#[doc = " @brief rocblas status codes definition"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocblas_status_(pub ::std::os::raw::c_uint); +#[doc = " @brief rocblas status codes definition"] +pub use self::rocblas_status_ as rocblas_status; +pub type rocsolver_int = rocblas_int; +pub type rocsolver_handle = rocblas_handle; +#[doc = " @brief rocblas status codes definition"] +pub use self::rocblas_status as rocsolver_status; +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_create_handle."] + pub fn rocsolver_create_handle(handle: *mut rocsolver_handle) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_destroy_handle."] + pub fn rocsolver_destroy_handle(handle: rocsolver_handle) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_set_stream."] + pub fn rocsolver_set_stream(handle: rocsolver_handle, stream: hipStream_t) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_get_stream."] + pub fn rocsolver_get_stream( + handle: rocsolver_handle, + stream: *mut hipStream_t, + ) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_set_vector."] + pub fn rocsolver_set_vector( + n: rocsolver_int, + elem_size: rocsolver_int, + x: *const ::std::os::raw::c_void, + incx: rocsolver_int, + y: *mut ::std::os::raw::c_void, + incy: rocsolver_int, + ) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_get_vector."] + pub fn rocsolver_get_vector( + n: rocsolver_int, + elem_size: rocsolver_int, + x: *const ::std::os::raw::c_void, + incx: rocsolver_int, + y: *mut ::std::os::raw::c_void, + incy: rocsolver_int, + ) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_set_matrix."] + pub fn rocsolver_set_matrix( + rows: rocsolver_int, + cols: rocsolver_int, + elem_size: rocsolver_int, + a: *const ::std::os::raw::c_void, + lda: rocsolver_int, + b: *mut ::std::os::raw::c_void, + ldb: rocsolver_int, + ) -> rocsolver_status; +} +extern "C" { + #[doc = " \\deprecated Use \\c rocblas_get_matrix."] + pub fn rocsolver_get_matrix( + rows: rocsolver_int, + cols: rocsolver_int, + elem_size: rocsolver_int, + a: *const ::std::os::raw::c_void, + lda: rocsolver_int, + b: *mut ::std::os::raw::c_void, + ldb: rocsolver_int, + ) -> rocsolver_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief GET_VERSION_STRING Queries the library version.\n\n\\details\n@param[out]\nbuf A buffer that the version string will be written into.\n@param[in]\nlen The size of the given buffer in bytes."] + pub fn rocsolver_get_version_string( + buf: *mut ::std::os::raw::c_char, + len: usize, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief GET_VERSION_STRING_SIZE Queries the minimum buffer size for a\nsuccessful call to \\ref rocsolver_get_version_string.\n\n\\details\n@param[out]\nlen pointer to size_t.\\n\nThe minimum length of buffer to pass to\n\\ref rocsolver_get_version_string."] + pub fn rocsolver_get_version_string_size(len: *mut usize) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_BEGIN begins a rocSOLVER multi-level logging session.\n\n\\details\nInitializes the rocSOLVER logging environment with default values (no\nlogging and one level depth). Default mode can be overridden by using the\nenvironment variables ROCSOLVER_LAYER and ROCSOLVER_LEVELS.\n\nThis function also sets the streams where the log results will be outputted.\nThe default is STDERR for all the modes. This default can also be overridden\nusing the environment variable ROCSOLVER_LOG_PATH, or specifically\nROCSOLVER_LOG_TRACE_PATH, ROCSOLVER_LOG_BENCH_PATH, and/or ROCSOLVER_LOG_PROFILE_PATH."] + pub fn rocsolver_log_begin() -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_END ends the multi-level rocSOLVER logging session.\n\n\\details\nIf applicable, this function also prints the profile logging results\nbefore cleaning the logging environment."] + pub fn rocsolver_log_end() -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_SET_LAYER_MODE sets the logging mode for the rocSOLVER multi-level\nlogging environment.\n\n\\details\n@param[in]\nlayer_mode rocblas_layer_mode_flags.\\n\nSpecifies the logging mode."] + pub fn rocsolver_log_set_layer_mode(layer_mode: rocblas_layer_mode_flags) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_SET_MAX_LEVELS sets the maximum trace log depth for the rocSOLVER\nmulti-level logging environment.\n\n\\details\n@param[in]\nmax_levels rocblas_int. max_levels >= 1.\\n\nSpecifies the maximum depth at which nested function calls\nwill appear in the trace and profile logs."] + pub fn rocsolver_log_set_max_levels(max_levels: rocblas_int) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_RESTORE_DEFAULTS restores the default values of the rocSOLVER\nmulti-level logging environment.\n\n\\details\nThis function sets the logging mode and maximum trace log depth to their\ndefault values (no logging and one level depth)."] + pub fn rocsolver_log_restore_defaults() -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_WRITE_PROFILE prints the profile logging results."] + pub fn rocsolver_log_write_profile() -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief LOG_FLUSH_PROFILE prints the profile logging results and clears the\nprofile record."] + pub fn rocsolver_log_flush_profile() -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LACGV conjugates the complex vector x.\n\n\\details\nIt conjugates the n entries of a complex vector x with increment incx.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe dimension of vector x.\n@param[inout]\nx pointer to type. Array on the GPU of size at least n (size depends on the value of incx).\\n\nOn entry, the vector x.\nOn exit, each entry is overwritten with its conjugate value.\n@param[in]\nincx rocblas_int. incx != 0.\\n\nThe distance between two consecutive elements of x.\nIf incx is negative, the elements of x are indexed in\nreverse order."] + pub fn rocsolver_clacgv( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlacgv( + handle: rocblas_handle, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LASWP performs a series of row interchanges on the matrix A.\n\n\\details\nRow interchanges are done one by one. If \\f$\\text{ipiv}[k_1 + (j - k_1) \\cdot \\text{abs}(\\text{incx})] = r\\f$, then the j-th row of A\nwill be interchanged with the r-th row of A, for \\f$j = k_1,k_1+1,\\dots,k_2\\f$. Indices \\f$k_1\\f$ and \\f$k_2\\f$ are 1-based indices.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n. \\n\nOn entry, the matrix to which the row\ninterchanges will be applied. On exit, the resulting permuted matrix.\n@param[in]\nlda rocblas_int. lda > 0.\\n\nThe leading dimension of the array A.\n@param[in]\nk1 rocblas_int. k1 > 0.\\n\nThe k_1 index. It is the first element of ipiv for which a row interchange will\nbe done. This is a 1-based index.\n@param[in]\nk2 rocblas_int. k2 > k1 > 0.\\n\nThe k_2 index. k_2 - k_1 + 1 is the number of elements of ipiv for which a row\ninterchange will be done. This is a 1-based index.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU of dimension at least k_1 + (k_2 - k_1)*abs(incx).\\n\nThe vector of pivot indices. Only the elements in positions\nk_1 through k_1 + (k_2 - k_1)*abs(incx) of this vector are accessed.\nElements of ipiv are considered 1-based.\n@param[in]\nincx rocblas_int. incx != 0.\\n\nThe distance between successive values of ipiv. If incx\nis negative, the pivots are applied in reverse order."] + pub fn rocsolver_slaswp( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + k1: rocblas_int, + k2: rocblas_int, + ipiv: *const rocblas_int, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlaswp( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + k1: rocblas_int, + k2: rocblas_int, + ipiv: *const rocblas_int, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_claswp( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + k1: rocblas_int, + k2: rocblas_int, + ipiv: *const rocblas_int, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlaswp( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + k1: rocblas_int, + k2: rocblas_int, + ipiv: *const rocblas_int, + incx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LARFG generates a Householder reflector H of order n.\n\n\\details\nThe reflector H is such that\n\n\\f[\nH'\\left[\\begin{array}{c}\n\\text{alpha}\\\\\nx\n\\end{array}\\right]=\\left[\\begin{array}{c}\n\\text{beta}\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere x is an n-1 vector, and alpha and beta are scalars. Matrix H can be\ngenerated as\n\n\\f[\nH = I - \\text{tau}\\left[\\begin{array}{c}\n1\\\\\nv\n\\end{array}\\right]\\left[\\begin{array}{cc}\n1 & v'\n\\end{array}\\right]\n\\f]\n\nwhere v is an n-1 vector, and tau is a scalar known as the Householder scalar. The vector\n\n\\f[\n\\bar{v}=\\left[\\begin{array}{c}\n1\\\\\nv\n\\end{array}\\right]\n\\f]\n\nis the Householder vector associated with the reflection.\n\n\\note\nThe matrix H is orthogonal/unitary (i.e. \\f$H'H=HH'=I\\f$). It is symmetric when real (i.e. \\f$H^T=H\\f$), but not Hermitian when complex\n(i.e. \\f$H^H\\neq H\\f$ in general).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order (size) of reflector H.\n@param[inout]\nalpha pointer to type. A scalar on the GPU.\\n\nOn entry, the scalar alpha.\nOn exit, it is overwritten with beta.\n@param[inout]\nx pointer to type. Array on the GPU of size at least n-1 (size depends on the value of incx).\\n\nOn entry, the vector x,\nOn exit, it is overwritten with vector v.\n@param[in]\nincx rocblas_int. incx > 0.\\n\nThe distance between two consecutive elements of x.\n@param[out]\ntau pointer to type. A scalar on the GPU.\\n\nThe Householder scalar tau."] + pub fn rocsolver_slarfg( + handle: rocblas_handle, + n: rocblas_int, + alpha: *mut f32, + x: *mut f32, + incx: rocblas_int, + tau: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlarfg( + handle: rocblas_handle, + n: rocblas_int, + alpha: *mut f64, + x: *mut f64, + incx: rocblas_int, + tau: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clarfg( + handle: rocblas_handle, + n: rocblas_int, + alpha: *mut rocblas_float_complex, + x: *mut rocblas_float_complex, + incx: rocblas_int, + tau: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlarfg( + handle: rocblas_handle, + n: rocblas_int, + alpha: *mut rocblas_double_complex, + x: *mut rocblas_double_complex, + incx: rocblas_int, + tau: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LARFT generates the triangular factor T of a block reflector H of\norder n.\n\n\\details\nThe block reflector H is defined as the product of k Householder matrices\n\n\\f[\n\\begin{array}{cl}\nH = H_1H_2\\cdots H_k & \\: \\text{if direct indicates forward direction, or} \\\\\nH = H_k\\cdots H_2H_1 & \\: \\text{if direct indicates backward direction}\n\\end{array}\n\\f]\n\nThe triangular factor T is upper triangular in the forward direction and lower triangular in the backward direction.\nIf storev is column-wise, then\n\n\\f[\nH = I - VTV'\n\\f]\n\nwhere the i-th column of matrix V contains the Householder vector associated with \\f$H_i\\f$. If storev is row-wise, then\n\n\\f[\nH = I - V'TV\n\\f]\n\nwhere the i-th row of matrix V contains the Householder vector associated with \\f$H_i\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ndirect #rocblas_direct.\\n\nSpecifies the direction in which the Householder matrices are applied.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies how the Householder vectors are stored in matrix V.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order (size) of the block reflector.\n@param[in]\nk rocblas_int. k >= 1.\\n\nThe number of Householder matrices forming H.\n@param[in]\nV pointer to type. Array on the GPU of size ldv*k if column-wise, or ldv*n if row-wise.\\n\nThe matrix of Householder vectors.\n@param[in]\nldv rocblas_int. ldv >= n if column-wise, or ldv >= k if row-wise.\\n\nLeading dimension of V.\n@param[in]\ntau pointer to type. Array of k scalars on the GPU.\\n\nThe vector of all the Householder scalars.\n@param[out]\nT pointer to type. Array on the GPU of dimension ldt*k.\\n\nThe triangular factor. T is upper triangular if direct indicates forward direction, otherwise it is\nlower triangular. The rest of the array is not used.\n@param[in]\nldt rocblas_int. ldt >= k.\\n\nThe leading dimension of T."] + pub fn rocsolver_slarft( + handle: rocblas_handle, + direct: rocblas_direct, + storev: rocblas_storev, + n: rocblas_int, + k: rocblas_int, + V: *mut f32, + ldv: rocblas_int, + tau: *mut f32, + T: *mut f32, + ldt: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlarft( + handle: rocblas_handle, + direct: rocblas_direct, + storev: rocblas_storev, + n: rocblas_int, + k: rocblas_int, + V: *mut f64, + ldv: rocblas_int, + tau: *mut f64, + T: *mut f64, + ldt: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clarft( + handle: rocblas_handle, + direct: rocblas_direct, + storev: rocblas_storev, + n: rocblas_int, + k: rocblas_int, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + tau: *mut rocblas_float_complex, + T: *mut rocblas_float_complex, + ldt: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlarft( + handle: rocblas_handle, + direct: rocblas_direct, + storev: rocblas_storev, + n: rocblas_int, + k: rocblas_int, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + tau: *mut rocblas_double_complex, + T: *mut rocblas_double_complex, + ldt: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LARF applies a Householder reflector H to a general matrix A.\n\n\\details\nThe Householder reflector H, of order m or n, is to be applied to an m-by-n matrix A\nfrom the left or the right, depending on the value of side. H is given by\n\n\\f[\nH = I - \\text{alpha}\\cdot xx'\n\\f]\n\nwhere alpha is the Householder scalar and x is a Householder vector. H is never actually computed.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nDetermines whether H is applied from the left or the right.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of A.\n@param[in]\nx pointer to type. Array on the GPU of size at least 1 + (m-1)*abs(incx) if left side, or\nat least 1 + (n-1)*abs(incx) if right side.\\n\nThe Householder vector x.\n@param[in]\nincx rocblas_int. incx != 0.\\n\nDistance between two consecutive elements of x.\nIf incx < 0, the elements of x are indexed in reverse order.\n@param[in]\nalpha pointer to type. A scalar on the GPU.\\n\nThe Householder scalar. If alpha = 0, then H = I (A will remain the same; x is never used)\n@param[inout]\nA pointer to type. Array on the GPU of size lda*n.\\n\nOn entry, the matrix A. On exit, it is overwritten with\nH*A (or A*H).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nLeading dimension of A."] + pub fn rocsolver_slarf( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + x: *mut f32, + incx: rocblas_int, + alpha: *const f32, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlarf( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + x: *mut f64, + incx: rocblas_int, + alpha: *const f64, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clarf( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + x: *mut rocblas_float_complex, + incx: rocblas_int, + alpha: *const rocblas_float_complex, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlarf( + handle: rocblas_handle, + side: rocblas_side, + m: rocblas_int, + n: rocblas_int, + x: *mut rocblas_double_complex, + incx: rocblas_int, + alpha: *const rocblas_double_complex, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LARFB applies a block reflector H to a general m-by-n matrix A.\n\n\\details\nThe block reflector H is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nHA & \\: \\text{(No transpose from the left),}\\\\\nH'A & \\: \\text{(Transpose or conjugate transpose from the left),}\\\\\nAH & \\: \\text{(No transpose from the right), or}\\\\\nAH' & \\: \\text{(Transpose or conjugate transpose from the right).}\n\\end{array}\n\\f]\n\nThe block reflector H is defined as the product of k Householder matrices as\n\n\\f[\n\\begin{array}{cl}\nH = H_1H_2\\cdots H_k & \\: \\text{if direct indicates forward direction, or} \\\\\nH = H_k\\cdots H_2H_1 & \\: \\text{if direct indicates backward direction}\n\\end{array}\n\\f]\n\nH is never stored. It is calculated as\n\n\\f[\nH = I - VTV'\n\\f]\n\nwhere the i-th column of matrix V contains the Householder vector associated with \\f$H_i\\f$, if storev is column-wise; or\n\n\\f[\nH = I - V'TV\n\\f]\n\nwhere the i-th row of matrix V contains the Householder vector associated with \\f$H_i\\f$, if storev is row-wise.\nT is the associated triangular factor as computed by \\ref rocsolver_slarft \"LARFT\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply H.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the block reflector or its transpose/conjugate transpose is to be applied.\n@param[in]\ndirect #rocblas_direct.\\n\nSpecifies the direction in which the Householder matrices are to be applied to generate H.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies how the Householder vectors are stored in matrix V.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix A.\n@param[in]\nk rocblas_int. k >= 1.\\n\nThe number of Householder matrices.\n@param[in]\nV pointer to type. Array on the GPU of size ldv*k if column-wise, ldv*n if row-wise and applying from the right,\nor ldv*m if row-wise and applying from the left.\\n\nThe matrix of Householder vectors.\n@param[in]\nldv rocblas_int. ldv >= k if row-wise, ldv >= m if column-wise and applying from the left, or ldv >= n if\ncolumn-wise and applying from the right.\\n\nLeading dimension of V.\n@param[in]\nT pointer to type. Array on the GPU of dimension ldt*k.\\n\nThe triangular factor of the block reflector.\n@param[in]\nldt rocblas_int. ldt >= k.\\n\nThe leading dimension of T.\n@param[inout]\nA pointer to type. Array on the GPU of size lda*n.\\n\nOn entry, the matrix A. On exit, it is overwritten with\nH*A, A*H, H'*A, or A*H'.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nLeading dimension of A."] + pub fn rocsolver_slarfb( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + direct: rocblas_direct, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + V: *mut f32, + ldv: rocblas_int, + T: *mut f32, + ldt: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlarfb( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + direct: rocblas_direct, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + V: *mut f64, + ldv: rocblas_int, + T: *mut f64, + ldt: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clarfb( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + direct: rocblas_direct, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + T: *mut rocblas_float_complex, + ldt: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlarfb( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + direct: rocblas_direct, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + T: *mut rocblas_double_complex, + ldt: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LABRD computes the bidiagonal form of the first k rows and columns of\na general m-by-n matrix A, as well as the matrices X and Y needed to reduce\nthe remaining part of A.\n\n\\details\nThe reduced form is given by:\n\n\\f[\nB = Q'AP\n\\f]\n\nwhere the leading k-by-k block of B is upper bidiagonal if m >= n, or lower bidiagonal if m < n. Q and\nP are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_k, & \\text{and} \\\\\nP = G_1G_2\\cdots G_k.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ and \\f$G_i\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_i = I - \\text{tauq}[i]\\cdot v_iv_i', & \\text{and} \\\\\nG_i = I - \\text{taup}[i]\\cdot u_iu_i'.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i]=1\\f$;\nwhile the first i elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i+1]=1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1]=1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i]=1\\f$.\n\nThe unreduced part of the matrix A can be updated using the block update\n\n\\f[\nA = A - VY' - XU'\n\\f]\n\nwhere V and U are the m-by-k and n-by-k matrices formed with the vectors \\f$v_i\\f$ and \\f$u_i\\f$, respectively.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[in]\nk rocblas_int. min(m,n) >= k >= 0.\\n\nThe number of leading rows and columns of matrix A that will be reduced.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be reduced.\nOn exit, the first k elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n), contain the bidiagonal form B.\nIf m >= n, the elements below the diagonal of the first k columns are the possibly non-zero elements\nof the Householder vectors associated with Q, while the elements above the\nsuperdiagonal of the first k rows are the n - i - 1 possibly non-zero elements of the Householder vectors related to P.\nIf m < n, the elements below the subdiagonal of the first k columns are the m - i - 1 possibly non-zero\nelements of the Householder vectors related to Q, while the elements above the\ndiagonal of the first k rows are the n - i possibly non-zero elements of the vectors associated with P.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension k.\\n\nThe diagonal elements of B.\n@param[out]\nE pointer to real type. Array on the GPU of dimension k.\\n\nThe off-diagonal elements of B.\n@param[out]\ntauq pointer to type. Array on the GPU of dimension k.\\n\nThe Householder scalars associated with matrix Q.\n@param[out]\ntaup pointer to type. Array on the GPU of dimension k.\\n\nThe Householder scalars associated with matrix P.\n@param[out]\nX pointer to type. Array on the GPU of dimension ldx*k.\\n\nThe m-by-k matrix needed to update the unreduced part of A.\n@param[in]\nldx rocblas_int. ldx >= m.\\n\nThe leading dimension of X.\n@param[out]\nY pointer to type. Array on the GPU of dimension ldy*k.\\n\nThe n-by-k matrix needed to update the unreduced part of A.\n@param[in]\nldy rocblas_int. ldy >= n.\\n\nThe leading dimension of Y."] + pub fn rocsolver_slabrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut f32, + taup: *mut f32, + X: *mut f32, + ldx: rocblas_int, + Y: *mut f32, + ldy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlabrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut f64, + taup: *mut f64, + X: *mut f64, + ldx: rocblas_int, + Y: *mut f64, + ldy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clabrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut rocblas_float_complex, + taup: *mut rocblas_float_complex, + X: *mut rocblas_float_complex, + ldx: rocblas_int, + Y: *mut rocblas_float_complex, + ldy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlabrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut rocblas_double_complex, + taup: *mut rocblas_double_complex, + X: *mut rocblas_double_complex, + ldx: rocblas_int, + Y: *mut rocblas_double_complex, + ldy: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LATRD computes the tridiagonal form of k rows and columns of\na symmetric/hermitian matrix A, as well as the matrix W needed to update\nthe remaining part of A.\n\n\\details\nThe reduced form is given by:\n\n\\f[\nT = Q'AQ\n\\f]\n\nIf uplo is lower, the first k rows and columns of T form the tridiagonal block. If uplo is upper, then the last\nk rows and columns of T form the tridiagonal block. Q is an orthogonal/unitary matrix represented as the\nproduct of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_k & \\text{if uplo indicates lower, or}\\\\\nQ = H_nH_{n-1}\\cdots H_{n-k+1} & \\text{if uplo is upper}.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{tau}[i]\\cdot v_iv_i'\n\\f]\n\nwhere tau[i] is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$. If uplo is upper,\nthe last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\nThe unreduced part of the matrix A can be updated using a rank update of the form:\n\n\\f[\nA = A - VW' - WV'\n\\f]\n\nwhere V is the n-by-k matrix formed by the vectors \\f$v_i\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of rows and columns of the matrix A to be reduced.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the n-by-n matrix to be reduced.\nOn exit, if uplo is lower, the first k columns have been reduced to tridiagonal form\n(given in the diagonal elements of A and the array E), the elements below the diagonal\ncontain the possibly non-zero entries of the Householder vectors associated with Q, stored as columns.\nIf uplo is upper, the last k columns have been reduced to tridiagonal form\n(given in the diagonal elements of A and the array E), the elements above the diagonal\ncontain the possibly non-zero entries of the Householder vectors associated with Q, stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nIf upper (lower), the last (first) k elements of E are the off-diagonal elements of the\ncomputed tridiagonal block.\n@param[out]\ntau pointer to type. Array on the GPU of dimension n-1.\\n\nIf upper (lower), the last (first) k elements of tau are the Householder scalars related to Q.\n@param[out]\nW pointer to type. Array on the GPU of dimension ldw*k.\\n\nThe n-by-k matrix needed to update the unreduced part of A.\n@param[in]\nldw rocblas_int. ldw >= n.\\n\nThe leading dimension of W."] + pub fn rocsolver_slatrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + E: *mut f32, + tau: *mut f32, + W: *mut f32, + ldw: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlatrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + E: *mut f64, + tau: *mut f64, + W: *mut f64, + ldw: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clatrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + E: *mut f32, + tau: *mut rocblas_float_complex, + W: *mut rocblas_float_complex, + ldw: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlatrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + E: *mut f64, + tau: *mut rocblas_double_complex, + W: *mut rocblas_double_complex, + ldw: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LASYF computes a partial factorization of a symmetric matrix \\f$A\\f$\nusing Bunch-Kaufman diagonal pivoting.\n\n\\details\nThe partial factorization has the form\n\n\\f[\nA = \\left[ \\begin{array}{cc}\nI & U_{12} \\\\\n0 & U_{22}\n\\end{array} \\right] \\left[ \\begin{array}{cc}\nA_{11} & 0 \\\\\n0 & D\n\\end{array} \\right] \\left[ \\begin{array}{cc}\nI & 0 \\\\\nU_{12}^T & U_{22}^T\n\\end{array} \\right]\n\\f]\n\nor\n\n\\f[\nA = \\left[ \\begin{array}{cc}\nL_{11} & 0 \\\\\nL_{21} & I\n\\end{array} \\right] \\left[ \\begin{array}{cc}\nD & 0 \\\\\n0 & A_{22}\n\\end{array} \\right] \\left[ \\begin{array}{cc}\nL_{11}^T & L_{21}^T \\\\\n0 & I\n\\end{array} \\right]\n\\f]\n\ndepending on the value of uplo. The order of the block diagonal matrix \\f$D\\f$\nis either \\f$nb\\f$ or \\f$nb-1\\f$, and is returned in the argument \\f$kb\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[in]\nnb rocblas_int. 2 <= nb <= n.\\n\nThe number of columns of A to be factored.\n@param[out]\nkb pointer to a rocblas_int on the GPU.\\n\nThe number of columns of A that were actually factored (either nb or\nnb-1).\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A to be factored.\nOn exit, the partially factored matrix.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nIf uplo is upper, then only the last kb elements of ipiv will be\nset. For n - kb < k <= n, if ipiv[k] > 0 then rows and columns k\nand ipiv[k] were interchanged and D[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv[k] = ipiv[k-1] < 0, then rows and columns k-1\nand -ipiv[k] were interchanged and D[k-1,k-1] to D[k,k] is a 2-by-2\ndiagonal block.\nIf uplo is lower, then only the first kb elements of ipiv will be\nset. For 1 <= k <= kb, if ipiv[k] > 0 then rows and columns k\nand ipiv[k] were interchanged and D[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv[k] = ipiv[k+1] < 0, then rows and columns k+1\nand -ipiv[k] were interchanged and D[k,k] to D[k+1,k+1] is a 2-by-2\ndiagonal block.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, D is singular. D[i,i] is the first diagonal zero."] + pub fn rocsolver_slasyf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nb: rocblas_int, + kb: *mut rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlasyf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nb: rocblas_int, + kb: *mut rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clasyf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nb: rocblas_int, + kb: *mut rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlasyf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nb: rocblas_int, + kb: *mut rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief LAUUM computes the product of the upper (or lower) triangular part U (or L) of a\nsymmetric/Hemitian matrix A with its transpose.\n\n\\details\nIf uplo indicates upper, then \\f$UU'\\f$ is computed. If uplo indicates lower, then \\f$L'L\\f$ is computed instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower triangular part of A will be used.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not referenced.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns and rows of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n. \\n\nOn entry, it contains the upper (or lower) part of the symmetric/Hermitian matrix.\nOn exit, the upper (or lower) part is overwritten with the result of U*U' (or L'*L).\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of the array A."] + pub fn rocsolver_slauum( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dlauum( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_clauum( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zlauum( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORG2R generates an m-by-n Matrix Q with orthonormal columns.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the first n columns of the product of k Householder\nreflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k.\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQRF\", with the Householder vectors in the first k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\"."] + pub fn rocsolver_sorg2r( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorg2r( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNG2R generates an m-by-n complex Matrix Q with orthonormal columns.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the first n columns of the product of k Householder\nreflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQRF\", with the Householder vectors in the first k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\"."] + pub fn rocsolver_cung2r( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zung2r( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGQR generates an m-by-n Matrix Q with orthonormal columns.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the first n columns of the product of k Householder\nreflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQRF\", with the Householder vectors in the first k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\"."] + pub fn rocsolver_sorgqr( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorgqr( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGQR generates an m-by-n complex Matrix Q with orthonormal columns.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the first n columns of the product of k Householder\nreflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nHouseholder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQRF\", with the Householder vectors in the first k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\"."] + pub fn rocsolver_cungqr( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zungqr( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGL2 generates an m-by-n Matrix Q with orthonormal rows.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the first m rows of the product of k Householder\nreflectors of order n\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. 0 <= m <= n.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= m.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GELQF\", with the Householder vectors in the first k rows.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\"."] + pub fn rocsolver_sorgl2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorgl2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGL2 generates an m-by-n complex Matrix Q with orthonormal rows.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the first m rows of the product of k Householder\nreflectors of order n\n\n\\f[\nQ = H_k^HH_{k-1}^H\\cdots H_1^H\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. 0 <= m <= n.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= m.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GELQF\", with the Householder vectors in the first k rows.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\"."] + pub fn rocsolver_cungl2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zungl2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGLQ generates an m-by-n Matrix Q with orthonormal rows.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the first m rows of the product of k Householder\nreflectors of order n\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. 0 <= m <= n.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= m.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GELQF\", with the Householder vectors in the first k rows.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\"."] + pub fn rocsolver_sorglq( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorglq( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGLQ generates an m-by-n complex Matrix Q with orthonormal rows.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the first m rows of the product of k Householder\nreflectors of order n\n\n\\f[\nQ = H_k^HH_{k-1}^H\\cdots H_1^H\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. 0 <= m <= n.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= m.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GELQF\", with the Householder vectors in the first k rows.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\"."] + pub fn rocsolver_cunglq( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunglq( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORG2L generates an m-by-n Matrix Q with orthonormal columns.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the last n columns of the product of k\nHouseholder reflectors of order m\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQLF\", with the Householder vectors in the last k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqlf \"GEQLF\"."] + pub fn rocsolver_sorg2l( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorg2l( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNG2L generates an m-by-n complex Matrix Q with orthonormal columns.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is defined as the last n columns of the product of k\nHouseholder reflectors of order m\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQLF\", with the Householder vectors in the last k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqlf \"GEQLF\"."] + pub fn rocsolver_cung2l( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zung2l( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGQL generates an m-by-n Matrix Q with orthonormal columns.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the last n column of the product of k Householder\nreflectors of order m\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQLF\", with the Householder vectors in the last k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqlf \"GEQLF\"."] + pub fn rocsolver_sorgql( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorgql( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGQL generates an m-by-n complex Matrix Q with orthonormal columns.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is defined as the last n columns of the product of k\nHouseholder reflectors of order m\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\n@param[in]\nn rocblas_int. 0 <= n <= m.\\n\nThe number of columns of the matrix Q.\n@param[in]\nk rocblas_int. 0 <= k <= n.\\n\nThe number of Householder reflectors.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A as returned by \\ref rocsolver_sgeqrf \"GEQLF\", with the Householder vectors in the last k columns.\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqlf \"GEQLF\"."] + pub fn rocsolver_cungql( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zungql( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGBR generates an m-by-n Matrix Q with orthonormal rows or columns.\n\n\\details\nIf storev is column-wise, then the matrix Q has orthonormal columns. If m >= k, Q is defined as the first\nn columns of the product of k Householder reflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nIf m < k, Q is defined as the product of Householder reflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_{m-1}\n\\f]\n\nOn the other hand, if storev is row-wise, then the matrix Q has orthonormal rows. If n > k, Q is defined as the\nfirst m rows of the product of k Householder reflectors of order n\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nIf n <= k, Q is defined as the product of Householder reflectors of order n\n\n\\f[\nQ = H_{n-1}H_{n-2}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgebrd \"GEBRD\" in its arguments A and tauq or taup.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies whether to work column-wise or row-wise.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\nIf row-wise, then min(n,k) <= m <= n.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\nIf column-wise, then min(m,k) <= n <= m.\n@param[in]\nk rocblas_int. k >= 0.\\n\nThe number of columns (if storev is column-wise) or rows (if row-wise) of the\noriginal matrix reduced by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the Householder vectors as returned by \\ref rocsolver_sgebrd \"GEBRD\".\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension min(m,k) if column-wise, or min(n,k) if row-wise.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\"."] + pub fn rocsolver_sorgbr( + handle: rocblas_handle, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorgbr( + handle: rocblas_handle, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGBR generates an m-by-n complex Matrix Q with orthonormal rows or\ncolumns.\n\n\\details\nIf storev is column-wise, then the matrix Q has orthonormal columns. If m >= k, Q is defined as the first\nn columns of the product of k Householder reflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nIf m < k, Q is defined as the product of Householder reflectors of order m\n\n\\f[\nQ = H_1H_2\\cdots H_{m-1}\n\\f]\n\nOn the other hand, if storev is row-wise, then the matrix Q has orthonormal rows. If n > k, Q is defined as the\nfirst m rows of the product of k Householder reflectors of order n\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nIf n <= k, Q is defined as the product of Householder reflectors of order n\n\n\\f[\nQ = H_{n-1}H_{n-2}\\cdots H_1\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by \\ref rocsolver_sgebrd \"GEBRD\" in its arguments A and tauq or taup.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies whether to work column-wise or row-wise.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix Q.\nIf row-wise, then min(n,k) <= m <= n.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix Q.\nIf column-wise, then min(m,k) <= n <= m.\n@param[in]\nk rocblas_int. k >= 0.\\n\nThe number of columns (if storev is column-wise) or rows (if row-wise) of the\noriginal matrix reduced by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the Householder vectors as returned by \\ref rocsolver_sgebrd \"GEBRD\".\nOn exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension min(m,k) if column-wise, or min(n,k) if row-wise.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\"."] + pub fn rocsolver_cungbr( + handle: rocblas_handle, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zungbr( + handle: rocblas_handle, + storev: rocblas_storev, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORGTR generates an n-by-n orthogonal Matrix Q.\n\n\\details\nQ is defined as the product of n-1 Householder reflectors of order n. If\nuplo indicates upper, then Q has the form\n\n\\f[\nQ = H_{n-1}H_{n-2}\\cdots H_1\n\\f]\n\nOn the other hand, if uplo indicates lower, then Q has the form\n\n\\f[\nQ = H_1H_2\\cdots H_{n-1}\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by\n\\ref rocsolver_ssytrd \"SYTRD\" in its arguments A and tau.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the \\ref rocsolver_ssytrd \"SYTRD\" factorization was upper or lower\ntriangular. If uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix Q.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the Householder vectors as returned\nby \\ref rocsolver_ssytrd \"SYTRD\". On exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars as returned by \\ref rocsolver_ssytrd \"SYTRD\"."] + pub fn rocsolver_sorgtr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorgtr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNGTR generates an n-by-n unitary Matrix Q.\n\n\\details\nQ is defined as the product of n-1 Householder reflectors of order n. If\nuplo indicates upper, then Q has the form\n\n\\f[\nQ = H_{n-1}H_{n-2}\\cdots H_1\n\\f]\n\nOn the other hand, if uplo indicates lower, then Q has the form\n\n\\f[\nQ = H_1H_2\\cdots H_{n-1}\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors \\f$v_i\\f$ and scalars \\f$\\text{ipiv}[i]\\f$, as returned by\n\\ref rocsolver_chetrd \"HETRD\" in its arguments A and tau.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the \\ref rocsolver_chetrd \"HETRD\" factorization was upper or lower\ntriangular. If uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix Q.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the Householder vectors as returned\nby \\ref rocsolver_chetrd \"HETRD\". On exit, the computed matrix Q.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars as returned by \\ref rocsolver_chetrd \"HETRD\"."] + pub fn rocsolver_cungtr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zungtr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORM2R multiplies a matrix Q with orthonormal columns by a general m-by-n\nmatrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2 \\cdots H_k\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the QR factorization \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqrf \"GEQRF\"\nin the first k columns of its argument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, or lda >= n if side is right. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sorm2r( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorm2r( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNM2R multiplies a complex matrix Q with orthonormal columns by a\ngeneral m-by-n matrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the QR factorization \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqrf \"GEQRF\"\nin the first k columns of its argument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, or lda >= n if side is right. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C.\n"] + pub fn rocsolver_cunm2r( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunm2r( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORMQR multiplies a matrix Q with orthonormal columns by a general m-by-n\nmatrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the QR factorization \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqrf \"GEQRF\"\nin the first k columns of its argument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, or lda >= n if side is right. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sormqr( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dormqr( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNMQR multiplies a complex matrix Q with orthonormal columns by a\ngeneral m-by-n matrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the QR factorization \\ref rocsolver_sgeqrf \"GEQRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqrf \"GEQRF\"\nin the first k columns of its argument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, or lda >= n if side is right. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgeqrf \"GEQRF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunmqr( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunmqr( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORML2 multiplies a matrix Q with orthonormal rows by a general m-by-n\nmatrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the LQ factorization \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*m if side is left, or lda*n if side is right.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgelqf \"GELQF\"\nin the first k rows of its argument A.\n@param[in]\nlda rocblas_int. lda >= k. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C.\n"] + pub fn rocsolver_sorml2( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorml2( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNML2 multiplies a complex matrix Q with orthonormal rows by a general\nm-by-n matrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_k^HH_{k-1}^H\\cdots H_1^H\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the LQ factorization \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*m if side is left, or lda*n if side is right.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgelqf \"GELQF\"\nin the first k rows of its argument A.\n@param[in]\nlda rocblas_int. lda >= k. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunml2( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunml2( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORMLQ multiplies a matrix Q with orthonormal rows by a general m-by-n\nmatrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the LQ factorization \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*m if side is left, or lda*n if side is right.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgelqf \"GELQF\"\nin the first k rows of its argument A.\n@param[in]\nlda rocblas_int. lda >= k. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sormlq( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dormlq( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNMLQ multiplies a complex matrix Q with orthonormal rows by a general\nm-by-n matrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_k^HH_{k-1}^H\\cdots H_1^H\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is never stored, it is\ncalculated from the Householder vectors and scalars returned by the LQ factorization \\ref rocsolver_sgelqf \"GELQF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*m if side is left, or lda*n if side is right.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgelqf \"GELQF\"\nin the first k rows of its argument A.\n@param[in]\nlda rocblas_int. lda >= k. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by \\ref rocsolver_sgelqf \"GELQF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunmlq( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunmlq( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORM2L multiplies a matrix Q with orthonormal columns by a general m-by-n\nmatrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is\nnever stored, it is calculated from the Householder vectors and scalars\nreturned by the QL factorization \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be\napplied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqlf \"GEQLF\" in the last k columns of its\nargument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, lda >= n if side is right.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_sgeqlf \"GEQLF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sorm2l( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dorm2l( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNM2L multiplies a complex matrix Q with orthonormal columns by a\ngeneral m-by-n matrix C.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is\nnever stored, it is calculated from the Householder vectors and scalars\nreturned by the QL factorization \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate\ntranspose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqlf \"GEQLF\" in the last k columns of its\nargument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, lda >= n if side is right.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_sgeqlf \"GEQLF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunm2l( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunm2l( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORMQL multiplies a matrix Q with orthonormal columns by a general m-by-n\nmatrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is\nnever stored, it is calculated from the Householder vectors and scalars\nreturned by the QL factorization \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be\napplied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqlf \"GEQLF\" in the last k columns of its\nargument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, lda >= n if side is right.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_sgeqlf \"GEQLF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sormql( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dormql( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNMQL multiplies a complex matrix Q with orthonormal columns by a\ngeneral m-by-n matrix C.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nQ is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1\n\\f]\n\nof order m if applying from the left, or n if applying from the right. Q is\nnever stored, it is calculated from the Householder vectors and scalars\nreturned by the QL factorization \\ref rocsolver_sgeqlf \"GEQLF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate\ntranspose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0; k <= m if side is left, k <= n if side is right.\\n\nThe number of Householder reflectors that form Q.\n@param[in]\nA pointer to type. Array on the GPU of size lda*k.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgeqlf \"GEQLF\" in the last k columns of its\nargument A.\n@param[in]\nlda rocblas_int. lda >= m if side is left, lda >= n if side is right.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least k.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_sgeqlf \"GEQLF\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunmql( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunmql( + handle: rocblas_handle, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORMBR multiplies a matrix Q with orthonormal rows or columns by a\ngeneral m-by-n matrix C.\n\n\\details\nIf storev is column-wise, then the matrix Q has orthonormal columns.\nIf storev is row-wise, then the matrix Q has orthonormal rows.\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nThe order q of the orthogonal matrix Q is q = m if applying from the left, or q = n if applying from the right.\n\nWhen storev is column-wise, if q >= k, then Q is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k,\n\\f]\n\nand if q < k, then Q is defined as the product\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}.\n\\f]\n\nWhen storev is row-wise, if q > k, then Q is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k,\n\\f]\n\nand if q <= k, Q is defined as the product\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}.\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors and scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\" in its arguments A and tauq or taup.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies whether to work column-wise or row-wise.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0.\\n\nThe number of columns (if storev is column-wise) or rows (if row-wise) of the\noriginal matrix reduced by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[in]\nA pointer to type. Array on the GPU of size lda*min(q,k) if column-wise, or lda*q if row-wise.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[in]\nlda rocblas_int. lda >= q if column-wise, or lda >= min(q,k) if row-wise. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least min(q,k).\\n\nThe Householder scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sormbr( + handle: rocblas_handle, + storev: rocblas_storev, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dormbr( + handle: rocblas_handle, + storev: rocblas_storev, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNMBR multiplies a complex matrix Q with orthonormal rows or columns by\na general m-by-n matrix C.\n\n\\details\nIf storev is column-wise, then the matrix Q has orthonormal columns.\nIf storev is row-wise, then the matrix Q has orthonormal rows.\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nThe order q of the unitary matrix Q is q = m if applying from the left, or q = n if applying from the right.\n\nWhen storev is column-wise, if q >= k, then Q is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k,\n\\f]\n\nand if q < k, then Q is defined as the product\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}.\n\\f]\n\nWhen storev is row-wise, if q > k, then Q is defined as the product of k Householder reflectors\n\n\\f[\nQ = H_1H_2\\cdots H_k,\n\\f]\n\nand if q <= k, Q is defined as the product\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}.\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its corresponding\nHouseholder vectors and scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\" in its arguments A and tauq or taup.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nstorev #rocblas_storev.\\n\nSpecifies whether to work column-wise or row-wise.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate transpose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nk rocblas_int. k >= 0.\\n\nThe number of columns (if storev is column-wise) or rows (if row-wise) of the\noriginal matrix reduced by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[in]\nA pointer to type. Array on the GPU of size lda*min(q,k) if column-wise, or lda*q if row-wise.\\n\nThe Householder vectors as returned by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[in]\nlda rocblas_int. lda >= q if column-wise, or lda >= min(q,k) if row-wise. \\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least min(q,k).\\n\nThe Householder scalars as returned by \\ref rocsolver_sgebrd \"GEBRD\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunmbr( + handle: rocblas_handle, + storev: rocblas_storev, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunmbr( + handle: rocblas_handle, + storev: rocblas_storev, + side: rocblas_side, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + k: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief ORMTR multiplies an orthogonal matrix Q by a general m-by-n matrix C.\n\n\\details\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^TC & \\: \\text{Transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^T & \\: \\text{Transpose from the right.}\n\\end{array}\n\\f]\n\nThe order q of the orthogonal matrix Q is q = m if applying from the left, or\nq = n if applying from the right.\n\nQ is defined as a product of q-1 Householder reflectors. If\nuplo indicates upper, then Q has the form\n\n\\f[\nQ = H_{q-1}H_{q-2}\\cdots H_1.\n\\f]\n\nOn the other hand, if uplo indicates lower, then Q has the form\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors and scalars as returned by\n\\ref rocsolver_ssytrd \"SYTRD\" in its arguments A and tau.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the \\ref rocsolver_ssytrd \"SYTRD\" factorization was upper or\nlower triangular. If uplo indicates lower (or upper), then the upper (or\nlower) part of A is not used.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its transpose is to be\napplied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nA pointer to type. Array on the GPU of size lda*q.\\n\nOn entry, the Householder vectors as\nreturned by \\ref rocsolver_ssytrd \"SYTRD\".\n@param[in]\nlda rocblas_int. lda >= q.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least q-1.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_ssytrd \"SYTRD\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_sormtr( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + C: *mut f32, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dormtr( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + C: *mut f64, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief UNMTR multiplies a unitary matrix Q by a general m-by-n matrix C.\n\n\\details\nThe matrix Q is applied in one of the following forms, depending on\nthe values of side and trans:\n\n\\f[\n\\begin{array}{cl}\nQC & \\: \\text{No transpose from the left,}\\\\\nQ^HC & \\: \\text{Conjugate transpose from the left,}\\\\\nCQ & \\: \\text{No transpose from the right, and}\\\\\nCQ^H & \\: \\text{Conjugate transpose from the right.}\n\\end{array}\n\\f]\n\nThe order q of the unitary matrix Q is q = m if applying from the left, or\nq = n if applying from the right.\n\nQ is defined as a product of q-1 Householder reflectors. If\nuplo indicates upper, then Q has the form\n\n\\f[\nQ = H_{q-1}H_{q-2}\\cdots H_1.\n\\f]\n\nOn the other hand, if uplo indicates lower, then Q has the form\n\n\\f[\nQ = H_1H_2\\cdots H_{q-1}\n\\f]\n\nThe Householder matrices \\f$H_i\\f$ are never stored, they are computed from its\ncorresponding Householder vectors and scalars as returned by\n\\ref rocsolver_chetrd \"HETRD\" in its arguments A and tau.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nside rocblas_side.\\n\nSpecifies from which side to apply Q.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the \\ref rocsolver_chetrd \"HETRD\" factorization was upper or\nlower triangular. If uplo indicates lower (or upper), then the upper (or\nlower) part of A is not used.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies whether the matrix Q or its conjugate\ntranspose is to be applied.\n@param[in]\nm rocblas_int. m >= 0.\\n\nNumber of rows of matrix C.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of columns of matrix C.\n@param[in]\nA pointer to type. Array on the GPU of size lda*q.\\n\nOn entry, the Householder vectors as\nreturned by \\ref rocsolver_chetrd \"HETRD\".\n@param[in]\nlda rocblas_int. lda >= q.\\n\nLeading dimension of A.\n@param[in]\nipiv pointer to type. Array on the GPU of dimension at least q-1.\\n\nThe Householder scalars as returned by\n\\ref rocsolver_chetrd \"HETRD\".\n@param[inout]\nC pointer to type. Array on the GPU of size ldc*n.\\n\nOn entry, the matrix C. On exit, it is overwritten with\nQ*C, C*Q, Q'*C, or C*Q'.\n@param[in]\nldc rocblas_int. ldc >= m.\\n\nLeading dimension of C."] + pub fn rocsolver_cunmtr( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zunmtr( + handle: rocblas_handle, + side: rocblas_side, + uplo: rocblas_fill, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BDSQR computes the singular value decomposition (SVD) of an\nn-by-n bidiagonal matrix B, using the implicit QR algorithm.\n\n\\details\nThe SVD of B has the form:\n\n\\f[\nB = QSP'\n\\f]\n\nwhere S is the n-by-n diagonal matrix of singular values of B, the columns of Q are the left\nsingular vectors of B, and the columns of P are its right singular vectors.\n\nThe computation of the singular vectors is optional; this function accepts input matrices\nU (of size nu-by-n) and V (of size n-by-nv) that are overwritten with \\f$UQ\\f$ and \\f$P'V\\f$. If nu = 0\nno left vectors are computed; if nv = 0 no right vectors are computed.\n\nOptionally, this function can also compute \\f$Q'C\\f$ for a given n-by-nc input matrix C.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether B is upper or lower bidiagonal.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix B.\n@param[in]\nnv rocblas_int. nv >= 0.\\n\nThe number of columns of matrix V.\n@param[in]\nnu rocblas_int. nu >= 0.\\n\nThe number of rows of matrix U.\n@param[in]\nnc rocblas_int. nu >= 0.\\n\nThe number of columns of matrix C.\n@param[inout]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn entry, the diagonal elements of B. On exit, if info = 0,\nthe singular values of B in decreasing order; if info > 0,\nthe diagonal elements of a bidiagonal matrix\northogonally equivalent to B.\n@param[inout]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nOn entry, the off-diagonal elements of B. On exit, if info > 0,\nthe off-diagonal elements of a bidiagonal matrix\northogonally equivalent to B (if info = 0 this matrix converges to zero).\n@param[inout]\nV pointer to type. Array on the GPU of dimension ldv*nv.\\n\nOn entry, the matrix V. On exit, it is overwritten with P'*V.\n(Not referenced if nv = 0).\n@param[in]\nldv rocblas_int. ldv >= n if nv > 0, or ldv >=1 if nv = 0.\\n\nThe leading dimension of V.\n@param[inout]\nU pointer to type. Array on the GPU of dimension ldu*n.\\n\nOn entry, the matrix U. On exit, it is overwritten with U*Q.\n(Not referenced if nu = 0).\n@param[in]\nldu rocblas_int. ldu >= nu.\\n\nThe leading dimension of U.\n@param[inout]\nC pointer to type. Array on the GPU of dimension ldc*nc.\\n\nOn entry, the matrix C. On exit, it is overwritten with Q'*C.\n(Not referenced if nc = 0).\n@param[in]\nldc rocblas_int. ldc >= n if nc > 0, or ldc >=1 if nc = 0.\\n\nThe leading dimension of C.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, i elements of E have not converged to zero."] + pub fn rocsolver_sbdsqr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nv: rocblas_int, + nu: rocblas_int, + nc: rocblas_int, + D: *mut f32, + E: *mut f32, + V: *mut f32, + ldv: rocblas_int, + U: *mut f32, + ldu: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dbdsqr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nv: rocblas_int, + nu: rocblas_int, + nc: rocblas_int, + D: *mut f64, + E: *mut f64, + V: *mut f64, + ldv: rocblas_int, + U: *mut f64, + ldu: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cbdsqr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nv: rocblas_int, + nu: rocblas_int, + nc: rocblas_int, + D: *mut f32, + E: *mut f32, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zbdsqr( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nv: rocblas_int, + nu: rocblas_int, + nc: rocblas_int, + D: *mut f64, + E: *mut f64, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief STERF computes the eigenvalues of a symmetric tridiagonal matrix.\n\n\\details\nThe eigenvalues of the symmetric tridiagonal matrix are computed by the\nPal-Walker-Kahan variant of the QL/QR algorithm, and returned in\nincreasing order.\n\nThe matrix is not represented explicitly, but rather as the array of\ndiagonal elements D and the array of symmetric off-diagonal elements E.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the tridiagonal matrix.\n@param[inout]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn entry, the diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, the eigenvalues in increasing order.\nIf info > 0, the diagonal elements of a tridiagonal matrix\nthat is similar to the original matrix (i.e. has the same\neigenvalues).\n@param[inout]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nOn entry, the off-diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, this array converges to zero.\nIf info > 0, the off-diagonal elements of a tridiagonal matrix\nthat is similar to the original matrix (i.e. has the same\neigenvalues).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, STERF did not converge. i elements of E did not\nconverge to zero."] + pub fn rocsolver_ssterf( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsterf( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief STEQR computes the eigenvalues and (optionally) eigenvectors of\na symmetric tridiagonal matrix.\n\n\\details\nThe eigenvalues of the symmetric tridiagonal matrix are computed by the\nimplicit QL/QR algorithm, and returned in increasing order.\n\nThe matrix is not represented explicitly, but rather as the array of\ndiagonal elements D and the array of symmetric off-diagonal elements E.\nWhen D and E correspond to the tridiagonal form of a full symmetric/Hermitian matrix, as returned by, e.g.,\n\\ref rocsolver_ssytrd \"SYTRD\" or \\ref rocsolver_chetrd \"HETRD\", the eigenvectors of the original matrix can also\nbe computed, depending on the value of evect.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies how the eigenvectors are computed.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the tridiagonal matrix.\n@param[inout]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn entry, the diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, the eigenvalues in increasing order.\nIf info > 0, the diagonal elements of a tridiagonal matrix\nthat is similar to the original matrix (i.e. has the same\neigenvalues).\n@param[inout]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nOn entry, the off-diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, this array converges to zero.\nIf info > 0, the off-diagonal elements of a tridiagonal matrix\nthat is similar to the original matrix (i.e. has the same\neigenvalues).\n@param[inout]\nC pointer to type. Array on the GPU of dimension ldc*n.\\n\nOn entry, if evect is original, the orthogonal/unitary matrix\nused for the reduction to tridiagonal form as returned by, e.g.,\n\\ref rocsolver_sorgtr \"ORGTR\" or \\ref rocsolver_cungtr \"UNGTR\".\nOn exit, it is overwritten with the eigenvectors of the original\nsymmetric/Hermitian matrix (if evect is original), or the\neigenvectors of the tridiagonal matrix (if evect is tridiagonal).\n(Not referenced if evect is none).\n@param[in]\nldc rocblas_int. ldc >= n if evect is original or tridiagonal.\\n\nSpecifies the leading dimension of C.\n(Not referenced if evect is none).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, STEQR did not converge. i elements of E did not\nconverge to zero."] + pub fn rocsolver_ssteqr( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsteqr( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csteqr( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsteqr( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief STEDC computes the eigenvalues and (optionally) eigenvectors of\na symmetric tridiagonal matrix.\n\n\\details\nThis function uses the divide and conquer method to compute the eigenvectors.\nThe eigenvalues are returned in increasing order.\n\nThe matrix is not represented explicitly, but rather as the array of\ndiagonal elements D and the array of symmetric off-diagonal elements E.\nWhen D and E correspond to the tridiagonal form of a full symmetric/Hermitian matrix, as returned by, e.g.,\n\\ref rocsolver_ssytrd \"SYTRD\" or \\ref rocsolver_chetrd \"HETRD\", the eigenvectors of the original matrix can also\nbe computed, depending on the value of evect.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies how the eigenvectors are computed.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the tridiagonal matrix.\n@param[inout]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn entry, the diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, the eigenvalues in increasing order.\n@param[inout]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nOn entry, the off-diagonal elements of the tridiagonal matrix.\nOn exit, if info = 0, the values of this array are destroyed.\n@param[inout]\nC pointer to type. Array on the GPU of dimension ldc*n.\\n\nOn entry, if evect is original, the orthogonal/unitary matrix\nused for the reduction to tridiagonal form as returned by, e.g.,\n\\ref rocsolver_sorgtr \"ORGTR\" or \\ref rocsolver_cungtr \"UNGTR\".\nOn exit, if info = 0, it is overwritten with the eigenvectors of the original\nsymmetric/Hermitian matrix (if evect is original), or the\neigenvectors of the tridiagonal matrix (if evect is tridiagonal).\n(Not referenced if evect is none).\n@param[in]\nldc rocblas_int. ldc >= n if evect is original or tridiagonal.\\n\nSpecifies the leading dimension of C. (Not referenced if evect is none).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, STEDC failed to compute an eigenvalue on the sub-matrix formed by\nthe rows and columns info/(n+1) through mod(info,n+1)."] + pub fn rocsolver_sstedc( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dstedc( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cstedc( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zstedc( + handle: rocblas_handle, + evect: rocblas_evect, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief STEBZ computes a set of eigenvalues of a symmetric tridiagonal matrix T.\n\n\\details\nThis function computes all the eigenvalues of T, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange.\n\nThe eigenvalues are returned in increasing order either for the entire matrix, or grouped by independent\ndiagonal blocks (if they exist), depending on the value of eorder.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\neorder #rocblas_eorder.\\n\nSpecifies whether the computed eigenvalues will be ordered by their position in the\nentire spectrum, or grouped by independent diagonal (split off) blocks.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the tridiagonal matrix T.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if erange indicates to look\nfor all the eigenvalues of T or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if erange indicates to look\nfor all the eigenvalues of T or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if erange indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the largest eigenvalue to be computed. Ignored if erange indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[in]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe diagonal elements of the tridiagonal matrix.\n@param[in]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of the tridiagonal matrix.\n@param[out]\nnev pointer to a rocblas_int on the GPU. \\n\nThe total number of eigenvalues found.\n@param[out]\nnsplit pointer to a rocblas_int on the GPU.\\n\nThe number of split off blocks in the matrix.\n@param[out]\nW pointer to real type. Array on the GPU of dimension n.\\n\nThe first nev elements contain the computed eigenvalues. (The remaining elements\nmay be used as workspace for internal computations).\n@param[out]\niblock pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe block indices corresponding to each eigenvalue. When matrix T has\nsplit off blocks (nsplit > 1), then if iblock[i] = k, the\neigenvalue W[i] belongs to the k-th diagonal block from the top.\n@param[out]\nisplit pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe splitting indices that divide the tridiagonal matrix into\ndiagonal blocks. The k-th block stretches from the end of the (k-1)-th\nblock (or the top left corner of the tridiagonal matrix,\nin the case of the 1st block) to the isplit[k]-th row/column.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = 1, the bisection did not converge for some eigenvalues, i.e. the returned\nvalues are not as accurate as the given tolerance. The non-converged eigenvalues\nare flagged by negative entries in iblock.\n"] + pub fn rocsolver_sstebz( + handle: rocblas_handle, + erange: rocblas_erange, + eorder: rocblas_eorder, + n: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + D: *mut f32, + E: *mut f32, + nev: *mut rocblas_int, + nsplit: *mut rocblas_int, + W: *mut f32, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dstebz( + handle: rocblas_handle, + erange: rocblas_erange, + eorder: rocblas_eorder, + n: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + D: *mut f64, + E: *mut f64, + nev: *mut rocblas_int, + nsplit: *mut rocblas_int, + W: *mut f64, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief STEIN computes the eigenvectors associated with a set of\nprovided eigenvalues of a symmetric tridiagonal matrix.\n\n\\details\nThe eigenvectors of the symmetric tridiagonal matrix are computed using\ninverse iteration.\n\nThe matrix is not represented explicitly, but rather as the array of\ndiagonal elements D and the array of symmetric off-diagonal elements E.\nThe eigenvalues must be provided in the array W, as returned by \\ref rocsolver_sstebz \"STEBZ\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the tridiagonal matrix.\n@param[in]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe diagonal elements of the tridiagonal matrix.\n@param[in]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of the tridiagonal matrix.\n@param[in]\nnev pointer to a rocblas_int on the GPU. 0 <= nev <= n.\\n\nThe number of provided eigenvalues, and the number of eigenvectors\nto be computed.\n@param[in]\nW pointer to real type. Array on the GPU of dimension >= nev.\\n\nA subset of nev eigenvalues of the tridiagonal matrix, as returned\nby \\ref rocsolver_sstebz \"STEBZ\".\n@param[in]\niblock pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe block indices corresponding to each eigenvalue, as\nreturned by \\ref rocsolver_sstebz \"STEBZ\". If iblock[i] = k,\nthen eigenvalue W[i] belongs to the k-th block from the top.\n@param[in]\nisplit pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe splitting indices that divide the tridiagonal matrix into\ndiagonal blocks, as returned by \\ref rocsolver_sstebz \"STEBZ\".\nThe k-th block stretches from the end of the (k-1)-th\nblock (or the top left corner of the tridiagonal matrix,\nin the case of the 1st block) to the isplit[k]-th row/column.\n@param[out]\nZ pointer to type. Array on the GPU of dimension ldz*nev.\\n\nOn exit, contains the eigenvectors of the tridiagonal matrix\ncorresponding to the provided eigenvalues, stored by columns.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nev elements of ifail are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, i eigenvectors did not converge; their indices are stored in\nifail.\n"] + pub fn rocsolver_sstein( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + nev: *mut rocblas_int, + W: *mut f32, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + Z: *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dstein( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + nev: *mut rocblas_int, + W: *mut f64, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + Z: *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cstein( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + nev: *mut rocblas_int, + W: *mut f32, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + Z: *mut rocblas_float_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zstein( + handle: rocblas_handle, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + nev: *mut rocblas_int, + W: *mut f64, + iblock: *mut rocblas_int, + isplit: *mut rocblas_int, + Z: *mut rocblas_double_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief BDSVDX computes a set of singular values of a bidiagonal matrix B.\n\n\\details\nThis function computes all the singular values of B, all the singular values in the half-open interval\n\\f$[vl, vu)\\f$, or the il-th through iu-th singular values, depending on the value of srange.\n\nDepending on the value of svect, the corresponding singular vectors will be computed and stored as blocks\nin the output matrix Z. That is,\n\n\\f[\nZ = \\left[\\begin{array}{c}\nU\\\\\nV\n\\end{array}\\right]\n\\f]\n\nwhere U contains the corresponding left singular vectors of B, and V contains the corresponding right\nsingular vectors.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether B is upper or lower bidiagonal.\n@param[in]\nsvect #rocblas_svect.\\n\nSpecifies how the singular vectors are computed. Only rocblas_svect_none and\nrocblas_svect_singular are accepted.\n@param[in]\nsrange #rocblas_srange.\\n\nSpecifies the type of range or interval of the singular values to be computed.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the bidiagonal matrix B.\n@param[in]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe diagonal elements of the bidiagonal matrix.\n@param[in]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of the bidiagonal matrix.\n@param[in]\nvl real type. 0 <= vl < vu.\\n\nThe lower bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of B or the singular values within a set of indices.\n@param[in]\nvu real type. 0 <= vl < vu.\\n\nThe upper bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of B or the singular values within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the largest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of B or the singular values in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of B or the singular values in a half-open interval.\n@param[out]\nnsv pointer to a rocblas_int on the GPU. \\n\nThe total number of singular values found. If srange is rocblas_srange_all, nsv = n.\nIf srange is rocblas_srange_index, nsv = iu - il + 1. Otherwise, 0 <= nsv <= n.\n@param[out]\nS pointer to real type. Array on the GPU of dimension n.\\n\nThe first nsv elements contain the computed singular values in descending order.\n@param[out]\nZ pointer to real type. Array on the GPU of dimension ldz*nsv.\\n\nIf info = 0, the first nsv columns contain the computed singular vectors corresponding to the\nsingular values in S. The first n rows of Z contain the matrix U, and the next n rows contain\nthe matrix V. Not referenced if svect is rocblas_svect_none.\nNote: If srange is rocblas_srange_value, then the values of nsv are not known in advance.\nThe user should ensure that Z is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= 2*n if svect is rocblas_svect_singular; ldz >= 1 otherwise.\\n\nSpecifies the leading dimension of Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nsv elements of ifail are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge, as returned by \\ref rocsolver_sstein \"STEIN\".\nNot referenced if svect is rocblas_svect_none.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, i eigenvectors did not converge in \\ref rocsolver_sstein \"STEIN\"; their\nindices are stored in ifail.\n"] + pub fn rocsolver_sbdsvdx( + handle: rocblas_handle, + uplo: rocblas_fill, + svect: rocblas_svect, + srange: rocblas_srange, + n: rocblas_int, + D: *mut f32, + E: *mut f32, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + Z: *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dbdsvdx( + handle: rocblas_handle, + uplo: rocblas_fill, + svect: rocblas_svect, + srange: rocblas_srange, + n: rocblas_int, + D: *mut f64, + E: *mut f64, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + Z: *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2_NPVT computes the LU factorization of a general m-by-n matrix A\nwithout partial pivoting.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization has the form\n\n\\f[\nA = LU\n\\f]\n\nwhere L is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and U is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetf2 \"GETF2\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix A to be factored.\nOn exit, the factors L and U from the factorization.\nThe unit diagonal elements of L are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete."] + pub fn rocsolver_sgetf2_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2_NPVT_BATCHED computes the LU factorization of a batch of\ngeneral m-by-n matrices without partial pivoting.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = L_jU_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetf2_batched \"GETF2_BATCHED\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorizations.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetf2_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2_NPVT_STRIDED_BATCHED computes the LU factorization of a batch\nof general m-by-n matrices without partial pivoting.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = L_jU_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetf2_strided_batched \"GETF2_STRIDED_BATCHED\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorization.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetf2_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF_NPVT computes the LU factorization of a general m-by-n matrix A\nwithout partial pivoting.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization has the form\n\n\\f[\nA = LU\n\\f]\n\nwhere L is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and U is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetrf \"GETRF\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix A to be factored.\nOn exit, the factors L and U from the factorization.\nThe unit diagonal elements of L are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete."] + pub fn rocsolver_sgetrf_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf_npvt( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF_NPVT_BATCHED computes the LU factorization of a batch of\ngeneral m-by-n matrices without partial pivoting.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = L_jU_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorizations.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch.\n"] + pub fn rocsolver_sgetrf_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf_npvt_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF_NPVT_STRIDED_BATCHED computes the LU factorization of a batch\nof general m-by-n matrices without partial pivoting.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = L_jU_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\nNote: Although this routine can offer better performance, Gaussian elimination without pivoting is not backward stable.\nIf numerical accuracy is compromised, use the legacy-LAPACK-like API \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\" routines instead.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorization.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero element in the diagonal. The factorization from\nthis point might be incomplete.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch.\n"] + pub fn rocsolver_sgetrf_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf_npvt_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2 computes the LU factorization of a general m-by-n matrix A\nusing partial pivoting with row interchanges.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization has the form\n\n\\f[\nA = PLU\n\\f]\n\nwhere P is a permutation matrix, L is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and U is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix A to be factored.\nOn exit, the factors L and U from the factorization.\nThe unit diagonal elements of L are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension min(m,n).\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= i <= min(m,n), the row i of the\nmatrix was interchanged with row ipiv[i].\nMatrix P of the factorization can be derived from ipiv.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetf2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2_BATCHED computes the LU factorization of a batch of general\nm-by-n matrices using partial pivoting with row interchanges.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = P_jL_jU_j\n\\f]\n\nwhere \\f$P_j\\f$ is a permutation matrix, \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorizations.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors of pivot indices ipiv_j (corresponding to A_j).\nDimension of ipiv_j is min(m,n).\nElements of ipiv_j are 1-based indices.\nFor each instance A_j in the batch and for 1 <= i <= min(m,n), the row i of the\nmatrix A_j was interchanged with row ipiv_j[i].\nMatrix P_j of the factorization can be derived from ipiv_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= min(m,n).\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetf2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETF2_STRIDED_BATCHED computes the LU factorization of a batch of\ngeneral m-by-n matrices using partial pivoting with row interchanges.\n\n\\details\n(This is the unblocked Level-2-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with small and mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = P_jL_jU_j\n\\f]\n\nwhere \\f$P_j\\f$ is a permutation matrix, \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorization.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors of pivots indices ipiv_j (corresponding to A_j).\nDimension of ipiv_j is min(m,n).\nElements of ipiv_j are 1-based indices.\nFor each instance A_j in the batch and for 1 <= i <= min(m,n), the row i of the\nmatrix A_j was interchanged with row ipiv_j[i].\nMatrix P_j of the factorization can be derived from ipiv_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= min(m,n).\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetf2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetf2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetf2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetf2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF computes the LU factorization of a general m-by-n matrix A\nusing partial pivoting with row interchanges.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization has the form\n\n\\f[\nA = PLU\n\\f]\n\nwhere P is a permutation matrix, L is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and U is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix A to be factored.\nOn exit, the factors L and U from the factorization.\nThe unit diagonal elements of L are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension min(m,n).\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= i <= min(m,n), the row i of the\nmatrix was interchanged with row ipiv[i].\nMatrix P of the factorization can be derived from ipiv.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF_BATCHED computes the LU factorization of a batch of general\nm-by-n matrices using partial pivoting with row interchanges.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = P_jL_jU_j\n\\f]\n\nwhere \\f$P_j\\f$ is a permutation matrix, \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorizations.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors of pivot indices ipiv_j (corresponding to A_j).\nDimension of ipiv_j is min(m,n).\nElements of ipiv_j are 1-based indices.\nFor each instance A_j in the batch and for 1 <= i <= min(m,n), the row i of the\nmatrix A_j was interchanged with row ipiv_j[i].\nMatrix P_j of the factorization can be derived from ipiv_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= min(m,n).\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRF_STRIDED_BATCHED computes the LU factorization of a batch of\ngeneral m-by-n matrices using partial pivoting with row interchanges.\n\n\\details\n(This is the blocked Level-3-BLAS version of the algorithm. An optimized internal implementation without rocBLAS calls\ncould be executed with mid-size matrices if optimizations are enabled (default option). For more details, see the\n\"Tuning rocSOLVER performance\" section of the Library Design Guide).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = P_jL_jU_j\n\\f]\n\nwhere \\f$P_j\\f$ is a permutation matrix, \\f$L_j\\f$ is lower triangular with unit\ndiagonal elements (lower trapezoidal if m > n), and \\f$U_j\\f$ is upper\ntriangular (upper trapezoidal if m < n).\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the factors L_j and U_j from the factorization.\nThe unit diagonal elements of L_j are not stored.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors of pivots indices ipiv_j (corresponding to A_j).\nDimension of ipiv_j is min(m,n).\nElements of ipiv_j are 1-based indices.\nFor each instance A_j in the batch and for 1 <= i <= min(m,n), the row i of the\nmatrix A_j was interchanged with row ipiv_j[i].\nMatrix P_j of the factorization can be derived from ipiv_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= min(m,n).\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQR2 computes a QR factorization of a general m-by-n matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = Q\\left[\\begin{array}{c}\nR\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere R is upper triangular (upper trapezoidal if m < n), and Q is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_1H_2\\cdots H_k, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R; the elements below the diagonal are the last m - i elements\nof Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgeqr2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqr2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqr2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqr2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQR2_BATCHED computes the QR factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\nR_j\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_k}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R_j. The elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqr2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqr2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqr2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqr2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQR2_STRIDED_BATCHED computes the QR factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\nR_j\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_k}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R_j. The elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqr2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqr2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqr2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqr2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQ2 computes a RQ factorization of a general m-by-n matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = \\left[\\begin{array}{cc}\n0 & R\n\\end{array}\\right] Q\n\\f]\n\nwhere R is upper triangular (upper trapezoidal if m > n), and Q is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_1'H_2' \\cdots H_k', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgerq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQ2_BATCHED computes the RQ factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\n0 & R_j\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}'H_{j_2}' \\cdots H_{j_k}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last n-i elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R_j; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgerq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQ2_STRIDED_BATCHED computes the RQ factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\n0 & R_j\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}'H_{j_2}' \\cdots H_{j_k}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last n-i elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R_j; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgerq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQL2 computes a QL factorization of a general m-by-n matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = Q\\left[\\begin{array}{c}\n0\\\\\nL\n\\end{array}\\right]\n\\f]\n\nwhere L is lower triangular (lower trapezoidal if m < n), and Q is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgeql2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeql2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeql2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeql2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQL2_BATCHED computes the QL factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\n0\\\\\nL_j\n\\end{array}\\right]\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_{j_k}H_{j_{k-1}}\\cdots H_{j_1}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L_j; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeql2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeql2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeql2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeql2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQL2_STRIDED_BATCHED computes the QL factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\n0\\\\\nL_j\n\\end{array}\\right]\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_{j_k}H_{j_{k-1}}\\cdots H_{j_1}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L_j; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeql2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeql2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeql2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeql2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQ2 computes a LQ factorization of a general m-by-n matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = \\left[\\begin{array}{cc}\nL & 0\n\\end{array}\\right] Q\n\\f]\n\nwhere L is lower triangular (lower trapezoidal if m > n), and Q is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_k'H_{k-1}' \\cdots H_1', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i' v_i\n\\f]\n\nwhere the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L; the elements above the diagonal are the last n - i elements\nof Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgelq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelq2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQ2_BATCHED computes the LQ factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\nL_j & 0\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_k}'H_{j_{k-1}}' \\cdots H_{j_1}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i}' v_{j_i}\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L_j. The elements above the diagonal are the last n - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgelq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelq2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQ2_STRIDED_BATCHED computes the LQ factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\nL_j & 0\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_k}'H_{j_{k-1}}' \\cdots H_{j_1}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i}' v_{j_i}\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L_j. The elements above the diagonal are the last n - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgelq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelq2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQRF computes a QR factorization of a general m-by-n matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = Q\\left[\\begin{array}{c}\nR\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere R is upper triangular (upper trapezoidal if m < n), and Q is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_1H_2\\cdots H_k, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R; the elements below the diagonal are the last m - i elements\nof Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgeqrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqrf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQRF_BATCHED computes the QR factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\nR_j\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_k}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R_j. The elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqrf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQRF_STRIDED_BATCHED computes the QR factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\nR_j\\\\\n0\n\\end{array}\\right]\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_k}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the diagonal contain the\nfactor R_j. The elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqrf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQF computes a RQ factorization of a general m-by-n matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = \\left[\\begin{array}{cc}\n0 & R\n\\end{array}\\right] Q\n\\f]\n\nwhere R is upper triangular (upper trapezoidal if m > n), and Q is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_1'H_2' \\cdots H_k', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgerqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQF_BATCHED computes the RQ factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\n0 & R_j\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}'H_{j_2}' \\cdots H_{j_k}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last n-i elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R_j; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgerqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GERQF_STRIDED_BATCHED computes the RQ factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\n0 & R_j\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$R_j\\f$ is upper triangular (upper trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_1}'H_{j_2}' \\cdots H_{j_k}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last n-i elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and above the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor R_j; the elements below the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgerqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgerqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgerqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgerqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQLF computes a QL factorization of a general m-by-n matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = Q\\left[\\begin{array}{c}\n0\\\\\nL\n\\end{array}\\right]\n\\f]\n\nwhere L is lower triangular (lower trapezoidal if m < n), and Q is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_kH_{k-1}\\cdots H_1, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i v_i'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgeqlf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqlf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqlf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqlf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQLF_BATCHED computes the QL factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\n0\\\\\nL_j\n\\end{array}\\right]\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_{j_k}H_{j_{k-1}}\\cdots H_{j_1}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L_j; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqlf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqlf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqlf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqlf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEQLF_STRIDED_BATCHED computes the QL factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = Q_j\\left[\\begin{array}{c}\n0\\\\\nL_j\n\\end{array}\\right]\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m < n), and \\f$Q_j\\f$ is\na m-by-m orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_{j_k}H_{j_{k-1}}\\cdots H_{j_1}, \\quad \\text{with} \\: k = \\text{min}(m,n)\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere the last m-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the (m-n)-th subdiagonal (when\nm >= n) or the (n-m)-th superdiagonal (when n > m) contain the\nfactor L_j; the elements above the sub/superdiagonal are the first i - 1\nelements of Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeqlf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeqlf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeqlf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeqlf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQF computes a LQ factorization of a general m-by-n matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\nA = \\left[\\begin{array}{cc}\nL & 0\n\\end{array}\\right] Q\n\\f]\n\nwhere L is lower triangular (lower trapezoidal if m > n), and Q is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ = H_k'H_{k-1}' \\cdots H_1', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{ipiv}[i] \\cdot v_i' v_i\n\\f]\n\nwhere the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L; the elements above the diagonal are the last n - i elements\nof Householder vector v_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars."] + pub fn rocsolver_sgelqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelqf( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQF_BATCHED computes the LQ factorization of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\nL_j & 0\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_k}'H_{j_{k-1}}' \\cdots H_{j_1}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i}' v_{j_i}\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L_j. The elements above the diagonal are the last n - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgelqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelqf_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELQF_STRIDED_BATCHED computes the LQ factorization of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form\n\n\\f[\nA_j = \\left[\\begin{array}{cc}\nL_j & 0\n\\end{array}\\right] Q_j\n\\f]\n\nwhere \\f$L_j\\f$ is lower triangular (lower trapezoidal if m > n), and \\f$Q_j\\f$ is\na n-by-n orthogonal/unitary matrix represented as the product of Householder matrices\n\n\\f[\nQ_j = H_{j_k}'H_{j_{k-1}}' \\cdots H_{j_1}', \\quad \\text{with} \\: k = \\text{min}(m,n).\n\\f]\n\nEach Householder matrices \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{ipiv}_j[i] \\cdot v_{j_i}' v_{j_i}\n\\f]\n\nwhere the first i-1 elements of Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on and below the diagonal contain the\nfactor L_j. The elements above the diagonal are the last n - i elements\nof Householder vector v_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgelqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgelqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgelqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgelqf_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBD2 computes the bidiagonal form of a general m-by-n matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe bidiagonal form is given by:\n\n\\f[\nB = Q' A P\n\\f]\n\nwhere B is upper bidiagonal if m >= n and lower bidiagonal if m < n, and Q and\nP are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_n\\: \\text{and} \\: P = G_1G_2\\cdots G_{n-1}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ = H_1H_2\\cdots H_{m-1}\\: \\text{and} \\: P = G_1G_2\\cdots G_{m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ and \\f$G_i\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_i = I - \\text{tauq}[i] \\cdot v_i v_i', & \\: \\text{and}\\\\\nG_i = I - \\text{taup}[i] \\cdot u_i' u_i.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_i, and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_i.\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_i, and the elements above the\ndiagonal are the last n - i elements of Householder vector u_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nspecifies the leading dimension of A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension min(m,n).\\n\nThe diagonal elements of B.\n@param[out]\nE pointer to real type. Array on the GPU of dimension min(m,n)-1.\\n\nThe off-diagonal elements of B.\n@param[out]\ntauq pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars associated with matrix Q.\n@param[out]\ntaup pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars associated with matrix P."] + pub fn rocsolver_sgebd2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut f32, + taup: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebd2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut f64, + taup: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebd2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut rocblas_float_complex, + taup: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebd2( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut rocblas_double_complex, + taup: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBD2_BATCHED computes the bidiagonal form of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the bidiagonal form is given by:\n\n\\f[\nB_j = Q_j' A_j P_j\n\\f]\n\nwhere \\f$B_j\\f$ is upper bidiagonal if m >= n and lower bidiagonal if m < n, and \\f$Q_j\\f$ and\n\\f$P_j\\f$ are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_n}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_{n-1}}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{m-1}}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ and \\f$G_{j_i}\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_{j_i} = I - \\text{tauq}_j[i] \\cdot v_{j_i} v_{j_i}', & \\: \\text{and}\\\\\nG_{j_i} = I - \\text{taup}_j[i] \\cdot u_{j_i}' u_{j_i}.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B_j.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i), and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_(j_i).\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_(j_i), and the elements above the\ndiagonal are the last n - i elements of Householder vector u_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of B_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= min(m,n).\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of B_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= min(m,n)-1.\n@param[out]\ntauq pointer to type. Array on the GPU (the size depends on the value of strideQ).\\n\nContains the vectors tauq_j of Householder scalars associated with matrices Q_j.\n@param[in]\nstrideQ rocblas_stride.\\n\nStride from the start of one vector tauq_j to the next one tauq_(j+1).\nThere is no restriction for the value\nof strideQ. Normal use is strideQ >= min(m,n).\n@param[out]\ntaup pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors taup_j of Householder scalars associated with matrices P_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector taup_j to the next one taup_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgebd2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut f32, + strideQ: rocblas_stride, + taup: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebd2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut f64, + strideQ: rocblas_stride, + taup: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebd2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut rocblas_float_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebd2_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut rocblas_double_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBD2_STRIDED_BATCHED computes the bidiagonal form of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the bidiagonal form is given by:\n\n\\f[\nB_j = Q_j' A_j P_j\n\\f]\n\nwhere \\f$B_j\\f$ is upper bidiagonal if m >= n and lower bidiagonal if m < n, and \\f$Q_j\\f$ and\n\\f$P_j\\f$ are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_n}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_{n-1}}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{m-1}}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ and \\f$G_{j_i}\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_{j_i} = I - \\text{tauq}_j[i] \\cdot v_{j_i} v_{j_i}', & \\: \\text{and}\\\\\nG_{j_i} = I - \\text{taup}_j[i] \\cdot u_{j_i}' u_{j_i}.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B_j.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i), and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_(j_i).\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_(j_i), and the elements above the\ndiagonal are the last n - i elements of Householder vector u_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of B_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= min(m,n).\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of B_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= min(m,n)-1.\n@param[out]\ntauq pointer to type. Array on the GPU (the size depends on the value of strideQ).\\n\nContains the vectors tauq_j of Householder scalars associated with matrices Q_j.\n@param[in]\nstrideQ rocblas_stride.\\n\nStride from the start of one vector tauq_j to the next one tauq_(j+1).\nThere is no restriction for the value\nof strideQ. Normal use is strideQ >= min(m,n).\n@param[out]\ntaup pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors taup_j of Householder scalars associated with matrices P_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector taup_j to the next one taup_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgebd2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut f32, + strideQ: rocblas_stride, + taup: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebd2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut f64, + strideQ: rocblas_stride, + taup: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebd2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut rocblas_float_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebd2_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut rocblas_double_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBRD computes the bidiagonal form of a general m-by-n matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe bidiagonal form is given by:\n\n\\f[\nB = Q' A P\n\\f]\n\nwhere B is upper bidiagonal if m >= n and lower bidiagonal if m < n, and Q and\nP are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_n\\: \\text{and} \\: P = G_1G_2\\cdots G_{n-1}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ = H_1H_2\\cdots H_{m-1}\\: \\text{and} \\: P = G_1G_2\\cdots G_{m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ and \\f$G_i\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_i = I - \\text{tauq}[i] \\cdot v_i v_i', & \\: \\text{and}\\\\\nG_i = I - \\text{taup}[i] \\cdot u_i' u_i.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_i\\f$ are zero, and \\f$u_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of the matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrix to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_i, and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_i.\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_i, and the elements above the\ndiagonal are the last n - i elements of Householder vector u_i.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nspecifies the leading dimension of A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension min(m,n).\\n\nThe diagonal elements of B.\n@param[out]\nE pointer to real type. Array on the GPU of dimension min(m,n)-1.\\n\nThe off-diagonal elements of B.\n@param[out]\ntauq pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars associated with matrix Q.\n@param[out]\ntaup pointer to type. Array on the GPU of dimension min(m,n).\\n\nThe Householder scalars associated with matrix P."] + pub fn rocsolver_sgebrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut f32, + taup: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut f64, + taup: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tauq: *mut rocblas_float_complex, + taup: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebrd( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tauq: *mut rocblas_double_complex, + taup: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBRD_BATCHED computes the bidiagonal form of a batch of general\nm-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the bidiagonal form is given by:\n\n\\f[\nB_j = Q_j' A_j P_j\n\\f]\n\nwhere \\f$B_j\\f$ is upper bidiagonal if m >= n and lower bidiagonal if m < n, and \\f$Q_j\\f$ and\n\\f$P_j\\f$ are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_n}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_{n-1}}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{m-1}}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ and \\f$G_{j_i}\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_{j_i} = I - \\text{tauq}_j[i] \\cdot v_{j_i} v_{j_i}', & \\: \\text{and}\\\\\nG_{j_i} = I - \\text{taup}_j[i] \\cdot u_{j_i}' u_{j_i}.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B_j.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i), and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_(j_i).\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_(j_i), and the elements above the\ndiagonal are the last n - i elements of Householder vector u_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of B_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= min(m,n).\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of B_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= min(m,n)-1.\n@param[out]\ntauq pointer to type. Array on the GPU (the size depends on the value of strideQ).\\n\nContains the vectors tauq_j of Householder scalars associated with matrices Q_j.\n@param[in]\nstrideQ rocblas_stride.\\n\nStride from the start of one vector tauq_j to the next one tauq_(j+1).\nThere is no restriction for the value\nof strideQ. Normal use is strideQ >= min(m,n).\n@param[out]\ntaup pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors taup_j of Householder scalars associated with matrices P_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector taup_j to the next one taup_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgebrd_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut f32, + strideQ: rocblas_stride, + taup: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebrd_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut f64, + strideQ: rocblas_stride, + taup: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebrd_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut rocblas_float_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebrd_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut rocblas_double_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBRD_STRIDED_BATCHED computes the bidiagonal form of a batch of\ngeneral m-by-n matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the bidiagonal form is given by:\n\n\\f[\nB_j = Q_j' A_j P_j\n\\f]\n\nwhere \\f$B_j\\f$ is upper bidiagonal if m >= n and lower bidiagonal if m < n, and \\f$Q_j\\f$ and\n\\f$P_j\\f$ are orthogonal/unitary matrices represented as the product of Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_n}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_{n-1}}, & \\: \\text{if}\\: m >= n, \\:\\text{or}\\\\\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{m-1}}\\: \\text{and} \\: P_j = G_{j_1}G_{j_2}\\cdots G_{j_m}, & \\: \\text{if}\\: m < n.\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ and \\f$G_{j_i}\\f$ is given by\n\n\\f[\n\\begin{array}{cl}\nH_{j_i} = I - \\text{tauq}_j[i] \\cdot v_{j_i} v_{j_i}', & \\: \\text{and}\\\\\nG_{j_i} = I - \\text{taup}_j[i] \\cdot u_{j_i}' u_{j_i}.\n\\end{array}\n\\f]\n\nIf m >= n, the first i-1 elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$;\nwhile the first i elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i+1] = 1\\f$.\nIf m < n, the first i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$;\nwhile the first i-1 elements of the Householder vector \\f$u_{j_i}\\f$ are zero, and \\f$u_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all the matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all the matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the m-by-n matrices A_j to be factored.\nOn exit, the elements on the diagonal and superdiagonal (if m >= n), or\nsubdiagonal (if m < n) contain the bidiagonal form B_j.\nIf m >= n, the elements below the diagonal are the last m - i elements\nof Householder vector v_(j_i), and the elements above the\nsuperdiagonal are the last n - i - 1 elements of Householder vector u_(j_i).\nIf m < n, the elements below the subdiagonal are the last m - i - 1\nelements of Householder vector v_(j_i), and the elements above the\ndiagonal are the last n - i elements of Householder vector u_(j_i).\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of B_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= min(m,n).\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of B_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= min(m,n)-1.\n@param[out]\ntauq pointer to type. Array on the GPU (the size depends on the value of strideQ).\\n\nContains the vectors tauq_j of Householder scalars associated with matrices Q_j.\n@param[in]\nstrideQ rocblas_stride.\\n\nStride from the start of one vector tauq_j to the next one tauq_(j+1).\nThere is no restriction for the value\nof strideQ. Normal use is strideQ >= min(m,n).\n@param[out]\ntaup pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors taup_j of Householder scalars associated with matrices P_j.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector taup_j to the next one taup_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= min(m,n).\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgebrd_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut f32, + strideQ: rocblas_stride, + taup: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgebrd_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut f64, + strideQ: rocblas_stride, + taup: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgebrd_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tauq: *mut rocblas_float_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgebrd_strided_batched( + handle: rocblas_handle, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tauq: *mut rocblas_double_complex, + strideQ: rocblas_stride, + taup: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRS solves a system of n linear equations on n variables in its factorized form.\n\n\\details\nIt solves one of the following systems, depending on the value of trans:\n\n\\f[\n\\begin{array}{cl}\nA X = B & \\: \\text{not transposed,}\\\\\nA^T X = B & \\: \\text{transposed, or}\\\\\nA^H X = B & \\: \\text{conjugate transposed.}\n\\end{array}\n\\f]\n\nMatrix A is defined by its triangular factors as returned by \\ref rocsolver_sgetrf \"GETRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof the matrix B.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nThe factors L and U of the factorization A = P*L*U returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[in,out]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrix B.\nOn exit, the solution matrix X.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of B."] + pub fn rocsolver_sgetrs( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *const rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrs( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *const rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrs( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *const rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrs( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *const rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRS_BATCHED solves a batch of systems of n linear equations on n\nvariables in its factorized forms.\n\n\\details\nFor each instance j in the batch, it solves one of the following systems, depending on the value of trans:\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = B_j & \\: \\text{not transposed,}\\\\\nA_j^T X_j = B_j & \\: \\text{transposed, or}\\\\\nA_j^H X_j = B_j & \\: \\text{conjugate transposed.}\n\\end{array}\n\\f]\n\nMatrix \\f$A_j\\f$ is defined by its triangular factors as returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations of each instance in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nThe factors L_j and U_j of the factorization A_j = P_j*L_j*U_j returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of pivot indices returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[in,out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sgetrs_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrs_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrs_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrs_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRS_STRIDED_BATCHED solves a batch of systems of n linear equations\non n variables in its factorized forms.\n\n\\details\nFor each instance j in the batch, it solves one of the following systems, depending on the value of trans:\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = B_j & \\: \\text{not transposed,}\\\\\nA_j^T X_j = B_j & \\: \\text{transposed, or}\\\\\nA_j^H X_j = B_j & \\: \\text{conjugate transposed.}\n\\end{array}\n\\f]\n\nMatrix \\f$A_j\\f$ is defined by its triangular factors as returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations of each instance in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nThe factors L_j and U_j of the factorization A_j = P_j*L_j*U_j returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors ipiv_j of pivot indices returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[in,out]\nB pointer to type. Array on the GPU (size depends on the value of strideB).\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*nrhs.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sgetrs_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetrs_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetrs_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetrs_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *const rocblas_int, + strideP: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESV solves a general system of n linear equations on n variables.\n\n\\details\nThe linear system is of the form\n\n\\f[\nA X = B\n\\f]\n\nwhere A is a general n-by-n matrix. Matrix A is first factorized in triangular factors L and U\nusing \\ref rocsolver_sgetrf \"GETRF\"; then, the solution is computed with \\ref rocsolver_sgetrs \"GETRS\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof the matrix B.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A.\nOn exit, if info = 0, the factors L and U of the LU decomposition of A returned by\n\\ref rocsolver_sgetrf \"GETRF\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[in,out]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrix B.\nOn exit, the solution matrix X.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of B.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular, and the solution could not be computed.\nU[i,i] is the first zero element in the diagonal."] + pub fn rocsolver_sgesv( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + B: *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesv( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + B: *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesv( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesv( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESV_BATCHED solves a batch of general systems of n linear equations on n\nvariables.\n\n\\details\nThe linear systems are of the form\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a general n-by-n matrix. Matrix \\f$A_j\\f$ is first factorized in triangular factors \\f$L_j\\f$ and \\f$U_j\\f$\nusing \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\"; then, the solutions are computed with \\ref rocsolver_sgetrs_batched \"GETRS_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j.\nOn exit, if info_j = 0, the factors L_j and U_j of the LU decomposition of A_j returned by\n\\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe vectors ipiv_j of pivot indices returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[in,out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for A_j.\nIf info[i] = j > 0, U_i is singular, and the solution could not be computed.\nU_j[i,i] is the first zero element in the diagonal.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sgesv_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *const *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesv_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *const *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesv_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesv_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESV_STRIDED_BATCHED solves a batch of general systems of n linear equations\non n variables.\n\n\\details\nThe linear systems are of the form\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a general n-by-n matrix. Matrix \\f$A_j\\f$ is first factorized in triangular factors \\f$L_j\\f$ and \\f$U_j\\f$\nusing \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\"; then, the solutions are computed with\n\\ref rocsolver_sgetrs_strided_batched \"GETRS_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j.\nOn exit, if info_j = 0, the factors L_j and U_j of the LU decomposition of A_j returned by\n\\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe vectors ipiv_j of pivot indices returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[in,out]\nB pointer to type. Array on the GPU (size depends on the value of strideB).\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*nrhs.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for A_j.\nIf info[i] = j > 0, U_i is singular, and the solution could not be computed.\nU_j[i,i] is the first zero element in the diagonal.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sgesv_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesv_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesv_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesv_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI inverts a general n-by-n matrix A using the LU factorization\ncomputed by \\ref rocsolver_sgetrf \"GETRF\".\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA^{-1}L = U^{-1}\n\\f]\n\nwhere L is the lower triangular factor of A with unit diagonal elements, and U is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the factors L and U of the factorization A = P*L*U returned by \\ref rocsolver_sgetrf \"GETRF\".\nOn exit, the inverse of A if info = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetri( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_BATCHED inverts a batch of general n-by-n matrices using\nthe LU factorization computed by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed by solving the linear system\n\n\\f[\nA_j^{-1} L_j = U_j^{-1}\n\\f]\n\nwhere \\f$L_j\\f$ is the lower triangular factor of \\f$A_j\\f$ with unit diagonal elements, and \\f$U_j\\f$ is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the factors L_j and U_j of the factorization A = P_j*L_j*U_j returned by\n\\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(i+j).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_STRIDED_BATCHED inverts a batch of general n-by-n matrices\nusing the LU factorization computed by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed by solving the linear system\n\n\\f[\nA_j^{-1} L_j = U_j^{-1}\n\\f]\n\nwhere \\f$L_j\\f$ is the lower triangular factor of \\f$A_j\\f$ with unit diagonal elements, and \\f$U_j\\f$ is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the factors L_j and U_j of the factorization A_j = P_j*L_j*U_j returned by\n\\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT inverts a general n-by-n matrix A using the LU factorization\ncomputed by \\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\".\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA^{-1}L = U^{-1}\n\\f]\n\nwhere L is the lower triangular factor of A with unit diagonal elements, and U is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the factors L and U of the factorization A = L*U returned by \\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\".\nOn exit, the inverse of A if info = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetri_npvt( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT_BATCHED inverts a batch of general n-by-n matrices using\nthe LU factorization computed by \\ref rocsolver_sgetrf_npvt_batched \"GETRF_NPVT_BATCHED\".\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed by solving the linear system\n\n\\f[\nA_j^{-1} L_j = U_j^{-1}\n\\f]\n\nwhere \\f$L_j\\f$ is the lower triangular factor of \\f$A_j\\f$ with unit diagonal elements, and \\f$U_j\\f$ is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the factors L_j and U_j of the factorization A = L_j*U_j returned by\n\\ref rocsolver_sgetrf_npvt_batched \"GETRF_NPVT_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_npvt_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT_STRIDED_BATCHED inverts a batch of general n-by-n matrices\nusing the LU factorization computed by \\ref rocsolver_sgetrf_npvt_strided_batched \"GETRF_NPVT_STRIDED_BATCHED\".\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed by solving the linear system\n\n\\f[\nA_j^{-1} L_j = U_j^{-1}\n\\f]\n\nwhere \\f$L_j\\f$ is the lower triangular factor of \\f$A_j\\f$ with unit diagonal elements, and \\f$U_j\\f$ is the\nupper triangular factor.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the factors L_j and U_j of the factorization A_j = L_j*U_j returned by\n\\ref rocsolver_sgetrf_npvt_strided_batched \"GETRF_NPVT_STRIDED_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0; otherwise undefined.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_npvt_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELS solves an overdetermined (or underdetermined) linear system defined by an m-by-n\nmatrix A, and a corresponding matrix B, using the QR factorization computed by \\ref rocsolver_sgeqrf \"GEQRF\" (or the LQ\nfactorization computed by \\ref rocsolver_sgelqf \"GELQF\").\n\n\\details\nDepending on the value of trans, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = B & \\: \\text{not transposed, or}\\\\\nA' X = B & \\: \\text{transposed if real, or conjugate transposed if complex}\n\\end{array}\n\\f]\n\nIf m >= n (or m < n in the case of transpose/conjugate transpose), the system is overdetermined\nand a least-squares solution approximating X is found by minimizing\n\n\\f[\n|| B - A X || \\quad \\text{(or} \\: || B - A' X ||\\text{)}\n\\f]\n\nIf m < n (or m >= n in the case of transpose/conjugate transpose), the system is underdetermined\nand a unique solution for X is chosen such that \\f$|| X ||\\f$ is minimal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of columns of matrices B and X;\ni.e., the columns on the right hand side.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A.\nOn exit, the QR (or LQ) factorization of A as returned by \\ref rocsolver_sgeqrf \"GEQRF\" (or \\ref rocsolver_sgelqf \"GELQF\").\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrix A.\n@param[inout]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the matrix B.\nOn exit, when info = 0, B is overwritten by the solution vectors (and the residuals in\nthe overdetermined cases) stored as columns.\n@param[in]\nldb rocblas_int. ldb >= max(m,n).\\n\nSpecifies the leading dimension of matrix B.\n@param[out]\ninfo pointer to rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, the solution could not be computed because input matrix A is\nrank deficient; the i-th diagonal element of its triangular factor is zero."] + pub fn rocsolver_sgels( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgels( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgels( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgels( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELS_BATCHED solves a batch of overdetermined (or underdetermined) linear systems\ndefined by a set of m-by-n matrices \\f$A_j\\f$, and corresponding matrices \\f$B_j\\f$, using the\nQR factorizations computed by \\ref rocsolver_sgeqrf_batched \"GEQRF_BATCHED\" (or the LQ factorizations computed by \\ref rocsolver_sgelqf_batched \"GELQF_BATCHED\").\n\n\\details\nFor each instance in the batch, depending on the value of trans, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = B_j & \\: \\text{not transposed, or}\\\\\nA_j' X_j = B_j & \\: \\text{transposed if real, or conjugate transposed if complex}\n\\end{array}\n\\f]\n\nIf m >= n (or m < n in the case of transpose/conjugate transpose), the system is overdetermined\nand a least-squares solution approximating X_j is found by minimizing\n\n\\f[\n|| B_j - A_j X_j || \\quad \\text{(or} \\: || B_j - A_j' X_j ||\\text{)}\n\\f]\n\nIf m < n (or m >= n in the case of transpose/conjugate transpose), the system is underdetermined\nand a unique solution for X_j is chosen such that \\f$|| X_j ||\\f$ is minimal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of columns of all matrices B_j and X_j in the batch;\ni.e., the columns on the right hand side.\n@param[inout]\nA array of pointer to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j.\nOn exit, the QR (or LQ) factorizations of A_j as returned by \\ref rocsolver_sgeqrf_batched \"GEQRF_BATCHED\"\n(or \\ref rocsolver_sgelqf_batched \"GELQF_BATCHED\").\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[inout]\nB array of pointer to type. Each pointer points to an array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the matrices B_j.\nOn exit, when info[j] = 0, B_j is overwritten by the solution vectors (and the residuals in\nthe overdetermined cases) stored as columns.\n@param[in]\nldb rocblas_int. ldb >= max(m,n).\\n\nSpecifies the leading dimension of matrices B_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for solution of A_j.\nIf info[j] = i > 0, the solution of A_j could not be computed because input\nmatrix A_j is rank deficient; the i-th diagonal element of its triangular factor is zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgels_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgels_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgels_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgels_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GELS_STRIDED_BATCHED solves a batch of overdetermined (or underdetermined) linear\nsystems defined by a set of m-by-n matrices \\f$A_j\\f$, and corresponding matrices \\f$B_j\\f$,\nusing the QR factorizations computed by \\ref rocsolver_sgeqrf_strided_batched \"GEQRF_STRIDED_BATCHED\"\n(or the LQ factorizations computed by \\ref rocsolver_sgelqf_strided_batched \"GELQF_STRIDED_BATCHED\").\n\n\\details\nFor each instance in the batch, depending on the value of trans, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = B_j & \\: \\text{not transposed, or}\\\\\nA_j' X_j = B_j & \\: \\text{transposed if real, or conjugate transposed if complex}\n\\end{array}\n\\f]\n\nIf m >= n (or m < n in the case of transpose/conjugate transpose), the system is overdetermined\nand a least-squares solution approximating X_j is found by minimizing\n\n\\f[\n|| B_j - A_j X_j || \\quad \\text{(or} \\: || B_j - A_j' X_j ||\\text{)}\n\\f]\n\nIf m < n (or m >= n in the case of transpose/conjugate transpose), the system is underdetermined\nand a unique solution for X_j is chosen such that \\f$|| X_j ||\\f$ is minimal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\ntrans rocblas_operation.\\n\nSpecifies the form of the system of equations.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of columns of all matrices B_j and X_j in the batch;\ni.e., the columns on the right hand side.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j.\nOn exit, the QR (or LQ) factorizations of A_j as returned by \\ref rocsolver_sgeqrf_strided_batched \"GEQRF_STRIDED_BATCHED\"\n(or \\ref rocsolver_sgelqf_strided_batched \"GELQF_STRIDED_BATCHED\").\n@param[in]\nlda rocblas_int. lda >= m.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[inout]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the matrices B_j.\nOn exit, when info[j] = 0, each B_j is overwritten by the solution vectors (and the residuals in\nthe overdetermined cases) stored as columns.\n@param[in]\nldb rocblas_int. ldb >= max(m,n).\\n\nSpecifies the leading dimension of matrices B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*nrhs\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for solution of A_j.\nIf info[j] = i > 0, the solution of A_j could not be computed because input\nmatrix A_j is rank deficient; the i-th diagonal element of its triangular factor is zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgels_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgels_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgels_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgels_strided_batched( + handle: rocblas_handle, + trans: rocblas_operation, + m: rocblas_int, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTF2 computes the Cholesky factorization of a real symmetric (complex\nHermitian) positive definite matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form:\n\n\\f[\n\\begin{array}{cl}\nA = U'U & \\: \\text{if uplo is upper, or}\\\\\nA = LL' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nU is an upper triangular matrix and L is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A to be factored. On exit, the lower or upper triangular factor.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful factorization of matrix A.\nIf info = i > 0, the leading minor of order i of A is not positive definite.\nThe factorization stopped at this point."] + pub fn rocsolver_spotf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTF2_BATCHED computes the Cholesky factorization of a\nbatch of real symmetric (complex Hermitian) positive definite matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form:\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\n\\f$U_j\\f$ is an upper triangular matrix and \\f$L_j\\f$ is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored. On exit, the upper or lower triangular factors.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful factorization of matrix A_j.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th factorization stopped at this point.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTF2_STRIDED_BATCHED computes the Cholesky factorization of a\nbatch of real symmetric (complex Hermitian) positive definite matrices.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form:\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\n\\f$U_j\\f$ is an upper triangular matrix and \\f$L_j\\f$ is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored. On exit, the upper or lower triangular factors.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful factorization of matrix A_j.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th factorization stopped at this point.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRF computes the Cholesky factorization of a real symmetric (complex\nHermitian) positive definite matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form:\n\n\\f[\n\\begin{array}{cl}\nA = U'U & \\: \\text{if uplo is upper, or}\\\\\nA = LL' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nU is an upper triangular matrix and L is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A to be factored. On exit, the lower or upper triangular factor.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful factorization of matrix A.\nIf info = i > 0, the leading minor of order i of A is not positive definite.\nThe factorization stopped at this point."] + pub fn rocsolver_spotrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRF_BATCHED computes the Cholesky factorization of a\nbatch of real symmetric (complex Hermitian) positive definite matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form:\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\n\\f$U_j\\f$ is an upper triangular matrix and \\f$L_j\\f$ is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored. On exit, the upper or lower triangular factors.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful factorization of matrix A_j.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th factorization stopped at this point.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRF_STRIDED_BATCHED computes the Cholesky factorization of a\nbatch of real symmetric (complex Hermitian) positive definite matrices.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization of matrix \\f$A_j\\f$ in the batch has the form:\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\n\\f$U_j\\f$ is an upper triangular matrix and \\f$L_j\\f$ is lower triangular.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored. On exit, the upper or lower triangular factors.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful factorization of matrix A_j.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th factorization stopped at this point.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRS solves a symmetric/hermitian system of n linear equations on n variables in its factorized form.\n\n\\details\nIt solves the system\n\n\\f[\nA X = B\n\\f]\n\nwhere A is a real symmetric (complex hermitian) positive definite matrix defined by its triangular factor\n\n\\f[\n\\begin{array}{cl}\nA = U'U & \\: \\text{if uplo is upper, or}\\\\\nA = LL' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nas returned by \\ref rocsolver_spotrf \"POTRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof the matrix B.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nThe factor L or U of the Cholesky factorization of A returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[in,out]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrix B.\nOn exit, the solution matrix X.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of B."] + pub fn rocsolver_spotrs( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrs( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrs( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrs( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRS_BATCHED solves a batch of symmetric/hermitian systems of n linear equations on n\nvariables in its factorized forms.\n\n\\details\nFor each instance j in the batch, it solves the system\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a real symmetric (complex hermitian) positive definite matrix defined by its\ntriangular factor\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nas returned by \\ref rocsolver_spotrf \"POTRF_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nThe factor L_j or U_j of the Cholesky factorization of A_j returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in,out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_spotrs_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrs_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrs_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrs_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRS_STRIDED_BATCHED solves a batch of symmetric/hermitian systems of n linear equations\non n variables in its factorized forms.\n\n\\details\nFor each instance j in the batch, it solves the system\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a real symmetric (complex hermitian) positive definite matrix defined by its\ntriangular factor\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j'U_j & \\: \\text{if uplo is upper, or}\\\\\nA_j = L_jL_j' & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nas returned by \\ref rocsolver_spotrf \"POTRF_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nThe factor L_j or U_j of the Cholesky factorization of A_j returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in,out]\nB pointer to type. Array on the GPU (size depends on the value of strideB).\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*nrhs.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_spotrs_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotrs_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotrs_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotrs_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POSV solves a symmetric/hermitian system of n linear equations on n variables.\n\n\\details\nIt solves the system\n\n\\f[\nA X = B\n\\f]\n\nwhere A is a real symmetric (complex hermitian) positive definite matrix. Matrix A is first\nfactorized as \\f$A=LL'\\f$ or \\f$A=U'U\\f$, depending on the value of uplo, using \\ref rocsolver_spotrf \"POTRF\";\nthen, the solution is computed with \\ref rocsolver_spotrs \"POTRS\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof the matrix B.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric/hermitian matrix A.\nOn exit, if info = 0, the factor L or U of the Cholesky factorization of A returned by\n\\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[in,out]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrix B.\nOn exit, the solution matrix X.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of B.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, the leading minor of order i of A is not positive definite.\nThe solution could not be computed."] + pub fn rocsolver_sposv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dposv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cposv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zposv( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POSV_BATCHED solves a batch of symmetric/hermitian systems of n linear equations on n\nvariables.\n\n\\details\nFor each instance j in the batch, it solves the system\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a real symmetric (complex hermitian) positive definite matrix. Matrix \\f$A_j\\f$ is first\nfactorized as \\f$A_j=L_jL_j'\\f$ or \\f$A_j=U_j'U_j\\f$, depending on the value of uplo, using \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\";\nthen, the solution is computed with \\ref rocsolver_spotrs_batched \"POTRS_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric/hermitian matrices A_j.\nOn exit, if info[j] = 0, the factor L_j or U_j of the Cholesky factorization of A_j returned by\n\\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in,out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*nrhs.\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th solution could not be computed.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sposv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dposv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cposv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zposv_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POSV_STRIDED_BATCHED solves a batch of symmetric/hermitian systems of n linear equations\non n variables.\n\n\\details\nFor each instance j in the batch, it solves the system\n\n\\f[\nA_j X_j = B_j\n\\f]\n\nwhere \\f$A_j\\f$ is a real symmetric (complex hermitian) positive definite matrix. Matrix \\f$A_j\\f$ is first\nfactorized as \\f$A_j=L_jL_j'\\f$ or \\f$A_j=U_j'U_j\\f$, depending on the value of uplo, using \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\";\nthen, the solution is computed with \\ref rocsolver_spotrs_strided_batched \"POTRS_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe order of the system, i.e. the number of columns and rows of all A_j matrices.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns\nof all the matrices B_j.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric/hermitian matrices A_j.\nOn exit, if info[j] = 0, the factor L_j or U_j of the Cholesky factorization of A_j returned by\n\\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in,out]\nB pointer to type. Array on the GPU (size depends on the value of strideB).\\n\nOn entry, the right hand side matrices B_j.\nOn exit, the solution matrix X_j of each system in the batch.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of matrices B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*nrhs.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, the leading minor of order i of A_j is not positive definite.\nThe j-th solution could not be computed.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of instances (systems) in the batch."] + pub fn rocsolver_sposv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dposv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cposv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zposv_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRI inverts a symmetric/hermitian positive definite matrix A.\n\n\\details\nThe inverse of matrix \\f$A\\f$ is computed as\n\n\\f[\n\\begin{array}{cl}\nA^{-1} = U^{-1} {U^{-1}}' & \\: \\text{if uplo is upper, or}\\\\\nA^{-1} = {L^{-1}}' L^{-1} & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nwhere \\f$U\\f$ or \\f$L\\f$ is the triangular factor of the Cholesky factorization of \\f$A\\f$ returned by\n\\ref rocsolver_spotrf \"POTRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the factor L or U of the Cholesky factorization of A returned by\n\\ref rocsolver_spotrf \"POTRF\".\nOn exit, the inverse of A if info = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit for inversion of A.\nIf info = i > 0, A is singular. L[i,i] or U[i,i] is zero."] + pub fn rocsolver_spotri( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotri( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotri( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotri( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRI_BATCHED inverts a batch of symmetric/hermitian positive definite matrices \\f$A_j\\f$.\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed as\n\n\\f[\n\\begin{array}{cl}\nA_j^{-1} = U_j^{-1} {U_j^{-1}}' & \\: \\text{if uplo is upper, or}\\\\\nA_j^{-1} = {L_j^{-1}}' L_j^{-1} & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is the triangular factor of the Cholesky factorization of \\f$A_j\\f$ returned by\n\\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the factor L_j or U_j of the Cholesky factorization of A_j returned by\n\\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, A_j is singular. L_j[i,i] or U_j[i,i] is zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief POTRI_STRIDED_BATCHED inverts a batch of symmetric/hermitian positive definite matrices \\f$A_j\\f$.\n\n\\details\nThe inverse of matrix \\f$A_j\\f$ in the batch is computed as\n\n\\f[\n\\begin{array}{cl}\nA_j^{-1} = U_j^{-1} {U_j^{-1}}' & \\: \\text{if uplo is upper, or}\\\\\nA_j^{-1} = {L_j^{-1}}' L_j^{-1} & \\: \\text{if uplo is lower.}\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is the triangular factor of the Cholesky factorization of \\f$A_j\\f$ returned by\n\\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the factorization is upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of matrix A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the factor L_j or U_j of the Cholesky factorization of A_j returned by\n\\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\nOn exit, the inverses of A_j if info[j] = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, A_j is singular. L_j[i,i] or U_j[i,i] is zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_spotri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dpotri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cpotri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zpotri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVD computes the singular values and optionally the singular\nvectors of a general m-by-n matrix A (Singular Value Decomposition).\n\n\\details\nThe SVD of matrix A is given by:\n\n\\f[\nA = U S V'\n\\f]\n\nwhere the m-by-n matrix S is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of A. U and V are orthogonal\n(unitary) matrices. The first min(m,n) columns of U and V are the left and\nright singular vectors of A, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of V'.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix U (or V') is computed,\n- rocblas_svect_singular: only the singular vectors (first min(m,n)\ncolumns of U or rows of V') are computed,\n- rocblas_svect_overwrite: the first\ncolumns (or rows) of A are overwritten with the singular vectors, or\n- rocblas_svect_none: no columns (or rows) of U (or V') are computed, i.e.\nno singular vectors.\n\nleft_svect and right_svect cannot both be set to overwrite. When neither is\nset to overwrite, the contents of A are destroyed by the time the function\nreturns.\n\n\\note\nWhen m >> n (or n >> m) the algorithm could be sped up by compressing\nthe matrix A via a QR (or LQ) factorization, and working with the triangular\nfactor afterwards (thin-SVD). If the singular vectors are also requested, its\ncomputation could be sped up as well via executing some intermediate\noperations out-of-place, and relying more on matrix multiplications (GEMMs);\nthis will require, however, a larger memory workspace. The parameter fast_alg\ncontrols whether the fast algorithm is executed or not. For more details, see\nthe \"Tuning rocSOLVER performance\" and \"Memory model\" sections of the documentation.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A.\nOn exit, if left_svect (or right_svect) is equal to overwrite,\nthe first columns (or rows) contain the left (or right) singular vectors;\notherwise, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A.\n@param[out]\nS pointer to real type. Array on the GPU of dimension min(m,n). \\n\nThe singular values of A in decreasing order.\n@param[out]\nU pointer to type. Array on the GPU of dimension ldu*min(m,n) if\nleft_svect is set to singular, or ldu*m when left_svect is equal to all.\\n\nThe matrix of left singular vectors stored as columns. Not\nreferenced if left_svect is set to overwrite or none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U.\n@param[out]\nV pointer to type. Array on the GPU of dimension ldv*n. \\n\nThe matrix of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to overwrite or none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is all; ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[out]\nE pointer to real type. Array on the GPU of dimension min(m,n)-1.\\n\nThis array is used to work internally with the bidiagonal matrix\nB associated with A (using \\ref rocsolver_sbdsqr \"BDSQR\"). On exit, if info > 0, it contains the\nunconverged off-diagonal elements of B (or properly speaking, a bidiagonal\nmatrix orthogonally equivalent to B). The diagonal elements of this matrix\nare in S; those that converged correspond to a subset of the singular values\nof A (not necessarily ordered).\n@param[in]\nfast_alg #rocblas_workmode. \\n\nIf set to rocblas_outofplace, the function will execute the\nfast thin-SVD version of the algorithm when possible.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, \\ref rocsolver_sbdsqr \"BDSQR\" did not converge. i elements of E did not converge to zero."] + pub fn rocsolver_sgesvd( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + S: *mut f32, + U: *mut f32, + ldu: rocblas_int, + V: *mut f32, + ldv: rocblas_int, + E: *mut f32, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvd( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + S: *mut f64, + U: *mut f64, + ldu: rocblas_int, + V: *mut f64, + ldv: rocblas_int, + E: *mut f64, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvd( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + S: *mut f32, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + E: *mut f32, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvd( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + S: *mut f64, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + E: *mut f64, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVD_BATCHED computes the singular values and optionally the\nsingular vectors of a batch of general m-by-n matrix A (Singular Value\nDecomposition).\n\n\\details\nThe SVD of matrix A_j in the batch is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$. \\f$U_j\\f$ and \\f$V_j\\f$ are\northogonal (unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are\nthe left and right singular vectors of \\f$A_j\\f$, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix \\f$U_j\\f$ (or \\f$V_j'\\f$) is computed,\n- rocblas_svect_singular: only the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$) are computed,\n- rocblas_svect_overwrite: the\nfirst columns (or rows) of \\f$A_j\\f$ are overwritten with the singular vectors, or\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$) are computed,\ni.e. no singular vectors.\n\nleft_svect and right_svect cannot both be set to overwrite. When neither is\nset to overwrite, the contents of \\f$A_j\\f$ are destroyed by the time the function\nreturns.\n\n\\note\nWhen m >> n (or n >> m) the algorithm could be sped up by compressing\nthe matrix \\f$A_j\\f$ via a QR (or LQ) factorization, and working with the\ntriangular factor afterwards (thin-SVD). If the singular vectors are also\nrequested, its computation could be sped up as well via executing some\nintermediate operations out-of-place, and relying more on matrix\nmultiplications (GEMMs); this will require, however, a larger memory\nworkspace. The parameter fast_alg controls whether the fast algorithm is\nexecuted or not. For more details, see the \"Tuning rocSOLVER performance\"\nand \"Memory model\" sections of the documentation.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on\nthe GPU of dimension lda*n.\\n\nOn entry, the matrices A_j.\nOn exit, if left_svect (or right_svect) is equal to overwrite,\nthe first columns (or rows) of A_j contain the left (or right)\ncorresponding singular vectors; otherwise, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS).\\n\nThe singular values of A_j in decreasing order.\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS.\nNormal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the side depends on the value of strideU). \\n\nThe matrices U_j of left singular vectors stored as columns.\nNot referenced if left_svect is set to overwrite or none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU.\nNormal use case is strideU >= ldu*min(m,n) if left_svect is set to singular,\nor strideU >= ldu*m when left_svect is equal to all.\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrices V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to overwrite or none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is all; ldv >= min(m,n) if\nright_svect is set to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV.\nNormal use case is strideV >= ldv*n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the bidiagonal matrix B_j associated with A_j (using \\ref rocsolver_sbdsqr \"BDSQR\").\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of B_j (or properly speaking,\na bidiagonal matrix orthogonally equivalent to B_j). The diagonal elements of this matrix are in S_j;\nthose that converged correspond to a subset of the singular values of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= min(m,n)-1.\n@param[in]\nfast_alg #rocblas_workmode. \\n\nIf set to rocblas_outofplace, the function will execute the fast thin-SVD version\nof the algorithm when possible.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, \\ref rocsolver_sbdsqr \"BDSQR\" did not converge. i elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvd_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvd_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvd_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvd_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVD_STRIDED_BATCHED computes the singular values and optionally the\nsingular vectors of a batch of general m-by-n matrix A (Singular Value\nDecomposition).\n\n\\details\nThe SVD of matrix A_j in the batch is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$. \\f$U_j\\f$ and \\f$V_j\\f$ are\northogonal (unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are\nthe left and right singular vectors of \\f$A_j\\f$, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix \\f$U_j\\f$ (or \\f$V_j'\\f$) is computed,\n- rocblas_svect_singular: only the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$) are computed,\n- rocblas_svect_overwrite: the\nfirst columns (or rows) of \\f$A_j\\f$ are overwritten with the singular vectors, or\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$) are computed,\ni.e. no singular vectors.\n\nleft_svect and right_svect cannot both be set to overwrite. When neither is\nset to overwrite, the contents of \\f$A_j\\f$ are destroyed by the time the function\nreturns.\n\n\\note\nWhen m >> n (or n >> m) the algorithm could be sped up by compressing\nthe matrix \\f$A_j\\f$ via a QR (or LQ) factorization, and working with the\ntriangular factor afterwards (thin-SVD). If the singular vectors are also\nrequested, its computation could be sped up as well via executing some\nintermediate operations out-of-place, and relying more on matrix\nmultiplications (GEMMs); this will require, however, a larger memory\nworkspace. The parameter fast_alg controls whether the fast algorithm is\nexecuted or not. For more details, see the \"Tuning rocSOLVER performance\"\nand \"Memory model\" sections of the documentation.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, if left_svect (or right_svect) is equal to\noverwrite, the first columns (or rows) of A_j contain the left (or right)\ncorresponding singular vectors; otherwise, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA.\nNormal use case is strideA >= lda*n.\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS).\\n\nThe singular values of A_j in decreasing order.\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS.\nNormal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the side depends on the value of strideU). \\n\nThe matrices U_j of left singular vectors stored as columns.\nNot referenced if left_svect is set to overwrite or none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU.\nNormal use case is strideU >= ldu*min(m,n) if left_svect is set to singular,\nor strideU >= ldu*m when left_svect is equal to all.\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrices V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to overwrite or none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is all; ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV.\nNormal use case is strideV >= ldv*n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the bidiagonal matrix B_j associated with A_j (using \\ref rocsolver_sbdsqr \"BDSQR\").\nOn exit, if info > 0, E_j contains the unconverged off-diagonal elements of B_j (or properly speaking,\na bidiagonal matrix orthogonally equivalent to B_j). The diagonal elements of this matrix are in S_j;\nthose that converged correspond to a subset of the singular values of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE.\nNormal use case is strideE >= min(m,n)-1.\n@param[in]\nfast_alg #rocblas_workmode. \\n\nIf set to rocblas_outofplace, the function will execute the fast thin-SVD version\nof the algorithm when possible.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, BDSQR did not converge. i elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvd_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvd_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvd_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvd_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + fast_alg: rocblas_workmode, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDJ computes the singular values and optionally the singular\nvectors of a general m-by-n matrix A (Singular Value Decomposition).\n\n\\details\nThe SVD of matrix A is given by:\n\n\\f[\nA = U S V'\n\\f]\n\nwhere the m-by-n matrix S is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of A. U and V are orthogonal\n(unitary) matrices. The first min(m,n) columns of U and V are the left and\nright singular vectors of A, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of V'.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix U (or V') is computed,\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of U or rows of V') are computed, or\n- rocblas_svect_none: no columns (or rows) of U (or V') are computed, i.e.\nno singular vectors.\n\nThe singular values are computed by applying QR factorization to AV if m >= n\n(resp. LQ factorization to U'A if m < n), where V (resp. U) is found as the\neigenvectors of A'A (resp. AA') using the Jacobi eigenvalue algorithm.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A.\nOn exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A'A)\nis <= norm(A'A) * abstol [resp. off(AA') <= norm(AA') * abstol]. If abstol <= 0,\nthen the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A'A (resp. AA') at the final\niteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to a rocblas_int on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm.\n@param[out]\nS pointer to real type. Array on the GPU of dimension min(m,n). \\n\nThe singular values of A in decreasing order.\n@param[out]\nU pointer to type. Array on the GPU of dimension ldu*min(m,n) if\nleft_svect is set to singular, or ldu*m when left_svect is equal to all.\\n\nThe matrix of left singular vectors stored as columns. Not\nreferenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is set to all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U.\n@param[out]\nV pointer to type. Array on the GPU of dimension ldv*n. \\n\nThe matrix of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is set to all; ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit. If info = 1, the algorithm did not converge."] + pub fn rocsolver_sgesvdj( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + U: *mut f32, + ldu: rocblas_int, + V: *mut f32, + ldv: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdj( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + U: *mut f64, + ldu: rocblas_int, + V: *mut f64, + ldv: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdj( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdj( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDJ_BATCHED computes the singular values and optionally the\nsingular vectors of a batch of general m-by-n matrix A (Singular Value\nDecomposition).\n\n\\details\nThe SVD of matrix A_j in the batch is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$. \\f$U_j\\f$ and \\f$V_j\\f$ are\northogonal (unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are\nthe left and right singular vectors of \\f$A_j\\f$, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix \\f$U_j\\f$ (or \\f$V_j'\\f$) is computed,\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$) are computed, or\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$) are computed,\ni.e. no singular vectors.\n\nThe singular values are computed by applying QR factorization to \\f$A_jV_j\\f$ if m >= n\n(resp. LQ factorization to \\f$U_j'A_j\\f$ if m < n), where \\f$V_j\\f$ (resp. \\f$U_j\\f$) is\nfound as the eigenvectors of \\f$A_j'A_j\\f$ (resp. \\f$A_jA_j'\\f$) using the Jacobi\neigenvalue algorithm.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on\nthe GPU of dimension lda*n.\\n\nOn entry, the matrices A_j.\nOn exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j'A_j)\nis <= norm(A_j'A_j) * abstol [resp. off(A_jA_j') <= norm(A_jA_j') * abstol]. If abstol <= 0,\nthen the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j'A_j (resp. A_jA_j') at the final\niteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS).\\n\nThe singular values of A_j in decreasing order.\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS.\nNormal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the side depends on the value of strideU). \\n\nThe matrices U_j of left singular vectors stored as columns.\nNot referenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is set to all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU.\nNormal use case is strideU >= ldu*min(m,n) if left_svect is set to singular,\nor strideU >= ldu*m when left_svect is equal to all.\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrices V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is set to all; ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV.\nNormal use case is strideV >= ldv*n.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvdj_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdj_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdj_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdj_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDJ_STRIDED_BATCHED computes the singular values and optionally the\nsingular vectors of a batch of general m-by-n matrix A (Singular Value\nDecomposition).\n\n\\details\nThe SVD of matrix A_j in the batch is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$. \\f$U_j\\f$ and \\f$V_j\\f$ are\northogonal (unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are\nthe left and right singular vectors of \\f$A_j\\f$, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that can take the\nfollowing values:\n\n- rocblas_svect_all: the entire matrix \\f$U_j\\f$ (or \\f$V_j'\\f$) is computed,\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$) are computed, or\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$) are computed,\ni.e. no singular vectors.\n\nThe singular values are computed by applying QR factorization to \\f$A_jV_j\\f$ if m >= n\n(resp. LQ factorization to \\f$U_j'A_j\\f$ if m < n), where \\f$V_j\\f$ (resp. \\f$U_j\\f$) is\nfound as the eigenvectors of \\f$A_j'A_j\\f$ (resp. \\f$A_jA_j'\\f$) using the Jacobi\neigenvalue algorithm.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies how the left singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies how the right singular vectors are computed.\nrocblas_svect_overwrite is not supported.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of all matrices A_j in the batch.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j.\nOn exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA.\nNormal use case is strideA >= lda*n.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j'A_j)\nis <= norm(A_j'A_j) * abstol [resp. off(A_jA_j') <= norm(A_jA_j') * abstol]. If abstol <= 0,\nthen the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j'A_j (resp. A_jA_j') at the final\niteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS).\\n\nThe singular values of A_j in decreasing order.\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS.\nNormal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the side depends on the value of strideU). \\n\nThe matrices U_j of left singular vectors stored as columns.\nNot referenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect is set to all or singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU.\nNormal use case is strideU >= ldu*min(m,n) if left_svect is set to singular,\nor strideU >= ldu*m when left_svect is equal to all.\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrices V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= n if right_svect is set to all; ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV.\nNormal use case is strideV >= ldv*n.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvdj_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdj_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdj_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdj_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDX computes a set of singular values and optionally the corresponding singular\nvectors of a general m-by-n matrix A (partial Singular Value Decomposition).\n\n\\details\nThis function computes all the singular values of A, all the singular values in the half-open interval\n\\f$[vl, vu)\\f$, or the il-th through iu-th singular values, depending on the value of srange.\n\nThe full SVD of matrix A is given by:\n\n\\f[\nA = U S V'\n\\f]\n\nwhere the m-by-n matrix S is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of A. U and V are orthogonal\n(unitary) matrices. The first min(m,n) columns of U and V are the left and\nright singular vectors of A, respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of V'.\n\nleft_svect and right_svect are #rocblas_svect enums that, for this function, can take the\nfollowing values:\n\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of U or rows of V') corresponding to the computed singular values are computed,\n- rocblas_svect_none: no columns (or rows) of U (or V') are computed, i.e.\nno singular vectors.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies if the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies if the right singular vectors are computed.\n@param[in]\nsrange #rocblas_srange.\\n\nSpecifies the type of range or interval of the singular values to be computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A.\nOn exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A.\n@param[in]\nvl real type. 0 <= vl < vu.\\n\nThe lower bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A or the singular values within a set of indices.\n@param[in]\nvu real type. 0 <= vl < vu.\\n\nThe upper bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A or the singular values within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the largest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A or the singular values in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A or the singular values in a half-open interval.\n@param[out]\nnsv pointer to a rocblas_int on the GPU. \\n\nThe total number of singular values found. If srange is rocblas_srange_all, nsv = min(m,n).\nIf srange is rocblas_srange_index, nsv = iu - il + 1. Otherwise, 0 <= nsv <= min(m,n).\n@param[out]\nS pointer to real type. Array on the GPU of dimension min(m,n). \\n\nThe first nsv elements contain the computed singular values in descending order.\n(The remaining elements may be used as workspace for internal computations).\n@param[out]\nU pointer to type. Array on the GPU of dimension ldu*min(m,n).\\n\nThe matrix of left singular vectors stored as columns. Not\nreferenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U.\n@param[out]\nV pointer to type. Array on the GPU of dimension ldv*n. \\n\nThe matrix of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension min(m,n).\\n\nIf info = 0, the first nsv elements of ifail are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge, as returned by \\ref rocsolver_sbdsvdx \"BDSVDX\".\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, i eigenvectors did not converge in \\ref rocsolver_sbdsvdx \"BDSVDX\"; their\nindices are stored in ifail."] + pub fn rocsolver_sgesvdx( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + U: *mut f32, + ldu: rocblas_int, + V: *mut f32, + ldv: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdx( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + U: *mut f64, + ldu: rocblas_int, + V: *mut f64, + ldv: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdx( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdx( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDX_BATCHED computes a set of singular values and optionally the corresponding singular\nvectors of a batch of general m-by-n matrices \\f$A_j\\f$ (partial Singular Value Decomposition).\n\n\\details\nThis function computes all the singular values of \\f$A_j\\f$, all the singular values in the half-open interval\n\\f$[vl, vu)\\f$, or the il-th through iu-th singular values, depending on the value of srange.\n\nThe full SVD of matrix \\f$A_j\\f$ is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$ . \\f$U_j\\f$ and \\f$V_j\\f$ are orthogonal\n(unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are the left and\nright singular vectors of \\f$A_j\\f$ , respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that, for this function, can take the\nfollowing values:\n\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$ ) corresponding to the computed singular values are computed,\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$ ) are computed, i.e.\nno singular vectors.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies if the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies if the right singular vectors are computed.\n@param[in]\nsrange #rocblas_srange.\\n\nSpecifies the type of range or interval of the singular values to be computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A_j.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j.\nOn exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[in]\nvl real type. 0 <= vl < vu.\\n\nThe lower bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values within a set of indices.\n@param[in]\nvu real type. 0 <= vl < vu.\\n\nThe upper bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the largest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values in a half-open interval.\n@param[out]\nnsv pointer to rocblas_int. Array of batch_count integers on the GPU. \\n\nThe total number of singular values found. If srange is rocblas_srange_all, nsv[j] = min(m,n).\nIf srange is rocblas_srange_index, nsv[j] = iu - il + 1. Otherwise, 0 <= nsv[j] <= min(m,n).\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS). \\n\nThe first nsv_j elements contain the computed singular values in descending order.\n(The remaining elements may be used as workspace for internal computations).\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS. Normal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the size depends on the value of strideU).\\n\nThe matrix U_j of left singular vectors stored as columns. Not\nreferenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU. Normal use case is strideU >= ldu*min(m,n).\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrix V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V_j.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV. Normal use case is strideV >= ldv*n.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nsv[j] elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge, as returned by \\ref rocsolver_sbdsvdx \"BDSVDX\".\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= min(m,n).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, i eigenvectors did not converge in \\ref rocsolver_sbdsvdx \"BDSVDX\"; their\nindices are stored in ifail_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvdx_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdx_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdx_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdx_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GESVDX_STRIDED_BATCHED computes a set of singular values and optionally the corresponding singular\nvectors of a batch of general m-by-n matrices \\f$A_j\\f$ (partial Singular Value Decomposition).\n\n\\details\nThis function computes all the singular values of \\f$A_j\\f$, all the singular values in the half-open interval\n\\f$[vl, vu)\\f$, or the il-th through iu-th singular values, depending on the value of srange.\n\nThe full SVD of matrix \\f$A_j\\f$ is given by:\n\n\\f[\nA_j = U_j S_j V_j'\n\\f]\n\nwhere the m-by-n matrix \\f$S_j\\f$ is zero except, possibly, for its min(m,n)\ndiagonal elements, which are the singular values of \\f$A_j\\f$ . \\f$U_j\\f$ and \\f$V_j\\f$ are orthogonal\n(unitary) matrices. The first min(m,n) columns of \\f$U_j\\f$ and \\f$V_j\\f$ are the left and\nright singular vectors of \\f$A_j\\f$ , respectively.\n\nThe computation of the singular vectors is optional and it is controlled by\nthe function arguments left_svect and right_svect as described below. When\ncomputed, this function returns the transpose (or transpose conjugate) of the\nright singular vectors, i.e. the rows of \\f$V_j'\\f$.\n\nleft_svect and right_svect are #rocblas_svect enums that, for this function, can take the\nfollowing values:\n\n- rocblas_svect_singular: the singular vectors (first min(m,n)\ncolumns of \\f$U_j\\f$ or rows of \\f$V_j'\\f$ ) corresponding to the computed singular values are computed,\n- rocblas_svect_none: no columns (or rows) of \\f$U_j\\f$ (or \\f$V_j'\\f$ ) are computed, i.e.\nno singular vectors.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nleft_svect #rocblas_svect.\\n\nSpecifies if the left singular vectors are computed.\n@param[in]\nright_svect #rocblas_svect.\\n\nSpecifies if the right singular vectors are computed.\n@param[in]\nsrange #rocblas_srange.\\n\nSpecifies the type of range or interval of the singular values to be computed.\n@param[in]\nm rocblas_int. m >= 0.\\n\nThe number of rows of matrix A_j.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of columns of matrix A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j.\nOn exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= m.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nvl real type. 0 <= vl < vu.\\n\nThe lower bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values within a set of indices.\n@param[in]\nvu real type. 0 <= vl < vu.\\n\nThe upper bound of the search interval [vl, vu). Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the largest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest singular value to be computed. Ignored if srange indicates to look\nfor all the singular values of A_j or the singular values in a half-open interval.\n@param[out]\nnsv pointer to rocblas_int. Array of batch_count integers on the GPU. \\n\nThe total number of singular values found. If srange is rocblas_srange_all, nsv[j] = min(m,n).\nIf srange is rocblas_srange_index, nsv[j] = iu - il + 1. Otherwise, 0 <= nsv[j] <= min(m,n).\n@param[out]\nS pointer to real type. Array on the GPU (the size depends on the value of strideS). \\n\nThe first nsv_j elements contain the computed singular values in descending order.\n(The remaining elements may be used as workspace for internal computations).\n@param[in]\nstrideS rocblas_stride.\\n\nStride from the start of one vector S_j to the next one S_(j+1).\nThere is no restriction for the value of strideS. Normal use case is strideS >= min(m,n).\n@param[out]\nU pointer to type. Array on the GPU (the size depends on the value of strideU).\\n\nThe matrix U_j of left singular vectors stored as columns. Not\nreferenced if left_svect is set to none.\n@param[in]\nldu rocblas_int. ldu >= m if left_svect singular; ldu >= 1 otherwise.\\n\nThe leading dimension of U_j.\n@param[in]\nstrideU rocblas_stride.\\n\nStride from the start of one matrix U_j to the next one U_(j+1).\nThere is no restriction for the value of strideU. Normal use case is strideU >= ldu*min(m,n).\n@param[out]\nV pointer to type. Array on the GPU (the size depends on the value of strideV). \\n\nThe matrix V_j of right singular vectors stored as rows (transposed / conjugate-transposed).\nNot referenced if right_svect is set to none.\n@param[in]\nldv rocblas_int. ldv >= min(m,n) if right_svect is\nset to singular; or ldv >= 1 otherwise.\\n\nThe leading dimension of V_j.\n@param[in]\nstrideV rocblas_stride.\\n\nStride from the start of one matrix V_j to the next one V_(j+1).\nThere is no restriction for the value of strideV. Normal use case is strideV >= ldv*n.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nsv[j] elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge, as returned by \\ref rocsolver_sbdsvdx \"BDSVDX\".\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= min(m,n).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info[j] = 0, successful exit.\nIf info[j] = i > 0, i eigenvectors did not converge in \\ref rocsolver_sbdsvdx \"BDSVDX\"; their\nindices are stored in ifail_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgesvdx_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut f32, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f32, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgesvdx_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut f64, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut f64, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgesvdx_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f32, + strideS: rocblas_stride, + U: *mut rocblas_float_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_float_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgesvdx_strided_batched( + handle: rocblas_handle, + left_svect: rocblas_svect, + right_svect: rocblas_svect, + srange: rocblas_srange, + m: rocblas_int, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + nsv: *mut rocblas_int, + S: *mut f64, + strideS: rocblas_stride, + U: *mut rocblas_double_complex, + ldu: rocblas_int, + strideU: rocblas_stride, + V: *mut rocblas_double_complex, + ldv: rocblas_int, + strideV: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTD2 computes the tridiagonal form of a real symmetric matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form is given by:\n\n\\f[\nT = Q' A Q\n\\f]\n\nwhere T is symmetric tridiagonal and Q is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_{n-1} & \\: \\text{if uplo indicates lower, or}\\\\\nQ = H_{n-1}H_{n-2}\\cdots H_1 & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{tau}[i] \\cdot v_i v_i'\n\\f]\n\nwhere tau[i] is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_i stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_i stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nThe diagonal elements of T.\n@param[out]\nE pointer to type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of T.\n@param[out]\ntau pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars."] + pub fn rocsolver_ssytd2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tau: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytd2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tau: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETD2 computes the tridiagonal form of a complex hermitian matrix A.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form is given by:\n\n\\f[\nT = Q' A Q\n\\f]\n\nwhere T is hermitian tridiagonal and Q is an unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_{n-1} & \\: \\text{if uplo indicates lower, or}\\\\\nQ = H_{n-1}H_{n-2}\\cdots H_1 & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{tau}[i] \\cdot v_i v_i'\n\\f]\n\nwhere tau[i] is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T; the elements above the superdiagonal contain\nthe first i-1 elements of the Householders vector v_i stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_i stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe diagonal elements of T.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of T.\n@param[out]\ntau pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars."] + pub fn rocsolver_chetd2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tau: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetd2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tau: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTD2_BATCHED computes the tridiagonal form of a batch of real symmetric matrices A_j.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is symmetric tridiagonal and \\f$Q_j\\f$ is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytd2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytd2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETD2_BATCHED computes the tridiagonal form of a batch of complex hermitian matrices A_j.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is Hermitian tridiagonal and \\f$Q_j\\f$ is a unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch.\n"] + pub fn rocsolver_chetd2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetd2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTD2_STRIDED_BATCHED computes the tridiagonal form of a batch of real symmetric matrices A_j.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is symmetric tridiagonal and \\f$Q_j\\f$ is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytd2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytd2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETD2_STRIDED_BATCHED computes the tridiagonal form of a batch of complex hermitian matrices A_j.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is Hermitian tridiagonal and \\f$Q_j\\f$ is a unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chetd2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetd2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRD computes the tridiagonal form of a real symmetric matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form is given by:\n\n\\f[\nT = Q' A Q\n\\f]\n\nwhere T is symmetric tridiagonal and Q is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_{n-1} & \\: \\text{if uplo indicates lower, or}\\\\\nQ = H_{n-1}H_{n-2}\\cdots H_1 & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{tau}[i] \\cdot v_i v_i'\n\\f]\n\nwhere tau[i] is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_i stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_i stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nThe diagonal elements of T.\n@param[out]\nE pointer to type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of T.\n@param[out]\ntau pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars."] + pub fn rocsolver_ssytrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tau: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tau: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETRD computes the tridiagonal form of a complex hermitian matrix A.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form is given by:\n\n\\f[\nT = Q' A Q\n\\f]\n\nwhere T is hermitian tridiagonal and Q is an unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ = H_1H_2\\cdots H_{n-1} & \\: \\text{if uplo indicates lower, or}\\\\\nQ = H_{n-1}H_{n-2}\\cdots H_1 & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_i\\f$ is given by\n\n\\f[\nH_i = I - \\text{tau}[i] \\cdot v_i v_i'\n\\f]\n\nwhere tau[i] is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_i\\f$ are zero, and \\f$v_i[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_i stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_i stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe diagonal elements of T.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n-1.\\n\nThe off-diagonal elements of T.\n@param[out]\ntau pointer to type. Array on the GPU of dimension n-1.\\n\nThe Householder scalars."] + pub fn rocsolver_chetrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + tau: *mut rocblas_float_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetrd( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + tau: *mut rocblas_double_complex, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRD_BATCHED computes the tridiagonal form of a batch of real symmetric matrices A_j.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is symmetric tridiagonal and \\f$Q_j\\f$ is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytrd_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrd_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETRD_BATCHED computes the tridiagonal form of a batch of complex hermitian matrices A_j.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is Hermitian tridiagonal and \\f$Q_j\\f$ is a unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chetrd_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetrd_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRD_STRIDED_BATCHED computes the tridiagonal form of a batch of real symmetric matrices A_j.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is symmetric tridiagonal and \\f$Q_j\\f$ is an orthogonal matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytrd_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut f32, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrd_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut f64, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HETRD_STRIDED_BATCHED computes the tridiagonal form of a batch of complex hermitian matrices A_j.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe tridiagonal form of \\f$A_j\\f$ is given by:\n\n\\f[\nT_j = Q_j' A_j Q_j\n\\f]\n\nwhere \\f$T_j\\f$ is Hermitian tridiagonal and \\f$Q_j\\f$ is a unitary matrix represented as the product\nof Householder matrices\n\n\\f[\n\\begin{array}{cl}\nQ_j = H_{j_1}H_{j_2}\\cdots H_{j_{n-1}} & \\: \\text{if uplo indicates lower, or}\\\\\nQ_j = H_{j_{n-1}}H_{j_{n-2}}\\cdots H_{j_1} & \\: \\text{if uplo indicates upper.}\n\\end{array}\n\\f]\n\nEach Householder matrix \\f$H_{j_i}\\f$ is given by\n\n\\f[\nH_{j_i} = I - \\text{tau}_j[i] \\cdot v_{j_i} v_{j_i}'\n\\f]\n\nwhere \\f$\\text{tau}_j[i]\\f$ is the corresponding Householder scalar. When uplo indicates lower, the first i\nelements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i+1] = 1\\f$. If uplo indicates upper,\nthe last n-i elements of the Householder vector \\f$v_{j_i}\\f$ are zero, and \\f$v_{j_i}[i] = 1\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the hermitian matrix A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j to be factored.\nOn exit, if upper, then the elements on the diagonal and superdiagonal\ncontain the tridiagonal form T_j; the elements above the superdiagonal contain\nthe first i-1 elements of the Householder vectors v_(j_i) stored as columns.\nIf lower, then the elements on the diagonal and subdiagonal\ncontain the tridiagonal form T_j; the elements below the subdiagonal contain\nthe last n-i-1 elements of the Householder vectors v_(j_i) stored as columns.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nThe leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe diagonal elements of T_j.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThe off-diagonal elements of T_j.\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n-1.\n@param[out]\ntau pointer to type. Array on the GPU (the size depends on the value of strideP).\\n\nContains the vectors tau_j of corresponding Householder scalars.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector tau_j to the next one tau_(j+1).\nThere is no restriction for the value\nof strideP. Normal use is strideP >= n-1.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chetrd_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + tau: *mut rocblas_float_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhetrd_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + tau: *mut rocblas_double_complex, + strideP: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGS2 reduces a real symmetric-definite generalized eigenproblem to standard\nform.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU^{-T} A U^{-1}, & \\: \\text{or}\\\\\nL^{-1} A L^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix B has been factorized as either \\f$U^T U\\f$ or\n\\f$L L^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU A U^T, & \\: \\text{or}\\\\\nL^T A L,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored, and\nwhether the factorization applied to B was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A and\nB are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the transformed matrix associated with\nthe equivalent standard eigenvalue problem.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nThe triangular factor of the matrix B, as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B."] + pub fn rocsolver_ssygs2( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygs2( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGS2 reduces a hermitian-definite generalized eigenproblem to standard form.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU^{-H} A U^{-1}, & \\: \\text{or}\\\\\nL^{-1} A L^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix B has been factorized as either \\f$U^H U\\f$ or\n\\f$L L^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU A U^H, & \\: \\text{or}\\\\\nL^H A L,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored, and\nwhether the factorization applied to B was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A and\nB are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the transformed matrix associated with\nthe equivalent standard eigenvalue problem.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nThe triangular factor of the matrix B, as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B."] + pub fn rocsolver_chegs2( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegs2( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGS2_BATCHED reduces a batch of real symmetric-definite generalized eigenproblems\nto standard form.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-T} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^T U_j\\f$ or\n\\f$L_j L_j^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^T, & \\: \\text{or}\\\\\nL_j^T A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygs2_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygs2_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGS2_BATCHED reduces a batch of hermitian-definite generalized eigenproblems to\nstandard form.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-H} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^H U_j\\f$ or\n\\f$L_j L_j^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^H, & \\: \\text{or}\\\\\nL_j^H A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegs2_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegs2_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGS2_STRIDED_BATCHED reduces a batch of real symmetric-definite generalized\neigenproblems to standard form.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-T} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^T U_j\\f$ or\n\\f$L_j L_j^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^T, & \\: \\text{or}\\\\\nL_j^T A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*n.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygs2_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygs2_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGS2_STRIDED_BATCHED reduces a batch of hermitian-definite generalized\neigenproblems to standard form.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-H} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^H U_j\\f$ or\n\\f$L_j L_j^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^H, & \\: \\text{or}\\\\\nL_j^H A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*n.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegs2_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegs2_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGST reduces a real symmetric-definite generalized eigenproblem to standard\nform.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU^{-T} A U^{-1}, & \\: \\text{or}\\\\\nL^{-1} A L^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix B has been factorized as either \\f$U^T U\\f$ or\n\\f$L L^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU A U^T, & \\: \\text{or}\\\\\nL^T A L,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored, and\nwhether the factorization applied to B was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A and\nB are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the transformed matrix associated with\nthe equivalent standard eigenvalue problem.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nThe triangular factor of the matrix B, as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B."] + pub fn rocsolver_ssygst( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygst( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGST reduces a hermitian-definite generalized eigenproblem to standard form.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU^{-H} A U^{-1}, & \\: \\text{or}\\\\\nL^{-1} A L^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix B has been factorized as either \\f$U^H U\\f$ or\n\\f$L L^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU A U^H, & \\: \\text{or}\\\\\nL^H A L,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored, and\nwhether the factorization applied to B was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A and\nB are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the transformed matrix associated with\nthe equivalent standard eigenvalue problem.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nThe triangular factor of the matrix B, as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B."] + pub fn rocsolver_chegst( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegst( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGST_BATCHED reduces a batch of real symmetric-definite generalized eigenproblems\nto standard form.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-T} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^T U_j\\f$ or\n\\f$L_j L_j^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^T, & \\: \\text{or}\\\\\nL_j^T A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygst_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygst_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGST_BATCHED reduces a batch of hermitian-definite generalized eigenproblems to\nstandard form.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-H} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^H U_j\\f$ or\n\\f$L_j L_j^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^H, & \\: \\text{or}\\\\\nL_j^H A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegst_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegst_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGST_STRIDED_BATCHED reduces a batch of real symmetric-definite generalized\neigenproblems to standard form.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-T} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-T},\n\\end{array}\n\\f]\n\nwhere the symmetric-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^T U_j\\f$ or\n\\f$L_j L_j^T\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^T, & \\: \\text{or}\\\\\nL_j^T A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*n.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygst_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygst_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGST_STRIDED_BATCHED reduces a batch of hermitian-definite generalized\neigenproblems to standard form.\n\n\\details\n(This is the blocked version of the algorithm).\n\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype.\n\nIf the problem is of the 1st form, then \\f$A_j\\f$ is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j^{-H} A_j U_j^{-1}, & \\: \\text{or}\\\\\nL_j^{-1} A_j L_j^{-H},\n\\end{array}\n\\f]\n\nwhere the hermitian-definite matrix \\f$B_j\\f$ has been factorized as either \\f$U_j^H U_j\\f$ or\n\\f$L_j L_j^H\\f$ as returned by \\ref rocsolver_spotrf \"POTRF\", depending on the value of uplo.\n\nIf the problem is of the 2nd or 3rd form, then A is overwritten with\n\n\\f[\n\\begin{array}{cl}\nU_j A_j U_j^H, & \\: \\text{or}\\\\\nL_j^H A_j L_j,\n\\end{array}\n\\f]\n\nalso depending on the value of uplo.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored, and\nwhether the factorization applied to B_j was upper or lower triangular.\nIf uplo indicates lower (or upper), then the upper (or lower) parts of A_j and\nB_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the transformed matrices associated with\nthe equivalent standard eigenvalue problems.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nThe triangular factors of the matrices B_j, as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use case is strideB >= ldb*n.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegst_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegst_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEV computes the eigenvalues and optionally the eigenvectors of a real symmetric\nmatrix A.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\nE pointer to type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with A.\nOn exit, if info > 0, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues of A (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit. If info = i > 0, the algorithm did not converge.\ni elements of E did not converge to zero."] + pub fn rocsolver_ssyev( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyev( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEV computes the eigenvalues and optionally the eigenvectors of a Hermitian matrix A.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with A.\nOn exit, if info > 0, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues of A (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit. If info = i > 0, the algorithm did not converge.\ni elements of E did not converge to zero."] + pub fn rocsolver_cheev( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheev( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEV_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = i > 0, the algorithm did not converge.\ni elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyev_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyev_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEV_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nHermitian matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = i > 0, the algorithm did not converge.\ni elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheev_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheev_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEV_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = i > 0, the algorithm did not converge.\ni elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyev_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyev_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEV_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nHermitian matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed depending\non the value of evect. The computed eigenvectors are orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = i > 0, the algorithm did not converge.\ni elements of E_j did not converge to zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheev_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheev_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVD computes the eigenvalues and optionally the eigenvectors of a real symmetric\nmatrix A.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\nE pointer to type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with A.\nOn exit, if info > 0, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues of A (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E did not converge to zero.\nIf info = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)]."] + pub fn rocsolver_ssyevd( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevd( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVD computes the eigenvalues and optionally the eigenvectors of a Hermitian matrix A.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with A.\nOn exit, if info > 0, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues of A (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E did not converge to zero.\nIf info = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)]."] + pub fn rocsolver_cheevd( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevd( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVD_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E_j did not converge to zero.\nIf info[j] = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevd_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevd_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVD_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nHermitian matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E_j did not converge to zero.\nIf info[j] = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevd_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevd_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVD_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E_j did not converge to zero.\nIf info[j] = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevd_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevd_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVD_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nHermitian matrices A_j.\n\n\\details\nThe eigenvalues are returned in ascending order. The eigenvectors are computed using a\ndivide-and-conquer algorithm, depending on the value of evect. The computed eigenvectors\nare orthonormal.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use case is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with A_j.\nOn exit, if info[j] > 0, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues of A_j (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use case is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0 and evect is rocblas_evect_none, the algorithm did not converge.\ni elements of E_j did not converge to zero.\nIf info[j] = i > 0 and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevd_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevd_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVJ computes the eigenvalues and optionally the eigenvectors of a real symmetric\nmatrix A.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A\\f$ is transformed by a product of Jacobi rotations \\f$V\\f$ as\n\n\\f[\nA^{(k)} = V' A^{(k-1)} V\n\\f]\n\nsuch that \\f$off(A^{(k)}) < off(A^{(k-1)})\\f$, where \\f$A^{(0)} = A\\f$ and \\f$off(A^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A^{(k)}\\f$. As \\f$off(A^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A)\nis <= norm(A) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A (i.e. off(A)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to a rocblas_int on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm.\n@param[out]\nW pointer to type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit. If info = 1, the algorithm did not converge."] + pub fn rocsolver_ssyevj( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevj( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVJ computes the eigenvalues and optionally the eigenvectors of a complex Hermitian\nmatrix A.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A\\f$ is transformed by a product of Jacobi rotations \\f$V\\f$ as\n\n\\f[\nA^{(k)} = V' A^{(k-1)} V\n\\f]\n\nsuch that \\f$off(A^{(k)}) < off(A^{(k-1)})\\f$, where \\f$A^{(0)} = A\\f$ and \\f$off(A^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A^{(k)}\\f$. As \\f$off(A^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the eigenvectors of A if they were computed and\nthe algorithm converged; otherwise the contents of A are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A)\nis <= norm(A) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A (i.e. off(A)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to a rocblas_int on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm.\n@param[out]\nW pointer to real type. Array on the GPU of dimension n.\\n\nThe eigenvalues of A in increasing order.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit. If info = 1, the algorithm did not converge."] + pub fn rocsolver_cheevj( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevj( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVJ_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A_j\\f$ is transformed by a product of Jacobi rotations \\f$V_j\\f$ as\n\n\\f[\nA_j^{(k)} = V_j' A_j^{(k-1)} V_j\n\\f]\n\nsuch that \\f$off(A_j^{(k)}) < off(A_j^{(k-1)})\\f$, where \\f$A_j^{(0)} = A_j\\f$ and \\f$off(A_j^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A_j^{(k)}\\f$. As \\f$off(A_j^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A_j^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A_j\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j)\nis <= norm(A_j) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type. Array of batch_count scalars on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j (i.e. off(A_j)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevj_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevj_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVJ_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\ncomplex Hermitian matrices A_j.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A_j\\f$ is transformed by a product of Jacobi rotations \\f$V_j\\f$ as\n\n\\f[\nA_j^{(k)} = V_j' A_j^{(k-1)} V_j\n\\f]\n\nsuch that \\f$off(A_j^{(k)}) < off(A_j^{(k-1)})\\f$, where \\f$A_j^{(0)} = A_j\\f$ and \\f$off(A_j^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A_j^{(k)}\\f$. As \\f$off(A_j^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A_j^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A_j\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j)\nis <= norm(A_j) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type. Array of batch_count scalars on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j (i.e. off(A_j)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevj_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevj_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVJ_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\nreal symmetric matrices A_j.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A_j\\f$ is transformed by a product of Jacobi rotations \\f$V_j\\f$ as\n\n\\f[\nA_j^{(k)} = V_j' A_j^{(k-1)} V_j\n\\f]\n\nsuch that \\f$off(A_j^{(k)}) < off(A_j^{(k-1)})\\f$, where \\f$A_j^{(0)} = A_j\\f$ and \\f$off(A_j^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A_j^{(k)}\\f$. As \\f$off(A_j^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A_j^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A_j\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j)\nis <= norm(A_j) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type. Array of batch_count scalars on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j (i.e. off(A_j)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevj_strided_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevj_strided_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVJ_STRIDED_BATCHED computes the eigenvalues and optionally the eigenvectors of a batch of\ncomplex Hermitian matrices A_j.\n\n\\details\nThe eigenvalues are found using the iterative Jacobi algorithm and are returned in an order\ndepending on the value of esort.\nThe eigenvectors are computed depending on the value of evect. The computed eigenvectors are orthonormal.\n\nAt the \\f$k\\f$-th iteration (or \"sweep\"), \\f$A_j\\f$ is transformed by a product of Jacobi rotations \\f$V_j\\f$ as\n\n\\f[\nA_j^{(k)} = V_j' A_j^{(k-1)} V_j\n\\f]\n\nsuch that \\f$off(A_j^{(k)}) < off(A_j^{(k-1)})\\f$, where \\f$A_j^{(0)} = A_j\\f$ and \\f$off(A_j^{(k)})\\f$ is the\nFrobenius norm of the off-diagonal elements of \\f$A_j^{(k)}\\f$. As \\f$off(A_j^{(k)}) \\rightarrow 0\\f$, the\ndiagonal elements of \\f$A_j^{(k)}\\f$ increasingly resemble the eigenvalues of \\f$A_j\\f$.\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nesort #rocblas_esort.\\n\nSpecifies the order of the returned eigenvalues. If esort is\nrocblas_esort_ascending, then the eigenvalues are sorted and returned in ascending order.\nIf esort is rocblas_esort_none, then the order of the returned eigenvalues is unspecified.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the Hermitian matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the eigenvectors of A_j if they were computed and\nthe algorithm converged; otherwise the contents of A_j are unchanged.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(A_j)\nis <= norm(A_j) * abstol. If abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to real type. Array of batch_count scalars on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of A_j (i.e. off(A_j)) at the final iteration.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe eigenvalues of A_j in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j. If info[j] = 1, the algorithm did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevj_strided_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevj_strided_batched( + handle: rocblas_handle, + esort: rocblas_esort, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVX computes a set of the eigenvalues and optionally the corresponding eigenvectors of a\nreal symmetric matrix A.\n\n\\details\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to a rocblas_int on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev = n.\nIf erange is rocblas_erange_index, nev = iu - il + 1. Otherwise, 0 <= nev <= n.\n@param[out]\nW pointer to type. Array on the GPU of dimension n.\\n\nThe first nev elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[out]\nZ pointer to type. Array on the GPU of dimension ldz*nev.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev columns contain\nthe eigenvectors of A corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev are not known in advance.\nThe user should ensure that Z is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrix Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nev elements of ifail are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, the algorithm did not converge. i columns of Z did not converge."] + pub fn rocsolver_ssyevx( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + Z: *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevx( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + Z: *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVX computes a set of the eigenvalues and optionally the corresponding eigenvectors of a\nHermitian matrix A.\n\n\\details\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to a rocblas_int on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev = n.\nIf erange is rocblas_erange_index, nev = iu - il + 1. Otherwise, 0 <= nev <= n.\n@param[out]\nW pointer to real type. Array on the GPU of dimension n.\\n\nThe first nev elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[out]\nZ pointer to type. Array on the GPU of dimension ldz*nev.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev columns contain\nthe eigenvectors of A corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev are not known in advance.\nThe user should ensure that Z is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrix Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nev elements of ifail are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, the algorithm did not converge. i columns of Z did not converge."] + pub fn rocsolver_cheevx( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + Z: *mut rocblas_float_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevx( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + Z: *mut rocblas_double_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVX_BATCHED computes a set of the eigenvalues and optionally the corresponding eigenvectors\nof a batch of real symmetric matrices A_j.\n\n\\details\nThis function computes all the eigenvalues of A_j, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ Array of pointers to type. Each pointer points to an array on the GPU of dimension ldz*nev_j.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0, the algorithm did not converge. i columns of Z_j did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevx_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *const *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevx_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *const *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVX_BATCHED computes a set of the eigenvalues and optionally the corresponding eigenvectors\nof a batch of Hermitian matrices A_j.\n\n\\details\nThis function computes all the eigenvalues of A_j, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ Array of pointers to type. Each pointer points to an array on the GPU of dimension ldz*nev_j.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0, the algorithm did not converge. i columns of Z_j did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevx_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *const *mut rocblas_float_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevx_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *const *mut rocblas_double_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYEVX_STRIDED_BATCHED computes a set of the eigenvalues and optionally the corresponding eigenvectors\nof a batch of real symmetric matrices A_j.\n\n\\details\nThis function computes all the eigenvalues of A_j, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ pointer to type. Array on the GPU (the size depends on the value of strideZ).\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[in]\nstrideZ rocblas_stride.\\n\nStride from the start of one matrix Z_j to the next one Z_(j+1).\nThere is no restriction for the value of strideZ. Normal use case is strideZ >= ldz*nev_j.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0, the algorithm did not converge. i columns of Z_j did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssyevx_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *mut f32, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsyevx_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *mut f64, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEEVX_STRIDED_BATCHED computes a set of the eigenvalues and optionally the corresponding eigenvectors\nof a batch of Hermitian matrices A_j.\n\n\\details\nThis function computes all the eigenvalues of A_j, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the symmetric matrices A_j is stored.\nIf uplo indicates lower (or upper), then the upper (or lower) part of A_j\nis not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nNumber of rows and columns of matrices A_j.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ pointer to type. Array on the GPU (the size depends on the value of strideZ).\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[in]\nstrideZ rocblas_stride.\\n\nStride from the start of one matrix Z_j to the next one Z_(j+1).\nThere is no restriction for the value of strideZ. Normal use case is strideZ >= ldz*nev_j.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nOtherwise, contains the indices of those eigenvectors that failed\nto converge. Not referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for matrix A_j.\nIf info[j] = i > 0, the algorithm did not converge. i columns of Z_j did not converge.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_cheevx_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *mut rocblas_float_complex, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zheevx_strided_batched( + handle: rocblas_handle, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *mut rocblas_double_complex, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGV computes the eigenvalues and (optionally) eigenvectors of\na real generalized symmetric-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^T B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^T B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\nE pointer to type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with\nthe reduced eigenvalue problem.\nOn exit, if 0 < info <= n, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_ssygv( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygv( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGV computes the eigenvalues and (optionally) eigenvectors of\na complex generalized hermitian-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^H B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^H B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with\nthe reduced eigenvalue problem.\nOn exit, if 0 < info <= n, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_chegv( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegv( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGV_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, E_j contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch instance j.\nIf info[j] = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygv_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygv_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGV_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegv_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegv_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGV_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygv_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygv_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGV_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n, i off-diagonal elements of an intermediate\ntridiagonal form did not converge to zero.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegv_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegv_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVD computes the eigenvalues and (optionally) eigenvectors of\na real generalized symmetric-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^T B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^T B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[out]\nD pointer to type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\nE pointer to type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with\nthe reduced eigenvalue problem.\nOn exit, if 0 < info <= n, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_ssygvd( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvd( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVD computes the eigenvalues and (optionally) eigenvectors of\na complex generalized hermitian-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^H B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^H B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[out]\nD pointer to real type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\nE pointer to real type. Array on the GPU of dimension n.\\n\nThis array is used to work internally with the tridiagonal matrix T associated with\nthe reduced eigenvalue problem.\nOn exit, if 0 < info <= n, it contains the unconverged off-diagonal elements of T\n(or properly speaking, a tridiagonal matrix equivalent to T). The diagonal elements\nof this matrix are in D; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_chegvd( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + D: *mut f32, + E: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvd( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + D: *mut f64, + E: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVD_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info[j] = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvd_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvd_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVD_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info[j] = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvd_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvd_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVD_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[out]\nD pointer to type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info[j] = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvd_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvd_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVD_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed using a divide-and-conquer algorithm, depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[out]\nD pointer to real type. Array on the GPU (the size depends on the value of strideD).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideD rocblas_stride.\\n\nStride from the start of one vector D_j to the next one D_(j+1).\nThere is no restriction for the value of strideD. Normal use is strideD >= n.\n@param[out]\nE pointer to real type. Array on the GPU (the size depends on the value of strideE).\\n\nThis array is used to work internally with the tridiagonal matrix T_j associated with\nthe jth reduced eigenvalue problem.\nOn exit, if 0 < info[j] <= n, it contains the unconverged off-diagonal elements of T_j\n(or properly speaking, a tridiagonal matrix equivalent to T_j). The diagonal elements\nof this matrix are in D_j; those that converged correspond to a subset of the\neigenvalues (not necessarily ordered).\n@param[in]\nstrideE rocblas_stride.\\n\nStride from the start of one vector E_j to the next one E_(j+1).\nThere is no restriction for the value of strideE. Normal use is strideE >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n and evect is rocblas_evect_none, i off-diagonal elements of an\nintermediate tridiagonal form did not converge to zero.\nIf info[j] = i <= n and evect is rocblas_evect_original, the algorithm failed to\ncompute an eigenvalue in the submatrix from [i/(n+1), i/(n+1)] to [i%(n+1), i%(n+1)].\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvd_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f32, + strideD: rocblas_stride, + E: *mut f32, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvd_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + D: *mut f64, + strideD: rocblas_stride, + E: *mut f64, + strideE: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVJ computes the eigenvalues and (optionally) eigenvectors of\na real generalized symmetric-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^T B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^T B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T)\nis <= norm(T) * abstol, where T is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T (i.e. off(T)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to a rocblas_int on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm.\n@param[out]\nW pointer to type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = 1, the algorithm did not converge.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_ssygvj( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvj( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVJ computes the eigenvalues and (optionally) eigenvectors of\na complex generalized hermitian-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^H B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^H B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrix A. On exit, if evect is original,\nthe normalized matrix Z of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrix A (including the diagonal) is destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T)\nis <= norm(T) * abstol, where T is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T (i.e. off(T)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to a rocblas_int on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm.\n@param[out]\nW pointer to real type. Array on the GPU of dimension n.\\n\nOn exit, the eigenvalues in increasing order.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = 1, the algorithm did not converge.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_chegvj( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvj( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVJ_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T_j)\nis <= norm(T_j) * abstol, where T_j is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T_j (i.e. off(T_j)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch instance j.\nIf info[j] = 1, the algorithm did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvj_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvj_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVJ_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[out]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T_j)\nis <= norm(T_j) * abstol, where T_j is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T_j (i.e. off(T_j)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = 1, the algorithm did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvj_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvj_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVJ_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T_j)\nis <= norm(T_j) * abstol, where T_j is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T_j (i.e. off(T_j)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = 1, the algorithm did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvj_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvj_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVJ_STRIDED_BATCHED computes the eigenvalues and (optionally)\neigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvalues are found using the iterative\nJacobi algorithm, and are returned in ascending order. The eigenvectors are computed\ndepending on the value of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\n\\note\nIn order to carry out calculations, this method may synchronize the stream contained within the\nrocblas_handle.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the hermitian matrices A_j. On exit, if evect is original,\nthe normalized matrix Z_j of eigenvectors. If evect is none, then the upper or lower triangular\npart of the matrices A_j (including the diagonal) are destroyed,\ndepending on the value of uplo.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. The algorithm is considered to have converged once off(T_j)\nis <= norm(T_j) * abstol, where T_j is the matrix obtained by reduction to standard form.\nIf abstol <= 0, then the tolerance will be set to machine precision.\n@param[out]\nresidual pointer to type on the GPU.\\n\nThe Frobenius norm of the off-diagonal elements of T_j (i.e. off(T_j)) at the final iteration,\nwhere T is the matrix obtained by reduction to standard form.\n@param[in]\nmax_sweeps rocblas_int. max_sweeps > 0.\\n\nMaximum number of sweeps (iterations) to be used by the algorithm.\n@param[out]\nn_sweeps pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe actual number of sweeps (iterations) used by the algorithm for each batch instance.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nOn exit, the eigenvalues in increasing order.\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use is strideW >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = 1, the algorithm did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvj_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + abstol: f32, + residual: *mut f32, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvj_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + abstol: f64, + residual: *mut f64, + max_sweeps: rocblas_int, + n_sweeps: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVX computes a set of the eigenvalues and optionally the corresponding eigenvectors of\na real generalized symmetric-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^T B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^T B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to a rocblas_int on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev = n.\nIf erange is rocblas_erange_index, nev = iu - il + 1. Otherwise, 0 <= nev <= n.\n@param[out]\nW pointer to type. Array on the GPU of dimension n.\\n\nThe first nev elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[out]\nZ pointer to type. Array on the GPU of dimension ldz*nev.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev columns contain\nthe eigenvectors of A corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev are not known in advance.\nThe user should ensure that Z is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrix Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nev elements of ifail are zero.\nIf info = i <= n, ifail contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n, i columns of Z did not converge.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_ssygvx( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + Z: *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvx( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + Z: *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVX computes a set of the eigenvalues and optionally the corresponding eigenvectors of\na complex generalized hermitian-definite eigenproblem.\n\n\\details\nThe problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA X = \\lambda B X & \\: \\text{1st form,}\\\\\nA B X = \\lambda X & \\: \\text{2nd form, or}\\\\\nB A X = \\lambda X & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix Z of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ^H B Z=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ^H B^{-1} Z=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblem.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA and B are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A and B are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the matrix A. On exit, the contents of A are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrix A.\n@param[out]\nB pointer to type. Array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrix B. On exit, the\ntriangular factor of B as returned by \\ref rocsolver_spotrf \"POTRF\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to a rocblas_int on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev = n.\nIf erange is rocblas_erange_index, nev = iu - il + 1. Otherwise, 0 <= nev <= n.\n@param[out]\nW pointer to real type. Array on the GPU of dimension n.\\n\nThe first nev elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[out]\nZ pointer to type. Array on the GPU of dimension ldz*nev.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev columns contain\nthe eigenvectors of A corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev are not known in advance.\nThe user should ensure that Z is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrix Z.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU of dimension n.\\n\nIf info = 0, the first nev elements of ifail are zero.\nIf info = i <= n, ifail contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i <= n, i columns of Z did not converge.\nIf info = n + i, the leading minor of order i of B is not\npositive definite."] + pub fn rocsolver_chegvx( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + Z: *mut rocblas_float_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvx( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + Z: *mut rocblas_double_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVX_BATCHED computes a set of the eigenvalues and optionally\nthe corresponding eigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ Array of pointers to type. Each pointer points to an array on the GPU of dimension ldz*nev_j.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nIf info[j] = i <= n, ifail_j contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch instance j.\nIf info[j] = i <= n, i columns of Z did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvx_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *const *mut f32, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvx_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *const *mut f64, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVX_BATCHED computes a set of the eigenvalues and optionally\nthe corresponding eigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA Array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nB Array of pointers to type. Each pointer points to an array on the GPU of dimension ldb*n.\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_batched \"POTRF_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ Array of pointers to type. Each pointer points to an array on the GPU of dimension ldz*nev_j.\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nIf info[j] = i <= n, ifail_j contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch instance j.\nIf info[j] = i <= n, i columns of Z did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvx_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *const *mut rocblas_float_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvx_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *const *mut rocblas_double_complex, + ldz: rocblas_int, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYGVX_STRIDED_BATCHED computes a set of the eigenvalues and optionally\nthe corresponding eigenvectors of a batch of real generalized symmetric-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^T B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^T B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the symmetric positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[in]\nvl type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ pointer to type. Array on the GPU (the size depends on the value of strideZ).\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[in]\nstrideZ rocblas_stride.\\n\nStride from the start of one matrix Z_j to the next one Z_(j+1).\nThere is no restriction for the value of strideZ. Normal use case is strideZ >= ldz*nev_j.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nIf info[j] = i <= n, ifail_j contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n, i columns of Z did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssygvx_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *mut f32, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsygvx_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *mut f64, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief HEGVX_STRIDED_BATCHED computes a set of the eigenvalues and optionally\nthe corresponding eigenvectors of a batch of complex generalized hermitian-definite eigenproblems.\n\n\\details\nFor each instance in the batch, the problem solved by this function is either of the form\n\n\\f[\n\\begin{array}{cl}\nA_j X_j = \\lambda B_j X_j & \\: \\text{1st form,}\\\\\nA_j B_j X_j = \\lambda X_j & \\: \\text{2nd form, or}\\\\\nB_j A_j X_j = \\lambda X_j & \\: \\text{3rd form,}\n\\end{array}\n\\f]\n\ndepending on the value of itype. The eigenvectors are computed depending on the\nvalue of evect.\n\nWhen computed, the matrix \\f$Z_j\\f$ of eigenvectors is normalized as follows:\n\n\\f[\n\\begin{array}{cl}\nZ_j^H B_j Z_j=I & \\: \\text{if 1st or 2nd form, or}\\\\\nZ_j^H B_j^{-1} Z_j=I & \\: \\text{if 3rd form.}\n\\end{array}\n\\f]\n\nThis function computes all the eigenvalues of A, all the eigenvalues in the half-open interval \\f$(vl, vu]\\f$,\nor the il-th through iu-th eigenvalues, depending on the value of erange. If evect is rocblas_evect_original,\nthe eigenvectors for these eigenvalues will be computed as well.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nitype #rocblas_eform.\\n\nSpecifies the form of the generalized eigenproblems.\n@param[in]\nevect #rocblas_evect.\\n\nSpecifies whether the eigenvectors are to be computed.\nIf evect is rocblas_evect_original, then the eigenvectors are computed.\nrocblas_evect_tridiagonal is not supported.\n@param[in]\nerange #rocblas_erange.\\n\nSpecifies the type of range or interval of the eigenvalues to be computed.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower parts of the matrices\nA_j and B_j are stored. If uplo indicates lower (or upper),\nthen the upper (or lower) parts of A_j and B_j are not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe matrix dimensions.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the matrices A_j. On exit, the contents of A_j are destroyed.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n.\n@param[out]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, the hermitian positive definite matrices B_j. On exit, the\ntriangular factor of B_j as returned by \\ref rocsolver_spotrf_strided_batched \"POTRF_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nSpecifies the leading dimension of B_j.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one matrix B_j to the next one B_(j+1).\nThere is no restriction for the value of strideB. Normal use is strideB >= ldb*n.\n@param[in]\nvl real type. vl < vu.\\n\nThe lower bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nvu real type. vl < vu.\\n\nThe upper bound of the search interval (vl, vu]. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues within a set of indices.\n@param[in]\nil rocblas_int. il = 1 if n = 0; 1 <= il <= iu otherwise.\\n\nThe index of the smallest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of A or the eigenvalues in a half-open interval.\n@param[in]\niu rocblas_int. iu = 0 if n = 0; 1 <= il <= iu otherwise..\\n\nThe index of the largest eigenvalue to be computed. Ignored if range indicates to look\nfor all the eigenvalues of T or the eigenvalues in a half-open interval.\n@param[in]\nabstol real type.\\n\nThe absolute tolerance. An eigenvalue is considered to be located if it lies\nin an interval whose width is <= abstol. If abstol is negative, then machine-epsilon times\nthe 1-norm of T will be used as tolerance. If abstol=0, then the tolerance will be set\nto twice the underflow threshold; this is the tolerance that could get the most accurate results.\n@param[out]\nnev pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nThe total number of eigenvalues found. If erange is rocblas_erange_all, nev_j = n.\nIf erange is rocblas_erange_index, nev_j = iu - il + 1. Otherwise, 0 <= nev_j <= n.\n@param[out]\nW pointer to real type. Array on the GPU (the size depends on the value of strideW).\\n\nThe first nev_j elements contain the computed eigenvalues. (The remaining elements\ncan be used as workspace for internal computations).\n@param[in]\nstrideW rocblas_stride.\\n\nStride from the start of one vector W_j to the next one W_(j+1).\nThere is no restriction for the value of strideW. Normal use case is strideW >= n.\n@param[out]\nZ pointer to type. Array on the GPU (the size depends on the value of strideZ).\\n\nOn exit, if evect is not rocblas_evect_none and info = 0, the first nev_j columns contain\nthe eigenvectors of A_j corresponding to the output eigenvalues. Not referenced if\nevect is rocblas_evect_none.\n@param[in]\nldz rocblas_int. ldz >= n.\\n\nSpecifies the leading dimension of matrices Z_j.\n@param[in]\nstrideZ rocblas_stride.\\n\nStride from the start of one matrix Z_j to the next one Z_(j+1).\nThere is no restriction for the value of strideZ. Normal use case is strideZ >= ldz*nev_j.\nNote: If erange is rocblas_range_value, then the values of nev_j are not known in advance.\nThe user should ensure that Z_j is large enough to hold n columns, as all n columns\ncan be used as workspace for internal computations.\n@param[out]\nifail pointer to rocblas_int. Array on the GPU (the size depends on the value of strideF).\\n\nIf info[j] = 0, the first nev_j elements of ifail_j are zero.\nIf info[j] = i <= n, ifail_j contains the indices of the i eigenvectors that failed\nto converge.\nNot referenced if evect is rocblas_evect_none.\n@param[in]\nstrideF rocblas_stride.\\n\nStride from the start of one vector ifail_j to the next one ifail_(j+1).\nThere is no restriction for the value of strideF. Normal use case is strideF >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit of batch j.\nIf info[j] = i <= n, i columns of Z did not converge.\nIf info[j] = n + i, the leading minor of order i of B_j is not\npositive definite.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_chegvx_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + vl: f32, + vu: f32, + il: rocblas_int, + iu: rocblas_int, + abstol: f32, + nev: *mut rocblas_int, + W: *mut f32, + strideW: rocblas_stride, + Z: *mut rocblas_float_complex, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zhegvx_strided_batched( + handle: rocblas_handle, + itype: rocblas_eform, + evect: rocblas_evect, + erange: rocblas_erange, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + vl: f64, + vu: f64, + il: rocblas_int, + iu: rocblas_int, + abstol: f64, + nev: *mut rocblas_int, + W: *mut f64, + strideW: rocblas_stride, + Z: *mut rocblas_double_complex, + ldz: rocblas_int, + strideZ: rocblas_stride, + ifail: *mut rocblas_int, + strideF: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_OUTOFPLACE computes the inverse \\f$C = A^{-1}\\f$ of a general n-by-n matrix A.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nAC = I\n\\f]\n\nwhere I is the identity matrix, and A is factorized as \\f$A = PLU\\f$ as given by \\ref rocsolver_sgetrf \"GETRF\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nThe factors L and U of the factorization A = P*L*U returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf \"GETRF\".\n@param[out]\nC pointer to type. Array on the GPU of dimension ldc*n.\\n\nIf info = 0, the inverse of A. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetri_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_OUTOFPLACE_BATCHED computes the inverse \\f$C_j = A_j^{-1}\\f$ of a batch of general n-by-n matrices \\f$A_j\\f$.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA_j C_j = I\n\\f]\n\nwhere I is the identity matrix, and \\f$A_j\\f$ is factorized as \\f$A_j = P_j L_j U_j\\f$ as given by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[in]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nThe factors L_j and U_j of the factorization A_j = P_j*L_j*U_j returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf_batched \"GETRF_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(i+j).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\nC array of pointers to type. Each pointer points to an array on the GPU of dimension ldc*n.\\n\nIf info[j] = 0, the inverse of matrices A_j. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *const *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *const *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_OUTOFPLACE_STRIDED_BATCHED computes the inverse \\f$C_j = A_j^{-1}\\f$ of a batch of general n-by-n matrices \\f$A_j\\f$.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA_j C_j = I\n\\f]\n\nwhere I is the identity matrix, and \\f$A_j\\f$ is factorized as \\f$A_j = P_j L_j U_j\\f$ as given by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nThe factors L_j and U_j of the factorization A_j = P_j*L_j*U_j returned by\n\\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[in]\nipiv pointer to rocblas_int. Array on the GPU (the size depends on the value of strideP).\\n\nThe pivot indices returned by \\ref rocsolver_sgetrf_strided_batched \"GETRF_STRIDED_BATCHED\".\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\nC pointer to type. Array on the GPU (the size depends on the value of strideC).\\n\nIf info[j] = 0, the inverse of matrices A_j. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C_j.\n@param[in]\nstrideC rocblas_stride.\\n\nStride from the start of one matrix C_j to the next one C_(j+1).\nThere is no restriction for the value of strideC. Normal use case is strideC >= ldc*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT_OUTOFPLACE computes the inverse \\f$C = A^{-1}\\f$ of a general n-by-n matrix A without partial pivoting.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nAC = I\n\\f]\n\nwhere I is the identity matrix, and A is factorized as \\f$A = LU\\f$ as given by \\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nThe factors L and U of the factorization A = L*U returned by \\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nC pointer to type. Array on the GPU of dimension ldc*n.\\n\nIf info = 0, the inverse of A. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, U is singular. U[i,i] is the first zero pivot."] + pub fn rocsolver_sgetri_npvt_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt_outofplace( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT_OUTOFPLACE_BATCHED computes the inverse \\f$C_j = A_j^{-1}\\f$ of a batch of general n-by-n matrices \\f$A_j\\f$\nwithout partial pivoting.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA_j C_j = I\n\\f]\n\nwhere I is the identity matrix, and \\f$A_j\\f$ is factorized as \\f$A_j = L_j U_j\\f$ as given by \\ref rocsolver_sgetrf_npvt_batched \"GETRF_NPVT_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[in]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nThe factors L_j and U_j of the factorization A_j = L_j*U_j returned by \\ref rocsolver_sgetrf_npvt_batched \"GETRF_NPVT_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nC array of pointers to type. Each pointer points to an array on the GPU of dimension ldc*n.\\n\nIf info[j] = 0, the inverse of matrices A_j. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_npvt_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt_outofplace_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GETRI_NPVT_OUTOFPLACE_STRIDED_BATCHED computes the inverse \\f$C_j = A_j^{-1}\\f$ of a batch of general n-by-n matrices \\f$A_j\\f$\nwithout partial pivoting.\n\n\\details\nThe inverse is computed by solving the linear system\n\n\\f[\nA_j C_j = I\n\\f]\n\nwhere I is the identity matrix, and \\f$A_j\\f$ is factorized as \\f$A_j = L_j U_j\\f$ as given by \\ref rocsolver_sgetrf_npvt_strided_batched \"GETRF_NPVT_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nThe factors L_j and U_j of the factorization A_j = L_j*U_j returned by\n\\ref rocsolver_sgetrf_npvt_strided_batched \"GETRF_NPVT_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\nC pointer to type. Array on the GPU (the size depends on the value of strideC).\\n\nIf info[j] = 0, the inverse of matrices A_j. Otherwise, undefined.\n@param[in]\nldc rocblas_int. ldc >= n.\\n\nSpecifies the leading dimension of C_j.\n@param[in]\nstrideC rocblas_stride.\\n\nStride from the start of one matrix C_j to the next one C_(j+1).\nThere is no restriction for the value of strideC. Normal use case is strideC >= ldc*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, U_j is singular. U_j[i,i] is the first zero pivot.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgetri_npvt_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgetri_npvt_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgetri_npvt_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgetri_npvt_outofplace_strided_batched( + handle: rocblas_handle, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief TRTRI inverts a triangular n-by-n matrix A.\n\n\\details\nA can be upper or lower triangular, depending on the value of uplo, and unit or non-unit\ntriangular, depending on the value of diag.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\ndiag rocblas_diagonal.\\n\nIf diag indicates unit, then the diagonal elements of A are not referenced and\nassumed to be one.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the triangular matrix.\nOn exit, the inverse of A if info = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, A is singular. A[i,i] is the first zero element in the diagonal."] + pub fn rocsolver_strtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dtrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ctrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ztrtri( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief TRTRI_BATCHED inverts a batch of triangular n-by-n matrices \\f$A_j\\f$.\n\n\\details\n\\f$A_j\\f$ can be upper or lower triangular, depending on the value of uplo, and unit or non-unit\ntriangular, depending on the value of diag.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\ndiag rocblas_diagonal.\\n\nIf diag indicates unit, then the diagonal elements of matrices A_j are not referenced and\nassumed to be one.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the triangular matrices A_j.\nOn exit, the inverses of A_j if info[j] = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, A_j is singular. A_j[i,i] is the first zero element in the diagonal.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_strtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dtrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ctrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ztrtri_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief TRTRI_STRIDED_BATCHED inverts a batch of triangular n-by-n matrices \\f$A_j\\f$.\n\n\\details\n\\f$A_j\\f$ can be upper or lower triangular, depending on the value of uplo, and unit or non-unit\ntriangular, depending on the value of diag.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\ndiag rocblas_diagonal.\\n\nIf diag indicates unit, then the diagonal elements of matrices A_j are not referenced and\nassumed to be one.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the triangular matrices A_j.\nOn exit, the inverses of A_j if info[j] = 0.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for inversion of A_j.\nIf info[j] = i > 0, A_j is singular. A_j[i,i] is the first zero element in the diagonal.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_strtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dtrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ctrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_ztrtri_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + diag: rocblas_diagonal, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTF2 computes the factorization of a symmetric indefinite matrix \\f$A\\f$\nusing Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA = U D U^T & \\: \\text{or}\\\\\nA = L D L^T &\n\\end{array}\n\\f]\n\nwhere \\f$U\\f$ or \\f$L\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D(k)\\f$.\n\nSpecifically, \\f$U\\f$ and \\f$L\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU = P(n) U(n) \\cdots P(k) U(k) \\cdots & \\: \\text{and}\\\\\nL = P(1) L(1) \\cdots P(k) L(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D(k)\\f$, and \\f$P(k)\\f$ is a permutation matrix defined by\n\\f$ipiv[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D(k)\\f$, then \\f$U(k)\\f$\nand \\f$L(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D(k)\\f$ is stored in \\f$A[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D(k)\\f$ is stored in \\f$A[k-1,k-1]\\f$, \\f$A[k-1,k]\\f$,\nand \\f$A[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D(k)\\f$ is stored in \\f$A[k,k]\\f$, \\f$A[k+1,k]\\f$,\nand \\f$A[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A to be factored.\nOn exit, the block diagonal matrix D and the multipliers needed to\ncompute U or L.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv[k] > 0 then rows and columns k and ipiv[k]\nwere interchanged and D[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv[k] = ipiv[k-1] < 0 and uplo is upper (or ipiv[k]\n= ipiv[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv[k] (or rows and columns k+1 and -ipiv[k]) were interchanged\nand D[k-1,k-1] to D[k,k] (or D[k,k] to D[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, D is singular. D[i,i] is the first diagonal zero."] + pub fn rocsolver_ssytf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytf2( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTF2_BATCHED computes the factorization of a batch of symmetric indefinite\nmatrices using Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j D_j U_j^T & \\: \\text{or}\\\\\nA_j = L_j D_j L_j^T &\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D_j\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D_j(k)\\f$.\n\nSpecifically, \\f$U_j\\f$ and \\f$L_j\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU_j = P_j(n) U_j(n) \\cdots P_j(k) U_j(k) \\cdots & \\: \\text{and}\\\\\nL_j = P_j(1) L_j(1) \\cdots P_j(k) L_j(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D_j(k)\\f$, and \\f$P_j(k)\\f$ is a permutation matrix defined by\n\\f$ipiv_j[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D_j(k)\\f$, then \\f$U_j(k)\\f$\nand \\f$L_j(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k-1,k-1]\\f$, \\f$A_j[k-1,k]\\f$,\nand \\f$A_j[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$, \\f$A_j[k+1,k]\\f$,\nand \\f$A_j[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A_j\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrices A_j to be factored.\nOn exit, the block diagonal matrices D_j and the multipliers needed to\ncompute U_j or L_j.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv_j[k] > 0 then rows and columns k and ipiv_j[k]\nwere interchanged and D_j[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv_j[k] = ipiv_j[k-1] < 0 and uplo is upper (or ipiv_j[k]\n= ipiv_j[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv_j[k] (or rows and columns k+1 and -ipiv_j[k]) were interchanged\nand D_j[k-1,k-1] to D_j[k,k] (or D_j[k,k] to D_j[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, D_j is singular. D_j[i,i] is the first diagonal zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytf2_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTF2_STRIDED_BATCHED computes the factorization of a batch of symmetric indefinite\nmatrices using Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the unblocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j D_j U_j^T & \\: \\text{or}\\\\\nA_j = L_j D_j L_j^T &\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D_j\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D_j(k)\\f$.\n\nSpecifically, \\f$U_j\\f$ and \\f$L_j\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU_j = P_j(n) U_j(n) \\cdots P_j(k) U_j(k) \\cdots & \\: \\text{and}\\\\\nL_j = P_j(1) L_j(1) \\cdots P_j(k) L_j(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D_j(k)\\f$, and \\f$P_j(k)\\f$ is a permutation matrix defined by\n\\f$ipiv_j[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D_j(k)\\f$, then \\f$U_j(k)\\f$\nand \\f$L_j(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k-1,k-1]\\f$, \\f$A_j[k-1,k]\\f$,\nand \\f$A_j[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$, \\f$A_j[k+1,k]\\f$,\nand \\f$A_j[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A_j\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric matrices A_j to be factored.\nOn exit, the block diagonal matrices D_j and the multipliers needed to\ncompute U_j or L_j.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv_j[k] > 0 then rows and columns k and ipiv_j[k]\nwere interchanged and D_j[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv_j[k] = ipiv_j[k-1] < 0 and uplo is upper (or ipiv_j[k]\n= ipiv_j[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv_j[k] (or rows and columns k+1 and -ipiv_j[k]) were interchanged\nand D_j[k-1,k-1] to D_j[k,k] (or D_j[k,k] to D_j[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, D_j is singular. D_j[i,i] is the first diagonal zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytf2_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRF computes the factorization of a symmetric indefinite matrix \\f$A\\f$\nusing Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA = U D U^T & \\: \\text{or}\\\\\nA = L D L^T &\n\\end{array}\n\\f]\n\nwhere \\f$U\\f$ or \\f$L\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D(k)\\f$.\n\nSpecifically, \\f$U\\f$ and \\f$L\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU = P(n) U(n) \\cdots P(k) U(k) \\cdots & \\: \\text{and}\\\\\nL = P(1) L(1) \\cdots P(k) L(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D(k)\\f$, and \\f$P(k)\\f$ is a permutation matrix defined by\n\\f$ipiv[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D(k)\\f$, then \\f$U(k)\\f$\nand \\f$L(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D(k)\\f$ is stored in \\f$A[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D(k)\\f$ is stored in \\f$A[k-1,k-1]\\f$, \\f$A[k-1,k]\\f$,\nand \\f$A[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D(k)\\f$ is stored in \\f$A[k,k]\\f$, \\f$A[k+1,k]\\f$,\nand \\f$A[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrix A is stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of the matrix A.\n@param[inout]\nA pointer to type. Array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrix A to be factored.\nOn exit, the block diagonal matrix D and the multipliers needed to\ncompute U or L.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of A.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv[k] > 0 then rows and columns k and ipiv[k]\nwere interchanged and D[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv[k] = ipiv[k-1] < 0 and uplo is upper (or ipiv[k]\n= ipiv[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv[k] (or rows and columns k+1 and -ipiv[k]) were interchanged\nand D[k-1,k-1] to D[k,k] (or D[k,k] to D[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, D is singular. D[i,i] is the first diagonal zero."] + pub fn rocsolver_ssytrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytrf( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRF_BATCHED computes the factorization of a batch of symmetric indefinite\nmatrices using Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j D_j U_j^T & \\: \\text{or}\\\\\nA_j = L_j D_j L_j^T &\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D_j\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D_j(k)\\f$.\n\nSpecifically, \\f$U_j\\f$ and \\f$L_j\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU_j = P_j(n) U_j(n) \\cdots P_j(k) U_j(k) \\cdots & \\: \\text{and}\\\\\nL_j = P_j(1) L_j(1) \\cdots P_j(k) L_j(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D_j(k)\\f$, and \\f$P_j(k)\\f$ is a permutation matrix defined by\n\\f$ipiv_j[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D_j(k)\\f$, then \\f$U_j(k)\\f$\nand \\f$L_j(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k-1,k-1]\\f$, \\f$A_j[k-1,k]\\f$,\nand \\f$A_j[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$, \\f$A_j[k+1,k]\\f$,\nand \\f$A_j[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A_j\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension lda*n.\\n\nOn entry, the symmetric matrices A_j to be factored.\nOn exit, the block diagonal matrices D_j and the multipliers needed to\ncompute U_j or L_j.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv_j[k] > 0 then rows and columns k and ipiv_j[k]\nwere interchanged and D_j[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv_j[k] = ipiv_j[k-1] < 0 and uplo is upper (or ipiv_j[k]\n= ipiv_j[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv_j[k] (or rows and columns k+1 and -ipiv_j[k]) were interchanged\nand D_j[k-1,k-1] to D_j[k,k] (or D_j[k,k] to D_j[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, D_j is singular. D_j[i,i] is the first diagonal zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytrf_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief SYTRF_STRIDED_BATCHED computes the factorization of a batch of symmetric indefinite\nmatrices using Bunch-Kaufman diagonal pivoting.\n\n\\details\n(This is the blocked version of the algorithm).\n\nThe factorization has the form\n\n\\f[\n\\begin{array}{cl}\nA_j = U_j D_j U_j^T & \\: \\text{or}\\\\\nA_j = L_j D_j L_j^T &\n\\end{array}\n\\f]\n\nwhere \\f$U_j\\f$ or \\f$L_j\\f$ is a product of permutation and unit upper/lower\ntriangular matrices (depending on the value of uplo), and \\f$D_j\\f$ is a symmetric\nblock diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks \\f$D_j(k)\\f$.\n\nSpecifically, \\f$U_j\\f$ and \\f$L_j\\f$ are computed as\n\n\\f[\n\\begin{array}{cl}\nU_j = P_j(n) U_j(n) \\cdots P_j(k) U_j(k) \\cdots & \\: \\text{and}\\\\\nL_j = P_j(1) L_j(1) \\cdots P_j(k) L_j(k) \\cdots &\n\\end{array}\n\\f]\n\nwhere \\f$k\\f$ decreases from \\f$n\\f$ to 1 (increases from 1 to \\f$n\\f$) in steps of 1 or 2,\ndepending on the order of block \\f$D_j(k)\\f$, and \\f$P_j(k)\\f$ is a permutation matrix defined by\n\\f$ipiv_j[k]\\f$. If we let \\f$s\\f$ denote the order of block \\f$D_j(k)\\f$, then \\f$U_j(k)\\f$\nand \\f$L_j(k)\\f$ are unit upper/lower triangular matrices defined as\n\n\\f[\nU_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-s} & v & 0 \\\\\n0 & I_s & 0 \\\\\n0 & 0 & I_{n-k}\n\\end{array} \\right]\n\\f]\n\nand\n\n\\f[\nL_j(k) = \\left[ \\begin{array}{ccc}\nI_{k-1} & 0 & 0 \\\\\n0 & I_s & 0 \\\\\n0 & v & I_{n-k-s+1}\n\\end{array} \\right].\n\\f]\n\nIf \\f$s = 1\\f$, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$ and \\f$v\\f$ is stored in the upper/lower\npart of column \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is upper, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k-1,k-1]\\f$, \\f$A_j[k-1,k]\\f$,\nand \\f$A_j[k,k]\\f$, and \\f$v\\f$ is stored in the upper parts of columns \\f$k-1\\f$ and \\f$k\\f$ of \\f$A_j\\f$.\nIf \\f$s = 2\\f$ and uplo is lower, then \\f$D_j(k)\\f$ is stored in \\f$A_j[k,k]\\f$, \\f$A_j[k+1,k]\\f$,\nand \\f$A_j[k+1,k+1]\\f$, and \\f$v\\f$ is stored in the lower parts of columns \\f$k\\f$ and \\f$k+1\\f$ of \\f$A_j\\f$.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nuplo rocblas_fill.\\n\nSpecifies whether the upper or lower part of the matrices A_j are stored.\nIf uplo indicates lower (or upper), then the upper (or lower)\npart of A_j is not used.\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows and columns of all matrices A_j in the batch.\n@param[inout]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nOn entry, the symmetric matrices A_j to be factored.\nOn exit, the block diagonal matrices D_j and the multipliers needed to\ncompute U_j or L_j.\n@param[in]\nlda rocblas_int. lda >= n.\\n\nSpecifies the leading dimension of matrices A_j.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one matrix A_j to the next one A_(j+1).\nThere is no restriction for the value of strideA. Normal use case is strideA >= lda*n\n@param[out]\nipiv pointer to rocblas_int. Array on the GPU of dimension n.\\n\nThe vector of pivot indices. Elements of ipiv are 1-based indices.\nFor 1 <= k <= n, if ipiv_j[k] > 0 then rows and columns k and ipiv_j[k]\nwere interchanged and D_j[k,k] is a 1-by-1 diagonal block.\nIf, instead, ipiv_j[k] = ipiv_j[k-1] < 0 and uplo is upper (or ipiv_j[k]\n= ipiv_j[k+1] < 0 and uplo is lower), then rows and columns k-1 and\n-ipiv_j[k] (or rows and columns k+1 and -ipiv_j[k]) were interchanged\nand D_j[k-1,k-1] to D_j[k,k] (or D_j[k,k] to D_j[k+1,k+1]) is a 2-by-2\ndiagonal block.\n@param[in]\nstrideP rocblas_stride.\\n\nStride from the start of one vector ipiv_j to the next one ipiv_(j+1).\nThere is no restriction for the value of strideP. Normal use case is strideP >= n.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of A_j.\nIf info[j] = i > 0, D_j is singular. D_j[i,i] is the first diagonal zero.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_ssytrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dsytrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_csytrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zsytrf_strided_batched( + handle: rocblas_handle, + uplo: rocblas_fill, + n: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + ipiv: *mut rocblas_int, + strideP: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRF_NPVT computes the LU factorization of a block tridiagonal matrix without partial pivoting.\n\n\\details The LU factorization of a block tridiagonal matrix\n\n\\f[\nM = \\left[\\begin{array}{ccccc}\nB_1 & C_1\\\\\nA_1 & B_2 & C_2\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{n-2} & B_{n-1} & C_{n-1}\\\\\n& & & A_{n-1} & B_n\n\\end{array}\\right]\n\\f]\n\nwith \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, can be represented as\n\n\\f[\nM = \\left[\\begin{array}{cccc}\nL_1 \\\\\nA_1 & L_2\\\\\n& \\ddots & \\ddots \\\\\n& & A_{n-1} & L_n\n\\end{array}\\right] \\left[\\begin{array}{cccc}\nI & U_1 \\\\\n& \\ddots & \\ddots \\\\\n& & I & U_{n-1}\\\\\n& & & I\n\\end{array}\\right] = LU\n\\f]\n\nwhere the blocks \\f$L_i\\f$ and \\f$U_i\\f$ are also general blocks of size nb.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of the matrix.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*nb*(nblocks-1).\\n\nContains the blocks A_i arranged one after the other.\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_i.\n@param[inout]\nB pointer to type. Array on the GPU of dimension ldb*nb*nblocks.\\n\nOn entry, contains the blocks B_i arranged one after the other.\nOn exit it is overwritten by blocks L_i in factorized form as returned by\n\\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\"\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of blocks B_i.\n@param[inout]\nC pointer to type. Array on the GPU of dimension ldc*nb*(nblocks-1).\\n\nOn entry, contains the blocks C_i arranged one after the other.\nOn exit it is overwritten by blocks U_i.\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of blocks C_i.\n@param[out]\ninfo pointer to a rocblas_int on the GPU.\\n\nIf info = 0, successful exit.\nIf info = i > 0, the matrix is singular."] + pub fn rocsolver_sgeblttrf_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrf_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrf_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrf_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRF_NPVT_BATCHED computes the LU factorization of a batch of block tridiagonal matrices without\npartial pivoting.\n\n\\details The LU factorization of a block tridiagonal matrix \\f$M_j\\f$ in the batch\n\n\\f[\nM_j = \\left[\\begin{array}{ccccc}\nB_{j1} & C_{j1}\\\\\nA_{j1} & B_{j2} & C_{j2}\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{j(n-2)} & B_{j(n-1)} & C_{j(n-1)}\\\\\n& & & A_{j(n-1)} & B_{jn}\n\\end{array}\\right]\n\\f]\n\nwith \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, can be represented as\n\n\\f[\nM_j = \\left[\\begin{array}{cccc}\nL_{j1} \\\\\nA_{j1} & L_{j2}\\\\\n& \\ddots & \\ddots \\\\\n& & A_{j(n-1)} & L_{jn}\n\\end{array}\\right] \\left[\\begin{array}{cccc}\nI & U_{j1} \\\\\n& \\ddots & \\ddots \\\\\n& & I & U_{j(n-1)}\\\\\n& & & I\n\\end{array}\\right] = L_jU_j\n\\f]\n\nwhere the blocks \\f$L_{ji}\\f$ and \\f$U_{ji}\\f$ are also general blocks of size nb.\n\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of each matrix in the batch.\n@param[in]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension\nlda*nb*(nblocks-1).\\n\nContains the blocks A_{ji} arranged one after the other.\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_{ji}.\n@param[inout]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension\nldb*nb*nblocks.\\n\nOn entry, contains the blocks B_{ji} arranged one after the other.\nOn exit it is overwritten by blocks L_{ji} in factorized form as returned by\n\\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\"\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of blocks B_{ji}.\n@param[inout]\nC array of pointers to type. Each pointer points to an array on the GPU of dimension\nldc*nb*(nblocks-1).\\n\nOn entry, contains the blocks C_{ji} arranged one after the other.\nOn exit it is overwritten by blocks U_{ji}.\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of blocks C_{ji}.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of j-th batch instance.\nIf info[j] = i > 0, the j-th batch instance is singular.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeblttrf_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrf_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrf_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrf_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRF_NPVT_STRIDED_BATCHED computes the LU factorization of a batch of block tridiagonal\nmatrices without partial pivoting.\n\n\\details The LU factorization of a block tridiagonal matrix \\f$M_j\\f$ in the batch\n\n\\f[\nM_j = \\left[\\begin{array}{ccccc}\nB_{j1} & C_{j1}\\\\\nA_{j1} & B_{j2} & C_{j2}\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{j(n-2)} & B_{j(n-1)} & C_{j(n-1)}\\\\\n& & & A_{j(n-1)} & B_{jn}\n\\end{array}\\right]\n\\f]\n\nwith \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, can be represented as\n\n\\f[\nM_j = \\left[\\begin{array}{cccc}\nL_{j1} \\\\\nA_{j1} & L_{j2}\\\\\n& \\ddots & \\ddots \\\\\n& & A_{j(n-1)} & L_{jn}\n\\end{array}\\right] \\left[\\begin{array}{cccc}\nI & U_{j1} \\\\\n& \\ddots & \\ddots \\\\\n& & I & U_{j(n-1)}\\\\\n& & & I\n\\end{array}\\right] = L_jU_j\n\\f]\n\nwhere the blocks \\f$L_{ji}\\f$ and \\f$U_{ji}\\f$ are also general blocks of size nb.\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of each matrix in the batch.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nContains the blocks A_{ji} arranged one after the other.\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_{ji}.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one block A_{ji} to the same block in the next batch\ninstance A_{(j+1)i}.\nThere is no restriction for the value of strideA. Normal use case is strideA >=\nlda*nb*nblocks.\n@param[inout]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nOn entry, contains the blocks B_{ji} arranged one after the other.\nOn exit it is overwritten by blocks L_{ji} in factorized form as returned by\n\\ref rocsolver_sgetrf_npvt \"GETRF_NPVT\"\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of matrix blocks B_{ji}.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one block B_{ji} to the same block in the next batch\ninstance B_{(j+1)i}.\nThere is no restriction for the value of strideB. Normal use case is strideB >=\nldb*nb*nblocks.\n@param[inout]\nC pointer to type. Array on the GPU (the size depends on the value of strideC).\\n\nOn entry, contains the blocks C_{ji} arranged one after the other.\nOn exit it is overwritten by blocks U_{ji}.\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of matrix blocks C_{ji}.\n@param[in]\nstrideC rocblas_stride.\\n\nStride from the start of one block B_{ji} to the same block in the next batch\ninstance B_{(j+1)i}.\nThere is no restriction for the value of strideC. Normal use case is strideC >=\nldc*nb*nblocks.\n@param[out]\ninfo pointer to rocblas_int. Array of batch_count integers on the GPU.\\n\nIf info[j] = 0, successful exit for factorization of j-th batch instance.\nIf info[j] = i > 0, the j-th batch instance is singular.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeblttrf_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrf_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrf_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrf_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + info: *mut rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRS_NPVT solves a system of linear equations given by a block tridiagonal matrix\nin its factorized form (without partial pivoting).\n\n\\details The linear system has the form\n\n\\f[\nMX = \\left[\\begin{array}{ccccc}\nB_1 & C_1\\\\\nA_1 & B_2 & C_2\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{n-2} & B_{n-1} & C_{n-1}\\\\\n& & & A_{n-1} & B_n\n\\end{array}\\right]\\left[\\begin{array}{c}\nX_1\\\\\nX_2\\\\\nX_3\\\\\n\\vdots\\\\\nX_n\n\\end{array}\\right]=\\left[\\begin{array}{c}\nR_1\\\\\nR_2\\\\\nR_3\\\\\n\\vdots\\\\\nR_n\n\\end{array}\\right]=R\n\\f]\n\nwhere matrix M has \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, and the right-hand-side\nblocks \\f$R_i\\f$ are general blocks of size nb-by-nrhs. The blocks of matrix M should be in\nthe factorized form as returned by \\ref rocsolver_sgeblttrf_npvt \"GEBLTTRF_NPVT\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of the matrix.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns of blocks R_i.\n@param[in]\nA pointer to type. Array on the GPU of dimension lda*nb*(nblocks-1).\\n\nContains the blocks A_i as returned by \\ref rocsolver_sgeblttrf_npvt \"GEBLTTRF_NPVT\".\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_i.\n@param[in]\nB pointer to type. Array on the GPU of dimension ldb*nb*nblocks.\\n\nContains the blocks B_i as returned by \\ref rocsolver_sgeblttrf_npvt \"GEBLTTRF_NPVT\".\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of blocks B_i.\n@param[in]\nC pointer to type. Array on the GPU of dimension ldc*nb*(nblocks-1).\\n\nContains the blocks C_i as returned by \\ref rocsolver_sgeblttrf_npvt \"GEBLTTRF_NPVT\".\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of blocks C_i.\n@param[inout]\nX pointer to type. Array on the GPU of dimension ldx*nblocks*nrhs.\\n\nOn entry, X contains the right-hand-side blocks R_i. It is overwritten by solution\nvectors X_i on exit.\n@param[in]\nldx rocblas_int. ldx >= nb.\\n\nSpecifies the leading dimension of blocks X_i."] + pub fn rocsolver_sgeblttrs_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + B: *mut f32, + ldb: rocblas_int, + C: *mut f32, + ldc: rocblas_int, + X: *mut f32, + ldx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrs_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + B: *mut f64, + ldb: rocblas_int, + C: *mut f64, + ldc: rocblas_int, + X: *mut f64, + ldx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrs_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + X: *mut rocblas_float_complex, + ldx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrs_npvt( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + X: *mut rocblas_double_complex, + ldx: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRS_NPVT_BATCHED solves a batch of system of linear equations given by block tridiagonal\nmatrices in its factorized form (without partial pivoting).\n\n\\details Each linear system has the form\n\n\\f[\nM_jX_j = \\left[\\begin{array}{ccccc}\nB_{j1} & C_{j1}\\\\\nA_{j1} & B_{j2} & C_{j2}\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{j(n-2)} & B_{j(n-1)} & C_{j(n-1)}\\\\\n& & & A_{j(n-1)} & B_{jn}\n\\end{array}\\right]\\left[\\begin{array}{c}\nX_{j1}\\\\\nX_{j2}\\\\\nX_{j3}\\\\\n\\vdots\\\\\nX_{jn}\n\\end{array}\\right]=\\left[\\begin{array}{c}\nR_{j1}\\\\\nR_{j2}\\\\\nR_{j3}\\\\\n\\vdots\\\\\nR_{jn}\n\\end{array}\\right]=R_j\n\\f]\n\nwhere matrix \\f$M_j\\f$ has \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, and the right-hand-side\nblocks \\f$R_{ji}\\f$ are general blocks of size nb-by-nrhs. The blocks of matrix \\f$M_j\\f$ should be in\nthe factorized form as returned by \\ref rocsolver_sgeblttrf_npvt_batched \"GEBLTTRF_NPVT_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of each matrix in the batch.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns of blocks R_{ji}.\n@param[in]\nA array of pointers to type. Each pointer points to an array on the GPU of dimension\nlda*nb*(nblocks-1).\\n\nContains the blocks A_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_batched \"GEBLTTRF_NPVT_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_{ji}.\n@param[in]\nB array of pointers to type. Each pointer points to an array on the GPU of dimension\nlda*nb*nblocks.\\n\nContains the blocks B_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_batched \"GEBLTTRF_NPVT_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of blocks B_{ji}.\n@param[in]\nC array of pointers to type. Each pointer points to an array on the GPU of dimension\nldc*nb*(nblocks-1).\\n\nContains the blocks C_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_batched \"GEBLTTRF_NPVT_BATCHED\".\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of blocks C_{ji}.\n@param[inout]\nX array of pointers to type. Each pointer points to an array on the GPU of dimension\nldx*nblocks*nrhs.\\n\nOn entry, X contains the right-hand-side blocks R_{ji}. It is overwritten by solution\nvectors X_{ji} on exit.\n@param[in]\nldx rocblas_int. ldx >= nb.\\n\nSpecifies the leading dimension of blocks X_{ji}.\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeblttrs_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f32, + lda: rocblas_int, + B: *const *mut f32, + ldb: rocblas_int, + C: *const *mut f32, + ldc: rocblas_int, + X: *const *mut f32, + ldx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrs_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *const *mut f64, + lda: rocblas_int, + B: *const *mut f64, + ldb: rocblas_int, + C: *const *mut f64, + ldc: rocblas_int, + X: *const *mut f64, + ldx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrs_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_float_complex, + lda: rocblas_int, + B: *const *mut rocblas_float_complex, + ldb: rocblas_int, + C: *const *mut rocblas_float_complex, + ldc: rocblas_int, + X: *const *mut rocblas_float_complex, + ldx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrs_npvt_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *const *mut rocblas_double_complex, + lda: rocblas_int, + B: *const *mut rocblas_double_complex, + ldb: rocblas_int, + C: *const *mut rocblas_double_complex, + ldc: rocblas_int, + X: *const *mut rocblas_double_complex, + ldx: rocblas_int, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief GEBLTTRS_NPVT_STRIDED_BATCHED solves a batch of system of linear equations given by block\ntridiagonal matrices in its factorized form (without partial pivoting).\n\n\\details Each linear system has the form\n\n\\f[\nM_jX_j = \\left[\\begin{array}{ccccc}\nB_{j1} & C_{j1}\\\\\nA_{j1} & B_{j2} & C_{j2}\\\\\n& \\ddots & \\ddots & \\ddots \\\\\n& & A_{j(n-2)} & B_{j(n-1)} & C_{j(n-1)}\\\\\n& & & A_{j(n-1)} & B_{jn}\n\\end{array}\\right]\\left[\\begin{array}{c}\nX_{j1}\\\\\nX_{j2}\\\\\nX_{j3}\\\\\n\\vdots\\\\\nX_{jn}\n\\end{array}\\right]=\\left[\\begin{array}{c}\nR_{j1}\\\\\nR_{j2}\\\\\nR_{j3}\\\\\n\\vdots\\\\\nR_{jn}\n\\end{array}\\right]=R_j\n\\f]\n\nwhere matrix \\f$M_j\\f$ has \\f$n = \\mathrm{nblocks}\\f$ diagonal blocks of size nb, and the right-hand-side\nblocks \\f$R_{ji}\\f$ are general blocks of size nb-by-nrhs. The blocks of matrix \\f$M_j\\f$ should be in\nthe factorized form as returned by \\ref rocsolver_sgeblttrf_npvt_strided_batched \"GEBLTTRF_NPVT_STRIDED_BATCHED\".\n\n@param[in]\nhandle rocblas_handle.\n@param[in]\nnb rocblas_int. nb >= 0.\\n\nThe number of rows and columns of each block.\n@param[in]\nnblocks rocblas_int. nblocks >= 0.\\n\nThe number of blocks along the diagonal of each matrix in the batch.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e., the number of columns of blocks R_{ji}.\n@param[in]\nA pointer to type. Array on the GPU (the size depends on the value of strideA).\\n\nContains the blocks A_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_strided_batched \"GEBLTTRF_NPVT_STRIDED_BATCHED\".\n@param[in]\nlda rocblas_int. lda >= nb.\\n\nSpecifies the leading dimension of blocks A_{ji}.\n@param[in]\nstrideA rocblas_stride.\\n\nStride from the start of one block A_{ji} to the same block in the next batch\ninstance A_{(j+1)i}.\nThere is no restriction for the value of strideA. Normal use case is strideA >=\nlda*nb*nblocks\n@param[in]\nB pointer to type. Array on the GPU (the size depends on the value of strideB).\\n\nContains the blocks B_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_strided_batched \"GEBLTTRF_NPVT_STRIDED_BATCHED\".\n@param[in]\nldb rocblas_int. ldb >= nb.\\n\nSpecifies the leading dimension of blocks B_{ji}.\n@param[in]\nstrideB rocblas_stride.\\n\nStride from the start of one block B_{ji} to the same block in the next batch\ninstance B_{(j+1)i}.\nThere is no restriction for the value of strideB. Normal use case is strideB >=\nldb*nb*nblocks\n@param[in]\nC pointer to type. Array on the GPU (the size depends on the value of strideC).\\n\nContains the blocks C_{ji} as returned by \\ref rocsolver_sgeblttrf_npvt_strided_batched \"GEBLTTRF_NPVT_STRIDED_BATCHED\".\n@param[in]\nldc rocblas_int. ldc >= nb.\\n\nSpecifies the leading dimension of blocks C_{ji}.\n@param[in]\nstrideC rocblas_stride.\\n\nStride from the start of one block C_{ji} to the same block in the next batch\ninstance C_{(j+1)i}.\nThere is no restriction for the value of strideC. Normal use case is strideC >=\nldc*nb*nblocks\n@param[inout]\nX pointer to type. Array on the GPU (the size depends on the value of strideX).\\n\nOn entry, X contains the right-hand-side blocks R_{ji}. It is overwritten by solution\nvectors X_{ji} on exit.\n@param[in]\nldx rocblas_int. ldx >= nb.\\n\nSpecifies the leading dimension of blocks X_{ji}.\n@param[in]\nstrideX rocblas_stride.\\n\nStride from the start of one block X_{ji} to the same block in the next batch\ninstance X_{(j+1)i}.\nThere is no restriction for the value of strideX. Normal use case is strideX >=\nldx*nblocks*nrhs\n@param[in]\nbatch_count rocblas_int. batch_count >= 0.\\n\nNumber of matrices in the batch."] + pub fn rocsolver_sgeblttrs_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut f32, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f32, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut f32, + ldc: rocblas_int, + strideC: rocblas_stride, + X: *mut f32, + ldx: rocblas_int, + strideX: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dgeblttrs_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut f64, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut f64, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut f64, + ldc: rocblas_int, + strideC: rocblas_stride, + X: *mut f64, + ldx: rocblas_int, + strideX: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_cgeblttrs_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_float_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_float_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut rocblas_float_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + X: *mut rocblas_float_complex, + ldx: rocblas_int, + strideX: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_zgeblttrs_npvt_strided_batched( + handle: rocblas_handle, + nb: rocblas_int, + nblocks: rocblas_int, + nrhs: rocblas_int, + A: *mut rocblas_double_complex, + lda: rocblas_int, + strideA: rocblas_stride, + B: *mut rocblas_double_complex, + ldb: rocblas_int, + strideB: rocblas_stride, + C: *mut rocblas_double_complex, + ldc: rocblas_int, + strideC: rocblas_stride, + X: *mut rocblas_double_complex, + ldx: rocblas_int, + strideX: rocblas_stride, + batch_count: rocblas_int, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief CREATE_RFINFO initializes the structure rfinfo, required by the re-factorization functions\n\\ref rocsolver_scsrrf_refactlu \"CSRRF_REFACTLU\" and \\ref rocsolver_scsrrf_solve \"CSRRF_SOLVE\",\nthat contains the meta data and descriptors of the involved matrices.\n\n\\details\n@param[out]\nrfinfo #rocsolver_rfinfo.\\n\nThe pointer to the rfinfo struct to be initialized.\n@param[in]\nhandle rocblas_handle.\\n"] + pub fn rocsolver_create_rfinfo( + rfinfo: *mut rocsolver_rfinfo, + handle: rocblas_handle, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " \\brief DESTROY_RFINFO destroys the structure rfinfo used by the re-factorization functions\n\\ref rocsolver_scsrrf_refactlu \"CSRRF_REFACTLU\" and \\ref rocsolver_scsrrf_solve \"CSRRF_SOLVE\".\n\n\\details\n@param[in]\nrfinfo #rocsolver_rfinfo.\\n\nThe rfinfo struct to be destroyed."] + pub fn rocsolver_destroy_rfinfo(rfinfo: rocsolver_rfinfo) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief CSRRF_SUMLU bundles the factors \\f$L\\f$ and \\f$U\\f$, associated with the LU factorization\nof a sparse matrix \\f$A\\f$, into a single sparse matrix \\f$T=(L-I)+U\\f$.\n\n\\details Factor \\f$L\\f$ is a sparse lower triangular matrix with unit diagonal elements, and\n\\f$U\\f$ is a sparse upper triangular matrix. The resulting sparse matrix \\f$T\\f$ combines both\nsparse factors without storing the unit diagonal; in other words, the number of non-zero\nelements of T, nnzT, is given by nnzT = nnzL - n + nnzU.\n\n@param[in]\nhandle rocblas_handle.\\n\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows (and columns) of matrix A.\n@param[in]\nnnzL rocblas_int. nnzL >= n.\\n\nThe number of non-zero elements in L.\n@param[in]\nptrL pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indL and valL.\nThe last element of ptrL is equal to nnzL.\n@param[in]\nindL pointer to rocblas_int. Array on the GPU of dimension nnzL.\\n\nIt contains the column indices of the non-zero elements of L. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalL pointer to type. Array on the GPU of dimension nnzL.\\n\nThe values of the non-zero elements of L.\n@param[in]\nnnzU rocblas_int. nnzU >= 0.\\n\nThe number of non-zero elements in U.\n@param[in]\nptrU pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indU and valU.\nThe last element of ptrU is equal to nnzU.\n@param[in]\nindU pointer to rocblas_int. Array on the GPU of dimension nnzU.\\n\nIt contains the column indices of the non-zero elements of U. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalU pointer to type. Array on the GPU of dimension nnzU.\\n\nThe values of the non-zero elements of U.\n@param[out]\nptrT pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indT and valT.\nThe last element of ptrT is equal to nnzT.\n@param[out]\nindT pointer to rocblas_int. Array on the GPU of dimension nnzT.\\n\nIt contains the column indices of the non-zero elements of T. Indices are\nsorted by row and by column within each row.\n@param[out]\nvalT pointer to type. Array on the GPU of dimension nnzT.\\n\nThe values of the non-zero elements of T."] + pub fn rocsolver_scsrrf_sumlu( + handle: rocblas_handle, + n: rocblas_int, + nnzL: rocblas_int, + ptrL: *mut rocblas_int, + indL: *mut rocblas_int, + valL: *mut f32, + nnzU: rocblas_int, + ptrU: *mut rocblas_int, + indU: *mut rocblas_int, + valU: *mut f32, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dcsrrf_sumlu( + handle: rocblas_handle, + n: rocblas_int, + nnzL: rocblas_int, + ptrL: *mut rocblas_int, + indL: *mut rocblas_int, + valL: *mut f64, + nnzU: rocblas_int, + ptrU: *mut rocblas_int, + indU: *mut rocblas_int, + valU: *mut f64, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief CSRRF_SPLITLU splits the factors \\f$L\\f$ and \\f$U\\f$, associated with the LU factorization\nof a sparse matrix \\f$A\\f$, from a bundled matrix \\f$T=(L-I)+U\\f$.\n\n\\details Factor \\f$L\\f$ is a sparse lower triangular matrix with unit diagonal elements, and\n\\f$U\\f$ is a sparse upper triangular matrix. Conceptually, on input, U is stored on the diagonal\nand upper part of \\f$T\\f$, while the non diagonal elements of \\f$L\\f$ are stored on the strictly\nlower part of \\f$T\\f$.\n\n@param[in]\nhandle rocblas_handle.\\n\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows (and columns) of matrix A.\n@param[in]\nnnzT rocblas_int. nnzT >= 0.\\n\nThe number of non-zero elements in T.\n@param[in]\nptrT pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indT and valT.\nThe last element of ptrT is equal to nnzT.\n@param[in]\nindT pointer to rocblas_int. Array on the GPU of dimension nnzT.\\n\nIt contains the column indices of the non-zero elements of T. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalT pointer to type. Array on the GPU of dimension nnzT.\\n\nThe values of the non-zero elements of T.\n@param[out]\nptrL pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indL and valL.\nThe last element of ptrL is equal to nnzL.\n@param[out]\nindL pointer to rocblas_int. Array on the GPU of dimension nnzL.\\n\nIt contains the column indices of the non-zero elements of L. Indices are\nsorted by row and by column within each row. (If nnzL is not known in advance,\nthe size of this array could be set to nnzT + n as an upper bound).\n@param[out]\nvalL pointer to type. Array on the GPU of dimension nnzL.\\n\nThe values of the non-zero elements of L. (If nnzL is not known in advance,\nthe size of this array could be set to nnzT + n as an upper bound).\n@param[out]\nptrU pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indU and valU.\nThe last element of ptrU is equal to nnzU.\n@param[out]\nindU pointer to rocblas_int. Array on the GPU of dimension nnzU.\\n\nIt contains the column indices of the non-zero elements of U. Indices are\nsorted by row and by column within each row. (If nnzU is not known in advance,\nthe size of this array could be set to nnzT as an upper bound).\n@param[out]\nvalU pointer to type. Array on the GPU of dimension nnzU.\\n\nThe values of the non-zero elements of U. (If nnzU is not known in advance,\nthe size of this array could be set to nnzT as an upper bound)."] + pub fn rocsolver_scsrrf_splitlu( + handle: rocblas_handle, + n: rocblas_int, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f32, + ptrL: *mut rocblas_int, + indL: *mut rocblas_int, + valL: *mut f32, + ptrU: *mut rocblas_int, + indU: *mut rocblas_int, + valU: *mut f32, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dcsrrf_splitlu( + handle: rocblas_handle, + n: rocblas_int, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f64, + ptrL: *mut rocblas_int, + indL: *mut rocblas_int, + valL: *mut f64, + ptrU: *mut rocblas_int, + indU: *mut rocblas_int, + valU: *mut f64, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief CSRRF_ANALYSIS performs the analysis phase required by the re-factorization functions\n\\ref rocsolver_scsrrf_refactlu \"CSRRF_REFACTLU\" and \\ref rocsolver_scsrrf_solve \"CSRRF_SOLVE\"\n\n\\details Consider a sparse matrix \\f$M\\f$ previously factorized as\n\n\\f[\nPMQ = L_MU_M\n\\f]\n\nwhere \\f$L_M\\f$ is lower triangular with unit diagonal, \\f$U_M\\f$ is upper triangular, and \\f$P\\f$\nand \\f$Q\\f$ are permutation matrices associated with pivoting and re-ordering (to minimize\nfill-in), respectively. The meta data generated by this routine is collected in the output parameter\nrfinfo. This information will allow the fast LU re-factorization of another sparse matrix \\f$A\\f$ as\n\n\\f[\nPAQ = L_AU_A\n\\f]\n\nand, eventually, the computation of the solution vector \\f$X\\f$ of any linear system of the form\n\n\\f[\nAX = B\n\\f]\n\nas long as \\f$A\\f$ has the same sparsity pattern as the previous matrix \\f$M\\f$.\n\nThis function supposes that the LU factors \\f$L_M\\f$ and \\f$U_M\\f$ are passed in a bundle\nmatrix \\f$T=(L_M-I)+U_M\\f$ as returned by \\ref rocsolver_scsrrf_sumlu \"CSRRF_SUMLU\",\nand that rfinfo has been initialized by \\ref rocsolver_create_rfinfo \"RFINFO_CREATE\".\n\n\\note\nIf only a re-factorization will be executed (i.e. no solver phase), then nrhs can be set to zero\nand B can be null.\n\n@param[in]\nhandle rocblas_handle.\\n\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows (and columns) of matrix M.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right-hand-sides (columns of matrix B). Set nrhs to zero when only the\nre-factorization is needed.\n@param[in]\nnnzM rocblas_int. nnzM >= 0.\\n\nThe number of non-zero elements in M.\n@param[in]\nptrM pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indM and valM.\nThe last element of ptrM is equal to nnzM.\n@param[in]\nindM pointer to rocblas_int. Array on the GPU of dimension nnzM.\\n\nIt contains the column indices of the non-zero elements of M. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalM pointer to type. Array on the GPU of dimension nnzM.\\n\nThe values of the non-zero elements of M.\n@param[in]\nnnzT rocblas_int. nnzT >= 0.\\n\nThe number of non-zero elements in T.\n@param[in]\nptrT pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indT and valT.\nThe last element of ptrT is equal to nnzT.\n@param[in]\nindT pointer to rocblas_int. Array on the GPU of dimension nnzT.\\n\nIt contains the column indices of the non-zero elements of T. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalT pointer to type. Array on the GPU of dimension nnzT.\\n\nThe values of the non-zero elements of T.\n@param[in]\npivP pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix P, i.e. the\norder in which the rows of matrix M were re-arranged.\n@param[in]\npivQ pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix Q, i.e. the\norder in which the columns of matrix M were re-arranged.\n@param[in]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nThe right hand side matrix B. It can be null if only the re-factorization is needed.\n@param[in]\nldb rocblas_int. ldb >= n.\nThe leading dimension of B.\n@param[out]\nrfinfo rocsolver_rfinfo.\\n\nStructure that holds the meta data generated in the analysis phase."] + pub fn rocsolver_scsrrf_analysis( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + nnzM: rocblas_int, + ptrM: *mut rocblas_int, + indM: *mut rocblas_int, + valM: *mut f32, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f32, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + B: *mut f32, + ldb: rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dcsrrf_analysis( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + nnzM: rocblas_int, + ptrM: *mut rocblas_int, + indM: *mut rocblas_int, + valM: *mut f64, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f64, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + B: *mut f64, + ldb: rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief CSRRF_REFACTLU performs a fast LU factorization of a sparse matrix \\f$A\\f$ based on the\ninformation from the factorization of a previous matrix \\f$M\\f$ with the same sparsity pattern\n(re-factorization).\n\n\\details Consider a sparse matrix \\f$M\\f$ previously factorized as\n\n\\f[\nPMQ = L_MU_M\n\\f]\n\nwhere \\f$L_M\\f$ is lower triangular with unit diagonal, \\f$U_M\\f$ is upper triangular, and \\f$P\\f$\nand \\f$Q\\f$ are permutation matrices associated with pivoting and re-ordering (to minimize\nfill-in), respectively. If \\f$A\\f$ has the same sparsity pattern as \\f$M\\f$, then the re-factorization\n\n\\f[\nPAQ = L_AU_A\n\\f]\n\ncan be computed numerically without any symbolic or analysis phases.\n\nThis function supposes that rfinfo has been updated, by function \\ref rocsolver_scsrrf_analysis \"CSRRF_ANALYSIS\",\nafter the analysis phase of the previous matrix M and its initial factorization.\n\n@param[in]\nhandle rocblas_handle.\\n\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows (and columns) of matrix A.\n@param[in]\nnnzA rocblas_int. nnzA >= 0.\\n\nThe number of non-zero elements in A.\n@param[in]\nptrA pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indA and valA.\nThe last element of ptrM is equal to nnzA.\n@param[in]\nindA pointer to rocblas_int. Array on the GPU of dimension nnzA.\\n\nIt contains the column indices of the non-zero elements of M. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalA pointer to type. Array on the GPU of dimension nnzA.\\n\nThe values of the non-zero elements of A.\n@param[in]\nnnzT rocblas_int. nnzT >= 0.\\n\nThe number of non-zero elements in T.\n@param[in]\nptrT pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indT and valT.\nThe last element of ptrT is equal to nnzT.\n@param[in]\nindT pointer to rocblas_int. Array on the GPU of dimension nnzT.\\n\nIt contains the column indices of the non-zero elements of T. Indices are\nsorted by row and by column within each row.\n@param[out]\nvalT pointer to type. Array on the GPU of dimension nnzT.\\n\nThe values of the non-zero elements of the new bundle matrix (L_A - I) + U_A.\n@param[in]\npivP pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix P, i.e. the\norder in which the rows of matrix M were re-arranged.\n@param[in]\npivQ pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix Q, i.e. the\norder in which the columns of matrix M were re-arranged.\n@param[in]\nrfinfo rocsolver_rfinfo.\\n\nStructure that holds the meta data generated in the analysis phase."] + pub fn rocsolver_scsrrf_refactlu( + handle: rocblas_handle, + n: rocblas_int, + nnzA: rocblas_int, + ptrA: *mut rocblas_int, + indA: *mut rocblas_int, + valA: *mut f32, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f32, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dcsrrf_refactlu( + handle: rocblas_handle, + n: rocblas_int, + nnzA: rocblas_int, + ptrA: *mut rocblas_int, + indA: *mut rocblas_int, + valA: *mut f64, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f64, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + #[doc = " @{\n\\brief CSRRF_SOLVE solves a linear system with sparse coefficient matrix \\f$A\\f$ in its\nfactorized form.\n\n\\details The linear system is of the form\n\n\\f[\nAX = B\n\\f]\n\nwhere the sparse matrix \\f$A\\f$ is factorized as\n\n\\f[\nPAQ = L_AU_A\n\\f]\n\nand \\f$B\\f$ is a dense matrix of right hand sides.\n\nThis function supposes that the LU factors \\f$L_A\\f$ and \\f$U_A\\f$ are passed in a bundle\nmatrix \\f$T=(L_A-I)+U_A\\f$ as returned by \\ref rocsolver_scsrrf_refactlu \"CSRRF_REFACTLU\" or\n\\ref rocsolver_scsrrf_sumlu \"CSRRF_SUMLU\", and that rfinfo has been updated, by function\n\\ref rocsolver_scsrrf_analysis \"CSRRF_ANALYSIS\", after the analysis phase.\n\n@param[in]\nhandle rocblas_handle.\\n\n@param[in]\nn rocblas_int. n >= 0.\\n\nThe number of rows (and columns) of matrix A.\n@param[in]\nnrhs rocblas_int. nrhs >= 0.\\n\nThe number of right hand sides, i.e. the number of columns of matrix B.\n@param[in]\nnnzT rocblas_int. nnzT >= 0.\\n\nThe number of non-zero elements in T.\n@param[in]\nptrT pointer to rocblas_int. Array on the GPU of dimension n+1.\\n\nIt contains the positions of the beginning of each row in indT and valT.\nThe last element of ptrT is equal to nnzT.\n@param[in]\nindT pointer to rocblas_int. Array on the GPU of dimension nnzT.\\n\nIt contains the column indices of the non-zero elements of T. Indices are\nsorted by row and by column within each row.\n@param[in]\nvalT pointer to type. Array on the GPU of dimension nnzT.\\n\nThe values of the non-zero elements of T.\n@param[in]\npivP pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix P, i.e. the\norder in which the rows of matrix A were re-arranged.\n@param[in]\npivQ pointer to rocblas_int. Array on the GPU of dimension n.\\n\nContains the pivot indices representing the permutation matrix Q, i.e. the\norder in which the columns of matrix A were re-arranged.\n@param[inout]\nB pointer to type. Array on the GPU of dimension ldb*nrhs.\\n\nOn entry the right hand side matrix B. On exit, the solution matrix X.\n@param[in]\nldb rocblas_int. ldb >= n.\\n\nThe leading dimension of B.\n@param[in]\nrfinfo rocsolver_rfinfo.\\n\nStructure that holds the meta data generated in the analysis phase."] + pub fn rocsolver_scsrrf_solve( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f32, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + B: *mut f32, + ldb: rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} +extern "C" { + #[must_use] + pub fn rocsolver_dcsrrf_solve( + handle: rocblas_handle, + n: rocblas_int, + nrhs: rocblas_int, + nnzT: rocblas_int, + ptrT: *mut rocblas_int, + indT: *mut rocblas_int, + valT: *mut f64, + pivP: *mut rocblas_int, + pivQ: *mut rocblas_int, + B: *mut f64, + ldb: rocblas_int, + rfinfo: rocsolver_rfinfo, + ) -> rocblas_status; +} diff --git a/rocsparse-sys/Cargo.toml b/rocsparse-sys/Cargo.toml new file mode 100644 index 0000000..827659e --- /dev/null +++ b/rocsparse-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rocsparse-sys" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" +links = "rocsparse" + +[lib] diff --git a/rocsparse-sys/README b/rocsparse-sys/README new file mode 100644 index 0000000..55e8f2a --- /dev/null +++ b/rocsparse-sys/README @@ -0,0 +1 @@ +bindgen /opt/rocm/include/rocsparse/rocsparse.h -o src/rocsparse.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --allowlist-function "rocsparse_.*" --allowlist-var "ROCSPARSE_*" --must-use-type rocsparse_status -- -I/opt/rocm/include \ No newline at end of file diff --git a/rocsparse-sys/build.rs b/rocsparse-sys/build.rs new file mode 100644 index 0000000..8470be3 --- /dev/null +++ b/rocsparse-sys/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-lib=dylib=rocsparse"); + println!("cargo:rustc-link-search=native=/opt/rocm/lib/"); +} diff --git a/rocsparse-sys/src/lib.rs b/rocsparse-sys/src/lib.rs new file mode 100644 index 0000000..5f4cb32 --- /dev/null +++ b/rocsparse-sys/src/lib.rs @@ -0,0 +1,3 @@ +#![allow(warnings)] +mod rocsparse; +pub use rocsparse::*; \ No newline at end of file diff --git a/rocsparse-sys/src/rocsparse.rs b/rocsparse-sys/src/rocsparse.rs new file mode 100644 index 0000000..58ac24b --- /dev/null +++ b/rocsparse-sys/src/rocsparse.rs @@ -0,0 +1,10631 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocsparse_float_complex { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rocsparse_double_complex { + pub x: f64, + pub y: f64, +} +pub type rocsparse_int = i32; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ihipStream_t { + _unused: [u8; 0], +} +#[doc = " \\cond DO_NOT_DOCUMENT"] +pub type hipStream_t = *mut ihipStream_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_handle { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Handle to the rocSPARSE library context queue.\n\n \\details\n The rocSPARSE handle is a structure holding the rocSPARSE library context. It must\n be initialized using rocsparse_create_handle() and the returned handle must be\n passed to all subsequent library function calls. It should be destroyed at the end\n using rocsparse_destroy_handle()."] +pub type rocsparse_handle = *mut _rocsparse_handle; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_mat_descr { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Descriptor of the matrix.\n\n \\details\n The rocSPARSE matrix descriptor is a structure holding all properties of a matrix.\n It must be initialized using rocsparse_create_mat_descr() and the returned\n descriptor must be passed to all subsequent library calls that involve the matrix.\n It should be destroyed at the end using rocsparse_destroy_mat_descr()."] +pub type rocsparse_mat_descr = *mut _rocsparse_mat_descr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_hyb_mat { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief HYB matrix storage format.\n\n \\details\n The rocSPARSE HYB matrix structure holds the HYB matrix. It must be initialized using\n rocsparse_create_hyb_mat() and the returned HYB matrix must be passed to all\n subsequent library calls that involve the matrix. It should be destroyed at the end\n using rocsparse_destroy_hyb_mat()."] +pub type rocsparse_hyb_mat = *mut _rocsparse_hyb_mat; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_mat_info { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Info structure to hold all matrix meta data.\n\n \\details\n The rocSPARSE matrix info is a structure holding all matrix information that is\n gathered during analysis routines. It must be initialized using\n rocsparse_create_mat_info() and the returned info structure must be passed to all\n subsequent library calls that require additional matrix information. It should be\n destroyed at the end using rocsparse_destroy_mat_info()."] +pub type rocsparse_mat_info = *mut _rocsparse_mat_info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_spvec_descr { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Generic API descriptor of the sparse vector.\n\n \\details\n The rocSPARSE sparse vector descriptor is a structure holding all properties of a sparse vector.\n It must be initialized using rocsparse_create_spvec_descr() and the returned\n descriptor must be passed to all subsequent generic API library calls that involve the sparse vector.\n It should be destroyed at the end using rocsparse_destroy_spvec_descr()."] +pub type rocsparse_spvec_descr = *mut _rocsparse_spvec_descr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_spmat_descr { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Generic API descriptor of the sparse matrix.\n\n \\details\n The rocSPARSE sparse matrix descriptor is a structure holding all properties of a sparse matrix.\n It must be initialized using rocsparse_create_coo_descr(), rocsparse_create_coo_aos_descr(),\n rocsparse_create_bsr_descr(), rocsparse_create_csr_descr(), rocsparse_create_csc_descr(),\n rocsparse_create_ell_descr(), or rocsparse_create_bell_descr() and the returned\n descriptor must be passed to all subsequent generic API library calls that involve the sparse matrix.\n It should be destroyed at the end using rocsparse_destroy_spmat_descr()."] +pub type rocsparse_spmat_descr = *mut _rocsparse_spmat_descr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_dnvec_descr { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Generic API descriptor of the dense vector.\n\n \\details\n The rocSPARSE dense vector descriptor is a structure holding all properties of a dense vector.\n It must be initialized using rocsparse_create_dnvec_descr() and the returned\n descriptor must be passed to all subsequent generic API library calls that involve the dense vector.\n It should be destroyed at the end using rocsparse_destroy_dnvec_descr()."] +pub type rocsparse_dnvec_descr = *mut _rocsparse_dnvec_descr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_dnmat_descr { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Generic API descriptor of the dense matrix.\n\n \\details\n The rocSPARSE dense matrix descriptor is a structure holding all properties of a dense matrix.\n It must be initialized using rocsparse_create_dnmat_descr() and the returned\n descriptor must be passed to all subsequent generic API library calls that involve the dense matrix.\n It should be destroyed at the end using rocsparse_destroy_dnmat_descr()."] +pub type rocsparse_dnmat_descr = *mut _rocsparse_dnmat_descr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _rocsparse_color_info { + _unused: [u8; 0], +} +#[doc = " \\ingroup types_module\n \\brief Coloring info structure to hold data gathered during analysis and later used in\n rocSPARSE sparse matrix coloring routines.\n\n \\details\n The rocSPARSE color info is a structure holding coloring data that is\n gathered during analysis routines. It must be initialized using\n rocsparse_create_color_info() and the returned info structure must be passed to all\n subsequent library calls that require coloring information. It should be\n destroyed at the end using rocsparse_destroy_color_info()."] +pub type rocsparse_color_info = *mut _rocsparse_color_info; +impl rocsparse_operation_ { + #[doc = "< Operate with matrix."] + pub const rocsparse_operation_none: rocsparse_operation_ = rocsparse_operation_(111); +} +impl rocsparse_operation_ { + #[doc = "< Operate with transpose."] + pub const rocsparse_operation_transpose: rocsparse_operation_ = rocsparse_operation_(112); +} +impl rocsparse_operation_ { + #[doc = "< Operate with conj. transpose."] + pub const rocsparse_operation_conjugate_transpose: rocsparse_operation_ = + rocsparse_operation_(113); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify whether the matrix is to be transposed or not.\n\n \\details\n The \\ref rocsparse_operation indicates the operation performed with the given matrix."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_operation_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify whether the matrix is to be transposed or not.\n\n \\details\n The \\ref rocsparse_operation indicates the operation performed with the given matrix."] +pub use self::rocsparse_operation_ as rocsparse_operation; +impl rocsparse_index_base_ { + #[doc = "< zero based indexing."] + pub const rocsparse_index_base_zero: rocsparse_index_base_ = rocsparse_index_base_(0); +} +impl rocsparse_index_base_ { + #[doc = "< one based indexing."] + pub const rocsparse_index_base_one: rocsparse_index_base_ = rocsparse_index_base_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify the matrix index base.\n\n \\details\n The \\ref rocsparse_index_base indicates the index base of the indices. For a\n given \\ref rocsparse_mat_descr, the \\ref rocsparse_index_base can be set using\n rocsparse_set_mat_index_base(). The current \\ref rocsparse_index_base of a matrix\n can be obtained by rocsparse_get_mat_index_base()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_index_base_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify the matrix index base.\n\n \\details\n The \\ref rocsparse_index_base indicates the index base of the indices. For a\n given \\ref rocsparse_mat_descr, the \\ref rocsparse_index_base can be set using\n rocsparse_set_mat_index_base(). The current \\ref rocsparse_index_base of a matrix\n can be obtained by rocsparse_get_mat_index_base()."] +pub use self::rocsparse_index_base_ as rocsparse_index_base; +impl rocsparse_matrix_type_ { + #[doc = "< general matrix type."] + pub const rocsparse_matrix_type_general: rocsparse_matrix_type_ = rocsparse_matrix_type_(0); +} +impl rocsparse_matrix_type_ { + #[doc = "< symmetric matrix type."] + pub const rocsparse_matrix_type_symmetric: rocsparse_matrix_type_ = rocsparse_matrix_type_(1); +} +impl rocsparse_matrix_type_ { + #[doc = "< hermitian matrix type."] + pub const rocsparse_matrix_type_hermitian: rocsparse_matrix_type_ = rocsparse_matrix_type_(2); +} +impl rocsparse_matrix_type_ { + #[doc = "< triangular matrix type."] + pub const rocsparse_matrix_type_triangular: rocsparse_matrix_type_ = rocsparse_matrix_type_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify the matrix type.\n\n \\details\n The \\ref rocsparse_matrix_type indices the type of a matrix. For a given\n \\ref rocsparse_mat_descr, the \\ref rocsparse_matrix_type can be set using\n rocsparse_set_mat_type(). The current \\ref rocsparse_matrix_type of a matrix can be\n obtained by rocsparse_get_mat_type()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_matrix_type_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify the matrix type.\n\n \\details\n The \\ref rocsparse_matrix_type indices the type of a matrix. For a given\n \\ref rocsparse_mat_descr, the \\ref rocsparse_matrix_type can be set using\n rocsparse_set_mat_type(). The current \\ref rocsparse_matrix_type of a matrix can be\n obtained by rocsparse_get_mat_type()."] +pub use self::rocsparse_matrix_type_ as rocsparse_matrix_type; +impl rocsparse_diag_type_ { + #[doc = "< diagonal entries are non-unity."] + pub const rocsparse_diag_type_non_unit: rocsparse_diag_type_ = rocsparse_diag_type_(0); +} +impl rocsparse_diag_type_ { + #[doc = "< diagonal entries are unity"] + pub const rocsparse_diag_type_unit: rocsparse_diag_type_ = rocsparse_diag_type_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Indicates if the diagonal entries are unity.\n\n \\details\n The \\ref rocsparse_diag_type indicates whether the diagonal entries of a matrix are\n unity or not. If \\ref rocsparse_diag_type_unit is specified, all present diagonal\n values will be ignored. For a given \\ref rocsparse_mat_descr, the\n \\ref rocsparse_diag_type can be set using rocsparse_set_mat_diag_type(). The current\n \\ref rocsparse_diag_type of a matrix can be obtained by\n rocsparse_get_mat_diag_type()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_diag_type_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Indicates if the diagonal entries are unity.\n\n \\details\n The \\ref rocsparse_diag_type indicates whether the diagonal entries of a matrix are\n unity or not. If \\ref rocsparse_diag_type_unit is specified, all present diagonal\n values will be ignored. For a given \\ref rocsparse_mat_descr, the\n \\ref rocsparse_diag_type can be set using rocsparse_set_mat_diag_type(). The current\n \\ref rocsparse_diag_type of a matrix can be obtained by\n rocsparse_get_mat_diag_type()."] +pub use self::rocsparse_diag_type_ as rocsparse_diag_type; +impl rocsparse_fill_mode_ { + #[doc = "< lower triangular part is stored."] + pub const rocsparse_fill_mode_lower: rocsparse_fill_mode_ = rocsparse_fill_mode_(0); +} +impl rocsparse_fill_mode_ { + #[doc = "< upper triangular part is stored."] + pub const rocsparse_fill_mode_upper: rocsparse_fill_mode_ = rocsparse_fill_mode_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify the matrix fill mode.\n\n \\details\n The \\ref rocsparse_fill_mode indicates whether the lower or the upper part is stored\n in a sparse triangular matrix. For a given \\ref rocsparse_mat_descr, the\n \\ref rocsparse_fill_mode can be set using rocsparse_set_mat_fill_mode(). The current\n \\ref rocsparse_fill_mode of a matrix can be obtained by\n rocsparse_get_mat_fill_mode()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_fill_mode_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify the matrix fill mode.\n\n \\details\n The \\ref rocsparse_fill_mode indicates whether the lower or the upper part is stored\n in a sparse triangular matrix. For a given \\ref rocsparse_mat_descr, the\n \\ref rocsparse_fill_mode can be set using rocsparse_set_mat_fill_mode(). The current\n \\ref rocsparse_fill_mode of a matrix can be obtained by\n rocsparse_get_mat_fill_mode()."] +pub use self::rocsparse_fill_mode_ as rocsparse_fill_mode; +impl rocsparse_storage_mode_ { + #[doc = "< matrix is sorted."] + pub const rocsparse_storage_mode_sorted: rocsparse_storage_mode_ = rocsparse_storage_mode_(0); +} +impl rocsparse_storage_mode_ { + #[doc = "< matrix is unsorted."] + pub const rocsparse_storage_mode_unsorted: rocsparse_storage_mode_ = rocsparse_storage_mode_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify whether the matrix is stored sorted or not.\n\n \\details\n The \\ref rocsparse_storage_mode indicates whether the matrix is stored sorted or not.\n For a given \\ref rocsparse_mat_descr, the \\ref rocsparse_storage_mode can be set\n using rocsparse_set_storage_mode(). The current \\ref rocsparse_storage_mode of a\n matrix can be obtained by rocsparse_get_mat_storage_mode()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_storage_mode_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify whether the matrix is stored sorted or not.\n\n \\details\n The \\ref rocsparse_storage_mode indicates whether the matrix is stored sorted or not.\n For a given \\ref rocsparse_mat_descr, the \\ref rocsparse_storage_mode can be set\n using rocsparse_set_storage_mode(). The current \\ref rocsparse_storage_mode of a\n matrix can be obtained by rocsparse_get_mat_storage_mode()."] +pub use self::rocsparse_storage_mode_ as rocsparse_storage_mode; +impl rocsparse_action_ { + #[doc = "< Operate only on indices."] + pub const rocsparse_action_symbolic: rocsparse_action_ = rocsparse_action_(0); +} +impl rocsparse_action_ { + #[doc = "< Operate on data and indices."] + pub const rocsparse_action_numeric: rocsparse_action_ = rocsparse_action_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify where the operation is performed on.\n\n \\details\n The \\ref rocsparse_action indicates whether the operation is performed on the full\n matrix, or only on the sparsity pattern of the matrix."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_action_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify where the operation is performed on.\n\n \\details\n The \\ref rocsparse_action indicates whether the operation is performed on the full\n matrix, or only on the sparsity pattern of the matrix."] +pub use self::rocsparse_action_ as rocsparse_action; +impl rocsparse_direction_ { + #[doc = "< Parse the matrix by rows."] + pub const rocsparse_direction_row: rocsparse_direction_ = rocsparse_direction_(0); +} +impl rocsparse_direction_ { + #[doc = "< Parse the matrix by columns."] + pub const rocsparse_direction_column: rocsparse_direction_ = rocsparse_direction_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify the matrix direction.\n\n \\details\n The \\ref rocsparse_direction indicates whether a dense matrix should be parsed by\n rows or by columns, assuming column-major storage."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_direction_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify the matrix direction.\n\n \\details\n The \\ref rocsparse_direction indicates whether a dense matrix should be parsed by\n rows or by columns, assuming column-major storage."] +pub use self::rocsparse_direction_ as rocsparse_direction; +impl rocsparse_hyb_partition_ { + #[doc = "< automatically decide on ELL nnz per row."] + pub const rocsparse_hyb_partition_auto: rocsparse_hyb_partition_ = rocsparse_hyb_partition_(0); +} +impl rocsparse_hyb_partition_ { + #[doc = "< user given ELL nnz per row."] + pub const rocsparse_hyb_partition_user: rocsparse_hyb_partition_ = rocsparse_hyb_partition_(1); +} +impl rocsparse_hyb_partition_ { + #[doc = "< max ELL nnz per row, no COO part."] + pub const rocsparse_hyb_partition_max: rocsparse_hyb_partition_ = rocsparse_hyb_partition_(2); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief HYB matrix partitioning type.\n\n \\details\n The \\ref rocsparse_hyb_partition type indicates how the hybrid format partitioning\n between COO and ELL storage formats is performed."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_hyb_partition_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief HYB matrix partitioning type.\n\n \\details\n The \\ref rocsparse_hyb_partition type indicates how the hybrid format partitioning\n between COO and ELL storage formats is performed."] +pub use self::rocsparse_hyb_partition_ as rocsparse_hyb_partition; +impl rocsparse_analysis_policy_ { + #[doc = "< try to re-use meta data."] + pub const rocsparse_analysis_policy_reuse: rocsparse_analysis_policy_ = + rocsparse_analysis_policy_(0); +} +impl rocsparse_analysis_policy_ { + #[doc = "< force to re-build meta data."] + pub const rocsparse_analysis_policy_force: rocsparse_analysis_policy_ = + rocsparse_analysis_policy_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify policy in analysis functions.\n\n \\details\n The \\ref rocsparse_analysis_policy specifies whether gathered analysis data should be\n re-used or not. If meta data from a previous e.g. rocsparse_csrilu0_analysis() call\n is available, it can be re-used for subsequent calls to e.g.\n rocsparse_csrsv_analysis() and greatly improve performance of the analysis function."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_analysis_policy_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify policy in analysis functions.\n\n \\details\n The \\ref rocsparse_analysis_policy specifies whether gathered analysis data should be\n re-used or not. If meta data from a previous e.g. rocsparse_csrilu0_analysis() call\n is available, it can be re-used for subsequent calls to e.g.\n rocsparse_csrsv_analysis() and greatly improve performance of the analysis function."] +pub use self::rocsparse_analysis_policy_ as rocsparse_analysis_policy; +impl rocsparse_solve_policy_ { + #[doc = "< automatically decide on level information."] + pub const rocsparse_solve_policy_auto: rocsparse_solve_policy_ = rocsparse_solve_policy_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Specify policy in triangular solvers and factorizations.\n\n \\details\n This is a placeholder."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_solve_policy_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Specify policy in triangular solvers and factorizations.\n\n \\details\n This is a placeholder."] +pub use self::rocsparse_solve_policy_ as rocsparse_solve_policy; +impl rocsparse_pointer_mode_ { + #[doc = "< scalar pointers are in host memory."] + pub const rocsparse_pointer_mode_host: rocsparse_pointer_mode_ = rocsparse_pointer_mode_(0); +} +impl rocsparse_pointer_mode_ { + #[doc = "< scalar pointers are in device memory."] + pub const rocsparse_pointer_mode_device: rocsparse_pointer_mode_ = rocsparse_pointer_mode_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief Indicates if the pointer is device pointer or host pointer.\n\n \\details\n The \\ref rocsparse_pointer_mode indicates whether scalar values are passed by\n reference on the host or device. The \\ref rocsparse_pointer_mode can be changed by\n rocsparse_set_pointer_mode(). The currently used pointer mode can be obtained by\n rocsparse_get_pointer_mode()."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_pointer_mode_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief Indicates if the pointer is device pointer or host pointer.\n\n \\details\n The \\ref rocsparse_pointer_mode indicates whether scalar values are passed by\n reference on the host or device. The \\ref rocsparse_pointer_mode can be changed by\n rocsparse_set_pointer_mode(). The currently used pointer mode can be obtained by\n rocsparse_get_pointer_mode()."] +pub use self::rocsparse_pointer_mode_ as rocsparse_pointer_mode; +impl rocsparse_status_ { + #[doc = "< success."] + pub const rocsparse_status_success: rocsparse_status_ = rocsparse_status_(0); +} +impl rocsparse_status_ { + #[doc = "< handle not initialized, invalid or null."] + pub const rocsparse_status_invalid_handle: rocsparse_status_ = rocsparse_status_(1); +} +impl rocsparse_status_ { + #[doc = "< function is not implemented."] + pub const rocsparse_status_not_implemented: rocsparse_status_ = rocsparse_status_(2); +} +impl rocsparse_status_ { + #[doc = "< invalid pointer parameter."] + pub const rocsparse_status_invalid_pointer: rocsparse_status_ = rocsparse_status_(3); +} +impl rocsparse_status_ { + #[doc = "< invalid size parameter."] + pub const rocsparse_status_invalid_size: rocsparse_status_ = rocsparse_status_(4); +} +impl rocsparse_status_ { + #[doc = "< failed memory allocation, copy, dealloc."] + pub const rocsparse_status_memory_error: rocsparse_status_ = rocsparse_status_(5); +} +impl rocsparse_status_ { + #[doc = "< other internal library failure."] + pub const rocsparse_status_internal_error: rocsparse_status_ = rocsparse_status_(6); +} +impl rocsparse_status_ { + #[doc = "< invalid value parameter."] + pub const rocsparse_status_invalid_value: rocsparse_status_ = rocsparse_status_(7); +} +impl rocsparse_status_ { + #[doc = "< device arch is not supported."] + pub const rocsparse_status_arch_mismatch: rocsparse_status_ = rocsparse_status_(8); +} +impl rocsparse_status_ { + #[doc = "< encountered zero pivot."] + pub const rocsparse_status_zero_pivot: rocsparse_status_ = rocsparse_status_(9); +} +impl rocsparse_status_ { + #[doc = "< descriptor has not been initialized."] + pub const rocsparse_status_not_initialized: rocsparse_status_ = rocsparse_status_(10); +} +impl rocsparse_status_ { + #[doc = "< index types do not match."] + pub const rocsparse_status_type_mismatch: rocsparse_status_ = rocsparse_status_(11); +} +impl rocsparse_status_ { + #[doc = "< sorted storage required."] + pub const rocsparse_status_requires_sorted_storage: rocsparse_status_ = rocsparse_status_(12); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of rocsparse status codes definition.\n\n \\details\n This is a list of the \\ref rocsparse_status types that are used by the rocSPARSE\n library."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_status_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of rocsparse status codes definition.\n\n \\details\n This is a list of the \\ref rocsparse_status types that are used by the rocSPARSE\n library."] +pub use self::rocsparse_status_ as rocsparse_status; +impl rocsparse_data_status_ { + #[doc = "< success."] + pub const rocsparse_data_status_success: rocsparse_data_status_ = rocsparse_data_status_(0); +} +impl rocsparse_data_status_ { + #[doc = "< An inf value detected."] + pub const rocsparse_data_status_inf: rocsparse_data_status_ = rocsparse_data_status_(1); +} +impl rocsparse_data_status_ { + #[doc = "< An nan value detected."] + pub const rocsparse_data_status_nan: rocsparse_data_status_ = rocsparse_data_status_(2); +} +impl rocsparse_data_status_ { + #[doc = "< An invalid row pointer offset detected."] + pub const rocsparse_data_status_invalid_offset_ptr: rocsparse_data_status_ = + rocsparse_data_status_(3); +} +impl rocsparse_data_status_ { + #[doc = "< An invalid row indice detected."] + pub const rocsparse_data_status_invalid_index: rocsparse_data_status_ = + rocsparse_data_status_(4); +} +impl rocsparse_data_status_ { + #[doc = "< Duplicate indice detected."] + pub const rocsparse_data_status_duplicate_entry: rocsparse_data_status_ = + rocsparse_data_status_(5); +} +impl rocsparse_data_status_ { + #[doc = "< Incorrect sorting detected."] + pub const rocsparse_data_status_invalid_sorting: rocsparse_data_status_ = + rocsparse_data_status_(6); +} +impl rocsparse_data_status_ { + #[doc = "< Incorrect fill mode detected."] + pub const rocsparse_data_status_invalid_fill: rocsparse_data_status_ = + rocsparse_data_status_(7); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of rocsparse data status codes definition.\n\n \\details\n This is a list of the \\ref rocsparse_data_status types that are used by the rocSPARSE\n library in the matrix check routines."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_data_status_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of rocsparse data status codes definition.\n\n \\details\n This is a list of the \\ref rocsparse_data_status types that are used by the rocSPARSE\n library in the matrix check routines."] +pub use self::rocsparse_data_status_ as rocsparse_data_status; +impl rocsparse_indextype_ { + #[doc = "< 16 bit unsigned integer."] + pub const rocsparse_indextype_u16: rocsparse_indextype_ = rocsparse_indextype_(1); +} +impl rocsparse_indextype_ { + #[doc = "< 32 bit signed integer."] + pub const rocsparse_indextype_i32: rocsparse_indextype_ = rocsparse_indextype_(2); +} +impl rocsparse_indextype_ { + #[doc = "< 64 bit signed integer."] + pub const rocsparse_indextype_i64: rocsparse_indextype_ = rocsparse_indextype_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of rocsparse index types.\n\n \\details\n Indicates the index width of a rocsparse index type."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_indextype_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of rocsparse index types.\n\n \\details\n Indicates the index width of a rocsparse index type."] +pub use self::rocsparse_indextype_ as rocsparse_indextype; +impl rocsparse_datatype_ { + #[doc = "< 32 bit floating point, real."] + pub const rocsparse_datatype_f32_r: rocsparse_datatype_ = rocsparse_datatype_(151); +} +impl rocsparse_datatype_ { + #[doc = "< 64 bit floating point, real."] + pub const rocsparse_datatype_f64_r: rocsparse_datatype_ = rocsparse_datatype_(152); +} +impl rocsparse_datatype_ { + #[doc = "< 32 bit floating point, complex."] + pub const rocsparse_datatype_f32_c: rocsparse_datatype_ = rocsparse_datatype_(154); +} +impl rocsparse_datatype_ { + #[doc = "< 64 bit floating point, complex."] + pub const rocsparse_datatype_f64_c: rocsparse_datatype_ = rocsparse_datatype_(155); +} +impl rocsparse_datatype_ { + #[doc = "< 8-bit signed integer, real"] + pub const rocsparse_datatype_i8_r: rocsparse_datatype_ = rocsparse_datatype_(160); +} +impl rocsparse_datatype_ { + #[doc = "< 8-bit unsigned integer, real"] + pub const rocsparse_datatype_u8_r: rocsparse_datatype_ = rocsparse_datatype_(161); +} +impl rocsparse_datatype_ { + #[doc = "< 32-bit signed integer, real"] + pub const rocsparse_datatype_i32_r: rocsparse_datatype_ = rocsparse_datatype_(162); +} +impl rocsparse_datatype_ { + #[doc = "< 32-bit unsigned integer, real"] + pub const rocsparse_datatype_u32_r: rocsparse_datatype_ = rocsparse_datatype_(163); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of rocsparse data types.\n\n \\details\n Indicates the precision width of data stored in a rocsparse type."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_datatype_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of rocsparse data types.\n\n \\details\n Indicates the precision width of data stored in a rocsparse type."] +pub use self::rocsparse_datatype_ as rocsparse_datatype; +impl rocsparse_format_ { + #[doc = "< COO sparse matrix format."] + pub const rocsparse_format_coo: rocsparse_format_ = rocsparse_format_(0); +} +impl rocsparse_format_ { + #[doc = "< COO AoS sparse matrix format."] + pub const rocsparse_format_coo_aos: rocsparse_format_ = rocsparse_format_(1); +} +impl rocsparse_format_ { + #[doc = "< CSR sparse matrix format."] + pub const rocsparse_format_csr: rocsparse_format_ = rocsparse_format_(2); +} +impl rocsparse_format_ { + #[doc = "< CSC sparse matrix format."] + pub const rocsparse_format_csc: rocsparse_format_ = rocsparse_format_(3); +} +impl rocsparse_format_ { + #[doc = "< ELL sparse matrix format."] + pub const rocsparse_format_ell: rocsparse_format_ = rocsparse_format_(4); +} +impl rocsparse_format_ { + #[doc = "< BLOCKED ELL sparse matrix format."] + pub const rocsparse_format_bell: rocsparse_format_ = rocsparse_format_(5); +} +impl rocsparse_format_ { + #[doc = "< BSR sparse matrix format."] + pub const rocsparse_format_bsr: rocsparse_format_ = rocsparse_format_(6); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of sparse matrix formats.\n\n \\details\n This is a list of supported \\ref rocsparse_format types that are used to describe a\n sparse matrix."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_format_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of sparse matrix formats.\n\n \\details\n This is a list of supported \\ref rocsparse_format types that are used to describe a\n sparse matrix."] +pub use self::rocsparse_format_ as rocsparse_format; +impl rocsparse_order_ { + #[doc = "< Row major."] + pub const rocsparse_order_row: rocsparse_order_ = rocsparse_order_(0); +} +impl rocsparse_order_ { + #[doc = "< Column major."] + pub const rocsparse_order_column: rocsparse_order_ = rocsparse_order_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of dense matrix ordering.\n\n \\details\n This is a list of supported \\ref rocsparse_order types that are used to describe the\n memory layout of a dense matrix"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_order_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of dense matrix ordering.\n\n \\details\n This is a list of supported \\ref rocsparse_order types that are used to describe the\n memory layout of a dense matrix"] +pub use self::rocsparse_order_ as rocsparse_order; +impl rocsparse_spmat_attribute_ { + #[doc = "< Fill mode attribute."] + pub const rocsparse_spmat_fill_mode: rocsparse_spmat_attribute_ = rocsparse_spmat_attribute_(0); +} +impl rocsparse_spmat_attribute_ { + #[doc = "< Diag type attribute."] + pub const rocsparse_spmat_diag_type: rocsparse_spmat_attribute_ = rocsparse_spmat_attribute_(1); +} +impl rocsparse_spmat_attribute_ { + #[doc = "< Matrix type attribute."] + pub const rocsparse_spmat_matrix_type: rocsparse_spmat_attribute_ = + rocsparse_spmat_attribute_(2); +} +impl rocsparse_spmat_attribute_ { + #[doc = "< Matrix storage attribute."] + pub const rocsparse_spmat_storage_mode: rocsparse_spmat_attribute_ = + rocsparse_spmat_attribute_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of sparse matrix attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spmat_attribute_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of sparse matrix attributes"] +pub use self::rocsparse_spmat_attribute_ as rocsparse_spmat_attribute; +impl rocsparse_itilu0_alg_ { + #[doc = "< ASynchronous ITILU0 algorithm with in-place storage"] + pub const rocsparse_itilu0_alg_default: rocsparse_itilu0_alg_ = rocsparse_itilu0_alg_(0); +} +impl rocsparse_itilu0_alg_ { + pub const rocsparse_itilu0_alg_async_inplace: rocsparse_itilu0_alg_ = rocsparse_itilu0_alg_(1); +} +impl rocsparse_itilu0_alg_ { + pub const rocsparse_itilu0_alg_async_split: rocsparse_itilu0_alg_ = rocsparse_itilu0_alg_(2); +} +impl rocsparse_itilu0_alg_ { + pub const rocsparse_itilu0_alg_sync_split: rocsparse_itilu0_alg_ = rocsparse_itilu0_alg_(3); +} +impl rocsparse_itilu0_alg_ { + pub const rocsparse_itilu0_alg_sync_split_fusion: rocsparse_itilu0_alg_ = + rocsparse_itilu0_alg_(4); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of Iterative ILU0 algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_itilu0_alg types that are used to perform\n the iterative ILU0 algorithm."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_itilu0_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of Iterative ILU0 algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_itilu0_alg types that are used to perform\n the iterative ILU0 algorithm."] +pub use self::rocsparse_itilu0_alg_ as rocsparse_itilu0_alg; +impl rocsparse_gtsv_interleaved_alg_ { + pub const rocsparse_gtsv_interleaved_alg_default: rocsparse_gtsv_interleaved_alg_ = + rocsparse_gtsv_interleaved_alg_(0); +} +impl rocsparse_gtsv_interleaved_alg_ { + pub const rocsparse_gtsv_interleaved_alg_thomas: rocsparse_gtsv_interleaved_alg_ = + rocsparse_gtsv_interleaved_alg_(1); +} +impl rocsparse_gtsv_interleaved_alg_ { + pub const rocsparse_gtsv_interleaved_alg_lu: rocsparse_gtsv_interleaved_alg_ = + rocsparse_gtsv_interleaved_alg_(2); +} +impl rocsparse_gtsv_interleaved_alg_ { + pub const rocsparse_gtsv_interleaved_alg_qr: rocsparse_gtsv_interleaved_alg_ = + rocsparse_gtsv_interleaved_alg_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of interleaved gtsv algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_gtsv_interleaved_alg types that are used to perform\n interleaved tridiagonal solve."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_gtsv_interleaved_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of interleaved gtsv algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_gtsv_interleaved_alg types that are used to perform\n interleaved tridiagonal solve."] +pub use self::rocsparse_gtsv_interleaved_alg_ as rocsparse_gtsv_interleaved_alg; +impl rocsparse_spmv_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spmv_stage_auto: rocsparse_spmv_stage_ = rocsparse_spmv_stage_(0); +} +impl rocsparse_spmv_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spmv_stage_buffer_size: rocsparse_spmv_stage_ = rocsparse_spmv_stage_(1); +} +impl rocsparse_spmv_stage_ { + #[doc = "< Preprocess data."] + pub const rocsparse_spmv_stage_preprocess: rocsparse_spmv_stage_ = rocsparse_spmv_stage_(2); +} +impl rocsparse_spmv_stage_ { + #[doc = "< Performs the actual SpMV computation."] + pub const rocsparse_spmv_stage_compute: rocsparse_spmv_stage_ = rocsparse_spmv_stage_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpMV stages.\n\n \\details\n This is a list of possible stages during SpMV computation. Typical order is\n rocsparse_spmv_buffer_size, rocsparse_spmv_preprocess, rocsparse_spmv_compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spmv_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpMV stages.\n\n \\details\n This is a list of possible stages during SpMV computation. Typical order is\n rocsparse_spmv_buffer_size, rocsparse_spmv_preprocess, rocsparse_spmv_compute."] +pub use self::rocsparse_spmv_stage_ as rocsparse_spmv_stage; +impl rocsparse_spmv_alg_ { + #[doc = "< Default SpMV algorithm for the given format."] + pub const rocsparse_spmv_alg_default: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(0); +} +impl rocsparse_spmv_alg_ { + #[doc = "< COO SpMV algorithm 1 (segmented) for COO matrices."] + pub const rocsparse_spmv_alg_coo: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(1); +} +impl rocsparse_spmv_alg_ { + #[doc = "< CSR SpMV algorithm 1 (adaptive) for CSR matrices."] + pub const rocsparse_spmv_alg_csr_adaptive: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(2); +} +impl rocsparse_spmv_alg_ { + #[doc = "< CSR SpMV algorithm 2 (stream) for CSR matrices."] + pub const rocsparse_spmv_alg_csr_stream: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(3); +} +impl rocsparse_spmv_alg_ { + #[doc = "< ELL SpMV algorithm for ELL matrices."] + pub const rocsparse_spmv_alg_ell: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(4); +} +impl rocsparse_spmv_alg_ { + #[doc = "< COO SpMV algorithm 2 (atomic) for COO matrices."] + pub const rocsparse_spmv_alg_coo_atomic: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(5); +} +impl rocsparse_spmv_alg_ { + #[doc = "< BSR SpMV algorithm 1 for BSR matrices."] + pub const rocsparse_spmv_alg_bsr: rocsparse_spmv_alg_ = rocsparse_spmv_alg_(6); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpMV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spmv_alg types that are used to perform\n matrix vector product."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spmv_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpMV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spmv_alg types that are used to perform\n matrix vector product."] +pub use self::rocsparse_spmv_alg_ as rocsparse_spmv_alg; +impl rocsparse_spsv_alg_ { + #[doc = "< Default SpSV algorithm for the given format."] + pub const rocsparse_spsv_alg_default: rocsparse_spsv_alg_ = rocsparse_spsv_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpSV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spsv_alg types that are used to perform\n triangular solve."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spsv_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpSV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spsv_alg types that are used to perform\n triangular solve."] +pub use self::rocsparse_spsv_alg_ as rocsparse_spsv_alg; +impl rocsparse_spsv_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spsv_stage_auto: rocsparse_spsv_stage_ = rocsparse_spsv_stage_(0); +} +impl rocsparse_spsv_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spsv_stage_buffer_size: rocsparse_spsv_stage_ = rocsparse_spsv_stage_(1); +} +impl rocsparse_spsv_stage_ { + #[doc = "< Preprocess data."] + pub const rocsparse_spsv_stage_preprocess: rocsparse_spsv_stage_ = rocsparse_spsv_stage_(2); +} +impl rocsparse_spsv_stage_ { + #[doc = "< Performs the actual SpSV computation."] + pub const rocsparse_spsv_stage_compute: rocsparse_spsv_stage_ = rocsparse_spsv_stage_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpSV stages.\n\n \\details\n This is a list of possible stages during SpSV computation. Typical order is\n rocsparse_spsv_buffer_size, rocsparse_spsv_preprocess, rocsparse_spsv_compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spsv_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpSV stages.\n\n \\details\n This is a list of possible stages during SpSV computation. Typical order is\n rocsparse_spsv_buffer_size, rocsparse_spsv_preprocess, rocsparse_spsv_compute."] +pub use self::rocsparse_spsv_stage_ as rocsparse_spsv_stage; +impl rocsparse_spitsv_alg_ { + #[doc = "< Default SpITSV algorithm for the given format."] + pub const rocsparse_spitsv_alg_default: rocsparse_spitsv_alg_ = rocsparse_spitsv_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpITSV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spitsv_alg types that are used to perform\n triangular solve."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spitsv_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpITSV algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spitsv_alg types that are used to perform\n triangular solve."] +pub use self::rocsparse_spitsv_alg_ as rocsparse_spitsv_alg; +impl rocsparse_spitsv_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spitsv_stage_auto: rocsparse_spitsv_stage_ = rocsparse_spitsv_stage_(0); +} +impl rocsparse_spitsv_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spitsv_stage_buffer_size: rocsparse_spitsv_stage_ = + rocsparse_spitsv_stage_(1); +} +impl rocsparse_spitsv_stage_ { + #[doc = "< Preprocess data."] + pub const rocsparse_spitsv_stage_preprocess: rocsparse_spitsv_stage_ = + rocsparse_spitsv_stage_(2); +} +impl rocsparse_spitsv_stage_ { + #[doc = "< Performs the actual SpITSV computation."] + pub const rocsparse_spitsv_stage_compute: rocsparse_spitsv_stage_ = rocsparse_spitsv_stage_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpITSV stages.\n\n \\details\n This is a list of possible stages during SpITSV computation. Typical order is\n buffer_size, preprocess, compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spitsv_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpITSV stages.\n\n \\details\n This is a list of possible stages during SpITSV computation. Typical order is\n buffer_size, preprocess, compute."] +pub use self::rocsparse_spitsv_stage_ as rocsparse_spitsv_stage; +impl rocsparse_spsm_alg_ { + #[doc = "< Default SpSM algorithm for the given format."] + pub const rocsparse_spsm_alg_default: rocsparse_spsm_alg_ = rocsparse_spsm_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpSM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spsm_alg types that are used to perform\n triangular solve."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spsm_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpSM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spsm_alg types that are used to perform\n triangular solve."] +pub use self::rocsparse_spsm_alg_ as rocsparse_spsm_alg; +impl rocsparse_spsm_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spsm_stage_auto: rocsparse_spsm_stage_ = rocsparse_spsm_stage_(0); +} +impl rocsparse_spsm_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spsm_stage_buffer_size: rocsparse_spsm_stage_ = rocsparse_spsm_stage_(1); +} +impl rocsparse_spsm_stage_ { + #[doc = "< Preprocess data."] + pub const rocsparse_spsm_stage_preprocess: rocsparse_spsm_stage_ = rocsparse_spsm_stage_(2); +} +impl rocsparse_spsm_stage_ { + #[doc = "< Performs the actual SpSM computation."] + pub const rocsparse_spsm_stage_compute: rocsparse_spsm_stage_ = rocsparse_spsm_stage_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpSM stages.\n\n \\details\n This is a list of possible stages during SpSM computation. Typical order is\n rocsparse_spsm_buffer_size, rocsparse_spsm_preprocess, rocsparse_spsm_compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spsm_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpSM stages.\n\n \\details\n This is a list of possible stages during SpSM computation. Typical order is\n rocsparse_spsm_buffer_size, rocsparse_spsm_preprocess, rocsparse_spsm_compute."] +pub use self::rocsparse_spsm_stage_ as rocsparse_spsm_stage; +impl rocsparse_spmm_alg_ { + #[doc = "< Default SpMM algorithm for the given format."] + pub const rocsparse_spmm_alg_default: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(0); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for CSR format using row split and shared memory."] + pub const rocsparse_spmm_alg_csr: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(1); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for COO format using segmented scan."] + pub const rocsparse_spmm_alg_coo_segmented: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(2); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for COO format using atomics."] + pub const rocsparse_spmm_alg_coo_atomic: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(3); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for CSR format using row split and shfl."] + pub const rocsparse_spmm_alg_csr_row_split: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(4); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for CSR format using conversion to COO."] + pub const rocsparse_spmm_alg_csr_merge: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(5); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for COO format using segmented scan and atomics."] + pub const rocsparse_spmm_alg_coo_segmented_atomic: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(6); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for Blocked ELL format."] + pub const rocsparse_spmm_alg_bell: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(7); +} +impl rocsparse_spmm_alg_ { + #[doc = "< SpMM algorithm for BSR format."] + pub const rocsparse_spmm_alg_bsr: rocsparse_spmm_alg_ = rocsparse_spmm_alg_(8); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpMM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spmm_alg types that are used to perform\n matrix vector product."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spmm_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpMM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spmm_alg types that are used to perform\n matrix vector product."] +pub use self::rocsparse_spmm_alg_ as rocsparse_spmm_alg; +impl rocsparse_sddmm_alg_ { + #[doc = "< Default sddmm algorithm for the given format."] + pub const rocsparse_sddmm_alg_default: rocsparse_sddmm_alg_ = rocsparse_sddmm_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of sddmm algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_sddmm_alg types that are used to perform\n matrix vector product."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_sddmm_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of sddmm algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_sddmm_alg types that are used to perform\n matrix vector product."] +pub use self::rocsparse_sddmm_alg_ as rocsparse_sddmm_alg; +impl rocsparse_sparse_to_dense_alg_ { + pub const rocsparse_sparse_to_dense_alg_default: rocsparse_sparse_to_dense_alg_ = + rocsparse_sparse_to_dense_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of sparse to dense algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_sparse_to_dense_alg types that are used to perform\n sparse to dense conversion."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_sparse_to_dense_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of sparse to dense algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_sparse_to_dense_alg types that are used to perform\n sparse to dense conversion."] +pub use self::rocsparse_sparse_to_dense_alg_ as rocsparse_sparse_to_dense_alg; +impl rocsparse_dense_to_sparse_alg_ { + pub const rocsparse_dense_to_sparse_alg_default: rocsparse_dense_to_sparse_alg_ = + rocsparse_dense_to_sparse_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of dense to sparse algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_dense_to_sparse_alg types that are used to perform\n dense to sparse conversion."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_dense_to_sparse_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of dense to sparse algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_dense_to_sparse_alg types that are used to perform\n dense to sparse conversion."] +pub use self::rocsparse_dense_to_sparse_alg_ as rocsparse_dense_to_sparse_alg; +impl rocsparse_spmm_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spmm_stage_auto: rocsparse_spmm_stage_ = rocsparse_spmm_stage_(0); +} +impl rocsparse_spmm_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spmm_stage_buffer_size: rocsparse_spmm_stage_ = rocsparse_spmm_stage_(1); +} +impl rocsparse_spmm_stage_ { + #[doc = "< Preprocess data."] + pub const rocsparse_spmm_stage_preprocess: rocsparse_spmm_stage_ = rocsparse_spmm_stage_(2); +} +impl rocsparse_spmm_stage_ { + #[doc = "< Performs the actual SpMM computation."] + pub const rocsparse_spmm_stage_compute: rocsparse_spmm_stage_ = rocsparse_spmm_stage_(3); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpMM stages.\n\n \\details\n This is a list of possible stages during SpMM computation. Typical order is\n rocsparse_spmm_buffer_size, rocsparse_spmm_preprocess, rocsparse_spmm_compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spmm_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpMM stages.\n\n \\details\n This is a list of possible stages during SpMM computation. Typical order is\n rocsparse_spmm_buffer_size, rocsparse_spmm_preprocess, rocsparse_spmm_compute."] +pub use self::rocsparse_spmm_stage_ as rocsparse_spmm_stage; +impl rocsparse_spgemm_stage_ { + #[doc = "< Automatic stage detection."] + pub const rocsparse_spgemm_stage_auto: rocsparse_spgemm_stage_ = rocsparse_spgemm_stage_(0); +} +impl rocsparse_spgemm_stage_ { + #[doc = "< Returns the required buffer size."] + pub const rocsparse_spgemm_stage_buffer_size: rocsparse_spgemm_stage_ = + rocsparse_spgemm_stage_(1); +} +impl rocsparse_spgemm_stage_ { + #[doc = "< Computes number of non-zero entries."] + pub const rocsparse_spgemm_stage_nnz: rocsparse_spgemm_stage_ = rocsparse_spgemm_stage_(2); +} +impl rocsparse_spgemm_stage_ { + #[doc = "< Performs the actual SpGEMM computation."] + pub const rocsparse_spgemm_stage_compute: rocsparse_spgemm_stage_ = rocsparse_spgemm_stage_(3); +} +impl rocsparse_spgemm_stage_ { + #[doc = "< Performs the actual SpGEMM symbolic computation."] + pub const rocsparse_spgemm_stage_symbolic: rocsparse_spgemm_stage_ = rocsparse_spgemm_stage_(4); +} +impl rocsparse_spgemm_stage_ { + #[doc = "< Performs the actual SpGEMM numeric computation."] + pub const rocsparse_spgemm_stage_numeric: rocsparse_spgemm_stage_ = rocsparse_spgemm_stage_(5); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpGEMM stages.\n\n \\details\n This is a list of possible stages during SpGEMM computation. Typical order is\n rocsparse_spgemm_buffer_size, rocsparse_spgemm_nnz, rocsparse_spgemm_compute."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spgemm_stage_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpGEMM stages.\n\n \\details\n This is a list of possible stages during SpGEMM computation. Typical order is\n rocsparse_spgemm_buffer_size, rocsparse_spgemm_nnz, rocsparse_spgemm_compute."] +pub use self::rocsparse_spgemm_stage_ as rocsparse_spgemm_stage; +impl rocsparse_spgemm_alg_ { + #[doc = "< Default SpGEMM algorithm for the given format."] + pub const rocsparse_spgemm_alg_default: rocsparse_spgemm_alg_ = rocsparse_spgemm_alg_(0); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of SpGEMM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spgemm_alg types that are used to perform\n sparse matrix sparse matrix product."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_spgemm_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of SpGEMM algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_spgemm_alg types that are used to perform\n sparse matrix sparse matrix product."] +pub use self::rocsparse_spgemm_alg_ as rocsparse_spgemm_alg; +impl rocsparse_gpsv_interleaved_alg_ { + #[doc = "< Default gpsv algorithm."] + pub const rocsparse_gpsv_interleaved_alg_default: rocsparse_gpsv_interleaved_alg_ = + rocsparse_gpsv_interleaved_alg_(0); +} +impl rocsparse_gpsv_interleaved_alg_ { + #[doc = "< QR algorithm"] + pub const rocsparse_gpsv_interleaved_alg_qr: rocsparse_gpsv_interleaved_alg_ = + rocsparse_gpsv_interleaved_alg_(1); +} +#[repr(transparent)] +#[doc = " \\ingroup types_module\n \\brief List of gpsv algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_gpsv_interleaved_alg types that are used to solve\n pentadiagonal linear systems."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct rocsparse_gpsv_interleaved_alg_(pub ::std::os::raw::c_uint); +#[doc = " \\ingroup types_module\n \\brief List of gpsv algorithms.\n\n \\details\n This is a list of supported \\ref rocsparse_gpsv_interleaved_alg types that are used to solve\n pentadiagonal linear systems."] +pub use self::rocsparse_gpsv_interleaved_alg_ as rocsparse_gpsv_interleaved_alg; +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a rocsparse handle\n\n \\details\n \\p rocsparse_create_handle creates the rocSPARSE library context. It must be\n initialized before any other rocSPARSE API function is invoked and must be passed to\n all subsequent library function calls. The handle should be destroyed at the end\n using rocsparse_destroy_handle().\n\n @param[out]\n handle the pointer to the handle to the rocSPARSE library context.\n\n \\retval rocsparse_status_success the initialization succeeded.\n \\retval rocsparse_status_invalid_handle \\p handle pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_create_handle(handle: *mut rocsparse_handle) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a rocsparse handle\n\n \\details\n \\p rocsparse_destroy_handle destroys the rocSPARSE library context and releases all\n resources used by the rocSPARSE library.\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_destroy_handle(handle: rocsparse_handle) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify user defined HIP stream\n\n \\details\n \\p rocsparse_set_stream specifies the stream to be used by the rocSPARSE library\n context and all subsequent function calls.\n\n @param[inout]\n handle the handle to the rocSPARSE library context.\n @param[in]\n stream the stream to be used by the rocSPARSE library context.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid.\n\n \\par Example\n This example illustrates, how a user defined stream can be used in rocSPARSE.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create stream\n hipStream_t stream;\n hipStreamCreate(&stream);\n\n // Set stream to rocSPARSE handle\n rocsparse_set_stream(handle, stream);\n\n // Do some work\n // ...\n\n // Clean up\n rocsparse_destroy_handle(handle);\n hipStreamDestroy(stream);\n \\endcode"] + pub fn rocsparse_set_stream(handle: rocsparse_handle, stream: hipStream_t) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get current stream from library context\n\n \\details\n \\p rocsparse_get_stream gets the rocSPARSE library context stream which is currently\n used for all subsequent function calls.\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n @param[out]\n stream the stream currently used by the rocSPARSE library context.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid."] + pub fn rocsparse_get_stream( + handle: rocsparse_handle, + stream: *mut hipStream_t, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify pointer mode\n\n \\details\n \\p rocsparse_set_pointer_mode specifies the pointer mode to be used by the rocSPARSE\n library context and all subsequent function calls. By default, all values are passed\n by reference on the host. Valid pointer modes are \\ref rocsparse_pointer_mode_host\n or \\p rocsparse_pointer_mode_device.\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n @param[in]\n pointer_mode the pointer mode to be used by the rocSPARSE library context.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid."] + pub fn rocsparse_set_pointer_mode( + handle: rocsparse_handle, + pointer_mode: rocsparse_pointer_mode, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get current pointer mode from library context\n\n \\details\n \\p rocsparse_get_pointer_mode gets the rocSPARSE library context pointer mode which\n is currently used for all subsequent function calls.\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n @param[out]\n pointer_mode the pointer mode that is currently used by the rocSPARSE library\n context.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid."] + pub fn rocsparse_get_pointer_mode( + handle: rocsparse_handle, + pointer_mode: *mut rocsparse_pointer_mode, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get rocSPARSE version\n\n \\details\n \\p rocsparse_get_version gets the rocSPARSE library version number.\n - patch = version % 100\n - minor = version / 100 % 1000\n - major = version / 100000\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n @param[out]\n version the version number of the rocSPARSE library.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid."] + pub fn rocsparse_get_version( + handle: rocsparse_handle, + version: *mut ::std::os::raw::c_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get rocSPARSE git revision\n\n \\details\n \\p rocsparse_get_git_rev gets the rocSPARSE library git commit revision (SHA-1).\n\n @param[in]\n handle the handle to the rocSPARSE library context.\n @param[out]\n rev the git commit revision (SHA-1).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle \\p handle is invalid."] + pub fn rocsparse_get_git_rev( + handle: rocsparse_handle, + rev: *mut ::std::os::raw::c_char, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a matrix descriptor\n \\details\n \\p rocsparse_create_mat_descr creates a matrix descriptor. It initializes\n \\ref rocsparse_matrix_type to \\ref rocsparse_matrix_type_general and\n \\ref rocsparse_index_base to \\ref rocsparse_index_base_zero. It should be destroyed\n at the end using rocsparse_destroy_mat_descr().\n\n @param[out]\n descr the pointer to the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid."] + pub fn rocsparse_create_mat_descr(descr: *mut rocsparse_mat_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Copy a matrix descriptor\n \\details\n \\p rocsparse_copy_mat_descr copies a matrix descriptor. Both, source and destination\n matrix descriptors must be initialized prior to calling \\p rocsparse_copy_mat_descr.\n\n @param[out]\n dest the pointer to the destination matrix descriptor.\n @param[in]\n src the pointer to the source matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p src or \\p dest pointer is invalid."] + pub fn rocsparse_copy_mat_descr( + dest: rocsparse_mat_descr, + src: rocsparse_mat_descr, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a matrix descriptor\n\n \\details\n \\p rocsparse_destroy_mat_descr destroys a matrix descriptor and releases all\n resources used by the descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr is invalid."] + pub fn rocsparse_destroy_mat_descr(descr: rocsparse_mat_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify the index base of a matrix descriptor\n\n \\details\n \\p rocsparse_set_mat_index_base sets the index base of a matrix descriptor. Valid\n options are \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p base is invalid."] + pub fn rocsparse_set_mat_index_base( + descr: rocsparse_mat_descr, + base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[doc = " \\ingroup aux_module\n \\brief Get the index base of a matrix descriptor\n\n \\details\n \\p rocsparse_get_mat_index_base returns the index base of a matrix descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\returns \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one."] + pub fn rocsparse_get_mat_index_base(descr: rocsparse_mat_descr) -> rocsparse_index_base; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify the matrix type of a matrix descriptor\n\n \\details\n \\p rocsparse_set_mat_type sets the matrix type of a matrix descriptor. Valid\n matrix types are \\ref rocsparse_matrix_type_general,\n \\ref rocsparse_matrix_type_symmetric, \\ref rocsparse_matrix_type_hermitian or\n \\ref rocsparse_matrix_type_triangular.\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or\n \\ref rocsparse_matrix_type_triangular.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p type is invalid."] + pub fn rocsparse_set_mat_type( + descr: rocsparse_mat_descr, + type_: rocsparse_matrix_type, + ) -> rocsparse_status; +} +extern "C" { + #[doc = " \\ingroup aux_module\n \\brief Get the matrix type of a matrix descriptor\n\n \\details\n \\p rocsparse_get_mat_type returns the matrix type of a matrix descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\returns \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or\n \\ref rocsparse_matrix_type_triangular."] + pub fn rocsparse_get_mat_type(descr: rocsparse_mat_descr) -> rocsparse_matrix_type; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify the matrix fill mode of a matrix descriptor\n\n \\details\n \\p rocsparse_set_mat_fill_mode sets the matrix fill mode of a matrix descriptor.\n Valid fill modes are \\ref rocsparse_fill_mode_lower or\n \\ref rocsparse_fill_mode_upper.\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n fill_mode \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p fill_mode is invalid."] + pub fn rocsparse_set_mat_fill_mode( + descr: rocsparse_mat_descr, + fill_mode: rocsparse_fill_mode, + ) -> rocsparse_status; +} +extern "C" { + #[doc = " \\ingroup aux_module\n \\brief Get the matrix fill mode of a matrix descriptor\n\n \\details\n \\p rocsparse_get_mat_fill_mode returns the matrix fill mode of a matrix descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\returns \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper."] + pub fn rocsparse_get_mat_fill_mode(descr: rocsparse_mat_descr) -> rocsparse_fill_mode; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify the matrix diagonal type of a matrix descriptor\n\n \\details\n \\p rocsparse_set_mat_diag_type sets the matrix diagonal type of a matrix\n descriptor. Valid diagonal types are \\ref rocsparse_diag_type_unit or\n \\ref rocsparse_diag_type_non_unit.\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n diag_type \\ref rocsparse_diag_type_unit or \\ref rocsparse_diag_type_non_unit.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p diag_type is invalid."] + pub fn rocsparse_set_mat_diag_type( + descr: rocsparse_mat_descr, + diag_type: rocsparse_diag_type, + ) -> rocsparse_status; +} +extern "C" { + #[doc = " \\ingroup aux_module\n \\brief Get the matrix diagonal type of a matrix descriptor\n\n \\details\n \\p rocsparse_get_mat_diag_type returns the matrix diagonal type of a matrix\n descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\returns \\ref rocsparse_diag_type_unit or \\ref rocsparse_diag_type_non_unit."] + pub fn rocsparse_get_mat_diag_type(descr: rocsparse_mat_descr) -> rocsparse_diag_type; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Specify the matrix storage mode of a matrix descriptor\n\n \\details\n \\p rocsparse_set_mat_storage_mode sets the matrix storage mode of a matrix descriptor.\n Valid fill modes are \\ref rocsparse_storage_mode_sorted or\n \\ref rocsparse_storage_mode_unsorted.\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n storage_mode \\ref rocsparse_storage_mode_sorted or\n \\ref rocsparse_storage_mode_unsorted.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p storage_mode is invalid."] + pub fn rocsparse_set_mat_storage_mode( + descr: rocsparse_mat_descr, + storage_mode: rocsparse_storage_mode, + ) -> rocsparse_status; +} +extern "C" { + #[doc = " \\ingroup aux_module\n \\brief Get the matrix storage mode of a matrix descriptor\n\n \\details\n \\p rocsparse_get_mat_storage_mode returns the matrix storage mode of a matrix descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\returns \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_unsorted."] + pub fn rocsparse_get_mat_storage_mode(descr: rocsparse_mat_descr) -> rocsparse_storage_mode; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a \\p HYB matrix structure\n\n \\details\n \\p rocsparse_create_hyb_mat creates a structure that holds the matrix in \\p HYB\n storage format. It should be destroyed at the end using rocsparse_destroy_hyb_mat().\n\n @param[inout]\n hyb the pointer to the hybrid matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p hyb pointer is invalid."] + pub fn rocsparse_create_hyb_mat(hyb: *mut rocsparse_hyb_mat) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Copy a \\p HYB matrix structure\n\n \\details\n \\p rocsparse_copy_hyb_mat copies a matrix info structure. Both, source and destination\n matrix info structure must be initialized prior to calling \\p rocsparse_copy_hyb_mat.\n\n @param[out]\n dest the pointer to the destination matrix info structure.\n @param[in]\n src the pointer to the source matrix info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p hyb pointer is invalid."] + pub fn rocsparse_copy_hyb_mat( + dest: rocsparse_hyb_mat, + src: rocsparse_hyb_mat, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a \\p HYB matrix structure\n\n \\details\n \\p rocsparse_destroy_hyb_mat destroys a \\p HYB structure.\n\n @param[in]\n hyb the hybrid matrix structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p hyb pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_destroy_hyb_mat(hyb: rocsparse_hyb_mat) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a matrix info structure\n\n \\details\n \\p rocsparse_create_mat_info creates a structure that holds the matrix info data\n that is gathered during the analysis routines available. It should be destroyed\n at the end using rocsparse_destroy_mat_info().\n\n @param[inout]\n info the pointer to the info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid."] + pub fn rocsparse_create_mat_info(info: *mut rocsparse_mat_info) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Copy a matrix info structure\n \\details\n \\p rocsparse_copy_mat_info copies a matrix info structure. Both, source and destination\n matrix info structure must be initialized prior to calling \\p rocsparse_copy_mat_info.\n\n @param[out]\n dest the pointer to the destination matrix info structure.\n @param[in]\n src the pointer to the source matrix info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p src or \\p dest pointer is invalid."] + pub fn rocsparse_copy_mat_info( + dest: rocsparse_mat_info, + src: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a matrix info structure\n\n \\details\n \\p rocsparse_destroy_mat_info destroys a matrix info structure.\n\n @param[in]\n info the info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_destroy_mat_info(info: rocsparse_mat_info) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a color info structure\n\n \\details\n \\p rocsparse_create_color_info creates a structure that holds the color info data\n that is gathered during the analysis routines available. It should be destroyed\n at the end using rocsparse_destroy_color_info().\n\n @param[inout]\n info the pointer to the info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid."] + pub fn rocsparse_create_color_info(info: *mut rocsparse_color_info) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Copy a color info structure\n \\details\n \\p rocsparse_copy_color_info copies a color info structure. Both, source and destination\n color info structure must be initialized prior to calling \\p rocsparse_copy_color_info.\n\n @param[out]\n dest the pointer to the destination color info structure.\n @param[in]\n src the pointer to the source color info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p src or \\p dest pointer is invalid."] + pub fn rocsparse_copy_color_info( + dest: rocsparse_color_info, + src: rocsparse_color_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a color info structure\n\n \\details\n \\p rocsparse_destroy_color_info destroys a color info structure.\n\n @param[in]\n info the info structure.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_destroy_color_info(info: rocsparse_color_info) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse vector descriptor\n \\details\n \\p rocsparse_create_spvec_descr creates a sparse vector descriptor. It should be\n destroyed at the end using rocsparse_destroy_mat_descr().\n\n @param[out]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n size size of the sparse vector.\n @param[in]\n nnz number of non-zeros in sparse vector.\n @param[in]\n indices indices of the sparse vector where non-zeros occur (must be array of length \\p nnz ).\n @param[in]\n values non-zero values in the sparse vector (must be array of length \\p nnz ).\n @param[in]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p indices or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p size or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_spvec_descr( + descr: *mut rocsparse_spvec_descr, + size: i64, + nnz: i64, + indices: *mut ::std::os::raw::c_void, + values: *mut ::std::os::raw::c_void, + idx_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a sparse vector descriptor\n\n \\details\n \\p rocsparse_destroy_spvec_descr destroys a sparse vector descriptor and releases all\n resources used by the descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr is invalid."] + pub fn rocsparse_destroy_spvec_descr(descr: rocsparse_spvec_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse vector descriptor\n \\details\n \\p rocsparse_spvec_get gets the fields of the sparse vector descriptor\n\n @param[in]\n descr the pointer to the sparse vector descriptor.\n @param[out]\n size size of the sparse vector.\n @param[out]\n nnz number of non-zeros in sparse vector.\n @param[out]\n indices indices of the sparse vector where non-zeros occur (must be array of length \\p nnz ).\n @param[out]\n values non-zero values in the sparse vector (must be array of length \\p nnz ).\n @param[out]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p indices or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p size or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_spvec_get( + descr: rocsparse_spvec_descr, + size: *mut i64, + nnz: *mut i64, + indices: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + idx_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the index base stored in the sparse vector descriptor\n\n @param[in]\n descr the pointer to the sparse vector descriptor.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_base is invalid."] + pub fn rocsparse_spvec_get_index_base( + descr: rocsparse_spvec_descr, + idx_base: *mut rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the values array stored in the sparse vector descriptor\n\n @param[in]\n descr the pointer to the sparse vector descriptor.\n @param[out]\n values non-zero values in the sparse vector (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid."] + pub fn rocsparse_spvec_get_values( + descr: rocsparse_spvec_descr, + values: *mut *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the values array in the sparse vector descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n values non-zero values in the sparse vector (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid."] + pub fn rocsparse_spvec_set_values( + descr: rocsparse_spvec_descr, + values: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse COO matrix descriptor\n \\details\n \\p rocsparse_create_coo_descr creates a sparse COO matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse COO matrix descriptor.\n @param[in]\n rows number of rows in the COO matrix.\n @param[in]\n cols number of columns in the COO matrix\n @param[in]\n nnz number of non-zeros in the COO matrix.\n @param[in]\n coo_row_ind row indices of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n coo_col_ind column indices of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n coo_val values of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_row_ind or \\p coo_col_ind or \\p coo_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_coo_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + nnz: i64, + coo_row_ind: *mut ::std::os::raw::c_void, + coo_col_ind: *mut ::std::os::raw::c_void, + coo_val: *mut ::std::os::raw::c_void, + idx_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse COO AoS matrix descriptor\n \\details\n \\p rocsparse_create_coo_aos_descr creates a sparse COO AoS matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse COO AoS matrix descriptor.\n @param[in]\n rows number of rows in the COO AoS matrix.\n @param[in]\n cols number of columns in the COO AoS matrix\n @param[in]\n nnz number of non-zeros in the COO AoS matrix.\n @param[in]\n coo_ind indices of the COO AoS matrix (must be array of length \\p nnz ).\n @param[in]\n coo_val values of the COO AoS matrix (must be array of length \\p nnz ).\n @param[in]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_ind or \\p coo_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_coo_aos_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + nnz: i64, + coo_ind: *mut ::std::os::raw::c_void, + coo_val: *mut ::std::os::raw::c_void, + idx_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse BSR matrix descriptor\n \\details\n \\p rocsparse_create_bsr_descr creates a sparse BSR matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse BSR matrix descriptor.\n @param[in]\n mb number of rows in the BSR matrix.\n @param[in]\n nb number of columns in the BSR matrix\n @param[in]\n nnzb number of non-zeros in the BSR matrix.\n @param[in]\n block_dir direction of the internal block storage.\n @param[in]\n block_dim dimension of the blocks.\n @param[in]\n bsr_row_ptr row offsets of the BSR matrix (must be array of length \\p mb+1 ).\n @param[in]\n bsr_col_ind column indices of the BSR matrix (must be array of length \\p nnzb ).\n @param[in]\n bsr_val values of the BSR matrix (must be array of length \\p nnzb * \\p block_dim * \\p block_dim ).\n @param[in]\n row_ptr_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n col_ind_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p bsr_row_ptr or \\p bsr_col_ind or \\p bsr_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p mb or \\p nb or \\p nnzb \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_value if \\p row_ptr_type or \\p col_ind_type or \\p idx_base or \\p data_type or \\p block_dir is invalid."] + pub fn rocsparse_create_bsr_descr( + descr: *mut rocsparse_spmat_descr, + mb: i64, + nb: i64, + nnzb: i64, + block_dir: rocsparse_direction, + block_dim: i64, + bsr_row_ptr: *mut ::std::os::raw::c_void, + bsr_col_ind: *mut ::std::os::raw::c_void, + bsr_val: *mut ::std::os::raw::c_void, + row_ptr_type: rocsparse_indextype, + col_ind_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse CSR matrix descriptor\n \\details\n \\p rocsparse_create_csr_descr creates a sparse CSR matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse CSR matrix descriptor.\n @param[in]\n rows number of rows in the CSR matrix.\n @param[in]\n cols number of columns in the CSR matrix\n @param[in]\n nnz number of non-zeros in the CSR matrix.\n @param[in]\n csr_row_ptr row offsets of the CSR matrix (must be array of length \\p rows+1 ).\n @param[in]\n csr_col_ind column indices of the CSR matrix (must be array of length \\p nnz ).\n @param[in]\n csr_val values of the CSR matrix (must be array of length \\p nnz ).\n @param[in]\n row_ptr_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n col_ind_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p csr_row_ptr or \\p csr_col_ind or \\p csr_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p row_ptr_type or \\p col_ind_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_csr_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + nnz: i64, + csr_row_ptr: *mut ::std::os::raw::c_void, + csr_col_ind: *mut ::std::os::raw::c_void, + csr_val: *mut ::std::os::raw::c_void, + row_ptr_type: rocsparse_indextype, + col_ind_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse CSC matrix descriptor\n \\details\n \\p rocsparse_create_csc_descr creates a sparse CSC matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse CSC matrix descriptor.\n @param[in]\n rows number of rows in the CSC matrix.\n @param[in]\n cols number of columns in the CSC matrix\n @param[in]\n nnz number of non-zeros in the CSC matrix.\n @param[in]\n csc_col_ptr column offsets of the CSC matrix (must be array of length \\p cols+1 ).\n @param[in]\n csc_row_ind row indices of the CSC matrix (must be array of length \\p nnz ).\n @param[in]\n csc_val values of the CSC matrix (must be array of length \\p nnz ).\n @param[in]\n col_ptr_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n row_ind_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p csc_col_ptr or \\p csc_row_ind or \\p csc_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p col_ptr_type or \\p row_ind_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_csc_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + nnz: i64, + csc_col_ptr: *mut ::std::os::raw::c_void, + csc_row_ind: *mut ::std::os::raw::c_void, + csc_val: *mut ::std::os::raw::c_void, + col_ptr_type: rocsparse_indextype, + row_ind_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse ELL matrix descriptor\n \\details\n \\p rocsparse_create_ell_descr creates a sparse ELL matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse ELL matrix descriptor.\n @param[in]\n rows number of rows in the ELL matrix.\n @param[in]\n cols number of columns in the ELL matrix\n @param[in]\n ell_col_ind column indices of the ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n ell_val values of the ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n ell_width width of the ELL matrix.\n @param[in]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p ell_col_ind or \\p ell_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_ell_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + ell_col_ind: *mut ::std::os::raw::c_void, + ell_val: *mut ::std::os::raw::c_void, + ell_width: i64, + idx_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a sparse blocked ELL matrix descriptor\n \\details\n \\p rocsparse_create_bell_descr creates a sparse blocked ELL matrix descriptor. It should be\n destroyed at the end using \\p rocsparse_destroy_spmat_descr.\n\n @param[out]\n descr the pointer to the sparse blocked ELL matrix descriptor.\n @param[in]\n rows number of rows in the blocked ELL matrix.\n @param[in]\n cols number of columns in the blocked ELL matrix\n @param[in]\n ell_block_dir \\ref rocsparse_direction_row or \\ref rocsparse_direction_column.\n @param[in]\n ell_block_dim block dimension of the sparse blocked ELL matrix.\n @param[in]\n ell_cols column indices of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n ell_col_ind column indices of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n ell_val values of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p ell_cols or \\p ell_col_ind or \\p ell_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_create_bell_descr( + descr: *mut rocsparse_spmat_descr, + rows: i64, + cols: i64, + ell_block_dir: rocsparse_direction, + ell_block_dim: i64, + ell_cols: i64, + ell_col_ind: *mut ::std::os::raw::c_void, + ell_val: *mut ::std::os::raw::c_void, + idx_type: rocsparse_indextype, + idx_base: rocsparse_index_base, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a sparse matrix descriptor\n\n \\details\n \\p rocsparse_destroy_spmat_descr destroys a sparse matrix descriptor and releases all\n resources used by the descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr is invalid."] + pub fn rocsparse_destroy_spmat_descr(descr: rocsparse_spmat_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse COO matrix descriptor\n \\details\n \\p rocsparse_coo_get gets the fields of the sparse COO matrix descriptor\n\n @param[in]\n descr the pointer to the sparse COO matrix descriptor.\n @param[out]\n rows number of rows in the sparse COO matrix.\n @param[out]\n cols number of columns in the sparse COO matrix.\n @param[out]\n nnz number of non-zeros in sparse COO matrix.\n @param[out]\n coo_row_ind row indices of the COO matrix (must be array of length \\p nnz ).\n @param[out]\n coo_col_ind column indices of the COO matrix (must be array of length \\p nnz ).\n @param[out]\n coo_val values of the COO matrix (must be array of length \\p nnz ).\n @param[out]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_row_ind or \\p coo_col_ind or \\p coo_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_coo_get( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + coo_row_ind: *mut *mut ::std::os::raw::c_void, + coo_col_ind: *mut *mut ::std::os::raw::c_void, + coo_val: *mut *mut ::std::os::raw::c_void, + idx_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse COO AoS matrix descriptor\n \\details\n \\p rocsparse_coo_aos_get gets the fields of the sparse COO AoS matrix descriptor\n\n @param[in]\n descr the pointer to the sparse COO AoS matrix descriptor.\n @param[out]\n rows number of rows in the sparse COO AoS matrix.\n @param[out]\n cols number of columns in the sparse COO AoS matrix.\n @param[out]\n nnz number of non-zeros in sparse COO AoS matrix.\n @param[out]\n coo_ind indices of the COO AoS matrix (must be array of length \\p nnz ).\n @param[out]\n coo_val values of the COO AoS matrix (must be array of length \\p nnz ).\n @param[out]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_ind or \\p coo_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_coo_aos_get( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + coo_ind: *mut *mut ::std::os::raw::c_void, + coo_val: *mut *mut ::std::os::raw::c_void, + idx_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse CSR matrix descriptor\n \\details\n \\p rocsparse_csr_get gets the fields of the sparse CSR matrix descriptor\n\n @param[in]\n descr the pointer to the sparse CSR matrix descriptor.\n @param[out]\n rows number of rows in the CSR matrix.\n @param[out]\n cols number of columns in the CSR matrix\n @param[out]\n nnz number of non-zeros in the CSR matrix.\n @param[out]\n csr_row_ptr row offsets of the CSR matrix (must be array of length \\p rows+1 ).\n @param[out]\n csr_col_ind column indices of the CSR matrix (must be array of length \\p nnz ).\n @param[out]\n csr_val values of the CSR matrix (must be array of length \\p nnz ).\n @param[out]\n row_ptr_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n col_ind_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p csr_row_ptr or \\p csr_col_ind or \\p csr_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value if \\p row_ptr_type or \\p col_ind_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_csr_get( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + csr_row_ptr: *mut *mut ::std::os::raw::c_void, + csr_col_ind: *mut *mut ::std::os::raw::c_void, + csr_val: *mut *mut ::std::os::raw::c_void, + row_ptr_type: *mut rocsparse_indextype, + col_ind_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse ELL matrix descriptor\n \\details\n \\p rocsparse_ell_get gets the fields of the sparse ELL matrix descriptor\n\n @param[in]\n descr the pointer to the sparse ELL matrix descriptor.\n @param[out]\n rows number of rows in the ELL matrix.\n @param[out]\n cols number of columns in the ELL matrix\n @param[out]\n ell_col_ind column indices of the ELL matrix (must be array of length \\p rows*ell_width ).\n @param[out]\n ell_val values of the ELL matrix (must be array of length \\p rows*ell_width ).\n @param[out]\n ell_width width of the ELL matrix.\n @param[out]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p ell_col_ind or \\p ell_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_ell_get( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + ell_col_ind: *mut *mut ::std::os::raw::c_void, + ell_val: *mut *mut ::std::os::raw::c_void, + ell_width: *mut i64, + idx_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the sparse blocked ELL matrix descriptor\n \\details\n \\p rocsparse_bell_get gets the fields of the sparse blocked ELL matrix descriptor\n\n @param[in]\n descr the pointer to the sparse blocked ELL matrix descriptor.\n @param[out]\n rows number of rows in the blocked ELL matrix.\n @param[out]\n cols number of columns in the blocked ELL matrix\n @param[out]\n ell_block_dir \\ref rocsparse_direction_row or \\ref rocsparse_direction_column.\n @param[out]\n ell_block_dim block dimension of the sparse blocked ELL matrix.\n @param[out]\n ell_cols column indices of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[out]\n ell_col_ind column indices of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[out]\n ell_val values of the blocked ELL matrix (must be array of length \\p rows*ell_width ).\n @param[out]\n idx_type \\ref rocsparse_indextype_i32 or \\ref rocsparse_indextype_i64.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p ell_cols or \\p ell_col_ind or \\p ell_val is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p ell_block_dim is invalid.\n \\retval rocsparse_status_invalid_value if \\p ell_block_dir or \\p idx_type or \\p idx_base or \\p data_type is invalid."] + pub fn rocsparse_bell_get( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + ell_block_dir: *mut rocsparse_direction, + ell_block_dim: *mut i64, + ell_cols: *mut i64, + ell_col_ind: *mut *mut ::std::os::raw::c_void, + ell_val: *mut *mut ::std::os::raw::c_void, + idx_type: *mut rocsparse_indextype, + idx_base: *mut rocsparse_index_base, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the row indices, column indices and values array in the sparse COO matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n coo_row_ind row indices of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n coo_col_ind column indices of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n coo_val values of the COO matrix (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_row_ind or \\p coo_col_ind or \\p coo_val is invalid."] + pub fn rocsparse_coo_set_pointers( + descr: rocsparse_spmat_descr, + coo_row_ind: *mut ::std::os::raw::c_void, + coo_col_ind: *mut ::std::os::raw::c_void, + coo_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the indices and values array in the sparse COO AoS matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n coo_ind indices of the COO matrix (must be array of length \\p nnz ).\n @param[in]\n coo_val values of the COO matrix (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_ind or \\p coo_val is invalid."] + pub fn rocsparse_coo_aos_set_pointers( + descr: rocsparse_spmat_descr, + coo_ind: *mut ::std::os::raw::c_void, + coo_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the row offsets, column indices and values array in the sparse CSR matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n csr_row_ptr row offsets of the CSR matrix (must be array of length \\p rows+1 ).\n @param[in]\n csr_col_ind column indices of the CSR matrix (must be array of length \\p nnz ).\n @param[in]\n csr_val values of the CSR matrix (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p coo_ind or \\p coo_val is invalid."] + pub fn rocsparse_csr_set_pointers( + descr: rocsparse_spmat_descr, + csr_row_ptr: *mut ::std::os::raw::c_void, + csr_col_ind: *mut ::std::os::raw::c_void, + csr_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the column offsets, row indices and values array in the sparse CSC matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n csc_col_ptr column offsets of the CSC matrix (must be array of length \\p cols+1 ).\n @param[in]\n csc_row_ind row indices of the CSC matrix (must be array of length \\p nnz ).\n @param[in]\n csc_val values of the CSC matrix (must be array of length \\p nnz ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p csc_col_ptr or \\p csc_row_ind or \\p csc_val is invalid."] + pub fn rocsparse_csc_set_pointers( + descr: rocsparse_spmat_descr, + csc_col_ptr: *mut ::std::os::raw::c_void, + csc_row_ind: *mut ::std::os::raw::c_void, + csc_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the column indices and values array in the sparse ELL matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n ell_col_ind column indices of the ELL matrix (must be array of length \\p rows*ell_width ).\n @param[in]\n ell_val values of the ELL matrix (must be array of length \\p rows*ell_width ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p ell_col_ind or \\p ell_val is invalid."] + pub fn rocsparse_ell_set_pointers( + descr: rocsparse_spmat_descr, + ell_col_ind: *mut ::std::os::raw::c_void, + ell_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the row offsets, column indices and values array in the sparse BSR matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse vector descriptor.\n @param[in]\n bsr_row_ptr row offsets of the BSR matrix (must be array of length \\p rows+1 ).\n @param[in]\n bsr_col_ind column indices of the BSR matrix (must be array of length \\p nnzb ).\n @param[in]\n bsr_val values of the BSR matrix (must be array of length \\p nnzb*block_dim*block_dim ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p bsr_row_ptr or \\p bsr_col_ind or \\p bsr_val is invalid."] + pub fn rocsparse_bsr_set_pointers( + descr: rocsparse_spmat_descr, + bsr_row_ptr: *mut ::std::os::raw::c_void, + bsr_col_ind: *mut ::std::os::raw::c_void, + bsr_val: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the number of rows, columns and non-zeros from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[out]\n rows number of rows in the sparse matrix.\n @param[out]\n cols number of columns in the sparse matrix.\n @param[out]\n nnz number of non-zeros in sparse matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p nnz is invalid."] + pub fn rocsparse_spmat_get_size( + descr: rocsparse_spmat_descr, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the sparse matrix format from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[out]\n format \\ref rocsparse_format_coo or \\ref rocsparse_format_coo_aos or\n \\ref rocsparse_format_csr or \\ref rocsparse_format_csc or\n \\ref rocsparse_format_ell\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_value if \\p format is invalid."] + pub fn rocsparse_spmat_get_format( + descr: rocsparse_spmat_descr, + format: *mut rocsparse_format, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the sparse matrix index base from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[out]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_value if \\p idx_base is invalid."] + pub fn rocsparse_spmat_get_index_base( + descr: rocsparse_spmat_descr, + idx_base: *mut rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the values array from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[out]\n values values array of the sparse matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid."] + pub fn rocsparse_spmat_get_values( + descr: rocsparse_spmat_descr, + values: *mut *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the values array in the sparse matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse matrix descriptor.\n @param[in]\n values values array of the sparse matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid."] + pub fn rocsparse_spmat_set_values( + descr: rocsparse_spmat_descr, + values: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the strided batch count from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[out]\n batch_count batch_count of the sparse matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count is invalid."] + pub fn rocsparse_spmat_get_strided_batch( + descr: rocsparse_spmat_descr, + batch_count: *mut ::std::os::raw::c_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the strided batch count in the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[in]\n batch_count batch_count of the sparse matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count is invalid."] + pub fn rocsparse_spmat_set_strided_batch( + descr: rocsparse_spmat_descr, + batch_count: ::std::os::raw::c_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the batch count and batch stride in the sparse COO matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse COO matrix descriptor.\n @param[in]\n batch_count batch_count of the sparse COO matrix.\n @param[in]\n batch_stride batch stride of the sparse COO matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count or \\p batch_stride is invalid."] + pub fn rocsparse_coo_set_strided_batch( + descr: rocsparse_spmat_descr, + batch_count: ::std::os::raw::c_int, + batch_stride: i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the batch count, row offset batch stride and the column indices batch stride in the sparse CSR matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse CSR matrix descriptor.\n @param[in]\n batch_count batch_count of the sparse CSR matrix.\n @param[in]\n offsets_batch_stride row offset batch stride of the sparse CSR matrix.\n @param[in]\n columns_values_batch_stride column indices batch stride of the sparse CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count or \\p offsets_batch_stride or \\p columns_values_batch_stride is invalid."] + pub fn rocsparse_csr_set_strided_batch( + descr: rocsparse_spmat_descr, + batch_count: ::std::os::raw::c_int, + offsets_batch_stride: i64, + columns_values_batch_stride: i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the batch count, column offset batch stride and the row indices batch stride in the sparse CSC matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse CSC matrix descriptor.\n @param[in]\n batch_count batch_count of the sparse CSC matrix.\n @param[in]\n offsets_batch_stride column offset batch stride of the sparse CSC matrix.\n @param[in]\n rows_values_batch_stride row indices batch stride of the sparse CSC matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count or \\p offsets_batch_stride or \\p rows_values_batch_stride is invalid."] + pub fn rocsparse_csc_set_strided_batch( + descr: rocsparse_spmat_descr, + batch_count: ::std::os::raw::c_int, + offsets_batch_stride: i64, + rows_values_batch_stride: i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the requested attribute data from the sparse matrix descriptor\n\n @param[in]\n descr the pointer to the sparse matrix descriptor.\n @param[in]\n attribute \\ref rocsparse_spmat_fill_mode or \\ref rocsparse_spmat_diag_type or\n \\ref rocsparse_spmat_matrix_type or \\ref rocsparse_spmat_storage_mode\n @param[out]\n data attribute data\n @param[in]\n data_size attribute data size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p data is invalid.\n \\retval rocsparse_status_invalid_value if \\p attribute is invalid.\n \\retval rocsparse_status_invalid_size if \\p data_size is invalid."] + pub fn rocsparse_spmat_get_attribute( + descr: rocsparse_spmat_descr, + attribute: rocsparse_spmat_attribute, + data: *mut ::std::os::raw::c_void, + data_size: usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the requested attribute data in the sparse matrix descriptor\n\n @param[inout]\n descr the pointer to the sparse matrix descriptor.\n @param[in]\n attribute \\ref rocsparse_spmat_fill_mode or \\ref rocsparse_spmat_diag_type or\n \\ref rocsparse_spmat_matrix_type or \\ref rocsparse_spmat_storage_mode\n @param[in]\n data attribute data\n @param[in]\n data_size attribute data size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p data is invalid.\n \\retval rocsparse_status_invalid_value if \\p attribute is invalid.\n \\retval rocsparse_status_invalid_size if \\p data_size is invalid."] + pub fn rocsparse_spmat_set_attribute( + descr: rocsparse_spmat_descr, + attribute: rocsparse_spmat_attribute, + data: *const ::std::os::raw::c_void, + data_size: usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a dense vector descriptor\n \\details\n \\p rocsparse_create_dnvec_descr creates a dense vector descriptor. It should be\n destroyed at the end using rocsparse_destroy_dnvec_descr().\n\n @param[out]\n descr the pointer to the dense vector descriptor.\n @param[in]\n size size of the dense vector.\n @param[in]\n values non-zero values in the dense vector (must be array of length \\p size ).\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p size is invalid.\n \\retval rocsparse_status_invalid_value if \\p data_type is invalid."] + pub fn rocsparse_create_dnvec_descr( + descr: *mut rocsparse_dnvec_descr, + size: i64, + values: *mut ::std::os::raw::c_void, + data_type: rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a dense vector descriptor\n\n \\details\n \\p rocsparse_destroy_dnvec_descr destroys a dense vector descriptor and releases all\n resources used by the descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr is invalid."] + pub fn rocsparse_destroy_dnvec_descr(descr: rocsparse_dnvec_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the dense vector descriptor\n \\details\n \\p rocsparse_dnvec_get gets the fields of the dense vector descriptor\n\n @param[in]\n descr the pointer to the dense vector descriptor.\n @param[out]\n size size of the dense vector.\n @param[out]\n values non-zero values in the dense vector (must be array of length \\p size ).\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p size is invalid.\n \\retval rocsparse_status_invalid_value if \\p data_type is invalid."] + pub fn rocsparse_dnvec_get( + descr: rocsparse_dnvec_descr, + size: *mut i64, + values: *mut *mut ::std::os::raw::c_void, + data_type: *mut rocsparse_datatype, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the values array from a dense vector descriptor\n\n @param[in]\n descr the matrix descriptor.\n @param[out]\n values non-zero values in the dense vector (must be array of length \\p size ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr or \\p values is invalid."] + pub fn rocsparse_dnvec_get_values( + descr: rocsparse_dnvec_descr, + values: *mut *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the values array in a dense vector descriptor\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n values non-zero values in the dense vector (must be array of length \\p size ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr or \\p values is invalid."] + pub fn rocsparse_dnvec_set_values( + descr: rocsparse_dnvec_descr, + values: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Create a dense matrix descriptor\n \\details\n \\p rocsparse_create_dnmat_descr creates a dense matrix descriptor. It should be\n destroyed at the end using rocsparse_destroy_dnmat_descr().\n\n @param[out]\n descr the pointer to the dense matrix descriptor.\n @param[in]\n rows number of rows in the dense matrix.\n @param[in]\n cols number of columns in the dense matrix.\n @param[in]\n ld leading dimension of the dense matrix.\n @param[in]\n values non-zero values in the dense vector (must be array of length\n \\p ld*rows if \\p order=rocsparse_order_column or \\p ld*cols if \\p order=rocsparse_order_row ).\n @param[in]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n @param[in]\n order \\ref rocsparse_order_row or \\ref rocsparse_order_column.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p ld is invalid.\n \\retval rocsparse_status_invalid_value if \\p data_type or \\p order is invalid."] + pub fn rocsparse_create_dnmat_descr( + descr: *mut rocsparse_dnmat_descr, + rows: i64, + cols: i64, + ld: i64, + values: *mut ::std::os::raw::c_void, + data_type: rocsparse_datatype, + order: rocsparse_order, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Destroy a dense matrix descriptor\n\n \\details\n \\p rocsparse_destroy_dnmat_descr destroys a dense matrix descriptor and releases all\n resources used by the descriptor.\n\n @param[in]\n descr the matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr is invalid."] + pub fn rocsparse_destroy_dnmat_descr(descr: rocsparse_dnmat_descr) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the fields of the dense matrix descriptor\n\n @param[in]\n descr the pointer to the dense matrix descriptor.\n @param[out]\n rows number of rows in the dense matrix.\n @param[out]\n cols number of columns in the dense matrix.\n @param[out]\n ld leading dimension of the dense matrix.\n @param[out]\n values non-zero values in the dense matrix (must be array of length\n \\p ld*rows if \\p order=rocsparse_order_column or \\p ld*cols if \\p order=rocsparse_order_row ).\n @param[out]\n data_type \\ref rocsparse_datatype_f32_r, \\ref rocsparse_datatype_f64_r,\n \\ref rocsparse_datatype_f32_c or \\ref rocsparse_datatype_f64_c.\n @param[out]\n order \\ref rocsparse_order_row or \\ref rocsparse_order_column.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid.\n \\retval rocsparse_status_invalid_size if \\p rows or \\p cols or \\p ld is invalid.\n \\retval rocsparse_status_invalid_value if \\p data_type or \\p order is invalid."] + pub fn rocsparse_dnmat_get( + descr: rocsparse_dnmat_descr, + rows: *mut i64, + cols: *mut i64, + ld: *mut i64, + values: *mut *mut ::std::os::raw::c_void, + data_type: *mut rocsparse_datatype, + order: *mut rocsparse_order, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the values array from the dense matrix descriptor\n\n @param[in]\n descr the pointer to the dense matrix descriptor.\n @param[out]\n values non-zero values in the dense matrix (must be array of length\n \\p ld*rows if \\p order=rocsparse_order_column or \\p ld*cols if \\p order=rocsparse_order_row ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr or \\p values is invalid."] + pub fn rocsparse_dnmat_get_values( + descr: rocsparse_dnmat_descr, + values: *mut *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the values array in a dense matrix descriptor\n\n @param[inout]\n descr the matrix descriptor.\n @param[in]\n values non-zero values in the dense matrix (must be array of length\n \\p ld*rows if \\p order=rocsparse_order_column or \\p ld*cols if \\p order=rocsparse_order_row ).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer \\p descr or \\p values is invalid."] + pub fn rocsparse_dnmat_set_values( + descr: rocsparse_dnmat_descr, + values: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Get the batch count and batch stride from the dense matrix descriptor\n\n @param[in]\n descr the pointer to the dense matrix descriptor.\n @param[out]\n batch_count the batch count in the dense matrix.\n @param[out]\n batch_stride the batch stride in the dense matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count or \\p batch_stride is invalid."] + pub fn rocsparse_dnmat_get_strided_batch( + descr: rocsparse_dnmat_descr, + batch_count: *mut ::std::os::raw::c_int, + batch_stride: *mut i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup aux_module\n \\brief Set the batch count and batch stride in the dense matrix descriptor\n\n @param[inout]\n descr the pointer to the dense matrix descriptor.\n @param[in]\n batch_count the batch count in the dense matrix.\n @param[in]\n batch_stride the batch stride in the dense matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_pointer if \\p descr is invalid.\n \\retval rocsparse_status_invalid_size if \\p batch_count or \\p batch_stride is invalid."] + pub fn rocsparse_dnmat_set_strided_batch( + descr: rocsparse_dnmat_descr, + batch_count: ::std::os::raw::c_int, + batch_stride: i64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_csr_buffer_size computes the required buffer size needed when calling \\p rocsparse_check_matrix_csr\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_csr(), rocsparse_dcheck_matrix_csr(),\n rocsparse_ccheck_matrix_csr() and rocsparse_zcheck_matrix_csr().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val, \\p csr_row_ptr, \\p csr_col_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_csr checks if the input CSR matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val, \\p csr_row_ptr, \\p csr_col_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_coo_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_coo\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n coo_val array of \\p nnz elements of the sparse COO matrix.\n @param[in]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse\n COO matrix.\n @param[in]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_coo(), rocsparse_dcheck_matrix_coo(),\n rocsparse_ccheck_matrix_coo() and rocsparse_zcheck_matrix_coo().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_val, \\p coo_row_ind, \\p coo_col_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_coo_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const f32, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_coo_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const f64, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_coo_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const rocsparse_float_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_coo_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const rocsparse_double_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_coo checks if the input COO matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse COO matrix.\n @param[in]\n n number of columns of the sparse COO matrix.\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[in]\n coo_val array of \\p nnz elements of the sparse COO matrix.\n @param[in]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse\n COO matrix.\n @param[in]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_val, \\p coo_row_ind, \\p coo_col_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const f32, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const f64, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const rocsparse_float_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_val: *const rocsparse_double_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_gebsr_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_gebsr\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of GEBSR blocks.\n @param[in]\n mb number of block rows of the sparse GEBSR matrix.\n @param[in]\n nb number of block columns of the sparse GEBSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEBSR matrix.\n @param[in]\n row_block_dim row block dimension of the sparse GEBSR matrix.\n @param[in]\n col_block_dim column block dimension of the sparse GEBSR matrix.\n @param[in]\n bsr_val array of \\p nnzb elements of the sparse GEBSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every row of the\n sparse GEBSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the column indices of the sparse\n GEBSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_gebsr(), rocsparse_dcheck_matrix_gebsr(),\n rocsparse_ccheck_matrix_gebsr() and rocsparse_zcheck_matrix_gebsr().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p dir or \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p mb \\p nb \\p nnzb \\p row_block_dim or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val, \\p bsr_row_ptr, \\p bsr_col_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_gebsr checks if the input GEBSR matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of GEBSR blocks.\n @param[in]\n mb number of block rows of the sparse GEBSR matrix.\n @param[in]\n nb number of block columns of the sparse GEBSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEBSR matrix.\n @param[in]\n row_block_dim row block dimension of the sparse GEBSR matrix.\n @param[in]\n col_block_dim column block dimension of the sparse GEBSR matrix.\n @param[in]\n bsr_val array of \\p nnzb elements of the sparse GEBSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every row of the\n sparse GEBSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the column indices of the sparse\n GEBSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p dir or \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p mb \\p nb \\p nnzb \\p row_block_dim or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val, \\p bsr_row_ptr, \\p bsr_col_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_gebsc_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_gebsc\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of GEBSC blocks.\n @param[in]\n mb number of block rows of the sparse GEBSC matrix.\n @param[in]\n nb number of block columns of the sparse GEBSC matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEBSC matrix.\n @param[in]\n row_block_dim row block dimension of the sparse GEBSC matrix.\n @param[in]\n col_block_dim column block dimension of the sparse GEBSC matrix.\n @param[in]\n bsc_val array of \\p nnzb elements of the sparse GEBSC matrix.\n @param[in]\n bsc_col_ptr array of \\p nb+1 elements that point to the start of every column of the\n sparse GEBSC matrix.\n @param[in]\n bsc_row_ind array of \\p nnzb elements containing the row indices of the sparse\n GEBSC matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_gebsc(), rocsparse_dcheck_matrix_gebsc(),\n rocsparse_ccheck_matrix_gebsc() and rocsparse_zcheck_matrix_gebsc().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p dir or \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p mb \\p nb \\p nnzb \\p row_block_dim or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsc_val, \\p bsc_col_ptr, \\p bsc_row_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_gebsc_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const f32, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_gebsc_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const f64, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_gebsc_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const rocsparse_float_complex, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_gebsc_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const rocsparse_double_complex, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_gebsc checks if the input GEBSC matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of GEBSC blocks.\n @param[in]\n mb number of block rows of the sparse GEBSC matrix.\n @param[in]\n nb number of block columns of the sparse GEBSC matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEBSC matrix.\n @param[in]\n row_block_dim row block dimension of the sparse GEBSC matrix.\n @param[in]\n col_block_dim column block dimension of the sparse GEBSC matrix.\n @param[in]\n bsc_val array of \\p nnzb elements of the sparse GEBSC matrix.\n @param[in]\n bsc_col_ptr array of \\p nb+1 elements that point to the start of every column of the\n sparse GEBSC matrix.\n @param[in]\n bsc_row_ind array of \\p nnzb elements containing the row indices of the sparse\n GEBSC matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p dir or \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p mb \\p nb \\p nnzb \\p row_block_dim or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsc_val, \\p bsc_col_ptr, \\p bsc_row_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_gebsc( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const f32, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_gebsc( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const f64, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_gebsc( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const rocsparse_float_complex, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_gebsc( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *const rocsparse_double_complex, + bsc_col_ptr: *const rocsparse_int, + bsc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_csc_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_csc\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSC matrix.\n @param[in]\n n number of columns of the sparse CSC matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSC matrix.\n @param[in]\n csc_val array of \\p nnz elements of the sparse CSC matrix.\n @param[in]\n csc_col_ptr array of \\p m+1 elements that point to the start of every column of the\n sparse CSC matrix.\n @param[in]\n csc_row_ind array of \\p nnz elements containing the row indices of the sparse\n CSC matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_csc(), rocsparse_dcheck_matrix_csc(),\n rocsparse_ccheck_matrix_csc() and rocsparse_zcheck_matrix_csc().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csc_val, \\p csc_col_ptr, \\p csc_row_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_csc_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const f32, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_csc_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const f64, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_csc_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const rocsparse_float_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_csc_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const rocsparse_double_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_csc checks if the input CSC matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSC matrix.\n @param[in]\n n number of columns of the sparse CSC matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSC matrix.\n @param[in]\n csc_val array of \\p nnz elements of the sparse CSC matrix.\n @param[in]\n csc_col_ptr array of \\p m+1 elements that point to the start of every column of the\n sparse CSC matrix.\n @param[in]\n csc_row_ind array of \\p nnz elements containing the row indices of the sparse\n CSC matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csc_val, \\p csc_col_ptr, \\p csc_row_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const f32, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const f64, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const rocsparse_float_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_val: *const rocsparse_double_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_ell_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_ell\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse ELL matrix.\n @param[in]\n n number of columns of the sparse ELL matrix.\n @param[in]\n ell_width number of non-zero elements per row of the sparse ELL matrix.\n @param[in]\n ell_val array that contains the elements of the sparse ELL matrix. Padded\n elements should be zero.\n @param[in]\n ell_col_ind array that contains the column indices of the sparse ELL matrix.\n Padded column indices should be -1.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scheck_matrix_ell(), rocsparse_dcheck_matrix_ell(),\n rocsparse_ccheck_matrix_ell() and rocsparse_zcheck_matrix_ell().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p ell_val, \\p ell_col_ind or \\p buffer_size pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_ell_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const f32, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_ell_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const f64, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_ell_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const rocsparse_float_complex, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_ell_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const rocsparse_double_complex, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_ell checks if the input ELL matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse ELL matrix.\n @param[in]\n n number of columns of the sparse ELL matrix.\n @param[in]\n ell_width number of non-zero elements per row of the sparse ELL matrix.\n @param[in]\n ell_val array that contains the elements of the sparse ELL matrix. Padded\n elements should be zero.\n @param[in]\n ell_col_ind array that contains the column indices of the sparse ELL matrix.\n Padded column indices should be -1.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_size \\p m \\p n or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p ell_val, \\p ell_col_ind, \\p temp_buffer or \\p data_status pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_scheck_matrix_ell( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const f32, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcheck_matrix_ell( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const f64, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccheck_matrix_ell( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const rocsparse_float_complex, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcheck_matrix_ell( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_width: rocsparse_int, + ell_val: *const rocsparse_double_complex, + ell_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_hyb_buffer_size computes the required buffer size needed when\n calling \\p rocsparse_check_matrix_hyb\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n hyb matrix in HYB storage format.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_check_matrix_hyb().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p hyb or \\p buffer_size pointer is invalid."] + pub fn rocsparse_check_matrix_hyb_buffer_size( + handle: rocsparse_handle, + hyb: rocsparse_hyb_mat, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup utility_module\n \\brief Check matrix to see if it is valid.\n\n \\details\n \\p rocsparse_check_matrix_hyb checks if the input HYB matrix is valid.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n hyb matrix in HYB storage format.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n matrix_type \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric,\n \\ref rocsparse_matrix_type_hermitian or \\ref rocsparse_matrix_type_triangular.\n @param[in]\n uplo \\ref rocsparse_fill_mode_lower or \\ref rocsparse_fill_mode_upper.\n @param[in]\n storage \\ref rocsparse_storage_mode_sorted or \\ref rocsparse_storage_mode_sorted.\n @param[out]\n data_status modified to indicate the status of the data\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base or \\p matrix_type or \\p uplo or \\p storage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p hyb or \\p data_status pointer is invalid."] + pub fn rocsparse_check_matrix_hyb( + handle: rocsparse_handle, + hyb: rocsparse_hyb_mat, + idx_base: rocsparse_index_base, + matrix_type: rocsparse_matrix_type, + uplo: rocsparse_fill_mode, + storage: rocsparse_storage_mode, + data_status: *mut rocsparse_data_status, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Scale a sparse vector and add it to a dense vector.\n\n \\details\n \\p rocsparse_axpyi multiplies the sparse vector \\f$x\\f$ with scalar \\f$\\alpha\\f$ and\n adds the result to the dense vector \\f$y\\f$, such that\n\n \\f[\n y := y + \\alpha \\cdot x\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n y[x_ind[i]] = y[x_ind[i]] + alpha * x_val[i];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of vector \\f$x\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n x_val array of \\p nnz elements containing the values of \\f$x\\f$.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[inout]\n y array of values in dense format.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p x_val, \\p x_ind or \\p y pointer\n is invalid.\n/\n/**@{"] + pub fn rocsparse_saxpyi( + handle: rocsparse_handle, + nnz: rocsparse_int, + alpha: *const f32, + x_val: *const f32, + x_ind: *const rocsparse_int, + y: *mut f32, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_daxpyi( + handle: rocsparse_handle, + nnz: rocsparse_int, + alpha: *const f64, + x_val: *const f64, + x_ind: *const rocsparse_int, + y: *mut f64, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_caxpyi( + handle: rocsparse_handle, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + x_val: *const rocsparse_float_complex, + x_ind: *const rocsparse_int, + y: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zaxpyi( + handle: rocsparse_handle, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + x_val: *const rocsparse_double_complex, + x_ind: *const rocsparse_int, + y: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Compute the dot product of a sparse vector with a dense vector.\n\n \\details\n \\p rocsparse_doti computes the dot product of the sparse vector \\f$x\\f$ with the\n dense vector \\f$y\\f$, such that\n \\f[\n \\text{result} := y^T x\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n result += x_val[i] * y[x_ind[i]];\n }\n \\endcode\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of vector \\f$x\\f$.\n @param[in]\n x_val array of \\p nnz values.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[in]\n y array of values in dense format.\n @param[out]\n result pointer to the result, can be host or device memory\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p x_val, \\p x_ind, \\p y or \\p result\n pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the dot product reduction\n could not be allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sdoti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const f32, + x_ind: *const rocsparse_int, + y: *const f32, + result: *mut f32, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ddoti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const f64, + x_ind: *const rocsparse_int, + y: *const f64, + result: *mut f64, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cdoti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_float_complex, + x_ind: *const rocsparse_int, + y: *const rocsparse_float_complex, + result: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zdoti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_double_complex, + x_ind: *const rocsparse_int, + y: *const rocsparse_double_complex, + result: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Compute the dot product of a complex conjugate sparse vector with a dense\n vector.\n\n \\details\n \\p rocsparse_dotci computes the dot product of the complex conjugate sparse vector\n \\f$x\\f$ with the dense vector \\f$y\\f$, such that\n \\f[\n \\text{result} := \\bar{x}^H y\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n result += conj(x_val[i]) * y[x_ind[i]];\n }\n \\endcode\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of vector \\f$x\\f$.\n @param[in]\n x_val array of \\p nnz values.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[in]\n y array of values in dense format.\n @param[out]\n result pointer to the result, can be host or device memory\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p x_val, \\p x_ind, \\p y or \\p result\n pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the dot product reduction\n could not be allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_cdotci( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_float_complex, + x_ind: *const rocsparse_int, + y: *const rocsparse_float_complex, + result: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zdotci( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_double_complex, + x_ind: *const rocsparse_int, + y: *const rocsparse_double_complex, + result: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Gather elements from a dense vector and store them into a sparse vector.\n\n \\details\n \\p rocsparse_gthr gathers the elements that are listed in \\p x_ind from the dense\n vector \\f$y\\f$ and stores them in the sparse vector \\f$x\\f$.\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n x_val[i] = y[x_ind[i]];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of \\f$x\\f$.\n @param[in]\n y array of values in dense format.\n @param[out]\n x_val array of \\p nnz elements containing the values of \\f$x\\f$.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p y, \\p x_val or \\p x_ind pointer is\n invalid.\n/\n/**@{"] + pub fn rocsparse_sgthr( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *const f32, + x_val: *mut f32, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgthr( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *const f64, + x_val: *mut f64, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgthr( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *const rocsparse_float_complex, + x_val: *mut rocsparse_float_complex, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgthr( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *const rocsparse_double_complex, + x_val: *mut rocsparse_double_complex, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Gather and zero out elements from a dense vector and store them into a sparse\n vector.\n\n \\details\n \\p rocsparse_gthrz gathers the elements that are listed in \\p x_ind from the dense\n vector \\f$y\\f$ and stores them in the sparse vector \\f$x\\f$. The gathered elements\n in \\f$y\\f$ are replaced by zero.\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n x_val[i] = y[x_ind[i]];\n y[x_ind[i]] = 0;\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of \\f$x\\f$.\n @param[inout]\n y array of values in dense format.\n @param[out]\n x_val array of \\p nnz elements containing the non-zero values of \\f$x\\f$.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p y, \\p x_val or \\p x_ind pointer is\n invalid.\n/\n/**@{"] + pub fn rocsparse_sgthrz( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *mut f32, + x_val: *mut f32, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgthrz( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *mut f64, + x_val: *mut f64, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgthrz( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *mut rocsparse_float_complex, + x_val: *mut rocsparse_float_complex, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgthrz( + handle: rocsparse_handle, + nnz: rocsparse_int, + y: *mut rocsparse_double_complex, + x_val: *mut rocsparse_double_complex, + x_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Apply Givens rotation to a dense and a sparse vector.\n\n \\details\n \\p rocsparse_roti applies the Givens rotation matrix \\f$G\\f$ to the sparse vector\n \\f$x\\f$ and the dense vector \\f$y\\f$, where\n \\f[\n G = \\begin{pmatrix} c & s \\\\ -s & c \\end{pmatrix}\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n x_tmp = x_val[i];\n y_tmp = y[x_ind[i]];\n\n x_val[i] = c * x_tmp + s * y_tmp;\n y[x_ind[i]] = c * y_tmp - s * x_tmp;\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of \\f$x\\f$.\n @param[inout]\n x_val array of \\p nnz elements containing the non-zero values of \\f$x\\f$.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of \\f$x\\f$.\n @param[inout]\n y array of values in dense format.\n @param[in]\n c pointer to the cosine element of \\f$G\\f$, can be on host or device.\n @param[in]\n s pointer to the sine element of \\f$G\\f$, can be on host or device.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p c, \\p s, \\p x_val, \\p x_ind or \\p y\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sroti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *mut f32, + x_ind: *const rocsparse_int, + y: *mut f32, + c: *const f32, + s: *const f32, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_droti( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *mut f64, + x_ind: *const rocsparse_int, + y: *mut f64, + c: *const f64, + s: *const f64, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level1_module\n \\brief Scatter elements from a dense vector across a sparse vector.\n\n \\details\n \\p rocsparse_sctr scatters the elements that are listed in \\p x_ind from the sparse\n vector \\f$x\\f$ into the dense vector \\f$y\\f$. Indices of \\f$y\\f$ that are not listed\n in \\p x_ind remain unchanged.\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n y[x_ind[i]] = x_val[i];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n nnz number of non-zero entries of \\f$x\\f$.\n @param[in]\n x_val array of \\p nnz elements containing the non-zero values of \\f$x\\f$.\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the non-zero\n values of x.\n @param[inout]\n y array of values in dense format.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p idx_base is invalid.\n \\retval rocsparse_status_invalid_size \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p x_val, \\p x_ind or \\p y pointer is\n invalid.\n/\n/**@{"] + pub fn rocsparse_ssctr( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const f32, + x_ind: *const rocsparse_int, + y: *mut f32, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dsctr( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const f64, + x_ind: *const rocsparse_int, + y: *mut f64, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_csctr( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_float_complex, + x_ind: *const rocsparse_int, + y: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zsctr( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_double_complex, + x_ind: *const rocsparse_int, + y: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_isctr( + handle: rocsparse_handle, + nnz: rocsparse_int, + x_val: *const rocsparse_int, + x_ind: *const rocsparse_int, + y: *mut rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrmv_ex_analysis performs the analysis step for rocsparse_sbsrmv(),\n rocsparse_dbsrmv(), rocsparse_cbsrmv() and rocsparse_zbsrmv(). It is expected that\n this function will be executed only once for a given matrix and particular operation\n type. The gathered analysis meta data can be cleared by rocsparse_bsrmv_ex_clear().\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nb number of block columns of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb or \\p nnzb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind or \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the gathered information\n could not be allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrmv_ex_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrmv_ex_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrmv_ex_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrmv_ex_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrmv_ex multiplies the scalar \\f$\\alpha\\f$ with a sparse\n \\f$(mb \\cdot \\text{block_dim}) \\times (nb \\cdot \\text{block_dim})\\f$\n matrix, defined in BSR storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nb number of block columns of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n x array of \\p nb*block_dim elements (\\f$op(A) = A\\f$) or \\p mb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p mb*block_dim elements (\\f$op(A) = A\\f$) or \\p nb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[out]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p nnzb or \\p block_dim is\n invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ind, \\p bsr_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrmv_ex( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrmv_ex( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrmv_ex( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrmv_ex( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrmv multiplies the scalar \\f$\\alpha\\f$ with a sparse\n \\f$(mb \\cdot \\text{block_dim}) \\times (nb \\cdot \\text{block_dim})\\f$\n matrix, defined in BSR storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nb number of block columns of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n x array of \\p nb*block_dim elements (\\f$op(A) = A\\f$) or \\p mb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p mb*block_dim elements (\\f$op(A) = A\\f$) or \\p nb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p nnzb or \\p block_dim is\n invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ind, \\p bsr_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication with mask operation using BSR storage format\n\n \\details\n \\p rocsparse_bsrxmv multiplies the scalar \\f$\\alpha\\f$ with a sparse\n \\f$(mb \\cdot \\text{block_dim}) \\times (nb \\cdot \\text{block_dim})\\f$\n modified matrix, defined in BSR storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\left( \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y \\right)\\left( \\text{mask} \\right),\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n The \\f$\\text{mask}\\f$ is defined as an array of block row indices.\n The input sparse matrix is defined with a modified BSR storage format where the beginning and the end of each row\n is defined with two arrays, \\p bsr_row_ptr and \\p bsr_end_ptr (both of size \\p mb), rather the usual \\p bsr_row_ptr of size \\p mb+1.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none is supported.\n Currently, \\p block_dim==1 is not supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n size_of_mask number of updated block rows of the array \\p y.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nb number of block columns of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n\n @param[in]\n bsr_mask_ptr array of \\p size_of_mask elements that give the indices of the updated block rows.\n\n @param[in]\n bsr_row_ptr array of \\p mb elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_end_ptr array of \\p mb elements that point to the end of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n x array of \\p nb*block_dim elements (\\f$op(A) = A\\f$) or \\p mb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p mb*block_dim elements (\\f$op(A) = A\\f$) or \\p nb*block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p nnzb, \\p block_dim or \\p size_of_mask is\n invalid.\n \\retval rocsparse_status_invalid_value \\p size_of_mask is greater than \\p mb.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ind, \\p bsr_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p block_dim==1, \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrxmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + size_of_mask: rocsparse_int, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_mask_ptr: *const rocsparse_int, + bsr_row_ptr: *const rocsparse_int, + bsr_end_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrxmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + size_of_mask: rocsparse_int, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_mask_ptr: *const rocsparse_int, + bsr_row_ptr: *const rocsparse_int, + bsr_end_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrxmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + size_of_mask: rocsparse_int, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_mask_ptr: *const rocsparse_int, + bsr_row_ptr: *const rocsparse_int, + bsr_end_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrxmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + size_of_mask: rocsparse_int, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_mask_ptr: *const rocsparse_int, + bsr_row_ptr: *const rocsparse_int, + bsr_end_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsv_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_sbsrsv_solve(),\n rocsparse_dbsrsv_solve(), rocsparse_cbsrsv_solve() or rocsparse_zbsrsv_solve()\n computation. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position,\n using same index base as the BSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_bsrsv_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_bsrsv_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsv_buffer_size returns the size of the temporary storage buffer that\n is required by rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(),\n rocsparse_cbsrsv_analysis(), rocsparse_zbsrsv_analysis(), rocsparse_sbsrsv_solve(),\n rocsparse_dbsrsv_solve(), rocsparse_cbsrsv_solve() and rocsparse_zbsrsv_solve(). The\n temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnz containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(),\n rocsparse_cbsrsv_analysis(), rocsparse_zbsrsv_analysis(),\n rocsparse_sbsrsv_solve(), rocsparse_dbsrsv_solve(),\n rocsparse_cbsrsv_solve() and rocsparse_zbsrsv_solve().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrsv_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsv_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsv_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsv_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsv_analysis performs the analysis step for rocsparse_sbsrsv_solve(),\n rocsparse_dbsrsv_solve(), rocsparse_cbsrsv_solve() and rocsparse_zbsrsv_solve(). It\n is expected that this function will be executed only once for a given matrix and\n particular operation type. The analysis meta data can be cleared by\n rocsparse_bsrsv_clear().\n\n \\p rocsparse_bsrsv_analysis can share its meta data with\n rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(),\n rocsparse_cbsrsm_analysis(), rocsparse_zbsrsm_analysis(),\n rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(),\n rocsparse_cbsrilu0_analysis(), rocsparse_zbsrilu0_analysis(),\n rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(),\n rocsparse_cbsric0_analysis() and rocsparse_zbsric0_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnz containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrsv_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsv_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsv_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsv_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrmv_ex_clear deallocates all memory that was allocated by\n rocsparse_sbsrmv_ex_analysis(), rocsparse_dbsrmv_ex_analysis(), rocsparse_cbsrmv_ex_analysis()\n or rocsparse_zbsrmv_ex_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required anymore for further computation, e.g. when\n switching to another sparse matrix format.\n\n \\note\n Calling \\p rocsparse_bsrmv_ex_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the gathered information\n could not be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_bsrmv_ex_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsv_clear deallocates all memory that was allocated by\n rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(), rocsparse_cbsrsv_analysis()\n or rocsparse_zbsrsv_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation, e.g. when switching to\n another sparse matrix format. Calling \\p rocsparse_bsrsv_clear is optional. All\n allocated resources will be cleared, when the opaque \\ref rocsparse_mat_info struct\n is destroyed using rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_bsrsv_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsv_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in BSR storage format, a dense solution vector\n \\f$y\\f$ and the right-hand side \\f$x\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot y = \\alpha \\cdot x,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_bsrsv_solve requires a user allocated temporary buffer. Its size is\n returned by rocsparse_sbsrsv_buffer_size(), rocsparse_dbsrsv_buffer_size(),\n rocsparse_cbsrsv_buffer_size() or rocsparse_zbsrsv_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_sbsrsv_analysis(),\n rocsparse_dbsrsv_analysis(), rocsparse_cbsrsv_analysis() or\n rocsparse_zbsrsv_analysis(). \\p rocsparse_bsrsv_solve reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be checked calling\n rocsparse_bsrsv_zero_pivot(). If\n \\ref rocsparse_diag_type == \\ref rocsparse_diag_type_unit, no zero pivot will be\n reported, even if \\f$A_{j,j} = 0\\f$ for some \\f$j\\f$.\n\n \\note\n The sparse BSR matrix has to be sorted.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none and\n \\p trans == \\ref rocsparse_operation_transpose is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnz containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n x array of \\p m elements, holding the right-hand side.\n @param[out]\n y array of \\p m elements, holding the solution.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p x or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the lower triangular \\f$m \\times m\\f$ matrix \\f$L\\f$, stored in BSR\n storage format with unit diagonal. The following example solves \\f$L \\cdot y = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor\n rocsparse_mat_descr descr;\n rocsparse_create_mat_descr(&descr);\n rocsparse_set_mat_fill_mode(descr, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr, rocsparse_diag_type_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size;\n rocsparse_dbsrsv_buffer_size(handle,\n rocsparse_direction_column,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis step\n rocsparse_dbsrsv_analysis(handle,\n rocsparse_direction_column,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve Ly = x\n rocsparse_dbsrsv_solve(handle,\n rocsparse_direction_column,\n rocsparse_operation_none,\n mb,\n nnzb,\n &alpha,\n descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n x,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // No zero pivot should be found, with L having unit diagonal\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsrsv_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const f32, + y: *mut f32, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsv_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const f64, + y: *mut f64, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsv_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsv_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using COO storage format\n\n \\details\n \\p rocsparse_coomv multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix, defined in COO storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n The COO matrix has to be sorted by row indices. This can be achieved by using\n rocsparse_coosort_by_row().\n\n \\code{.c}\n for(i = 0; i < m; ++i)\n {\n y[i] = beta * y[i];\n }\n\n for(i = 0; i < nnz; ++i)\n {\n y[coo_row_ind[i]] += alpha * coo_val[i] * x[coo_col_ind[i]];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse COO matrix.\n @param[in]\n n number of columns of the sparse COO matrix.\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse COO matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n coo_val array of \\p nnz elements of the sparse COO matrix.\n @param[in]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse COO\n matrix.\n @param[in]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[in]\n x array of \\p n elements (\\f$op(A) = A\\f$) or \\p m elements\n (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p m elements (\\f$op(A) = A\\f$) or \\p n elements\n (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p coo_val,\n \\p coo_row_ind, \\p coo_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scoomv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + coo_val: *const f32, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcoomv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + coo_val: *const f64, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccoomv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + coo_val: *const rocsparse_float_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcoomv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + coo_val: *const rocsparse_double_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrmv_analysis performs the analysis step for rocsparse_scsrmv(),\n rocsparse_dcsrmv(), rocsparse_ccsrmv() and rocsparse_zcsrmv(). It is expected that\n this function will be executed only once for a given matrix and particular operation\n type. The gathered analysis meta data can be cleared by rocsparse_csrmv_clear().\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind or \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the gathered information\n could not be allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented if \\ref rocsparse_matrix_type is not one of\n \\ref rocsparse_matrix_type_general, \\ref rocsparse_matrix_type_symmetric, or\n \\ref rocsparse_matrix_type_triangular.\n/\n/**@{"] + pub fn rocsparse_scsrmv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrmv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrmv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrmv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrmv_clear deallocates all memory that was allocated by\n rocsparse_scsrmv_analysis(), rocsparse_dcsrmv_analysis(), rocsparse_ccsrmv_analysis()\n or rocsparse_zcsrmv_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required anymore for further computation, e.g. when\n switching to another sparse matrix format.\n\n \\note\n Calling \\p rocsparse_csrmv_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the gathered information\n could not be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csrmv_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrmv multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix, defined in CSR storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n The \\p info parameter is optional and contains information collected by\n rocsparse_scsrmv_analysis(), rocsparse_dcsrmv_analysis(), rocsparse_ccsrmv_analysis()\n or rocsparse_zcsrmv_analysis(). If present, the information will be used to speed up\n the \\p csrmv computation. If \\p info == \\p NULL, general \\p csrmv routine will be\n used instead.\n\n \\code{.c}\n for(i = 0; i < m; ++i)\n {\n y[i] = beta * y[i];\n\n for(j = csr_row_ptr[i]; j < csr_row_ptr[i + 1]; ++j)\n {\n y[i] = y[i] + alpha * csr_val[j] * x[csr_col_ind[j]];\n }\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n info information collected by rocsparse_scsrmv_analysis(),\n rocsparse_dcsrmv_analysis(), rocsparse_ccsrmv_analysis() or\n rocsparse_dcsrmv_analysis(), can be \\p NULL if no information is\n available.\n @param[in]\n x array of \\p n elements (\\f$op(A) == A\\f$) or \\p m elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p m elements (\\f$op(A) == A\\f$) or \\p n elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p x, \\p beta or \\p y pointer is\n invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example performs a sparse matrix vector multiplication in CSR format\n using additional meta data to improve performance.\n \\code{.c}\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Perform analysis step to obtain meta data\n rocsparse_scsrmv_analysis(handle,\n rocsparse_operation_none,\n m,\n n,\n nnz,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info);\n\n // Compute y = Ax\n rocsparse_scsrmv(handle,\n rocsparse_operation_none,\n m,\n n,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n x,\n &beta,\n y);\n\n // Do more work\n // ...\n\n // Clean up\n rocsparse_destroy_mat_info(info);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsv_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_scsrsv_solve(),\n rocsparse_dcsrsv_solve(), rocsparse_ccsrsv_solve() or rocsparse_zcsrsv_solve()\n computation. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position,\n using same index base as the CSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_csrsv_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_csrsv_zero_pivot( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse iterative triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csritsv_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_csritsv_solve() and or rocsparse_csritsv_analysis(),\n execution. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position,\n using same index base as the CSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_csritsv_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_csritsv_zero_pivot( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsv_buffer_size returns the size of the temporary storage buffer that\n is required by rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(),\n rocsparse_ccsrsv_analysis(), rocsparse_zcsrsv_analysis(), rocsparse_scsrsv_solve(),\n rocsparse_dcsrsv_solve(), rocsparse_ccsrsv_solve() and rocsparse_zcsrsv_solve(). The\n temporary storage buffer must be allocated by the user. The size of the temporary\n storage buffer is identical to the size returned by rocsparse_scsrilu0_buffer_size(),\n rocsparse_dcsrilu0_buffer_size(), rocsparse_ccsrilu0_buffer_size() and\n rocsparse_zcsrilu0_buffer_size() if the matrix sparsity pattern is identical. The\n user allocated buffer can thus be shared between subsequent calls to those functions.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(),\n rocsparse_ccsrsv_analysis(), rocsparse_zcsrsv_analysis(),\n rocsparse_scsrsv_solve(), rocsparse_dcsrsv_solve(),\n rocsparse_ccsrsv_solve() and rocsparse_zcsrsv_solve().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse iterative triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csritsv_buffer_size returns the size of the temporary storage buffer that\n is required by rocsparse_scsritsv_analysis(), rocsparse_dcsritsv_analysis(),\n rocsparse_ccsritsv_analysis(), rocsparse_zcsritsv_analysis(), rocsparse_scsritsv_solve(),\n rocsparse_dcsritsv_solve(), rocsparse_ccsritsv_solve() and rocsparse_zcsritsv_solve(). The\n temporary storage buffer must be allocated by the user.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsritsv_analysis(), rocsparse_dcsritsv_analysis(),\n rocsparse_ccsritsv_analysis(), rocsparse_zcsritsv_analysis(),\n rocsparse_scsritsv_solve(), rocsparse_dcsritsv_solve(),\n rocsparse_ccsritsv_solve() and rocsparse_zcsritsv_solve().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general and \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_triangular.\n/\n/**@{"] + pub fn rocsparse_scsritsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsritsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsritsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsritsv_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsv_analysis performs the analysis step for rocsparse_scsrsv_solve(),\n rocsparse_dcsrsv_solve(), rocsparse_ccsrsv_solve() and rocsparse_zcsrsv_solve(). It\n is expected that this function will be executed only once for a given matrix and\n particular operation type. The analysis meta data can be cleared by\n rocsparse_csrsv_clear().\n\n \\p rocsparse_csrsv_analysis can share its meta data with\n rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(),\n rocsparse_ccsrsm_analysis(), rocsparse_zcsrsm_analysis(),\n rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis(), rocsparse_zcsrilu0_analysis(),\n rocsparse_scsric0_analysis(), rocsparse_dcsric0_analysis(),\n rocsparse_ccsric0_analysis() and rocsparse_zcsric0_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse iterative triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csritsv_analysis performs the analysis step for rocsparse_scsritsv_solve(),\n rocsparse_dcsritsv_solve(), rocsparse_ccsritsv_solve() and rocsparse_zcsritsv_solve(). It\n is expected that this function will be executed only once for a given matrix and\n particular operation type. The analysis meta data can be cleared by\n rocsparse_csritsv_clear().\n\n Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general and \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_triangular.\n/\n/**@{"] + pub fn rocsparse_scsritsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsritsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsritsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsritsv_analysis( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsv_clear deallocates all memory that was allocated by\n rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(), rocsparse_ccsrsv_analysis()\n or rocsparse_zcsrsv_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation, e.g. when switching to\n another sparse matrix format. Calling \\p rocsparse_csrsv_clear is optional. All\n allocated resources will be cleared, when the opaque \\ref rocsparse_mat_info struct\n is destroyed using rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csrsv_clear( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csritsv_clear deallocates all memory that was allocated by\n rocsparse_scsritsv_analysis(), rocsparse_dcsritsv_analysis(), rocsparse_ccsritsv_analysis()\n or rocsparse_zcsritsv_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation, e.g. when switching to\n another sparse matrix format. Calling \\p rocsparse_csritsv_clear is optional. All\n allocated resources will be cleared, when the opaque \\ref rocsparse_mat_info struct\n is destroyed using rocsparse_destroy_mat_info().\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csritsv_clear( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsv_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR storage format, a dense solution vector\n \\f$y\\f$ and the right-hand side \\f$x\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot y = \\alpha \\cdot x,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_csrsv_solve requires a user allocated temporary buffer. Its size is\n returned by rocsparse_scsrsv_buffer_size(), rocsparse_dcsrsv_buffer_size(),\n rocsparse_ccsrsv_buffer_size() or rocsparse_zcsrsv_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_scsrsv_analysis(),\n rocsparse_dcsrsv_analysis(), rocsparse_ccsrsv_analysis() or\n rocsparse_zcsrsv_analysis(). \\p rocsparse_csrsv_solve reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be checked calling\n rocsparse_csrsv_zero_pivot(). If\n \\ref rocsparse_diag_type == \\ref rocsparse_diag_type_unit, no zero pivot will be\n reported, even if \\f$A_{j,j} = 0\\f$ for some \\f$j\\f$.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none and\n \\p trans == \\ref rocsparse_operation_transpose is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n x array of \\p m elements, holding the right-hand side.\n @param[out]\n y array of \\p m elements, holding the solution.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p x or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the lower triangular \\f$m \\times m\\f$ matrix \\f$L\\f$, stored in CSR\n storage format with unit diagonal. The following example solves \\f$L \\cdot y = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor\n rocsparse_mat_descr descr;\n rocsparse_create_mat_descr(&descr);\n rocsparse_set_mat_fill_mode(descr, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr, rocsparse_diag_type_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size;\n rocsparse_dcsrsv_buffer_size(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis step\n rocsparse_dcsrsv_analysis(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve Ly = x\n rocsparse_dcsrsv_solve(handle,\n rocsparse_operation_none,\n m,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n x,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // No zero pivot should be found, with L having unit diagonal\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrsv_solve( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const f32, + y: *mut f32, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsv_solve( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const f64, + y: *mut f64, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsv_solve( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsv_solve( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse iterative triangular solve using CSR storage format\n\n \\details\n \\p rocsparse_csritsv_solve solves iteratively with the use of the Jacobi method a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR storage format, a dense solution vector\n \\f$y\\f$ and the right-hand side \\f$x\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot y = \\alpha \\cdot x,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_csritsv_solve requires a user allocated temporary buffer. Its size is\n returned by rocsparse_scsritsv_buffer_size(), rocsparse_dcsritsv_buffer_size(),\n rocsparse_ccsritsv_buffer_size() or rocsparse_zcsritsv_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_scsritsv_analysis(),\n rocsparse_dcsritsv_analysis(), rocsparse_ccsritsv_analysis() or\n rocsparse_zcsritsv_analysis(). \\p rocsparse_csritsv_solve reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be checked calling\n rocsparse_csritsv_zero_pivot(). If\n \\ref rocsparse_diag_type == \\ref rocsparse_diag_type_unit, no zero pivot will be\n reported, even if \\f$A_{j,j} = 0\\f$ for some \\f$j\\f$.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n host_nmaxiter maximum number of iteration on input and maximum number of iteration on output.\n @param[in]\n host_tol if the pointer is null then loop will execute \\p nmaxiter[0] iterations.\n @param[out]\n host_history (optional, record history)\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n x array of \\p m elements, holding the right-hand side.\n @param[out]\n y array of \\p m elements, holding the solution.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p x or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general and \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_triangular.\n\n \\par Example\n Consider the lower triangular \\f$m \\times m\\f$ matrix \\f$L\\f$, stored in CSR\n storage format with unit diagonal. The following example solves \\f$L \\cdot y = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor\n rocsparse_mat_descr descr;\n rocsparse_create_mat_descr(&descr);\n rocsparse_set_mat_fill_mode(descr, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr, rocsparse_diag_type_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size;\n rocsparse_dcsritsv_buffer_size(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis step\n rocsparse_dcsritsv_analysis(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve Ly = x\n rocsparse_int nmaxiter = 200;\n rocsparse_int maxiter = nmaxiter;\n tol = 1.0e-4;\n history[200];\n rocsparse_dcsritsv_solve(handle,\n &maxiter,\n &tol,\n history,\n rocsparse_operation_none,\n m,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n x,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n if (maxiter < nmaxiter) {} // convergence\n else {} // non converged\n for (int i=0;i rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsritsv_solve( + handle: rocsparse_handle, + host_nmaxiter: *mut rocsparse_int, + host_tol: *const f64, + host_history: *mut f64, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const f64, + y: *mut f64, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsritsv_solve( + handle: rocsparse_handle, + host_nmaxiter: *mut rocsparse_int, + host_tol: *const f32, + host_history: *mut f32, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsritsv_solve( + handle: rocsparse_handle, + host_nmaxiter: *mut rocsparse_int, + host_tol: *const f64, + host_history: *mut f64, + trans: rocsparse_operation, + m: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + x: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using ELL storage format\n\n \\details\n \\p rocsparse_ellmv multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix, defined in ELL storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\code{.c}\n for(i = 0; i < m; ++i)\n {\n y[i] = beta * y[i];\n\n for(p = 0; p < ell_width; ++p)\n {\n idx = p * m + i;\n\n if((ell_col_ind[idx] >= 0) && (ell_col_ind[idx] < n))\n {\n y[i] = y[i] + alpha * ell_val[idx] * x[ell_col_ind[idx]];\n }\n }\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the sparse ELL matrix.\n @param[in]\n n number of columns of the sparse ELL matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse ELL matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n ell_val array that contains the elements of the sparse ELL matrix. Padded\n elements should be zero.\n @param[in]\n ell_col_ind array that contains the column indices of the sparse ELL matrix.\n Padded column indices should be -1.\n @param[in]\n ell_width number of non-zero elements per row of the sparse ELL matrix.\n @param[in]\n x array of \\p n elements (\\f$op(A) == A\\f$) or \\p m elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p m elements (\\f$op(A) == A\\f$) or \\p n elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p ell_val,\n \\p ell_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sellmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + ell_val: *const f32, + ell_col_ind: *const rocsparse_int, + ell_width: rocsparse_int, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dellmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + ell_val: *const f64, + ell_col_ind: *const rocsparse_int, + ell_width: rocsparse_int, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cellmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + ell_val: *const rocsparse_float_complex, + ell_col_ind: *const rocsparse_int, + ell_width: rocsparse_int, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zellmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + ell_val: *const rocsparse_double_complex, + ell_col_ind: *const rocsparse_int, + ell_width: rocsparse_int, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using HYB storage format\n\n \\details\n \\p rocsparse_hybmv multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix, defined in HYB storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse HYB matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n hyb matrix in HYB storage format.\n @param[in]\n x array of \\p n elements (\\f$op(A) == A\\f$) or \\p m elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p m elements (\\f$op(A) == A\\f$) or \\p n elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p hyb structure was not initialized with\n valid matrix sizes.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p hyb, \\p x,\n \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_invalid_value \\p hyb structure was not initialized\n with a valid partitioning type.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_memory_error the buffer could not be allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_shybmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const f32, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dhybmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const f64, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_chybmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zhybmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Sparse matrix vector multiplication using GEBSR storage format\n\n \\details\n \\p rocsparse_gebsrmv multiplies the scalar \\f$\\alpha\\f$ with a sparse\n \\f$(mb \\cdot \\text{row_block_dim}) \\times (nb \\cdot \\text{col_block_dim})\\f$\n matrix, defined in GEBSR storage format, and the dense vector \\f$x\\f$ and adds the\n result to the dense vector \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$,\n such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of GEBSR blocks.\n @param[in]\n trans matrix operation type.\n @param[in]\n mb number of block rows of the sparse GEBSR matrix.\n @param[in]\n nb number of block columns of the sparse GEBSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEBSR matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse GEBSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse GEBSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse GEBSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnz containing the block column indices of the sparse\n GEBSR matrix.\n @param[in]\n row_block_dim row block dimension of the sparse GEBSR matrix.\n @param[in]\n col_block_dim column block dimension of the sparse GEBSR matrix.\n @param[in]\n x array of \\p nb*col_block_dim elements (\\f$op(A) = A\\f$) or \\p mb*row_block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p mb*row_block_dim elements (\\f$op(A) = A\\f$) or \\p nb*col_block_dim\n elements (\\f$op(A) = A^T\\f$ or \\f$op(A) = A^H\\f$).\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p nnzb, \\p row_block_dim\n or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ind, \\p bsr_col_ind, \\p x, \\p beta or \\p y pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sgebsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + x: *const f32, + beta: *const f32, + y: *mut f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + x: *const f64, + beta: *const f64, + y: *mut f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + x: *const rocsparse_float_complex, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsrmv( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + x: *const rocsparse_double_complex, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Dense matrix sparse vector multiplication\n\n \\details\n \\p rocsparse_gemvi_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_sgemvi(), rocsparse_dgemvi(), rocsparse_cgemvi() or\n rocsparse_zgemvi(). The temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the dense matrix.\n @param[in]\n n number of columns of the dense matrix.\n @param[in]\n nnz number of non-zero entries in the sparse vector.\n @param[out]\n buffer_size temporary storage buffer size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sgemvi_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgemvi_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgemvi_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgemvi_buffer_size( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level2_module\n \\brief Dense matrix sparse vector multiplication\n\n \\details\n \\p rocsparse_gemvi multiplies the scalar \\f$\\alpha\\f$ with a dense \\f$m \\times n\\f$\n matrix \\f$A\\f$ and the sparse vector \\f$x\\f$ and adds the result to the dense vector\n \\f$y\\f$ that is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_gemvi requires a user allocated temporary buffer. Its size is returned\n by rocsparse_sgemvi_buffer_size(), rocsparse_dgemvi_buffer_size(),\n rocsparse_cgemvi_buffer_size() or rocsparse_zgemvi_buffer_size().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n m number of rows of the dense matrix.\n @param[in]\n n number of columns of the dense matrix.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A pointer to the dense matrix.\n @param[in]\n lda leading dimension of the dense matrix\n @param[in]\n nnz number of non-zero entries in the sparse vector\n @param[in]\n x_val array of \\p nnz elements containing the values of the sparse vector\n @param[in]\n x_ind array of \\p nnz elements containing the indices of the sparse vector\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y array of \\p m elements (\\f$op(A) == A\\f$) or \\p n elements\n (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n @param[in]\n idx_base rocsparse_index_base_zero or rocsparse_index_base_one.\n @param[in]\n temp_buffer temporary storage buffer\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p lda or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p A, \\p x_val, \\p x_ind,\n \\p beta, \\p y or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sgemvi( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f32, + A: *const f32, + lda: rocsparse_int, + nnz: rocsparse_int, + x_val: *const f32, + x_ind: *const rocsparse_int, + beta: *const f32, + y: *mut f32, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgemvi( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f64, + A: *const f64, + lda: rocsparse_int, + nnz: rocsparse_int, + x_val: *const f64, + x_ind: *const rocsparse_int, + beta: *const f64, + y: *mut f64, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgemvi( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_float_complex, + A: *const rocsparse_float_complex, + lda: rocsparse_int, + nnz: rocsparse_int, + x_val: *const rocsparse_float_complex, + x_ind: *const rocsparse_int, + beta: *const rocsparse_float_complex, + y: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgemvi( + handle: rocsparse_handle, + trans: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_double_complex, + A: *const rocsparse_double_complex, + lda: rocsparse_int, + nnz: rocsparse_int, + x_val: *const rocsparse_double_complex, + x_ind: *const rocsparse_int, + beta: *const rocsparse_double_complex, + y: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse matrix dense matrix multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrmm multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$mb \\times kb\\f$\n matrix \\f$A\\f$, defined in BSR storage format, and the dense \\f$k \\times n\\f$\n matrix \\f$B\\f$ (where \\f$k = block\\_dim \\times kb\\f$) and adds the result to the dense\n \\f$m \\times n\\f$ matrix \\f$C\\f$ (where \\f$m = block\\_dim \\times mb\\f$) that\n is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot C,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks. Can be \\ref rocsparse_direction_row or \\ref rocsparse_direction_column.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type. Currently, only \\ref rocsparse_operation_none is supported.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type. Currently, only \\ref rocsparse_operation_none and rocsparse_operation_transpose\n are supported.\n @param[in]\n mb number of block rows of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n n number of columns of the dense matrix \\f$op(B)\\f$ and \\f$C\\f$.\n @param[in]\n kb number of block columns of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix \\f$A\\f$. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb*block_dim*block_dim elements of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix \\f$A\\f$.\n @param[in]\n block_dim size of the blocks in the sparse BSR matrix.\n @param[in]\n B array of dimension \\f$ldb \\times n\\f$ (\\f$op(B) == B\\f$),\n \\f$ldb \\times k\\f$ otherwise.\n @param[in]\n ldb leading dimension of \\f$B\\f$, must be at least \\f$\\max{(1, k)}\\f$ (\\f$ op(B) == B\\f$) where \\f$k = block\\_dim \\times kb\\f$,\n \\f$\\max{(1, n)}\\f$ otherwise.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C array of dimension \\f$ldc \\times n\\f$.\n @param[in]\n ldc leading dimension of \\f$C\\f$, must be at least \\f$\\max{(1, m)}\\f$ (\\f$ op(A) == A\\f$) where \\f$m = block\\_dim \\times mb\\f$,\n \\f$\\max{(1, k)}\\f$ where \\f$k = block\\_dim \\times kb\\f$ otherwise.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p n, \\p kb, \\p nnzb, \\p ldb or \\p ldc\n is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p B, \\p beta or \\p C pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none or\n \\p trans_B == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies a BSR matrix with a dense matrix.\n \\code{.c}\n // 1 2 0 3 0 0\n // A = 0 4 5 0 0 0\n // 0 0 0 7 8 0\n // 0 0 1 2 4 1\n\n rocsparse_int block_dim = 2;\n rocsparse_int mb = 2;\n rocsparse_int kb = 3;\n rocsparse_int nnzb = 4;\n rocsparse_direction dir = rocsparse_direction_row;\n\n bsr_row_ptr[mb+1] = {0, 2, 4}; // device memory\n bsr_col_ind[nnzb] = {0, 1, 1, 2}; // device memory\n bsr_val[nnzb*block_dim*block_dim] = {1, 2, 0, 4, 0, 3, 5, 0, 0, 7, 1, 2, 8, 0, 4, 1}; // device memory\n\n // Set dimension n of B\n rocsparse_int n = 64;\n rocsparse_int m = mb * block_dim;\n rocsparse_int k = kb * block_dim;\n\n // Allocate and generate dense matrix B\n std::vector hB(k * n);\n for(rocsparse_int i = 0; i < k * n; ++i)\n {\n hB[i] = static_cast(rand()) / RAND_MAX;\n }\n\n // Copy B to the device\n float* B;\n hipMalloc((void**)&B, sizeof(float) * k * n);\n hipMemcpy(B, hB.data(), sizeof(float) * k * n, hipMemcpyHostToDevice);\n\n // alpha and beta\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Allocate memory for the resulting matrix C\n float* C;\n hipMalloc((void**)&C, sizeof(float) * m * n);\n\n // Perform the matrix multiplication\n rocsparse_sbsrmm(handle,\n dir,\n rocsparse_operation_none,\n rocsparse_operation_none,\n mb,\n n,\n kb,\n nnzb,\n &alpha,\n descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n B,\n k,\n &beta,\n C,\n m);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + B: *const f32, + ldb: rocsparse_int, + beta: *const f32, + C: *mut f32, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + B: *const f64, + ldb: rocsparse_int, + beta: *const f64, + C: *mut f64, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + beta: *const rocsparse_float_complex, + C: *mut rocsparse_float_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + beta: *const rocsparse_double_complex, + C: *mut rocsparse_double_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse matrix dense matrix multiplication using GEneral BSR storage format\n\n \\details\n \\p rocsparse_gebsrmm multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$mb \\times kb\\f$\n matrix \\f$A\\f$, defined in GEneral BSR storage format, and the dense \\f$k \\times n\\f$\n matrix \\f$B\\f$ (where \\f$k = col_block\\_dim \\times kb\\f$) and adds the result to the dense\n \\f$m \\times n\\f$ matrix \\f$C\\f$ (where \\f$m = row_block\\_dim \\times mb\\f$) that\n is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot C,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks. Can be \\ref rocsparse_direction_row or \\ref rocsparse_direction_column.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type. Currently, only \\ref rocsparse_operation_none is supported.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type. Currently, only \\ref rocsparse_operation_none and rocsparse_operation_transpose\n are supported.\n @param[in]\n mb number of block rows of the sparse GEneral BSR matrix \\f$A\\f$.\n @param[in]\n n number of columns of the dense matrix \\f$op(B)\\f$ and \\f$C\\f$.\n @param[in]\n kb number of block columns of the sparse GEneral BSR matrix \\f$A\\f$.\n @param[in]\n nnzb number of non-zero blocks of the sparse GEneral BSR matrix \\f$A\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse GEneral BSR matrix \\f$A\\f$. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb*row_block_dim*col_block_dim elements of the sparse GEneral BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse GEneral BSR matrix \\f$A\\f$.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n GEneral BSR matrix \\f$A\\f$.\n @param[in]\n row_block_dim row size of the blocks in the sparse GEneral BSR matrix.\n @param[in]\n col_block_dim column size of the blocks in the sparse GEneral BSR matrix.\n @param[in]\n B array of dimension \\f$ldb \\times n\\f$ (\\f$op(B) == B\\f$),\n \\f$ldb \\times k\\f$ otherwise.\n @param[in]\n ldb leading dimension of \\f$B\\f$, must be at least \\f$\\max{(1, k)}\\f$ (\\f$ op(B) == B\\f$) where \\f$k = col\\_block\\_dim \\times kb\\f$,\n \\f$\\max{(1, n)}\\f$ otherwise.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C array of dimension \\f$ldc \\times n\\f$.\n @param[in]\n ldc leading dimension of \\f$C\\f$, must be at least \\f$\\max{(1, m)}\\f$ (\\f$ op(A) == A\\f$) where \\f$m = row\\_block\\_dim \\times mb\\f$,\n \\f$\\max{(1, k)}\\f$ where \\f$k = col\\_block\\_dim \\times kb\\f$ otherwise.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p n, \\p kb, \\p nnzb, \\p ldb, \\p ldc, \\p row_block_dim\n or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p B, \\p beta or \\p C pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none or\n \\p trans_B == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies a GEneral BSR matrix with a dense matrix.\n \\code{.c}\n // 1 2 0 3 0 0\n // A = 0 4 5 0 0 0\n // 0 0 0 7 8 0\n // 0 0 1 2 4 1\n\n rocsparse_int row_block_dim = 2;\n rocsparse_int col_block_dim = 3;\n rocsparse_int mb = 2;\n rocsparse_int kb = 2;\n rocsparse_int nnzb = 4;\n rocsparse_direction dir = rocsparse_direction_row;\n\n bsr_row_ptr[mb+1] = {0, 2, 4}; // device memory\n bsr_col_ind[nnzb] = {0, 1, 0, 1}; // device memory\n bsr_val[nnzb*row_block_dim*col_block_dim] = {1, 2, 0, 0, 4, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 8, 0, 2, 4, 1}; // device memory\n\n // Set dimension n of B\n rocsparse_int n = 64;\n rocsparse_int m = mb * row_block_dim;\n rocsparse_int k = kb * col_block_dim;\n\n // Allocate and generate dense matrix B\n std::vector hB(k * n);\n for(rocsparse_int i = 0; i < k * n; ++i)\n {\n hB[i] = static_cast(rand()) / RAND_MAX;\n }\n\n // Copy B to the device\n float* B;\n hipMalloc((void**)&B, sizeof(float) * k * n);\n hipMemcpy(B, hB.data(), sizeof(float) * k * n, hipMemcpyHostToDevice);\n\n // alpha and beta\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Allocate memory for the resulting matrix C\n float* C;\n hipMalloc((void**)&C, sizeof(float) * m * n);\n\n // Perform the matrix multiplication\n rocsparse_sgebsrmm(handle,\n dir,\n rocsparse_operation_none,\n rocsparse_operation_none,\n mb,\n n,\n kb,\n nnzb,\n &alpha,\n descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n row_block_dim,\n col_block_dim,\n B,\n k,\n &beta,\n C,\n m);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sgebsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + B: *const f32, + ldb: rocsparse_int, + beta: *const f32, + C: *mut f32, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + B: *const f64, + ldb: rocsparse_int, + beta: *const f64, + C: *mut f64, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + beta: *const rocsparse_float_complex, + C: *mut rocsparse_float_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsrmm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + n: rocsparse_int, + kb: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + beta: *const rocsparse_double_complex, + C: *mut rocsparse_double_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse matrix dense matrix multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrmm multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times k\\f$\n matrix \\f$A\\f$, defined in CSR storage format, and the dense \\f$k \\times n\\f$\n matrix \\f$B\\f$ and adds the result to the dense \\f$m \\times n\\f$ matrix \\f$C\\f$ that\n is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot C,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\code{.c}\n for(i = 0; i < ldc; ++i)\n {\n for(j = 0; j < n; ++j)\n {\n C[i][j] = beta * C[i][j];\n\n for(k = csr_row_ptr[i]; k < csr_row_ptr[i + 1]; ++k)\n {\n C[i][j] += alpha * csr_val[k] * B[csr_col_ind[k]][j];\n }\n }\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n n number of columns of the dense matrix \\f$op(B)\\f$ and \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix \\f$A\\f$. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix \\f$A\\f$.\n @param[in]\n B array of dimension \\f$ldb \\times n\\f$ (\\f$op(B) == B\\f$),\n \\f$ldb \\times k\\f$ otherwise.\n @param[in]\n ldb leading dimension of \\f$B\\f$, must be at least \\f$\\max{(1, k)}\\f$\n (\\f$op(B) == B\\f$), \\f$\\max{(1, n)}\\f$ otherwise.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C array of dimension \\f$ldc \\times n\\f$.\n @param[in]\n ldc leading dimension of \\f$C\\f$, must be at least \\f$\\max{(1, m)}\\f$\n (\\f$op(A) == A\\f$), \\f$\\max{(1, k)}\\f$ otherwise.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz, \\p ldb or \\p ldc\n is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p alpha, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p B, \\p beta or \\p C pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies a CSR matrix with a dense matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m = 3;\n rocsparse_int k = 5;\n rocsparse_int nnz = 8;\n\n csr_row_ptr[m+1] = {0, 3, 5, 8}; // device memory\n csr_col_ind[nnz] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n csr_val[nnz] = {1, 2, 3, 4, 5, 6, 7, 8}; // device memory\n\n // Set dimension n of B\n rocsparse_int n = 64;\n\n // Allocate and generate dense matrix B\n std::vector hB(k * n);\n for(rocsparse_int i = 0; i < k * n; ++i)\n {\n hB[i] = static_cast(rand()) / RAND_MAX;\n }\n\n // Copy B to the device\n float* B;\n hipMalloc((void**)&B, sizeof(float) * k * n);\n hipMemcpy(B, hB.data(), sizeof(float) * k * n, hipMemcpyHostToDevice);\n\n // alpha and beta\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Allocate memory for the resulting matrix C\n float* C;\n hipMalloc((void**)&C, sizeof(float) * m * n);\n\n // Perform the matrix multiplication\n rocsparse_scsrmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n B,\n k,\n &beta,\n C,\n m);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrmm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f32, + ldb: rocsparse_int, + beta: *const f32, + C: *mut f32, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrmm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f64, + ldb: rocsparse_int, + beta: *const f64, + C: *mut f64, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrmm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + beta: *const rocsparse_float_complex, + C: *mut rocsparse_float_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrmm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + beta: *const rocsparse_double_complex, + C: *mut rocsparse_double_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsm_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_scsrsm_solve(),\n rocsparse_dcsrsm_solve(), rocsparse_ccsrsm_solve() or rocsparse_zcsrsm_solve()\n computation. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position,\n using same index base as the CSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_csrsm_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_csrsm_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsm_buffer_size returns the size of the temporary storage buffer that\n is required by rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(),\n rocsparse_ccsrsm_analysis(), rocsparse_zcsrsm_analysis(), rocsparse_scsrsm_solve(),\n rocsparse_dcsrsm_solve(), rocsparse_ccsrsm_solve() and rocsparse_zcsrsm_solve(). The\n temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_B matrix B operation type.\n @param[in]\n m number of rows of the sparse CSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(B).\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix A.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix A.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix A.\n @param[in]\n B array of \\p m \\f$\\times\\f$ \\p nrhs elements of the rhs matrix B.\n @param[in]\n ldb leading dimension of rhs matrix B.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(),\n rocsparse_ccsrsm_analysis(), rocsparse_zcsrsm_analysis(),\n rocsparse_scsrsm_solve(), rocsparse_dcsrsm_solve(),\n rocsparse_ccsrsm_solve() and rocsparse_zcsrsm_solve().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p nrhs or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p B, \\p info or \\p buffer_size pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_B == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrsm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f32, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f64, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsm_analysis performs the analysis step for rocsparse_scsrsm_solve(),\n rocsparse_dcsrsm_solve(), rocsparse_ccsrsm_solve() and rocsparse_zcsrsm_solve(). It\n is expected that this function will be executed only once for a given matrix and\n particular operation type. The analysis meta data can be cleared by\n rocsparse_csrsm_clear().\n\n \\p rocsparse_csrsm_analysis can share its meta data with\n rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis(), rocsparse_zcsrilu0_analysis(),\n rocsparse_scsric0_analysis(), rocsparse_dcsric0_analysis(),\n rocsparse_ccsric0_analysis(), rocsparse_zcsric0_analysis(),\n rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(),\n rocsparse_ccsrsv_analysis() and rocsparse_zcsrsv_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_B matrix B operation type.\n @param[in]\n m number of rows of the sparse CSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(B).\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix A.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix A.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix A.\n @param[in]\n B array of \\p m \\f$\\times\\f$ \\p nrhs elements of the rhs matrix B.\n @param[in]\n ldb leading dimension of rhs matrix B.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p nrhs or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p B, \\p info or \\p temp_buffer pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_B == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrsm_analysis( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f32, + ldb: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsm_analysis( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const f64, + ldb: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsm_analysis( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsm_analysis( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsm_clear deallocates all memory that was allocated by\n rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(), rocsparse_ccsrsm_analysis()\n or rocsparse_zcsrsm_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation, e.g. when switching to\n another sparse matrix format. Calling \\p rocsparse_csrsm_clear is optional. All\n allocated resources will be cleared, when the opaque \\ref rocsparse_mat_info struct\n is destroyed using rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csrsm_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using CSR storage format\n\n \\details\n \\p rocsparse_csrsm_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR storage format, a dense solution matrix\n \\f$X\\f$ and the right-hand side matrix \\f$B\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot op(X) = \\alpha \\cdot op(B),\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n ,\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(X) = \\left\\{\n \\begin{array}{ll}\n X, & \\text{if trans_B == rocsparse_operation_none} \\\\\n X^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n X^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_csrsm_solve requires a user allocated temporary buffer. Its size is\n returned by rocsparse_scsrsm_buffer_size(), rocsparse_dcsrsm_buffer_size(),\n rocsparse_ccsrsm_buffer_size() or rocsparse_zcsrsm_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_scsrsm_analysis(),\n rocsparse_dcsrsm_analysis(), rocsparse_ccsrsm_analysis() or\n rocsparse_zcsrsm_analysis(). \\p rocsparse_csrsm_solve reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be checked calling\n rocsparse_csrsm_zero_pivot(). If\n \\ref rocsparse_diag_type == \\ref rocsparse_diag_type_unit, no zero pivot will be\n reported, even if \\f$A_{j,j} = 0\\f$ for some \\f$j\\f$.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans_A != \\ref rocsparse_operation_conjugate_transpose and\n \\p trans_B != \\ref rocsparse_operation_conjugate_transpose is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_B matrix B operation type.\n @param[in]\n m number of rows of the sparse CSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(B).\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix A.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse CSR matrix A.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix A.\n @param[inout]\n B array of \\p m \\f$\\times\\f$ \\p nrhs elements of the rhs matrix B.\n @param[in]\n ldb leading dimension of rhs matrix B.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p nrhs or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p B, \\p info or \\p temp_buffer pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_B == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the lower triangular \\f$m \\times m\\f$ matrix \\f$L\\f$, stored in CSR\n storage format with unit diagonal. The following example solves \\f$L \\cdot X = B\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor\n rocsparse_mat_descr descr;\n rocsparse_create_mat_descr(&descr);\n rocsparse_set_mat_fill_mode(descr, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr, rocsparse_diag_type_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size;\n rocsparse_dcsrsm_buffer_size(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n nrhs,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n B,\n ldb,\n info,\n rocsparse_solve_policy_auto,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis step\n rocsparse_dcsrsm_analysis(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n nrhs,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n B,\n ldb,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve LX = B\n rocsparse_dcsrsm_solve(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n nrhs,\n nnz,\n &alpha,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n B,\n ldb,\n info,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // No zero pivot should be found, with L having unit diagonal\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrsm_solve( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *mut f32, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrsm_solve( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *mut f64, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrsm_solve( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *mut rocsparse_float_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrsm_solve( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + nrhs: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + B: *mut rocsparse_double_complex, + ldb: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsm_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_sbsrsm_solve(),\n rocsparse_dbsrsm_solve(), rocsparse_cbsrsm_solve() or rocsparse_zbsrsm_solve()\n computation. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position,\n using same index base as the BSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_bsrsm_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_bsrsm_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsm_buffer_size returns the size of the temporary storage buffer that\n is required by rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(),\n rocsparse_cbsrsm_analysis(), rocsparse_zbsrsm_analysis(), rocsparse_sbsrsm_solve(),\n rocsparse_dbsrsm_solve(), rocsparse_cbsrsm_solve() and rocsparse_zbsrsm_solve(). The\n temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_X matrix X operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(X).\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix A.\n @param[in]\n descr descriptor of the sparse BSR matrix A.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(),\n rocsparse_cbsrsm_analysis(), rocsparse_zbsrsm_analysis(),\n rocsparse_sbsrsm_solve(), rocsparse_dbsrsm_solve(),\n rocsparse_cbsrsm_solve() and rocsparse_zbsrsm_solve().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nrhs, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p info or \\p buffer_size pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_X == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrsm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsm_analysis performs the analysis step for rocsparse_sbsrsm_solve(),\n rocsparse_dbsrsm_solve(), rocsparse_cbsrsm_solve() and rocsparse_zbsrsm_solve(). It\n is expected that this function will be executed only once for a given matrix and\n particular operation type. The analysis meta data can be cleared by\n rocsparse_bsrsm_clear().\n\n \\p rocsparse_bsrsm_analysis can share its meta data with\n rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(),\n rocsparse_cbsrilu0_analysis(), rocsparse_zbsrilu0_analysis(),\n rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(),\n rocsparse_cbsric0_analysis(), rocsparse_zbsric0_analysis(),\n rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(),\n rocsparse_cbsrsv_analysis() and rocsparse_zbsrsv_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_X matrix X operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(X).\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix A.\n @param[in]\n descr descriptor of the sparse BSR matrix A.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix A.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix A.\n @param[in]\n bsr_col_ind array of \\p nnzb containing the block column indices of the sparse\n BSR matrix A.\n @param[in]\n block_dim block dimension of the sparse BSR matrix A.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nrhs, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_X == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrsm_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsm_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsm_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsm_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsm_clear deallocates all memory that was allocated by\n rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(), rocsparse_cbsrsm_analysis()\n or rocsparse_zbsrsm_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation, e.g. when switching to\n another sparse matrix format. Calling \\p rocsparse_bsrsm_clear is optional. All\n allocated resources will be cleared, when the opaque \\ref rocsparse_mat_info struct\n is destroyed using rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_bsrsm_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Sparse triangular system solve using BSR storage format\n\n \\details\n \\p rocsparse_bsrsm_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in BSR storage format, a dense solution matrix\n \\f$X\\f$ and the right-hand side matrix \\f$B\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot op(X) = \\alpha \\cdot op(B),\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n ,\n \\f[\n op(X) = \\left\\{\n \\begin{array}{ll}\n X, & \\text{if trans_X == rocsparse_operation_none} \\\\\n X^T, & \\text{if trans_X == rocsparse_operation_transpose} \\\\\n X^H, & \\text{if trans_X == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\p rocsparse_bsrsm_solve requires a user allocated temporary buffer. Its size is\n returned by rocsparse_sbsrsm_buffer_size(), rocsparse_dbsrsm_buffer_size(),\n rocsparse_cbsrsm_buffer_size() or rocsparse_zbsrsm_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_sbsrsm_analysis(),\n rocsparse_dbsrsm_analysis(), rocsparse_cbsrsm_analysis() or\n rocsparse_zbsrsm_analysis(). \\p rocsparse_bsrsm_solve reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be checked calling\n rocsparse_bsrsm_zero_pivot(). If\n \\ref rocsparse_diag_type == \\ref rocsparse_diag_type_unit, no zero pivot will be\n reported, even if \\f$A_{j,j} = 0\\f$ for some \\f$j\\f$.\n\n \\note\n The sparse BSR matrix has to be sorted.\n\n \\note\n Operation type of B and X must match, if \\f$op(B)=B, op(X)=X\\f$.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n Currently, only \\p trans_A != \\ref rocsparse_operation_conjugate_transpose and\n \\p trans_X != \\ref rocsparse_operation_conjugate_transpose is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir matrix storage of BSR blocks.\n @param[in]\n trans_A matrix A operation type.\n @param[in]\n trans_X matrix X operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix A.\n @param[in]\n nrhs number of columns of the dense matrix op(X).\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix A.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr descriptor of the sparse BSR matrix A.\n @param[in]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb containing the block column indices of the sparse\n BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n B rhs matrix B with leading dimension \\p ldb.\n @param[in]\n ldb leading dimension of rhs matrix B.\n @param[out]\n X solution matrix X with leading dimension \\p ldx.\n @param[in]\n ldx leading dimension of solution matrix X.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nrhs, \\p nnzb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr, \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p B, \\p X \\p info or \\p temp_buffer pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans_A == \\ref rocsparse_operation_conjugate_transpose,\n \\p trans_X == \\ref rocsparse_operation_conjugate_transpose or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrsm_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f32, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + B: *const f32, + ldb: rocsparse_int, + X: *mut f32, + ldx: rocsparse_int, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrsm_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const f64, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + B: *const f64, + ldb: rocsparse_int, + X: *mut f64, + ldx: rocsparse_int, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrsm_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + X: *mut rocsparse_float_complex, + ldx: rocsparse_int, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrsm_solve( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_X: rocsparse_operation, + mb: rocsparse_int, + nrhs: rocsparse_int, + nnzb: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + X: *mut rocsparse_double_complex, + ldx: rocsparse_int, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup level3_module\n \\brief Dense matrix sparse matrix multiplication using CSR storage format\n\n \\details\n \\p rocsparse_gemmi multiplies the scalar \\f$\\alpha\\f$ with a dense \\f$m \\times k\\f$\n matrix \\f$A\\f$ and the sparse \\f$k \\times n\\f$ matrix \\f$B\\f$, defined in CSR\n storage format and adds the result to the dense \\f$m \\times n\\f$ matrix \\f$C\\f$ that\n is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot C\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the dense matrix \\f$A\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and \\f$C\\f$.\n @param[in]\n k number of columns of the dense matrix \\f$A\\f$.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A array of dimension \\f$lda \\times k\\f$ (\\f$op(A) == A\\f$) or\n \\f$lda \\times m\\f$ (\\f$op(A) == A^T\\f$ or \\f$op(A) == A^H\\f$).\n @param[in]\n lda leading dimension of \\f$A\\f$, must be at least \\f$m\\f$\n (\\f$op(A) == A\\f$) or \\f$k\\f$ (\\f$op(A) == A^T\\f$ or\n \\f$op(A) == A^H\\f$).\n @param[in]\n descr descriptor of the sparse CSR matrix \\f$B\\f$. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse CSR\n matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C array of dimension \\f$ldc \\times n\\f$ that holds the values of \\f$C\\f$.\n @param[in]\n ldc leading dimension of \\f$C\\f$, must be at least \\f$m\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz, \\p lda or \\p ldc\n is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p A, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p beta or \\p C pointer is invalid.\n\n \\par Example\n This example multiplies a dense matrix with a CSC matrix.\n \\code{.c}\n rocsparse_int m = 2;\n rocsparse_int n = 5;\n rocsparse_int k = 3;\n rocsparse_int nnz = 8;\n rocsparse_int lda = m;\n rocsparse_int ldc = m;\n\n // Matrix A (m x k)\n // ( 9.0 10.0 11.0 )\n // ( 12.0 13.0 14.0 )\n\n // Matrix B (k x n)\n // ( 1.0 2.0 0.0 3.0 0.0 )\n // ( 0.0 4.0 5.0 0.0 0.0 )\n // ( 6.0 0.0 0.0 7.0 8.0 )\n\n // Matrix C (m x n)\n // ( 15.0 16.0 17.0 18.0 19.0 )\n // ( 20.0 21.0 22.0 23.0 24.0 )\n\n A[lda * k] = {9.0, 12.0, 10.0, 13.0, 11.0, 14.0}; // device memory\n csc_col_ptr_B[n + 1] = {0, 2, 4, 5, 7, 8}; // device memory\n csc_row_ind_B[nnz] = {0, 0, 1, 1, 2, 3, 3, 4}; // device memory\n csc_val_B[nnz] = {1.0, 6.0, 2.0, 4.0, 5.0, 3.0, 7.0, 8.0}; // device memory\n C[ldc * n] = {15.0, 20.0, 16.0, 21.0, 17.0, 22.0, // device memory\n 18.0, 23.0, 19.0, 24.0};\n\n // alpha and beta\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Perform the matrix multiplication\n rocsparse_sgemmi(handle,\n rocsparse_operation_none,\n rocsparse_operation_transpose,\n m,\n n,\n k,\n nnz,\n &alpha,\n A,\n lda,\n descr_B,\n csc_val_B,\n csc_col_ptr_B,\n csc_row_ind_B,\n &beta,\n C,\n ldc);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sgemmi( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f32, + A: *const f32, + lda: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + beta: *const f32, + C: *mut f32, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgemmi( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const f64, + A: *const f64, + lda: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + beta: *const f64, + C: *mut f64, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgemmi( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_float_complex, + A: *const rocsparse_float_complex, + lda: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + beta: *const rocsparse_float_complex, + C: *mut rocsparse_float_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgemmi( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + nnz: rocsparse_int, + alpha: *const rocsparse_double_complex, + A: *const rocsparse_double_complex, + lda: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + beta: *const rocsparse_double_complex, + C: *mut rocsparse_double_complex, + ldc: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix addition using BSR storage format\n\n \\details\n \\p rocsparse_bsrgeam_nnz computes the total BSR non-zero elements and the BSR row\n offsets, that point to the start of every row of the sparse BSR matrix, of the\n resulting matrix C. It is assumed that \\p bsr_row_ptr_C has been allocated with\n size \\p mb+1.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row in the BSR matrices \\f$A\\f$, \\f$B\\f$, and \\f$C\\f$.\n @param[in]\n mb number of block rows in the sparse BSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n nb number of block columns of the sparse BSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n block_dim the block dimension of the BSR matrix \\f$A\\f$. Between 1 and m where \\p m=mb*block_dim.\n @param[in]\n descr_A descriptor of the sparse BSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_A number of non-zero block entries of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_col_ind_A array of \\p nnzb_A elements containing the column indices of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse BSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_B number of non-zero block entries of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_row_ptr_B array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_col_ind_B array of \\p nnzb_B elements containing the block column indices of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n descr_C descriptor of the sparse BSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_row_ptr_C array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix \\f$C\\f$.\n @param[out]\n nnzb_C pointer to the number of non-zero block entries of the sparse BSR\n matrix \\f$C\\f$. \\p nnzb_C can be a host or device pointer.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p kb, \\p nnzb_A or \\p nnzb_B is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr_A, \\p bsr_row_ptr_A,\n \\p bsr_col_ind_A, \\p descr_B, \\p bsr_row_ptr_B, \\p bsr_col_ind_B,\n \\p descr_C, \\p bsr_row_ptr_C or \\p nnzb_C is invalid.\n \\retval rocsparse_status_not_implemented\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_bsrgeam_nnzb( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + block_dim: rocsparse_int, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_row_ptr_C: *mut rocsparse_int, + nnzb_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix addition using BSR storage format\n\n \\details\n \\p rocsparse_bsrgeam multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$m \\times n\\f$ matrix \\f$A\\f$, defined in BSR storage format, multiplies the\n scalar \\f$\\beta\\f$ with the sparse \\f$mb \\times nb\\f$ matrix \\f$B\\f$, defined in BSR\n storage format, and adds both resulting matrices to obtain the sparse\n \\f$mb \\times nb\\f$ matrix \\f$C\\f$, defined in BSR storage format, such that\n \\f[\n C := \\alpha \\cdot A + \\beta \\cdot B.\n \\f]\n\n It is assumed that \\p bsr_row_ptr_C has already been filled and that \\p bsr_val_C and\n \\p bsr_col_ind_C are allocated by the user. \\p bsr_row_ptr_C and allocation size of\n \\p bsr_col_ind_C and \\p bsr_val_C is defined by the number of non-zero block elements of\n the sparse BSR matrix C. Both can be obtained by rocsparse_bsrgeam_nnz().\n\n \\note Both scalars \\f$\\alpha\\f$ and \\f$beta\\f$ have to be valid.\n\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row in the BSR matrices \\f$A\\f$, \\f$B\\f$, and \\f$C\\f$.\n @param[in]\n mb number of rows of the sparse BSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n nb number of columns of the sparse BSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n block_dim the block dimension of the BSR matrix \\f$A\\f$. Between 1 and m where \\p m=mb*block_dim.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_A number of non-zero block entries of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_val_A array of \\p nnzb_A block elements of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_col_ind_A array of \\p nnzb_A block elements containing the block column indices of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_B descriptor of the sparse BSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_B number of non-zero block entries of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_val_B array of \\p nnzb_B block elements of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_row_ptr_B array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_col_ind_B array of \\p nnzb_B block elements containing the block column indices of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n descr_C descriptor of the sparse BSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_val_C array of block elements of the sparse BSR matrix \\f$C\\f$.\n @param[in]\n bsr_row_ptr_C array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$C\\f$.\n @param[out]\n bsr_col_ind_C array of block elements containing the block column indices of the\n sparse BSR matrix \\f$C\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p nnzb_A or \\p nnzb_B is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr_A, \\p bsr_val_A,\n \\p bsr_row_ptr_A, \\p bsr_col_ind_A, \\p beta, \\p descr_B, \\p bsr_val_B,\n \\p bsr_row_ptr_B, \\p bsr_col_ind_B, \\p descr_C, \\p csr_val_C,\n \\p bsr_row_ptr_C or \\p bsr_col_ind_C is invalid.\n \\retval rocsparse_status_not_implemented\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example adds two CSR matrices.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 1.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Obtain number of total non-zero block entries in C and block row pointers of C\n rocsparse_int nnzb_C;\n hipMalloc((void**)&bsr_row_ptr_C, sizeof(rocsparse_int) * (mb + 1));\n\n rocsparse_bsrgeam_nnzb(handle,\n dir,\n mb,\n nb,\n block_dim,\n descr_A,\n nnzb_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n descr_B,\n nnzb_B,\n bsr_row_ptr_B,\n bsr_col_ind_B,\n descr_C,\n bsr_row_ptr_C,\n &nnzb_C);\n\n // Compute block column indices and block values of C\n hipMalloc((void**)&bsr_col_ind_C, sizeof(rocsparse_int) * nnzb_C);\n hipMalloc((void**)&bsr_val_C, sizeof(float) * nnzb_C * block_dim * block_dim);\n\n rocsparse_sbsrgeam(handle,\n dir,\n mb,\n nb,\n block_dim,\n &alpha,\n descr_A,\n nnzb_A,\n bsr_val_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n &beta,\n descr_B,\n nnzb_B,\n bsr_val_B,\n bsr_row_ptr_B,\n bsr_col_ind_B,\n descr_C,\n bsr_val_C,\n bsr_row_ptr_C,\n bsr_col_ind_C);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsrgeam( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const f32, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + beta: *const f32, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const f32, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f32, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrgeam( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const f64, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + beta: *const f64, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const f64, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f64, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrgeam( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const rocsparse_float_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const rocsparse_float_complex, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_float_complex, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrgeam( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const rocsparse_double_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const rocsparse_double_complex, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_double_complex, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix addition using CSR storage format\n\n \\details\n \\p rocsparse_csrgeam_nnz computes the total CSR non-zero elements and the CSR row\n offsets, that point to the start of every row of the sparse CSR matrix, of the\n resulting matrix C. It is assumed that \\p csr_row_ptr_C has been allocated with\n size \\p m+1.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[out]\n nnz_C pointer to the number of non-zero entries of the sparse CSR\n matrix \\f$C\\f$. \\p nnz_C can be a host or device pointer.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p nnz_A or \\p nnz_B is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr_A, \\p csr_row_ptr_A,\n \\p csr_col_ind_A, \\p descr_B, \\p csr_row_ptr_B, \\p csr_col_ind_B,\n \\p descr_C, \\p csr_row_ptr_C or \\p nnz_C is invalid.\n \\retval rocsparse_status_not_implemented\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_csrgeam_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix addition using CSR storage format\n\n \\details\n \\p rocsparse_csrgeam multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$m \\times n\\f$ matrix \\f$A\\f$, defined in CSR storage format, multiplies the\n scalar \\f$\\beta\\f$ with the sparse \\f$m \\times n\\f$ matrix \\f$B\\f$, defined in CSR\n storage format, and adds both resulting matrices to obtain the sparse\n \\f$m \\times n\\f$ matrix \\f$C\\f$, defined in CSR storage format, such that\n \\f[\n C := \\alpha \\cdot A + \\beta \\cdot B.\n \\f]\n\n It is assumed that \\p csr_row_ptr_C has already been filled and that \\p csr_val_C and\n \\p csr_col_ind_C are allocated by the user. \\p csr_row_ptr_C and allocation size of\n \\p csr_col_ind_C and \\p csr_val_C is defined by the number of non-zero elements of\n the sparse CSR matrix C. Both can be obtained by rocsparse_csrgeam_nnz().\n\n \\note Both scalars \\f$\\alpha\\f$ and \\f$beta\\f$ have to be valid.\n\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$A\\f$, \\f$B\\f$ and \\f$C\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_val_A array of \\p nnz_A elements of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_val_B array of \\p nnz_B elements of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val_C array of elements of the sparse CSR matrix \\f$C\\f$.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[out]\n csr_col_ind_C array of elements containing the column indices of the\n sparse CSR matrix \\f$C\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p nnz_A or \\p nnz_B is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p descr_A, \\p csr_val_A,\n \\p csr_row_ptr_A, \\p csr_col_ind_A, \\p beta, \\p descr_B, \\p csr_val_B,\n \\p csr_row_ptr_B, \\p csr_col_ind_B, \\p descr_C, \\p csr_val_C,\n \\p csr_row_ptr_C or \\p csr_col_ind_C is invalid.\n \\retval rocsparse_status_not_implemented\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example adds two CSR matrices.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 1.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Obtain number of total non-zero entries in C and row pointers of C\n rocsparse_int nnz_C;\n hipMalloc((void**)&csr_row_ptr_C, sizeof(rocsparse_int) * (m + 1));\n\n rocsparse_csrgeam_nnz(handle,\n m,\n n,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_C,\n csr_row_ptr_C,\n &nnz_C);\n\n // Compute column indices and values of C\n hipMalloc((void**)&csr_col_ind_C, sizeof(rocsparse_int) * nnz_C);\n hipMalloc((void**)&csr_val_C, sizeof(float) * nnz_C);\n\n rocsparse_scsrgeam(handle,\n m,\n n,\n &alpha,\n descr_A,\n nnz_A,\n csr_val_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n &beta,\n descr_B,\n nnz_B,\n csr_val_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_C,\n csr_val_C,\n csr_row_ptr_C,\n csr_col_ind_C);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrgeam( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + beta: *const f32, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f32, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrgeam( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + beta: *const f64, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f64, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrgeam( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_float_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_float_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut rocsparse_float_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrgeam( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_double_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_double_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut rocsparse_double_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrgemm_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_bsrgemm_nnzb(), rocsparse_sbsrgemm(),\n rocsparse_dbsrgemm(), rocsparse_cbsrgemm() and rocsparse_zbsrgemm(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n This function is blocking with respect to the host.\n \\note\n Currently, only \\p trans_A == \\p trans_B == \\ref rocsparse_operation_none is\n supported.\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row in the BSR matrices \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n mb number of block rows in the sparse BSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n nb number of block columns of the sparse BSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n kb number of block columns of the sparse BSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse BSR matrix \\f$op(B)\\f$.\n @param[in]\n block_dim the block dimension of the BSR matrix \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse BSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_A number of non-zero block entries of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 elements (\\f$op(A) == A\\f$, \\p kb+1 otherwise)\n that point to the start of every block row of the sparse BSR matrix\n \\f$op(A)\\f$.\n @param[in]\n bsr_col_ind_A array of \\p nnzb_A elements containing the block column indices of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse BSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_B number of non-zero block entries of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_row_ptr_B array of \\p kb+1 elements (\\f$op(B) == B\\f$, \\p mb+1 otherwise)\n that point to the start of every block row of the sparse BSR matrix\n \\f$op(B)\\f$.\n @param[in]\n bsr_col_ind_B array of \\p nnzb_B elements containing the block column indices of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_D descriptor of the sparse BSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_D number of non-zero block entries of the sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_row_ptr_D array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_col_ind_D array of \\p nnzb_D elements containing the block column indices of the sparse\n BSR matrix \\f$D\\f$.\n @param[inout]\n info_C structure that holds meta data for the sparse BSR matrix \\f$C\\f$.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_bsrgemm_nnzb(), rocsparse_sbsrgemm(), rocsparse_dbsrgemm(),\n rocsparse_cbsrgemm() and rocsparse_zbsrgemm().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p kb, \\p block_dim, \\p nnzb_A, \\p nnzb_B or\n \\p nnzb_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p descr_A, \\p bsr_row_ptr_A, \\p bsr_col_ind_A, \\p descr_B,\n \\p bsr_row_ptr_B or \\p bsr_col_ind_B are invalid if \\p alpha is valid,\n \\p descr_D, \\p bsr_row_ptr_D or \\p bsr_col_ind_D is invalid if \\p beta is\n valid, \\p info_C or \\p buffer_size is invalid.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrgemm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const f32, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrgemm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const f64, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrgemm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrgemm_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrgemm_nnzb computes the total BSR non-zero block elements and the BSR block row\n offsets, that point to the start of every block row of the sparse BSR matrix, of the\n resulting multiplied matrix C. It is assumed that \\p bsr_row_ptr_C has been allocated\n with size \\p mb+1.\n The required buffer size can be obtained by rocsparse_sbsrgemm_buffer_size(),\n rocsparse_dbsrgemm_buffer_size(), rocsparse_cbsrgemm_buffer_size() and\n rocsparse_zbsrgemm_buffer_size(), respectively.\n\n \\note\n This function is blocking with respect to the host.\n \\note\n Currently, only \\p trans_A == \\p trans_B == \\ref rocsparse_operation_none is\n supported.\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row in the BSR matrices \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n mb number of block rows in the sparse BSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n nb number of block columns of the sparse BSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n kb number of block columns of the sparse BSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse BSR matrix \\f$op(B)\\f$.\n @param[in]\n block_dim the block dimension of the BSR matrix \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n descr_A descriptor of the sparse BSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_A number of non-zero block entries of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 block elements (\\f$op(A) == A\\f$, \\p kb+1 otherwise)\n that point to the start of every row of the sparse BSR matrix\n \\f$op(A)\\f$.\n @param[in]\n bsr_col_ind_A array of \\p nnzb_A block elements containing the block column indices of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse BSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_B number of non-zero block entries of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_row_ptr_B array of \\p kb+1 block elements (\\f$op(B) == B\\f$, \\p mb+1 otherwise)\n that point to the start of every block row of the sparse BSR matrix\n \\f$op(B)\\f$.\n @param[in]\n bsr_col_ind_B array of \\p nnzb_B block elements containing the block column indices of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n descr_D descriptor of the sparse BSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_D number of non-zero block entries of the sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_row_ptr_D array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_col_ind_D array of \\p nnzb_D block elements containing the block column indices of the sparse\n BSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse BSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_row_ptr_C array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$C\\f$.\n @param[out]\n nnzb_C pointer to the number of non-zero block entries of the sparse BSR\n matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse BSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_sbsrgemm_buffer_size(),\n rocsparse_dbsrgemm_buffer_size(), rocsparse_cbsrgemm_buffer_size() or\n rocsparse_zbsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p kb, \\p block_dim, \\p nnzb_A, \\p nnzb_B or\n \\p nnzb_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr_A, \\p bsr_row_ptr_A,\n \\p bsr_col_ind_A, \\p descr_B, \\p bsr_row_ptr_B, \\p bsr_col_ind_B,\n \\p descr_D, \\p bsr_row_ptr_D, \\p bsr_col_ind_D, \\p descr_C,\n \\p bsr_row_ptr_C, \\p nnzb_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_bsrgemm_nnzb( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_row_ptr_C: *mut rocsparse_int, + nnzb_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using BSR storage format\n\n \\details\n \\p rocsparse_bsrgemm multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$mb \\times kb\\f$ matrix \\f$A\\f$, defined in BSR storage format, and the sparse\n \\f$kb \\times nb\\f$ matrix \\f$B\\f$, defined in BSR storage format, and adds the result\n to the sparse \\f$mb \\times nb\\f$ matrix \\f$D\\f$ that is multiplied by \\f$\\beta\\f$. The\n final result is stored in the sparse \\f$mb \\times nb\\f$ matrix \\f$C\\f$, defined in BSR\n storage format, such\n that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot D,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n It is assumed that \\p bsr_row_ptr_C has already been filled and that \\p bsr_val_C and\n \\p bsr_col_ind_C are allocated by the user. \\p bsr_row_ptr_C and allocation size of\n \\p bsr_col_ind_C and \\p bsr_val_C is defined by the number of non-zero elements of\n the sparse BSR matrix C. Both can be obtained by rocsparse_bsrgemm_nnzb(). The\n required buffer size for the computation can be obtained by\n rocsparse_sbsrgemm_buffer_size(), rocsparse_dbsrgemm_buffer_size(),\n rocsparse_cbsrgemm_buffer_size() and rocsparse_zbsrgemm_buffer_size(), respectively.\n\n \\note If \\f$\\alpha == 0\\f$, then \\f$C = \\beta \\cdot D\\f$ will be computed.\n \\note If \\f$\\beta == 0\\f$, then \\f$C = \\alpha \\cdot op(A) \\cdot op(B)\\f$ will be computed.\n \\note \\f$\\alpha == beta == 0\\f$ is invalid.\n \\note Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\p trans_B == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n \\note This function is blocking with respect to the host.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row in the BSR matrices \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n mb number of block rows of the sparse BSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n nb number of block columns of the sparse BSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n kb number of block columns of the sparse BSR matrix \\f$op(A)\\f$ and number of\n block rows of the sparse BSR matrix \\f$op(B)\\f$.\n @param[in]\n block_dim the block dimension of the BSR matrix \\f$A\\f$, \\f$B\\f$, \\f$C\\f$, and \\f$D\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse BSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_A number of non-zero block entries of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_val_A array of \\p nnzb_A block elements of the sparse BSR matrix \\f$A\\f$.\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 block elements (\\f$op(A) == A\\f$, \\p kb+1 otherwise)\n that point to the start of every block row of the sparse BSR matrix\n \\f$op(A)\\f$.\n @param[in]\n bsr_col_ind_A array of \\p nnzb_A block elements containing the block column indices of the\n sparse BSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse BSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_B number of non-zero block entries of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_val_B array of \\p nnzb_B block elements of the sparse BSR matrix \\f$B\\f$.\n @param[in]\n bsr_row_ptr_B array of \\p kb+1 block elements (\\f$op(B) == B\\f$, \\p mb+1 otherwise)\n that point to the start of every block row of the sparse BSR matrix\n \\f$op(B)\\f$.\n @param[in]\n bsr_col_ind_B array of \\p nnzb_B block elements containing the block column indices of the\n sparse BSR matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_D descriptor of the sparse BSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnzb_D number of non-zero block entries of the sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_val_D array of \\p nnzb_D block elements of the sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_row_ptr_D array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$D\\f$.\n @param[in]\n bsr_col_ind_D array of \\p nnzb_D block elements containing the block column indices of the\n sparse BSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse BSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_val_C array of \\p nnzb_C elements of the sparse BSR matrix \\f$C\\f$.\n @param[in]\n bsr_row_ptr_C array of \\p mb+1 block elements that point to the start of every block row of the\n sparse BSR matrix \\f$C\\f$.\n @param[out]\n bsr_col_ind_C array of \\p nnzb_C block elements containing the block column indices of the\n sparse BSR matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse BSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_sbsrgemm_buffer_size(),\n rocsparse_dbsrgemm_buffer_size(), rocsparse_cbsrgemm_buffer_size() or\n rocsparse_zbsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb, \\p kb, \\p block_dim, \\p nnzb_A, \\p nnzb_B or\n \\p nnzb_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p descr_A, \\p bsr_val_A, \\p bsr_row_ptr_A, \\p bsr_col_ind_A, \\p descr_B,\n \\p bsr_val_B, \\p bsr_row_ptr_B or \\p bsr_col_ind_B are invalid if \\p alpha\n is valid, \\p descr_D, \\p bsr_val_D, \\p bsr_row_ptr_D or \\p bsr_col_ind_D is\n invalid if \\p beta is valid, \\p bsr_val_C, \\p bsr_row_ptr_C,\n \\p bsr_col_ind_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies two BSR matrices with a scalar alpha and adds the result to\n another BSR matrix.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 2.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n rocsparse_mat_descr descr_D;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n rocsparse_create_mat_descr(&descr_D);\n\n // Create matrix info structure\n rocsparse_mat_info info_C;\n rocsparse_create_mat_info(&info_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Query rocsparse for the required buffer size\n size_t buffer_size;\n\n rocsparse_sbsrgemm_buffer_size(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n rocsparse_operation_none,\n mb,\n nb,\n kb,\n block_dim,\n &alpha,\n descr_A,\n nnzb_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n descr_B,\n nnzb_B,\n bsr_row_ptr_B,\n bsr_col_ind_B,\n &beta,\n descr_D,\n nnzb_D,\n bsr_row_ptr_D,\n bsr_col_ind_D,\n info_C,\n &buffer_size);\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n // Obtain number of total non-zero block entries in C and block row pointers of C\n rocsparse_int nnzb_C;\n hipMalloc((void**)&bsr_row_ptr_C, sizeof(rocsparse_int) * (mb + 1));\n\n rocsparse_bsrgemm_nnzb(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n rocsparse_operation_none,\n mb,\n nb,\n kb,\n block_dim,\n descr_A,\n nnzb_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n descr_B,\n nnzb_B,\n bsr_row_ptr_B,\n bsr_col_ind_B,\n descr_D,\n nnzb_D,\n bsr_row_ptr_D,\n bsr_col_ind_D,\n descr_C,\n bsr_row_ptr_C,\n &nnzb_C,\n info_C,\n buffer);\n\n // Compute block column indices and values of C\n hipMalloc((void**)&bsr_col_ind_C, sizeof(rocsparse_int) * nnzb_C);\n hipMalloc((void**)&bsr_val_C, sizeof(float) * block_dim * block_dim *nnzb_C);\n\n rocsparse_sbsrgemm(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n rocsparse_operation_none,\n mb,\n nb,\n kb,\n block_dim,\n &alpha,\n descr_A,\n nnzb_A,\n bsr_val_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n descr_B,\n nnzb_B,\n bsr_val_B,\n bsr_row_ptr_B,\n bsr_col_ind_B,\n &beta,\n descr_D,\n nnzb_D,\n bsr_val_D,\n bsr_row_ptr_D,\n bsr_col_ind_D,\n descr_C,\n bsr_val_C,\n bsr_row_ptr_C,\n bsr_col_ind_C,\n info_C,\n buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsrgemm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const f32, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const f32, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const f32, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_val_D: *const f32, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f32, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrgemm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const f64, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const f64, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const f64, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_val_D: *const f64, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f64, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrgemm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const rocsparse_float_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const rocsparse_float_complex, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_val_D: *const rocsparse_float_complex, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_float_complex, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrgemm( + handle: rocsparse_handle, + dir: rocsparse_direction, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + mb: rocsparse_int, + nb: rocsparse_int, + kb: rocsparse_int, + block_dim: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnzb_A: rocsparse_int, + bsr_val_A: *const rocsparse_double_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnzb_B: rocsparse_int, + bsr_val_B: *const rocsparse_double_complex, + bsr_row_ptr_B: *const rocsparse_int, + bsr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_D: rocsparse_mat_descr, + nnzb_D: rocsparse_int, + bsr_val_D: *const rocsparse_double_complex, + bsr_row_ptr_D: *const rocsparse_int, + bsr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_double_complex, + bsr_row_ptr_C: *const rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrgemm_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_csrgemm_nnz(), rocsparse_scsrgemm(),\n rocsparse_dcsrgemm(), rocsparse_ccsrgemm() and rocsparse_zcsrgemm(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n Please note, that for matrix products with more than 4096 non-zero entries per row,\n additional temporary storage buffer is allocated by the algorithm.\n \\note\n Please note, that for matrix products with more than 8192 intermediate products per\n row, additional temporary storage buffer is allocated by the algorithm.\n \\note\n Currently, only \\p trans_A == \\p trans_B == \\ref rocsparse_operation_none is\n supported.\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse CSR matrix \\f$op(B)\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements (\\f$op(A) == A\\f$, \\p k+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(A)\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p k+1 elements (\\f$op(B) == B\\f$, \\p m+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(B)\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_D descriptor of the sparse CSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_D number of non-zero entries of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_row_ptr_D array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_col_ind_D array of \\p nnz_D elements containing the column indices of the sparse\n CSR matrix \\f$D\\f$.\n @param[inout]\n info_C structure that holds meta data for the sparse CSR matrix \\f$C\\f$.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_csrgemm_nnz(), rocsparse_scsrgemm(), rocsparse_dcsrgemm(),\n rocsparse_ccsrgemm() and rocsparse_zcsrgemm().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz_A, \\p nnz_B or\n \\p nnz_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p descr_A, \\p csr_row_ptr_A, \\p csr_col_ind_A, \\p descr_B,\n \\p csr_row_ptr_B or \\p csr_col_ind_B are invalid if \\p alpha is valid,\n \\p descr_D, \\p csr_row_ptr_D or \\p csr_col_ind_D is invalid if \\p beta is\n valid, \\p info_C or \\p buffer_size is invalid.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrgemm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f32, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrgemm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f64, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrgemm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrgemm_buffer_size( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + info_C: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrgemm_nnz computes the total CSR non-zero elements and the CSR row\n offsets, that point to the start of every row of the sparse CSR matrix, of the\n resulting multiplied matrix C. It is assumed that \\p csr_row_ptr_C has been allocated\n with size \\p m+1.\n The required buffer size can be obtained by rocsparse_scsrgemm_buffer_size(),\n rocsparse_dcsrgemm_buffer_size(), rocsparse_ccsrgemm_buffer_size() and\n rocsparse_zcsrgemm_buffer_size(), respectively.\n\n \\note\n Please note, that for matrix products with more than 8192 intermediate products per\n row, additional temporary storage buffer is allocated by the algorithm.\n \\note\n This function supports unsorted CSR matrices as input, while output will be sorted.\n Please note that matrices B and D can only be unsorted up to 8192 intermediate\n products per row. If this number is exceeded, \\ref rocsparse_status_requires_sorted_storage\n will be returned.\n \\note\n This function is blocking with respect to the host.\n \\note\n Currently, only \\p trans_A == \\p trans_B == \\ref rocsparse_operation_none is\n supported.\n \\note\n Currently, only \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse CSR matrix \\f$op(B)\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements (\\f$op(A) == A\\f$, \\p k+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(A)\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p k+1 elements (\\f$op(B) == B\\f$, \\p m+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(B)\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n descr_D descriptor of the sparse CSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_D number of non-zero entries of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_row_ptr_D array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_col_ind_D array of \\p nnz_D elements containing the column indices of the sparse\n CSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[out]\n nnz_C pointer to the number of non-zero entries of the sparse CSR\n matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse CSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_scsrgemm_buffer_size(),\n rocsparse_dcsrgemm_buffer_size(), rocsparse_ccsrgemm_buffer_size() or\n rocsparse_zcsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz_A, \\p nnz_B or\n \\p nnz_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr_A, \\p csr_row_ptr_A,\n \\p csr_col_ind_A, \\p descr_B, \\p csr_row_ptr_B, \\p csr_col_ind_B,\n \\p descr_D, \\p csr_row_ptr_D, \\p csr_col_ind_D, \\p descr_C,\n \\p csr_row_ptr_C, \\p nnz_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_csrgemm_nnz( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrgemm multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$m \\times k\\f$ matrix \\f$A\\f$, defined in CSR storage format, and the sparse\n \\f$k \\times n\\f$ matrix \\f$B\\f$, defined in CSR storage format, and adds the result\n to the sparse \\f$m \\times n\\f$ matrix \\f$D\\f$ that is multiplied by \\f$\\beta\\f$. The\n final result is stored in the sparse \\f$m \\times n\\f$ matrix \\f$C\\f$, defined in CSR\n storage format, such\n that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot D,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n It is assumed that \\p csr_row_ptr_C has already been filled and that \\p csr_val_C and\n \\p csr_col_ind_C are allocated by the user. \\p csr_row_ptr_C and allocation size of\n \\p csr_col_ind_C and \\p csr_val_C is defined by the number of non-zero elements of\n the sparse CSR matrix C. Both can be obtained by rocsparse_csrgemm_nnz(). The\n required buffer size for the computation can be obtained by\n rocsparse_scsrgemm_buffer_size(), rocsparse_dcsrgemm_buffer_size(),\n rocsparse_ccsrgemm_buffer_size() and rocsparse_zcsrgemm_buffer_size(), respectively.\n\n \\note If \\f$\\alpha == 0\\f$, then \\f$C = \\beta \\cdot D\\f$ will be computed.\n \\note If \\f$\\beta == 0\\f$, then \\f$C = \\alpha \\cdot op(A) \\cdot op(B)\\f$ will be computed.\n \\note \\f$\\alpha == beta == 0\\f$ is invalid.\n \\note Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\p trans_B == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n \\note Please note, that for matrix products with more than 4096 non-zero entries per\n row, additional temporary storage buffer is allocated by the algorithm.\n \\note\n This function supports unsorted CSR matrices as input, while output will be sorted.\n Please note that matrices B and D can only be unsorted up to 4096 non-zero entries\n per row. If this number is exceeded, \\ref rocsparse_status_requires_sorted_storage\n will be returned.\n \\note\n This function is blocking with respect to the host.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse CSR matrix \\f$op(B)\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_val_A array of \\p nnz_A elements of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements (\\f$op(A) == A\\f$, \\p k+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(A)\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_val_B array of \\p nnz_B elements of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p k+1 elements (\\f$op(B) == B\\f$, \\p m+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(B)\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_D descriptor of the sparse CSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_D number of non-zero entries of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_val_D array of \\p nnz_D elements of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_row_ptr_D array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_col_ind_D array of \\p nnz_D elements containing the column indices of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val_C array of \\p nnz_C elements of the sparse CSR matrix \\f$C\\f$.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[out]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the\n sparse CSR matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse CSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_scsrgemm_buffer_size(),\n rocsparse_dcsrgemm_buffer_size(), rocsparse_ccsrgemm_buffer_size() or\n rocsparse_zcsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz_A, \\p nnz_B or\n \\p nnz_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p descr_A, \\p csr_val_A, \\p csr_row_ptr_A, \\p csr_col_ind_A, \\p descr_B,\n \\p csr_val_B, \\p csr_row_ptr_B or \\p csr_col_ind_B are invalid if \\p alpha\n is valid, \\p descr_D, \\p csr_val_D, \\p csr_row_ptr_D or \\p csr_col_ind_D is\n invalid if \\p beta is valid, \\p csr_val_C, \\p csr_row_ptr_C,\n \\p csr_col_ind_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies two CSR matrices with a scalar alpha and adds the result to\n another CSR matrix.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 2.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n rocsparse_mat_descr descr_D;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n rocsparse_create_mat_descr(&descr_D);\n\n // Create matrix info structure\n rocsparse_mat_info info_C;\n rocsparse_create_mat_info(&info_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Query rocsparse for the required buffer size\n size_t buffer_size;\n\n rocsparse_scsrgemm_buffer_size(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n &alpha,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n &beta,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n info_C,\n &buffer_size);\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n // Obtain number of total non-zero entries in C and row pointers of C\n rocsparse_int nnz_C;\n hipMalloc((void**)&csr_row_ptr_C, sizeof(rocsparse_int) * (m + 1));\n\n rocsparse_csrgemm_nnz(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n csr_row_ptr_C,\n &nnz_C,\n info_C,\n buffer);\n\n // Compute column indices and values of C\n hipMalloc((void**)&csr_col_ind_C, sizeof(rocsparse_int) * nnz_C);\n hipMalloc((void**)&csr_val_C, sizeof(float) * nnz_C);\n\n rocsparse_scsrgemm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n &alpha,\n descr_A,\n nnz_A,\n csr_val_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_val_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n &beta,\n descr_D,\n nnz_D,\n csr_val_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n csr_val_C,\n csr_row_ptr_C,\n csr_col_ind_C,\n info_C,\n buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrgemm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f32, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f32, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const f32, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrgemm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f64, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f64, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const f64, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrgemm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_float_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_float_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const rocsparse_float_complex, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut rocsparse_float_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrgemm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_double_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_double_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const rocsparse_double_complex, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + csr_val_C: *mut rocsparse_double_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix symbolic multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrgemm_symbolic multiplies two sparsity patterns and add an extra one: \\f[ opA \\cdot op(B) + D \\f]\n with \\f$m \\times k\\f$ matrix \\f$A\\f$, defined in CSR storage format, the sparse\n \\f$k \\times n\\f$ matrix \\f$B\\f$, defined in CSR storage format and the sparse \\f$m \\times n\\f$ matrix \\f$D\\f$.\n The * final result is stored in the sparse \\f$m \\times n\\f$ matrix \\f$C\\f$, defined in CSR\n storage format, such\n that\n \\f[\n C := op(A) \\cdot op(B) + D,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n It is assumed that \\p csr_row_ptr_C has already been filled and that and\n \\p csr_col_ind_C is allocated by the user. \\p csr_row_ptr_C and allocation size of\n \\p csr_col_ind_C is defined by the number of non-zero elements of\n the sparse CSR matrix C. Both can be obtained by rocsparse_csrgemm_nnz(). The\n required buffer size for the computation can be obtained by\n rocsparse_scsrgemm_buffer_size(), rocsparse_dcsrgemm_buffer_size(),\n rocsparse_ccsrgemm_buffer_size() and rocsparse_zcsrgemm_buffer_size(), respectively.\n\n \\note Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\p trans_B == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n \\note Please note, that for matrix products with more than 4096 non-zero entries per\n row, additional temporary storage buffer is allocated by the algorithm.\n \\note This function is blocking with respect to the host.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse CSR matrix \\f$op(B)\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements (\\f$op(A) == A\\f$, \\p k+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(A)\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p k+1 elements (\\f$op(B) == B\\f$, \\p m+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(B)\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n descr_D descriptor of the sparse CSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_D number of non-zero entries of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_row_ptr_D array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_col_ind_D array of \\p nnz_D elements containing the column indices of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_C number of non-zero entries of the sparse CSR matrix \\f$C\\f$.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[out]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the\n sparse CSR matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse CSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_scsrgemm_buffer_size(),\n rocsparse_dcsrgemm_buffer_size(), rocsparse_ccsrgemm_buffer_size() or\n rocsparse_zcsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz_A, \\p nnz_B or\n \\p nnz_D is invalid.\n \\retval rocsparse_status_invalid_pointer\n \\p descr_A, \\p csr_row_ptr_A, \\p csr_col_ind_A, \\p descr_B,\n \\p csr_row_ptr_B or \\p csr_col_ind_B, \\p descr_D, \\p csr_row_ptr_D, \\p csr_col_ind_D\n \\p csr_row_ptr_C,\n \\p csr_col_ind_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies symbolically two CSR matrices and adds the result to\n another CSR matrix.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 2.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n rocsparse_mat_descr descr_D;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n rocsparse_create_mat_descr(&descr_D);\n\n // Create matrix info structure\n rocsparse_mat_info info_C;\n rocsparse_create_mat_info(&info_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Query rocsparse for the required buffer size\n size_t buffer_size;\n\n rocsparse_scsrgemm_buffer_size(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n &alpha,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n &beta,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n info_C,\n &buffer_size);\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n // Obtain number of total non-zero entries in C and row pointers of C\n rocsparse_int nnz_C;\n hipMalloc((void**)&csr_row_ptr_C, sizeof(rocsparse_int) * (m + 1));\n\n rocsparse_csrgemm_nnz(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n csr_row_ptr_C,\n &nnz_C,\n info_C,\n buffer);\n\n // Compute column indices of C\n hipMalloc((void**)&csr_col_ind_C, sizeof(rocsparse_int) * nnz_C);\n\n rocsparse_csrgemm_symbolic(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n nnz_C,\n csr_row_ptr_C,\n csr_col_ind_C,\n info_C,\n buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_csrgemm_symbolic( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + nnz_C: rocsparse_int, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup extra_module\n \\brief Sparse matrix sparse matrix numeric multiplication using CSR storage format\n\n \\details\n \\p rocsparse_csrgemm_numeric multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$m \\times k\\f$ matrix \\f$A\\f$, defined in CSR storage format, and the sparse\n \\f$k \\times n\\f$ matrix \\f$B\\f$, defined in CSR storage format, and adds the result\n to the sparse \\f$m \\times n\\f$ matrix \\f$D\\f$ that is multiplied by \\f$\\beta\\f$. The\n final result is stored in the sparse \\f$m \\times n\\f$ matrix \\f$C\\f$, predefined in CSR\n storage format, such\n that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot D,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n The symbolic part of the csr matrix C can be obtained by rocsparse_csrgemm_symbolic().\n It is assumed that \\p csr_row_ptr_C and \\p csr_col_ind_C have already been filled and that \\p csr_val_C is allocated by the user. \\p csr_row_ptr_C and allocation size of\n \\p csr_col_ind_C and \\p csr_val_C is defined by the number of non-zero elements of\n the sparse CSR matrix C. Both can be obtained by rocsparse_csrgemm_nnz(). The\n required buffer size for the computation can be obtained by\n rocsparse_scsrgemm_buffer_size(), rocsparse_dcsrgemm_buffer_size(),\n rocsparse_ccsrgemm_buffer_size() and rocsparse_zcsrgemm_buffer_size(), respectively.\n\n \\note If \\f$\\alpha == 0\\f$, then \\f$C = \\beta \\cdot D\\f$ will be computed.\n \\note If \\f$\\beta == 0\\f$, then \\f$C = \\alpha \\cdot op(A) \\cdot op(B)\\f$ will be computed.\n \\note \\f$\\alpha == beta == 0\\f$ is invalid.\n \\note Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\p trans_B == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\ref rocsparse_matrix_type_general is supported.\n \\note Please note, that for matrix products with more than 4096 non-zero entries per\n row, additional temporary storage buffer is allocated by the algorithm.\n \\note This function is blocking with respect to the host.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B matrix \\f$B\\f$ operation type.\n @param[in]\n m number of rows of the sparse CSR matrix \\f$op(A)\\f$ and \\f$C\\f$.\n @param[in]\n n number of columns of the sparse CSR matrix \\f$op(B)\\f$ and\n \\f$C\\f$.\n @param[in]\n k number of columns of the sparse CSR matrix \\f$op(A)\\f$ and number of\n rows of the sparse CSR matrix \\f$op(B)\\f$.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n descr_A descriptor of the sparse CSR matrix \\f$A\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_A number of non-zero entries of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_val_A array of \\p nnz_A elements of the sparse CSR matrix \\f$A\\f$.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements (\\f$op(A) == A\\f$, \\p k+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(A)\\f$.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the\n sparse CSR matrix \\f$A\\f$.\n @param[in]\n descr_B descriptor of the sparse CSR matrix \\f$B\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_B number of non-zero entries of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_val_B array of \\p nnz_B elements of the sparse CSR matrix \\f$B\\f$.\n @param[in]\n csr_row_ptr_B array of \\p k+1 elements (\\f$op(B) == B\\f$, \\p m+1 otherwise)\n that point to the start of every row of the sparse CSR matrix\n \\f$op(B)\\f$.\n @param[in]\n csr_col_ind_B array of \\p nnz_B elements containing the column indices of the\n sparse CSR matrix \\f$B\\f$.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n descr_D descriptor of the sparse CSR matrix \\f$D\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_D number of non-zero entries of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_val_D array of \\p nnz_D elements of the sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_row_ptr_D array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n csr_col_ind_D array of \\p nnz_D elements containing the column indices of the\n sparse CSR matrix \\f$D\\f$.\n @param[in]\n descr_C descriptor of the sparse CSR matrix \\f$C\\f$. Currenty, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n nnz_C number of non-zero entries of the sparse CSR matrix \\f$C\\f$.\n @param[out]\n csr_val_C array of \\p nnz_C elements of the sparse CSR matrix \\f$C\\f$.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix \\f$C\\f$.\n @param[in]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the\n sparse CSR matrix \\f$C\\f$.\n @param[in]\n info_C structure that holds meta data for the sparse CSR matrix \\f$C\\f$.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned\n by rocsparse_scsrgemm_buffer_size(),\n rocsparse_dcsrgemm_buffer_size(), rocsparse_ccsrgemm_buffer_size() or\n rocsparse_zcsrgemm_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n, \\p k, \\p nnz_A, \\p nnz_B or\n \\p nnz_D is invalid.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p descr_A, \\p csr_val_A, \\p csr_row_ptr_A, \\p csr_col_ind_A, \\p descr_B,\n \\p csr_val_B, \\p csr_row_ptr_B or \\p csr_col_ind_B are invalid if \\p alpha\n is valid, \\p descr_D, \\p csr_val_D, \\p csr_row_ptr_D or \\p csr_col_ind_D is\n invalid if \\p beta is valid, \\p csr_val_C, \\p csr_row_ptr_C,\n \\p csr_col_ind_C, \\p info_C or \\p temp_buffer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none,\n \\p trans_B != \\ref rocsparse_operation_none, or\n \\p rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example multiplies two CSR matrices with a scalar alpha and adds the result to\n another CSR matrix.\n \\code{.c}\n // Initialize scalar multipliers\n float alpha = 2.0f;\n float beta = 1.0f;\n\n // Create matrix descriptors\n rocsparse_mat_descr descr_A;\n rocsparse_mat_descr descr_B;\n rocsparse_mat_descr descr_C;\n rocsparse_mat_descr descr_D;\n\n rocsparse_create_mat_descr(&descr_A);\n rocsparse_create_mat_descr(&descr_B);\n rocsparse_create_mat_descr(&descr_C);\n rocsparse_create_mat_descr(&descr_D);\n\n // Create matrix info structure\n rocsparse_mat_info info_C;\n rocsparse_create_mat_info(&info_C);\n\n // Set pointer mode\n rocsparse_set_pointer_mode(handle, rocsparse_pointer_mode_host);\n\n // Query rocsparse for the required buffer size\n size_t buffer_size;\n\n rocsparse_scsrgemm_buffer_size(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n &alpha,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n &beta,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n info_C,\n &buffer_size);\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n // Obtain number of total non-zero entries in C and row pointers of C\n rocsparse_int nnz_C;\n hipMalloc((void**)&csr_row_ptr_C, sizeof(rocsparse_int) * (m + 1));\n\n rocsparse_csrgemm_nnz(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n csr_row_ptr_C,\n &nnz_C,\n info_C,\n buffer);\n\n // Compute column indices and values of C\n hipMalloc((void**)&csr_col_ind_C, sizeof(rocsparse_int) * nnz_C);\n rocsparse_csrgemm_symbolic(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n descr_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n descr_D,\n nnz_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n nnz_C,\n csr_row_ptr_C,\n csr_col_ind_C,\n info_C,\n buffer);\n hipMalloc((void**)&csr_val_C, sizeof(float) * nnz_C);\n\n rocsparse_scsrgemm_numeric(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n m,\n n,\n k,\n &alpha,\n descr_A,\n nnz_A,\n csr_val_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n descr_B,\n nnz_B,\n csr_val_B,\n csr_row_ptr_B,\n csr_col_ind_B,\n &beta,\n descr_D,\n nnz_D,\n csr_val_D,\n csr_row_ptr_D,\n csr_col_ind_D,\n descr_C,\n nnz_C,\n csr_val_C,\n csr_row_ptr_C,\n csr_col_ind_C,\n info_C,\n buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrgemm_numeric( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f32, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f32, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f32, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const f32, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + nnz_C: rocsparse_int, + csr_val_C: *mut f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrgemm_numeric( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const f64, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const f64, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const f64, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const f64, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + nnz_C: rocsparse_int, + csr_val_C: *mut f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrgemm_numeric( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_float_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_float_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_float_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_float_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const rocsparse_float_complex, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + nnz_C: rocsparse_int, + csr_val_C: *mut rocsparse_float_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrgemm_numeric( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + m: rocsparse_int, + n: rocsparse_int, + k: rocsparse_int, + alpha: *const rocsparse_double_complex, + descr_A: rocsparse_mat_descr, + nnz_A: rocsparse_int, + csr_val_A: *const rocsparse_double_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + descr_B: rocsparse_mat_descr, + nnz_B: rocsparse_int, + csr_val_B: *const rocsparse_double_complex, + csr_row_ptr_B: *const rocsparse_int, + csr_col_ind_B: *const rocsparse_int, + beta: *const rocsparse_double_complex, + descr_D: rocsparse_mat_descr, + nnz_D: rocsparse_int, + csr_val_D: *const rocsparse_double_complex, + csr_row_ptr_D: *const rocsparse_int, + csr_col_ind_D: *const rocsparse_int, + descr_C: rocsparse_mat_descr, + nnz_C: rocsparse_int, + csr_val_C: *mut rocsparse_double_complex, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info_C: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR\n storage format\n\n \\details\n \\p rocsparse_bsric0_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_sbsric0(),\n rocsparse_dbsric0(), rocsparse_cbsric0() or rocsparse_zbsric0() computation.\n The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position, using same\n index base as the BSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note\n If a zero pivot is found, \\p position=j means that either the diagonal block \\p A(j,j)\n is missing (structural zero) or the diagonal block \\p A(j,j) is not positive definite\n (numerical zero).\n\n \\note \\p rocsparse_bsric0_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_bsric0_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR\n storage format\n\n \\details\n \\p rocsparse_bsric0_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(),\n rocsparse_cbsric0_analysis(), rocsparse_zbsric0_analysis(), rocsparse_sbsric0(),\n rocsparse_dbsric0(), rocsparse_sbsric0() and rocsparse_dbsric0(). The temporary\n storage buffer must be allocated by the user. The size of the temporary storage\n buffer is identical to the size returned by rocsparse_sbsrsv_buffer_size(),\n rocsparse_dbsrsv_buffer_size(), rocsparse_cbsrsv_buffer_size(), rocsparse_zbsrsv_buffer_size(),\n rocsparse_sbsrilu0_buffer_size(), rocsparse_dbsrilu0_buffer_size(), rocsparse_cbsrilu0_buffer_size()\n and rocsparse_zbsrilu0_buffer_size() if the matrix sparsity pattern is identical. The user\n allocated buffer can thus be shared between subsequent calls to those functions.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(),\n rocsparse_cbsric0_analysis(), rocsparse_zbsric0_analysis(),\n rocsparse_sbsric0(), rocsparse_dbsric0(), rocsparse_cbsric0()\n and rocsparse_zbsric0().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsric0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsric0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsric0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsric0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR\n storage format\n\n \\details\n \\p rocsparse_bsric0_analysis performs the analysis step for rocsparse_sbsric0()\n rocsparse_dbsric0(), rocsparse_cbsric0(), and rocsparse_zbsric0(). It is expected\n that this function will be executed only once for a given matrix and particular\n operation type. The analysis meta data can be cleared by rocsparse_bsric0_clear().\n\n \\p rocsparse_bsric0_analysis can share its meta data with\n rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(),\n rocsparse_cbsrilu0_analysis(), rocsparse_zbsrilu0_analysis(),\n rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(),\n rocsparse_cbsrsv_analysis(), rocsparse_zbsrsv_analysis(),\n rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(),\n rocsparse_cbsrsm_analysis() and rocsparse_zbsrsm_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsric0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsric0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsric0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsric0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR\n storage format\n\n \\details\n \\p rocsparse_bsric0_clear deallocates all memory that was allocated by\n rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(), rocsparse_cbsric0_analysis()\n or rocsparse_zbsric0_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation.\n\n \\note\n Calling \\p rocsparse_bsric0_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_bsric0_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using BSR\n storage format\n\n \\details\n \\p rocsparse_bsric0 computes the incomplete Cholesky factorization with 0 fill-ins\n and no pivoting of a sparse \\f$mb \\times mb\\f$ BSR matrix \\f$A\\f$, such that\n \\f[\n A \\approx LL^T\n \\f]\n\n \\p rocsparse_bsric0 requires a user allocated temporary buffer. Its size is returned\n by rocsparse_sbsric0_buffer_size(), rocsparse_dbsric0_buffer_size(),\n rocsparse_cbsric0_buffer_size() or rocsparse_zbsric0_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_sbsric0_analysis(),\n rocsparse_dbsric0_analysis(), rocsparse_cbsric0_analysis() or rocsparse_zbsric0_analysis().\n \\p rocsparse_bsric0 reports the first zero pivot (either numerical or structural zero).\n The zero pivot status can be obtained by calling rocsparse_bsric0_zero_pivot().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[inout]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr\n or \\p bsr_col_ind pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the sparse \\f$m \\times m\\f$ matrix \\f$A\\f$, stored in BSR\n storage format. The following example computes the incomplete Cholesky factorization\n \\f$M \\approx LL^T\\f$ and solves the preconditioned system \\f$My = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor for M\n rocsparse_mat_descr descr_M;\n rocsparse_create_mat_descr(&descr_M);\n\n // Create matrix descriptor for L\n rocsparse_mat_descr descr_L;\n rocsparse_create_mat_descr(&descr_L);\n rocsparse_set_mat_fill_mode(descr_L, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr_L, rocsparse_diag_type_unit);\n\n // Create matrix descriptor for L'\n rocsparse_mat_descr descr_Lt;\n rocsparse_create_mat_descr(&descr_Lt);\n rocsparse_set_mat_fill_mode(descr_Lt, rocsparse_fill_mode_upper);\n rocsparse_set_mat_diag_type(descr_Lt, rocsparse_diag_type_non_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size_M;\n size_t buffer_size_L;\n size_t buffer_size_Lt;\n rocsparse_dbsric0_buffer_size(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_M);\n rocsparse_dbsrsv_buffer_size(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_L);\n rocsparse_dbsrsv_buffer_size(handle,\n rocsparse_direction_row,\n rocsparse_operation_transpose,\n mb,\n nnzb,\n descr_Lt,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_Lt);\n\n size_t buffer_size = max(buffer_size_M, max(buffer_size_L, buffer_size_Lt));\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis steps, using rocsparse_analysis_policy_reuse to improve\n // computation performance\n rocsparse_dbsric0_analysis(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dbsrsv_analysis(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dbsrsv_analysis(handle,\n rocsparse_direction_row,\n rocsparse_operation_transpose,\n mb,\n nnzb,\n descr_Lt,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n rocsparse_int position;\n if(rocsparse_status_zero_pivot == rocsparse_bsric0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"A has structural zero at A(%d,%d)\\n\", position, position);\n }\n\n // Compute incomplete Cholesky factorization M = LL'\n rocsparse_dbsric0(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n if(rocsparse_status_zero_pivot == rocsparse_bsric0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"L has structural and/or numerical zero at L(%d,%d)\\n\",\n position,\n position);\n }\n\n // Solve Lz = x\n rocsparse_dbsrsv_solve(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n &alpha,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n x,\n z,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve L'y = z\n rocsparse_dbsrsv_solve(handle,\n rocsparse_direction_row,\n rocsparse_operation_transpose,\n mb,\n nnzb,\n &alpha,\n descr_Lt,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n z,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr_M);\n rocsparse_destroy_mat_descr(descr_L);\n rocsparse_destroy_mat_descr(descr_Lt);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsric0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsric0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsric0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsric0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_sbsrilu0(),\n rocsparse_dbsrilu0(), rocsparse_cbsrilu0() or rocsparse_zbsrilu0() computation.\n The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position, using same\n index base as the BSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note\n If a zero pivot is found, \\p position \\f$=j\\f$ means that either the diagonal block\n \\f$A_{j,j}\\f$ is missing (structural zero) or the diagonal block \\f$A_{j,j}\\f$ is not\n invertible (numerical zero).\n\n \\note \\p rocsparse_bsrilu0_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_bsrilu0_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0_numeric_boost enables the user to replace a numerical value in\n an incomplete LU factorization. \\p tol is used to determine whether a numerical value\n is replaced by \\p boost_val, such that \\f$A_{j,j} = \\text{boost_val}\\f$ if\n \\f$\\text{tol} \\ge \\left|A_{j,j}\\right|\\f$.\n\n \\note The boost value is enabled by setting \\p enable_boost to 1 or disabled by\n setting \\p enable_boost to 0.\n\n \\note \\p tol and \\p boost_val can be in host or device memory.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n enable_boost enable/disable numeric boost.\n @param[in]\n boost_tol tolerance to determine whether a numerical value is replaced or not.\n @param[in]\n boost_val boost value to replace a numerical value.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info, \\p tol or \\p boost_val pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f32, + boost_val: *const f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f32, + boost_val: *const rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dsbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcbsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(),\n rocsparse_cbsrilu0_analysis(), rocsparse_zbsrilu0_analysis(), rocsparse_sbsrilu0(),\n rocsparse_dbsrilu0(), rocsparse_sbsrilu0() and rocsparse_dbsrilu0(). The temporary\n storage buffer must be allocated by the user. The size of the temporary storage\n buffer is identical to the size returned by rocsparse_sbsrsv_buffer_size(),\n rocsparse_dbsrsv_buffer_size(), rocsparse_cbsrsv_buffer_size(), rocsparse_zbsrsv_buffer_size(),\n rocsparse_sbsric0_buffer_size(), rocsparse_dbsric0_buffer_size(), rocsparse_cbsric0_buffer_size()\n and rocsparse_zbsric0_buffer_size() if the matrix sparsity pattern is identical. The user\n allocated buffer can thus be shared between subsequent calls to those functions.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specifies whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(),\n rocsparse_cbsrilu0_analysis(), rocsparse_zbsrilu0_analysis(),\n rocsparse_sbsrilu0(), rocsparse_dbsrilu0(), rocsparse_cbsrilu0()\n and rocsparse_zbsrilu0().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrilu0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrilu0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrilu0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrilu0_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0_analysis performs the analysis step for rocsparse_sbsrilu0()\n rocsparse_dbsrilu0(), rocsparse_cbsrilu0(), and rocsparse_zbsrilu0(). It is expected\n that this function will be executed only once for a given matrix. The analysis meta\n data can be cleared by rocsparse_bsrilu0_clear().\n\n \\p rocsparse_bsrilu0_analysis can share its meta data with\n rocsparse_sbsric0_analysis(), rocsparse_dbsric0_analysis(),\n rocsparse_cbsric0_analysis(), rocsparse_zbsric0_analysis(),\n rocsparse_sbsrsv_analysis(), rocsparse_dbsrsv_analysis(),\n rocsparse_cbsrsv_analysis(), rocsparse_zbsrsv_analysis(),\n rocsparse_sbsrsm_analysis(), rocsparse_dbsrsm_analysis(),\n rocsparse_cbsrsm_analysis() and rocsparse_zbsrsm_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specified whether to count nonzero elements by\n \\ref rocsparse_direction_row or by \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[in]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_sbsrilu0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrilu0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrilu0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrilu0_analysis( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0_clear deallocates all memory that was allocated by\n rocsparse_sbsrilu0_analysis(), rocsparse_dbsrilu0_analysis(), rocsparse_cbsrilu0_analysis()\n or rocsparse_zbsrilu0_analysis(). This is especially useful, if memory is an issue and\n the analysis data is not required for further computation.\n\n \\note\n Calling \\p rocsparse_bsrilu0_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_bsrilu0_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using BSR storage\n format\n\n \\details\n \\p rocsparse_bsrilu0 computes the incomplete LU factorization with 0 fill-ins and no\n pivoting of a sparse \\f$mb \\times mb\\f$ BSR matrix \\f$A\\f$, such that\n \\f[\n A \\approx LU\n \\f]\n\n \\p rocsparse_bsrilu0 requires a user allocated temporary buffer. Its size is returned\n by rocsparse_sbsrilu0_buffer_size(), rocsparse_dbsrilu0_buffer_size(),\n rocsparse_cbsrilu0_buffer_size() or rocsparse_zbsrilu0_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_sbsrilu0_analysis(),\n rocsparse_dbsrilu0_analysis(), rocsparse_cbsrilu0_analysis() or\n rocsparse_zbsrilu0_analysis(). \\p rocsparse_bsrilu0 reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be obtained by\n calling rocsparse_bsrilu0_zero_pivot().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir direction that specified whether to count nonzero elements by\n \\ref rocsparse_direction_row or by \\ref rocsparse_direction_row.\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero block entries of the sparse BSR matrix.\n @param[in]\n descr descriptor of the sparse BSR matrix.\n @param[inout]\n bsr_val array of length \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and m where \\p m=mb*block_dim.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nnzb, or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p bsr_val, \\p bsr_row_ptr\n or \\p bsr_col_ind pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the sparse \\f$m \\times m\\f$ matrix \\f$A\\f$, stored in BSR\n storage format. The following example computes the incomplete LU factorization\n \\f$M \\approx LU\\f$ and solves the preconditioned system \\f$My = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor for M\n rocsparse_mat_descr descr_M;\n rocsparse_create_mat_descr(&descr_M);\n\n // Create matrix descriptor for L\n rocsparse_mat_descr descr_L;\n rocsparse_create_mat_descr(&descr_L);\n rocsparse_set_mat_fill_mode(descr_L, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr_L, rocsparse_diag_type_unit);\n\n // Create matrix descriptor for U\n rocsparse_mat_descr descr_U;\n rocsparse_create_mat_descr(&descr_U);\n rocsparse_set_mat_fill_mode(descr_U, rocsparse_fill_mode_upper);\n rocsparse_set_mat_diag_type(descr_U, rocsparse_diag_type_non_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size_M;\n size_t buffer_size_L;\n size_t buffer_size_U;\n rocsparse_dbsrilu0_buffer_size(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_M);\n rocsparse_dbsrsv_buffer_size(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_L);\n rocsparse_dbsrsv_buffer_size(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_U,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n &buffer_size_U);\n\n size_t buffer_size = max(buffer_size_M, max(buffer_size_L, buffer_size_U));\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis steps, using rocsparse_analysis_policy_reuse to improve\n // computation performance\n rocsparse_dbsrilu0_analysis(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dbsrsv_analysis(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dbsrsv_analysis(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n descr_U,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n rocsparse_int position;\n if(rocsparse_status_zero_pivot == rocsparse_bsrilu0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"A has structural zero at A(%d,%d)\\n\", position, position);\n }\n\n // Compute incomplete LU factorization M = LU\n rocsparse_dbsrilu0(handle,\n rocsparse_direction_row,\n mb,\n nnzb,\n descr_M,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n if(rocsparse_status_zero_pivot == rocsparse_bsrilu0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"L has structural and/or numerical zero at L(%d,%d)\\n\",\n position,\n position);\n }\n\n // Solve Lz = x\n rocsparse_dbsrsv_solve(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n &alpha,\n descr_L,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n x,\n z,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve Uy = z\n rocsparse_dbsrsv_solve(handle,\n rocsparse_direction_row,\n rocsparse_operation_none,\n mb,\n nnzb,\n &alpha,\n descr_U,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n info,\n z,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr_M);\n rocsparse_destroy_mat_descr(descr_L);\n rocsparse_destroy_mat_descr(descr_U);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsrilu0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrilu0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrilu0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrilu0( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nnzb: rocsparse_int, + descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csric_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_scsric0() or\n rocsparse_dcsric0() computation. The first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$\n is stored in \\p position, using same index base as the CSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_csric0_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_csric0_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csric0_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_scsric0_analysis(), rocsparse_dcsric0_analysis(),\n rocsparse_scsric0() and rocsparse_dcsric0(). The temporary storage buffer must\n be allocated by the user. The size of the temporary storage buffer is identical to\n the size returned by rocsparse_scsrsv_buffer_size(), rocsparse_dcsrsv_buffer_size(),\n rocsparse_scsrilu0_buffer_size() and rocsparse_dcsrilu0_buffer_size() if the matrix\n sparsity pattern is identical. The user allocated buffer can thus be shared between\n subsequent calls to those functions.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsric0_analysis(), rocsparse_dcsric0_analysis(),\n rocsparse_scsric0() and rocsparse_dcsric0().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsric0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsric0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsric0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsric0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csric0_analysis performs the analysis step for rocsparse_scsric0()\n and rocsparse_dcsric0(). It is expected that this function will be executed only\n once for a given matrix and particular operation type. The analysis meta data can be\n cleared by rocsparse_csric0_clear().\n\n \\p rocsparse_csric0_analysis can share its meta data with\n rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis(), rocsparse_zcsrilu0_analysis(),\n rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(),\n rocsparse_ccsrsv_analysis(), rocsparse_zcsrsv_analysis(),\n rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(),\n rocsparse_scsrsm_analysis() and rocsparse_dcsrsm_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsric0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsric0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsric0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsric0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csric0_clear deallocates all memory that was allocated by\n rocsparse_scsric0_analysis() or rocsparse_dcsric0_analysis(). This is especially\n useful, if memory is an issue and the analysis data is not required for further\n computation.\n\n \\note\n Calling \\p rocsparse_csric0_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csric0_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete Cholesky factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csric0 computes the incomplete Cholesky factorization with 0 fill-ins\n and no pivoting of a sparse \\f$m \\times m\\f$ CSR matrix \\f$A\\f$, such that\n \\f[\n A \\approx LL^T\n \\f]\n\n \\p rocsparse_csric0 requires a user allocated temporary buffer. Its size is returned\n by rocsparse_scsric0_buffer_size() or rocsparse_dcsric0_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_scsric0_analysis()\n or rocsparse_dcsric0_analysis(). \\p rocsparse_csric0 reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be obtained by\n calling rocsparse_csric0_zero_pivot().\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[inout]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr\n or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the sparse \\f$m \\times m\\f$ matrix \\f$A\\f$, stored in CSR\n storage format. The following example computes the incomplete Cholesky factorization\n \\f$M \\approx LL^T\\f$ and solves the preconditioned system \\f$My = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor for M\n rocsparse_mat_descr descr_M;\n rocsparse_create_mat_descr(&descr_M);\n\n // Create matrix descriptor for L\n rocsparse_mat_descr descr_L;\n rocsparse_create_mat_descr(&descr_L);\n rocsparse_set_mat_fill_mode(descr_L, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr_L, rocsparse_diag_type_unit);\n\n // Create matrix descriptor for L'\n rocsparse_mat_descr descr_Lt;\n rocsparse_create_mat_descr(&descr_Lt);\n rocsparse_set_mat_fill_mode(descr_Lt, rocsparse_fill_mode_upper);\n rocsparse_set_mat_diag_type(descr_Lt, rocsparse_diag_type_non_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size_M;\n size_t buffer_size_L;\n size_t buffer_size_Lt;\n rocsparse_dcsric0_buffer_size(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_M);\n rocsparse_dcsrsv_buffer_size(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_L);\n rocsparse_dcsrsv_buffer_size(handle,\n rocsparse_operation_transpose,\n m,\n nnz,\n descr_Lt,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_Lt);\n\n size_t buffer_size = max(buffer_size_M, max(buffer_size_L, buffer_size_Lt));\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis steps, using rocsparse_analysis_policy_reuse to improve\n // computation performance\n rocsparse_dcsric0_analysis(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dcsrsv_analysis(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dcsrsv_analysis(handle,\n rocsparse_operation_transpose,\n m,\n nnz,\n descr_Lt,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n rocsparse_int position;\n if(rocsparse_status_zero_pivot == rocsparse_csric0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"A has structural zero at A(%d,%d)\\n\", position, position);\n }\n\n // Compute incomplete Cholesky factorization M = LL'\n rocsparse_dcsric0(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n if(rocsparse_status_zero_pivot == rocsparse_csric0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"L has structural and/or numerical zero at L(%d,%d)\\n\",\n position,\n position);\n }\n\n // Solve Lz = x\n rocsparse_dcsrsv_solve(handle,\n rocsparse_operation_none,\n m,\n nnz,\n &alpha,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n x,\n z,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve L'y = z\n rocsparse_dcsrsv_solve(handle,\n rocsparse_operation_transpose,\n m,\n nnz,\n &alpha,\n descr_Lt,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n z,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr_M);\n rocsparse_destroy_mat_descr(descr_L);\n rocsparse_destroy_mat_descr(descr_Lt);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsric0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsric0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsric0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsric0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csrilu0_zero_pivot returns \\ref rocsparse_status_zero_pivot, if either a\n structural or numerical zero has been found during rocsparse_scsrilu0(),\n rocsparse_dcsrilu0(), rocsparse_ccsrilu0() or rocsparse_zcsrilu0() computation. The\n first zero pivot \\f$j\\f$ at \\f$A_{j,j}\\f$ is stored in \\p position, using same index\n base as the CSR matrix.\n\n \\p position can be in host or device memory. If no zero pivot has been found,\n \\p position is set to -1 and \\ref rocsparse_status_success is returned instead.\n\n \\note \\p rocsparse_csrilu0_zero_pivot is a blocking function. It might influence\n performance negatively.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[inout]\n position pointer to zero pivot \\f$j\\f$, can be in host or device memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info or \\p position pointer is\n invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot zero pivot has been found."] + pub fn rocsparse_csrilu0_zero_pivot( + handle: rocsparse_handle, + info: rocsparse_mat_info, + position: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR storage\n format\n\n \\details\n \\p rocsparse_csrilu0_numeric_boost enables the user to replace a numerical value in\n an incomplete LU factorization. \\p tol is used to determine whether a numerical value\n is replaced by \\p boost_val, such that \\f$A_{j,j} = \\text{boost_val}\\f$ if\n \\f$\\text{tol} \\ge \\left|A_{j,j}\\right|\\f$.\n\n \\note The boost value is enabled by setting \\p enable_boost to 1 or disabled by\n setting \\p enable_boost to 0.\n\n \\note \\p tol and \\p boost_val can be in host or device memory.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n enable_boost enable/disable numeric boost.\n @param[in]\n boost_tol tolerance to determine whether a numerical value is replaced or not.\n @param[in]\n boost_val boost value to replace a numerical value.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info, \\p tol or \\p boost_val pointer\n is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_scsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f32, + boost_val: *const f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f32, + boost_val: *const rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dscsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dccsrilu0_numeric_boost( + handle: rocsparse_handle, + info: rocsparse_mat_info, + enable_boost: ::std::os::raw::c_int, + boost_tol: *const f64, + boost_val: *const rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csrilu0_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis(), rocsparse_zcsrilu0_analysis(), rocsparse_scsrilu0(),\n rocsparse_dcsrilu0(), rocsparse_ccsrilu0() and rocsparse_zcsrilu0(). The temporary\n storage buffer must be allocated by the user. The size of the temporary storage\n buffer is identical to the size returned by rocsparse_scsrsv_buffer_size(),\n rocsparse_dcsrsv_buffer_size(), rocsparse_ccsrsv_buffer_size() and\n rocsparse_zcsrsv_buffer_size() if the matrix sparsity pattern is identical. The user\n allocated buffer can thus be shared between subsequent calls to those functions.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during the analysis step.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis(), rocsparse_zcsrilu0_analysis(),\n rocsparse_scsrilu0(), rocsparse_dcsrilu0(), rocsparse_ccsrilu0() and\n rocsparse_zcsrilu0().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrilu0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrilu0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrilu0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrilu0_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csrilu0_analysis performs the analysis step for rocsparse_scsrilu0(),\n rocsparse_dcsrilu0(), rocsparse_ccsrilu0() and rocsparse_zcsrilu0(). It is expected\n that this function will be executed only once for a given matrix and particular\n operation type. The analysis meta data can be cleared by rocsparse_csrilu0_clear().\n\n \\p rocsparse_csrilu0_analysis can share its meta data with\n rocsparse_scsric0_analysis(), rocsparse_dcsric0_analysis(),\n rocsparse_ccsric0_analysis(), rocsparse_zcsric0_analysis(),\n rocsparse_scsrsv_analysis(), rocsparse_dcsrsv_analysis(),\n rocsparse_ccsrsv_analysis(), rocsparse_zcsrsv_analysis(),\n rocsparse_scsrsm_analysis(), rocsparse_dcsrsm_analysis(),\n rocsparse_scsrsm_analysis() and rocsparse_dcsrsm_analysis(). Selecting\n \\ref rocsparse_analysis_policy_reuse policy can greatly improve computation\n performance of meta data. However, the user need to make sure that the sparsity\n pattern remains unchanged. If this cannot be assured,\n \\ref rocsparse_analysis_policy_force has to be used.\n\n \\note\n If the matrix sparsity pattern changes, the gathered information will become invalid.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n info structure that holds the information collected during\n the analysis step.\n @param[in]\n analysis \\ref rocsparse_analysis_policy_reuse or\n \\ref rocsparse_analysis_policy_force.\n @param[in]\n solve \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p info or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n/\n/**@{"] + pub fn rocsparse_scsrilu0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrilu0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrilu0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrilu0_analysis( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + analysis: rocsparse_analysis_policy, + solve: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csrilu0_clear deallocates all memory that was allocated by\n rocsparse_scsrilu0_analysis(), rocsparse_dcsrilu0_analysis(),\n rocsparse_ccsrilu0_analysis() or rocsparse_zcsrilu0_analysis(). This is especially\n useful, if memory is an issue and the analysis data is not required for further\n computation.\n\n \\note\n Calling \\p rocsparse_csrilu0_clear is optional. All allocated resources will be\n cleared, when the opaque \\ref rocsparse_mat_info struct is destroyed using\n rocsparse_destroy_mat_info().\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n info structure that holds the information collected during the analysis step.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p info pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer holding the meta data could not\n be deallocated.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csrilu0_clear( + handle: rocsparse_handle, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format\n\n \\details\n \\p rocsparse_csrilu0 computes the incomplete LU factorization with 0 fill-ins and no\n pivoting of a sparse \\f$m \\times m\\f$ CSR matrix \\f$A\\f$, such that\n \\f[\n A \\approx LU\n \\f]\n\n \\p rocsparse_csrilu0 requires a user allocated temporary buffer. Its size is returned\n by rocsparse_scsrilu0_buffer_size(), rocsparse_dcsrilu0_buffer_size(),\n rocsparse_ccsrilu0_buffer_size() or rocsparse_zcsrilu0_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_scsrilu0_analysis(),\n rocsparse_dcsrilu0_analysis(), rocsparse_ccsrilu0_analysis() or\n rocsparse_zcsrilu0_analysis(). \\p rocsparse_csrilu0 reports the first zero pivot\n (either numerical or structural zero). The zero pivot status can be obtained by\n calling rocsparse_csrilu0_zero_pivot().\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix.\n @param[inout]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n info structure that holds the information collected during the analysis step.\n @param[in]\n policy \\ref rocsparse_solve_policy_auto.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr\n or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\p trans != \\ref rocsparse_operation_none or\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n Consider the sparse \\f$m \\times m\\f$ matrix \\f$A\\f$, stored in CSR\n storage format. The following example computes the incomplete LU factorization\n \\f$M \\approx LU\\f$ and solves the preconditioned system \\f$My = x\\f$.\n \\code{.c}\n // Create rocSPARSE handle\n rocsparse_handle handle;\n rocsparse_create_handle(&handle);\n\n // Create matrix descriptor for M\n rocsparse_mat_descr descr_M;\n rocsparse_create_mat_descr(&descr_M);\n\n // Create matrix descriptor for L\n rocsparse_mat_descr descr_L;\n rocsparse_create_mat_descr(&descr_L);\n rocsparse_set_mat_fill_mode(descr_L, rocsparse_fill_mode_lower);\n rocsparse_set_mat_diag_type(descr_L, rocsparse_diag_type_unit);\n\n // Create matrix descriptor for U\n rocsparse_mat_descr descr_U;\n rocsparse_create_mat_descr(&descr_U);\n rocsparse_set_mat_fill_mode(descr_U, rocsparse_fill_mode_upper);\n rocsparse_set_mat_diag_type(descr_U, rocsparse_diag_type_non_unit);\n\n // Create matrix info structure\n rocsparse_mat_info info;\n rocsparse_create_mat_info(&info);\n\n // Obtain required buffer size\n size_t buffer_size_M;\n size_t buffer_size_L;\n size_t buffer_size_U;\n rocsparse_dcsrilu0_buffer_size(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_M);\n rocsparse_dcsrsv_buffer_size(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_L);\n rocsparse_dcsrsv_buffer_size(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_U,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n &buffer_size_U);\n\n size_t buffer_size = max(buffer_size_M, max(buffer_size_L, buffer_size_U));\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // Perform analysis steps, using rocsparse_analysis_policy_reuse to improve\n // computation performance\n rocsparse_dcsrilu0_analysis(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dcsrsv_analysis(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n rocsparse_dcsrsv_analysis(handle,\n rocsparse_operation_none,\n m,\n nnz,\n descr_U,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_analysis_policy_reuse,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n rocsparse_int position;\n if(rocsparse_status_zero_pivot == rocsparse_csrilu0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"A has structural zero at A(%d,%d)\\n\", position, position);\n }\n\n // Compute incomplete LU factorization\n rocsparse_dcsrilu0(handle,\n m,\n nnz,\n descr_M,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Check for zero pivot\n if(rocsparse_status_zero_pivot == rocsparse_csrilu0_zero_pivot(handle,\n info,\n &position))\n {\n printf(\"U has structural and/or numerical zero at U(%d,%d)\\n\",\n position,\n position);\n }\n\n // Solve Lz = x\n rocsparse_dcsrsv_solve(handle,\n rocsparse_operation_none,\n m,\n nnz,\n &alpha,\n descr_L,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n x,\n z,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Solve Uy = z\n rocsparse_dcsrsv_solve(handle,\n rocsparse_operation_none,\n m,\n nnz,\n &alpha,\n descr_U,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n info,\n z,\n y,\n rocsparse_solve_policy_auto,\n temp_buffer);\n\n // Clean up\n hipFree(temp_buffer);\n rocsparse_destroy_mat_info(info);\n rocsparse_destroy_mat_descr(descr_M);\n rocsparse_destroy_mat_descr(descr_L);\n rocsparse_destroy_mat_descr(descr_U);\n rocsparse_destroy_handle(handle);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsrilu0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrilu0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrilu0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrilu0( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + policy: rocsparse_solve_policy, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Iterative Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format.\n\n \\details\n \\p rocsparse_csritilu0_buffer_size computes the size in bytes of the buffer that has to be allocated by the user.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to use, \\ref rocsparse_itilu0_alg\n @param[in]\n option combination of enumeration values from \\ref rocsparse_itilu0_option.\n @param[in]\n nmaxiter maximum number of iterations.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n datatype Type of numerical values, \\ref rocsparse_datatype.\n @param[out]\n buffer_size size of the temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_value \\p alg, \\p base or datatype is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr\n or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_zero_pivot if nnz is zero.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csritilu0_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: rocsparse_int, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + datatype: rocsparse_datatype, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Iterative Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format.\n\n \\details\n \\p rocsparse_csritilu0_preprocess computes the information required to run \\ref rocsparse_scsritilu0_compute,\n \\ref rocsparse_dcsritilu0_compute, \\ref rocsparse_ccsritilu0_compute, or \\ref rocsparse_zcsritilu0_compute,\n and stores it in the buffer.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to use, \\ref rocsparse_itilu0_alg\n @param[in]\n option combination of enumeration values from \\ref rocsparse_itilu0_option.\n @param[in]\n nmaxiter maximum number of iterations.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n datatype Type of numerical values, \\ref rocsparse_datatype.\n @param[in]\n buffer_size size of the storage buffer allocated by the user.\n @param[in]\n buffer storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_value \\p alg, \\p base or datatype is invalid.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr\n or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_zero_pivot if missing diagonal element is detected."] + pub fn rocsparse_csritilu0_preprocess( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: rocsparse_int, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + idx_base: rocsparse_index_base, + datatype: rocsparse_datatype, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Iterative Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format.\n\n \\details\n \\p rocsparse_csritilu0_compute computes iteratively the incomplete LU factorization with 0 fill-ins and no\n pivoting of a sparse \\f$m \\times m\\f$ CSR matrix \\f$A\\f$, such that\n \\f[\n A \\approx LU\n \\f]\n\n \\p rocsparse_csritilu0 requires a user allocated temporary buffer. Its size is returned\n by rocsparse_csritilu0_buffer_size(). Furthermore,\n analysis meta data is required. It can be obtained by rocsparse_csritlu0_preprocess().\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is blocking with respect to the host.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to use, \\ref rocsparse_itilu0_alg\n @param[in]\n option combination of enumeration values from \\ref rocsparse_itilu0_option.\n @param[inout]\n nmaxiter maximum number of iterations.\n @param[in]\n tol tolerance to use for stopping criteria.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start\n of every row of the sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[inout]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[out]\n ilu0 incomplete factorization.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n buffer_size size of the storage buffer allocated by the user.\n @param[in]\n buffer storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_value \\p alg or \\p base is invalid.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr\n or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n/\n/**@{"] + pub fn rocsparse_scsritilu0_compute( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: *mut rocsparse_int, + tol: f32, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csr_val: *const f32, + ilu0: *mut f32, + idx_base: rocsparse_index_base, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsritilu0_compute( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: *mut rocsparse_int, + tol: f64, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csr_val: *const f64, + ilu0: *mut f64, + idx_base: rocsparse_index_base, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsritilu0_compute( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: *mut rocsparse_int, + tol: f32, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csr_val: *const rocsparse_float_complex, + ilu0: *mut rocsparse_float_complex, + idx_base: rocsparse_index_base, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsritilu0_compute( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + option: rocsparse_int, + nmaxiter: *mut rocsparse_int, + tol: f64, + m: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csr_val: *const rocsparse_double_complex, + ilu0: *mut rocsparse_double_complex, + idx_base: rocsparse_index_base, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Iterative Incomplete LU factorization with 0 fill-ins and no pivoting using CSR\n storage format.\n\n \\details\n \\p rocsparse_csritilu0_history fetches convergence history data.\n\n \\note\n The sparse CSR matrix has to be sorted. This can be achieved by calling\n rocsparse_csrsort().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to use, \\ref rocsparse_itilu0_alg\n @param[out]\n niter number of performed iterations.\n @param[out]\n data norms.\n @param[in]\n buffer_size size of the buffer allocated by the user.\n @param[in]\n buffer buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p niter or \\p data is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n/\n/**@{"] + pub fn rocsparse_scsritilu0_history( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + niter: *mut rocsparse_int, + data: *mut f32, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsritilu0_history( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + niter: *mut rocsparse_int, + data: *mut f64, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsritilu0_history( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + niter: *mut rocsparse_int, + data: *mut f32, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsritilu0_history( + handle: rocsparse_handle, + alg: rocsparse_itilu0_alg, + niter: *mut rocsparse_int, + data: *mut f64, + buffer_size: usize, + buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Tridiagonal solver with pivoting\n\n \\details\n \\p rocsparse_gtsv_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sgtsv(), rocsparse_dgtsv(),\n rocsparse_cgtsv() and rocsparse_zgtsv(). The temporary storage buffer\n must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system (must be >= 2).\n @param[in]\n n number of columns in the dense matrix B.\n @param[in]\n dl lower diagonal of tri-diagonal system. First entry must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. Last entry must be zero.\n @param[in]\n B Dense matrix of size ( \\p ldb, \\p n ).\n @param[in]\n ldb Leading dimension of B. Must satisfy \\p ldb >= max(1, m).\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sgtsv(), rocsparse_dgtsv(), rocsparse_cgtsv()\n and rocsparse_zgtsv().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ldb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d, \\p du,\n \\p B or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *const f32, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *const f64, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Tridiagonal solver with pivoting\n\n \\details\n \\p rocsparse_gtsv solves a tridiagonal system for multiple right hand sides using pivoting.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system (must be >= 2).\n @param[in]\n n number of columns in the dense matrix B.\n @param[in]\n dl lower diagonal of tri-diagonal system. First entry must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. Last entry must be zero.\n @param[inout]\n B Dense matrix of size ( \\p ldb, \\p n ).\n @param[in]\n ldb Leading dimension of B. Must satisfy \\p ldb >= max(1, m).\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ldb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d,\n \\p du, \\p B or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *mut f32, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *mut f64, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + B: *mut rocsparse_float_complex, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + B: *mut rocsparse_double_complex, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Tridiagonal solver (no pivoting)\n\n \\details\n \\p rocsparse_gtsv_no_pivot_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sgtsv_no_pivot(), rocsparse_dgtsv_no_pivot(),\n rocsparse_cgtsv_no_pivot() and rocsparse_zgtsv_no_pivot(). The temporary storage buffer\n must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system (must be >= 2).\n @param[in]\n n number of columns in the dense matrix B.\n @param[in]\n dl lower diagonal of tri-diagonal system. First entry must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. Last entry must be zero.\n @param[in]\n B Dense matrix of size ( \\p ldb, \\p n ).\n @param[in]\n ldb Leading dimension of B. Must satisfy \\p ldb >= max(1, m).\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sgtsv_no_pivot(), rocsparse_dgtsv_no_pivot(), rocsparse_cgtsv_no_pivot()\n and rocsparse_zgtsv_no_pivot().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ldb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d, \\p du,\n \\p B or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_no_pivot_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *const f32, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_no_pivot_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *const f64, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_no_pivot_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + B: *const rocsparse_float_complex, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_no_pivot_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + B: *const rocsparse_double_complex, + ldb: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Tridiagonal solver (no pivoting)\n\n \\details\n \\p rocsparse_gtsv_no_pivot solves a tridiagonal linear system for multiple right-hand sides\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system (must be >= 2).\n @param[in]\n n number of columns in the dense matrix B.\n @param[in]\n dl lower diagonal of tri-diagonal system. First entry must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. Last entry must be zero.\n @param[inout]\n B Dense matrix of size ( \\p ldb, \\p n ).\n @param[in]\n ldb Leading dimension of B. Must satisfy \\p ldb >= max(1, m).\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ldb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d,\n \\p du, \\p B or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_no_pivot( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *mut f32, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_no_pivot( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *mut f64, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_no_pivot( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + B: *mut rocsparse_float_complex, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_no_pivot( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + B: *mut rocsparse_double_complex, + ldb: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Strided Batch tridiagonal solver (no pivoting)\n\n \\details\n \\p rocsparse_gtsv_no_pivot_strided_batch_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sgtsv_no_pivot_strided_batch(), rocsparse_dgtsv_no_pivot_strided_batch(),\n rocsparse_cgtsv_no_pivot_strided_batch() and rocsparse_zgtsv_no_pivot_strided_batch(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system.\n @param[in]\n dl lower diagonal of tri-diagonal system where the ith system lower diagonal starts at \\p dl+batch_stride*i.\n @param[in]\n d main diagonal of tri-diagonal system where the ith system diagonal starts at \\p d+batch_stride*i.\n @param[in]\n du upper diagonal of tri-diagonal system where the ith system upper diagonal starts at \\p du+batch_stride*i.\n @param[inout]\n x Dense array of righthand-sides where the ith righthand-side starts at \\p x+batch_stride*i.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate each system. Must satisfy \\p batch_stride >= m.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sgtsv_no_pivot_strided_batch(), rocsparse_dgtsv_no_pivot_strided_batch(), rocsparse_cgtsv_no_pivot_strided_batch()\n and rocsparse_zgtsv_no_pivot_strided_batch().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p batch_count or \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d, \\p du,\n \\p x or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_no_pivot_strided_batch_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *const f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_no_pivot_strided_batch_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *const f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_no_pivot_strided_batch_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + x: *const rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_no_pivot_strided_batch_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + x: *const rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Strided Batch tridiagonal solver (no pivoting)\n\n \\details\n \\p rocsparse_gtsv_no_pivot_strided_batch solves a batched tridiagonal linear system\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m size of the tri-diagonal linear system (must be >= 2).\n @param[in]\n dl lower diagonal of tri-diagonal system. First entry must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. Last entry must be zero.\n @param[inout]\n x Dense array of righthand-sides where the ith righthand-side starts at \\p x+batch_stride*i.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate each system. Must satisfy \\p batch_stride >= m.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p batch_count or \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d,\n \\p du, \\p x or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_no_pivot_strided_batch( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *mut f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_no_pivot_strided_batch( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *mut f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_no_pivot_strided_batch( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + x: *mut rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_no_pivot_strided_batch( + handle: rocsparse_handle, + m: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + x: *mut rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Interleaved Batch tridiagonal solver\n\n \\details\n \\p rocsparse_gtsv_interleaved_batch_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sgtsv_interleaved_batch(), rocsparse_dgtsv_interleaved_batch(),\n rocsparse_cgtsv_interleaved_batch() and rocsparse_zgtsv_interleaved_batch(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg Algorithm to use when solving tridiagonal systems. Options are thomas ( \\p rocsparse_gtsv_interleaved_thomas ),\n LU ( \\p rocsparse_gtsv_interleaved_lu ), or QR ( \\p rocsparse_gtsv_interleaved_qr ). Passing\n \\p rocsparse_gtsv_interleaved_default defaults the algorithm to use QR. Thomas algorithm is the fastest but is not\n stable while LU and QR are slower but are stable.\n @param[in]\n m size of the tri-diagonal linear system.\n @param[in]\n dl lower diagonal of tri-diagonal system. The first element of the lower diagonal must be zero.\n @param[in]\n d main diagonal of tri-diagonal system.\n @param[in]\n du upper diagonal of tri-diagonal system. The last element of the upper diagonal must be zero.\n @param[inout]\n x Dense array of righthand-sides with dimension \\p batch_stride by \\p m.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate consecutive elements in a system. Must satisfy \\p batch_stride >= batch_count.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sgtsv_interleaved_batch(), rocsparse_dgtsv_interleaved_batch(), rocsparse_cgtsv_interleaved_batch()\n and rocsparse_zgtsv_interleaved_batch().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p batch_count, \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d, \\p du,\n \\p x or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *const f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *const f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + x: *const rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + x: *const rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Interleaved Batch tridiagonal solver\n\n \\details\n \\p rocsparse_gtsv_interleaved_batch solves a batched tridiagonal linear system. The routine requires a temporary storage\n buffer that must be allocated by the user. The size of this buffer can be determined by first calling\n \\p rocsparse_gtsv_interleaved_batch_buffer_size. The user can specify different algorithms for \\p rocsparse_gtsv_interleaved_batch\n to use. Options are thomas ( \\p rocsparse_gtsv_interleaved_thomas ), LU ( \\p rocsparse_gtsv_interleaved_lu ),\n or QR ( \\p rocsparse_gtsv_interleaved_qr ). Passing \\p rocsparse_gtsv_interleaved_default defaults the algorithm to use QR.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg Algorithm to use when solving tridiagonal systems. Options are thomas ( \\p rocsparse_gtsv_interleaved_thomas ),\n LU ( \\p rocsparse_gtsv_interleaved_lu ), or QR ( \\p rocsparse_gtsv_interleaved_qr ). Passing\n \\p rocsparse_gtsv_interleaved_default defaults the algorithm to use QR. Thomas algorithm is the fastest but is not\n stable while LU and QR are slower but are stable.\n @param[in]\n m size of the tri-diagonal linear system.\n @param[inout]\n dl lower diagonal of tri-diagonal system. The first element of the lower diagonal must be zero.\n @param[inout]\n d main diagonal of tri-diagonal system.\n @param[inout]\n du upper diagonal of tri-diagonal system. The last element of the upper diagonal must be zero.\n @param[inout]\n x Dense array of righthand-sides with dimension \\p batch_stride by \\p m.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate consecutive elements in a system. Must satisfy \\p batch_stride >= batch_count.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p batch_count or \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p dl, \\p d,\n \\p du, \\p x or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgtsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *mut f32, + d: *mut f32, + du: *mut f32, + x: *mut f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgtsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *mut f64, + d: *mut f64, + du: *mut f64, + x: *mut f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgtsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *mut rocsparse_float_complex, + d: *mut rocsparse_float_complex, + du: *mut rocsparse_float_complex, + x: *mut rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgtsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gtsv_interleaved_alg, + m: rocsparse_int, + dl: *mut rocsparse_double_complex, + d: *mut rocsparse_double_complex, + du: *mut rocsparse_double_complex, + x: *mut rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Batched Pentadiagonal solver\n\n \\details\n \\p rocsparse_gpsv_interleaved_batch_buffer_size calculates the required buffer size\n for rocsparse_gpsv_interleaved_batch(). It is the users responsibility to allocate\n this buffer.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to solve the linear system.\n @param[in]\n m size of the pentadiagonal linear system.\n @param[in]\n ds lower diagonal (distance 2) of pentadiagonal system. First two entries\n must be zero.\n @param[in]\n dl lower diagonal of pentadiagonal system. First entry must be zero.\n @param[in]\n d main diagonal of pentadiagonal system.\n @param[in]\n du upper diagonal of pentadiagonal system. Last entry must be zero.\n @param[in]\n dw upper diagonal (distance 2) of pentadiagonal system. Last two entries\n must be zero.\n @param[in]\n x Dense array of right-hand-sides with dimension \\p batch_stride by \\p m.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate consecutive elements in a system.\n Must satisfy \\p batch_stride >= batch_count.\n @param[out]\n buffer_size Number of bytes of the temporary storage buffer required.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p alg, \\p batch_count or\n \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p ds, \\p dl, \\p d, \\p du, \\p dw, \\p x\n or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgpsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *const f32, + dl: *const f32, + d: *const f32, + du: *const f32, + dw: *const f32, + x: *const f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgpsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *const f64, + dl: *const f64, + d: *const f64, + du: *const f64, + dw: *const f64, + x: *const f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgpsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *const rocsparse_float_complex, + dl: *const rocsparse_float_complex, + d: *const rocsparse_float_complex, + du: *const rocsparse_float_complex, + dw: *const rocsparse_float_complex, + x: *const rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgpsv_interleaved_batch_buffer_size( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *const rocsparse_double_complex, + dl: *const rocsparse_double_complex, + d: *const rocsparse_double_complex, + du: *const rocsparse_double_complex, + dw: *const rocsparse_double_complex, + x: *const rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup precond_module\n \\brief Batched Pentadiagonal solver\n\n \\details\n \\p rocsparse_gpsv_interleaved_batch solves a batch of pentadiagonal linear systems.\n The coefficient matrix of each pentadiagonal linear system is defined by five vectors\n for the lower part (ds, dl), main diagonal (d) and upper part (du, dw).\n\n The function requires a temporary buffer. The size of the required buffer is returned\n by rocsparse_gpsv_interleaved_batch_buffer_size().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n The routine is numerically stable because it uses QR to solve the linear systems.\n\n \\note\n m need to be at least 3, to be a valid pentadiagonal matrix.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alg algorithm to solve the linear system.\n @param[in]\n m size of the pentadiagonal linear system.\n @param[inout]\n ds lower diagonal (distance 2) of pentadiagonal system. First two entries\n must be zero.\n @param[inout]\n dl lower diagonal of pentadiagonal system. First entry must be zero.\n @param[inout]\n d main diagonal of pentadiagonal system.\n @param[inout]\n du upper diagonal of pentadiagonal system. Last entry must be zero.\n @param[inout]\n dw upper diagonal (distance 2) of pentadiagonal system. Last two entries\n must be zero.\n @param[inout]\n x Dense array of right-hand-sides with dimension \\p batch_stride by \\p m.\n @param[in]\n batch_count The number of systems to solve.\n @param[in]\n batch_stride The number of elements that separate consecutive elements in a system.\n Must satisfy \\p batch_stride >= batch_count.\n @param[in]\n temp_buffer Temporary storage buffer allocated by the user.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p alg, \\p batch_count or\n \\p batch_stride is invalid.\n \\retval rocsparse_status_invalid_pointer \\p ds, \\p dl, \\p d, \\p du, \\p dw, \\p x\n or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgpsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *mut f32, + dl: *mut f32, + d: *mut f32, + du: *mut f32, + dw: *mut f32, + x: *mut f32, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgpsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *mut f64, + dl: *mut f64, + d: *mut f64, + du: *mut f64, + dw: *mut f64, + x: *mut f64, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgpsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *mut rocsparse_float_complex, + dl: *mut rocsparse_float_complex, + d: *mut rocsparse_float_complex, + du: *mut rocsparse_float_complex, + dw: *mut rocsparse_float_complex, + x: *mut rocsparse_float_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgpsv_interleaved_batch( + handle: rocsparse_handle, + alg: rocsparse_gpsv_interleaved_alg, + m: rocsparse_int, + ds: *mut rocsparse_double_complex, + dl: *mut rocsparse_double_complex, + d: *mut rocsparse_double_complex, + du: *mut rocsparse_double_complex, + dw: *mut rocsparse_double_complex, + x: *mut rocsparse_double_complex, + batch_count: rocsparse_int, + batch_stride: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the number of nonzero elements per row or column and the total number of nonzero elements in a dense matrix.\n \\details\n The routine does support asynchronous execution if the pointer mode is set to device.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by \\ref rocsparse_direction_row.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p ld, \\p n)\n\n @param[in]\n ld leading dimension of dense array \\p A.\n\n @param[out]\n nnz_per_row_columns\n array of size \\p m or \\p n containing the number of nonzero elements per row or column, respectively.\n @param[out]\n nnz_total_dev_host_ptr\n total number of nonzero elements in device or host memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p nnz_per_row_columns or \\p nnz_total_dev_host_ptr\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_snnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f32, + ld: rocsparse_int, + nnz_per_row_columns: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dnnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f64, + ld: rocsparse_int, + nnz_per_row_columns: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cnnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_float_complex, + ld: rocsparse_int, + nnz_per_row_columns: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_znnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_double_complex, + ld: rocsparse_int, + nnz_per_row_columns: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the matrix A in dense format into a sparse matrix in CSR format.\n All the parameters are assumed to have been pre-allocated by the user and the arrays are filled in based on nnz_per_row, which can be pre-computed with rocsparse_xnnz().\n\n \\note\n This function is blocking with respect to the host.\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n A array of dimensions (\\p ld, \\p n)\n\n @param[in]\n ld leading dimension of dense array \\p A.\n\n @param[in]\n nnz_per_rows array of size \\p n containing the number of non-zero elements per row.\n\n @param[out]\n csr_val\n array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n @param[out]\n csr_row_ptr\n integer array of m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[out]\n csr_col_ind\n integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p nnz_per_rows or \\p csr_val \\p csr_row_ptr or \\p csr_col_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sdense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f32, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + csr_val: *mut f32, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ddense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f64, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + csr_val: *mut f64, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cdense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_float_complex, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zdense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_double_complex, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the the size of the user allocated temporary storage buffer used when converting and pruning\n a dense matrix to a CSR matrix.\n\n \\details\n \\p rocsparse_prune_dense2csr_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_sprune_dense2csr_nnz(), rocsparse_dprune_dense2csr_nnz(),\n rocsparse_sprune_dense2csr(), and rocsparse_dprune_dense2csr(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n threshold pointer to the pruning non-negative threshold which can exist in either host or device memory.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n csr_val\n array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n @param[in]\n csr_row_ptr\n integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[in]\n csr_col_ind\n integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sprune_dense2csr_nnz(), rocsparse_dprune_dense2csr_nnz(),\n rocsparse_sprune_dense2csr() and rocsparse_dprune_dense2csr().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + threshold: *const f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + threshold: *const f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the number of nonzero elements per row and the total number of nonzero elements in a dense matrix once\n elements less than the threshold are pruned from the matrix.\n\n \\details\n The routine does support asynchronous execution if the pointer mode is set to device.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n threshold pointer to the pruning non-negative threshold which can exist in either host or device memory.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A.\n\n @param[out]\n csr_row_ptr\n integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[out]\n nnz_total_dev_host_ptr\n total number of nonzero elements in device or host memory.\n\n @param[out]\n temp_buffer\n buffer allocated by the user whose size is determined by calling rocsparse_xprune_dense2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p lda is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p threshold or \\p descr or \\p csr_row_ptr\n or \\p nnz_total_dev_host_ptr or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + threshold: *const f32, + descr: rocsparse_mat_descr, + csr_row_ptr: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + threshold: *const f64, + descr: rocsparse_mat_descr, + csr_row_ptr: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the matrix A in dense format into a sparse matrix in CSR format while pruning values\n that are less than the threshold. All the parameters are assumed to have been pre-allocated by the user.\n\n \\details\n The user first allocates \\p csr_row_ptr to have \\p m+1 elements and then calls rocsparse_xprune_dense2csr_nnz()\n which fills in the \\p csr_row_ptr array and stores the number of elements that are larger than the pruning threshold\n in \\p nnz_total_dev_host_ptr. The user then allocates \\p csr_col_ind and \\p csr_val to have size \\p nnz_total_dev_host_ptr\n and completes the conversion by calling rocsparse_xprune_dense2csr(). A temporary storage buffer is used by both\n rocsparse_xprune_dense2csr_nnz() and rocsparse_xprune_dense2csr() and must be allocated by the user and whose size is determined\n by rocsparse_xprune_dense2csr_buffer_size().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n threshold pointer to the non-negative pruning threshold which can exist in either host or device memory.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[out]\n csr_val\n array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n @param[in]\n csr_row_ptr\n integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[out]\n csr_col_ind\n integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_xprune_dense2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p lda is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p descr or \\p threshold or \\p csr_val\n or \\p csr_row_ptr or \\p csr_col_ind or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + threshold: *const f32, + descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + threshold: *const f64, + descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the size of the user allocated temporary storage buffer used when converting and pruning by percentage a\n dense matrix to a CSR matrix.\n\n \\details\n When converting and pruning a dense matrix A to a CSR matrix by percentage the following steps are performed. First the user\n calls \\p rocsparse_prune_dense2csr_by_percentage_buffer_size which determines the size of the temporary storage buffer. Once\n determined, this buffer must be allocated by the user. Next the user allocates the csr_row_ptr array to have \\p m+1 elements\n and calls \\p rocsparse_prune_dense2csr_nnz_by_percentage. Finally the user finishes the conversion by allocating the csr_col_ind\n and csr_val arrays (whos size is determined by the value at nnz_total_dev_host_ptr) and calling \\p rocsparse_prune_dense2csr_by_percentage.\n\n The pruning by percentage works by first sorting the absolute values of the dense matrix \\p A. We then determine a position in this\n sorted array by\n \\f[\n pos = ceil(m*n*(percentage/100)) - 1\n pos = min(pos, m*n-1)\n pos = max(pos, 0)\n threshold = sorted_A[pos]\n \\f]\n Once we have this threshold we prune values in the dense matrix \\p A as in \\p rocsparse_prune_dense2csr.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n csr_val array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n\n @param[in]\n csr_row_ptr integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n\n @param[in]\n csr_col_ind integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[in]\n info prune information structure\n\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sprune_dense2csr_nnz_by_percentage(), rocsparse_dprune_dense2csr_nnz_by_percentage(),\n rocsparse_sprune_dense2csr_by_percentage() and rocsparse_dprune_dense2csr_by_percentage().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr_by_percentage_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + percentage: f32, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr_by_percentage_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + percentage: f64, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the number of nonzero elements per row and the total number of nonzero elements in a dense matrix\n when converting and pruning by percentage a dense matrix to a CSR matrix.\n\n \\details\n When converting and pruning a dense matrix A to a CSR matrix by percentage the following steps are performed. First the user\n calls \\p rocsparse_prune_dense2csr_by_percentage_buffer_size which determines the size of the temporary storage buffer. Once\n determined, this buffer must be allocated by the user. Next the user allocates the csr_row_ptr array to have \\p m+1 elements\n and calls \\p rocsparse_prune_dense2csr_nnz_by_percentage. Finally the user finishes the conversion by allocating the csr_col_ind\n and csr_val arrays (whos size is determined by the value at nnz_total_dev_host_ptr) and calling \\p rocsparse_prune_dense2csr_by_percentage.\n\n The pruning by percentage works by first sorting the absolute values of the dense matrix \\p A. We then determine a position in this\n sorted array by\n \\f[\n pos = ceil(m*n*(percentage/100)) - 1\n pos = min(pos, m*n-1)\n pos = max(pos, 0)\n threshold = sorted_A[pos]\n \\f]\n Once we have this threshold we prune values in the dense matrix \\p A as in \\p rocsparse_prune_dense2csr.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A.\n\n @param[out]\n csr_row_ptr integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n\n @param[out]\n nnz_total_dev_host_ptr total number of nonzero elements in device or host memory.\n\n @param[in]\n info prune information structure\n\n @param[out]\n temp_buffer buffer allocated by the user whose size is determined by calling rocsparse_xprune_dense2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p lda or \\p percentage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p descr or \\p info or \\p csr_row_ptr\n or \\p nnz_total_dev_host_ptr or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr_nnz_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + percentage: f32, + descr: rocsparse_mat_descr, + csr_row_ptr: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr_nnz_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + percentage: f64, + descr: rocsparse_mat_descr, + csr_row_ptr: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the matrix A in dense format into a sparse matrix in CSR format while pruning values\n based on percentage.\n\n \\details\n When converting and pruning a dense matrix A to a CSR matrix by percentage the following steps are performed. First the user\n calls \\p rocsparse_prune_dense2csr_by_percentage_buffer_size which determines the size of the temporary storage buffer. Once\n determined, this buffer must be allocated by the user. Next the user allocates the csr_row_ptr array to have \\p m+1 elements\n and calls \\p rocsparse_prune_dense2csr_nnz_by_percentage. Finally the user finishes the conversion by allocating the csr_col_ind\n and csr_val arrays (whos size is determined by the value at nnz_total_dev_host_ptr) and calling \\p rocsparse_prune_dense2csr_by_percentage.\n\n The pruning by percentage works by first sorting the absolute values of the dense matrix \\p A. We then determine a position in this\n sorted array by\n \\f[\n pos = ceil(m*n*(percentage/100)) - 1\n pos = min(pos, m*n-1)\n pos = max(pos, 0)\n threshold = sorted_A[pos]\n \\f]\n Once we have this threshold we prune values in the dense matrix \\p A as in \\p rocsparse_prune_dense2csr.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n A array of dimensions (\\p lda, \\p n)\n\n @param[in]\n lda leading dimension of dense array \\p A.\n\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[out]\n csr_val array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n\n @param[in]\n csr_row_ptr integer array of \\p m+1 elements that contains the start of every row and the end of the last row plus one.\n\n @param[out]\n csr_col_ind integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[in]\n info prune information structure\n\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_xprune_dense2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p lda or \\p percentage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p descr or \\p info or \\p csr_val\n or \\p csr_row_ptr or \\p csr_col_ind or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_dense2csr_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f32, + lda: rocsparse_int, + percentage: f32, + descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_dense2csr_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + A: *const f64, + lda: rocsparse_int, + percentage: f64, + descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n\n This function converts the matrix A in dense format into a sparse matrix in CSC format.\n All the parameters are assumed to have been pre-allocated by the user and the arrays are\n filled in based on nnz_per_columns, which can be pre-computed with rocsparse_xnnz().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n A array of dimensions (\\p ld, \\p n)\n\n @param[in]\n ld leading dimension of dense array \\p A.\n\n @param[in]\n nnz_per_columns array of size \\p n containing the number of non-zero elements per column.\n\n @param[out]\n csc_val\n array of nnz ( = \\p csc_col_ptr[m] - \\p csc_col_ptr[0] ) nonzero elements of matrix \\p A.\n @param[out]\n csc_col_ptr\n integer array of m+1 elements that contains the start of every column and the end of the last column plus one.\n @param[out]\n csc_row_ind\n integer array of nnz ( = \\p csc_col_ptr[m] - csc_col_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p nnz_per_columns or \\p csc_val \\p csc_col_ptr or \\p csc_row_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sdense2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f32, + ld: rocsparse_int, + nnz_per_columns: *const rocsparse_int, + csc_val: *mut f32, + csc_col_ptr: *mut rocsparse_int, + csc_row_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ddense2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f64, + ld: rocsparse_int, + nnz_per_columns: *const rocsparse_int, + csc_val: *mut f64, + csc_col_ptr: *mut rocsparse_int, + csc_row_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cdense2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_float_complex, + ld: rocsparse_int, + nnz_per_columns: *const rocsparse_int, + csc_val: *mut rocsparse_float_complex, + csc_col_ptr: *mut rocsparse_int, + csc_row_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zdense2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_double_complex, + ld: rocsparse_int, + nnz_per_columns: *const rocsparse_int, + csc_val: *mut rocsparse_double_complex, + csc_col_ptr: *mut rocsparse_int, + csc_row_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n\n This function converts the matrix A in dense format into a sparse matrix in COO format.\n All the parameters are assumed to have been pre-allocated by the user and the arrays are\n filled in based on nnz_per_rows, which can be pre-computed with rocsparse_xnnz().\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n A array of dimensions (\\p ld, \\p n)\n\n @param[in]\n ld leading dimension of dense array \\p A.\n\n @param[in]\n nnz_per_rows array of size \\p n containing the number of non-zero elements per row.\n\n @param[out]\n coo_val\n array of nnz nonzero elements of matrix \\p A.\n @param[out]\n coo_row_ind\n integer array of nnz row indices of the non-zero elements of matrix \\p A.\n @param[out]\n coo_col_ind integer array of nnz column indices of the non-zero elements of matrix \\p A.\n\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p nnz_per_rows or \\p coo_val \\p coo_col_ind or \\p coo_row_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sdense2coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f32, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + coo_val: *mut f32, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ddense2coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const f64, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + coo_val: *mut f64, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cdense2coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_float_complex, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + coo_val: *mut rocsparse_float_complex, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zdense2coo( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + A: *const rocsparse_double_complex, + ld: rocsparse_int, + nnz_per_rows: *const rocsparse_int, + coo_val: *mut rocsparse_double_complex, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the sparse matrix in CSR format into a dense matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is \\ref rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n csr_val array of nnz ( = \\p csr_row_ptr[m] - \\p csr_row_ptr[0] ) nonzero elements of matrix \\p A.\n @param[in]\n csr_row_ptr integer array of m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[in]\n csr_col_ind integer array of nnz ( = \\p csr_row_ptr[m] - csr_row_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[out]\n A array of dimensions (\\p ld, \\p n)\n\n @param[out]\n ld leading dimension of dense array \\p A.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p csr_val \\p csr_row_ptr or \\p csr_col_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_scsr2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + A: *mut f32, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + A: *mut f64, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + A: *mut rocsparse_float_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + A: *mut rocsparse_double_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the sparse matrix in CSC format into a dense matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is \\ref rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n csc_val array of nnz ( = \\p csc_col_ptr[m] - \\p csc_col_ptr[0] ) nonzero elements of matrix \\p A.\n @param[in]\n csc_col_ptr integer array of m+1 elements that contains the start of every row and the end of the last row plus one.\n @param[in]\n csc_row_ind integer array of nnz ( = \\p csc_col_ptr[m] - csc_col_ptr[0] ) column indices of the non-zero elements of matrix \\p A.\n\n @param[out]\n A array of dimensions (\\p ld, \\p n)\n\n @param[out]\n ld leading dimension of dense array \\p A.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p csc_val \\p csc_col_ptr or \\p csc_row_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_scsc2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csc_val: *const f32, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + A: *mut f32, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsc2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csc_val: *const f64, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + A: *mut f64, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsc2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csc_val: *const rocsparse_float_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + A: *mut rocsparse_float_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsc2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csc_val: *const rocsparse_double_complex, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + A: *mut rocsparse_double_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the sparse matrix in COO format into a dense matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the dense matrix \\p A.\n\n @param[in]\n n number of columns of the dense matrix \\p A.\n\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[in]\n descr the descriptor of the dense matrix \\p A, the supported matrix type is \\ref rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n coo_val array of nnz nonzero elements of matrix \\p A.\n @param[in]\n coo_row_ind integer array of nnz row indices of the non-zero elements of matrix \\p A.\n\n @param[in]\n coo_col_ind integer array of nnz column indices of the non-zero elements of matrix \\p A.\n @param[out]\n A array of dimensions (\\p ld, \\p n)\n\n @param[out]\n ld leading dimension of dense array \\p A.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p nnz or \\p ld is invalid.\n \\retval rocsparse_status_invalid_pointer \\p A or \\p coo_val \\p coo_col_ind or \\p coo_row_ind\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_scoo2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + coo_val: *const f32, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + A: *mut f32, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcoo2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + coo_val: *const f64, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + A: *mut f64, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccoo2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + coo_val: *const rocsparse_float_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + A: *mut rocsparse_float_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcoo2dense( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + coo_val: *const rocsparse_double_complex, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + A: *mut rocsparse_double_complex, + ld: rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n Given a sparse CSR matrix and a non-negative tolerance, this function computes how many entries would be left\n in each row of the matrix if elements less than the tolerance were removed. It also computes the total number\n of remaining elements in the matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n m number of rows of the sparse CSR matrix.\n\n @param[in]\n descr_A the descriptor of the sparse CSR matrix.\n\n @param[in]\n csr_val_A array of \\p nnz_A elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n uncompressed sparse CSR matrix.\n @param[out]\n nnz_per_row array of length \\p m containing the number of entries that will be kept per row in\n the final compressed CSR matrix.\n @param[out]\n nnz_C number of elements in the column indices and values arrays of the compressed\n sparse CSR matrix. Can be either host or device pointer.\n @param[in]\n tol the non-negative tolerance used for compression. If \\p tol is complex then only the magnitude\n of the real part is used. Entries in the input uncompressed CSR array that are below the tolerance\n are removed in output compressed CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n is invalid.\n \\retval rocsparse_status_invalid_value \\p tol is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val_A or \\p csr_row_ptr_A or \\p nnz_per_row or \\p nnz_C\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_snnz_compress( + handle: rocsparse_handle, + m: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + nnz_per_row: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + tol: f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dnnz_compress( + handle: rocsparse_handle, + m: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + nnz_per_row: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + tol: f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cnnz_compress( + handle: rocsparse_handle, + m: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const rocsparse_float_complex, + csr_row_ptr_A: *const rocsparse_int, + nnz_per_row: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + tol: rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_znnz_compress( + handle: rocsparse_handle, + m: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const rocsparse_double_complex, + csr_row_ptr_A: *const rocsparse_int, + nnz_per_row: *mut rocsparse_int, + nnz_C: *mut rocsparse_int, + tol: rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse COO matrix\n\n \\details\n \\p rocsparse_csr2coo converts the CSR array containing the row offsets, that point\n to the start of every row, into a COO array of row indices.\n\n \\note\n It can also be used to convert a CSC array containing the column offsets into a COO\n array of column indices.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row\n of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[out]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse COO\n matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr or \\p coo_row_ind\n pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n\n \\par Example\n This example converts a CSR matrix into a COO matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m = 3;\n rocsparse_int n = 5;\n rocsparse_int nnz = 8;\n\n csr_row_ptr[m+1] = {0, 3, 5, 8}; // device memory\n csr_col_ind[nnz] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n csr_val[nnz] = {1, 2, 3, 4, 5, 6, 7, 8}; // device memory\n\n // Allocate COO matrix arrays\n rocsparse_int* coo_row_ind;\n rocsparse_int* coo_col_ind;\n float* coo_val;\n\n hipMalloc((void**)&coo_row_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&coo_col_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&coo_val, sizeof(float) * nnz);\n\n // Convert the csr row offsets into coo row indices\n rocsparse_csr2coo(handle,\n csr_row_ptr,\n nnz,\n m,\n coo_row_ind,\n rocsparse_index_base_zero);\n\n // Copy the column and value arrays\n hipMemcpy(coo_col_ind,\n csr_col_ind,\n sizeof(rocsparse_int) * nnz,\n hipMemcpyDeviceToDevice);\n\n hipMemcpy(coo_val,\n csr_val,\n sizeof(float) * nnz,\n hipMemcpyDeviceToDevice);\n \\endcode"] + pub fn rocsparse_csr2coo( + handle: rocsparse_handle, + csr_row_ptr: *const rocsparse_int, + nnz: rocsparse_int, + m: rocsparse_int, + coo_row_ind: *mut rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse CSC matrix\n\n \\details\n \\p rocsparse_csr2csc_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_scsr2csc(), rocsparse_dcsr2csc(), rocsparse_ccsr2csc() and\n rocsparse_zcsr2csc(). The temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n copy_values \\ref rocsparse_action_symbolic or \\ref rocsparse_action_numeric.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_scsr2csc(), rocsparse_dcsr2csc(), rocsparse_ccsr2csc() and\n rocsparse_zcsr2csc().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr, \\p csr_col_ind or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_csr2csc_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + copy_values: rocsparse_action, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse CSC matrix\n\n \\details\n \\p rocsparse_csr2csc converts a CSR matrix into a CSC matrix. \\p rocsparse_csr2csc\n can also be used to convert a CSC matrix into a CSR matrix. \\p copy_values decides\n whether \\p csc_val is being filled during conversion (\\ref rocsparse_action_numeric)\n or not (\\ref rocsparse_action_symbolic).\n\n \\p rocsparse_csr2csc requires extra temporary storage buffer that has to be allocated\n by the user. Storage buffer size can be determined by rocsparse_csr2csc_buffer_size().\n\n \\note\n The resulting matrix can also be seen as the transpose of the input matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n csc_val array of \\p nnz elements of the sparse CSC matrix.\n @param[out]\n csc_row_ind array of \\p nnz elements containing the row indices of the sparse CSC\n matrix.\n @param[out]\n csc_col_ptr array of \\p n+1 elements that point to the start of every column of the\n sparse CSC matrix.\n @param[in]\n copy_values \\ref rocsparse_action_symbolic or \\ref rocsparse_action_numeric.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_csr2csc_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val, \\p csr_row_ptr,\n \\p csr_col_ind, \\p csc_val, \\p csc_row_ind, \\p csc_col_ptr or\n \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n \\par Example\n This example computes the transpose of a CSR matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m_A = 3;\n rocsparse_int n_A = 5;\n rocsparse_int nnz_A = 8;\n\n csr_row_ptr_A[m+1] = {0, 3, 5, 8}; // device memory\n csr_col_ind_A[nnz] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n csr_val_A[nnz] = {1, 2, 3, 4, 5, 6, 7, 8}; // device memory\n\n // Allocate memory for transposed CSR matrix\n rocsparse_int m_T = n_A;\n rocsparse_int n_T = m_A;\n rocsparse_int nnz_T = nnz_A;\n\n rocsparse_int* csr_row_ptr_T;\n rocsparse_int* csr_col_ind_T;\n float* csr_val_T;\n\n hipMalloc((void**)&csr_row_ptr_T, sizeof(rocsparse_int) * (m_T + 1));\n hipMalloc((void**)&csr_col_ind_T, sizeof(rocsparse_int) * nnz_T);\n hipMalloc((void**)&csr_val_T, sizeof(float) * nnz_T);\n\n // Obtain the temporary buffer size\n size_t buffer_size;\n rocsparse_csr2csc_buffer_size(handle,\n m_A,\n n_A,\n nnz_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n rocsparse_action_numeric,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n rocsparse_scsr2csc(handle,\n m_A,\n n_A,\n nnz_A,\n csr_val_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n csr_val_T,\n csr_col_ind_T,\n csr_row_ptr_T,\n rocsparse_action_numeric,\n rocsparse_index_base_zero,\n temp_buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csc_val: *mut f32, + csc_row_ind: *mut rocsparse_int, + csc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csc_val: *mut f64, + csc_row_ind: *mut rocsparse_int, + csc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csc_val: *mut rocsparse_float_complex, + csc_row_ind: *mut rocsparse_int, + csc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2csc( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csc_val: *mut rocsparse_double_complex, + csc_row_ind: *mut rocsparse_int, + csc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse GEneral BSR matrix into a sparse GEneral BSC matrix\n\n \\details\n \\p rocsparse_gebsr2gebsc_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_sgebsr2gebsc(), rocsparse_dgebsr2gebsc(), rocsparse_cgebsr2gebsc() and\n rocsparse_zgebsr2gebsc(). The temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n mb number of rows of the sparse GEneral BSR matrix.\n @param[in]\n nb number of columns of the sparse GEneral BSR matrix.\n @param[in]\n nnzb number of non-zero entries of the sparse GEneral BSR matrix.\n @param[in]\n bsr_val array of \\p nnzb*row_block_dim*col_block_dim containing the values of the sparse GEneral BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every row of the\n sparse GEneral BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the column indices of the sparse\n GEneral BSR matrix.\n @param[in]\n row_block_dim row size of the blocks in the sparse general BSR matrix.\n @param[in]\n col_block_dim col size of the blocks in the sparse general BSR matrix.\n\n @param[out]\n p_buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_sgebsr2gebsc(), rocsparse_dgebsr2gebsc(), rocsparse_cgebsr2gebsc() and\n rocsparse_zgebsr2gebsc().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb or \\p nnzb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_row_ptr, \\p bsr_col_ind or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n/\n/**@{"] + pub fn rocsparse_sgebsr2gebsc_buffer_size( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + p_buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsr2gebsc_buffer_size( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + p_buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsr2gebsc_buffer_size( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + p_buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsr2gebsc_buffer_size( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + p_buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse GEneral BSR matrix into a sparse GEneral BSC matrix\n\n \\details\n \\p rocsparse_gebsr2gebsc converts a GEneral BSR matrix into a GEneral BSC matrix. \\p rocsparse_gebsr2gebsc\n can also be used to convert a GEneral BSC matrix into a GEneral BSR matrix. \\p copy_values decides\n whether \\p bsc_val is being filled during conversion (\\ref rocsparse_action_numeric)\n or not (\\ref rocsparse_action_symbolic).\n\n \\p rocsparse_gebsr2gebsc requires extra temporary storage buffer that has to be allocated\n by the user. Storage buffer size can be determined by rocsparse_gebsr2gebsc_buffer_size().\n\n \\note\n The resulting matrix can also be seen as the transpose of the input matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n mb number of rows of the sparse GEneral BSR matrix.\n @param[in]\n nb number of columns of the sparse GEneral BSR matrix.\n @param[in]\n nnzb number of non-zero entries of the sparse GEneral BSR matrix.\n @param[in]\n bsr_val array of \\p nnzb * \\p row_block_dim * \\p col_block_dim elements of the sparse GEneral BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse GEneral BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnz elements containing the column indices of the sparse\n GEneral BSR matrix.\n @param[in]\n row_block_dim row size of the blocks in the sparse general BSR matrix.\n @param[in]\n col_block_dim col size of the blocks in the sparse general BSR matrix.\n @param[out]\n bsc_val array of \\p nnz elements of the sparse BSC matrix.\n @param[out]\n bsc_row_ind array of \\p nnz elements containing the row indices of the sparse BSC\n matrix.\n @param[out]\n bsc_col_ptr array of \\p n+1 elements that point to the start of every column of the\n sparse BSC matrix.\n @param[in]\n copy_values \\ref rocsparse_action_symbolic or \\ref rocsparse_action_numeric.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_gebsr2gebsc_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb, \\p nb or \\p nnzb is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val, \\p bsr_row_ptr,\n \\p bsr_col_ind, \\p bsc_val, \\p bsc_row_ind, \\p bsc_col_ptr or\n \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_arch_mismatch the device is not supported.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n \\par Example\n This example computes the transpose of a GEneral BSR matrix.\n \\code{.c}\n // 1 2 0 3\n // A = 0 4 5 0\n // 6 0 0 7\n // 1 2 3 4\n\n rocsparse_int mb_A = 2;\n rocsparse_int row_block_dim = 2;\n rocsparse_int col_block_dim = 2;\n rocsparse_int nb_A = 2;\n rocsparse_int nnzb_A = 4;\n\n bsr_row_ptr_A[mb_A+1] = {0, 2, 4}; // device memory\n bsr_col_ind_A[nnzb_A] = {0, 1, 0, 1}; // device memory\n bsr_val_A[nnzb_A] = {1, 0, 2, 4, 0, 5, 3, 0, 6, 1, 0, 2, 0, 3, 7, 4}; // device memory\n\n // Allocate memory for transposed BSR matrix\n rocsparse_int mb_T = nb_A;\n rocsparse_int nb_T = mb_A;\n rocsparse_int nnzb_T = nnzb_A;\n\n rocsparse_int* bsr_row_ptr_T;\n rocsparse_int* bsr_col_ind_T;\n float* bsr_val_T;\n\n hipMalloc((void**)&bsr_row_ptr_T, sizeof(rocsparse_int) * (mb_T + 1));\n hipMalloc((void**)&bsr_col_ind_T, sizeof(rocsparse_int) * nnzb_T);\n hipMalloc((void**)&bsr_val_T, sizeof(float) * nnzb_T);\n\n // Obtain the temporary buffer size\n size_t buffer_size;\n rocsparse_gebsr2gebsc_buffer_size(handle,\n mb_A,\n nb_A,\n nnzb_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n rocsparse_action_numeric,\n &buffer_size);\n\n // Allocate temporary buffer\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n rocsparse_sgebsr2gebsc(handle,\n mb_A,\n nb_A,\n nnzb_A,\n bsr_val_A,\n bsr_row_ptr_A,\n bsr_col_ind_A,\n row_block_dim,\n col_block_dim,\n bsr_val_T,\n bsr_col_ind_T,\n bsr_row_ptr_T,\n rocsparse_action_numeric,\n rocsparse_index_base_zero,\n temp_buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sgebsr2gebsc( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *mut f32, + bsc_row_ind: *mut rocsparse_int, + bsc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsr2gebsc( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *mut f64, + bsc_row_ind: *mut rocsparse_int, + bsc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsr2gebsc( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *mut rocsparse_float_complex, + bsc_row_ind: *mut rocsparse_int, + bsc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsr2gebsc( + handle: rocsparse_handle, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsc_val: *mut rocsparse_double_complex, + bsc_row_ind: *mut rocsparse_int, + bsc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse ELL matrix\n\n \\details\n \\p rocsparse_csr2ell_width computes the maximum of the per row non-zero elements\n over all rows, the ELL \\p width, for a given CSR matrix.\n\n \\note\n This function is blocking with respect to the host.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n ell_descr descriptor of the sparse ELL matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n ell_width pointer to the number of non-zero elements per row in ELL storage\n format.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_descr, \\p csr_row_ptr, or\n \\p ell_width pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_csr2ell_width( + handle: rocsparse_handle, + m: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_row_ptr: *const rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse ELL matrix\n\n \\details\n \\p rocsparse_csr2ell converts a CSR matrix into an ELL matrix. It is assumed,\n that \\p ell_val and \\p ell_col_ind are allocated. Allocation size is computed by the\n number of rows times the number of ELL non-zero elements per row, such that\n \\f$\\text{nnz}_{\\text{ELL}} = m \\cdot \\text{ell_width}\\f$. The number of ELL\n non-zero elements per row is obtained by rocsparse_csr2ell_width().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array containing the values of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array containing the column indices of the sparse CSR matrix.\n @param[in]\n ell_descr descriptor of the sparse ELL matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n ell_width number of non-zero elements per row in ELL storage format.\n @param[out]\n ell_val array of \\p m times \\p ell_width elements of the sparse ELL matrix.\n @param[out]\n ell_col_ind array of \\p m times \\p ell_width elements containing the column indices\n of the sparse ELL matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_descr, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p ell_descr, \\p ell_val or\n \\p ell_col_ind pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example converts a CSR matrix into an ELL matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m = 3;\n rocsparse_int n = 5;\n rocsparse_int nnz = 8;\n\n csr_row_ptr[m+1] = {0, 3, 5, 8}; // device memory\n csr_col_ind[nnz] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n csr_val[nnz] = {1, 2, 3, 4, 5, 6, 7, 8}; // device memory\n\n // Create ELL matrix descriptor\n rocsparse_mat_descr ell_descr;\n rocsparse_create_mat_descr(&ell_descr);\n\n // Obtain the ELL width\n rocsparse_int ell_width;\n rocsparse_csr2ell_width(handle,\n m,\n csr_descr,\n csr_row_ptr,\n ell_descr,\n &ell_width);\n\n // Compute ELL non-zero entries\n rocsparse_int ell_nnz = m * ell_width;\n\n // Allocate ELL column and value arrays\n rocsparse_int* ell_col_ind;\n hipMalloc((void**)&ell_col_ind, sizeof(rocsparse_int) * ell_nnz);\n\n float* ell_val;\n hipMalloc((void**)&ell_val, sizeof(float) * ell_nnz);\n\n // Format conversion\n rocsparse_scsr2ell(handle,\n m,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n ell_descr,\n ell_width,\n ell_val,\n ell_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2ell( + handle: rocsparse_handle, + m: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *mut f32, + ell_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2ell( + handle: rocsparse_handle, + m: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *mut f64, + ell_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2ell( + handle: rocsparse_handle, + m: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *mut rocsparse_float_complex, + ell_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2ell( + handle: rocsparse_handle, + m: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *mut rocsparse_double_complex, + ell_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse HYB matrix\n\n \\details\n \\p rocsparse_csr2hyb converts a CSR matrix into a HYB matrix. It is assumed\n that \\p hyb has been initialized with rocsparse_create_hyb_mat().\n\n \\note\n This function requires a significant amount of storage for the HYB matrix,\n depending on the matrix structure.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array containing the values of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array containing the column indices of the sparse CSR matrix.\n @param[out]\n hyb sparse matrix in HYB format.\n @param[in]\n user_ell_width width of the ELL part of the HYB matrix (only required if\n \\p partition_type == \\ref rocsparse_hyb_partition_user).\n @param[in]\n partition_type \\ref rocsparse_hyb_partition_auto (recommended),\n \\ref rocsparse_hyb_partition_user or\n \\ref rocsparse_hyb_partition_max.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p user_ell_width is invalid.\n \\retval rocsparse_status_invalid_value \\p partition_type is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p hyb, \\p csr_val,\n \\p csr_row_ptr or \\p csr_col_ind pointer is invalid.\n \\retval rocsparse_status_memory_error the buffer for the HYB matrix could not be\n allocated.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example converts a CSR matrix into a HYB matrix using user defined partitioning.\n \\code{.c}\n // Create HYB matrix structure\n rocsparse_hyb_mat hyb;\n rocsparse_create_hyb_mat(&hyb);\n\n // User defined ell width\n rocsparse_int user_ell_width = 5;\n\n // Perform the conversion\n rocsparse_scsr2hyb(handle,\n m,\n n,\n descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n hyb,\n user_ell_width,\n rocsparse_hyb_partition_user);\n\n // Do some work\n\n // Clean up\n rocsparse_destroy_hyb_mat(hyb);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2hyb( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + hyb: rocsparse_hyb_mat, + user_ell_width: rocsparse_int, + partition_type: rocsparse_hyb_partition, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2hyb( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + hyb: rocsparse_hyb_mat, + user_ell_width: rocsparse_int, + partition_type: rocsparse_hyb_partition, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2hyb( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + hyb: rocsparse_hyb_mat, + user_ell_width: rocsparse_int, + partition_type: rocsparse_hyb_partition, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2hyb( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + hyb: rocsparse_hyb_mat, + user_ell_width: rocsparse_int, + partition_type: rocsparse_hyb_partition, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the number of nonzero block columns per row and the total number of nonzero blocks in a sparse\n BSR matrix given a sparse CSR matrix as input.\n\n \\details\n The routine does support asynchronous execution if the pointer mode is set to device.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n\n @param[in]\n m number of rows of the sparse CSR matrix.\n\n @param[in]\n n number of columns of the sparse CSR matrix.\n\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_row_ptr integer array containing \\p m+1 elements that point to the start of each row of the CSR matrix\n\n @param[in]\n csr_col_ind integer array of the column indices for each non-zero element in the CSR matrix\n\n @param[in]\n block_dim the block dimension of the BSR matrix. Between 1 and min(m, n)\n\n @param[in]\n bsr_descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_row_ptr integer array containing \\p mb+1 elements that point to the start of each block row of the BSR matrix\n\n @param[out]\n bsr_nnz total number of nonzero elements in device or host memory.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr or \\p csr_col_ind or \\p bsr_row_ptr or \\p bsr_nnz\n pointer is invalid."] + pub fn rocsparse_csr2bsr_nnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_row_ptr: *mut rocsparse_int, + bsr_nnz: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse BSR matrix\n\n \\details\n \\p rocsparse_csr2bsr converts a CSR matrix into a BSR matrix. It is assumed,\n that \\p bsr_val, \\p bsr_col_ind and \\p bsr_row_ptr are allocated. Allocation size\n for \\p bsr_row_ptr is computed as \\p mb+1 where \\p mb is the number of block rows in\n the BSR matrix. Allocation size for \\p bsr_val and \\p bsr_col_ind is computed using\n \\p csr2bsr_nnz() which also fills in \\p bsr_row_ptr.\n\n \\p rocsparse_csr2bsr requires extra temporary storage that is allocated internally if \\p block_dim>16\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array of \\p nnz elements containing the values of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse CSR matrix.\n @param[in]\n block_dim size of the blocks in the sparse BSR matrix.\n @param[in]\n bsr_descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_val array of \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[out]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[out]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p csr_val, \\p csr_row_ptr or\n \\p csr_col_ind pointer is invalid.\n\n \\par Example\n This example converts a CSR matrix into an BSR matrix.\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n rocsparse_int m = 4;\n rocsparse_int n = 6;\n rocsparse_int block_dim = 2;\n rocsparse_int nnz = 9;\n rocsparse_int mb = (m + block_dim - 1) / block_dim;\n rocsparse_int nb = (n + block_dim - 1) / block_dim;\n\n csr_row_ptr[m+1] = {0, 2, 4, 7, 9}; // device memory\n csr_col_ind[nnz] = {0, 1, 1, 2, 0, 3, 4, 2, 4}; // device memory\n csr_val[nnz] = {1, 4, 2, 3, 5, 7, 8, 9, 6}; // device memory\n\n hipMalloc(&bsr_row_ptr, sizeof(rocsparse_int) *(mb + 1));\n rocsparse_int nnzb;\n rocsparse_int* nnzTotalHostPtr = &nnzb;\n csr2bsr_nnz(handle,\n rocsparse_direction_row,\n m,\n n,\n csr_descr,\n csr_row_ptr,\n csr_col_ind,\n block_dim,\n bsr_descr,\n bsr_row_ptr,\n nnzTotalHostPtr);\n nnzb = *nnzTotalDevHostPtr;\n hipMalloc(&bsr_col_ind, sizeof(int)*nnzb);\n hipMalloc(&bsr_val, sizeof(float)*(block_dim * block_dim) * nnzb);\n scsr2bsr(handle,\n rocsparse_direction_row,\n m,\n n,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n block_dim,\n bsr_descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2bsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f32, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2bsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f64, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2bsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_float_complex, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2bsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_double_complex, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Pads a value to the diagonal of the last block (if the last block is a diagonal block) in the sparse BSR matrix\n when the matrix expands outside m x m\n\n \\details When converting from a CSR matrix to a BSR matrix the resulting BSR matrix will be larger when m < mb * block_dim.\n In these situations, the CSR to BSR conversion will expand the BSR matrix to have zeros when outside m x m. This routine\n converts the resulting BSR matrix to one that has a value on the last diagonal blocks diagonal if this last block is a diagonal\n block in the BSR matrix.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse BSR matrix.\n @param[in]\n mb number of block rows of the sparse BSR matrix.\n @param[in]\n nnzb number of non-zero blocks of the sparse BSR matrix.\n @param[in]\n block_dim block dimension of the sparse BSR matrix.\n @param[in]\n value scalar value that is set on the diagonal of the last block when the matrix expands outside of \\p m x \\p m\n @param[in]\n bsr_descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[inout]\n bsr_val array of \\p nnzb blocks of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of\n the sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse\n BSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p mb, \\p nnzb or \\p block_dim is\n invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_descr, \\p bsr_val,\n \\p bsr_row_ind, \\p bsr_col_ind, pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sbsrpad_value( + handle: rocsparse_handle, + m: rocsparse_int, + mb: rocsparse_int, + nnzb: rocsparse_int, + block_dim: rocsparse_int, + value: f32, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsrpad_value( + handle: rocsparse_handle, + m: rocsparse_int, + mb: rocsparse_int, + nnzb: rocsparse_int, + block_dim: rocsparse_int, + value: f64, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsrpad_value( + handle: rocsparse_handle, + m: rocsparse_int, + mb: rocsparse_int, + nnzb: rocsparse_int, + block_dim: rocsparse_int, + value: rocsparse_float_complex, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsrpad_value( + handle: rocsparse_handle, + m: rocsparse_int, + mb: rocsparse_int, + nnzb: rocsparse_int, + block_dim: rocsparse_int, + value: rocsparse_double_complex, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n \\details\n \\p rocsparse_csr2gebsr_buffer_size returns the size of the temporary buffer that\n is required by \\p rocsparse_csr2gebcsr_nnz, \\p rocsparse_scsr2gebcsr, \\p rocsparse_dcsr2gebsr,\n \\p rocsparse_ccsr2gebsr and \\p rocsparse_zcsr2gebsr. The temporary storage buffer must be\n allocated by the user.\n\n This function computes the number of nonzero block columns per row and the total number of nonzero blocks in a sparse\n GEneral BSR matrix given a sparse CSR matrix as input.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n\n @param[in]\n m number of rows of the sparse CSR matrix.\n\n @param[in]\n n number of columns of the sparse CSR matrix.\n\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n\n @param[in]\n csr_val array of \\p nnz elements containing the values of the sparse CSR matrix.\n\n @param[in]\n csr_row_ptr integer array containing \\p m+1 elements that point to the start of each row of the CSR matrix\n\n @param[in]\n csr_col_ind integer array of the column indices for each non-zero element in the CSR matrix\n\n @param[in]\n row_block_dim the row block dimension of the GEneral BSR matrix. Between 1 and \\p m\n\n @param[in]\n col_block_dim the col block dimension of the GEneral BSR matrix. Between 1 and \\p n\n\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by \\p rocsparse_csr2gebsr_nnz and \\p rocsparse_Xcsr2gebsr.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p row_block_dim \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val or \\p csr_row_ptr or \\p csr_col_ind or \\p bsr_row_ptr or \\p buffer_size\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_scsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the number of nonzero block columns per row and the total number of nonzero blocks in a sparse\n GEneral BSR matrix given a sparse CSR matrix as input.\n\n \\details\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir direction that specified whether to count nonzero elements by \\ref rocsparse_direction_row or by\n \\ref rocsparse_direction_row.\n\n @param[in]\n m number of rows of the sparse CSR matrix.\n\n @param[in]\n n number of columns of the sparse CSR matrix.\n\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_row_ptr integer array containing \\p m+1 elements that point to the start of each row of the CSR matrix\n\n @param[in]\n csr_col_ind integer array of the column indices for each non-zero element in the CSR matrix\n\n @param[in]\n bsr_descr descriptor of the sparse GEneral BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_row_ptr integer array containing \\p mb+1 elements that point to the start of each block row of the General BSR matrix\n\n @param[in]\n row_block_dim the row block dimension of the GEneral BSR matrix. Between 1 and min(m, n)\n\n @param[in]\n col_block_dim the col block dimension of the GEneral BSR matrix. Between 1 and min(m, n)\n\n @param[out]\n bsr_nnz_devhost total number of nonzero elements in device or host memory.\n\n @param[in]\n temp_buffer buffer allocated by the user whose size is determined by calling \\p rocsparse_xcsr2gebsr_buffer_size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p row_block_dim \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr or \\p csr_col_ind or \\p bsr_row_ptr or \\p bsr_nnz_devhost\n pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_csr2gebsr_nnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_row_ptr: *mut rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + bsr_nnz_devhost: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a sparse GEneral BSR matrix\n\n \\details\n \\p rocsparse_csr2gebsr converts a CSR matrix into a GEneral BSR matrix. It is assumed,\n that \\p bsr_val, \\p bsr_col_ind and \\p bsr_row_ptr are allocated. Allocation size\n for \\p bsr_row_ptr is computed as \\p mb+1 where \\p mb is the number of block rows in\n the GEneral BSR matrix. Allocation size for \\p bsr_val and \\p bsr_col_ind is computed using\n \\p csr2gebsr_nnz() which also fills in \\p bsr_row_ptr.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val array of \\p nnz elements containing the values of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse CSR matrix.\n @param[in]\n bsr_descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n bsr_val array of \\p nnzb* \\p row_block_dim* \\p col_block_dim containing the values of the sparse BSR matrix.\n @param[out]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[out]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n row_block_dim row size of the blocks in the sparse GEneral BSR matrix.\n @param[in]\n col_block_dim col size of the blocks in the sparse GEneral BSR matrix.\n @param[in]\n temp_buffer buffer allocated by the user whose size is determined by calling \\p rocsparse_xcsr2gebsr_buffer_size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p row_block_dim or \\p col_block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p csr_val, \\p csr_row_ptr or\n \\p csr_col_ind pointer is invalid.\n\n \\par Example\n This example converts a CSR matrix into an BSR matrix.\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n rocsparse_int m = 4;\n rocsparse_int n = 6;\n rocsparse_int row_block_dim = 2;\n rocsparse_int col_block_dim = 3;\n rocsparse_int nnz = 9;\n rocsparse_int mb = (m + row_block_dim - 1) / row_block_dim;\n rocsparse_int nb = (n + col_block_dim - 1) / col_block_dim;\n\n csr_row_ptr[m+1] = {0, 2, 4, 7, 9}; // device memory\n csr_col_ind[nnz] = {0, 1, 1, 2, 0, 3, 4, 2, 4}; // device memory\n csr_val[nnz] = {1, 4, 2, 3, 5, 7, 8, 9, 6}; // device memory\n\n hipMalloc(&bsr_row_ptr, sizeof(rocsparse_int) *(mb + 1));\n rocsparse_int nnzb;\n rocsparse_int* nnzTotalHostPtr = &nnzb;\n csr2gebsr_nnz(handle,\n rocsparse_direction_row,\n m,\n n,\n csr_descr,\n csr_row_ptr,\n csr_col_ind,\n row_block_dim,\n col_block_dim,\n bsr_descr,\n bsr_row_ptr,\n nnzTotalHostPtr);\n nnzb = *nnzTotalHostPtr;\n hipMalloc(&bsr_col_ind, sizeof(int)*nnzb);\n hipMalloc(&bsr_val, sizeof(float)*(row_block_dim * col_block_dim) * nnzb);\n scsr2gebsr(handle,\n rocsparse_direction_row,\n m,\n n,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n row_block_dim,\n col_block_dim,\n bsr_descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f32, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut f64, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_float_complex, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + m: rocsparse_int, + n: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *mut rocsparse_double_complex, + bsr_row_ptr: *mut rocsparse_int, + bsr_col_ind: *mut rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse CSR matrix into a compressed sparse CSR matrix\n\n \\details\n \\p rocsparse_csr2csr_compress converts a CSR matrix into a compressed CSR matrix by\n removing entries in the input CSR matrix that are below a non-negative threshold \\p tol\n\n \\note\n In the case of complex matrices only the magnitude of the real part of \\p tol is used.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n descr_A matrix descriptor for the CSR matrix\n @param[in]\n csr_val_A array of \\p nnz_A elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n uncompressed sparse CSR matrix.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the uncompressed\n sparse CSR matrix.\n @param[in]\n nnz_A number of elements in the column indices and values arrays of the uncompressed\n sparse CSR matrix.\n @param[in]\n nnz_per_row array of length \\p m containing the number of entries that will be kept per row in\n the final compressed CSR matrix.\n @param[out]\n csr_val_C array of \\p nnz_C elements of the compressed sparse CSC matrix.\n @param[out]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every column of the compressed\n sparse CSR matrix.\n @param[out]\n csr_col_ind_C array of \\p nnz_C elements containing the row indices of the compressed\n sparse CSR matrix.\n @param[in]\n tol the non-negative tolerance used for compression. If \\p tol is complex then only the magnitude\n of the real part is used. Entries in the input uncompressed CSR array that are below the tolerance\n are removed in output compressed CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz_A is invalid.\n \\retval rocsparse_status_invalid_value \\p tol is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_val_A, \\p csr_row_ptr_A,\n \\p csr_col_ind_A, \\p csr_val_C, \\p csr_row_ptr_C, \\p csr_col_ind_C or\n \\p nnz_per_row pointer is invalid.\n\n \\par Example\n This example demonstrates how to compress a CSR matrix. Compressing a CSR matrix involves two steps. First we use\n nnz_compress() to determine how many entries will be in the final compressed CSR matrix. Then we call csr2csr_compress()\n to finish the compression and fill in the column indices and values arrays of the compressed CSR matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n float tol = 0.0f;\n\n rocsparse_int m = 3;\n rocsparse_int n = 5;\n rocsparse_int nnz_A = 8;\n\n csr_row_ptr_A[m+1] = {0, 3, 5, 8}; // device memory\n csr_col_ind_A[nnz_A] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n csr_val_A[nnz_A] = {1, 0, 3, 4, 0, 6, 7, 0}; // device memory\n\n // Allocate memory for the row pointer array of the compressed CSR matrix\n rocsparse_int* csr_row_ptr_C;\n hipMalloc(csr_row_ptr_C, sizeof(rocsparse_int) * (m + 1));\n\n // Allocate memory for the nnz_per_row array\n rocsparse_int* nnz_per_row;\n hipMalloc(nnz_per_row, sizeof(rocsparse_int) * m);\n\n // Call nnz_compress() which fills in nnz_per_row array and finds the number\n // of entries that will be in the compressed CSR matrix\n rocsparse_int nnz_C;\n nnz_compress(handle,\n m,\n descr_A,\n csr_val_A,\n csr_row_ptr_A,\n nnz_per_row,\n &nnz_C,\n tol);\n\n // Allocate column indices and values array for the compressed CSR matrix\n rocsparse_int* csr_col_ind_C;\n rocsparse_int* csr_val_C;\n hipMalloc(csr_col_ind_C, sizeof(rocsparse_int) * nnz_C;\n hipMalloc(csr_val_C, sizeof(rocsparse_int) * nnz_C;\n\n // Finish compression by calling csr2csr_compress()\n csr2csr_compress(handle,\n m,\n n,\n descr_A,\n csr_val_A,\n csr_row_ptr_A,\n csr_col_ind_A,\n nnz_A,\n nnz_per_row,\n csr_val_C,\n csr_row_ptr_C,\n csr_col_ind_C,\n tol);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_scsr2csr_compress( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + nnz_A: rocsparse_int, + nnz_per_row: *const rocsparse_int, + csr_val_C: *mut f32, + csr_row_ptr_C: *mut rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + tol: f32, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsr2csr_compress( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + nnz_A: rocsparse_int, + nnz_per_row: *const rocsparse_int, + csr_val_C: *mut f64, + csr_row_ptr_C: *mut rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + tol: f64, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsr2csr_compress( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const rocsparse_float_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + nnz_A: rocsparse_int, + nnz_per_row: *const rocsparse_int, + csr_val_C: *mut rocsparse_float_complex, + csr_row_ptr_C: *mut rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + tol: rocsparse_float_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsr2csr_compress( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + descr_A: rocsparse_mat_descr, + csr_val_A: *const rocsparse_double_complex, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + nnz_A: rocsparse_int, + nnz_per_row: *const rocsparse_int, + csr_val_C: *mut rocsparse_double_complex, + csr_row_ptr_C: *mut rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + tol: rocsparse_double_complex, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune sparse CSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_prune_csr2csr_buffer_size returns the size of the temporary buffer that\n is required by \\p rocsparse_sprune_csr2csr_nnz, \\p rocsparse_dprune_csr2csr_nnz,\n \\p rocsparse_sprune_csr2csr, and \\p rocsparse_dprune_csr2csr. The temporary storage\n buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n threshold pointer to the non-negative pruning threshold which can exist in either host or device memory.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_C array of \\p nnz_C elements containing the values of the sparse CSR matrix C.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[in]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the sparse CSR matrix C.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by \\p rocsparse_sprune_csr2csr_nnz,\n \\p rocsparse_dprune_csr2csr_nnz, \\p rocsparse_sprune_csr2csr, and \\p rocsparse_dprune_csr2csr.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f32, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *const f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f64, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *const f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune sparse CSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_prune_csr2csr_nnz computes the number of nonzero elements per row and the total\n number of nonzero elements in a sparse CSR matrix once elements less than the threshold are\n pruned from the matrix.\n\n \\note The routine does support asynchronous execution if the pointer mode is set to device.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n threshold pointer to the non-negative pruning threshold which can exist in either host or device memory.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[out]\n nnz_total_dev_host_ptr total number of nonzero elements in device or host memory.\n @param[out]\n temp_buffer buffer allocated by the user whose size is determined by calling \\p rocsparse_xprune_csr2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p nnz_A is invalid.\n \\retval rocsparse_status_invalid_pointer \\p threshold or \\p csr_descr_A or \\p csr_descr_C or \\p csr_val_A\n or \\p csr_row_ptr_A or \\p csr_col_ind_A or \\p csr_row_ptr_C or \\p nnz_total_dev_host_ptr\n or \\p temp_buffer pointer is invalid.\n\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f32, + csr_descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f64, + csr_descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune sparse CSR matrix into a sparse CSR matrix\n\n \\details\n This function converts the sparse CSR matrix A into a sparse CSR matrix C by pruning values in A\n that are less than the threshold. All the parameters are assumed to have been pre-allocated by the user.\n The user first calls rocsparse_xprune_csr2csr_buffer_size() to determine the size of the buffer used\n by rocsparse_xprune_csr2csr_nnz() and rocsparse_xprune_csr2csr() which the user then allocates. The user then\n allocates \\p csr_row_ptr_C to have \\p m+1 elements and then calls rocsparse_xprune_csr2csr_nnz() which fills\n in the \\p csr_row_ptr_C array stores then number of elements that are larger than the pruning threshold\n in \\p nnz_total_dev_host_ptr. The user then calls rocsparse_xprune_csr2csr() to complete the conversion.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n threshold pointer to the non-negative pruning threshold which can exist in either host or device memory.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val_C array of \\p nnz_C elements containing the values of the sparse CSR matrix C.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[out]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the sparse CSR matrix C.\n @param[in]\n temp_buffer buffer allocated by the user whose size is determined by calling \\p rocsparse_xprune_csr2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p nnz_A is invalid.\n \\retval rocsparse_status_invalid_pointer \\p threshold or \\p csr_descr_A or \\p csr_descr_C or \\p csr_val_A\n or \\p csr_row_ptr_A or \\p csr_col_ind_A or \\p csr_val_C or \\p csr_row_ptr_C or \\p csr_col_ind_C\n or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f32, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *mut f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + threshold: *const f64, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *mut f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune by percentage a sparse CSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_prune_csr2csr__by_percentage_buffer_size returns the size of the temporary buffer that\n is required by \\p rocsparse_sprune_csr2csr_nnz_by_percentage, \\p rocsparse_dprune_csr2csr_nnz_by_percentage,\n \\p rocsparse_sprune_csr2csr_by_percentage, and \\p rocsparse_dprune_csr2csr_by_percentage. The temporary storage\n buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_C array of \\p nnz_C elements containing the values of the sparse CSR matrix C.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[in]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the sparse CSR matrix C.\n @param[in]\n info prune info structure.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by \\p rocsparse_sprune_csr2csr_nnz_by_percentage,\n \\p rocsparse_dprune_csr2csr_nnz_by_percentage, \\p rocsparse_sprune_csr2csr_by_percentage,\n and \\p rocsparse_dprune_csr2csr_by_percentage.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr_by_percentage_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f32, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *const f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr_by_percentage_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f64, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *const f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *const rocsparse_int, + info: rocsparse_mat_info, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune by percentage a sparse CSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_prune_csr2csr_nnz_by_percentage computes the number of nonzero elements per row and the total\n number of nonzero elements in a sparse CSR matrix once elements less than the threshold are\n pruned from the matrix.\n\n \\note The routine does support asynchronous execution if the pointer mode is set to device.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[out]\n nnz_total_dev_host_ptr total number of nonzero elements in device or host memory.\n @param[in]\n info prune info structure.\n @param[out]\n temp_buffer buffer allocated by the user whose size is determined by calling\n \\p rocsparse_xprune_csr2csr_by_percentage_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p nnz_A or \\p percentage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_descr_A or \\p csr_descr_C or \\p info or \\p csr_val_A\n or \\p csr_row_ptr_A or \\p csr_col_ind_A or \\p csr_row_ptr_C or \\p nnz_total_dev_host_ptr\n or \\p temp_buffer pointer is invalid.\n\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr_nnz_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f32, + csr_descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr_nnz_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f64, + csr_descr_C: rocsparse_mat_descr, + csr_row_ptr_C: *mut rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert and prune by percentage a sparse CSR matrix into a sparse CSR matrix\n\n \\details\n This function converts the sparse CSR matrix A into a sparse CSR matrix C by pruning values in A\n that are less than the threshold. All the parameters are assumed to have been pre-allocated by the user.\n The user first calls rocsparse_xprune_csr2csr_buffer_size() to determine the size of the buffer used\n by rocsparse_xprune_csr2csr_nnz() and rocsparse_xprune_csr2csr() which the user then allocates. The user then\n allocates \\p csr_row_ptr_C to have \\p m+1 elements and then calls rocsparse_xprune_csr2csr_nnz() which fills\n in the \\p csr_row_ptr_C array stores then number of elements that are larger than the pruning threshold\n in \\p nnz_total_dev_host_ptr. The user then calls rocsparse_xprune_csr2csr() to complete the conversion.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows in the sparse CSR matrix.\n @param[in]\n n number of columns in the sparse CSR matrix.\n @param[in]\n nnz_A number of non-zeros in the sparse CSR matrix A.\n @param[in]\n csr_descr_A descriptor of the sparse CSR matrix A. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_val_A array of \\p nnz_A elements containing the values of the sparse CSR matrix A.\n @param[in]\n csr_row_ptr_A array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix A.\n @param[in]\n csr_col_ind_A array of \\p nnz_A elements containing the column indices of the sparse CSR matrix A.\n @param[in]\n percentage percentage >= 0 and percentage <= 100.\n @param[in]\n csr_descr_C descriptor of the sparse CSR matrix C. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val_C array of \\p nnz_C elements containing the values of the sparse CSR matrix C.\n @param[in]\n csr_row_ptr_C array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix C.\n @param[out]\n csr_col_ind_C array of \\p nnz_C elements containing the column indices of the sparse CSR matrix C.\n @param[in]\n info prune info structure.\n @param[in]\n temp_buffer buffer allocated by the user whose size is determined by calling \\p rocsparse_xprune_csr2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p n or \\p nnz_A or \\p percentage is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_descr_A or \\p csr_descr_C or \\p info or \\p csr_val_A\n or \\p csr_row_ptr_A or \\p csr_col_ind_A or \\p csr_val_C or \\p csr_row_ptr_C or \\p csr_col_ind_C\n or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sprune_csr2csr_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f32, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f32, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *mut f32, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dprune_csr2csr_by_percentage( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz_A: rocsparse_int, + csr_descr_A: rocsparse_mat_descr, + csr_val_A: *const f64, + csr_row_ptr_A: *const rocsparse_int, + csr_col_ind_A: *const rocsparse_int, + percentage: f64, + csr_descr_C: rocsparse_mat_descr, + csr_val_C: *mut f64, + csr_row_ptr_C: *const rocsparse_int, + csr_col_ind_C: *mut rocsparse_int, + info: rocsparse_mat_info, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse COO matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_coo2csr converts the COO array containing the row indices into a\n CSR array of row offsets, that point to the start of every row.\n It is assumed that the COO row index array is sorted.\n\n \\note It can also be used, to convert a COO array containing the column indices into\n a CSC array of column offsets, that point to the start of every column. Then, it is\n assumed that the COO column index array is sorted, instead.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse COO\n matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[out]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n idx_base \\ref rocsparse_index_base_zero or \\ref rocsparse_index_base_one.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_row_ind or \\p csr_row_ptr\n pointer is invalid.\n\n \\par Example\n This example converts a COO matrix into a CSR matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m = 3;\n rocsparse_int n = 5;\n rocsparse_int nnz = 8;\n\n coo_row_ind[nnz] = {0, 0, 0, 1, 1, 2, 2, 2}; // device memory\n coo_col_ind[nnz] = {0, 1, 3, 1, 2, 0, 3, 4}; // device memory\n coo_val[nnz] = {1, 2, 3, 4, 5, 6, 7, 8}; // device memory\n\n // Allocate CSR matrix arrays\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&csr_val, sizeof(float) * nnz);\n\n // Convert the coo row indices into csr row offsets\n rocsparse_coo2csr(handle,\n coo_row_ind,\n nnz,\n m,\n csr_row_ptr,\n rocsparse_index_base_zero);\n\n // Copy the column and value arrays\n hipMemcpy(csr_col_ind,\n coo_col_ind,\n sizeof(rocsparse_int) * nnz,\n hipMemcpyDeviceToDevice);\n\n hipMemcpy(csr_val,\n coo_val,\n sizeof(float) * nnz,\n hipMemcpyDeviceToDevice);\n \\endcode"] + pub fn rocsparse_coo2csr( + handle: rocsparse_handle, + coo_row_ind: *const rocsparse_int, + nnz: rocsparse_int, + m: rocsparse_int, + csr_row_ptr: *mut rocsparse_int, + idx_base: rocsparse_index_base, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse ELL matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_ell2csr_nnz computes the total CSR non-zero elements and the CSR\n row offsets, that point to the start of every row of the sparse CSR matrix, for\n a given ELL matrix. It is assumed that \\p csr_row_ptr has been allocated with\n size \\p m+1.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse ELL matrix.\n @param[in]\n n number of columns of the sparse ELL matrix.\n @param[in]\n ell_descr descriptor of the sparse ELL matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n ell_width number of non-zero elements per row in ELL storage format.\n @param[in]\n ell_col_ind array of \\p m times \\p ell_width elements containing the column indices\n of the sparse ELL matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n csr_nnz pointer to the total number of non-zero elements in CSR storage\n format.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p ell_descr, \\p ell_col_ind,\n \\p csr_descr, \\p csr_row_ptr or \\p csr_nnz pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_ell2csr_nnz( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_col_ind: *const rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_row_ptr: *mut rocsparse_int, + csr_nnz: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse ELL matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_ell2csr converts an ELL matrix into a CSR matrix. It is assumed\n that \\p csr_row_ptr has already been filled and that \\p csr_val and \\p csr_col_ind\n are allocated by the user. \\p csr_row_ptr and allocation size of \\p csr_col_ind and\n \\p csr_val is defined by the number of CSR non-zero elements. Both can be obtained\n by rocsparse_ell2csr_nnz().\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse ELL matrix.\n @param[in]\n n number of columns of the sparse ELL matrix.\n @param[in]\n ell_descr descriptor of the sparse ELL matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n ell_width number of non-zero elements per row in ELL storage format.\n @param[in]\n ell_val array of \\p m times \\p ell_width elements of the sparse ELL matrix.\n @param[in]\n ell_col_ind array of \\p m times \\p ell_width elements containing the column indices\n of the sparse ELL matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val array containing the values of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n csr_col_ind array containing the column indices of the sparse CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p ell_width is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_descr, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind, \\p ell_descr, \\p ell_val or\n \\p ell_col_ind pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example converts an ELL matrix into a CSR matrix.\n \\code{.c}\n // 1 2 0 3 0\n // A = 0 4 5 0 0\n // 6 0 0 7 8\n\n rocsparse_int m = 3;\n rocsparse_int n = 5;\n rocsparse_int nnz = 9;\n rocsparse_int ell_width = 3;\n\n ell_col_ind[nnz] = {0, 1, 0, 1, 2, 3, 3, -1, 4}; // device memory\n ell_val[nnz] = {1, 4, 6, 2, 5, 7, 3, 0, 8}; // device memory\n\n // Create CSR matrix descriptor\n rocsparse_mat_descr csr_descr;\n rocsparse_create_mat_descr(&csr_descr);\n\n // Allocate csr_row_ptr array for row offsets\n rocsparse_int* csr_row_ptr;\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n\n // Obtain the number of CSR non-zero entries\n // and fill csr_row_ptr array with row offsets\n rocsparse_int csr_nnz;\n rocsparse_ell2csr_nnz(handle,\n m,\n n,\n ell_descr,\n ell_width,\n ell_col_ind,\n csr_descr,\n csr_row_ptr,\n &csr_nnz);\n\n // Allocate CSR column and value arrays\n rocsparse_int* csr_col_ind;\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * csr_nnz);\n\n float* csr_val;\n hipMalloc((void**)&csr_val, sizeof(float) * csr_nnz);\n\n // Format conversion\n rocsparse_sell2csr(handle,\n m,\n n,\n ell_descr,\n ell_width,\n ell_val,\n ell_col_ind,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sell2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *const f32, + ell_col_ind: *const rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dell2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *const f64, + ell_col_ind: *const rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cell2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *const rocsparse_float_complex, + ell_col_ind: *const rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zell2csr( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + ell_descr: rocsparse_mat_descr, + ell_width: rocsparse_int, + ell_val: *const rocsparse_double_complex, + ell_col_ind: *const rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse HYB matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_hyb2csr_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_shyb2csr(), rocsparse_dhyb2csr(), rocsparse_chyb2csr() and\n rocsparse_dhyb2csr(). The temporary storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse HYB matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n hyb sparse matrix in HYB format.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_shyb2csr(), rocsparse_dhyb2csr(), rocsparse_chyb2csr() and\n rocsparse_zhyb2csr().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p hyb, \\p csr_row_ptr or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general."] + pub fn rocsparse_hyb2csr_buffer_size( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + csr_row_ptr: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse HYB matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_hyb2csr converts a HYB matrix into a CSR matrix.\n\n \\p rocsparse_hyb2csr requires extra temporary storage buffer that has to be allocated\n by the user. Storage buffer size can be determined by\n rocsparse_hyb2csr_buffer_size().\n\n \\note\n This function is blocking with respect to the host.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n descr descriptor of the sparse HYB matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n hyb sparse matrix in HYB format.\n @param[out]\n csr_val array containing the values of the sparse CSR matrix.\n @param[out]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n csr_col_ind array containing the column indices of the sparse CSR matrix.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_hyb2csr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p hyb, \\p csr_val,\n \\p csr_row_ptr, \\p csr_col_ind or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n This example converts a HYB matrix into a CSR matrix.\n \\code{.c}\n // Create CSR matrix arrays\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&csr_val, sizeof(float) * nnz);\n\n // Get required size of temporary buffer\n size_t size;\n rocsparse_hyb2csr_buffer_size(handle,\n descr,\n hyb,\n csr_row_ptr,\n &size);\n\n // Allocate temporary buffer\n void* buffer;\n hipMalloc(&buffer, size);\n\n // Perform the conversion\n rocsparse_shyb2csr(handle,\n descr,\n hyb,\n csr_val,\n csr_row_ptr,\n csr_col_ind,\n buffer);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_shyb2csr( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + csr_val: *mut f32, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dhyb2csr( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + csr_val: *mut f64, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_chyb2csr( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zhyb2csr( + handle: rocsparse_handle, + descr: rocsparse_mat_descr, + hyb: rocsparse_hyb_mat, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Create the identity map\n\n \\details\n \\p rocsparse_create_identity_permutation stores the identity map in \\p p, such that\n \\f$p = 0:1:(n-1)\\f$.\n\n \\code{.c}\n for(i = 0; i < n; ++i)\n {\n p[i] = i;\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n n size of the map \\p p.\n @param[out]\n p array of \\p n integers containing the map.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p n is invalid.\n \\retval rocsparse_status_invalid_pointer \\p p pointer is invalid.\n\n \\par Example\n The following example creates an identity permutation.\n \\code{.c}\n rocsparse_int size = 200;\n\n // Allocate memory to hold the identity map\n rocsparse_int* perm;\n hipMalloc((void**)&perm, sizeof(rocsparse_int) * size);\n\n // Fill perm with the identity permutation\n rocsparse_create_identity_permutation(handle, size, perm);\n \\endcode"] + pub fn rocsparse_create_identity_permutation( + handle: rocsparse_handle, + n: rocsparse_int, + p: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse CSR matrix\n\n \\details\n \\p rocsparse_csrsort_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_csrsort(). The temporary storage buffer must be allocated by\n the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_csrsort().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csr_row_ptr, \\p csr_col_ind or\n \\p buffer_size pointer is invalid."] + pub fn rocsparse_csrsort_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse CSR matrix\n\n \\details\n \\p rocsparse_csrsort sorts a matrix in CSR format. The sorted permutation vector\n \\p perm can be used to obtain sorted \\p csr_val array. In this case, \\p perm must be\n initialized as the identity permutation, see rocsparse_create_identity_permutation().\n\n \\p rocsparse_csrsort requires extra temporary storage buffer that has to be allocated by\n the user. Storage buffer size can be determined by rocsparse_csrsort_buffer_size().\n\n \\note\n \\p perm can be \\p NULL if a sorted permutation vector is not required.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSR matrix.\n @param[in]\n n number of columns of the sparse CSR matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSR matrix.\n @param[in]\n descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[inout]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[inout]\n perm array of \\p nnz integers containing the unsorted map indices, can be\n \\p NULL.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_csrsort_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_row_ptr, \\p csr_col_ind\n or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n The following example sorts a \\f$3 \\times 3\\f$ CSR matrix.\n \\code{.c}\n // 1 2 3\n // A = 4 5 6\n // 7 8 9\n rocsparse_int m = 3;\n rocsparse_int n = 3;\n rocsparse_int nnz = 9;\n\n csr_row_ptr[m + 1] = {0, 3, 6, 9}; // device memory\n csr_col_ind[nnz] = {2, 0, 1, 0, 1, 2, 0, 2, 1}; // device memory\n csr_val[nnz] = {3, 1, 2, 4, 5, 6, 7, 9, 8}; // device memory\n\n // Create permutation vector perm as the identity map\n rocsparse_int* perm;\n hipMalloc((void**)&perm, sizeof(rocsparse_int) * nnz);\n rocsparse_create_identity_permutation(handle, nnz, perm);\n\n // Allocate temporary buffer\n size_t buffer_size;\n void* temp_buffer;\n rocsparse_csrsort_buffer_size(handle, m, n, nnz, csr_row_ptr, csr_col_ind, &buffer_size);\n hipMalloc(&temp_buffer, buffer_size);\n\n // Sort the CSR matrix\n rocsparse_csrsort(handle, m, n, nnz, descr, csr_row_ptr, csr_col_ind, perm, temp_buffer);\n\n // Gather sorted csr_val array\n float* csr_val_sorted;\n hipMalloc((void**)&csr_val_sorted, sizeof(float) * nnz);\n rocsparse_sgthr(handle, nnz, csr_val, csr_val_sorted, perm, rocsparse_index_base_zero);\n\n // Clean up\n hipFree(temp_buffer);\n hipFree(perm);\n hipFree(csr_val);\n \\endcode"] + pub fn rocsparse_csrsort( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *mut rocsparse_int, + perm: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse CSC matrix\n\n \\details\n \\p rocsparse_cscsort_buffer_size returns the size of the temporary storage buffer\n required by rocsparse_cscsort(). The temporary storage buffer must be allocated by\n the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSC matrix.\n @param[in]\n n number of columns of the sparse CSC matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSC matrix.\n @param[in]\n csc_col_ptr array of \\p n+1 elements that point to the start of every column of\n the sparse CSC matrix.\n @param[in]\n csc_row_ind array of \\p nnz elements containing the row indices of the sparse\n CSC matrix.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_cscsort().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p csc_col_ptr, \\p csc_row_ind or\n \\p buffer_size pointer is invalid."] + pub fn rocsparse_cscsort_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse CSC matrix\n\n \\details\n \\p rocsparse_cscsort sorts a matrix in CSC format. The sorted permutation vector\n \\p perm can be used to obtain sorted \\p csc_val array. In this case, \\p perm must be\n initialized as the identity permutation, see rocsparse_create_identity_permutation().\n\n \\p rocsparse_cscsort requires extra temporary storage buffer that has to be allocated by\n the user. Storage buffer size can be determined by rocsparse_cscsort_buffer_size().\n\n \\note\n \\p perm can be \\p NULL if a sorted permutation vector is not required.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse CSC matrix.\n @param[in]\n n number of columns of the sparse CSC matrix.\n @param[in]\n nnz number of non-zero entries of the sparse CSC matrix.\n @param[in]\n descr descriptor of the sparse CSC matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n csc_col_ptr array of \\p n+1 elements that point to the start of every column of\n the sparse CSC matrix.\n @param[inout]\n csc_row_ind array of \\p nnz elements containing the row indices of the sparse\n CSC matrix.\n @param[inout]\n perm array of \\p nnz integers containing the unsorted map indices, can be\n \\p NULL.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_cscsort_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csc_col_ptr, \\p csc_row_ind\n or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n \\retval rocsparse_status_not_implemented\n \\ref rocsparse_matrix_type != \\ref rocsparse_matrix_type_general.\n\n \\par Example\n The following example sorts a \\f$3 \\times 3\\f$ CSC matrix.\n \\code{.c}\n // 1 2 3\n // A = 4 5 6\n // 7 8 9\n rocsparse_int m = 3;\n rocsparse_int n = 3;\n rocsparse_int nnz = 9;\n\n csc_col_ptr[m + 1] = {0, 3, 6, 9}; // device memory\n csc_row_ind[nnz] = {2, 0, 1, 0, 1, 2, 0, 2, 1}; // device memory\n csc_val[nnz] = {7, 1, 4, 2, 5, 8, 3, 9, 6}; // device memory\n\n // Create permutation vector perm as the identity map\n rocsparse_int* perm;\n hipMalloc((void**)&perm, sizeof(rocsparse_int) * nnz);\n rocsparse_create_identity_permutation(handle, nnz, perm);\n\n // Allocate temporary buffer\n size_t buffer_size;\n void* temp_buffer;\n rocsparse_cscsort_buffer_size(handle, m, n, nnz, csc_col_ptr, csc_row_ind, &buffer_size);\n hipMalloc(&temp_buffer, buffer_size);\n\n // Sort the CSC matrix\n rocsparse_cscsort(handle, m, n, nnz, descr, csc_col_ptr, csc_row_ind, perm, temp_buffer);\n\n // Gather sorted csc_val array\n float* csc_val_sorted;\n hipMalloc((void**)&csc_val_sorted, sizeof(float) * nnz);\n rocsparse_sgthr(handle, nnz, csc_val, csc_val_sorted, perm, rocsparse_index_base_zero);\n\n // Clean up\n hipFree(temp_buffer);\n hipFree(perm);\n hipFree(csc_val);\n \\endcode"] + pub fn rocsparse_cscsort( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csc_col_ptr: *const rocsparse_int, + csc_row_ind: *mut rocsparse_int, + perm: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse COO matrix\n\n \\details\n \\p coosort_buffer_size returns the size of the temporary storage buffer that is\n required by rocsparse_coosort_by_row() and rocsparse_coosort_by_column(). The\n temporary storage buffer has to be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse COO matrix.\n @param[in]\n n number of columns of the sparse COO matrix.\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[in]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse\n COO matrix.\n @param[in]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by\n rocsparse_coosort_by_row() and rocsparse_coosort_by_column().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_row_ind, \\p coo_col_ind or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred."] + pub fn rocsparse_coosort_buffer_size( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_row_ind: *const rocsparse_int, + coo_col_ind: *const rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse COO matrix by row\n\n \\details\n \\p rocsparse_coosort_by_row sorts a matrix in COO format by row. The sorted\n permutation vector \\p perm can be used to obtain sorted \\p coo_val array. In this\n case, \\p perm must be initialized as the identity permutation, see\n rocsparse_create_identity_permutation().\n\n \\p rocsparse_coosort_by_row requires extra temporary storage buffer that has to be\n allocated by the user. Storage buffer size can be determined by\n rocsparse_coosort_buffer_size().\n\n \\note\n \\p perm can be \\p NULL if a sorted permutation vector is not required.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse COO matrix.\n @param[in]\n n number of columns of the sparse COO matrix.\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[inout]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse\n COO matrix.\n @param[inout]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[inout]\n perm array of \\p nnz integers containing the unsorted map indices, can be\n \\p NULL.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_coosort_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_row_ind, \\p coo_col_ind or\n \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n \\par Example\n The following example sorts a \\f$3 \\times 3\\f$ COO matrix by row indices.\n \\code{.c}\n // 1 2 3\n // A = 4 5 6\n // 7 8 9\n rocsparse_int m = 3;\n rocsparse_int n = 3;\n rocsparse_int nnz = 9;\n\n coo_row_ind[nnz] = {0, 1, 2, 0, 1, 2, 0, 1, 2}; // device memory\n coo_col_ind[nnz] = {0, 0, 0, 1, 1, 1, 2, 2, 2}; // device memory\n coo_val[nnz] = {1, 4, 7, 2, 5, 8, 3, 6, 9}; // device memory\n\n // Create permutation vector perm as the identity map\n rocsparse_int* perm;\n hipMalloc((void**)&perm, sizeof(rocsparse_int) * nnz);\n rocsparse_create_identity_permutation(handle, nnz, perm);\n\n // Allocate temporary buffer\n size_t buffer_size;\n void* temp_buffer;\n rocsparse_coosort_buffer_size(handle,\n m,\n n,\n nnz,\n coo_row_ind,\n coo_col_ind,\n &buffer_size);\n hipMalloc(&temp_buffer, buffer_size);\n\n // Sort the COO matrix\n rocsparse_coosort_by_row(handle,\n m,\n n,\n nnz,\n coo_row_ind,\n coo_col_ind,\n perm,\n temp_buffer);\n\n // Gather sorted coo_val array\n float* coo_val_sorted;\n hipMalloc((void**)&coo_val_sorted, sizeof(float) * nnz);\n rocsparse_sgthr(handle, nnz, coo_val, coo_val_sorted, perm, rocsparse_index_base_zero);\n\n // Clean up\n hipFree(temp_buffer);\n hipFree(perm);\n hipFree(coo_val);\n \\endcode"] + pub fn rocsparse_coosort_by_row( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + perm: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Sort a sparse COO matrix by column\n\n \\details\n \\p rocsparse_coosort_by_column sorts a matrix in COO format by column. The sorted\n permutation vector \\p perm can be used to obtain sorted \\p coo_val array. In this\n case, \\p perm must be initialized as the identity permutation, see\n rocsparse_create_identity_permutation().\n\n \\p rocsparse_coosort_by_column requires extra temporary storage buffer that has to be\n allocated by the user. Storage buffer size can be determined by\n rocsparse_coosort_buffer_size().\n\n \\note\n \\p perm can be \\p NULL if a sorted permutation vector is not required.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of the sparse COO matrix.\n @param[in]\n n number of columns of the sparse COO matrix.\n @param[in]\n nnz number of non-zero entries of the sparse COO matrix.\n @param[inout]\n coo_row_ind array of \\p nnz elements containing the row indices of the sparse\n COO matrix.\n @param[inout]\n coo_col_ind array of \\p nnz elements containing the column indices of the sparse\n COO matrix.\n @param[inout]\n perm array of \\p nnz integers containing the unsorted map indices, can be\n \\p NULL.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user, size is returned by\n rocsparse_coosort_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m, \\p n or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p coo_row_ind, \\p coo_col_ind or\n \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_internal_error an internal error occurred.\n\n \\par Example\n The following example sorts a \\f$3 \\times 3\\f$ COO matrix by column indices.\n \\code{.c}\n // 1 2 3\n // A = 4 5 6\n // 7 8 9\n rocsparse_int m = 3;\n rocsparse_int n = 3;\n rocsparse_int nnz = 9;\n\n coo_row_ind[nnz] = {0, 0, 0, 1, 1, 1, 2, 2, 2}; // device memory\n coo_col_ind[nnz] = {0, 1, 2, 0, 1, 2, 0, 1, 2}; // device memory\n coo_val[nnz] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // device memory\n\n // Create permutation vector perm as the identity map\n rocsparse_int* perm;\n hipMalloc((void**)&perm, sizeof(rocsparse_int) * nnz);\n rocsparse_create_identity_permutation(handle, nnz, perm);\n\n // Allocate temporary buffer\n size_t buffer_size;\n void* temp_buffer;\n rocsparse_coosort_buffer_size(handle,\n m,\n n,\n nnz,\n coo_row_ind,\n coo_col_ind,\n &buffer_size);\n hipMalloc(&temp_buffer, buffer_size);\n\n // Sort the COO matrix\n rocsparse_coosort_by_column(handle,\n m,\n n,\n nnz,\n coo_row_ind,\n coo_col_ind,\n perm,\n temp_buffer);\n\n // Gather sorted coo_val array\n float* coo_val_sorted;\n hipMalloc((void**)&coo_val_sorted, sizeof(float) * nnz);\n rocsparse_sgthr(handle, nnz, coo_val, coo_val_sorted, perm, rocsparse_index_base_zero);\n\n // Clean up\n hipFree(temp_buffer);\n hipFree(perm);\n hipFree(coo_val);\n \\endcode"] + pub fn rocsparse_coosort_by_column( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + coo_row_ind: *mut rocsparse_int, + coo_col_ind: *mut rocsparse_int, + perm: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse BSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_bsr2csr converts a BSR matrix into a CSR matrix. It is assumed,\n that \\p csr_val, \\p csr_col_ind and \\p csr_row_ptr are allocated. Allocation size\n for \\p csr_row_ptr is computed by the number of block rows multiplied by the block\n dimension plus one. Allocation for \\p csr_val and \\p csr_col_ind is computed by the\n the number of blocks in the BSR matrix multiplied by the block dimension squared.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n @param[in]\n mb number of block rows in the sparse BSR matrix.\n @param[in]\n nb number of block columns in the sparse BSR matrix.\n @param[in]\n bsr_descr descriptor of the sparse BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb*block_dim*block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n block_dim size of the blocks in the sparse BSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val array of \\p nnzb*block_dim*block_dim elements containing the values of the sparse CSR matrix.\n @param[out]\n csr_row_ptr array of \\p m+1 where \\p m=mb*block_dim elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n csr_col_ind array of \\p nnzb*block_dim*block_dim elements containing the column indices of the sparse CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb or \\p nb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p csr_val, \\p csr_row_ptr or\n \\p csr_col_ind pointer is invalid.\n\n \\par Example\n This example converts a BSR matrix into an CSR matrix.\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n rocsparse_int mb = 2;\n rocsparse_int nb = 3;\n rocsparse_int block_dim = 2;\n rocsparse_int m = Mb * block_dim;\n rocsparse_int n = Nb * block_dim;\n\n bsr_row_ptr[mb+1] = {0, 2, 5}; // device memory\n bsr_col_ind[nnzb] = {0, 1, 0, 1, 2}; // device memory\n bsr_val[nnzb*block_dim*block_dim] = {1, 0, 4, 2, 0, 3, 0, 0, 5, 0, 0, 0, 0, 9, 7, 0, 8, 6, 0, 0}; // device memory\n\n rocsparse_int nnzb = bsr_row_ptr[mb] - bsr_row_ptr[0];\n\n // Create CSR arrays on device\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnzb * block_dim * block_dim);\n hipMalloc((void**)&csr_val, sizeof(float) * nnzb * block_dim * block_dim);\n\n // Create rocsparse handle\n rocsparse_local_handle handle;\n\n rocsparse_mat_descr bsr_descr = nullptr;\n rocsparse_create_mat_descr(&bsr_descr);\n\n rocsparse_mat_descr csr_descr = nullptr;\n rocsparse_create_mat_descr(&csr_descr);\n\n rocsparse_set_mat_index_base(bsr_descr, rocsparse_index_base_zero);\n rocsparse_set_mat_index_base(csr_descr, rocsparse_index_base_zero);\n\n // Format conversion\n rocsparse_sbsr2csr(handle,\n rocsparse_direction_column,\n mb,\n nb,\n bsr_descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n block_dim,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sbsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dbsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cbsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zbsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief Convert a sparse general BSR matrix into a sparse CSR matrix\n\n \\details\n \\p rocsparse_gebsr2csr converts a BSR matrix into a CSR matrix. It is assumed,\n that \\p csr_val, \\p csr_col_ind and \\p csr_row_ptr are allocated. Allocation size\n for \\p csr_row_ptr is computed by the number of block rows multiplied by the block\n dimension plus one. Allocation for \\p csr_val and \\p csr_col_ind is computed by the\n the number of blocks in the BSR matrix multiplied by the product of the block dimensions.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n @param[in]\n mb number of block rows in the sparse general BSR matrix.\n @param[in]\n nb number of block columns in the sparse general BSR matrix.\n @param[in]\n bsr_descr descriptor of the sparse general BSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[in]\n bsr_val array of \\p nnzb*row_block_dim*col_block_dim containing the values of the sparse BSR matrix.\n @param[in]\n bsr_row_ptr array of \\p mb+1 elements that point to the start of every block row of the\n sparse BSR matrix.\n @param[in]\n bsr_col_ind array of \\p nnzb elements containing the block column indices of the sparse BSR matrix.\n @param[in]\n row_block_dim row size of the blocks in the sparse general BSR matrix.\n @param[in]\n col_block_dim column size of the blocks in the sparse general BSR matrix.\n @param[in]\n csr_descr descriptor of the sparse CSR matrix. Currently, only\n \\ref rocsparse_matrix_type_general is supported.\n @param[out]\n csr_val array of \\p nnzb*row_block_dim*col_block_dim elements containing the values of the sparse CSR matrix.\n @param[out]\n csr_row_ptr array of \\p m+1 where \\p m=mb*row_block_dim elements that point to the start of every row of the\n sparse CSR matrix.\n @param[out]\n csr_col_ind array of \\p nnzb*block_dim*block_dim elements containing the column indices of the sparse CSR matrix.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb or \\p nb or \\p block_dim is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_val,\n \\p bsr_row_ptr, \\p bsr_col_ind, \\p csr_val, \\p csr_row_ptr or\n \\p csr_col_ind pointer is invalid.\n\n \\par Example\n This example converts a general BSR matrix into an CSR matrix.\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n rocsparse_int mb = 2;\n rocsparse_int nb = 2;\n rocsparse_int row_block_dim = 2;\n rocsparse_int col_block_dim = 3;\n rocsparse_int m = Mb * row_block_dim;\n rocsparse_int n = Nb * col_block_dim;\n\n bsr_row_ptr[mb+1] = {0, 1, 3}; // device memory\n bsr_col_ind[nnzb] = {0, 0, 1}; // device memory\n bsr_val[nnzb*block_dim*block_dim] = {1, 0, 4, 2, 0, 3, 5, 0, 0, 0, 0, 9, 7, 0, 8, 6, 0, 0}; // device memory\n\n rocsparse_int nnzb = bsr_row_ptr[mb] - bsr_row_ptr[0];\n\n // Create CSR arrays on device\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnzb * row_block_dim * col_block_dim);\n hipMalloc((void**)&csr_val, sizeof(float) * nnzb * row_block_dim * col_block_dim);\n\n // Create rocsparse handle\n rocsparse_local_handle handle;\n\n rocsparse_mat_descr bsr_descr = nullptr;\n rocsparse_create_mat_descr(&bsr_descr);\n\n rocsparse_mat_descr csr_descr = nullptr;\n rocsparse_create_mat_descr(&csr_descr);\n\n rocsparse_set_mat_index_base(bsr_descr, rocsparse_index_base_zero);\n rocsparse_set_mat_index_base(csr_descr, rocsparse_index_base_zero);\n\n // Format conversion\n rocsparse_sgebsr2csr(handle,\n rocsparse_direction_column,\n mb,\n nb,\n bsr_descr,\n bsr_val,\n bsr_row_ptr,\n bsr_col_ind,\n row_block_dim,\n col_block_dim,\n csr_descr,\n csr_val,\n csr_row_ptr,\n csr_col_ind);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_sgebsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const f32, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f32, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const f64, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut f64, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_float_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_float_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsr2csr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + bsr_descr: rocsparse_mat_descr, + bsr_val: *const rocsparse_double_complex, + bsr_row_ptr: *const rocsparse_int, + bsr_col_ind: *const rocsparse_int, + row_block_dim: rocsparse_int, + col_block_dim: rocsparse_int, + csr_descr: rocsparse_mat_descr, + csr_val: *mut rocsparse_double_complex, + csr_row_ptr: *mut rocsparse_int, + csr_col_ind: *mut rocsparse_int, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function computes the the size of the user allocated temporary storage buffer used when converting a sparse\n general BSR matrix to another sparse general BSR matrix.\n\n \\details\n \\p rocsparse_gebsr2gebsr_buffer_size returns the size of the temporary storage buffer\n that is required by rocsparse_gebsr2gebsr_nnz(), rocsparse_sgebsr2gebsr(), rocsparse_dgebsr2gebsr(),\n rocsparse_cgebsr2gebsr(), and rocsparse_zgebsr2gebsr(). The temporary\n storage buffer must be allocated by the user.\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n \\note\n This routine supports execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n\n @param[in]\n mb number of block rows of the general BSR sparse matrix \\p A.\n\n @param[in]\n nb number of block columns of the general BSR sparse matrix \\p A.\n\n @param[in]\n nnzb number of blocks in the general BSR sparse matrix \\p A.\n\n @param[in]\n descr_A the descriptor of the general BSR sparse matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n bsr_val_A array of \\p nnzb*row_block_dim_A*col_block_dim_A containing the values of the sparse general BSR matrix \\p A.\n\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 elements that point to the start of every block row of the\n sparse general BSR matrix \\p A.\n @param[in]\n bsr_col_ind_A array of \\p nnzb elements containing the block column indices of the sparse general BSR matrix \\p A.\n\n @param[in]\n row_block_dim_A row size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n col_block_dim_A column size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n row_block_dim_C row size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[in]\n col_block_dim_C column size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[out]\n buffer_size number of bytes of the temporary storage buffer required by rocsparse_gebsr2gebsr_nnz(),\n rocsparse_sgebsr2gebsr(), rocsparse_dgebsr2gebsr(), rocsparse_cgebsr2gebsr(), and rocsparse_zgebsr2gebsr().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb or \\p nb or \\p nnzb or \\p row_block_dim_A or\n \\p col_block_dim_A or \\p row_block_dim_C or \\p col_block_dim_C is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_row_ptr_A or \\p bsr_col_ind_A\n or \\p descr_A or \\p buffer_size pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sgebsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const f32, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const f64, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const rocsparse_float_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsr2gebsr_buffer_size( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const rocsparse_double_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief This function is used when converting a general BSR sparse matrix \\p A to another general BSR sparse matrix \\p C.\n Specifically, this function determines the number of non-zero blocks that will exist in \\p C (stored using either a host\n or device pointer), and computes the row pointer array for \\p C.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n\n @param[in]\n mb number of block rows of the general BSR sparse matrix \\p A.\n\n @param[in]\n nb number of block columns of the general BSR sparse matrix \\p A.\n\n @param[in]\n nnzb number of blocks in the general BSR sparse matrix \\p A.\n\n @param[in]\n descr_A the descriptor of the general BSR sparse matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 elements that point to the start of every block row of the\n sparse general BSR matrix \\p A.\n @param[in]\n bsr_col_ind_A array of \\p nnzb elements containing the block column indices of the sparse general BSR matrix \\p A.\n\n @param[in]\n row_block_dim_A row size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n col_block_dim_A column size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n descr_C the descriptor of the general BSR sparse matrix \\p C, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n bsr_row_ptr_C array of \\p mb_C+1 elements that point to the start of every block row of the\n sparse general BSR matrix \\p C where \\p mb_C=(m+row_block_dim_C-1)/row_block_dim_C.\n @param[in]\n row_block_dim_C row size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[in]\n col_block_dim_C column size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[out]\n nnz_total_dev_host_ptr\n total number of nonzero blocks in general BSR sparse matrix \\p C stored using device or host memory.\n\n @param[out]\n temp_buffer\n buffer allocated by the user whose size is determined by calling rocsparse_xgebsr2gebsr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb or \\p nb or \\p nnzb or \\p row_block_dim_A or\n \\p col_block_dim_A or \\p row_block_dim_C or \\p col_block_dim_C is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_row_ptr_A or \\p bsr_col_ind_A\n or \\p bsr_row_ptr_C or \\p descr_A or \\p descr_C or \\p temp_buffer pointer is invalid."] + pub fn rocsparse_gebsr2gebsr_nnz( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_row_ptr_C: *mut rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + nnz_total_dev_host_ptr: *mut rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup conv_module\n \\brief\n This function converts the general BSR sparse matrix \\p A to another general BSR sparse matrix \\p C.\n\n \\details\n The conversion uses three steps. First, the user calls rocsparse_xgebsr2gebsr_buffer_size() to determine the size of\n the required temporary storage buffer. The user then allocates this buffer. Secondly, the user then allocates \\p mb_C+1\n integers for the row pointer array for \\p C where \\p mb_C=(m+row_block_dim_C-1)/row_block_dim_C. The user then calls\n rocsparse_xgebsr2gebsr_nnz() to fill in the row pointer array for \\p C ( \\p bsr_row_ptr_C ) and determine the number of\n non-zero blocks that will exist in \\p C. Finally, the user allocates space for the colimn indices array of \\p C to have\n \\p nnzb_C elements and space for the values array of \\p C to have \\p nnzb_C*roc_block_dim_C*col_block_dim_C and then calls\n rocsparse_xgebsr2gebsr() to complete the conversion.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n\n @param[in]\n dir the storage format of the blocks, \\ref rocsparse_direction_row or \\ref rocsparse_direction_column\n\n @param[in]\n mb number of block rows of the general BSR sparse matrix \\p A.\n\n @param[in]\n nb number of block columns of the general BSR sparse matrix \\p A.\n\n @param[in]\n nnzb number of blocks in the general BSR sparse matrix \\p A.\n\n @param[in]\n descr_A the descriptor of the general BSR sparse matrix \\p A, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n bsr_val_A array of \\p nnzb*row_block_dim_A*col_block_dim_A containing the values of the sparse general BSR matrix \\p A.\n\n @param[in]\n bsr_row_ptr_A array of \\p mb+1 elements that point to the start of every block row of the\n sparse general BSR matrix \\p A.\n @param[in]\n bsr_col_ind_A array of \\p nnzb elements containing the block column indices of the sparse general BSR matrix \\p A.\n\n @param[in]\n row_block_dim_A row size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n col_block_dim_A column size of the blocks in the sparse general BSR matrix \\p A.\n\n @param[in]\n descr_C the descriptor of the general BSR sparse matrix \\p C, the supported matrix type is rocsparse_matrix_type_general and also any valid value of the \\ref rocsparse_index_base.\n\n @param[in]\n bsr_val_C array of \\p nnzb_C*row_block_dim_C*col_block_dim_C containing the values of the sparse general BSR matrix \\p C.\n\n @param[in]\n bsr_row_ptr_C array of \\p mb_C+1 elements that point to the start of every block row of the\n sparse general BSR matrix \\p C.\n @param[in]\n bsr_col_ind_C array of \\p nnzb_C elements containing the block column indices of the sparse general BSR matrix \\p C.\n\n @param[in]\n row_block_dim_C row size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[in]\n col_block_dim_C column size of the blocks in the sparse general BSR matrix \\p C.\n\n @param[out]\n temp_buffer\n buffer allocated by the user whose size is determined by calling rocsparse_xgebsr2gebsr_buffer_size().\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p mb or \\p nb or \\p nnzb or \\p row_block_dim_A or\n \\p col_block_dim_A or \\p row_block_dim_C or \\p col_block_dim_C is invalid.\n \\retval rocsparse_status_invalid_pointer \\p bsr_row_ptr_A or \\p bsr_col_ind_A or \\p bsr_val_A\n or \\p bsr_row_ptr_C or \\p bsr_col_ind_C or \\p bsr_val_C or \\p descr_A or \\p descr_C\n or \\p temp_buffer pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_sgebsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const f32, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f32, + bsr_row_ptr_C: *mut rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dgebsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const f64, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut f64, + bsr_row_ptr_C: *mut rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_cgebsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const rocsparse_float_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_float_complex, + bsr_row_ptr_C: *mut rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zgebsr2gebsr( + handle: rocsparse_handle, + dir: rocsparse_direction, + mb: rocsparse_int, + nb: rocsparse_int, + nnzb: rocsparse_int, + descr_A: rocsparse_mat_descr, + bsr_val_A: *const rocsparse_double_complex, + bsr_row_ptr_A: *const rocsparse_int, + bsr_col_ind_A: *const rocsparse_int, + row_block_dim_A: rocsparse_int, + col_block_dim_A: rocsparse_int, + descr_C: rocsparse_mat_descr, + bsr_val_C: *mut rocsparse_double_complex, + bsr_row_ptr_C: *mut rocsparse_int, + bsr_col_ind_C: *mut rocsparse_int, + row_block_dim_C: rocsparse_int, + col_block_dim_C: rocsparse_int, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Scale a sparse vector and add it to a scaled dense vector.\n\n \\details\n \\ref rocsparse_axpby multiplies the sparse vector \\f$x\\f$ with scalar \\f$\\alpha\\f$ and\n adds the result to the dense vector \\f$y\\f$ that is multiplied with scalar\n \\f$\\beta\\f$, such that\n\n \\f[\n y := \\alpha \\cdot x + \\beta \\cdot y\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n y[x_ind[i]] = alpha * x_val[i] + beta * y[x_ind[i]]\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n x sparse matrix descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y dense matrix descriptor.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p x, \\p beta or \\p y pointer is\n invalid."] + pub fn rocsparse_axpby( + handle: rocsparse_handle, + alpha: *const ::std::os::raw::c_void, + x: rocsparse_spvec_descr, + beta: *const ::std::os::raw::c_void, + y: rocsparse_dnvec_descr, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Gather elements from a dense vector and store them into a sparse vector.\n\n \\details\n \\ref rocsparse_gather gathers the elements from the dense vector \\f$y\\f$ and stores\n them in the sparse vector \\f$x\\f$.\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n x_val[i] = y[x_ind[i]];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n y dense vector \\f$y\\f$.\n @param[out]\n x sparse vector \\f$x\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p x or \\p y pointer is invalid."] + pub fn rocsparse_gather( + handle: rocsparse_handle, + y: rocsparse_dnvec_descr, + x: rocsparse_spvec_descr, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Scatter elements from a sparse vector into a dense vector.\n\n \\details\n \\ref rocsparse_scatter scatters the elements from the sparse vector \\f$x\\f$ in the dense\n vector \\f$y\\f$.\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n y[x_ind[i]] = x_val[i];\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n x sparse vector \\f$x\\f$.\n @param[out]\n y dense vector \\f$y\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p x or \\p y pointer is invalid."] + pub fn rocsparse_scatter( + handle: rocsparse_handle, + x: rocsparse_spvec_descr, + y: rocsparse_dnvec_descr, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Apply Givens rotation to a dense and a sparse vector.\n\n \\details\n \\ref rocsparse_rot applies the Givens rotation matrix \\f$G\\f$ to the sparse vector\n \\f$x\\f$ and the dense vector \\f$y\\f$, where\n \\f[\n G = \\begin{pmatrix} c & s \\\\ -s & c \\end{pmatrix}\n \\f]\n\n \\code{.c}\n for(i = 0; i < nnz; ++i)\n {\n x_tmp = x_val[i];\n y_tmp = y[x_ind[i]];\n\n x_val[i] = c * x_tmp + s * y_tmp;\n y[x_ind[i]] = c * y_tmp - s * x_tmp;\n }\n \\endcode\n\n \\note\n This function is non blocking and executed asynchronously with respect to the host.\n It may return before the actual computation has finished.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n c pointer to the cosine element of \\f$G\\f$, can be on host or device.\n @param[in]\n s pointer to the sine element of \\f$G\\f$, can be on host or device.\n @param[inout]\n x sparse vector \\f$x\\f$.\n @param[inout]\n y dense vector \\f$y\\f$.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p c, \\p s, \\p x or \\p y pointer is\n invalid."] + pub fn rocsparse_rot( + handle: rocsparse_handle, + c: *const ::std::os::raw::c_void, + s: *const ::std::os::raw::c_void, + x: rocsparse_spvec_descr, + y: rocsparse_dnvec_descr, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse matrix to dense matrix conversion\n\n \\details\n \\p rocsparse_sparse_to_dense\n \\p rocsparse_sparse_to_dense performs the conversion of a sparse matrix in CSR, CSC, or COO format to\n a dense matrix\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the sparse to dense operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n mat_A sparse matrix descriptor.\n @param[in]\n mat_B dense matrix descriptor.\n @param[in]\n alg algorithm for the sparse to dense computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the sparse to dense operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p mat_A, \\p mat_B, or \\p buffer_size\n pointer is invalid."] + pub fn rocsparse_sparse_to_dense( + handle: rocsparse_handle, + mat_A: rocsparse_spmat_descr, + mat_B: rocsparse_dnmat_descr, + alg: rocsparse_sparse_to_dense_alg, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Dense matrix to sparse matrix conversion\n\n \\details\n \\p rocsparse_dense_to_sparse\n \\p rocsparse_dense_to_sparse performs the conversion of a dense matrix to a sparse matrix in CSR, CSC, or COO format.\n\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the dense to sparse operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n mat_A dense matrix descriptor.\n @param[in]\n mat_B sparse matrix descriptor.\n @param[in]\n alg algorithm for the sparse to dense computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the dense to sparse operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p mat_A, \\p mat_B, or \\p buffer_size\n pointer is invalid."] + pub fn rocsparse_dense_to_sparse( + handle: rocsparse_handle, + mat_A: rocsparse_dnmat_descr, + mat_B: rocsparse_spmat_descr, + alg: rocsparse_dense_to_sparse_alg, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse vector inner dot product\n\n \\details\n \\ref rocsparse_spvv computes the inner dot product of the sparse vecotr \\f$x\\f$ with the\n dense vector \\f$y\\f$, such that\n \\f[\n \\text{result} := x^{'} \\cdot y,\n \\f]\n with\n \\f[\n op(x) = \\left\\{\n \\begin{array}{ll}\n x, & \\text{if trans == rocsparse_operation_none} \\\\\n \\bar{x}, & \\text{if trans == rocsparse_operation_conjugate_transpose} \\\\\n \\end{array}\n \\right.\n \\f]\n\n \\code{.c}\n result = 0;\n for(i = 0; i < nnz; ++i)\n {\n result += x_val[i] * y[x_ind[i]];\n }\n \\endcode\n\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the SpVV operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans sparse vector operation type.\n @param[in]\n x sparse vector descriptor.\n @param[in]\n y dense vector descriptor.\n @param[out]\n result pointer to the result, can be host or device memory\n @param[in]\n compute_type floating point precision for the SpVV computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpVV operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p x, \\p y, \\p result or \\p buffer_size\n pointer is invalid.\n \\retval rocsparse_status_not_implemented \\p compute_type is currently not\n supported.\n\n \\par Example\n \\code{.c}\n // Number of non-zeros of the sparse vector\n int nnz = 3;\n\n // Size of sparse and dense vector\n int size = 9;\n\n // Sparse index vector\n std::vector hx_ind = {0, 3, 5};\n\n // Sparse value vector\n std::vector hx_val = {1.0f, 2.0f, 3.0f};\n\n // Dense vector\n std::vector hy = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};\n\n // Offload data to device\n int* dx_ind;\n float* dx_val;\n float* dy;\n hipMalloc((void**)&dx_ind, sizeof(int) * nnz);\n hipMalloc((void**)&dx_val, sizeof(float) * nnz);\n hipMalloc((void**)&dy, sizeof(float) * size);\n\n hipMemcpy(dx_ind, hx_ind.data(), sizeof(int) * nnz, hipMemcpyHostToDevice);\n hipMemcpy(dx_val, hx_val.data(), sizeof(float) * nnz, hipMemcpyHostToDevice);\n hipMemcpy(dy, hy.data(), sizeof(float) * size, hipMemcpyHostToDevice);\n\n rocsparse_handle handle;\n rocsparse_spvec_descr vecX;\n rocsparse_dnvec_descr vecY;\n\n rocsparse_indextype idx_type = rocsparse_indextype_i32;\n rocsparse_datatype data_type = rocsparse_datatype_f32_r;\n rocsparse_datatype compute_type = rocsparse_datatype_f32_r;\n rocsparse_operation trans = rocsparse_operation_none;\n rocsparse_index_base idx_base = rocsparse_index_base_zero;\n\n rocsparse_create_handle(&handle);\n\n // Create sparse vector X\n rocsparse_create_spvec_descr(&vecX,\n size,\n nnz,\n dx_ind,\n dx_val,\n idx_type,\n idx_base,\n data_type);\n\n // Create dense vector Y\n rocsparse_create_dnvec_descr(&vecY,\n size,\n dy,\n data_type);\n\n // Obtain buffer size\n float hresult = 0.0f;\n size_t buffer_size;\n rocsparse_spvv(handle,\n trans,\n vecX,\n vecY,\n &hresult,\n compute_type,\n &buffer_size,\n nullptr);\n\n void* temp_buffer;\n hipMalloc(&temp_buffer, buffer_size);\n\n // SpVV\n rocsparse_spvv(handle,\n trans,\n vecX,\n vecY,\n &hresult,\n compute_type,\n &buffer_size,\n temp_buffer);\n\n hipDeviceSynchronize();\n\n std::cout << \"hresult: \" << hresult << std::endl;\n\n // Clear rocSPARSE\n rocsparse_destroy_spvec_descr(vecX);\n rocsparse_destroy_dnvec_descr(vecY);\n rocsparse_destroy_handle(handle);\n\n // Clear device memory\n hipFree(dx_ind);\n hipFree(dx_val);\n hipFree(dy);\n hipFree(temp_buffer);\n \\endcode"] + pub fn rocsparse_spvv( + handle: rocsparse_handle, + trans: rocsparse_operation, + x: rocsparse_spvec_descr, + y: rocsparse_dnvec_descr, + result: *mut ::std::os::raw::c_void, + compute_type: rocsparse_datatype, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse matrix vector multiplication\n\n \\details\n \\ref rocsparse_spmv multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix and the dense vector \\f$x\\f$ and adds the result to the dense vector \\f$y\\f$\n that is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\details\n \\ref rocsparse_spmv supports multiple combinations of data types and compute types. The tables below indicate the currently\n supported different data types that can be used for for the sparse matrix A and the dense vectors X and Y and the compute\n type for \\f$\\alpha\\f$ and \\f$\\beta\\f$. The advantage of using different data types is to save on memory bandwidth and storage\n when a user application allows while performing the actual computation in a higher precision.\n\n Uniform Precisions:\n \\verbatim\n |----------------------------------------------------|\n | A / X / Y / compute_type |\n |----------------------------------------------------|\n | rocsparse_datatype_f32_r |\n |----------------------------------------------------|\n | rocsparse_datatype_f64_r |\n |----------------------------------------------------|\n | rocsparse_datatype_f32_c |\n |----------------------------------------------------|\n | rocsparse_datatype_f64_c |\n |----------------------------------------------------|\n \\endverbatim\n\n Mixed precisions:\n \\verbatim\n |-------------------------|--------------------------|--------------------------|\n | A / X | Y | compute_type |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_i32_r | rocsparse_datatype_i32_r |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_f32_r | rocsparse_datatype_f32_r |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_i32_r | rocsparse_datatype_i32_r |\n |-------------------------|--------------------------|--------------------------|\n \\endverbatim\n\n Mixed-regular Complex precisions\n \\verbatim\n |----------------------------|----------------------------|\n | A | X / Y / compute_type |\n |----------------------------|----------------------------|\n | rocsparse_datatype_f32_r | rocsparse_datatype_f32_c |\n |----------------------------|----------------------------|\n | rocsparse_datatype_f64_r | rocsparse_datatype_f64_c |\n |----------------------------|----------------------------|\n \\endverbatim\n\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the SpMV operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note\n Only the \\ref rocsparse_spmv_stage_buffer_size stage and the \\ref rocsparse_spmv_stage_compute stage are non blocking\n and executed asynchronously with respect to the host. They may return before the actual computation has finished.\n The \\ref rocsparse_spmv_stage_preprocess stage is blocking with respect to the host.\n\n \\note\n Only the \\ref rocsparse_spmv_stage_buffer_size stage and the \\ref rocsparse_spmv_stage_compute stage\n support execution in a hipGraph context. The \\ref rocsparse_spmv_stage_preprocess stage does not support hipGraph.\n\n \\note\n The sparse matrix formats currently supported are: rocsparse_format_bsr, rocsparse_format_coo,\n rocsparse_format_coo_aos, rocsparse_format_csr, rocsparse_format_csc and rocsparse_format_ell.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n mat matrix descriptor.\n @param[in]\n x vector descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y vector descriptor.\n @param[in]\n compute_type floating point precision for the SpMV computation.\n @param[in]\n alg SpMV algorithm for the SpMV computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpMV operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p mat, \\p x, \\p beta, \\p y or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_invalid_value the value of \\p trans, \\p trans\\_B, \\p compute\\_type, \\p alg is incorrect.\n \\retval rocsparse_status_not_implemented \\p compute_type or \\p alg is\n currently not supported."] + pub fn rocsparse_spmv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat: rocsparse_spmat_descr, + x: rocsparse_dnvec_descr, + beta: *const ::std::os::raw::c_void, + y: rocsparse_dnvec_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spmv_alg, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse matrix vector multiplication\n\n \\details\n \\ref rocsparse_spmv_ex multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times n\\f$\n matrix and the dense vector \\f$x\\f$ and adds the result to the dense vector \\f$y\\f$\n that is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n y := \\alpha \\cdot op(A) \\cdot x + \\beta \\cdot y,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\details\n \\ref rocsparse_spmv supports multiple combinations of data types and compute types. The tables below indicate the currently\n supported different data types that can be used for for the sparse matrix A and the dense vectors X and Y and the compute\n type for \\f$\\alpha\\f$ and \\f$\\beta\\f$. The advantage of using different data types is to save on memory bandwidth and storage\n when a user application allows while performing the actual computation in a higher precision.\n\n Uniform Precisions:\n \\verbatim\n |----------------------------------------------------|\n | A / X / Y / compute_type |\n |----------------------------------------------------|\n | rocsparse_datatype_f32_r |\n |----------------------------------------------------|\n | rocsparse_datatype_f64_r |\n |----------------------------------------------------|\n | rocsparse_datatype_f32_c |\n |----------------------------------------------------|\n | rocsparse_datatype_f64_c |\n |----------------------------------------------------|\n \\endverbatim\n\n Mixed precisions:\n \\verbatim\n |-------------------------|--------------------------|--------------------------|\n | A / X | Y | compute_type |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_i32_r | rocsparse_datatype_i32_r |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_f32_r | rocsparse_datatype_f32_r |\n |-------------------------|--------------------------|--------------------------|\n | rocsparse_datatype_i8_r | rocsparse_datatype_i32_r | rocsparse_datatype_i32_r |\n |-------------------------|--------------------------|--------------------------|\n \\endverbatim\n\n Mixed-regular Complex precisions\n \\verbatim\n |----------------------------|----------------------------|\n | A | X / Y / compute_type |\n |----------------------------|----------------------------|\n | rocsparse_datatype_f32_r | rocsparse_datatype_f32_c |\n |----------------------------|----------------------------|\n | rocsparse_datatype_f64_r | rocsparse_datatype_f64_c |\n |----------------------------|----------------------------|\n \\endverbatim\n\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the SpMV operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note\n The sparse matrix formats currently supported are: rocsparse_format_bsr, rocsparse_format_coo,\n rocsparse_format_coo_aos, rocsparse_format_csr, rocsparse_format_csc and rocsparse_format_ell.\n\n \\note SpMV_ex requires three stages to complete. The first stage\n \\ref rocsparse_spmv_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls to \\ref rocsparse_spmv_ex. The second stage\n \\ref rocsparse_spmv_stage_preprocess will preprocess data that would be saved in the temporary storage buffer.\n In the final stage \\ref rocsparse_spmv_stage_compute, the actual computation is performed.\n \\note If \\ref rocsparse_spmv_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n Else, the SpMV_ex preprocess and the SpMV algorithm will be executed.\n\n \\note\n Only the \\ref rocsparse_spmv_stage_buffer_size stage and the \\ref rocsparse_spmv_stage_compute stage are non blocking\n and executed asynchronously with respect to the host. They may return before the actual computation has finished.\n The \\ref rocsparse_spmv_stage_preprocess stage is blocking with respect to the host.\n\n \\note\n Only the \\ref rocsparse_spmv_stage_buffer_size stage and the \\ref rocsparse_spmv_stage_compute stage\n support execution in a hipGraph context. The \\ref rocsparse_spmv_stage_preprocess stage does not support hipGraph.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n mat matrix descriptor.\n @param[in]\n x vector descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n y vector descriptor.\n @param[in]\n compute_type floating point precision for the SpMV computation.\n @param[in]\n alg SpMV algorithm for the SpMV computation.\n @param[in]\n stage SpMV stage for the SpMV computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpMV operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p mat, \\p x, \\p beta, \\p y or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_invalid_value the value of \\p trans, \\p trans\\_B, \\p compute\\_type, \\p alg or \\p stage is incorrect.\n \\retval rocsparse_status_not_implemented \\p compute_type or \\p alg is\n currently not supported."] + pub fn rocsparse_spmv_ex( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat: rocsparse_spmat_descr, + x: rocsparse_dnvec_descr, + beta: *const ::std::os::raw::c_void, + y: rocsparse_dnvec_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spmv_alg, + stage: rocsparse_spmv_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse triangular solve\n\n \\details\n \\p rocsparse_spsv_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR or COO storage format, a dense solution vector\n \\f$y\\f$ and the right-hand side \\f$x\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot y = \\alpha \\cdot x,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note SpSV requires three stages to complete. The first stage\n \\ref rocsparse_spsv_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls. The second stage\n \\ref rocsparse_spsv_stage_preprocess will preprocess data that would be saved in the temporary storage buffer.\n In the final stage \\ref rocsparse_spsv_stage_compute, the actual computation is performed.\n \\note If \\ref rocsparse_spsv_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n If \\p buffer_size is equal to \\p nullptr, analysis will be performed.\n Otherwise, the SpSV preprocess and the SpSV algorithm will be executed.\n\n \\note\n Only the \\ref rocsparse_spsv_stage_buffer_size stage and the \\ref rocsparse_spsv_stage_compute stage are non blocking\n and executed asynchronously with respect to the host. They may return before the actual computation has finished.\n The \\ref rocsparse_spsv_stage_preprocess stage is blocking with respect to the host.\n\n \\note\n Currently, only \\p trans == \\ref rocsparse_operation_none and \\p trans == \\ref rocsparse_operation_transpose is supported.\n\n \\note\n Only the \\ref rocsparse_spsv_stage_buffer_size stage and the \\ref rocsparse_spsv_stage_compute stage\n support execution in a hipGraph context. The \\ref rocsparse_spsv_stage_preprocess stage does not support hipGraph.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n mat matrix descriptor.\n @param[in]\n x vector descriptor.\n @param[inout]\n y vector descriptor.\n @param[in]\n compute_type floating point precision for the SpSV computation.\n @param[in]\n alg SpSV algorithm for the SpSV computation.\n @param[in]\n stage SpSV stage for the SpSV computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpSV operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p mat, \\p x, \\p y, \\p descr or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented \\p trans, \\p compute_type, \\p stage or \\p alg is\n currently not supported."] + pub fn rocsparse_spsv( + handle: rocsparse_handle, + trans: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat: rocsparse_spmat_descr, + x: rocsparse_dnvec_descr, + y: rocsparse_dnvec_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spsv_alg, + stage: rocsparse_spsv_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse iterative triangular solve\n\n \\details\n \\p rocsparse_spitsv solves, using the Jacobi iterative method, a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR format, a dense solution vector\n \\f$y\\f$ and the right-hand side \\f$x\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot y = \\alpha \\cdot x,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note SpITSV requires three stages to complete. The first stage\n \\ref rocsparse_spitsv_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls. The second stage\n \\ref rocsparse_spitsv_stage_preprocess will preprocess data that would be saved in the temporary storage buffer.\n In the final stage \\ref rocsparse_spitsv_stage_compute, the actual computation is performed.\n \\note If \\ref rocsparse_spitsv_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n If \\p buffer_size is equal to \\p nullptr, analysis will be performed.\n Otherwise, the SpITSV preprocess and the SpITSV iterative algorithm will be executed.\n\n \\note\n Currently, only non-mixed numerical precision is supported.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[inout]\n host_nmaxiter maximum number of iteration on input and maximum number of iteration on output.\n @param[in]\n host_tol if the pointer is null then loop will execute \\p nmaxiter[0] iterations. The precision is float for f32 based calculation (including the complex case) and double for f64 based calculation (including the complex case).\n @param[out]\n host_history Optional array to record the history. The precision is float for f32 based calculation (including the complex case) and double for f64 based calculation (including the complex case).\n @param[in]\n trans matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n mat matrix descriptor.\n @param[in]\n x vector descriptor.\n @param[inout]\n y vector descriptor.\n @param[in]\n compute_type floating point precision for the SpITSV computation.\n @param[in]\n alg SpITSV algorithm for the SpITSV computation.\n @param[in]\n stage SpITSV stage for the SpITSV computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpITSV operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p mat, \\p x, \\p y, \\p descr or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented \\p trans, \\p compute_type, \\p stage or \\p alg is\n currently not supported."] + pub fn rocsparse_spitsv( + handle: rocsparse_handle, + host_nmaxiter: *mut rocsparse_int, + host_tol: *const ::std::os::raw::c_void, + host_history: *mut ::std::os::raw::c_void, + trans: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat: rocsparse_spmat_descr, + x: rocsparse_dnvec_descr, + y: rocsparse_dnvec_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spitsv_alg, + stage: rocsparse_spitsv_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse triangular system solve\n\n \\details\n \\p rocsparse_spsm_solve solves a sparse triangular linear system of a sparse\n \\f$m \\times m\\f$ matrix, defined in CSR or COO storage format, a dense solution matrix\n \\f$C\\f$ and the right-hand side \\f$B\\f$ that is multiplied by \\f$\\alpha\\f$, such that\n \\f[\n op(A) \\cdot C = \\alpha \\cdot op(B),\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note SpSM requires three stages to complete. The first stage\n \\ref rocsparse_spsm_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls. The second stage\n \\ref rocsparse_spsm_stage_preprocess will preprocess data that would be saved in the temporary storage buffer.\n In the final stage \\ref rocsparse_spsm_stage_compute, the actual computation is performed.\n \\note If \\ref rocsparse_spsm_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n If \\p buffer_size is equal to \\p nullptr, analysis will be performed.\n Otherwise, the SpSM preprocess and the SpSM algorithm will be executed.\n\n \\note\n Only the \\ref rocsparse_spsm_stage_buffer_size stage and the \\ref rocsparse_spsm_stage_compute stage are non blocking\n and executed asynchronously with respect to the host. They may return before the actual computation has finished.\n The \\ref rocsparse_spsm_stage_preprocess stage is blocking with respect to the host.\n\n \\note\n Currently, only \\p trans_A == \\ref rocsparse_operation_none and \\p trans_A == \\ref rocsparse_operation_transpose is supported.\n Currently, only \\p trans_B == \\ref rocsparse_operation_none and \\p trans_B == \\ref rocsparse_operation_transpose is supported.\n\n \\note\n Only the \\ref rocsparse_spsm_stage_buffer_size stage and the \\ref rocsparse_spsm_stage_compute stage\n support execution in a hipGraph context. The \\ref rocsparse_spsm_stage_preprocess stage does not support hipGraph.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix operation type for the sparse matrix A.\n @param[in]\n trans_B matrix operation type for the dense matrix B.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n matA sparse matrix descriptor.\n @param[in]\n matB dense matrix descriptor.\n @param[inout]\n matC dense matrix descriptor.\n @param[in]\n compute_type floating point precision for the SpSM computation.\n @param[in]\n alg SpSM algorithm for the SpSM computation.\n @param[in]\n stage SpSM stage for the SpSM computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpSM operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p matA, \\p matB, \\p matC, \\p descr or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented \\p trans_A, \\p trans_B, \\p compute_type, \\p stage or \\p alg is\n currently not supported."] + pub fn rocsparse_spsm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + matA: rocsparse_spmat_descr, + matB: rocsparse_dnmat_descr, + matC: rocsparse_dnmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spsm_alg, + stage: rocsparse_spsm_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse matrix dense matrix multiplication, extension routine.\n\n \\details\n \\p rocsparse_spmm (or \\p rocsparse_spmm_ex ) multiplies the scalar \\f$\\alpha\\f$ with a sparse \\f$m \\times k\\f$\n matrix \\f$A\\f$, defined in CSR or COO or Blocked ELL storage format, and the dense \\f$k \\times n\\f$\n matrix \\f$B\\f$ and adds the result to the dense \\f$m \\times n\\f$ matrix \\f$C\\f$ that\n is multiplied by the scalar \\f$\\beta\\f$, such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot C,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note\n Only the \\ref rocsparse_spmm_stage_buffer_size stage and the \\ref rocsparse_spmm_stage_compute stage are non blocking\n and executed asynchronously with respect to the host. They may return before the actual computation has finished.\n The \\ref rocsparse_spmm_stage_preprocess stage is blocking with respect to the host.\n\n \\note\n Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported for COO and Blocked ELL formats.\n\n \\note\n Only the \\ref rocsparse_spmm_stage_buffer_size stage and the \\ref rocsparse_spmm_stage_compute stage\n support execution in a hipGraph context. The \\ref rocsparse_spmm_stage_preprocess stage does not support hipGraph.\n\n \\note\n Currently, only CSR, COO and Blocked ELL sparse formats are supported.\n\n \\note\n Different algorithms are available which can provide better performance for different matrices.\n Currently, the available algorithms are rocsparse_spmm_alg_csr, rocsparse_spmm_alg_csr_row_split\n or rocsparse_spmm_alg_csr_merge for CSR matrices, rocsparse_spmm_alg_bell for Blocked ELL matrices and\n rocsparse_spmm_alg_coo_segmented or rocsparse_spmm_alg_coo_atomic for COO matrices. Additionally,\n one can specify the algorithm to be rocsparse_spmm_alg_default. In the case of CSR matrices this will\n set the algorithm to be rocsparse_spmm_alg_csr, in the case of Blocked ELL matrices this will set the\n algorithm to be rocsparse_spmm_alg_bell and for COO matrices it will set the algorithm to be\n rocsparse_spmm_alg_coo_atomic. When A is transposed, rocsparse_spmm will revert to using\n rocsparse_spmm_alg_csr for CSR format and rocsparse_spmm_alg_coo_atomic for COO format regardless\n of algorithm selected.\n\n \\note\n This function writes the required allocation size (in bytes) to \\p buffer_size and\n returns without performing the SpMM operation, when a nullptr is passed for\n \\p temp_buffer.\n\n \\note SpMM requires three stages to complete. The first stage\n \\ref rocsparse_spmm_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls to \\ref rocsparse_spmm (or \\ref rocsparse_spmm_ex). The second stage\n \\ref rocsparse_spmm_stage_preprocess will preprocess data that would be saved in the temporary storage buffer.\n In the final stage \\ref rocsparse_spmm_stage_compute, the actual computation is performed.\n \\note If \\ref rocsparse_spmm_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n Else, the SpMM preprocess and the SpMM algorithm will be executed.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A matrix operation type.\n @param[in]\n trans_B matrix operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n mat_A matrix descriptor.\n @param[in]\n mat_B matrix descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n mat_C matrix descriptor.\n @param[in]\n compute_type floating point precision for the SpMM computation.\n @param[in]\n alg SpMM algorithm for the SpMM computation.\n @param[in]\n stage SpMM stage for the SpMM computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpMM operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha, \\p mat_A, \\p mat_B, \\p mat_C, \\p beta, or\n \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented \\p trans_A, \\p trans_B, \\p compute_type or \\p alg is\n currently not supported.\n \\par Example\n This example performs sparse matrix-dense matrix multiplication, C = alpha * A * B + beta * C\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n // 1 4 2\n // 1 2 3\n // B = 5 4 0\n // 3 1 9\n // 1 2 2\n // 0 3 0\n\n // 1 1 5\n // C = 1 2 1\n // 1 3 1\n // 6 2 4\n\n rocsparse_int m = 4;\n rocsparse_int k = 6;\n rocsparse_int n = 3;\n\n csr_row_ptr[m + 1] = {0, 1, 3}; // device memory\n csr_col_ind[nnz] = {0, 0, 1}; // device memory\n csr_val[nnz] = {1, 0, 4, 2, 0, 3, 5, 0, 0, 0, 0, 9, 7, 0, 8, 6, 0, 0}; // device memory\n\n B[k * n] = {1, 1, 5, 3, 1, 0, 4, 2, 4, 1, 2, 3, 2, 3, 0, 9, 2, 0}; // device memory\n C[m * n] = {1, 1, 1, 6, 1, 2, 3, 2, 5, 1, 1, 4}; // device memory\n\n rocsparse_int nnz = csr_row_ptr[m] - csr_row_ptr[0];\n\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Create CSR arrays on device\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n float* B;\n float* C;\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&csr_val, sizeof(float) * nnz);\n hipMalloc((void**)&B, sizeof(float) * k * n);\n hipMalloc((void**)&C, sizeof(float) * m * n);\n\n // Create rocsparse handle\n rocsparse_local_handle handle;\n\n // Types\n rocsparse_indextype itype = rocsparse_indextype_i32;\n rocsparse_indextype jtype = rocsparse_indextype_i32;\n rocsparse_datatype ttype = rocsparse_datatype_f32_r;\n\n // Create descriptors\n rocsparse_spmat_descr mat_A;\n rocsparse_dnmat_descr mat_B;\n rocsparse_dnmat_descr mat_C;\n\n rocsparse_create_csr_descr(&mat_A, m, k, nnz, csr_row_ptr, csr_col_ind, csr_val, itype, jtype, rocsparse_index_base_zero, ttype);\n rocsparse_create_dnmat_descr(&mat_B, k, n, k, B, ttype, rocsparse_order_column);\n rocsparse_create_dnmat_descr(&mat_C, m, n, m, C, ttype, rocsparse_order_column);\n\n // Query SpMM buffer\n size_t buffer_size;\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_buffer_size,\n &buffer_size,\n nullptr));\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_preprocess,\n &buffer_size,\n buffer));\n\n // Pointer mode host\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_compute,\n &buffer_size,\n buffer));\n\n // Clear up on device\n hipFree(csr_row_ptr);\n hipFree(csr_col_ind);\n hipFree(csr_val);\n hipFree(B);\n hipFree(C);\n hipFree(temp_buffer);\n\n rocsparse_destroy_spmat_descr(mat_A);\n rocsparse_destroy_dnmat_descr(mat_B);\n rocsparse_destroy_dnmat_descr(mat_C);\n \\endcode\n\n \\par Example\n SpMM also supports batched computation for CSR and COO matrices. There are three supported batch modes:\n C_i = A * B_i\n C_i = A_i * B\n C_i = A_i * B_i\n The batch mode is determined by the batch count and stride passed for each matrix. For example\n to use the first batch mode (C_i = A * B_i) with 100 batches for non-transposed A, B, and C, one passes:\n batch_count_A = 1\n batch_count_B = 100\n batch_count_C = 100\n offsets_batch_stride_A = 0\n columns_values_batch_stride_A = 0\n batch_stride_B = k * n\n batch_stride_C = m * n\n To use the second batch mode (C_i = A_i * B) one could use:\n batch_count_A = 100\n batch_count_B = 1\n batch_count_C = 100\n offsets_batch_stride_A = m + 1\n columns_values_batch_stride_A = nnz\n batch_stride_B = 0\n batch_stride_C = m * n\n And to use the third batch mode (C_i = A_i * B_i) one could use:\n batch_count_A = 100\n batch_count_B = 100\n batch_count_C = 100\n offsets_batch_stride_A = m + 1\n columns_values_batch_stride_A = nnz\n batch_stride_B = k * n\n batch_stride_C = m * n\n An example of the first batch mode (C_i = A * B_i) is provided below.\n \\code{.c}\n // 1 4 0 0 0 0\n // A = 0 2 3 0 0 0\n // 5 0 0 7 8 0\n // 0 0 9 0 6 0\n\n rocsparse_int m = 4;\n rocsparse_int k = 6;\n rocsparse_int n = 3;\n\n csr_row_ptr[m + 1] = {0, 1, 3}; // device memory\n csr_col_ind[nnz] = {0, 0, 1}; // device memory\n csr_val[nnz] = {1, 0, 4, 2, 0, 3, 5, 0, 0, 0, 0, 9, 7, 0, 8, 6, 0, 0}; // device memory\n\n B[batch_count_B * k * n] = {...}; // device memory\n C[batch_count_C * m * n] = {...}; // device memory\n\n rocsparse_int nnz = csr_row_ptr[m] - csr_row_ptr[0];\n\n rocsparse_int batch_count_A = 1;\n rocsparse_int batch_count_B = 100;\n rocsparse_int batch_count_C = 100;\n\n rocsparse_int offsets_batch_stride_A = 0;\n rocsparse_int columns_values_batch_stride_A = 0;\n rocsparse_int batch_stride_B = k * n;\n rocsparse_int batch_stride_C = m * n;\n\n float alpha = 1.0f;\n float beta = 0.0f;\n\n // Create CSR arrays on device\n rocsparse_int* csr_row_ptr;\n rocsparse_int* csr_col_ind;\n float* csr_val;\n float* B;\n float* C;\n hipMalloc((void**)&csr_row_ptr, sizeof(rocsparse_int) * (m + 1));\n hipMalloc((void**)&csr_col_ind, sizeof(rocsparse_int) * nnz);\n hipMalloc((void**)&csr_val, sizeof(float) * nnz);\n hipMalloc((void**)&B, sizeof(float) * batch_count_B * k * n);\n hipMalloc((void**)&C, sizeof(float) * batch_count_C * m * n);\n\n // Create rocsparse handle\n rocsparse_local_handle handle;\n\n // Types\n rocsparse_indextype itype = rocsparse_indextype_i32;\n rocsparse_indextype jtype = rocsparse_indextype_i32;\n rocsparse_datatype ttype = rocsparse_datatype_f32_r;\n\n // Create descriptors\n rocsparse_spmat_descr mat_A;\n rocsparse_dnmat_descr mat_B;\n rocsparse_dnmat_descr mat_C;\n\n rocsparse_create_csr_descr(&mat_A, m, k, nnz, csr_row_ptr, csr_col_ind, csr_val, itype, jtype, rocsparse_index_base_zero, ttype);\n rocsparse_create_dnmat_descr(&mat_B, k, n, k, B, ttype, rocsparse_order_column);\n rocsparse_create_dnmat_descr(&mat_C, m, n, m, C, ttype, rocsparse_order_column);\n\n rocsparse_csr_set_strided_batch(mat_A, batch_count_A, offsets_batch_stride_A, columns_values_batch_stride_A);\n rocsparse_dnmat_set_strided_batch(B, batch_count_B, batch_stride_B);\n rocsparse_dnmat_set_strided_batch(C, batch_count_C, batch_stride_C);\n\n // Query SpMM buffer\n size_t buffer_size;\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_buffer_size,\n &buffer_size,\n nullptr));\n\n // Allocate buffer\n void* buffer;\n hipMalloc(&buffer, buffer_size);\n\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_preprocess,\n &buffer_size,\n buffer));\n\n // Pointer mode host\n rocsparse_spmm(handle,\n rocsparse_operation_none,\n rocsparse_operation_none,\n &alpha,\n mat_A,\n mat_B,\n &beta,\n mat_C,\n ttype,\n rocsparse_spmm_alg_default,\n rocsparse_spmm_stage_compute,\n &buffer_size,\n buffer));\n\n // Clear up on device\n hipFree(csr_row_ptr);\n hipFree(csr_col_ind);\n hipFree(csr_val);\n hipFree(B);\n hipFree(C);\n hipFree(temp_buffer);\n\n rocsparse_destroy_spmat_descr(mat_A);\n rocsparse_destroy_dnmat_descr(mat_B);\n rocsparse_destroy_dnmat_descr(mat_C);\n \\endcode\n/\n/**@{"] + pub fn rocsparse_spmm_ex( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat_A: rocsparse_spmat_descr, + mat_B: rocsparse_dnmat_descr, + beta: *const ::std::os::raw::c_void, + mat_C: rocsparse_dnmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spmm_alg, + stage: rocsparse_spmm_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_spmm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + mat_A: rocsparse_spmat_descr, + mat_B: rocsparse_dnmat_descr, + beta: *const ::std::os::raw::c_void, + mat_C: rocsparse_dnmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spmm_alg, + stage: rocsparse_spmm_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sparse matrix sparse matrix multiplication\n\n \\details\n \\ref rocsparse_spgemm multiplies the scalar \\f$\\alpha\\f$ with the sparse\n \\f$m \\times k\\f$ matrix \\f$A\\f$ and the sparse \\f$k \\times n\\f$ matrix \\f$B\\f$ and\n adds the result to the sparse \\f$m \\times n\\f$ matrix \\f$D\\f$ that is multiplied by\n \\f$\\beta\\f$. The final result is stored in the sparse \\f$m \\times n\\f$ matrix \\f$C\\f$,\n such that\n \\f[\n C := \\alpha \\cdot op(A) \\cdot op(B) + \\beta \\cdot D,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if trans_A == rocsparse_operation_none} \\\\\n A^T, & \\text{if trans_A == rocsparse_operation_transpose} \\\\\n A^H, & \\text{if trans_A == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if trans_B == rocsparse_operation_none} \\\\\n B^T, & \\text{if trans_B == rocsparse_operation_transpose} \\\\\n B^H, & \\text{if trans_B == rocsparse_operation_conjugate_transpose}\n \\end{array}\n \\right.\n \\f]\n\n \\note SpGEMM requires three stages to complete. The first stage\n \\ref rocsparse_spgemm_stage_buffer_size will return the size of the temporary storage buffer\n that is required for subsequent calls to \\ref rocsparse_spgemm. The second stage\n \\ref rocsparse_spgemm_stage_nnz will determine the number of non-zero elements of the\n resulting \\f$C\\f$ matrix. If the sparsity pattern of \\f$C\\f$ is already known, this\n stage can be skipped. In the final stage \\ref rocsparse_spgemm_stage_compute, the actual\n computation is performed.\n \\note If \\ref rocsparse_spgemm_stage_auto is selected, rocSPARSE will automatically detect\n which stage is required based on the following indicators:\n If \\p temp_buffer is equal to \\p nullptr, the required buffer size will be returned.\n Else, if the number of non-zeros of \\f$C\\f$ is zero, the number of non-zero entries will be\n computed.\n Else, the SpGEMM algorithm will be executed.\n \\note If \\f$\\alpha == 0\\f$, then \\f$C = \\beta \\cdot D\\f$ will be computed.\n \\note If \\f$\\beta == 0\\f$, then \\f$C = \\alpha \\cdot op(A) \\cdot op(B)\\f$ will be\n computed.\n \\note Currently only CSR and BSR formats are supported.\n \\note If \\ref rocsparse_spgemm_stage_symbolic is selected then the symbolic computation is performed only.\n \\note If \\ref rocsparse_spgemm_stage_numeric is selected then the numeric computation is performed only.\n \\note For the \\ref rocsparse_spgemm_stage_symbolic and \\ref rocsparse_spgemm_stage_numeric stages, only\n CSR matrix format is currently supported.\n \\note \\f$\\alpha == beta == 0\\f$ is invalid.\n \\note It is allowed to pass the same sparse matrix for \\f$C\\f$ and \\f$D\\f$, if both\n matrices have the same sparsity pattern.\n \\note Currently, only \\p trans_A == \\ref rocsparse_operation_none is supported.\n \\note Currently, only \\p trans_B == \\ref rocsparse_operation_none is supported.\n \\note This function is non blocking and executed asynchronously with respect to the\n host. It may return before the actual computation has finished.\n \\note Please note, that for rare matrix products with more than 4096 non-zero entries\n per row, additional temporary storage buffer is allocated by the algorithm.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n trans_A sparse matrix \\f$A\\f$ operation type.\n @param[in]\n trans_B sparse matrix \\f$B\\f$ operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A sparse matrix \\f$A\\f$ descriptor.\n @param[in]\n B sparse matrix \\f$B\\f$ descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[in]\n D sparse matrix \\f$D\\f$ descriptor.\n @param[out]\n C sparse matrix \\f$C\\f$ descriptor.\n @param[in]\n compute_type floating point precision for the SpGEMM computation.\n @param[in]\n alg SpGEMM algorithm for the SpGEMM computation.\n @param[in]\n stage SpGEMM stage for the SpGEMM computation.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer. buffer_size is set when\n \\p temp_buffer is nullptr.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user. When a nullptr is passed,\n the required allocation size (in bytes) is written to \\p buffer_size and\n function returns without performing the SpGEMM operation.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p A, \\p B, \\p D, \\p C or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_memory_error additional buffer for long rows could not be\n allocated.\n \\retval rocsparse_status_not_implemented\n \\p trans_A != \\ref rocsparse_operation_none or\n \\p trans_B != \\ref rocsparse_operation_none."] + pub fn rocsparse_spgemm( + handle: rocsparse_handle, + trans_A: rocsparse_operation, + trans_B: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + A: rocsparse_spmat_descr, + B: rocsparse_spmat_descr, + beta: *const ::std::os::raw::c_void, + D: rocsparse_spmat_descr, + C: rocsparse_spmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_spgemm_alg, + stage: rocsparse_spgemm_stage, + buffer_size: *mut usize, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Sampled Dense-Dense Matrix Multiplication.\n\n \\details\n \\ref rocsparse_sddmm multiplies the scalar \\f$\\alpha\\f$ with the dense\n \\f$m \\times k\\f$ matrix \\f$A\\f$, the dense \\f$k \\times n\\f$ matrix \\f$B\\f$, filtered by the sparsity pattern of the \\f$m \\times n\\f$ sparse matrix \\f$C\\f$ and\n adds the result to \\f$C\\f$ scaled by\n \\f$\\beta\\f$. The final result is stored in the sparse \\f$m \\times n\\f$ matrix \\f$C\\f$,\n such that\n \\f[\n C := \\alpha ( opA(A) \\cdot opB(B) ) \\cdot spy(C) + \\beta C,\n \\f]\n with\n \\f[\n op(A) = \\left\\{\n \\begin{array}{ll}\n A, & \\text{if opA == rocsparse_operation_none} \\\\\n A^T, & \\text{if opA == rocsparse_operation_transpose} \\\\\n \\end{array}\n \\right.\n \\f],\n \\f[\n op(B) = \\left\\{\n \\begin{array}{ll}\n B, & \\text{if opB == rocsparse_operation_none} \\\\\n B^T, & \\text{if opB == rocsparse_operation_transpose} \\\\\n \\end{array}\n \\right.\n \\f]\n and\n \\f[\n spy(C)_ij = \\left\\{\n \\begin{array}{ll}\n 1 \\text{if i == j}, & 0 \\text{if i != j} \\\\\n \\end{array}\n \\right.\n \\f]\n \\note \\p opA == \\ref rocsparse_operation_conjugate_transpose is not supported.\n \\note \\p opB == \\ref rocsparse_operation_conjugate_transpose is not supported.\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n opA dense matrix \\f$A\\f$ operation type.\n @param[in]\n opB dense matrix \\f$B\\f$ operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A dense matrix \\f$A\\f$ descriptor.\n @param[in]\n B dense matrix \\f$B\\f$ descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C sparse matrix \\f$C\\f$ descriptor.\n @param[in]\n compute_type floating point precision for the SDDMM computation.\n @param[in]\n alg specification of the algorithm to use.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n The size must be greater or equal to the size obtained with \\ref rocsparse_sddmm_buffer_size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_value the value of \\p trans\\_A, \\p trans\\_B, \\p compute\\_type or alg is incorrect.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p A, \\p B, \\p D, \\p C or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\p opA == \\ref rocsparse_operation_conjugate_transpose or\n \\p opB == \\ref rocsparse_operation_conjugate_transpose."] + pub fn rocsparse_sddmm( + handle: rocsparse_handle, + opA: rocsparse_operation, + opB: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + A: rocsparse_dnmat_descr, + B: rocsparse_dnmat_descr, + beta: *const ::std::os::raw::c_void, + C: rocsparse_spmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_sddmm_alg, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Calculate the size in bytes of the required buffer for the use of \\ref rocsparse_sddmm and \\ref rocsparse_sddmm_preprocess\n\n \\details\n \\ref rocsparse_sddmm_buffer_size returns the size of the required buffer to execute the SDDMM operation from a given configuration.\n\n \\note\n This routine does not support execution in a hipGraph context.\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n opA dense matrix \\f$A\\f$ operation type.\n @param[in]\n opB dense matrix \\f$B\\f$ operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A dense matrix \\f$A\\f$ descriptor.\n @param[in]\n B dense matrix \\f$B\\f$ descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C sparse matrix \\f$C\\f$ descriptor.\n @param[in]\n compute_type floating point precision for the SDDMM computation.\n @param[in]\n alg specification of the algorithm to use.\n @param[out]\n buffer_size number of bytes of the temporary storage buffer.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_value the value of \\p trans\\_A or \\p trans\\_B is incorrect.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p A, \\p B, \\p D, \\p C or \\p buffer_size pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\p opA == \\ref rocsparse_operation_conjugate_transpose or\n \\p opB == \\ref rocsparse_operation_conjugate_transpose."] + pub fn rocsparse_sddmm_buffer_size( + handle: rocsparse_handle, + opA: rocsparse_operation, + opB: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + A: rocsparse_dnmat_descr, + B: rocsparse_dnmat_descr, + beta: *const ::std::os::raw::c_void, + C: rocsparse_spmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_sddmm_alg, + buffer_size: *mut usize, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup generic_module\n \\brief Preprocess data before the use of \\ref rocsparse_sddmm.\n\n \\details\n \\ref rocsparse_sddmm_preprocess executes a part of the algorithm that can be calculated once in the context of multiple calls of the \\ref rocsparse_sddmm\n with the same sparsity pattern.\n\n \\note\n This routine does not support execution in a hipGraph context.\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n opA dense matrix \\f$A\\f$ operation type.\n @param[in]\n opB dense matrix \\f$B\\f$ operation type.\n @param[in]\n alpha scalar \\f$\\alpha\\f$.\n @param[in]\n A dense matrix \\f$A\\f$ descriptor.\n @param[in]\n B dense matrix \\f$B\\f$ descriptor.\n @param[in]\n beta scalar \\f$\\beta\\f$.\n @param[inout]\n C sparse matrix \\f$C\\f$ descriptor.\n @param[in]\n compute_type floating point precision for the SDDMM computation.\n @param[in]\n alg specification of the algorithm to use.\n @param[in]\n temp_buffer temporary storage buffer allocated by the user.\n The size must be greater or equal to the size obtained with \\ref rocsparse_sddmm_buffer_size.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_value the value of \\p trans\\_A or \\p trans\\_B is incorrect.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_pointer \\p alpha and \\p beta are invalid,\n \\p A, \\p B, \\p D, \\p C or \\p temp_buffer pointer is invalid.\n \\retval rocsparse_status_not_implemented\n \\p opA == \\ref rocsparse_operation_conjugate_transpose or\n \\p opB == \\ref rocsparse_operation_conjugate_transpose."] + pub fn rocsparse_sddmm_preprocess( + handle: rocsparse_handle, + opA: rocsparse_operation, + opB: rocsparse_operation, + alpha: *const ::std::os::raw::c_void, + A: rocsparse_dnmat_descr, + B: rocsparse_dnmat_descr, + beta: *const ::std::os::raw::c_void, + C: rocsparse_spmat_descr, + compute_type: rocsparse_datatype, + alg: rocsparse_sddmm_alg, + temp_buffer: *mut ::std::os::raw::c_void, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + #[doc = " \\ingroup reordering_module\n \\brief Coloring of the adjacency graph of the matrix \\f$A\\f$ stored in the CSR format.\n\n \\details\n \\p rocsparse_csrcolor performs the coloring of the undirected graph represented by the (symmetric) sparsity pattern of the\n matrix \\f$A\\f$ stored in CSR format. Graph coloring is a way of coloring the nodes of a graph such that no two adjacent nodes\n are of the same color. The \\p fraction_to_color is a parameter to only color a given percentage of the graph nodes, the\n remaining uncolored nodes receive distinct new colors. The optional \\p reordering array is a permutation array such that\n unknowns of the same color are grouped. The matrix \\f$A\\f$ must be stored as a general matrix with a symmetric sparsity pattern,\n and if the matrix \\f$A\\f$ is non-symmetric then the user is responsible to provide the symmetric part \\f$\\frac{A+A^T}{2}\\f$.\n\n \\note\n This function is blocking with respect to the host.\n\n \\note\n This routine does not support execution in a hipGraph context.\n\n @param[in]\n handle handle to the rocsparse library context queue.\n @param[in]\n m number of rows of sparse matrix \\f$A\\f$.\n @param[in]\n nnz number of non-zero entries of sparse matrix \\f$A\\f$.\n @param[in]\n descr sparse matrix descriptor.\n @param[in]\n csr_val array of \\p nnz elements of the sparse CSR matrix.\n @param[in]\n csr_row_ptr array of \\p m+1 elements that point to the start of every row of the\n sparse CSR matrix.\n @param[in]\n csr_col_ind array of \\p nnz elements containing the column indices of the sparse\n CSR matrix.\n @param[in]\n fraction_to_color fraction of nodes to be colored, which should be in the interval [0.0,1.0], for example 0.8 implies that 80 percent of nodes will be colored.\n @param[out]\n ncolors resulting number of distinct colors.\n @param[out]\n coloring resulting mapping of colors.\n @param[out]\n reordering optional resulting reordering permutation if \\p reordering is a non-null pointer.\n @param[inout]\n info structure that holds the information collected during the coloring algorithm.\n\n \\retval rocsparse_status_success the operation completed successfully.\n \\retval rocsparse_status_invalid_handle the library context was not initialized.\n \\retval rocsparse_status_invalid_size \\p m or \\p nnz is invalid.\n \\retval rocsparse_status_invalid_pointer \\p descr, \\p csr_val, \\p csr_row_ptr, \\p csr_col_ind, \\p fraction_to_color, \\p ncolors, \\p coloring or \\p info pointer is invalid.\n/\n/**@{"] + pub fn rocsparse_scsrcolor( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f32, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + fraction_to_color: *const f32, + ncolors: *mut rocsparse_int, + coloring: *mut rocsparse_int, + reordering: *mut rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_dcsrcolor( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const f64, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + fraction_to_color: *const f64, + ncolors: *mut rocsparse_int, + coloring: *mut rocsparse_int, + reordering: *mut rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_ccsrcolor( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_float_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + fraction_to_color: *const f32, + ncolors: *mut rocsparse_int, + coloring: *mut rocsparse_int, + reordering: *mut rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} +extern "C" { + #[must_use] + pub fn rocsparse_zcsrcolor( + handle: rocsparse_handle, + m: rocsparse_int, + nnz: rocsparse_int, + descr: rocsparse_mat_descr, + csr_val: *const rocsparse_double_complex, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + fraction_to_color: *const f64, + ncolors: *mut rocsparse_int, + coloring: *mut rocsparse_int, + reordering: *mut rocsparse_int, + info: rocsparse_mat_info, + ) -> rocsparse_status; +} diff --git a/spirv_tools-sys/README b/spirv_tools-sys/README deleted file mode 100644 index 3152164..0000000 --- a/spirv_tools-sys/README +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index ae72561..0000000 --- a/spirv_tools-sys/build.rs +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index c1a9dc2..0000000 --- a/spirv_tools-sys/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[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 deleted file mode 100644 index fe9640b..0000000 --- a/spirv_tools-sys/src/spirv_tools.rs +++ /dev/null @@ -1,972 +0,0 @@ -/* 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 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 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 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 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::(), - 16usize, - concat!("Size of: ", stringify!(spv_parsed_operand_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(spv_parsed_operand_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).offset as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_parsed_operand_t), - "::", - stringify!(offset) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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::())).type_ as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(spv_parsed_operand_t), - "::", - stringify!(type_) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).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::())).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::(), - 40usize, - concat!("Size of: ", stringify!(spv_parsed_instruction_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_parsed_instruction_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).words as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_parsed_instruction_t), - "::", - stringify!(words) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).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::())).opcode as *const _ as usize }, - 10usize, - concat!( - "Offset of field: ", - stringify!(spv_parsed_instruction_t), - "::", - stringify!(opcode) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).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::())).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::())).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::())).operands as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(spv_parsed_instruction_t), - "::", - stringify!(operands) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).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::(), - 16usize, - concat!("Size of: ", stringify!(spv_const_binary_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_const_binary_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).code as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_const_binary_t), - "::", - stringify!(code) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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::(), - 16usize, - concat!("Size of: ", stringify!(spv_binary_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_binary_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).code as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_binary_t), - "::", - stringify!(code) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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::(), - 16usize, - concat!("Size of: ", stringify!(spv_text_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_text_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).str_ as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_text_t), - "::", - stringify!(str_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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::(), - 24usize, - concat!("Size of: ", stringify!(spv_position_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_position_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).line as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_position_t), - "::", - stringify!(line) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).column as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(spv_position_t), - "::", - stringify!(column) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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::(), - 40usize, - concat!("Size of: ", stringify!(spv_diagnostic_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(spv_diagnostic_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).position as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(spv_diagnostic_t), - "::", - stringify!(position) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).error as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(spv_diagnostic_t), - "::", - stringify!(error) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).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/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 0000000..2a214e4 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "xtask" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[dependencies] +argh = "0.1" +# v18 requires rust 1.70 or higher +cargo_metadata = "=0.17.0" +# cargo-platform is a cargo_metadata, version 0.1.6 requires rust 1.70 or higher +cargo-platform = "=0.1.5" +serde = "1.0.193" +serde_json = "1.0.108" \ No newline at end of file diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 0000000..317ec01 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,281 @@ +use argh::{EarlyExit, FromArgs, TopLevelCommand}; +use serde::Deserialize; +use std::{ + env, + path::{Path, PathBuf}, + process::Command, +}; + +type DynError = Box; + +struct Arguments { + command: Subcommand, +} + +impl TopLevelCommand for Arguments {} +impl FromArgs for Arguments { + fn from_args(command_name: &[&str], args: &[&str]) -> Result { + #[derive(FromArgs)] + /// Run various ZLUDA tasks + struct TryArguments { + #[argh(subcommand)] + command: Option, + } + Ok( + match ::from_args(command_name, args) { + Ok(TryArguments { command }) => Arguments { + command: command.unwrap_or_default(), + }, + Err(err @ EarlyExit { status: Ok(()), .. }) => return Err(err), + Err(EarlyExit { + status: Err(()), .. + }) => Arguments { + command: Subcommand::Build(BuildCommand::from_args(command_name, args)?), + }, + }, + ) + } +} + +#[derive(FromArgs)] +#[argh(subcommand)] +enum Subcommand { + Build(BuildCommand), + Zip(ZipCommand), +} + +impl Default for Subcommand { + fn default() -> Self { + Subcommand::Build(BuildCommand { release: false }) + } +} + +#[derive(FromArgs)] +/// Compile ZLUDA for the current platform (default command) +#[argh(subcommand, name = "build")] +struct BuildCommand { + /// build artifacts in release mode, with optimizations + #[argh(switch, short = 'r')] + release: bool, +} + +#[derive(FromArgs)] +/// Package build artifacts into an archive (.zip or .tar.gz) +#[argh(subcommand, name = "zip")] +struct ZipCommand { + /// use artifacts from release mode + #[argh(switch, short = 'r')] + #[allow(dead_code)] + release: bool, +} + +fn main() -> Result<(), DynError> { + let args: Arguments = argh::from_env(); + std::process::exit(match args.command { + Subcommand::Build(BuildCommand { release }) => build(!release)?, + Subcommand::Zip(_) => panic!(), + }) +} + +#[derive(Deserialize)] +struct ZludaMetadata { + zluda: Project, +} + +#[derive(Deserialize, Default, PartialEq, Debug)] +#[serde(deny_unknown_fields)] +struct Project { + #[serde(skip_deserializing)] + name: String, + #[serde(skip_deserializing)] + target_name: String, + #[serde(skip_deserializing)] + kind: TargetKind, + #[serde(default)] + top_level: bool, + #[serde(default)] + windows_only: bool, + #[serde(default)] + linux_only: bool, + #[serde(default)] + debug_only: bool, + #[serde(default)] + broken: bool, + #[serde(default)] + skip_dump_link: bool, + #[serde(default)] + linux_names: Vec, + #[serde(default)] + dump_names: Vec, +} + +#[derive(Clone, Copy, Default, PartialEq, Debug)] +enum TargetKind { + #[default] + Binary, + Cdylib, +} + +impl Project { + fn new(json_pkg: cargo_metadata::Package) -> Self { + let mut project = serde_json::from_value::>(json_pkg.metadata) + .unwrap() + .map_or(Default::default(), |x| x.zluda); + if project != Default::default() { + project.top_level = true; + } + project.name = json_pkg.name; + if let Some((target_name, kind)) = json_pkg.targets.into_iter().find_map(|t| { + match t.kind.first().map(std::ops::Deref::deref) { + Some("cdylib") => Some((t.name, TargetKind::Cdylib)), + Some("bin") => Some((t.name, TargetKind::Binary)), + _ => None, + } + }) { + project.target_name = target_name; + project.kind = kind; + } + project + } + + fn skip_build(&self, is_debug: bool) -> bool { + if !self.top_level { + return true; + } + if self.broken { + return true; + } + if cfg!(windows) && self.linux_only { + return true; + } + if !cfg!(windows) && self.windows_only { + return true; + } + if !is_debug && self.debug_only { + return true; + } + false + } +} + +fn build(is_debug: bool) -> Result { + let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); + let project_root = project_root()?; + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(&cargo).current_dir(&project_root).no_deps(); + let metadata = cmd.exec()?; + let projects = metadata + .packages + .into_iter() + .map(Project::new) + .filter(|p| !p.skip_build(is_debug)) + .collect::>(); + let mut command = Command::new(&cargo); + command.current_dir(&project_root).arg("build"); + projects.iter().fold(&mut command, |command, proj| { + command.args(["-p", &proj.name]) + }); + if !is_debug { + command.arg("--release"); + } + let build_result = command.status()?.code().unwrap(); + if build_result != 0 { + return Ok(build_result); + } + os::create_dump_dir_and_symlinks(is_debug, metadata.target_directory, projects); + Ok(0) +} + +fn project_root() -> Result { + Ok(Path::new(&env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(1) + .ok_or::("CARGO_MANIFEST_DIR".into())? + .to_path_buf()) +} + +#[cfg(not(unix))] +mod os { + use super::Project; + use cargo_metadata::camino::Utf8PathBuf; + + // This is 100% intentional, we don't want symlinks on Windows since + // we use completely different scheme for injections here + pub(crate) fn create_dump_dir_and_symlinks(_: bool, _: Utf8PathBuf, _: Vec) {} +} + +#[cfg(unix)] +mod os { + use super::{Project, TargetKind}; + use cargo_metadata::camino::Utf8PathBuf; + + pub(crate) fn create_dump_dir_and_symlinks( + is_debug: bool, + mut target_directory: Utf8PathBuf, + projects: Vec, + ) { + use std::fs; + target_directory.push(if is_debug { "debug" } else { "release" }); + let mut dump_dir = target_directory.clone(); + dump_dir.push("dump"); + fs::create_dir_all(&dump_dir).unwrap(); + for project in projects { + let dst = format!( + "{}{}{}", + project.kind.prefix(), + project.target_name, + project.kind.suffix() + ); + let dump_dst = format!("../{}", dst); + for src_file in project.linux_names { + force_symlink(&dst, &target_directory, &src_file); + if project.skip_dump_link { + continue; + } + force_symlink(&dump_dst, &dump_dir, &src_file); + } + for src_file in project.dump_names { + force_symlink(&dump_dst, &dump_dir, &src_file); + } + } + } + + fn force_symlink(dst: &str, src_dir: &Utf8PathBuf, src_file: &str) { + use std::io::ErrorKind; + use std::os::unix::fs as unix_fs; + let mut src = src_dir.clone(); + src.push(src_file); + match unix_fs::symlink(dst, &src) { + Ok(()) => {} + Err(err) if err.kind() == ErrorKind::AlreadyExists => { + let current_dst = std::fs::read_link(&src); + match current_dst { + Ok(current_dst) if current_dst.to_str() == Some(dst) => { + return; + } + _ => { + std::fs::remove_file(&src).unwrap(); + unix_fs::symlink(dst, &src).unwrap(); + } + } + } + Err(err) => panic!("{:?}", err), + } + } + + impl TargetKind { + fn prefix(self) -> &'static str { + match self { + TargetKind::Binary => "", + TargetKind::Cdylib => "lib", + } + } + + fn suffix(self) -> &'static str { + match self { + TargetKind::Binary => "", + TargetKind::Cdylib => ".so", + } + } + } +} diff --git a/zluda/Cargo.toml b/zluda/Cargo.toml index 6e0d077..448154a 100644 --- a/zluda/Cargo.toml +++ b/zluda/Cargo.toml @@ -8,13 +8,45 @@ edition = "2018" name = "zluda" [dependencies] +comgr = { path = "../comgr" } +cuda_base = { path = "../cuda_base" } +cuda_types = { path = "../cuda_types" } +hip_common = { path = "../hip_common" } +hip_runtime-sys = { path = "../hip_runtime-sys" } ptx = { path = "../ptx" } -level_zero = { path = "../level_zero" } -level_zero-sys = { path = "../level_zero-sys" } +zluda_dark_api = { path = "../zluda_dark_api" } lazy_static = "1.4" num_enum = "0.4" lz4-sys = "1.9" +tempfile = "3" +paste = "1.0" +rustc-hash = "1.1" +rusqlite = { version = "0.28.0", features = ["bundled"] } +# blake3 1.4 requires rust 1.66 +blake3 = "=1.3.3" +dirs = "4.0.0" +# we don't need elf32, but goblin has a bug where elf64 does not build without elf32 +goblin = { version = "0.5.1", default-features = false, features = ["elf64", "elf32", "endian_fd"] } +memchr = "2.5.0" +memoffset = "0.8" +static_assertions = "1.1.0" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["heapapi", "std"] } [dev-dependencies] -cuda-driver-sys = "0.3.0" -paste = "1.0" \ No newline at end of file +paste = "1.0" +rand_chacha = "0.3.1" +rand = "0.8.5" +num-traits = "0.2.14" +half = { version ="1.8.2", features = ["num-traits"] } +gag = "1.0.0" + +[target.'cfg(not(windows))'.dev-dependencies] +libc = "0.2" + +[build-dependencies] +vergen = { version = "7.5.1", default-features = false, features = ["git"] } +# We don't use time crate, but this coerces vergen to not use newer version that requires +# higher minimum rust version +time = "=0.3.23" \ No newline at end of file diff --git a/zluda/README b/zluda/README index 089ddcd..f6d929c 100644 --- a/zluda/README +++ b/zluda/README @@ -1,3 +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 +sed -i -e 's/extern "C" {//g' -e 's/-> CUresult;/-> CUresult { impl_::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' cuda.rs rustfmt cuda.rs \ No newline at end of file diff --git a/zluda/build.rs b/zluda/build.rs index 94c2c6f..9d7f95d 100644 --- a/zluda/build.rs +++ b/zluda/build.rs @@ -1,20 +1,5 @@ -use env::VarError; -use std::{env, path::PathBuf}; +use vergen::{Config, vergen}; -// HACK ALERT -// This is a temporary hack to to make sure that linker does not pick up -// NVIDIA OpenCL .lib using paths injected by cl-sys - -fn main() -> Result<(), VarError> { - if cfg!(windows) { - let env = env::var("CARGO_CFG_TARGET_ENV")?; - if env == "msvc" { - let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); - path.push("lib"); - println!("cargo:rustc-link-search=native={}", path.display()); - } else { - println!("cargo:rustc-link-search=native=C:\\Windows\\System32"); - }; - } - Ok(()) -} +fn main() { + vergen(Config::default()).unwrap() +} \ No newline at end of file diff --git a/zluda/lib/OpenCL.lib b/zluda/lib/OpenCL.lib deleted file mode 100644 index 2b766ee858f3f474258b211c632aef8bc5368416..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28824 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 diff --git a/zluda/src/cuda.rs b/zluda/src/cuda.rs index 1eb08d5..898d732 100644 --- a/zluda/src/cuda.rs +++ b/zluda/src/cuda.rs @@ -1,4613 +1,1650 @@ -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; -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 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::get_error_string(error, pStr).encuda() -} - -#[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 cuDeviceGetLuid( - luid: *mut ::std::os::raw::c_char, - deviceNodeMask: *mut ::std::os::raw::c_uint, - dev: CUdevice, -) -> CUresult { - r#impl::device::get_luid(luid, deviceNodeMask, 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::context::push_current_v2(ctx.decuda()) -} - -#[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::module::load(module.decuda(), fname).encuda() -} - -#[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() -} - -// TODO: parse jit options -#[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::module::load_data(module.decuda(), image).encuda() -} - -#[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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuMemcpyHtoD_v2_ptds( - 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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuMemcpyDtoH_v2_ptds( - 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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuMemsetD8_v2_ptds( - 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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuMemsetD32_v2_ptds( - 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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuStreamGetCtx_ptsz(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() -} - -// TODO: implement default stream semantics -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuLaunchKernel_ptsz( - 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::function::set_block_shape(hfunc.decuda(), x, y, z).encuda() -} - -#[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() -} - -impl CUoutput_mode_enum { - pub const CU_OUT_KEY_VALUE_PAIR: CUoutput_mode_enum = CUoutput_mode_enum(0); -} -impl CUoutput_mode_enum { - pub const CU_OUT_CSV: CUoutput_mode_enum = CUoutput_mode_enum(1); -} -#[repr(transparent)] -#[derive(Copy, Clone, Hash, PartialEq, Eq)] -pub struct CUoutput_mode_enum(pub ::std::os::raw::c_uint); -pub use self::CUoutput_mode_enum as CUoutput_mode; - -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuProfilerInitialize( - configFile: *const ::std::os::raw::c_char, - outputFile: *const ::std::os::raw::c_char, - outputMode: CUoutput_mode, -) -> CUresult { - r#impl::unimplemented() -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuProfilerStart() -> CUresult { - r#impl::unimplemented() -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn cuProfilerStop() -> CUresult { - r#impl::unimplemented() -} +use cuda_base::cuda_function_declarations; + +use crate::r#impl::{FromCuda, IntoCuda}; + +macro_rules! unimplemented_cuda_fn { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + $( + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + crate::r#impl::unimplemented() + } + )* + }; +} + +macro_rules! implemented_cuda_fn { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + $( + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + definitions::$fn_name($(FromCuda::from_cuda($arg_id)),*).into_cuda() + } + )* + }; +} + +cuda_function_declarations!( + cuda_types, + unimplemented_cuda_fn, + implemented_cuda_fn, + [ + cuGetErrorString, + cuInit, + cuGetProcAddress, + cuGetProcAddress_v2, + cuGetExportTable, + cuDriverGetVersion, + cuDeviceCanAccessPeer, + cuDeviceGet, + cuDeviceGetCount, + cuDeviceGetMemPool, + cuDeviceGetName, + cuDeviceGetUuid, + cuDeviceGetUuid_v2, + cuDeviceGetLuid, + cuDeviceTotalMem, + cuDeviceTotalMem_v2, + cuDeviceGetAttribute, + cuDeviceGetProperties, + cuDeviceComputeCapability, + cuDevicePrimaryCtxRetain, + cuDevicePrimaryCtxRelease, + cuDevicePrimaryCtxRelease_v2, + cuDevicePrimaryCtxReset, + cuDevicePrimaryCtxReset_v2, + cuDevicePrimaryCtxSetFlags, + cuDevicePrimaryCtxSetFlags_v2, + cuDevicePrimaryCtxGetState, + cuCtxCreate, + cuCtxCreate_v2, + cuCtxDestroy, + cuCtxDestroy_v2, + cuCtxPushCurrent, + cuCtxPushCurrent_v2, + cuCtxPopCurrent, + cuCtxPopCurrent_v2, + cuCtxSetCurrent, + cuCtxGetCurrent, + cuCtxGetDevice, + cuCtxGetLimit, + cuCtxSetLimit, + cuCtxGetStreamPriorityRange, + cuCtxSynchronize, + cuCtxSetCacheConfig, + cuCtxGetApiVersion, + cuFuncSetCacheConfig, + cuLibraryLoadData, + cuLibraryGetModule, + cuLibraryUnload, + cuModuleLoad, + cuModuleLoadData, + cuModuleLoadDataEx, + cuModuleUnload, + cuModuleGetFunction, + cuModuleGetGlobal_v2, + cuModuleGetLoadingMode, + cuModuleGetSurfRef, + cuModuleGetTexRef, + cuMemGetInfo_v2, + cuMemAlloc_v2, + cuMemAllocManaged, + cuMemAllocPitch_v2, + cuMemFree_v2, + cuMemFreeAsync, + cuMemFreeHost, + cuMemHostAlloc, + cuMemHostRegister, + cuMemHostRegister_v2, + cuMemHostUnregister, + cuMemGetAddressRange_v2, + cuMemPoolSetAttribute, + cuMemPrefetchAsync, + cuDeviceGetPCIBusId, + cuMemcpy, + cuMemcpy_ptds, + cuMemcpyAsync, + cuMemcpyAsync_ptsz, + cuMemcpyHtoD_v2, + cuMemcpyHtoD_v2_ptds, + cuMemcpyDtoH_v2, + cuMemcpyDtoH_v2_ptds, + cuMemcpyDtoD_v2, + cuMemcpyDtoDAsync_v2, + cuMemcpyDtoDAsync_v2_ptsz, + cuMemcpyHtoDAsync_v2, + cuMemcpyHtoDAsync_v2_ptsz, + cuMemcpyDtoHAsync_v2, + cuMemcpyDtoHAsync_v2_ptsz, + cuMemcpy2D_v2, + cuMemcpy2DAsync_v2, + cuMemcpy2DUnaligned_v2, + cuMemcpy3D_v2, + cuMemcpy3DAsync_v2, + cuMemsetD8_v2, + cuMemsetD8_v2_ptds, + cuMemsetD8Async, + cuMemsetD8Async_ptsz, + cuMemsetD16_v2, + cuMemsetD32Async, + cuMemsetD32_v2, + cuMemsetD32_v2_ptds, + cuMemsetD2D8_v2, + cuOccupancyMaxPotentialBlockSize, + cuArrayCreate_v2, + cuArrayDestroy, + cuArray3DCreate_v2, + cuArray3DGetDescriptor_v2, + cuPointerGetAttribute, + cuPointerGetAttributes, + cuStreamCreate, + cuStreamCreateWithPriority, + cuStreamGetCaptureInfo, + cuStreamGetCtx, + cuStreamGetCtx_ptsz, + cuStreamGetFlags, + cuStreamIsCapturing, + cuStreamQuery, + cuStreamSynchronize, + cuStreamSynchronize_ptsz, + cuStreamDestroy, + cuStreamDestroy_v2, + cuStreamWaitEvent, + cuStreamWaitEvent_ptsz, + cuFuncGetAttribute, + cuFuncSetAttribute, + cuLaunchHostFunc, + cuLaunchKernel, + cuLaunchKernel_ptsz, + cuMemHostGetDevicePointer_v2, + cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags, + cuSurfObjectCreate, + cuSurfObjectDestroy, + cuTexObjectCreate, + cuTexObjectDestroy, + cuTexRefGetAddress_v2, + cuTexRefGetAddressMode, + cuTexRefGetFilterMode, + cuTexRefGetFlags, + cuTexRefGetMipmapFilterMode, + cuTexRefGetMipmapLevelBias, + cuTexRefGetMipmapLevelClamp, + cuTexRefGetMaxAnisotropy, + cuTexRefSetAddress2D_v3, + cuTexRefSetAddressMode, + cuTexRefSetAddress_v2, + cuTexRefSetArray, + cuTexRefSetFilterMode, + cuTexRefSetFlags, + cuTexRefSetFormat, + cuTexRefGetFormat, + cuTexRefSetMaxAnisotropy, + cuTexRefSetMipmapFilterMode, + cuTexRefSetMipmapLevelBias, + cuTexRefSetMipmapLevelClamp, + cuSurfRefSetArray, + cuCtxDetach, + cuFuncSetBlockShape, + cuEventCreate, + cuEventDestroy, + cuEventDestroy_v2, + cuEventQuery, + cuEventElapsedTime, + cuEventRecord, + cuEventRecord_ptsz, + cuEventSynchronize, + cuGraphAddDependencies, + cuGraphAddEmptyNode, + cuGraphAddKernelNode, + cuGraphCreate, + cuGraphDestroy, + cuGraphExecDestroy, + cuGraphInstantiate, + cuGraphInstantiate_v2, + cuGraphLaunch, + cuGraphicsSubResourceGetMappedArray, + cuGraphicsGLRegisterBuffer, + cuGraphicsGLRegisterImage, + cuGraphicsMapResources, + cuGraphicsResourceGetMappedPointer_v2, + cuGraphicsUnmapResources, + cuGraphicsUnregisterResource, + cuLinkAddData_v2, + cuLinkComplete, + cuLinkDestroy, + cuLinkCreate_v2, + ] +); + +mod definitions { + use std::ptr; + + use cuda_types::*; + use hip_runtime_sys::*; + + use crate::hip_call_cuda; + use crate::r#impl; + use crate::r#impl::array; + use crate::r#impl::context; + use crate::r#impl::dark_api; + use crate::r#impl::device; + use crate::r#impl::function; + use crate::r#impl::gl; + use crate::r#impl::graph; + use crate::r#impl::hipfix; + use crate::r#impl::library; + use crate::r#impl::link; + use crate::r#impl::memcpy2d_from_cuda; + use crate::r#impl::memory; + use crate::r#impl::module; + use crate::r#impl::pointer; + use crate::r#impl::stream; + use crate::r#impl::surface; + use crate::r#impl::surfref; + use crate::r#impl::texobj; + use crate::r#impl::texref; + + pub(crate) unsafe fn cuGetErrorString( + error: hipError_t, + pStr: *mut *const ::std::os::raw::c_char, + ) -> CUresult { + *pStr = hipGetErrorString(error); + CUresult::CUDA_SUCCESS + } + + pub(crate) unsafe fn cuInit(Flags: ::std::os::raw::c_uint) -> Result<(), CUresult> { + r#impl::init(Flags) + } + + pub(crate) unsafe fn cuGetProcAddress( + symbol: *const ::std::os::raw::c_char, + pfn: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + ) -> CUresult { + cuGetProcAddress_v2(symbol, pfn, cudaVersion, flags, ptr::null_mut()) + } + + pub(crate) fn cuGetProcAddress_v2( + symbol: *const ::std::os::raw::c_char, + pfn: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + symbolStatus: *mut CUdriverProcAddressQueryResult, + ) -> CUresult { + unsafe { r#impl::get_proc_address_v2(symbol, pfn, cudaVersion, flags, symbolStatus) } + } + + pub(crate) unsafe fn cuGetExportTable( + ppExportTable: *mut *const ::std::os::raw::c_void, + pExportTableId: *const CUuuid, + ) -> CUresult { + dark_api::get_table(ppExportTable, pExportTableId) + } + + pub(crate) unsafe fn cuDriverGetVersion(driverVersion: *mut ::std::os::raw::c_int) -> CUresult { + *driverVersion = crate::DRIVER_VERSION; + CUresult::CUDA_SUCCESS + } + + pub(crate) unsafe fn cuDeviceCanAccessPeer( + canAccessPeer: *mut ::std::os::raw::c_int, + dev: hipDevice_t, + peerDev: hipDevice_t, + ) -> hipError_t { + hipDeviceCanAccessPeer(canAccessPeer, dev, peerDev) + } + + pub(crate) unsafe fn cuDeviceGet( + device: *mut hipDevice_t, + ordinal: ::std::os::raw::c_int, + ) -> hipError_t { + hipDeviceGet(device as _, ordinal) + } + + pub(crate) unsafe fn cuDeviceGetCount(count: *mut ::std::os::raw::c_int) -> hipError_t { + hipGetDeviceCount(count) + } + + pub(crate) unsafe fn cuDeviceGetMemPool( + pool: *mut hipMemPool_t, + dev: hipDevice_t, + ) -> hipError_t { + hipDeviceGetMemPool(pool, dev) + } + + pub(crate) unsafe fn cuDeviceGetName( + name: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + dev: hipDevice_t, + ) -> hipError_t { + device::get_name(name, len, dev) + } + + pub(crate) unsafe fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: hipDevice_t) -> CUresult { + device::get_uuid(uuid, dev) + } + + pub(crate) unsafe fn cuDeviceGetUuid_v2(uuid: *mut CUuuid, dev: hipDevice_t) -> CUresult { + device::get_uuid(uuid, dev) + } + + pub(crate) unsafe fn cuDeviceGetLuid( + luid: *mut ::std::os::raw::c_char, + deviceNodeMask: *mut ::std::os::raw::c_uint, + dev: hipDevice_t, + ) -> CUresult { + device::get_luid(luid, deviceNodeMask, dev) + } + + pub(crate) unsafe fn cuDeviceTotalMem( + bytes: *mut u32, + dev: hipDevice_t, + ) -> Result<(), hipError_t> { + device::total_mem(bytes, dev) + } + + pub(crate) unsafe fn cuDeviceTotalMem_v2(bytes: *mut usize, dev: hipDevice_t) -> hipError_t { + hipDeviceTotalMem(bytes, dev) + } + + pub(crate) unsafe fn cuDeviceGetAttribute( + pi: *mut ::std::os::raw::c_int, + attrib: CUdevice_attribute, + dev: hipDevice_t, + ) -> Result<(), CUresult> { + device::get_attribute(pi, attrib, dev) + } + + pub(crate) unsafe fn cuDeviceGetProperties( + prop: *mut CUdevprop, + dev: hipDevice_t, + ) -> Result<(), CUresult> { + device::get_properties(prop, dev) + } + + pub(crate) unsafe fn cuDeviceComputeCapability( + major: *mut ::std::os::raw::c_int, + minor: *mut ::std::os::raw::c_int, + dev: hipDevice_t, + ) { + device::compute_capability(major, minor, dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxRetain( + pctx: *mut *mut context::Context, + dev: hipDevice_t, + ) -> Result<(), CUresult> { + device::primary_ctx_retain(pctx, dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxRelease(dev: hipDevice_t) -> Result<(), CUresult> { + device::primary_ctx_release(dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxRelease_v2(dev: hipDevice_t) -> Result<(), CUresult> { + device::primary_ctx_release(dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxReset(dev: hipDevice_t) -> Result<(), CUresult> { + device::primary_ctx_reset(dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxReset_v2(dev: hipDevice_t) -> Result<(), CUresult> { + device::primary_ctx_reset(dev) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxSetFlags( + dev: hipDevice_t, + flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + device::primary_ctx_set_flags(dev, flags) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxSetFlags_v2( + dev: hipDevice_t, + flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + device::primary_ctx_set_flags(dev, flags) + } + + pub(crate) unsafe fn cuDevicePrimaryCtxGetState( + dev: hipDevice_t, + flags: *mut ::std::os::raw::c_uint, + active: *mut ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + device::primary_ctx_get_state(dev, flags, active) + } + + pub(crate) unsafe fn cuCtxCreate( + pctx: *mut *mut context::Context, + flags: ::std::os::raw::c_uint, + dev: hipDevice_t, + ) -> Result<(), CUresult> { + context::create(pctx, flags, dev) + } + + pub(crate) unsafe fn cuCtxCreate_v2( + pctx: *mut *mut context::Context, + flags: ::std::os::raw::c_uint, + dev: hipDevice_t, + ) -> Result<(), CUresult> { + context::create(pctx, flags, dev) + } + + pub(crate) unsafe fn cuCtxDestroy(ctx: *mut context::Context) -> Result<(), CUresult> { + context::destroy(ctx) + } + + pub(crate) unsafe fn cuCtxDestroy_v2(ctx: *mut context::Context) -> Result<(), CUresult> { + context::destroy(ctx) + } + + pub(crate) unsafe fn cuCtxDetach(ctx: *mut context::Context) -> Result<(), CUresult> { + Ok(()) + } + + pub(crate) unsafe fn cuCtxPushCurrent(ctx: *mut context::Context) -> Result<(), CUresult> { + context::push_current(ctx) + } + + pub(crate) unsafe fn cuCtxPushCurrent_v2(ctx: *mut context::Context) -> Result<(), CUresult> { + context::push_current(ctx) + } + + pub(crate) unsafe fn cuCtxPopCurrent(pctx: *mut *mut context::Context) -> Result<(), CUresult> { + context::pop_current(pctx) + } + + pub(crate) unsafe fn cuCtxPopCurrent_v2( + pctx: *mut *mut context::Context, + ) -> Result<(), CUresult> { + context::pop_current(pctx) + } + + pub(crate) unsafe fn cuCtxSetCurrent(ctx: *mut context::Context) -> Result<(), CUresult> { + context::set_current(ctx) + } + + pub(crate) unsafe fn cuCtxGetCurrent(pctx: *mut *mut context::Context) -> CUresult { + context::get_current(pctx) + } + + pub(crate) unsafe fn cuCtxGetDevice(device: *mut hipDevice_t) -> Result<(), CUresult> { + context::get_device(device) + } + + pub(crate) unsafe fn cuCtxGetLimit( + pvalue: *mut usize, + limit: hipLimit_t, + ) -> Result<(), CUresult> { + context::get_limit(pvalue, limit) + } + + pub(crate) unsafe fn cuCtxSetLimit(limit: hipLimit_t, value: usize) -> Result<(), CUresult> { + context::set_limit(limit, value) + } + + pub(crate) unsafe fn cuCtxGetStreamPriorityRange( + leastPriority: *mut ::std::os::raw::c_int, + greatestPriority: *mut ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + context::get_stream_priority_range(leastPriority, greatestPriority) + } + + pub(crate) unsafe fn cuCtxSynchronize() -> Result<(), CUresult> { + context::synchronize() + } + + // TODO + pub(crate) unsafe fn cuCtxSetCacheConfig(config: CUfunc_cache) -> CUresult { + CUresult::CUDA_SUCCESS + } + + pub(crate) unsafe fn cuCtxGetApiVersion( + ctx: *mut context::Context, + version: *mut ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + context::get_api_version(ctx, version) + } + + pub(crate) unsafe fn cuFuncSetCacheConfig( + hfunc: *mut function::Function, + config: hipFuncCache_t, + ) -> CUresult { + CUresult::CUDA_SUCCESS + } + + pub(crate) unsafe fn cuLibraryLoadData( + library: *mut *mut library::Library, + code: *const ::std::os::raw::c_void, + jitOptions: *mut CUjit_option, + jitOptionsValues: *mut *mut ::std::os::raw::c_void, + numJitOptions: ::std::os::raw::c_uint, + libraryOptions: *mut CUlibraryOption, + libraryOptionValues: *mut *mut ::std::os::raw::c_void, + numLibraryOptions: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + library::load_data( + library, + code, + jitOptions, + jitOptionsValues, + numJitOptions, + libraryOptions, + libraryOptionValues, + numLibraryOptions, + ) + } + + pub(crate) unsafe fn cuLibraryGetModule( + pMod: *mut *mut module::Module, + library: *mut library::Library, + ) -> Result<(), CUresult> { + library::get_module(pMod, library) + } + + pub(crate) unsafe fn cuLibraryUnload(library: *mut library::Library) -> Result<(), CUresult> { + library::unload(library) + } + + pub(crate) unsafe fn cuModuleLoad( + module: *mut *mut module::Module, + fname: *const ::std::os::raw::c_char, + ) -> Result<(), CUresult> { + module::load(module, fname) + } + + pub(crate) unsafe fn cuModuleLoadData( + module: *mut *mut module::Module, + image: *const ::std::os::raw::c_void, + ) -> Result<(), CUresult> { + module::load_data(module, image) + } + + // TODO: parse jit options + pub(crate) unsafe fn cuModuleLoadDataEx( + module: *mut *mut module::Module, + 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, + ) -> Result<(), CUresult> { + module::load_data(module, image) + } + + pub(crate) unsafe fn cuModuleUnload(hmod: *mut module::Module) -> Result<(), CUresult> { + module::unload(hmod) + } + + pub(crate) unsafe fn cuModuleGetFunction( + hfunc: *mut *mut function::Function, + hmod: *mut module::Module, + name: *const ::std::os::raw::c_char, + ) -> Result<(), CUresult> { + module::get_function(hfunc, hmod, name) + } + + pub(crate) unsafe fn cuModuleGetGlobal_v2( + dptr: *mut hipDeviceptr_t, + bytes: *mut usize, + hmod: *mut module::Module, + name: *const ::std::os::raw::c_char, + ) -> Result<(), CUresult> { + module::get_global(dptr, bytes, hmod, name) + } + + pub(crate) unsafe fn cuModuleGetLoadingMode(mode: *mut CUmoduleLoadingMode) -> CUresult { + module::get_loading_mode(mode) + } + + pub(crate) unsafe fn cuModuleGetSurfRef( + pTexRef: *mut *mut textureReference, + hmod: *mut module::Module, + name: *const ::std::os::raw::c_char, + ) -> Result<(), CUresult> { + module::get_surf_ref(pTexRef, hmod, name) + } + + pub(crate) unsafe fn cuModuleGetTexRef( + pTexRef: *mut *mut textureReference, + hmod: *mut module::Module, + name: *const ::std::os::raw::c_char, + ) -> Result<(), CUresult> { + module::get_tex_ref(pTexRef, hmod, name) + } + + pub(crate) unsafe fn cuMemGetInfo_v2(free: *mut usize, total: *mut usize) -> hipError_t { + hipMemGetInfo(free, total) + } + + pub(crate) unsafe fn cuMemAlloc_v2( + dptr: *mut hipDeviceptr_t, + bytesize: usize, + ) -> Result<(), CUresult> { + memory::alloc(dptr, bytesize) + } + + pub(crate) unsafe fn cuMemAllocManaged( + dev_ptr: *mut hipDeviceptr_t, + size: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipMallocManaged(dev_ptr.cast(), size, flags) + } + + pub(crate) unsafe fn cuMemAllocPitch_v2( + dptr: *mut hipDeviceptr_t, + ptr_pitch: *mut usize, + width_in_bytes: usize, + height: usize, + _element_size_bytes: ::std::os::raw::c_uint, + ) -> hipError_t { + hipMallocPitch(dptr as _, ptr_pitch, width_in_bytes, height) + } + + pub(crate) unsafe fn cuMemFree_v2(dptr: hipDeviceptr_t) -> hipError_t { + hipFree(dptr.0) + } + + pub(crate) unsafe fn cuMemFreeAsync( + dptr: hipDeviceptr_t, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::free_async(dptr, hStream) + } + + pub(crate) unsafe fn cuMemFreeHost(p: *mut ::std::os::raw::c_void) -> hipError_t { + hipFreeHost(p) + } + + pub(crate) unsafe fn cuMemHostAlloc( + pp: *mut *mut ::std::os::raw::c_void, + bytesize: usize, + flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipHostMalloc(pp, bytesize, flags) + } + + pub(crate) unsafe fn cuMemHostRegister( + p: *mut ::std::os::raw::c_void, + bytesize: usize, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipHostRegister(p, bytesize, Flags) + } + + pub(crate) unsafe fn cuMemHostRegister_v2( + p: *mut ::std::os::raw::c_void, + bytesize: usize, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipHostRegister(p, bytesize, Flags) + } + + pub(crate) unsafe fn cuMemHostUnregister(p: *mut ::std::os::raw::c_void) -> hipError_t { + hipHostUnregister(p) + } + + pub(crate) unsafe fn cuMemGetAddressRange_v2( + pbase: *mut hipDeviceptr_t, + psize: *mut usize, + dptr: hipDeviceptr_t, + ) -> hipError_t { + memory::get_address_range(pbase, psize, dptr) + } + + pub(crate) unsafe fn cuMemPoolSetAttribute( + pool: hipMemPool_t, + attr: hipMemPoolAttr, + value: *mut ::std::os::raw::c_void, + ) -> hipError_t { + hipMemPoolGetAttribute(pool, attr, value) + } + + pub(crate) unsafe fn cuMemPrefetchAsync( + devPtr: hipDeviceptr_t, + count: usize, + dev: hipDevice_t, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::prefetch_async(devPtr, count, dev, hStream) + } + + pub(crate) unsafe fn cuDeviceGetPCIBusId( + pciBusId: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, + dev: hipDevice_t, + ) -> hipError_t { + hipDeviceGetPCIBusId(pciBusId, len, dev) + } + + pub(crate) unsafe fn cuMemcpy( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + ByteCount: usize, + ) -> hipError_t { + hipMemcpy(dst.0, src.0, ByteCount, hipMemcpyKind::hipMemcpyDefault) + } + + pub(crate) unsafe fn cuMemcpy_ptds( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + ByteCount: usize, + ) -> hipError_t { + hipMemcpy_spt(dst.0, src.0, ByteCount, hipMemcpyKind::hipMemcpyDefault) + } + + pub(crate) unsafe fn cuMemcpyAsync( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_async(dst, src, ByteCount, hStream, false) + } + + pub(crate) unsafe fn cuMemcpyAsync_ptsz( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_async(dst, src, ByteCount, hStream, true) + } + + pub(crate) unsafe fn cuMemcpyHtoD_v2( + dstDevice: hipDeviceptr_t, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> hipError_t { + hipMemcpyHtoD(dstDevice, srcHost as _, ByteCount) + } + + pub(crate) unsafe fn cuMemcpyHtoD_v2_ptds( + dstDevice: hipDeviceptr_t, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + ) -> hipError_t { + hipMemcpy_spt( + dstDevice.0, + srcHost, + ByteCount, + hipMemcpyKind::hipMemcpyHostToDevice, + ) + } + + pub(crate) unsafe fn cuMemcpyDtoH_v2( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + ) -> hipError_t { + hipMemcpyDtoH(dstHost, srcDevice, ByteCount) + } + + pub(crate) unsafe fn cuMemcpyDtoH_v2_ptds( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + ) -> hipError_t { + hipMemcpy_spt( + dstHost, + srcDevice.0, + ByteCount, + hipMemcpyKind::hipMemcpyDeviceToHost, + ) + } + + pub(crate) unsafe fn cuMemcpyDtoD_v2( + dstDevice: hipDeviceptr_t, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + ) -> hipError_t { + hipMemcpyDtoD(dstDevice, srcDevice, ByteCount) + } + + pub(crate) unsafe fn cuMemcpyDtoDAsync_v2( + dstDevice: hipDeviceptr_t, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_dtd_async(dstDevice, srcDevice, ByteCount, hStream, false) + } + + pub(crate) unsafe fn cuMemcpyDtoDAsync_v2_ptsz( + dstDevice: hipDeviceptr_t, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_dtd_async(dstDevice, srcDevice, ByteCount, hStream, true) + } + + pub(crate) unsafe fn cuMemcpyHtoDAsync_v2( + dstDevice: hipDeviceptr_t, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_h_to_d_async(dstDevice, srcHost, ByteCount, hStream, false) + } + + pub(crate) unsafe fn cuMemcpyHtoDAsync_v2_ptsz( + dstDevice: hipDeviceptr_t, + srcHost: *const ::std::os::raw::c_void, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_h_to_d_async(dstDevice, srcHost, ByteCount, hStream, true) + } + + pub(crate) unsafe fn cuMemcpyDtoHAsync_v2( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_d_to_h_async(dstHost, srcDevice, ByteCount, hStream, false) + } + + pub(crate) unsafe fn cuMemcpyDtoHAsync_v2_ptsz( + dstHost: *mut ::std::os::raw::c_void, + srcDevice: hipDeviceptr_t, + ByteCount: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy_d_to_h_async(dstHost, srcDevice, ByteCount, hStream, true) + } + + pub(crate) unsafe fn cuMemcpy2D_v2(copy: *const CUDA_MEMCPY2D) -> hipError_t { + memory::copy2d(copy) + } + + pub(crate) unsafe fn cuMemcpy2DAsync_v2( + copy: *const CUDA_MEMCPY2D, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy2d_async(copy, hStream) + } + + pub(crate) unsafe fn cuMemcpy2DUnaligned_v2(copy: *const CUDA_MEMCPY2D) -> hipError_t { + memory::copy2d_unaligned(copy) + } + + pub(crate) unsafe fn cuMemcpy3D_v2(copy: *const CUDA_MEMCPY3D) -> Result<(), CUresult> { + memory::copy3d(copy) + } + + pub(crate) unsafe fn cuMemcpy3DAsync_v2( + copy: *const CUDA_MEMCPY3D, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::copy3d_async(copy, hStream) + } + + pub(crate) unsafe fn cuMemsetD8_v2( + dstDevice: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + N: usize, + ) -> hipError_t { + hipMemsetD8(dstDevice, uc, N) + } + + pub(crate) unsafe fn cuMemsetD8_v2_ptds( + dstDevice: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + N: usize, + ) -> hipError_t { + memory::set_d8_ptds(dstDevice, uc, N) + } + + pub(crate) unsafe fn cuMemsetD8Async( + dstDevice: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + N: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::set_d8_async(dstDevice, uc, N, hStream, false) + } + + pub(crate) unsafe fn cuMemsetD8Async_ptsz( + dstDevice: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + N: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::set_d8_async(dstDevice, uc, N, hStream, true) + } + + pub(crate) unsafe fn cuMemsetD16_v2( + dstDevice: hipDeviceptr_t, + us: ::std::os::raw::c_ushort, + N: usize, + ) -> hipError_t { + hipMemsetD16(dstDevice, us, N) + } + + pub(crate) unsafe fn cuMemsetD32Async( + dstDevice: hipDeviceptr_t, + ui: ::std::os::raw::c_uint, + N: usize, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + memory::set_d32_async(dstDevice, ui, N, hStream) + } + + pub(crate) unsafe fn cuMemsetD16_v2_ptds( + dstDevice: hipDeviceptr_t, + us: ::std::os::raw::c_ushort, + N: usize, + ) -> hipError_t { + hipMemsetD16(dstDevice, us, N) + } + + pub(crate) unsafe fn cuMemsetD32_v2( + dstDevice: hipDeviceptr_t, + ui: ::std::os::raw::c_uint, + N: usize, + ) -> hipError_t { + hipMemsetD32(dstDevice, ui as i32, N) + } + + pub(crate) unsafe fn cuMemsetD32_v2_ptds( + dstDevice: hipDeviceptr_t, + ui: ::std::os::raw::c_uint, + N: usize, + ) -> hipError_t { + hipMemset_spt(dstDevice.0, ui as i32, N) + } + + pub(crate) unsafe fn cuMemsetD2D8_v2( + dst_device: hipDeviceptr_t, + dst_pitch: usize, + uc: ::std::os::raw::c_uchar, + width: usize, + height: usize, + ) -> hipError_t { + hipMemset2D( + dst_device.0, + dst_pitch, + i32::from_ne_bytes([uc, uc, uc, uc]), + width, + height, + ) + } + + pub(crate) unsafe fn cuOccupancyMaxPotentialBlockSize( + minGridSize: *mut ::std::os::raw::c_int, + blockSize: *mut ::std::os::raw::c_int, + func: *mut function::Function, + blockSizeToDynamicSMemSize: CUoccupancyB2DSize, + dynamicSMemSize: usize, + blockSizeLimit: ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + function::occupancy_max_potential_block_size( + minGridSize, + blockSize, + func, + blockSizeToDynamicSMemSize, + dynamicSMemSize, + blockSizeLimit, + ) + } + + pub(crate) unsafe fn cuArrayCreate_v2( + pHandle: *mut CUarray, + pAllocateArray: *const HIP_ARRAY_DESCRIPTOR, + ) -> Result<(), CUresult> { + array::create(pHandle, pAllocateArray) + } + + pub(crate) unsafe fn cuArrayDestroy(hArray: CUarray) -> hipError_t { + let cu_array = hipfix::array::get(hArray); + hipArrayDestroy(cu_array) + } + + pub(crate) unsafe fn cuArray3DCreate_v2( + pHandle: *mut CUarray, + pAllocateArray: *const HIP_ARRAY3D_DESCRIPTOR, + ) -> Result<(), CUresult> { + array::create_3d(pHandle, pAllocateArray) + } + + pub(crate) unsafe fn cuArray3DGetDescriptor_v2( + pArrayDescriptor: *mut CUDA_ARRAY3D_DESCRIPTOR, + hArray: CUarray, + ) -> hipError_t { + array::get_descriptor_3d(pArrayDescriptor, hArray) + } + + pub(crate) unsafe fn cuPointerGetAttribute( + data: *mut ::std::os::raw::c_void, + attribute: hipPointer_attribute, + ptr: hipDeviceptr_t, + ) -> Result<(), CUresult> { + pointer::get_attribute(data, attribute, ptr) + } + + pub(crate) unsafe fn cuPointerGetAttributes( + numAttributes: ::std::os::raw::c_uint, + attributes: *mut hipPointer_attribute, + data: *mut *mut ::std::os::raw::c_void, + ptr: hipDeviceptr_t, + ) -> hipError_t { + pointer::get_attributes(numAttributes, attributes, data, ptr) + } + + pub(crate) unsafe fn cuStreamCreate( + phStream: *mut *mut stream::Stream, + Flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + stream::create_with_priority(phStream, Flags, 0) + } + + pub(crate) unsafe fn cuStreamCreateWithPriority( + phStream: *mut *mut stream::Stream, + flags: ::std::os::raw::c_uint, + priority: ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + stream::create_with_priority(phStream, flags, priority) + } + + pub(crate) unsafe fn cuStreamGetCaptureInfo( + stream: *mut stream::Stream, + captureStatus_out: *mut hipStreamCaptureStatus, + id_out: *mut cuuint64_t, + ) -> Result<(), CUresult> { + stream::get_capture_info(stream, captureStatus_out, id_out) + } + + pub(crate) unsafe fn cuStreamGetCtx( + hStream: *mut stream::Stream, + pctx: *mut *mut context::Context, + ) -> Result<(), CUresult> { + stream::get_ctx(hStream, pctx) + } + + pub(crate) unsafe fn cuStreamGetCtx_ptsz( + hStream: *mut stream::Stream, + pctx: *mut *mut context::Context, + ) -> Result<(), CUresult> { + stream::get_ctx(hStream, pctx) + } + + pub(crate) unsafe fn cuStreamGetFlags( + hStream: *mut stream::Stream, + flags: *mut ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + stream::get_flags(hStream, flags) + } + + pub(crate) unsafe fn cuStreamIsCapturing( + hStream: *mut stream::Stream, + captureStatus: *mut hipStreamCaptureStatus, + ) -> Result<(), CUresult> { + stream::is_capturing(hStream, captureStatus) + } + + pub(crate) unsafe fn cuStreamQuery(hStream: *mut stream::Stream) -> Result<(), CUresult> { + stream::query(hStream) + } + + pub(crate) unsafe fn cuStreamSynchronize(hStream: *mut stream::Stream) -> Result<(), CUresult> { + stream::synchronize(hStream, false) + } + + pub(crate) unsafe fn cuStreamSynchronize_ptsz( + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + stream::synchronize(hStream, true) + } + + pub(crate) unsafe fn cuStreamDestroy(hStream: *mut stream::Stream) -> Result<(), CUresult> { + stream::destroy(hStream) + } + + pub(crate) unsafe fn cuStreamDestroy_v2(hStream: *mut stream::Stream) -> Result<(), CUresult> { + stream::destroy(hStream) + } + + pub(crate) unsafe fn cuStreamWaitEvent( + hStream: *mut stream::Stream, + hEvent: hipEvent_t, + Flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + stream::wait_event(hStream, hEvent, Flags, false) + } + + pub(crate) unsafe fn cuStreamWaitEvent_ptsz( + hStream: *mut stream::Stream, + hEvent: hipEvent_t, + Flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + stream::wait_event(hStream, hEvent, Flags, true) + } + + pub(crate) unsafe fn cuFuncGetAttribute( + pi: *mut ::std::os::raw::c_int, + attrib: hipFunction_attribute, + func: *mut function::Function, + ) -> Result<(), CUresult> { + function::get_attribute(pi, attrib, func) + } + + pub(crate) unsafe fn cuFuncSetAttribute( + func: *mut function::Function, + attrib: hipFunction_attribute, + value: ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + function::set_attribute(func, attrib, value) + } + + pub(crate) unsafe fn cuLaunchHostFunc( + stream: *mut stream::Stream, + fn_: CUhostFn, + userData: *mut ::std::os::raw::c_void, + ) -> Result<(), CUresult> { + stream::launch_host_func(stream, fn_, userData) + } + + pub(crate) unsafe fn cuLaunchKernel( + f: *mut function::Function, + 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: *mut stream::Stream, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + ) -> Result<(), CUresult> { + function::launch_kernel( + f, + gridDimX, + gridDimY, + gridDimZ, + blockDimX, + blockDimY, + blockDimZ, + sharedMemBytes, + hStream, + kernelParams, + extra, + false, + ) + } + + pub(crate) unsafe fn cuLaunchKernel_ptsz( + f: *mut function::Function, + 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: *mut stream::Stream, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + ) -> Result<(), CUresult> { + function::launch_kernel( + f, + gridDimX, + gridDimY, + gridDimZ, + blockDimX, + blockDimY, + blockDimZ, + sharedMemBytes, + hStream, + kernelParams, + extra, + true, + ) + } + + pub(crate) unsafe fn cuMemHostGetDevicePointer_v2( + pdptr: *mut hipDeviceptr_t, + p: *mut ::std::os::raw::c_void, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t { + memory::host_get_device_pointer(pdptr, p, Flags) + } + + pub(crate) unsafe fn cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( + num_blocks: *mut ::std::os::raw::c_int, + func: *mut function::Function, + block_size: ::std::os::raw::c_int, + dynamic_smem_size: usize, + flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + function::occupancy_max_potential_blocks_per_multiprocessor( + num_blocks, + func, + block_size, + dynamic_smem_size, + flags, + ) + } + + pub(crate) unsafe fn cuSurfObjectCreate( + pSurfObject: *mut hipSurfaceObject_t, + pResDesc: *const CUDA_RESOURCE_DESC, + ) -> Result<(), CUresult> { + surface::create(pSurfObject, pResDesc) + } + + pub(crate) unsafe fn cuSurfObjectDestroy( + surfObject: hipSurfaceObject_t, + ) -> hipError_t { + hipDestroySurfaceObject(surfObject) + } + + pub(crate) unsafe fn cuTexObjectCreate( + pTexObject: *mut hipTextureObject_t, + pResDesc: *const CUDA_RESOURCE_DESC, + pTexDesc: *const HIP_TEXTURE_DESC, + pResViewDesc: *const HIP_RESOURCE_VIEW_DESC, + ) -> hipError_t { + texobj::create(pTexObject, pResDesc, pTexDesc, pResViewDesc) + } + + pub(crate) unsafe fn cuTexObjectDestroy(texObject: hipTextureObject_t) -> hipError_t { + hipTexObjectDestroy(texObject) + } + + pub(crate) unsafe fn cuTexRefGetAddress_v2( + pdptr: *mut hipDeviceptr_t, + tex_ref: *mut textureReference, + ) -> hipError_t { + hipTexRefGetAddress(pdptr, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetAddressMode( + pam: *mut hipTextureAddressMode, + tex_ref: *mut textureReference, + dim: ::std::os::raw::c_int, + ) -> hipError_t { + hipTexRefGetAddressMode(pam, tex_ref, dim) + } + + pub(crate) unsafe fn cuTexRefGetFilterMode( + pfm: *mut hipTextureFilterMode, + tex_ref: *mut textureReference, + ) -> hipError_t { + hipTexRefGetFilterMode(pfm, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetFlags( + flags: *mut ::std::os::raw::c_uint, + tex_ref: *mut textureReference, + ) -> hipError_t { + hipTexRefGetFlags(flags, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetMipmapFilterMode( + pfm: *mut hipTextureFilterMode, + tex_ref: *mut textureReference, + ) -> hipError_t { + texref::get_mipmap_filter_mode(pfm, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetMipmapLevelBias( + pbias: *mut f32, + tex_ref: *mut textureReference, + ) -> hipError_t { + texref::get_mipmap_level_bias(pbias, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetMipmapLevelClamp( + min_mipmap_level_clamp: *mut f32, + max_mipmap_level_clamp: *mut f32, + tex_ref: *mut textureReference, + ) -> hipError_t { + texref::get_mipmap_level_clamp(min_mipmap_level_clamp, max_mipmap_level_clamp, tex_ref) + } + + pub(crate) unsafe fn cuTexRefGetMaxAnisotropy( + pmaxAniso: *mut ::std::os::raw::c_int, + tex_ref: *mut textureReference, + ) -> hipError_t { + texref::get_max_anisotropy(pmaxAniso, tex_ref) + } + + pub(crate) unsafe fn cuTexRefSetAddress2D_v3( + tex_ref: *mut textureReference, + desc: *const HIP_ARRAY_DESCRIPTOR, + dptr: hipDeviceptr_t, + pitch: usize, + ) -> hipError_t { + hipTexRefSetAddress2D(tex_ref, desc, dptr, pitch) + } + + pub(crate) unsafe fn cuTexRefSetAddressMode( + tex_ref: *mut textureReference, + dim: ::std::os::raw::c_int, + am: hipTextureAddressMode, + ) -> Result<(), CUresult> { + texref::set_address_mode(tex_ref, dim, am) + } + + pub(crate) unsafe fn cuTexRefSetAddress_v2( + byte_offset: *mut usize, + tex_ref: *mut textureReference, + dptr: hipDeviceptr_t, + bytes: usize, + ) -> hipError_t { + texref::set_address(byte_offset, tex_ref, dptr, bytes) + } + + pub(crate) unsafe fn cuTexRefSetArray( + hTexRef: *mut textureReference, + hArray: CUarray, + Flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + texref::set_array(hTexRef, hArray, Flags) + } + + pub(crate) unsafe fn cuTexRefSetFilterMode( + tex_ref: *mut textureReference, + fm: hipTextureFilterMode, + ) -> Result<(), CUresult> { + texref::set_filter_mode(tex_ref, fm) + } + + pub(crate) unsafe fn cuTexRefSetFlags( + tex_ref: *mut textureReference, + flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + texref::set_flags(tex_ref, flags) + } + + pub(crate) unsafe fn cuTexRefSetFormat( + tex_ref: *mut textureReference, + fmt: hipArray_Format, + num_packed_components: ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + texref::set_format(tex_ref, fmt, num_packed_components) + } + + pub(crate) unsafe fn cuTexRefGetFormat( + pFormat: *mut hipArray_Format, + pNumChannels: *mut ::std::os::raw::c_int, + hTexRef: *mut textureReference, + ) -> hipError_t { + hipTexRefGetFormat(pFormat, pNumChannels, hTexRef) + } + + pub(crate) unsafe fn cuTexRefSetMaxAnisotropy( + tex_ref: *mut textureReference, + max_aniso: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + texref::set_max_anisotropy(tex_ref, max_aniso) + } + + pub(crate) unsafe fn cuTexRefSetMipmapFilterMode( + tex_ref: *mut textureReference, + fm: hipTextureFilterMode, + ) -> Result<(), CUresult> { + texref::set_mipmap_filter_mode(tex_ref, fm) + } + + pub(crate) unsafe fn cuTexRefSetMipmapLevelBias( + tex_ref: *mut textureReference, + bias: f32, + ) -> Result<(), CUresult> { + texref::set_mipmap_level_bias(tex_ref, bias) + } + + pub(crate) unsafe fn cuTexRefSetMipmapLevelClamp( + tex_ref: *mut textureReference, + min_mipmap_level_clamp: f32, + max_mipmap_level_clamp: f32, + ) -> Result<(), CUresult> { + texref::set_mipmap_level_clamp(tex_ref, min_mipmap_level_clamp, max_mipmap_level_clamp) + } + + pub(crate) unsafe fn cuSurfRefSetArray( + hSurfRef: *mut textureReference, + hArray: CUarray, + Flags: ::std::os::raw::c_uint, + ) -> Result<(), CUresult> { + surfref::set_array(hSurfRef, hArray, Flags) + } + + pub(crate) unsafe fn cuFuncSetBlockShape( + hfunc: *mut function::Function, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + z: ::std::os::raw::c_int, + ) -> Result<(), CUresult> { + Ok(()) + } + + pub(crate) unsafe fn cuEventCreate( + phEvent: *mut hipEvent_t, + Flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipEventCreate(phEvent) + } + + pub(crate) unsafe fn cuEventDestroy(event: hipEvent_t) -> hipError_t { + cuEventDestroy_v2(event) + } + + pub(crate) unsafe fn cuEventDestroy_v2(event: hipEvent_t) -> hipError_t { + hipEventDestroy(event) + } + + pub(crate) unsafe fn cuEventQuery(event: hipEvent_t) -> hipError_t { + hipEventQuery(event) + } + + pub(crate) unsafe fn cuEventElapsedTime( + ms: *mut f32, + start: hipEvent_t, + stop: hipEvent_t, + ) -> hipError_t { + hipEventElapsedTime(ms, start, stop) + } + + pub(crate) unsafe fn cuEventRecord( + event: hipEvent_t, + stream: *mut stream::Stream, + ) -> Result<(), CUresult> { + let stream = stream::as_hip_stream(stream)?; + hip_call_cuda!(hipEventRecord(event, stream)); + Ok(()) + } + + pub(crate) unsafe fn cuEventRecord_ptsz( + event: hipEvent_t, + stream: *mut stream::Stream, + ) -> Result<(), CUresult> { + let stream = hipfix::as_hip_stream_per_thread(stream, true)?; + hip_call_cuda!(hipEventRecord(event, stream)); + Ok(()) + } + + pub(crate) unsafe fn cuEventSynchronize(event: hipEvent_t) -> hipError_t { + hipEventSynchronize(event) + } + + pub(crate) unsafe fn cuGraphAddDependencies( + graph: hipGraph_t, + from: *const hipGraphNode_t, + to: *const hipGraphNode_t, + numDependencies: usize, + ) -> hipError_t { + hipGraphAddDependencies(graph, from, to, numDependencies) + } + + pub(crate) unsafe fn cuGraphAddEmptyNode( + pGraphNode: *mut hipGraphNode_t, + graph: hipGraph_t, + pDependencies: *const hipGraphNode_t, + numDependencies: usize, + ) -> hipError_t { + hipGraphAddEmptyNode(pGraphNode, graph, pDependencies, numDependencies) + } + + pub(crate) unsafe fn cuGraphAddKernelNode( + phGraphNode: *mut hipGraphNode_t, + hGraph: hipGraph_t, + dependencies: *const hipGraphNode_t, + numDependencies: usize, + nodeParams: *const CUDA_KERNEL_NODE_PARAMS_v1, + ) -> Result<(), CUresult> { + graph::add_kernel_node( + phGraphNode, + hGraph, + dependencies, + numDependencies, + nodeParams, + ) + } + + pub(crate) unsafe fn cuGraphCreate( + phGraph: *mut hipGraph_t, + flags: ::std::os::raw::c_uint, + ) -> hipError_t { + hipGraphCreate(phGraph, flags) + } + + pub(crate) unsafe fn cuGraphDestroy(graph: hipGraph_t) -> hipError_t { + hipGraphDestroy(graph) + } + + pub(crate) unsafe fn cuGraphExecDestroy(graphExec: hipGraphExec_t) -> hipError_t { + hipGraphExecDestroy(graphExec) + } + + pub(crate) unsafe fn cuGraphInstantiate( + phGraphExec: *mut hipGraphExec_t, + hGraph: hipGraph_t, + phErrorNode: *mut hipGraphNode_t, + logBuffer: *mut ::std::os::raw::c_char, + bufferSize: usize, + ) -> hipError_t { + hipGraphInstantiate(phGraphExec, hGraph, phErrorNode, logBuffer, bufferSize) + } + + pub(crate) unsafe fn cuGraphInstantiate_v2( + phGraphExec: *mut hipGraphExec_t, + hGraph: hipGraph_t, + phErrorNode: *mut hipGraphNode_t, + logBuffer: *mut ::std::os::raw::c_char, + bufferSize: usize, + ) -> hipError_t { + cuGraphInstantiate(phGraphExec, hGraph, phErrorNode, logBuffer, bufferSize) + } + + pub(crate) unsafe fn cuGraphLaunch( + hGraph: hipGraphExec_t, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + graph::launch(hGraph, hStream) + } + + pub(crate) unsafe fn cuGraphicsSubResourceGetMappedArray( + pArray: *mut CUarray, + resource: hipGraphicsResource_t, + arrayIndex: ::std::os::raw::c_uint, + mipLevel: ::std::os::raw::c_uint, + ) -> hipError_t { + hipGraphicsSubResourceGetMappedArray(pArray.cast(), resource, arrayIndex, mipLevel) + } + + pub(crate) unsafe fn cuGraphicsGLRegisterBuffer( + resource: *mut hipGraphicsResource_t, + buffer: u32, + flags: ::std::os::raw::c_uint, + ) -> hipError_t { + gl::register_buffer(resource, buffer, flags) + } + + pub(crate) unsafe fn cuGraphicsGLRegisterImage( + resource: *mut hipGraphicsResource_t, + image: u32, + target: u32, + flags: ::std::os::raw::c_uint, + ) -> hipError_t { + gl::register_image(resource, image, target, flags) + } + + pub(crate) unsafe fn cuGraphicsMapResources( + count: ::std::os::raw::c_uint, + resources: *mut hipGraphicsResource_t, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + gl::map_resources(count, resources, hStream) + } + + pub(crate) unsafe fn cuGraphicsResourceGetMappedPointer_v2( + pDevPtr: *mut hipDeviceptr_t, + pSize: *mut usize, + resource: hipGraphicsResource_t, + ) -> hipError_t { + hipGraphicsResourceGetMappedPointer(pDevPtr.cast(), pSize, resource) + } + + pub(crate) unsafe fn cuGraphicsUnmapResources( + count: ::std::os::raw::c_uint, + resources: *mut hipGraphicsResource_t, + hStream: *mut stream::Stream, + ) -> Result<(), CUresult> { + gl::unmap_resources(count, resources, hStream) + } + + pub(crate) unsafe fn cuGraphicsUnregisterResource( + resource: hipGraphicsResource_t, + ) -> hipError_t { + hipGraphicsUnregisterResource(resource) + } + + pub(crate) unsafe fn cuLinkAddData_v2( + state: *mut link::LinkState, + 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, + ) -> Result<(), CUresult> { + link::add_data( + state, + type_, + data, + size, + name, + numOptions, + options, + optionValues, + ) + } + + pub(crate) unsafe fn cuLinkComplete( + state: *mut link::LinkState, + cubinOut: *mut *mut ::std::os::raw::c_void, + sizeOut: *mut usize, + ) -> Result<(), CUresult> { + link::complete(state, cubinOut, sizeOut) + } + + pub(crate) unsafe fn cuLinkDestroy(state: *mut link::LinkState) -> Result<(), CUresult> { + link::destroy(state) + } + + pub(crate) unsafe fn cuLinkCreate_v2( + numOptions: ::std::os::raw::c_uint, + options: *mut CUjit_option, + optionValues: *mut *mut ::std::os::raw::c_void, + stateOut: *mut *mut link::LinkState, + ) -> Result<(), CUresult> { + link::create(numOptions, options, optionValues, stateOut) + } +} diff --git a/zluda/src/cuda_impl/mod.rs b/zluda/src/cuda_impl/mod.rs deleted file mode 100644 index 63b9049..0000000 --- a/zluda/src/cuda_impl/mod.rs +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 3931bc3..0000000 --- a/zluda/src/cuda_impl/rt.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub enum ContextState {} -pub enum ContextStateManager {} diff --git a/zluda/src/impl/array.rs b/zluda/src/impl/array.rs new file mode 100644 index 0000000..ab2db78 --- /dev/null +++ b/zluda/src/impl/array.rs @@ -0,0 +1,83 @@ +use std::{mem, ptr}; + +use crate::hip_call_cuda; + +use super::hipfix; +use cuda_types::*; +use hip_runtime_sys::*; + +pub(crate) unsafe fn create_3d( + array: *mut CUarray, + allocate_array: *const HIP_ARRAY3D_DESCRIPTOR, +) -> Result<(), CUresult> { + if let (Some(array_ptr), Some(desc)) = ( + array.as_mut(), + (allocate_array as *const HIP_ARRAY3D_DESCRIPTOR).as_ref(), + ) { + let mut desc = *desc; + let (hack_flag, format) = hipfix::get_non_broken_format(desc.Format); + desc.Format = format; + hipfix::array_3d_create(&mut desc); + let mut hip_array = mem::zeroed(); + hip_call_cuda!(hipArray3DCreate(&mut hip_array, &mut desc as _)); + (&mut *hip_array).textureType = hack_flag; + let layered_dimensions = if desc.Flags & hipArrayLayered != 0 { + if desc.Height == 0 { + 1usize + } else { + 2 + } + } else { + 0 + }; + *array_ptr = hipfix::array::to_cuda(hip_array, layered_dimensions); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} + +pub(crate) unsafe fn get_descriptor_3d( + array_descriptor: *mut CUDA_ARRAY3D_DESCRIPTOR, + array: CUarray, +) -> hipError_t { + let layered = hipfix::array::get_layered_dimensions(array); + let mut flags = if layered > 0 { CUDA_ARRAY3D_LAYERED } else { 0 }; + // HIP surfaces are always ld/st capable you want it or not + flags |= CUDA_ARRAY3D_SURFACE_LDST; + let array = hipfix::array::get(array); + if let (Some(array), Some(array_descriptor)) = (array.as_ref(), array_descriptor.as_mut()) { + *array_descriptor = CUDA_ARRAY3D_DESCRIPTOR { + Width: array.width as usize, + Height: array.height as usize, + Depth: array.depth as usize, + NumChannels: array.NumChannels, + Format: mem::transmute(array.Format), // compatible + Flags: flags, + }; + hipError_t::hipSuccess + } else { + hipError_t::hipErrorInvalidValue + } +} + +pub(crate) unsafe fn create( + array: *mut *mut CUarray_st, + desc: *const HIP_ARRAY_DESCRIPTOR, +) -> Result<(), CUresult> { + if array == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + if let Some(desc) = (desc as *const HIP_ARRAY_DESCRIPTOR).as_ref() { + let mut desc = *desc; + let (hack_flag, format) = hipfix::get_non_broken_format(desc.Format); + desc.Format = format; + let mut hip_array = ptr::null_mut(); + hip_call_cuda!(hipArrayCreate(&mut hip_array, &desc)); + (&mut *hip_array).textureType = hack_flag; + *array = hip_array.cast(); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} diff --git a/zluda/src/impl/cache.rs b/zluda/src/impl/cache.rs new file mode 100644 index 0000000..5946bb9 --- /dev/null +++ b/zluda/src/impl/cache.rs @@ -0,0 +1,82 @@ +use hip_common::{ + cache::{KernelExtendedData, KernelRepository}, + unwrap_or_return, CompilationMode, +}; +use static_assertions::assert_impl_one; +use std::{borrow::Cow, ffi::CStr, path::Path}; + +pub(crate) struct KernelCache(KernelRepository); +assert_impl_one!(KernelCache: Sync); + +impl KernelCache { + pub(crate) const CACHE_FILE: &'static str = "zluda.db"; + + pub(crate) fn new(cache_dir: &Path) -> Option { + let mut file = cache_dir.to_path_buf(); + file.push(Self::CACHE_FILE); + Some(Self(KernelRepository::new(Some(file)).ok()?)) + } + + pub(crate) fn save_program( + &self, + compiler_version: &str, + device: &CStr, + ptx_modules: &[Cow<'_, str>], + compilation_mode: CompilationMode, + binary: &[u8], + ) { + let now = unwrap_or_return!(KernelRepository::::now()); + let mut hasher = blake3::Hasher::new(); + for module in ptx_modules { + hasher.update(module.as_bytes()); + } + let hash = hasher.finalize().to_hex(); + let git_hash = env!("VERGEN_GIT_SHA"); + self.0 + .save_program( + now, + hash.as_str(), + compiler_version, + git_hash, + device, + binary, + rusqlite::params![compilation_mode as u8], + ) + .ok(); + } + + pub(crate) fn try_load_program( + &self, + compiler_version: &str, + device: &CStr, + ptx_modules: &[Cow<'_, str>], + compilation_mode: CompilationMode, + ) -> Option> { + let now = KernelRepository::::now().ok()?; + let mut hasher = blake3::Hasher::new(); + for module in ptx_modules { + hasher.update(module.as_bytes()); + } + let hash = hasher.finalize().to_hex(); + let git_hash = env!("VERGEN_GIT_SHA"); + Some( + self.0 + .try_load_program( + now, + hash.as_str(), + compiler_version, + git_hash, + device, + rusqlite::params![compilation_mode as u8], + ) + .ok() + .flatten()?, + ) + } +} + +struct NoExtendedData; + +impl KernelExtendedData for NoExtendedData { + const INPUT_COLUMNS: &'static [[&'static str; 2]] = &[["compilation_mode", "INTEGER NOT NULL"]]; +} diff --git a/zluda/src/impl/context.rs b/zluda/src/impl/context.rs index f50d64b..429338b 100644 --- a/zluda/src/impl/context.rs +++ b/zluda/src/impl/context.rs @@ -1,367 +1,246 @@ -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}, -}; +// HIP does not implement context APIs: +// https://rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html#hip-context-management-apis +use super::{fold_cuda_errors, module, stream, LiveCheck, ZludaObject}; +use crate::hip_call_cuda; +use cuda_types::*; +use hip_runtime_sys::*; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::ptr; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::Mutex; +use std::{cell::RefCell, ffi::c_void}; + +// We store device separately to avoid accessing context fields when popping +// a context from the stack. It's perfectly ok to destroy a context and remove +// it from the stack later thread_local! { - pub static CONTEXT_STACK: RefCell> = RefCell::new(Vec::new()); + pub(crate) static CONTEXT_STACK: RefCell> = RefCell::new(Vec::new()); } -pub type Context = LiveCheck; +pub(crate) type Context = LiveCheck; -impl HasLivenessCookie for ContextData { +impl ZludaObject for ContextData { #[cfg(target_pointer_width = "64")] - const COOKIE: usize = 0x5f0119560b643ffb; - + const LIVENESS_COOKIE: usize = 0x5f0119560b643ffb; #[cfg(target_pointer_width = "32")] - const COOKIE: usize = 0x0b643ffb; - + const LIVENESS_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(()) + fn drop_with_result(&mut self, _: bool) -> Result<(), CUresult> { + let mutable = self + .mutable + .get_mut() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + fold_cuda_errors(mutable.streams.iter().copied().map(|s| { + unsafe { LiveCheck::drop_box_with_result(s, true)? }; + 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, - ), - >, +pub(crate) struct ContextData { + pub(crate) flags: AtomicU32, + is_primary: bool, + pub(crate) ref_count: AtomicU32, + pub(crate) device: hipDevice_t, + pub(crate) mutable: Mutex, } impl ContextData { - pub fn new( - l0_ctx: &mut l0::Context, - l0_dev: &l0::Device, - flags: c_uint, + pub(crate) fn new( + flags: u32, + device: hipDevice_t, is_primary: bool, - dev: *mut device::Device, + initial_refcount: u32, ) -> Result { - 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, + device, + ref_count: AtomicU32::new(initial_refcount), + is_primary, + mutable: Mutex::new(ContextDataMutable::new()), }) } } -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(crate) struct ContextDataMutable { + pub(crate) streams: FxHashSet<*mut stream::Stream>, + pub(crate) modules: FxHashSet<*mut module::Module>, + // Field below is here to support CUDA Driver Dark API + pub(crate) local_storage: FxHashMap<*mut c_void, LocalStorageValue>, +} + +impl ContextDataMutable { + fn new() -> Self { + ContextDataMutable { + streams: FxHashSet::default(), + modules: FxHashSet::default(), + local_storage: FxHashMap::default(), + } } } -pub fn create_v2( +pub(crate) struct LocalStorageValue { + pub(crate) value: *mut c_void, + pub(crate) _dtor_callback: Option, +} + +pub(crate) unsafe fn create( pctx: *mut *mut Context, flags: u32, - dev_idx: device::Index, + dev: hipDevice_t, ) -> 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(()) + let context_box = Box::new(LiveCheck::new(ContextData::new(flags, dev, false, 1)?)); + let context_ptr = Box::into_raw(context_box); + *pctx = context_ptr; + push_context_stack(context_ptr) } -pub fn destroy_v2(ctx: *mut Context) -> Result<(), CUresult> { +pub(crate) unsafe fn destroy(ctx: *mut Context) -> Result<(), CUresult> { if ctx == ptr::null_mut() { return Err(CUresult::CUDA_ERROR_INVALID_VALUE); } + let ctx_ref = LiveCheck::as_result(ctx)?; + if ctx_ref.is_primary { + return Err(CUresult::CUDA_ERROR_INVALID_CONTEXT); + } CONTEXT_STACK.with(|stack| { let mut stack = stack.borrow_mut(); let should_pop = match stack.last() { - Some(active_ctx) => *active_ctx == (ctx as *mut _), + Some((active_ctx, _)) => *active_ctx == ctx, None => false, }; if should_pop { - stack.pop(); + pop_context_stack_impl(&mut stack)?; } - }); - GlobalState::lock(|_| Context::destroy_impl(ctx))? + Ok(()) + })?; + LiveCheck::drop_box_with_result(ctx, false) } -pub(crate) fn push_current_v2(pctx: *mut Context) -> CUresult { +pub(crate) unsafe fn push_current(pctx: *mut Context) -> Result<(), CUresult> { if pctx == ptr::null_mut() { - return CUresult::CUDA_ERROR_INVALID_VALUE; - } - CONTEXT_STACK.with(|stack| stack.borrow_mut().push(pctx)); - CUresult::CUDA_SUCCESS -} - -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 }; + push_context_stack(pctx) +} + +pub(crate) unsafe fn pop_current(pctx: *mut *mut Context) -> Result<(), CUresult> { + let mut ctx = pop_context_stack()?; + let ctx_ptr = match &mut ctx { + Some(ctx) => *ctx as *mut _, + None => return Err(CUresult::CUDA_ERROR_INVALID_CONTEXT), + }; + if pctx != ptr::null_mut() { + *pctx = ctx_ptr; + } Ok(()) } -pub fn get_device(dev: *mut device::Index) -> Result<(), CUresult> { - let dev_idx = GlobalState::lock_current_context(|ctx| unsafe { &*ctx.device }.index)?; +pub(crate) unsafe fn set_current(ctx: *mut Context) -> Result<(), CUresult> { + if ctx == ptr::null_mut() { + pop_context_stack()?; + } else { + push_context_stack(ctx)?; + } + Ok(()) +} + +pub(crate) fn get_current(pctx: *mut *mut Context) -> CUresult { + if pctx == ptr::null_mut() { + return CUresult::CUDA_ERROR_INVALID_VALUE; + } + let ctx = get_current_from_stack().unwrap_or(ptr::null_mut()); + unsafe { *pctx = ctx }; + CUresult::CUDA_SUCCESS +} + +pub fn get_device(dev: *mut hipDevice_t) -> Result<(), CUresult> { + let dev_idx = with_current(|ctx| ctx.device)?; 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 }; +pub(crate) fn get_limit(pvalue: *mut usize, limit: hipLimit_t) -> Result<(), CUresult> { + hip_call_cuda! { hipDeviceGetLimit(pvalue, limit) }; 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 set_limit(limit: hipLimit_t, value: usize) -> Result<(), CUresult> { + hip_call_cuda! { hipDeviceSetLimit(limit, value) }; + Ok(()) } -pub(crate) fn synchronize() -> CUresult { - // TODO: change the implementation once we do async stream operations - CUresult::CUDA_SUCCESS +pub(crate) unsafe fn get_api_version(ctx: *mut Context, version: *mut u32) -> Result<(), CUresult> { + if ctx == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_CONTEXT); + } + let ctx = LiveCheck::as_result(ctx)?; + if ctx.ref_count.load(Ordering::Acquire) == 0 { + return Err(CUresult::CUDA_ERROR_INVALID_CONTEXT); + } + //TODO: query device for properties roughly matching CUDA API version + *version = 3020; + Ok(()) } -#[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() { - 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() { - 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() { - 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() { - 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() { - 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()); - } +pub(crate) unsafe fn synchronize() -> Result<(), CUresult> { + // TODO + // We currently do this to sync with default stream which syncs whole device anyway, + // figure out if we can do something smarter here + hip_call_cuda!(hipDeviceSynchronize()); + Ok(()) +} + +pub(crate) fn with_current(f: impl FnOnce(&ContextData) -> T) -> Result { + CONTEXT_STACK.with(|stack| { + stack + .borrow() + .last() + .ok_or(CUresult::CUDA_ERROR_INVALID_CONTEXT) + .and_then(|(ctx, _)| Ok(f(unsafe { LiveCheck::as_result(*ctx)? }))) + }) +} + +fn get_current_from_stack() -> Option<*mut Context> { + CONTEXT_STACK.with(|stack| stack.borrow().last().copied().map(|(ctx, _)| ctx)) +} + +fn pop_context_stack() -> Result, CUresult> { + CONTEXT_STACK.with(|stack| { + let mut stack = stack.borrow_mut(); + pop_context_stack_impl(&mut stack) + }) +} + +fn pop_context_stack_impl( + stack: &mut Vec<(*mut Context, hipDevice_t)>, +) -> Result, CUresult> { + let ctx = stack.pop(); + if let Some((_, device)) = stack.last() { + hip_call_cuda!(hipSetDevice(*device)); + } + Ok(ctx.map(|(ctx, _)| ctx)) +} + +unsafe fn push_context_stack(ctx: *mut Context) -> Result<(), CUresult> { + let device = { LiveCheck::as_result(ctx)?.device }; + CONTEXT_STACK.with(|stack| stack.borrow_mut().push((ctx, device))); + hip_call_cuda!(hipSetDevice(device)); + Ok(()) +} + +pub(crate) unsafe fn get_stream_priority_range( + least_priority: *mut ::std::os::raw::c_int, + greatest_priority: *mut ::std::os::raw::c_int, +) -> Result<(), CUresult> { + hip_call_cuda!(hipDeviceGetStreamPriorityRange( + least_priority, + greatest_priority + )); + Ok(()) } diff --git a/zluda/src/impl/dark_api.rs b/zluda/src/impl/dark_api.rs new file mode 100644 index 0000000..c3f4fca --- /dev/null +++ b/zluda/src/impl/dark_api.rs @@ -0,0 +1,399 @@ +use super::module; +use super::{ + context::{self, LocalStorageValue}, + device, FromCuda, IntoCuda, LiveCheck, +}; +use crate::r#impl::{dark_api, stream}; +use cuda_types::*; +use hip_common::zluda_ext::CudaResult; +use std::{ + ffi::c_void, + mem, + os::raw::{c_int, c_uchar, c_uint}, + ptr, +}; +use zluda_dark_api::{ + AntiZludaHashInput, CUmoduleContent, CudaDarkApi, CudaDarkApiTable, CudaFatbin, +}; + +pub(crate) unsafe fn get_table( + pp_export_table: *mut *const ::std::os::raw::c_void, + p_export_table_id: *const CUuuid, +) -> CUresult { + if pp_export_table == ptr::null_mut() || p_export_table_id == ptr::null() { + return CUresult::CUDA_ERROR_INVALID_VALUE; + } + if let Some(table_ptr) = CUDA_DARK_API_TABLE.get(&(*p_export_table_id).bytes) { + *pp_export_table = table_ptr.as_ptr() as _; + CUresult::CUDA_SUCCESS + } else { + CUresult::CUDA_ERROR_UNKNOWN + } +} + +static CUDA_DARK_API_TABLE: CudaDarkApiTable = zluda_dark_api::init_dark_api::(); + +struct CudaDarkApiZluda; + +static mut TOOLS_RUNTIME_CALLBACK_HOOKS_FN2_SPACE: [usize; 1024] = [0; 1024]; +static mut TOOLS_RUNTIME_CALLBACK_HOOKS_FN6_SPACE: [u8; 14] = [0; 14]; + +impl CudaDarkApi for CudaDarkApiZluda { + unsafe extern "system" fn get_module_from_cubin( + module: *mut cuda_types::CUmodule, + fatbinc_wrapper: *const zluda_dark_api::FatbincWrapper, + ) -> CUresult { + if module == ptr::null_mut() || fatbinc_wrapper == ptr::null_mut() { + return CUresult::CUDA_ERROR_INVALID_VALUE; + } + let fatbin = match CudaFatbin::from_wrapper(fatbinc_wrapper) { + Ok(fatbin) => fatbin, + Err(_) => return CUresult::CUDA_ERROR_NOT_SUPPORTED, + }; + module::load_impl(module.cast(), CUmoduleContent::Fatbin(fatbin)).into_cuda() + } + + unsafe extern "system" fn get_primary_context( + pctx: *mut cuda_types::CUcontext, + dev: cuda_types::CUdevice, + ) -> CUresult { + let pctx: *mut *mut context::Context = FromCuda::from_cuda(pctx); + let hip_dev = FromCuda::from_cuda(dev); + device::primary_ctx_get(pctx, hip_dev).into_cuda() + } + + unsafe extern "system" fn get_module_from_cubin_ex1( + module: *mut cuda_types::CUmodule, + fatbinc_wrapper: *const zluda_dark_api::FatbincWrapper, + arg3: *mut c_void, + arg4: *mut c_void, + _arg5: usize, + ) -> CUresult { + if arg3 != ptr::null_mut() || arg4 != ptr::null_mut() { + return CUresult::CUDA_ERROR_NOT_SUPPORTED; + } + if module == ptr::null_mut() || fatbinc_wrapper == ptr::null_mut() { + return CUresult::CUDA_ERROR_INVALID_VALUE; + } + let fatbin = match CudaFatbin::from_wrapper(fatbinc_wrapper) { + Ok(fatbin) => fatbin, + Err(_) => return CUresult::CUDA_ERROR_NOT_SUPPORTED, + }; + module::load_impl(module.cast(), CUmoduleContent::Fatbin(fatbin)).into_cuda() + } + + unsafe extern "system" fn cudart_interface_fn7(_arg1: usize) -> () {} + + unsafe extern "system" fn get_module_from_cubin_ex2( + fatbin_header: *const zluda_dark_api::FatbinHeader, + module: *mut cuda_types::CUmodule, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: c_uint, + ) -> CUresult { + if arg3 != ptr::null_mut() || arg4 != ptr::null_mut() || arg5 != 0 { + CUresult::CUDA_ERROR_NOT_SUPPORTED + } else { + let fatbin = CudaFatbin::from_header(fatbin_header); + module::load_impl(module.cast(), CUmoduleContent::Fatbin(fatbin)).into_cuda() + } + } + + unsafe extern "system" fn tools_runtime_callback_hooks_fn2( + ptr: *mut *mut usize, + size: *mut usize, + ) -> () { + *ptr = TOOLS_RUNTIME_CALLBACK_HOOKS_FN2_SPACE.as_mut_ptr(); + *size = TOOLS_RUNTIME_CALLBACK_HOOKS_FN2_SPACE.len(); + } + + unsafe extern "system" fn tools_runtime_callback_hooks_fn6( + ptr: *mut *mut u8, + size: *mut usize, + ) -> () { + *ptr = TOOLS_RUNTIME_CALLBACK_HOOKS_FN6_SPACE.as_mut_ptr(); + *size = TOOLS_RUNTIME_CALLBACK_HOOKS_FN6_SPACE.len(); + } + + unsafe extern "system" fn context_local_storage_insert( + cu_ctx: cuda_types::CUcontext, + key: *mut c_void, + value: *mut c_void, + dtor_callback: Option, + ) -> CUresult { + with_context_or_current(cu_ctx, |ctx| { + let mut ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + ctx_mutable.local_storage.insert( + key, + LocalStorageValue { + value, + _dtor_callback: dtor_callback, + }, + ); + Ok(()) + }) + } + + // TODO + unsafe extern "system" fn context_local_storage_remove(_arg1: usize, _arg2: usize) -> CUresult { + CUresult::CUDA_SUCCESS + } + + unsafe extern "system" fn context_local_storage_get( + result: *mut *mut c_void, + cu_ctx: cuda_types::CUcontext, + key: *mut c_void, + ) -> CUresult { + let mut cu_result = None; + let query_cu_result = with_context_or_current(cu_ctx, |ctx| { + let ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + cu_result = ctx_mutable.local_storage.get(&key).map(|v| v.value); + Ok(()) + }); + if query_cu_result != CUresult::CUDA_SUCCESS { + query_cu_result + } else { + match cu_result { + Some(value) => { + *result = value; + CUresult::CUDA_SUCCESS + } + None => CUresult::CUDA_ERROR_INVALID_VALUE, + } + } + } + + unsafe extern "system" fn ctx_create_v2_bypass( + pctx: *mut cuda_types::CUcontext, + flags: c_uint, + dev: cuda_types::CUdevice, + ) -> CUresult { + let pctx = FromCuda::from_cuda(pctx); + let dev = FromCuda::from_cuda(dev); + context::create(pctx, flags, dev).into_cuda() + } + + unsafe extern "system" fn heap_alloc( + _halloc_ptr: *mut *mut zluda_dark_api::HeapAllocRecord, + _param1: usize, + _param2: usize, + ) -> CUresult { + super::unimplemented() + } + + unsafe extern "system" fn heap_free( + _halloc: *mut zluda_dark_api::HeapAllocRecord, + _param2: *mut usize, + ) -> CUresult { + super::unimplemented() + } + + unsafe extern "system" fn device_get_attribute_ex( + _dev: cuda_types::CUdevice, + _attribute: c_uint, + _unknown: c_int, + _result: *mut [usize; 2], + ) -> CUresult { + super::unimplemented() + } + + unsafe extern "system" fn device_get_something( + _result: *mut c_uchar, + _dev: cuda_types::CUdevice, + ) -> CUresult { + super::unimplemented() + } + + unsafe extern "system" fn launch_kernel( + _f: CUfunction, + _grid_dim_x: std::os::raw::c_uint, + _grid_dim_y: std::os::raw::c_uint, + _grid_dim_z: std::os::raw::c_uint, + _block_dim_x: std::os::raw::c_uint, + _block_dim_y: std::os::raw::c_uint, + _block_dim_z: std::os::raw::c_uint, + _shared_mem_bytes: std::os::raw::c_uint, + _stream: CUstream, + _extra: *mut *mut std::os::raw::c_void, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_cuInit() -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_start1( + _retval1: *mut *mut c_void, + _arg2: *mut c_void, + _arg3: *mut c_void, + _arg4: *mut c_void, + _arg5: *mut c_void, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_start2(_handle: *mut c_void, _arg2: *mut u32) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_module_load( + _context: CUcontext, + _result: *mut CUmodule, + _fatbin: *mut c_void, + _arg4: u32, + _arg5: *mut c_void, + _arg6: *mut c_void, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_module_get_function( + _result: *mut CUfunction, + _module: CUmodule, + _name: *const i8, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_feature_evaluate2( + _handle1: *mut c_void, + _handle2: *mut c_void, + _handle3: *mut c_void, + _arg4: u8, + _handle5: *mut c_void, + _arg6: u32, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_feature_evaluate1( + _retval1: *mut u32, + _retval2: *mut u32, + _retval3: *mut u32, + _handle: *mut c_void, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn dlss_feature_evaluate_init( + _retval1: *mut *mut c_void, + _handle: *mut c_void, + _retval2: *mut *mut c_void, + ) -> CUresult { + super::unimplemented() + } + + #[allow(non_snake_case)] + unsafe extern "system" fn zluda_check( + rt_version: u32, + timestamp: u64, + result: *mut u128, + ) -> CUresult { + use crate::hip_call_cuda; + use hip_common::cuda; + use hip_runtime_sys::*; + unsafe fn zluda_check_impl(rt_version: u32, timestamp: u64) -> Result { + let mut device_count = 0i32; + hip_call_cuda! { hipGetDeviceCount(&mut device_count as _) }; + let driver_version = crate::DRIVER_VERSION as u32; + let device_attributes = (0..device_count) + .map(|dev| { + let mut device_attributes = + mem::zeroed::(); + cuda! { device::get_uuid(&mut device_attributes.guid, dev)}; + device::get_attribute( + &mut device_attributes.pci_bus as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, + dev, + )?; + device::get_attribute( + &mut device_attributes.pci_domain as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, + dev, + )?; + device::get_attribute( + &mut device_attributes.pci_device as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, + dev, + )?; + Ok(device_attributes) + }) + .collect::, _>>()?; + let mut cudart_export_table = ptr::null(); + cuda! { dark_api::get_table( + &mut cudart_export_table, + &zluda_dark_api::CudartInterface::GUID as _, + ) }; + let mut anti_zluda_export_table = ptr::null(); + cuda! { dark_api::get_table( + &mut anti_zluda_export_table, + &zluda_dark_api::AntiZluda::GUID as _, + ) }; + let hash_input = AntiZludaHashInput { + cudart_export_table: cudart_export_table as _, + anti_zluda_export_table: anti_zluda_export_table as _, + fn_ptr: CudaDarkApiZluda::zluda_check as _, + device_count: device_count as u32, + driver_version, + rt_version, + timestamp, + }; + let dev_getter = |dev| device_attributes[dev as usize].clone(); + Ok(zluda_dark_api::anti_zluda_hash( + false, hash_input, dev_getter, + )) + } + match zluda_check_impl(rt_version, timestamp) { + Ok(hash) => { + *result = hash; + CUresult::CUDA_SUCCESS + } + Err(e) => e, + } + } + + unsafe extern "system" fn get_hip_stream( + stream: CUstream, + ) -> CudaResult<*const std::os::raw::c_void> { + let cuda_object: *mut LiveCheck = stream as *mut stream::Stream; + stream::as_hip_stream(cuda_object) + .map(|ptr| ptr as *const _) + .into() + } + + unsafe extern "system" fn unwrap_context( + _ctx: CUcontext, + is_wrapped: *mut u32, + _unwrapped_ctx: *mut CUcontext, + ) -> CUresult { + *is_wrapped = 0; + CUresult::CUDA_SUCCESS + } +} + +unsafe fn with_context_or_current( + ctx: CUcontext, + f: impl FnOnce(&context::ContextData) -> Result<(), CUresult>, +) -> CUresult { + if ctx == ptr::null_mut() { + context::with_current(|c| f(c)).into_cuda() + } else { + let ctx = FromCuda::from_cuda(ctx); + LiveCheck::as_result(ctx).map(f).into_cuda() + } +} diff --git a/zluda/src/impl/device.rs b/zluda/src/impl/device.rs index 29cac2d..4a97b3b 100644 --- a/zluda/src/impl/device.rs +++ b/zluda/src/impl/device.rs @@ -1,414 +1,659 @@ -use super::{context, CUresult, GlobalState}; -use crate::cuda; -use cuda::{CUdevice_attribute, CUuuid_st}; +use super::{ + context, LiveCheck, GLOBAL_STATE, +}; +use crate::{r#impl::IntoCuda, hip_call_cuda}; +use crate::hip_call; +use cuda_types::{CUdevice_attribute, CUdevprop, CUuuid_st, CUresult}; +use hip_common::CompilationMode; +use hip_runtime_sys::*; +use paste::paste; use std::{ - cmp, mem, - os::raw::{c_char, c_int, c_uint}, + mem, + os::raw::{c_char, c_uint}, ptr, - sync::atomic::{AtomicU32, Ordering}, + sync::{ + atomic::AtomicU32, + Mutex, + }, ops::AddAssign, ffi::CString, }; -const PROJECT_URL_SUFFIX_SHORT: &'static str = " [ZLUDA]"; -const PROJECT_URL_SUFFIX_LONG: &'static str = " [github.com/vosen/ZLUDA]"; +const ZLUDA_SUFFIX: &'static [u8] = b" [ZLUDA]\0"; +// We report the highest non-existent compute capability mainly to fool Blender. +// Blender will look for known compute sapabilities and give them ELF. +// If the compute capability is unknown it gives them PTX +pub const COMPUTE_CAPABILITY_MAJOR: u32 = 8; +pub const COMPUTE_CAPABILITY_MINOR: u32 = 8; -#[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>, - image_properties: Option>, - memory_properties: Option>, - compute_properties: Option>, +pub(crate) struct Device { + pub(crate) compilation_mode: CompilationMode, + pub(crate) comgr_isa: CString, + // Primary context is lazy-initialized, the mutex is here to secure retain + // from multiple threads + primary_context: Mutex>, } -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 { - 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(), - )?); + pub(crate) fn new(index: usize) -> Result { + let comgr_isa = unsafe { hip_common::comgr_isa(index as i32) }.map_err(hipError_t::into_cuda)?; + let mut warp_size = 0i32; + hip_call_cuda!{ hipDeviceGetAttribute(&mut warp_size, hipDeviceAttribute_t::hipDeviceAttributeWarpSize, index as i32) }; + let compilation_mode = if warp_size == 32 { + CompilationMode::Wave32 + } else if warp_size == 64 { + get_wave64_mode() + } else { + return Err(CUresult::CUDA_ERROR_ILLEGAL_STATE); + }; 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, + compilation_mode, + comgr_isa, + primary_context: Mutex::new(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 { - let props = self.get_compute_properties()?; - Ok(*props.subGroupSizes[0..props.numSubGroupSizes as usize] - .iter() - .max() - .unwrap()) - } } -pub fn init(driver: &l0::Driver) -> Result, CUresult> { - let ze_devices = driver.devices()?; - let mut devices = ze_devices - .into_iter() - .enumerate() - .map(|(idx, d)| unsafe { Device::new(driver, d, idx) }) - .collect::, _>>()?; - for dev in devices.iter_mut() { - dev.late_init(); - dev.primary_context.late_init(); +fn get_wave64_mode() -> CompilationMode { + match std::env::var("ZLUDA_WAVE64_SLOW_MODE") { + Ok(value) => { + if let Ok(value) = str::parse::(&value) { + if value != 0 { + return CompilationMode::Wave32OnWave64; + } + } + } + Err(_) => {} } - Ok(devices) + CompilationMode::DoubleWave32OnWave64 } -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(()) +#[allow(warnings)] +trait hipDeviceAttribute_t_ext { + const hipDeviceAttributeMaximumTexture1DWidth: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture1DWidth; + const hipDeviceAttributeMaximumTexture2DWidth: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DWidth; + const hipDeviceAttributeMaximumTexture2DHeight: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DHeight; + const hipDeviceAttributeMaximumTexture3DWidth: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DWidth; + const hipDeviceAttributeMaximumTexture3DHeight: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DHeight; + const hipDeviceAttributeMaximumTexture3DDepth: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DDepth; + const hipDeviceAttributeGlobalMemoryBusWidth: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMemoryBusWidth; + const hipDeviceAttributeMaxThreadsPerMultiprocessor: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeMaxThreadsPerMultiProcessor; + const hipDeviceAttributeAsyncEngineCount: hipDeviceAttribute_t = + hipDeviceAttribute_t::hipDeviceAttributeConcurrentKernels; } -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) - } -} +impl hipDeviceAttribute_t_ext for hipDeviceAttribute_t {} -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 { - 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, +macro_rules! remap_attribute { + ($attrib:expr => $([ $($word:expr)* ]),*,) => { + match $attrib { + $( + paste! { CUdevice_attribute:: [< CU_DEVICE_ATTRIBUTE $(_ $word:upper)* >] } => { + paste! { hipDeviceAttribute_t:: [< hipDeviceAttribute $($word:camel)* >] } + } + )* + _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE) } } } -pub fn get_attribute( +pub(crate) unsafe fn get_attribute( pi: *mut i32, attrib: CUdevice_attribute, - dev_idx: Index, + dev: hipDevice_t, ) -> 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 { + let hip_attrib = 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, - )) - */ + *pi = 1; return Ok(()); } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GPU_OVERLAP + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_STREAM_PRIORITIES_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GLOBAL_L1_CACHE_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_LOCAL_L1_CACHE_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_PREEMPTION_SUPPORTED=> { + *pi = 1; + return Ok(()); + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_TCC_DRIVER + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_HEIGHT + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_WIDTH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_HEIGHT + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_PITCH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_PERSISTING_L2_CACHE_SIZE + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD_GROUP_ID + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_HOST_NATIVE_ATOMIC_SUPPORTED + // possibly true for integrated GPUs + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_ACCESS_POLICY_WINDOW_SIZE + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_RESERVED_SHARED_MEMORY_PER_BLOCK + // Possibly true + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_HOST_REGISTER_SUPPORTED + // Possibly true + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_READ_ONLY_HOST_REGISTER_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_SPARSE_CUDA_ARRAY_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_TIMELINE_SEMAPHORE_INTEROP_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MEMORY_POOLS_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_FLUSH_WRITES_OPTIONS + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_WRITES_ORDERING + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MEMPOOL_SUPPORTED_HANDLE_TYPES + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_DEFERRED_MAPPING_CUDA_ARRAY_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORTED + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_CLUSTER_LAUNCH + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_UNIFIED_FUNCTION_POINTERS => { + *pi = 0; + return Ok(()); + } + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_SINGLE_TO_DOUBLE_PRECISION_PERF_RATIO => { + // true for most navi1 and navi2 cards + *pi = 16; + return Ok(()); + } + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCKS_PER_MULTIPROCESSOR => { + // in practical terms max group size = max blocks * warp size + let mut prop = mem::zeroed(); + hip_call_cuda! { hipGetDeviceProperties(&mut prop, dev) }; + *pi = (prop.maxThreadsPerBlock / 2) / prop.warpSize; + return Ok(()); + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR => { + compute_capability(pi, &mut 0i32, dev); + return Ok(()); + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR => { + compute_capability(&mut 0i32, pi, dev); + return Ok(()); + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR => { + // My 1060 returns same for CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR and + // CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK, not sure what is the difference + hipDeviceAttribute_t::hipDeviceAttributeMaxRegistersPerBlock + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK_OPTIN => { + hipDeviceAttribute_t::hipDeviceAttributeMaxSharedMemoryPerBlock + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD => { + hipDeviceAttribute_t::hipDeviceAttributeIsMultiGpuBoard + } + // we assume that arrayed texts have the same limits + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DHeight + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture1DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_LAYERED_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture1DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_HEIGHT => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DHeight + } + // we treat surface the same as texture + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT => { + hipDeviceAttribute_t::hipDeviceAttributeTextureAlignment + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture1DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_HEIGHT => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DHeight + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_HEIGHT => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DHeight + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_DEPTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture3DDepth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DWidth + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture2DHeight + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH => { + hipDeviceAttribute_t::hipDeviceAttributeMaxTexture1DWidth + } + // Totally made up + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_LAYERS + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_LAYERED_LAYERS + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_LAYERS => { + *pi = u16::MAX as i32; + return Ok(()); + } + // linear sizes + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LINEAR_WIDTH => { + let mut prop = mem::zeroed(); + hip_call_cuda! { hipGetDeviceProperties(&mut prop, dev) }; + *pi = prop.maxTexture1DLinear; + return Ok(()); + } + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID => { + let mut prop = mem::zeroed(); + hip_call_cuda! { hipGetDeviceProperties(&mut prop, dev) }; + *pi = prop.pciDomainID; + return Ok(()); + } + attrib @ + (CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y + | CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z) => { + let attrib = remap_attribute! { + attrib => + [MAX THREADS PER BLOCK], + [MAX BLOCK DIM X], + [MAX BLOCK DIM Y], + [MAX BLOCK DIM Z], + [MAX GRID DIM X], + [MAX GRID DIM Y], + [MAX GRID DIM Z], + }; + hip_call_cuda! { hipDeviceGetAttribute(pi, attrib, dev) }; + let dev = GLOBAL_STATE.get()?.device(dev)?; + if dev.compilation_mode == CompilationMode::Wave32OnWave64 { + *pi /= 2; + } + return Ok(()) + } + attrib => remap_attribute! { + attrib => + [MAX SHARED MEMORY PER BLOCK], + [TOTAL CONSTANT MEMORY], + [WARP SIZE], + [MAX PITCH], + [MAX REGISTERS PER BLOCK], + [CLOCK RATE], + [TEXTURE ALIGNMENT], + //[GPU OVERLAP], + [MULTIPROCESSOR COUNT], + [KERNEL EXEC TIMEOUT], + [INTEGRATED], + [CAN MAP HOST MEMORY], + [COMPUTE MODE], + [MAXIMUM TEXTURE1D WIDTH], + [MAXIMUM TEXTURE2D WIDTH], + [MAXIMUM TEXTURE2D HEIGHT], + [MAXIMUM TEXTURE3D WIDTH], + [MAXIMUM TEXTURE3D HEIGHT], + [MAXIMUM TEXTURE3D DEPTH], + //[MAXIMUM TEXTURE2D LAYERED WIDTH], + //[MAXIMUM TEXTURE2D LAYERED HEIGHT], + //[MAXIMUM TEXTURE2D LAYERED LAYERS], + //[MAXIMUM TEXTURE2D ARRAY WIDTH], + //[MAXIMUM TEXTURE2D ARRAY HEIGHT], + //[MAXIMUM TEXTURE2D ARRAY NUMSLICES], + //[SURFACE ALIGNMENT], + [CONCURRENT KERNELS], + [ECC ENABLED], + [PCI BUS ID], + [PCI DEVICE ID], + //[TCC DRIVER], + [MEMORY CLOCK RATE], + [GLOBAL MEMORY BUS WIDTH], + [L2 CACHE SIZE], + [MAX THREADS PER MULTIPROCESSOR], + [ASYNC ENGINE COUNT], + //[UNIFIED ADDRESSING], + //[MAXIMUM TEXTURE1D LAYERED WIDTH], + //[MAXIMUM TEXTURE1D LAYERED LAYERS], + //[CAN TEX2D GATHER], + //[MAXIMUM TEXTURE2D GATHER WIDTH], + //[MAXIMUM TEXTURE2D GATHER HEIGHT], + //[MAXIMUM TEXTURE3D WIDTH ALTERNATE], + //[MAXIMUM TEXTURE3D HEIGHT ALTERNATE], + //[MAXIMUM TEXTURE3D DEPTH ALTERNATE], + //[PCI DOMAIN ID], + [TEXTURE PITCH ALIGNMENT], + //[MAXIMUM TEXTURECUBEMAP WIDTH], + //[MAXIMUM TEXTURECUBEMAP LAYERED WIDTH], + //[MAXIMUM TEXTURECUBEMAP LAYERED LAYERS], + //[MAXIMUM SURFACE1D WIDTH], + //[MAXIMUM SURFACE2D WIDTH], + //[MAXIMUM SURFACE2D HEIGHT], + //[MAXIMUM SURFACE3D WIDTH], + //[MAXIMUM SURFACE3D HEIGHT], + //[MAXIMUM SURFACE3D DEPTH], + //[MAXIMUM SURFACE1D LAYERED WIDTH], + //[MAXIMUM SURFACE1D LAYERED LAYERS], + //[MAXIMUM SURFACE2D LAYERED WIDTH], + //[MAXIMUM SURFACE2D LAYERED HEIGHT], + //[MAXIMUM SURFACE2D LAYERED LAYERS], + //[MAXIMUM SURFACECUBEMAP WIDTH], + //[MAXIMUM SURFACECUBEMAP LAYERED WIDTH], + //[MAXIMUM SURFACECUBEMAP LAYERED LAYERS], + //[MAXIMUM TEXTURE1D LINEAR WIDTH], + //[MAXIMUM TEXTURE2D LINEAR WIDTH], + //[MAXIMUM TEXTURE2D LINEAR HEIGHT], + //[MAXIMUM TEXTURE2D LINEAR PITCH], + //[MAXIMUM TEXTURE2D MIPMAPPED WIDTH], + //[MAXIMUM TEXTURE2D MIPMAPPED HEIGHT], + //[COMPUTE CAPABILITY MAJOR], + //[COMPUTE CAPABILITY MINOR], + //[MAXIMUM TEXTURE1D MIPMAPPED WIDTH], + //[STREAM PRIORITIES SUPPORTED], + //[GLOBAL L1 CACHE SUPPORTED], + //[LOCAL L1 CACHE SUPPORTED], + [MAX SHARED MEMORY PER MULTIPROCESSOR], + //[MAX REGISTERS PER MULTIPROCESSOR], + [MANAGED MEMORY], + //[MULTI GPU BOARD], + //[MULTI GPU BOARD GROUP ID], + //[HOST NATIVE ATOMIC SUPPORTED], + [SINGLE TO DOUBLE PRECISION PERF RATIO], + [PAGEABLE MEMORY ACCESS], + [CONCURRENT MANAGED ACCESS], + //[COMPUTE PREEMPTION SUPPORTED], + //[CAN USE HOST POINTER FOR REGISTERED MEM], + //[CAN USE STREAM MEM OPS], + //[CAN USE 64 BIT STREAM MEM OPS], + //[CAN USE STREAM WAIT VALUE NOR], + [COOPERATIVE LAUNCH], + [COOPERATIVE MULTI DEVICE LAUNCH], + //[MAX SHARED MEMORY PER BLOCK OPTIN], + //[CAN FLUSH REMOTE WRITES], + //[HOST REGISTER SUPPORTED], + [PAGEABLE MEMORY ACCESS USES HOST PAGE TABLES], + [DIRECT MANAGED MEM ACCESS FROM HOST], + //[VIRTUAL ADDRESS MANAGEMENT SUPPORTED], + //[VIRTUAL MEMORY MANAGEMENT SUPPORTED], + //[HANDLE TYPE POSIX FILE DESCRIPTOR SUPPORTED], + //[HANDLE TYPE WIN32 HANDLE SUPPORTED], + //[HANDLE TYPE WIN32 KMT HANDLE SUPPORTED], + //[MAX BLOCKS PER MULTIPROCESSOR], + //[GENERIC COMPRESSION SUPPORTED], + //[MAX ACCESS POLICY WINDOW SIZE], + //[GPU DIRECT RDMA WITH CUDA VMM SUPPORTED], + //[RESERVED SHARED MEMORY PER BLOCK], + //[SPARSE CUDA ARRAY SUPPORTED], + //[READ ONLY HOST REGISTER SUPPORTED], + //[TIMELINE SEMAPHORE INTEROP SUPPORTED], + //[MEMORY POOLS SUPPORTED], + }, }; - unsafe { *pi = value }; - Ok(()) + let error = hipDeviceGetAttribute(pi, hip_attrib, dev); + // For properties: + // * CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY + // * CU_DEVICE_ATTRIBUTE_MAX_PITCH + // HIP returns negative numbers (overflows) + if error == hipError_t::hipSuccess { + if *pi < 0 { + *pi = i32::MAX; + } + Ok(()) + } else { + Err(error.into_cuda()) + } + } -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) - })??; +// TODO +pub(crate) fn get_uuid(uuid: *mut CUuuid_st, _dev: hipDevice_t) -> CUresult { unsafe { *uuid = CUuuid_st { - bytes: mem::transmute(ze_uuid.id), + bytes: mem::zeroed(), } }; - Ok(()) -} - -// TODO: add support if Level 0 exposes it -pub fn get_luid(luid: *mut c_char, dev_node_mask: *mut c_uint, _dev_idx: Index) -> Result<(), CUresult> { - unsafe { ptr::write_bytes(luid, 0u8, 8) }; - unsafe { *dev_node_mask = 0 }; - 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 } +// TODO +pub(crate) fn get_luid( + luid: *mut c_char, + dev_node_mask: *mut c_uint, + _dev: hipDevice_t, +) -> CUresult { + unsafe { ptr::write_bytes(luid, 0u8, 8) }; + unsafe { *dev_node_mask = 0 }; + CUresult::CUDA_SUCCESS +} + +pub(crate) unsafe fn get_properties( + prop: *mut CUdevprop, + dev: hipDevice_t, +) -> Result<(), CUresult> { + if prop == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let mut hip_props = mem::zeroed(); + hip_call_cuda! { hipGetDeviceProperties(&mut hip_props, dev) }; + (*prop).maxThreadsPerBlock = hip_props.maxThreadsPerBlock; + (*prop).maxThreadsDim = hip_props.maxThreadsDim; + (*prop).maxGridSize = hip_props.maxGridSize; + (*prop).totalConstantMemory = usize::min(hip_props.totalConstMem, i32::MAX as usize) as i32; + (*prop).SIMDWidth = hip_props.warpSize; + (*prop).memPitch = usize::min(hip_props.memPitch, i32::MAX as usize) as i32; + (*prop).regsPerBlock = hip_props.regsPerBlock; + (*prop).clockRate = hip_props.clockRate; + (*prop).textureAlign = usize::min(hip_props.textureAlignment, i32::MAX as usize) as i32; + let dev = GLOBAL_STATE.get()?.device(dev)?; + if dev.compilation_mode == CompilationMode::Wave32OnWave64 { + (*prop).maxThreadsPerBlock /= 2; + (*prop).maxThreadsDim[0] /= 2; + (*prop).maxThreadsDim[1] /= 2; + (*prop).maxThreadsDim[2] /= 2; + (*prop).maxGridSize[0] /= 2; + (*prop).maxGridSize[1] /= 2; + (*prop).maxGridSize[2] /= 2; + } + Ok(()) +} + +pub(crate) unsafe fn compute_capability( + major: *mut ::std::os::raw::c_int, + minor: *mut ::std::os::raw::c_int, + _dev: hipDevice_t, +) { + *major = COMPUTE_CAPABILITY_MAJOR as i32; + *minor = COMPUTE_CAPABILITY_MINOR as i32; +} + +pub(crate) unsafe fn total_mem(bytes: *mut u32, dev: hipDevice_t) -> Result<(), hipError_t> { + let mut bytes_usize = 0; + hip_call!(hipDeviceTotalMem(&mut bytes_usize, dev)); + *bytes = usize::min(bytes_usize, u32::MAX as usize) as u32; + Ok(()) +} + +pub(crate) unsafe fn primary_ctx_get( + pctx: *mut *mut context::Context, + hip_dev: hipDevice_t, +) -> Result<(), CUresult> { + primary_ctx_get_or_retain(pctx, hip_dev, false) +} + +pub(crate) unsafe fn primary_ctx_retain( + pctx: *mut *mut context::Context, + hip_dev: hipDevice_t, +) -> Result<(), CUresult> { + primary_ctx_get_or_retain(pctx, hip_dev, true) +} + +unsafe fn primary_ctx_get_or_retain( + pctx: *mut *mut context::Context, + hip_dev: hipDevice_t, + increment_refcount: bool +) -> Result<(), CUresult> { + if pctx == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let ctx = primary_ctx(hip_dev, |ctx| { + let ctx = match ctx { + Some(ref mut ctx) => ctx, + None => { + ctx.insert(LiveCheck::new(context::ContextData::new(0, hip_dev, true, 0)?)) + }, + }; + if increment_refcount { + ctx.as_mut_unchecked().ref_count.get_mut().add_assign(1); + } + Ok(ctx as *mut _) + })??; + *pctx = ctx; + Ok(()) +} + +pub(crate) unsafe fn primary_ctx_release(hip_dev: hipDevice_t) -> Result<(), CUresult> { + primary_ctx(hip_dev, move |maybe_ctx| { + if let Some(ctx) = maybe_ctx { + let ctx_data = ctx.as_mut_unchecked(); + let ref_count = ctx_data.ref_count.get_mut(); + *ref_count -= 1; + if *ref_count == 0 { + //TODO: fix + //ctx.try_drop(false) + Ok(()) + } else { + Ok(()) + } + } else { + Err(CUresult::CUDA_ERROR_INVALID_CONTEXT) + } + })? +} + +pub(crate) unsafe fn primary_ctx_reset(_hip_dev: hipDevice_t) -> Result<(), CUresult> { + Ok(()) + //TODO: fix + /* + let maybe_ctx = primary_ctx(hip_dev, Option::take)?; + maybe_ctx + .map(|mut ctx| ctx.try_drop(false)) + .unwrap_or(Err(CUresult::CUDA_ERROR_INVALID_CONTEXT)) + */ +} + +pub(crate) unsafe fn primary_ctx_set_flags( + hip_dev: hipDevice_t, + flags: ::std::os::raw::c_uint, +) -> Result<(), CUresult> { + primary_ctx(hip_dev, move |maybe_ctx| { + if let Some(ctx) = maybe_ctx { + let ctx = ctx.as_mut_unchecked(); + ctx.flags = AtomicU32::new(flags); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_CONTEXT) + } + })? +} + +pub(crate) unsafe fn primary_ctx_get_state( + hip_dev: hipDevice_t, + flags_ptr: *mut ::std::os::raw::c_uint, + active_ptr: *mut ::std::os::raw::c_int, +) -> Result<(), CUresult> { + if flags_ptr == ptr::null_mut() || active_ptr == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let maybe_flags = primary_ctx(hip_dev, move |maybe_ctx| { + if let Some(ctx) = maybe_ctx { + let ctx = ctx.as_mut_unchecked(); + Some(*ctx.flags.get_mut()) + } else { + None + } + })?; + if let Some(flags) = maybe_flags { + *flags_ptr = flags; + *active_ptr = 1; + } else { + *flags_ptr = 0; + *active_ptr = 0; + } + Ok(()) +} + +pub(crate) unsafe fn primary_ctx( + dev: hipDevice_t, + f: impl FnOnce(&mut Option) -> T, +) -> Result { + let device = GLOBAL_STATE.get()?.device(dev)?; + let mut maybe_primary_context = device + .primary_context + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + Ok(f(&mut maybe_primary_context)) +} + +pub(crate) unsafe fn get_name(name: *mut i8, len: i32, device: i32) -> hipError_t { + let result= hipDeviceGetName(name, len, device); + if result != hipError_t::hipSuccess { + return result; + } + append_zluda_suffix(name, len); + hipError_t::hipSuccess +} + +unsafe fn append_zluda_suffix(name: *mut i8, len: i32) { + let len = len as usize; + let str_len = (0..len).position(|i| unsafe { *name.add(i) == 0 } ).unwrap(); + if (str_len + ZLUDA_SUFFIX.len()) > len { + return; + } + ptr::copy_nonoverlapping(ZLUDA_SUFFIX.as_ptr() as _,name.add(str_len), ZLUDA_SUFFIX.len()); +} + + #[cfg(test)] -mod test { - use super::super::test::CudaDriverFns; - use super::super::CUresult; +mod tests { + use super::append_zluda_suffix; - cuda_driver_test!(primary_ctx_default_inactive); + #[test] + fn append_name_too_short() { + let mut input = b"gfx-1030\0\n\n\n\n\n\n\n".to_vec(); + unsafe { append_zluda_suffix(input.as_mut_ptr() as _, input.len() as i32) }; + assert_eq!(input, b"gfx-1030\0\n\n\n\n\n\n\n"); + } - fn primary_ctx_default_inactive() { - 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); + #[test] + fn append_name_equal() { + let mut input = b"gfx-1030\0\n\n\n\n\n\n\n\n".to_vec(); + unsafe { append_zluda_suffix(input.as_mut_ptr() as _, input.len() as i32) }; + assert_eq!(input, b"gfx-1030 [ZLUDA]\0"); + } + + #[test] + fn append_name_long() { + let mut input = b"gfx-1030\0\n\n\n\n\n\n\n\n\n\n".to_vec(); + unsafe { append_zluda_suffix(input.as_mut_ptr() as _, input.len() as i32) }; + assert_eq!(input, b"gfx-1030 [ZLUDA]\0\n\n"); } } diff --git a/zluda/src/impl/empty_module.ptx b/zluda/src/impl/empty_module.ptx new file mode 100644 index 0000000..429cd69 --- /dev/null +++ b/zluda/src/impl/empty_module.ptx @@ -0,0 +1,3 @@ +.version 1.0 +.target sm_10 +.address_size 64 \ No newline at end of file diff --git a/zluda/src/impl/export_table.rs b/zluda/src/impl/export_table.rs deleted file mode 100644 index d3ae82d..0000000 --- a/zluda/src/impl/export_table.rs +++ /dev/null @@ -1,398 +0,0 @@ -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::os::raw::{c_uint, c_ulong, c_ushort}; -use std::{ - ffi::{c_void, CStr}, - ptr, -}; -use std::{mem, os::raw::c_int}; - -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)] -#[derive(Debug)] -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 kernel_text = match decompress_kernel_module(file) { - None => continue, - Some(vec) => vec, - }; - 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 -} - -const MAX_PTX_MODULE_DECOMPRESSION_BOUND: usize = 16 * 1024 * 1024; - -unsafe fn decompress_kernel_module(file: *const FatbinFileHeader) -> Option> { - let decompressed_size = usize::max(1024, (*file).uncompressed_payload as usize); - let mut decompressed_vec = vec![0u8; decompressed_size]; - loop { - match lz4_sys::LZ4_decompress_safe( - (file as *const u8).add((*file).header_size as usize) as *const _, - decompressed_vec.as_mut_ptr() as *mut _, - (*file).payload_size as c_int, - decompressed_vec.len() as c_int, - ) { - error if error < 0 => { - let new_size = decompressed_vec.len() * 2; - if new_size > MAX_PTX_MODULE_DECOMPRESSION_BOUND { - return None; - } - decompressed_vec.resize(decompressed_vec.len() * 2, 0); - } - real_decompressed_size => { - decompressed_vec.truncate(real_decompressed_size as usize); - return Some(decompressed_vec); - } - } - } -} - -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( - cu_ctx: *mut context::Context, - fn_impl: impl FnOnce(&mut ContextData) -> T, -) -> Result { - 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 index 11f15e6..d574589 100644 --- a/zluda/src/impl/function.rs +++ b/zluda/src/impl/function.rs @@ -1,191 +1,214 @@ -use super::{stream::Stream, CUresult, GlobalState, HasLivenessCookie, LiveCheck}; -use crate::cuda::CUfunction_attribute; -use ::std::os::raw::{c_uint, c_void}; -use std::{hint, ptr}; +use super::{stream, LiveCheck, ZludaObject}; +use crate::{hip_call_cuda, r#impl::hipfix}; +use cuda_types::*; +use hip_common::CompilationMode; +use hip_runtime_sys::*; +use std::{ffi::c_void, ptr}; -const CU_LAUNCH_PARAM_END: *mut c_void = 0 as *mut _; const CU_LAUNCH_PARAM_BUFFER_POINTER: *mut c_void = 1 as *mut _; const CU_LAUNCH_PARAM_BUFFER_SIZE: *mut c_void = 2 as *mut _; +const CU_LAUNCH_PARAM_END: *mut c_void = 0 as *mut _; +const HIP_LAUNCH_PARAM_END: *mut c_void = 3 as *mut _; -pub type Function = LiveCheck; +pub(crate) type Function = LiveCheck; -impl HasLivenessCookie for FunctionData { +impl ZludaObject for FunctionData { #[cfg(target_pointer_width = "64")] - const COOKIE: usize = 0x5e2ab14d5840678e; - + const LIVENESS_COOKIE: usize = 0x86b7301e5869d145; #[cfg(target_pointer_width = "32")] - const COOKIE: usize = 0x33e6a1e6; - + const LIVENESS_COOKIE: usize = 0x5cebb802; const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE; - fn try_drop(&mut self) -> Result<(), CUresult> { + fn drop_with_result(&mut self, _by_owner: bool) -> Result<(), CUresult> { Ok(()) } } -pub struct FunctionData { - pub base: l0::Kernel<'static>, - pub arg_size: Vec, - pub use_shared_mem: bool, - pub properties: Option>, - pub legacy_args: LegacyArguments, +pub(crate) struct FunctionData { + pub(crate) base: hipFunction_t, + pub(crate) ptx_version: u32, + pub(crate) binary_version: u32, + pub(crate) group_size: Option<(u32, u32)>, + pub(crate) compilation_mode: CompilationMode, } -pub struct LegacyArguments { - block_shape: Option<(i32, i32, i32)>, -} - -impl LegacyArguments { - pub fn new() -> Self { - LegacyArguments { block_shape: None } - } - - #[allow(dead_code)] - pub fn is_initialized(&self) -> bool { - self.block_shape.is_some() - } - - pub fn reset(&mut self) { - self.block_shape = None; - } -} - -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( +pub(crate) unsafe 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, + grid_dim_x: ::std::os::raw::c_uint, + grid_dim_y: ::std::os::raw::c_uint, + grid_dim_z: ::std::os::raw::c_uint, + block_dim_x: ::std::os::raw::c_uint, + block_dim_y: ::std::os::raw::c_uint, + mut block_dim_z: ::std::os::raw::c_uint, + shared_mem_bytes: ::std::os::raw::c_uint, + stream: *mut stream::Stream, + kernel_params: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + default_stream_per_thread: bool, ) -> Result<(), CUresult> { - if f == ptr::null_mut() - || (kernel_params == ptr::null_mut() && extra == ptr::null_mut()) - || (kernel_params != ptr::null_mut() && extra != ptr::null_mut()) - { - return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + let function = LiveCheck::as_result(f)?; + hipfix::validate_block_size(function, block_dim_x, block_dim_y, block_dim_z)?; + if function.compilation_mode == CompilationMode::Wave32OnWave64 { + block_dim_z *= 2; } - GlobalState::lock_stream(hstream, |stream| { - let func: &mut FunctionData = unsafe { &mut *f }.as_result_mut()?; + if extra != ptr::null_mut() { if kernel_params != ptr::null_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))? - }; - } - } else { - let mut offset = 0; - let mut buffer_ptr = None; - let mut buffer_size = None; - loop { - match unsafe { *extra.add(offset) } { - CU_LAUNCH_PARAM_END => break, - CU_LAUNCH_PARAM_BUFFER_POINTER => { - buffer_ptr = Some(unsafe { *extra.add(offset + 1) as *mut u8 }); - } - CU_LAUNCH_PARAM_BUFFER_SIZE => { - buffer_size = Some(unsafe { *(*extra.add(offset + 1) as *mut usize) }); - } - _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), - } - offset += 2; - } - match (buffer_size, buffer_ptr) { - (Some(buffer_size), Some(buffer_ptr)) => { - let sum_of_kernel_argument_sizes = - func.arg_size.iter().fold(0, |offset, size_of_arg| { - size_of_arg + round_up_to_multiple(offset, *size_of_arg) - }); - if buffer_size != sum_of_kernel_argument_sizes { - return Err(CUresult::CUDA_ERROR_INVALID_VALUE); - } - let mut offset = 0; - for (i, arg_size) in func.arg_size.iter().enumerate() { - let buffer_offset = round_up_to_multiple(offset, *arg_size); - unsafe { - func.base.set_arg_raw( - i as u32, - *arg_size, - buffer_ptr.add(buffer_offset) as *const _, - )? - }; - offset = buffer_offset + *arg_size; - } - } - _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), - } + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); } - if func.use_shared_mem { - unsafe { - func.base.set_arg_raw( - func.arg_size.len() as u32, - shared_mem_bytes as usize, - ptr::null(), - )? - }; + let mut extra_params = *(extra as *mut [*mut c_void; 5]); + if extra_params[0] != CU_LAUNCH_PARAM_BUFFER_POINTER + || extra_params[2] != CU_LAUNCH_PARAM_BUFFER_SIZE + || extra_params[4] != CU_LAUNCH_PARAM_END + { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); } - func.base - .set_group_size(block_dim_x, block_dim_y, block_dim_z)?; - func.legacy_args.reset(); - 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(()) - })? + // CU_LAUNCH_PARAM_END is 0, while HIP_LAUNCH_PARAM_END is 3 + extra_params[4] = HIP_LAUNCH_PARAM_END; + hip_call_cuda!(hipModuleLaunchKernel( + function.base, + grid_dim_x, + grid_dim_y, + grid_dim_z, + block_dim_x, + block_dim_y, + block_dim_z, + shared_mem_bytes, + hip_stream, + ptr::null_mut(), + extra_params.as_mut_ptr(), + )); + } else { + hip_call_cuda!(hipModuleLaunchKernel( + function.base, + grid_dim_x, + grid_dim_y, + grid_dim_z, + block_dim_x, + block_dim_y, + block_dim_z, + shared_mem_bytes, + hip_stream, + kernel_params, + extra, + )); + } + + Ok(()) } -fn round_up_to_multiple(x: usize, multiple: usize) -> usize { - ((x + multiple - 1) / multiple) * multiple -} - -pub(crate) fn get_attribute( - pi: *mut i32, - attrib: CUfunction_attribute, +pub(crate) unsafe fn occupancy_max_potential_block_size( + min_grid_size: *mut i32, + block_size: *mut i32, func: *mut Function, + _block_size_to_dynamic_smem_size: CUoccupancyB2DSize, + dynamic_smem_size: usize, + block_size_limit: i32, ) -> Result<(), CUresult> { - if pi == ptr::null_mut() || func == ptr::null_mut() { + if min_grid_size == ptr::null_mut() || block_size == 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(()) + let function = LiveCheck::as_result(func)?; + hip_call_cuda!(hipModuleOccupancyMaxPotentialBlockSize( + min_grid_size, + block_size, + function.base, + dynamic_smem_size, + block_size_limit + )); + hipfix::override_occupancy(function, min_grid_size, block_size); + if function.compilation_mode == CompilationMode::Wave32OnWave64 { + *block_size /= 2; + } + Ok(()) +} + +pub(crate) unsafe fn occupancy_max_potential_blocks_per_multiprocessor( + num_blocks: *mut i32, + func: *mut LiveCheck, + mut block_size: i32, + dynamic_smem_size: usize, + flags: u32, +) -> Result<(), CUresult> { + let function = LiveCheck::as_result(func)?; + if function.compilation_mode == CompilationMode::Wave32OnWave64 { + block_size *= 2; + } + hip_call_cuda!(hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( + num_blocks, + function.base, + block_size, + dynamic_smem_size, + flags, + )); + hipfix::occupancy_max_potential_blocks_per_multiprocessor(num_blocks); + Ok(()) +} + +pub(crate) unsafe fn get_attribute( + pi: *mut i32, + attrib: hipFunction_attribute, + func: *mut LiveCheck, +) -> Result<(), CUresult> { + let function = LiveCheck::as_result(func)?; + + match CUfunction_attribute(attrib.0) { + CUfunction_attribute::CU_FUNC_ATTRIBUTE_PTX_VERSION => { + *pi = function.ptx_version as i32; + return Ok(()); } + CUfunction_attribute::CU_FUNC_ATTRIBUTE_BINARY_VERSION => { + *pi = function.binary_version as i32; + return Ok(()); + } + CUfunction_attribute::CU_FUNC_ATTRIBUTE_PREFERRED_SHARED_MEMORY_CARVEOUT => { + *pi = -1; + return Ok(()); + } + CUfunction_attribute::CU_FUNC_ATTRIBUTE_CLUSTER_SIZE_MUST_BE_SET + | CUfunction_attribute::CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_WIDTH + | CUfunction_attribute::CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_HEIGHT + | CUfunction_attribute::CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_DEPTH + | CUfunction_attribute::CU_FUNC_ATTRIBUTE_NON_PORTABLE_CLUSTER_SIZE_ALLOWED + | CUfunction_attribute::CU_FUNC_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE => { + *pi = 0; + return Ok(()); + } + _ => {} + } + hip_call_cuda!(hipFuncGetAttribute(pi, attrib, function.base)); + if attrib == hipFunction_attribute::HIP_FUNC_ATTRIBUTE_NUM_REGS { + // For a completely empty kernel CUDA 11.8 returns 2 regs + // HIP returns zero + // Kokkos relies on this property being non-zero + *pi = i32::max(*pi, 1); + } + if attrib == hipFunction_attribute::HIP_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK { + if function.compilation_mode == CompilationMode::Wave32OnWave64 { + *pi /= 2; + } + } + Ok(()) +} + +pub(crate) unsafe fn set_attribute( + func: *mut LiveCheck, + attrib: hipFunction_attribute, + requested_value: i32, +) -> Result<(), CUresult> { + let function = LiveCheck::as_result(func)?; + match attrib { + // Required by xgboost + hipFunction_attribute::HIP_FUNC_ATTRIBUTE_MAX_DYNAMIC_SHARED_SIZE_BYTES => { + let mut current_value = 0; + hip_call_cuda! { hipFuncGetAttribute(&mut current_value, hipFunction_attribute::HIP_FUNC_ATTRIBUTE_MAX_DYNAMIC_SHARED_SIZE_BYTES, function.base) }; + if requested_value > current_value { + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } else { + Ok(()) + } + } + // Can't set attributes in HIP _ => Err(CUresult::CUDA_ERROR_NOT_SUPPORTED), } } - -pub(crate) fn set_block_shape(func: *mut Function, x: i32, y: i32, z: i32) -> Result<(), CUresult> { - if func == ptr::null_mut() || x < 0 || y < 0 || z < 0 { - return Err(CUresult::CUDA_ERROR_INVALID_VALUE); - } - GlobalState::lock_function(func, |func| { - func.legacy_args.block_shape = Some((x, y, z)); - }) -} diff --git a/zluda/src/impl/gl.rs b/zluda/src/impl/gl.rs new file mode 100644 index 0000000..d0cc376 --- /dev/null +++ b/zluda/src/impl/gl.rs @@ -0,0 +1,43 @@ +use super::{hipfix, stream}; +use crate::hip_call_cuda; +use cuda_types::CUresult; +use hip_runtime_sys::*; + +pub(crate) unsafe fn register_buffer( + resource: *mut hipGraphicsResource_t, + buffer: u32, + flags: ::std::os::raw::c_uint, +) -> hipError_t { + hipfix::init_opengl(); + hipGraphicsGLRegisterBuffer(resource, buffer, flags) +} + +pub(crate) unsafe fn register_image( + resource: *mut hipGraphicsResource_t, + image: u32, + target: u32, + flags: ::std::os::raw::c_uint, +) -> hipError_t { + hipfix::init_opengl(); + hipGraphicsGLRegisterImage(resource, image, target, flags) +} + +pub(crate) unsafe fn map_resources( + count: ::std::os::raw::c_uint, + resources: *mut hipGraphicsResource_t, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let stream = stream::as_hip_stream(stream)?; + hip_call_cuda! { hipGraphicsMapResources(count as i32, resources, stream) }; + Ok(()) +} + +pub(crate) unsafe fn unmap_resources( + count: ::std::os::raw::c_uint, + resources: *mut hipGraphicsResource_t, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let stream = stream::as_hip_stream(stream)?; + hip_call_cuda! { hipGraphicsUnmapResources(count as i32, resources, stream) }; + Ok(()) +} diff --git a/zluda/src/impl/graph.rs b/zluda/src/impl/graph.rs new file mode 100644 index 0000000..f8b2199 --- /dev/null +++ b/zluda/src/impl/graph.rs @@ -0,0 +1,57 @@ +use super::{function, stream, LiveCheck}; +use crate::hip_call_cuda; +use cuda_types::*; +use hip_runtime_sys::*; + +pub(crate) unsafe fn add_kernel_node( + ph_graph_node: *mut hipGraphNode_t, + h_graph: hipGraph_t, + dependencies: *const hipGraphNode_t, + num_dependencies: usize, + node_params: *const CUDA_KERNEL_NODE_PARAMS_v1, +) -> Result<(), CUresult> { + let node_params = node_params + .as_ref() + .ok_or(CUresult::CUDA_ERROR_INVALID_VALUE)?; + let node_params = hip_node_params(node_params)?; + hip_call_cuda!(hipGraphAddKernelNode( + ph_graph_node, + h_graph, + dependencies, + num_dependencies, + &node_params, + )); + Ok(()) +} + +unsafe fn hip_node_params( + cuda: &CUDA_KERNEL_NODE_PARAMS_v1, +) -> Result { + let zluda_func = cuda.func.cast::(); + let zluda_func = LiveCheck::as_result(zluda_func)?; + Ok(hipKernelNodeParams { + blockDim: dim3 { + x: cuda.blockDimX, + y: cuda.blockDimY, + z: cuda.blockDimZ, + }, + extra: cuda.extra, + func: zluda_func.base.cast(), + gridDim: dim3 { + x: cuda.gridDimX, + y: cuda.gridDimY, + z: cuda.gridDimZ, + }, + kernelParams: cuda.kernelParams, + sharedMemBytes: cuda.sharedMemBytes, + }) +} + +pub(crate) unsafe fn launch( + graph: hipGraphExec_t, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let stream = stream::as_hip_stream(stream)?; + hip_call_cuda!(hipGraphLaunch(graph, stream)); + Ok(()) +} diff --git a/zluda/src/impl/hipfix.rs b/zluda/src/impl/hipfix.rs new file mode 100644 index 0000000..77fec00 --- /dev/null +++ b/zluda/src/impl/hipfix.rs @@ -0,0 +1,377 @@ +// This module is the central place for HIP workarounds +use cuda_types::*; +use hip_runtime_sys::*; +use std::{env, ptr}; + +use super::{function::FunctionData, stream, LiveCheck}; + +// For some reason HIP does not tolerate hipArraySurfaceLoadStore, even though +// it works just fine +pub(crate) unsafe fn array_3d_create(descriptor: &mut HIP_ARRAY3D_DESCRIPTOR) { + descriptor.Flags &= !hipArraySurfaceLoadStore; +} + +#[must_use] +pub(crate) fn get_non_broken_format(format: hipArray_Format) -> (u32, hipArray_Format) { + match format { + hipArray_Format::HIP_AD_FORMAT_HALF => (2, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16), + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT16 => { + (1, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16) + } + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT8 => { + (1, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT8) + } + f => (0, f), + } +} + +#[must_use] +pub(crate) fn get_broken_format(broken: u32, format: hipArray_Format) -> hipArray_Format { + match (broken, format) { + (2, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16) => hipArray_Format::HIP_AD_FORMAT_HALF, + (1, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16) => { + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT16 + } + (1, hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT8) => { + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT8 + } + (_, f) => f, + } +} + +// memcpy3d fails when copying array1d arrays, so we mark all layered arrays by +// settings LSB +pub(crate) mod array { + use crate::{ + hip_call_cuda, + r#impl::{memcpy3d_from_cuda, memory_type_from_cuda, FromCuda}, + }; + use cuda_types::*; + use hip_runtime_sys::*; + use std::{mem, ptr}; + + pub(crate) unsafe fn with_resource_desc( + cuda: *const CUDA_RESOURCE_DESC, + fn_: impl FnOnce(*const HIP_RESOURCE_DESC) -> T, + ) -> T { + let cuda = &*cuda; + if cuda.resType == CUresourcetype::CU_RESOURCE_TYPE_ARRAY { + let mut cuda = *cuda; + cuda.res.array.hArray = mem::transmute(get(cuda.res.array.hArray)); + fn_((&cuda as *const CUDA_RESOURCE_DESC).cast::()) + } else { + fn_((cuda as *const CUDA_RESOURCE_DESC).cast::()) + } + } + + pub(crate) fn get(cuda: CUarray) -> hipArray_t { + (cuda as usize & !3usize) as hipArray_t + } + + pub(crate) fn to_cuda(array: hipArray_t, layered_dims: usize) -> CUarray { + let a1d_layered = layered_dims as usize; + ((array as usize) | a1d_layered) as CUarray + } + + pub(crate) fn get_layered_dimensions(cuda: CUarray) -> usize { + cuda as usize & 3usize + } + + pub(crate) fn copy3d_async( + stream: hipStream_t, + copy_desc: &CUDA_MEMCPY3D, + ) -> Result<(), CUresult> { + let src = get_array(copy_desc.srcMemoryType, copy_desc.srcArray); + let dst = get_array(copy_desc.dstMemoryType, copy_desc.dstArray); + match (src, dst) { + (Some((_, 1)), Some((_, 2))) | (Some((_, 2)), Some((_, 1))) => { + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + (Some((_, 1)), _) | (_, Some((_, 1))) => { + hip_call_cuda!(hipMemcpyParam2DAsync( + &memcpy3d_to_2d_layered(copy_desc), + stream + )); + Ok(()) + } + _ => { + // hipDrvMemcpy3D does not respect pitch parameter if src or target is an array + let hip_copy_desc = memcpy3d_from_cuda(copy_desc)?; + if (hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeArray + || hip_copy_desc.dstMemoryType == hipMemoryType::hipMemoryTypeArray) + && (hip_copy_desc.dstPitch > hip_copy_desc.WidthInBytes + || hip_copy_desc.srcPitch > hip_copy_desc.WidthInBytes) + { + if hip_copy_desc.srcPitch > hip_copy_desc.WidthInBytes + && (hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeDevice + || hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeHost) + && hip_copy_desc.dstMemoryType == hipMemoryType::hipMemoryTypeArray + { + if hip_copy_desc.srcXInBytes != 0 + || hip_copy_desc.srcY != 0 + || hip_copy_desc.srcZ != 0 + { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + if hip_copy_desc.dstXInBytes != 0 || hip_copy_desc.dstY != 0 { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + let mut temporary_buffer = ptr::null_mut(); + hip_call_cuda!(hipMalloc( + &mut temporary_buffer, + hip_copy_desc.WidthInBytes as usize + * hip_copy_desc.Height as usize + * hip_copy_desc.Depth as usize + )); + let mut reduce_pitch = hip_copy_desc.clone(); + reduce_pitch.dstMemoryType = hipMemoryType::hipMemoryTypeDevice; + reduce_pitch.dstDevice = hipDeviceptr_t(temporary_buffer); + reduce_pitch.dstArray = ptr::null_mut(); + reduce_pitch.dstZ = 0; + hip_call_cuda!(hipDrvMemcpy3DAsync(&reduce_pitch, stream)); + let mut final_copy = hip_copy_desc.clone(); + final_copy.srcMemoryType = hipMemoryType::hipMemoryTypeDevice; + final_copy.srcDevice = hipDeviceptr_t(temporary_buffer); + final_copy.srcPitch = final_copy.WidthInBytes; + hip_call_cuda!(hipDrvMemcpy3DAsync(&final_copy, stream)); + Ok(()) + /* + hip_call_cuda!(hipStreamAddCallback( + stream, + Some(free_device_allocation), + temporary_buffer, + 0 + )); + */ + } else { + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + } else { + hip_call_cuda!(hipDrvMemcpy3DAsync(&hip_copy_desc, stream)); + Ok(()) + } + } + } + } + + pub(crate) fn copy3d(copy_desc: &CUDA_MEMCPY3D) -> Result<(), CUresult> { + let src = get_array(copy_desc.srcMemoryType, copy_desc.srcArray); + let dst = get_array(copy_desc.dstMemoryType, copy_desc.dstArray); + match (src, dst) { + (Some((_, 1)), Some((_, 2))) | (Some((_, 2)), Some((_, 1))) => { + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + (Some((_, 1)), _) | (_, Some((_, 1))) => { + hip_call_cuda!(hipMemcpyParam2D(&memcpy3d_to_2d_layered(copy_desc))); + Ok(()) + } + _ => { + // hipDrvMemcpy3D does not respect pitch parameter if src or target is an array + let hip_copy_desc = memcpy3d_from_cuda(copy_desc)?; + if (hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeArray + || hip_copy_desc.dstMemoryType == hipMemoryType::hipMemoryTypeArray) + && (hip_copy_desc.dstPitch > hip_copy_desc.WidthInBytes + || hip_copy_desc.srcPitch > hip_copy_desc.WidthInBytes) + { + if hip_copy_desc.srcPitch > hip_copy_desc.WidthInBytes + && (hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeDevice + || hip_copy_desc.srcMemoryType == hipMemoryType::hipMemoryTypeHost) + && hip_copy_desc.dstMemoryType == hipMemoryType::hipMemoryTypeArray + { + if hip_copy_desc.srcXInBytes != 0 + || hip_copy_desc.srcY != 0 + || hip_copy_desc.srcZ != 0 + { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + if hip_copy_desc.dstXInBytes != 0 || hip_copy_desc.dstY != 0 { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + let mut temporary_buffer = ptr::null_mut(); + hip_call_cuda!(hipMalloc( + &mut temporary_buffer, + hip_copy_desc.WidthInBytes as usize + * hip_copy_desc.Height as usize + * hip_copy_desc.Depth as usize + )); + let mut reduce_pitch = hip_copy_desc.clone(); + reduce_pitch.dstMemoryType = hipMemoryType::hipMemoryTypeDevice; + reduce_pitch.dstDevice = hipDeviceptr_t(temporary_buffer); + reduce_pitch.dstArray = ptr::null_mut(); + reduce_pitch.dstZ = 0; + hip_call_cuda!(hipDrvMemcpy3D(&reduce_pitch)); + let mut final_copy = hip_copy_desc.clone(); + final_copy.srcMemoryType = hipMemoryType::hipMemoryTypeDevice; + final_copy.srcDevice = hipDeviceptr_t(temporary_buffer); + final_copy.srcPitch = final_copy.WidthInBytes; + hip_call_cuda!(hipDrvMemcpy3D(&final_copy)); + hip_call_cuda!(hipFree(temporary_buffer)); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + } else { + hip_call_cuda!(hipDrvMemcpy3D(&hip_copy_desc)); + Ok(()) + } + } + } + } + + fn memcpy3d_to_2d_layered(desc_3d: &CUDA_MEMCPY3D) -> hip_Memcpy2D { + hip_Memcpy2D { + srcXInBytes: desc_3d.srcXInBytes, + srcY: desc_3d.srcY, + srcMemoryType: memory_type_from_cuda(desc_3d.srcMemoryType), + srcHost: desc_3d.srcHost, + srcDevice: FromCuda::from_cuda(desc_3d.srcDevice), + srcArray: get(desc_3d.srcArray), + srcPitch: desc_3d.srcPitch, + dstXInBytes: desc_3d.dstXInBytes, + dstY: desc_3d.dstY, + dstMemoryType: memory_type_from_cuda(desc_3d.dstMemoryType), + dstHost: desc_3d.dstHost, + dstDevice: FromCuda::from_cuda(desc_3d.dstDevice), + dstArray: get(desc_3d.dstArray), + dstPitch: desc_3d.dstPitch, + WidthInBytes: desc_3d.WidthInBytes, + Height: desc_3d.Depth, + } + } + + fn get_array(type_: CUmemorytype, array: CUarray) -> Option<(hipArray_t, usize)> { + if type_ == CUmemorytype::CU_MEMORYTYPE_ARRAY { + let dims = get_layered_dimensions(array); + Some((get(array), dims)) + } else { + None + } + } +} + +// Somehow if we get a global with hipModuleGetGlobal and pass NULL as bytes, +// then this global is later unusable (e.g. copying to it returns +// CUDA_ERROR_INVALID_VALUE) +pub(crate) unsafe fn module_get_global( + dptr: *mut hipDeviceptr_t, + mut bytes: *mut usize, + hip_module: *mut ihipModule_t, + name: *const i8, +) -> hipError_t { + let mut unused = 0usize; + if bytes == ptr::null_mut() { + bytes = &mut unused; + } + hipModuleGetGlobal(dptr, bytes, hip_module, name) +} + +pub(crate) unsafe fn override_occupancy( + function: &FunctionData, + min_grid_size: *mut i32, + block_size: *mut i32, +) { + let block_size_override = if let Some((min_block_size, max_block_size)) = function.group_size { + if (*block_size as u32) < min_block_size { + Some(min_block_size as f64) + } else if (*block_size as u32) > max_block_size { + Some(max_block_size as f64) + } else { + None + } + } else { + None + }; + if let Some(new_block_size) = block_size_override { + let threads = (*min_grid_size as f64) * (*block_size as f64); + let grid_size = (threads / new_block_size).round(); + *min_grid_size = grid_size as i32; + *block_size = new_block_size as i32; + } +} + +pub(crate) fn validate_block_size( + function: &FunctionData, + block_dim_x: u32, + block_dim_y: u32, + block_dim_z: u32, +) -> Result<(), CUresult> { + if let Some((min_size, max_size)) = function.group_size { + let requested_size = block_dim_x * block_dim_y * block_dim_z; + if requested_size < min_size || requested_size > max_size { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + } + Ok(()) +} + +// HACK ALERT +// GeekBench expects device memory allocations to be zeroed out +// We would prefer to zero-out every buffer on allocation, but +// there is no way to zero-out device memory synchronously. +// cuMemset*/hipMemset* are not synchronous: +// (https://docs.nvidia.com/cuda/cuda-driver-api/api-sync-behavior.html#api-sync-behavior__memset) +pub(crate) fn should_zero_buffers() -> Option { + let path = env::current_exe().ok()?; + let name = path.file_name()?; + let s_name = name.to_str()?.to_ascii_lowercase(); + Some(s_name.contains("geekbench")) +} + +// As of ROCm ~5.6, if you call some OpenGL interop functions (hipGraphicsGLRegisterBuffer and such) without +// calling OpenGL interop functions first, you get failures due to OpenGL interop being uninitialized. +// Calling hipGLGetDevices(...) internally calls setupGLInteropOnce which sets up required interop: +// https://github.com/ROCm-Developer-Tools/clr/blob/5a0085e5166640b1a93822454aa6652335740de4/hipamd/src/hip_gl.cpp#L92C36-L92C54 +#[allow(unused_must_use)] +pub(crate) fn init_opengl() { + unsafe { hipGLGetDevices(ptr::null_mut(), ptr::null_mut(), 0, hipGLDeviceList(0)) }; +} + +// We round up all allocations to be multiple of 4. +// This helps with implementing cuMemsetD8_v2_ptds: +// right now in HIP there's no _spt for single byte memset, +// there's only one four byte one +pub(crate) fn alloc_round_up(bytesize: usize) -> usize { + ((bytesize + 3) / 4) * 4 +} + +// ┌────────────┬─────────────┐ +// │ Normal │ _ptds/_ptsz │ +// ┌────────────┼────────────┼─────────────┤ +// │ NULL │ legacy │ per-thread │ +// ├────────────┼────────────┼─────────────┤ +// │ legacy │ legacy │ legacy │ +// ├────────────┼────────────┼─────────────┤ +// │ per-thread │ per-thread │ per-thread │ +// └────────────┴────────────┴─────────────┘ +// Unfortunately, explicit legacy stream does not exist in HIP +// We need to call non-ptds functions if the legacy stream has been explicitly requested +pub(crate) fn as_default_stream_per_thread( + stream: *mut stream::Stream, + default_stream_per_thread: bool, +) -> Option { + match (stream, default_stream_per_thread) { + (stream::CU_STREAM_NULL, false) => Some(hipStreamNull), + (stream::CU_STREAM_NULL, true) => Some(hipStreamPerThread), + (stream::CU_STREAM_LEGACY, _) => Some(hipStreamNull), + (stream::CU_STREAM_PER_THREAD, _) => Some(hipStreamPerThread), + _ => None, + } +} + +pub(crate) unsafe fn as_hip_stream_per_thread( + stream: *mut stream::Stream, + default_stream_per_thread: bool, +) -> Result { + Ok( + match as_default_stream_per_thread(stream, default_stream_per_thread) { + Some(s) => s, + None => LiveCheck::as_result(stream)?.base, + }, + ) +} + +// I don't know why, but hipModuleOccupancyMaxActiveBlocksPerMultiprocessorWithFlags +// sometimes returns 0, which is clearly wrong +pub(crate) unsafe fn occupancy_max_potential_blocks_per_multiprocessor(num_blocks: *mut i32) { + *num_blocks = i32::max(*num_blocks, 1); +} diff --git a/zluda/src/impl/library.rs b/zluda/src/impl/library.rs new file mode 100644 index 0000000..6cc37c9 --- /dev/null +++ b/zluda/src/impl/library.rs @@ -0,0 +1,90 @@ +// Library is a module that is not context-bound, see here: +// https://developer.nvidia.com/blog/cuda-context-independent-module-loading/ +// It's supposed to be lazy-loaded for each device (depending on cuModuleGetLoadingMode(...)), +// but we do eager loading right now for simplicity +// TODO: make libraries lazy-loadable +use super::{ + context, fold_cuda_errors, + module::{self, ModuleData}, + LiveCheck, ZludaObject, GLOBAL_STATE, +}; +use cuda_types::{CUjit_option, CUlibraryOption, CUresult}; + +pub(crate) type Library = LiveCheck; + +impl ZludaObject for LibraryData { + #[cfg(target_pointer_width = "64")] + const LIVENESS_COOKIE: usize = 0x9769b2dd3d1764df; + #[cfg(target_pointer_width = "32")] + const LIVENESS_COOKIE: usize = 0xdbbdd7c7; + const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE; + + fn drop_with_result(&mut self, _by_owner: bool) -> Result<(), CUresult> { + fold_cuda_errors( + self.modules + .iter_mut() + .map(|module| unsafe { LiveCheck::drop_box_with_result(*module, true) }), + ) + } +} + +pub(crate) struct LibraryData { + modules: Vec<*mut module::Module>, +} + +pub(crate) unsafe fn load_data( + library: *mut *mut Library, + code: *const ::std::os::raw::c_void, + // TODO: start handling JIT options + _jit_options: *mut CUjit_option, + _jit_options_values: *mut *mut ::std::os::raw::c_void, + _num_jit_options: ::std::os::raw::c_uint, + library_options: *mut CUlibraryOption, + _library_option_values: *mut *mut ::std::os::raw::c_void, + num_library_options: ::std::os::raw::c_uint, +) -> Result<(), CUresult> { + for option in std::slice::from_raw_parts(library_options, num_library_options as usize) { + if !matches!(*option, CUlibraryOption::CU_LIBRARY_BINARY_IS_PRESERVED) { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + } + let global_state = GLOBAL_STATE.get()?; + let modules = global_state + .devices + .iter() + .map(|device| { + let module_data = module::load_data_any( + None, + device.compilation_mode, + &device.comgr_isa, + zluda_dark_api::CUmoduleContent::from_ptr(code.cast()) + .map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?, + )?; + Ok(ModuleData::alloc(module_data)) + }) + .collect::, _>>()?; + let library_data = LibraryData { modules }; + *library = Box::into_raw(Box::new(LiveCheck::new(library_data))); + Ok(()) +} + +pub(crate) unsafe fn get_module( + output: *mut *mut module::Module, + library: *mut Library, +) -> Result<(), CUresult> { + let library = LiveCheck::as_result(library)?; + context::with_current(|ctx| { + let device = ctx.device as usize; + let module = library + .modules + .get(device) + .copied() + .ok_or(CUresult::CUDA_ERROR_UNKNOWN)?; + *output = module; + Ok(()) + })? +} + +pub(crate) unsafe fn unload(library: *mut Library) -> Result<(), CUresult> { + LiveCheck::drop_box_with_result(library, false) +} diff --git a/zluda/src/impl/link.rs b/zluda/src/impl/link.rs new file mode 100644 index 0000000..9e31f52 --- /dev/null +++ b/zluda/src/impl/link.rs @@ -0,0 +1,112 @@ +use super::{context, module, LiveCheck, ZludaObject, GLOBAL_STATE}; +use cuda_types::*; +use std::{borrow::Cow, ptr, sync::Mutex}; + +pub(crate) type LinkState = LiveCheck; + +impl ZludaObject for LinkStateData { + #[cfg(target_pointer_width = "64")] + const LIVENESS_COOKIE: usize = 0x0f8acfce25ea71da; + #[cfg(target_pointer_width = "32")] + const LIVENESS_COOKIE: usize = 0x5f92e7dc; + const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE; + + fn drop_with_result(&mut self, _by_owner: bool) -> Result<(), CUresult> { + Ok(()) + } +} + +pub(crate) struct LinkStateData { + ptx_modules: Mutex>>, +} + +pub(crate) unsafe fn add_data( + state: *mut LinkState, + type_: CUjitInputType, + data: *mut ::std::os::raw::c_void, + mut size: usize, + _name: *const ::std::os::raw::c_char, + _num_options: ::std::os::raw::c_uint, + _options: *mut CUjit_option, + _option_values: *mut *mut ::std::os::raw::c_void, +) -> Result<(), CUresult> { + let state = LiveCheck::as_result(state)?; + match type_ { + CUjitInputType::CU_JIT_INPUT_PTX => { + let data = data.cast::(); + loop { + if *data.add(size - 1) == 0 { + size -= 1; + } else { + break; + } + } + let buffer = std::slice::from_raw_parts(data.cast::(), size); + let buffer = + std::str::from_utf8(buffer).map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?; + let ptx = buffer.to_string(); + let mut modules = state + .ptx_modules + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + modules.push(Cow::Owned(ptx)); + Ok(()) + } + // Right now only user of this data type is + // V-Ray, which passes CUDA Runtime archive + // that is not used anyway + CUjitInputType::CU_JIT_INPUT_LIBRARY => Ok(()), + _ => Err(CUresult::CUDA_ERROR_NOT_SUPPORTED), + } +} + +pub(crate) unsafe fn complete( + state: *mut LinkState, + cubin_out: *mut *mut ::std::os::raw::c_void, + size_out: *mut usize, +) -> Result<(), CUresult> { + if cubin_out == std::ptr::null_mut() || size_out == std::ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let state = LiveCheck::as_result(state)?; + let modules = state + .ptx_modules + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + let device = context::with_current(|ctx| ctx.device)?; + let global_state = GLOBAL_STATE.get()?; + let device_object = global_state.device(device)?; + let module = module::link_build_zluda_module( + global_state, + device_object.compilation_mode, + &device_object.comgr_isa, + &modules, + )?; + let module = module.into_boxed_slice(); + let size = module.len(); + let ptr = Box::into_raw(module); + *size_out = size; + *cubin_out = ptr.cast(); + Ok(()) +} + +pub(crate) unsafe fn create( + _num_options: ::std::os::raw::c_uint, + _options: *mut CUjit_option, + _option_values: *mut *mut ::std::os::raw::c_void, + state_out: *mut *mut LinkState, +) -> Result<(), CUresult> { + let link_state = LinkState::new(LinkStateData { + ptx_modules: Mutex::new(Vec::new()), + }); + let link_state = Box::into_raw(Box::new(link_state)); + *state_out = link_state; + Ok(()) +} + +pub(crate) unsafe fn destroy(state: *mut LinkState) -> Result<(), CUresult> { + if state == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + LiveCheck::drop_box_with_result(state, false) +} diff --git a/zluda/src/impl/memory.rs b/zluda/src/impl/memory.rs index f33a08c..41840b9 100644 --- a/zluda/src/impl/memory.rs +++ b/zluda/src/impl/memory.rs @@ -1,100 +1,218 @@ -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::() * 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::() * 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() { - 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::()), - CUresult::CUDA_ERROR_INVALID_CONTEXT - ); - assert_eq!(mem, ptr::null_mut()); - } - - cuda_driver_test!(alloc_with_ctx); - - fn alloc_with_ctx() { - 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::()), - 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() { - 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::()), - 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); - } -} +use super::stream::Stream; +use super::{hipfix, stream}; +use crate::hip_call_cuda; +use crate::r#impl::{memcpy2d_from_cuda, GLOBAL_STATE}; +use cuda_types::*; +use hip_runtime_sys::*; +use std::{mem, ptr}; + +pub(crate) unsafe fn alloc(dptr: *mut hipDeviceptr_t, mut bytesize: usize) -> Result<(), CUresult> { + if dptr == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let zero_buffers = GLOBAL_STATE.get()?.zero_buffers; + bytesize = hipfix::alloc_round_up(bytesize); + let mut ptr = mem::zeroed(); + hip_call_cuda!(hipMalloc(&mut ptr, bytesize)); + if zero_buffers { + hip_call_cuda!(hipMemsetD32(hipDeviceptr_t(ptr), 0, bytesize / 4)); + } + *dptr = hipDeviceptr_t(ptr); + Ok(()) +} + +pub(crate) unsafe fn copy_h_to_d_async( + dst_device: hipDeviceptr_t, + src_host: *const std::ffi::c_void, + byte_count: usize, + stream: *mut Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda!(hipMemcpyHtoDAsync( + dst_device, + src_host as _, + byte_count, + hip_stream + )); + Ok(()) +} + +pub(crate) unsafe fn copy_d_to_h_async( + dst_host: *mut ::std::os::raw::c_void, + src_device: hipDeviceptr_t, + byte_count: usize, + stream: *mut Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda!(hipMemcpyDtoHAsync( + dst_host, src_device, byte_count, hip_stream + )); + Ok(()) +} + +// TODO: just call hipMemGetAddressRange when HIP fixes handling of NULL args +pub(crate) unsafe fn get_address_range( + pbase: *mut hipDeviceptr_t, + psize: *mut usize, + dptr: hipDeviceptr_t, +) -> hipError_t { + let mut base = hipDeviceptr_t(ptr::null_mut()); + let mut size = 0; + let result = hipMemGetAddressRange(&mut base, &mut size, dptr); + if pbase != ptr::null_mut() { + *pbase = base; + } + if psize != ptr::null_mut() { + *psize = size; + } + result +} + +pub(crate) unsafe fn copy3d(copy: *const CUDA_MEMCPY3D) -> Result<(), CUresult> { + if let Some(copy_desc) = copy.as_ref() { + hipfix::array::copy3d(copy_desc) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} + +pub(crate) unsafe fn copy2d_async( + copy: *const CUDA_MEMCPY2D, + stream: *mut Stream, +) -> Result<(), CUresult> { + if let Some(copy) = copy.as_ref() { + let hip_stream = stream::as_hip_stream(stream)?; + let copy = memcpy2d_from_cuda(copy); + hip_call_cuda!(hipMemcpyParam2DAsync(©, hip_stream)); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} + +pub(crate) unsafe fn copy3d_async( + copy: *const CUDA_MEMCPY3D, + stream: *mut Stream, +) -> Result<(), CUresult> { + if let Some(copy) = copy.as_ref() { + let hip_stream = stream::as_hip_stream(stream)?; + hipfix::array::copy3d_async(hip_stream, copy)?; + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} + +pub(crate) unsafe fn copy2d(copy: *const CUDA_MEMCPY2D) -> hipError_t { + if let Some(copy) = copy.as_ref() { + let copy = memcpy2d_from_cuda(copy); + hipMemcpyParam2D(©) + } else { + hipError_t::hipErrorInvalidValue + } +} + +pub(crate) unsafe fn copy2d_unaligned(copy: *const CUDA_MEMCPY2D) -> hipError_t { + if let Some(copy) = copy.as_ref() { + let copy = memcpy2d_from_cuda(copy); + hipDrvMemcpy2DUnaligned(©) + } else { + hipError_t::hipErrorInvalidValue + } +} + +pub(crate) unsafe fn set_d8_async( + dst_device: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + n: usize, + stream: *mut stream::Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda!(hipMemsetD8Async(dst_device, uc, n, hip_stream)); + Ok(()) +} + +pub(crate) unsafe fn set_d32_async( + dst_device: hipDeviceptr_t, + uc: ::std::os::raw::c_uint, + n: usize, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let hip_stream = stream::as_hip_stream(stream)?; + hip_call_cuda!(hipMemsetD32Async(dst_device, uc as i32, n, hip_stream)); + Ok(()) +} + +pub(crate) unsafe fn host_get_device_pointer( + pdptr: *mut hipDeviceptr_t, + p: *mut ::std::os::raw::c_void, + flags: ::std::os::raw::c_uint, +) -> hipError_t { + hipHostGetDevicePointer(pdptr as _, p, flags) +} + +pub(crate) unsafe fn copy_dtd_async( + dst_device: hipDeviceptr_t, + src_device: hipDeviceptr_t, + byte_count: usize, + stream: *mut stream::Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda!(hipMemcpyDtoDAsync( + dst_device, src_device, byte_count, hip_stream + )); + Ok(()) +} + +pub(crate) unsafe fn copy_async( + dst: hipDeviceptr_t, + src: hipDeviceptr_t, + byte_count: usize, + h_stream: *mut stream::Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(h_stream, default_stream_per_thread)?; + hip_call_cuda!(hipMemcpyAsync( + dst.0, + src.0, + byte_count, + hipMemcpyKind::hipMemcpyDefault, + hip_stream + )); + Ok(()) +} + +pub(crate) unsafe fn free_async( + dptr: hipDeviceptr_t, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let hip_stream = stream::as_hip_stream(stream)?; + hip_call_cuda! { hipFreeAsync(dptr.0, hip_stream) }; + Ok(()) +} + +pub(crate) unsafe fn prefetch_async( + dev_ptr: hipDeviceptr_t, + count: usize, + dst_device: hipDevice_t, + stream: *mut stream::Stream, +) -> Result<(), CUresult> { + let hip_stream = stream::as_hip_stream(stream)?; + hip_call_cuda! { hipMemPrefetchAsync(dev_ptr.0, count, dst_device, hip_stream) }; + Ok(()) +} + +pub(crate) unsafe fn set_d8_ptds( + dst_device: hipDeviceptr_t, + uc: ::std::os::raw::c_uchar, + byte_size: usize, +) -> hipError_t { + let byte_size = hipfix::alloc_round_up(byte_size); + let int_size = byte_size / 4; + let value = i32::from_ne_bytes([uc, uc, uc, uc]); + hipMemset_spt(dst_device.0, value, int_size) +} diff --git a/zluda/src/impl/mod.rs b/zluda/src/impl/mod.rs index 67b3e2b..88a95c4 100644 --- a/zluda/src/impl/mod.rs +++ b/zluda/src/impl/mod.rs @@ -1,38 +1,115 @@ -use crate::{ - cuda::{CUctx_st, CUdevice, CUdeviceptr, CUfunc_st, CUmod_st, CUresult, CUstream_st}, - r#impl::device::Device, -}; +use comgr::{sys::amd_comgr_status_t, Comgr}; +use cuda_types::*; +use hip_runtime_sys::*; +use memoffset::offset_of; +use static_assertions::assert_impl_one; use std::{ - ffi::c_void, - mem::{self, ManuallyDrop}, - os::raw::c_int, - ptr, - sync::Mutex, - sync::TryLockError, + cell::Cell, + ffi::{c_void, CStr}, + fs, + mem::{self, ManuallyDrop, MaybeUninit}, + ptr::{self, NonNull}, + sync::{atomic::AtomicI32, Once}, }; -#[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; +use self::cache::KernelCache; + +pub(crate) mod array; +pub(crate) mod cache; +pub(crate) mod context; +pub(crate) mod dark_api; +pub(crate) mod device; +pub(crate) mod function; +pub(crate) mod gl; +pub(crate) mod graph; +pub(crate) mod hipfix; +pub(crate) mod library; +pub(crate) mod link; +pub(crate) mod memory; +pub(crate) mod module; +#[cfg_attr(windows, path = "os_win.rs")] +#[cfg_attr(not(windows), path = "os_unix.rs")] +pub(crate) mod os; +pub(crate) mod pointer; +pub(crate) mod stream; +pub(crate) mod surface; +pub(crate) mod surfref; +pub(crate) mod texobj; +pub(crate) mod texref; #[cfg(debug_assertions)] -pub fn unimplemented() -> CUresult { +pub(crate) fn unimplemented() -> cuda_types::CUresult { unimplemented!() } #[cfg(not(debug_assertions))] -pub fn unimplemented() -> CUresult { - CUresult::CUDA_ERROR_NOT_SUPPORTED +pub(crate) fn unimplemented() -> cuda_types::CUresult { + cuda_types::CUresult::CUDA_ERROR_NOT_SUPPORTED } -pub trait HasLivenessCookie: Sized { +#[macro_export] +macro_rules! hip_call { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(err); + } + } + }; +} + +#[macro_export] +macro_rules! hip_call_cuda { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + use crate::r#impl::IntoCuda; + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(err.into_cuda()); + } + } + }; +} + +static GLOBAL_STATE: Lazy = Lazy::INIT; + +pub(crate) struct GlobalState { + pub(crate) devices: Vec, + _dark_api_heap: *mut c_void, + pub(crate) kernel_cache: Option, + pub(crate) comgr: Comgr, + pub(crate) comgr_version: String, + pub(crate) zero_buffers: bool, +} +assert_impl_one!(GlobalState: Sync); + +impl GlobalState { + pub(crate) fn device(&self, device: hipDevice_t) -> Result<&device::Device, CUresult> { + if device < 0 || device as usize >= self.devices.len() { + Err(CUresult::CUDA_ERROR_INVALID_DEVICE) + } else { + Ok(&self.devices[device as usize]) + } + } +} + +unsafe impl Sync for GlobalState {} + +pub(crate) trait ZludaObject: Sized { + const LIVENESS_COOKIE: usize; + const LIVENESS_FAIL: CUresult; + // This function exists to support "drop-with-return-value" + // By default Drop returns nothing, while we want to signal that e.g. + // cuCtxDestroy returned an error destroying underlying resources + // * by_owner patameter tells us if the drop comes from CUDA owner + // (typically context), in this cane we must skip deregistration + fn drop_with_result(&mut self, by_owner: bool) -> Result<(), CUresult>; +} + +pub(crate) trait HasLivenessCookie: Sized { const COOKIE: usize; const LIVENESS_FAIL: CUresult; @@ -42,64 +119,55 @@ pub trait HasLivenessCookie: Sized { // 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 { +pub(crate) struct LiveCheck { cookie: usize, data: ManuallyDrop, } -impl LiveCheck { +impl LiveCheck { pub fn new(data: T) -> Self { LiveCheck { - cookie: T::COOKIE, + cookie: T::LIVENESS_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) }; + pub unsafe fn drop_box_with_result(this: *mut Self, by_owner: bool) -> Result<(), CUresult> { + (&mut *this).try_drop(by_owner)?; + drop(Box::from_raw(this)); Ok(()) } - unsafe fn ptr_from_inner(this: *mut T) -> *mut Self { - let outer_ptr = (this as *mut u8).sub(mem::size_of::()); + unsafe fn from_ref(this: &T) -> NonNull { + NonNull::new_unchecked(Self::from_raw(this as *const T as *mut T)) + } + + unsafe fn from_raw(this: *mut T) -> *mut Self { + let offset = offset_of!(Self, data); + let outer_ptr = (this as *mut u8).wrapping_sub(offset); outer_ptr as *mut Self } - pub unsafe fn as_ref_unchecked(&self) -> &T { - &self.data + pub unsafe fn as_mut_unchecked(&mut self) -> &mut T { + &mut self.data } - pub fn as_option_mut(&mut self) -> Option<&mut T> { - if self.cookie == T::COOKIE { - Some(&mut self.data) - } else { - None + pub unsafe fn as_result<'a>(this: *mut Self) -> Result<&'a T, CUresult> { + if this == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); } - } - - 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) + if (*this).cookie == T::LIVENESS_COOKIE { + Ok(&(*this).data) } else { Err(T::LIVENESS_FAIL) } } #[must_use] - pub fn try_drop(&mut self) -> Result<(), CUresult> { - if self.cookie == T::COOKIE { + pub fn try_drop(&mut self, by_owner: bool) -> Result<(), CUresult> { + if self.cookie == T::LIVENESS_COOKIE { self.cookie = 0; - self.data.try_drop()?; + self.data.drop_with_result(by_owner)?; unsafe { ManuallyDrop::drop(&mut self.data) }; return Ok(()); } @@ -107,349 +175,344 @@ impl LiveCheck { } } -impl Drop for LiveCheck { +impl Drop for LiveCheck { fn drop(&mut self) { self.cookie = 0; } } -pub trait CudaRepr: Sized { - type Impl: Sized; -} - -impl CudaRepr for *mut T { - type Impl = *mut T::Impl; -} - -pub trait Decuda { - fn decuda(self: Self) -> To; -} - -impl Decuda<*mut T::Impl> for *mut T { - fn decuda(self: Self) -> *mut T::Impl { - self as *mut _ +pub(crate) trait FromCuda: Sized { + fn from_cuda(t: T) -> Self { + unsafe { mem::transmute_copy(&t) } } } -impl From 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 +impl FromCuda for i8 {} +impl FromCuda for u8 {} +impl FromCuda for u16 {} +impl FromCuda for i32 {} +impl FromCuda for u32 {} +impl FromCuda for f32 {} +impl FromCuda for usize {} +impl FromCuda for u64 {} +impl FromCuda for CUuuid {} +impl FromCuda for CUdevice_attribute {} +impl FromCuda for CUdevprop {} +impl FromCuda for CUlimit {} +impl FromCuda for CUfunc_cache {} +impl FromCuda for CUjit_option {} +impl FromCuda for CUfunction_attribute {} +// Same layout, but if it's a an array resource it needs an adjustment in hipfix +impl FromCuda for CUDA_MEMCPY2D {} +impl FromCuda for CUDA_MEMCPY3D {} +impl FromCuda for CUDA_ARRAY3D_DESCRIPTOR {} +impl FromCuda for c_void {} +impl FromCuda for CUarray {} +impl FromCuda for CUhostFn {} +impl FromCuda for CUoccupancyB2DSize {} +impl FromCuda for CUdriverProcAddressQueryResult_enum {} +impl FromCuda for CUmoduleLoadingMode {} +impl FromCuda for CUlibraryOption {} +impl FromCuda for CUDA_KERNEL_NODE_PARAMS_v1 {} +impl FromCuda for CUjitInputType {} +impl FromCuda for CUDA_RESOURCE_DESC {} + +impl FromCuda for *mut context::Context {} +impl FromCuda for *mut stream::Stream {} +impl FromCuda for hipDevice_t {} +impl FromCuda for hipDeviceptr_t {} +impl FromCuda for *mut module::Module {} +impl FromCuda for *mut library::Library {} +impl FromCuda for *mut function::Function {} +impl FromCuda for *mut link::LinkState {} +impl FromCuda for *mut textureReference {} +impl FromCuda for *mut textureReference {} +impl FromCuda for hipEvent_t {} +impl FromCuda for hipTextureObject_t {} +impl FromCuda for hipMemPool_t {} +// values are compatible +impl FromCuda for hipStreamCaptureStatus {} +// values are compatible +impl FromCuda for hipMemPoolAttr {} +// values are compatible +impl FromCuda for hipPointer_attribute {} +impl FromCuda for hipFunction_attribute {} +impl FromCuda for hipTextureFilterMode {} +impl FromCuda for hipTextureAddressMode {} +impl FromCuda for hipArray_Format {} +impl FromCuda for HIP_ARRAY_DESCRIPTOR {} +impl FromCuda for HIP_ARRAY3D_DESCRIPTOR {} +// Same layout, but if it's a an array resource it needs an adjustment in hipfix +// impl FromCuda for HIP_RESOURCE_DESC {} +impl FromCuda for HIP_TEXTURE_DESC {} +impl FromCuda for HIP_RESOURCE_VIEW_DESC {} +impl FromCuda for hipFuncCache_t {} +impl FromCuda for hipGraph_t {} +impl FromCuda for hipGraphNode_t {} +impl FromCuda for hipGraphExec_t {} +impl FromCuda for hipGraphicsResource_t {} +impl FromCuda for hipLimit_t {} +impl FromCuda for hipSurfaceObject_t {} + +impl> FromCuda<*mut From> for *mut Into {} +impl> FromCuda<*const From> for *const Into {} + +pub(crate) fn memcpy2d_from_cuda(this: &CUDA_MEMCPY2D) -> hip_Memcpy2D { + hip_Memcpy2D { + srcXInBytes: this.srcXInBytes, + srcY: this.srcY, + srcMemoryType: memory_type_from_cuda(this.srcMemoryType), + srcHost: this.srcHost, + srcDevice: FromCuda::from_cuda(this.srcDevice), + srcArray: hipfix::array::get(this.srcArray), + srcPitch: this.srcPitch, + dstXInBytes: this.dstXInBytes, + dstY: this.dstY, + dstMemoryType: memory_type_from_cuda(this.dstMemoryType), + dstHost: this.dstHost, + dstDevice: FromCuda::from_cuda(this.dstDevice), + dstArray: hipfix::array::get(this.dstArray), + dstPitch: this.dstPitch, + WidthInBytes: this.WidthInBytes, + Height: this.Height, + } +} + +#[macro_export] +macro_rules! try_downcast { + ($expr:expr, $type_from:ty => $type_to:ty) => {{ + { + let value = $expr; + if value <= (<$type_to>::MAX as $type_from) { + value as $type_to + } else { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); } - l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_ENUMERATION - | l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_ARGUMENT - | l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION - | l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION => { - 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, } + }}; +} + +#[allow(non_snake_case)] +pub(crate) fn memcpy3d_from_cuda(this: &CUDA_MEMCPY3D) -> Result { + // TODO: remove the casts when HIP fixes it + let srcXInBytes = try_downcast!(this.srcXInBytes, usize => u32); + let srcY = try_downcast!(this.srcY, usize => u32); + let srcZ = try_downcast!(this.srcZ, usize => u32); + let srcLOD = try_downcast!(this.srcLOD, usize => u32); + let srcPitch = try_downcast!(this.srcPitch, usize => u32); + let srcHeight = try_downcast!(this.srcHeight, usize => u32); + let dstXInBytes = try_downcast!(this.dstXInBytes, usize => u32); + let dstY = try_downcast!(this.dstY, usize => u32); + let dstZ = try_downcast!(this.dstZ, usize => u32); + let dstLOD = try_downcast!(this.dstLOD, usize => u32); + let dstPitch = try_downcast!(this.dstPitch, usize => u32); + let dstHeight = try_downcast!(this.dstHeight, usize => u32); + let WidthInBytes = try_downcast!(this.WidthInBytes, usize => u32); + let Height = try_downcast!(this.Height, usize => u32); + let Depth = try_downcast!(this.Depth, usize => u32); + Ok(HIP_MEMCPY3D { + srcXInBytes, + srcY, + srcZ, + srcLOD, + srcMemoryType: memory_type_from_cuda(this.srcMemoryType), + srcHost: this.srcHost, + srcDevice: FromCuda::from_cuda(this.srcDevice), + srcArray: hipfix::array::get(this.srcArray), + srcPitch, + srcHeight, + dstXInBytes, + dstY, + dstZ, + dstLOD, + dstMemoryType: memory_type_from_cuda(this.dstMemoryType), + dstHost: this.dstHost, + dstDevice: FromCuda::from_cuda(this.dstDevice), + dstArray: hipfix::array::get(this.dstArray), + dstPitch, + dstHeight, + WidthInBytes, + Height, + Depth, + }) +} + +pub(crate) fn memory_type_from_cuda(this: CUmemorytype) -> hipMemoryType { + match this { + CUmemorytype::CU_MEMORYTYPE_HOST => hipMemoryType::hipMemoryTypeHost, + CUmemorytype::CU_MEMORYTYPE_DEVICE => hipMemoryType::hipMemoryTypeDevice, + CUmemorytype::CU_MEMORYTYPE_ARRAY => hipMemoryType::hipMemoryTypeArray, + CUmemorytype::CU_MEMORYTYPE_UNIFIED => hipMemoryType::hipMemoryTypeUnified, + CUmemorytype(val) => hipMemoryType(val - 1), } } -impl From> for CUresult { - fn from(_: TryLockError) -> Self { - CUresult::CUDA_ERROR_ILLEGAL_STATE +impl FromCuda for hipError_t { + fn from_cuda(this: CUresult) -> hipError_t { + hipError_t(this.0) } } -pub trait Encuda { - type To: Sized; - fn encuda(self: Self) -> Self::To; +pub(crate) trait IntoCuda { + fn into_cuda(self) -> CUresult; } -impl Encuda for CUresult { - type To = CUresult; - fn encuda(self: Self) -> Self::To { +impl IntoCuda for CUresult { + fn into_cuda(self) -> CUresult { 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 { +impl IntoCuda for () { + fn into_cuda(self) -> CUresult { CUresult::CUDA_SUCCESS } } -impl, T2: Encuda> Encuda for Result { - type To = CUresult; - fn encuda(self: Self) -> Self::To { +pub(crate) fn comgr_error_to_cuda(this: amd_comgr_status_t) -> CUresult { + match this { + amd_comgr_status_t::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT => { + CUresult::CUDA_ERROR_INVALID_VALUE + } + amd_comgr_status_t::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES => { + CUresult::CUDA_ERROR_OUT_OF_MEMORY + } + _ => CUresult::CUDA_ERROR_UNKNOWN, + } +} + +impl IntoCuda for Result { + fn into_cuda(self) -> CUresult { match self { - Ok(e) => e.encuda(), - Err(e) => e.encuda(), + Ok(e) => e.into_cuda(), + Err(e) => e.into_cuda(), } } } -lazy_static! { - static ref GLOBAL_STATE: Mutex> = Mutex::new(None); -} - -struct GlobalState { - devices: Vec, -} - -unsafe impl Send for GlobalState {} - -impl GlobalState { - fn lock(f: impl FnOnce(&mut GlobalState) -> T) -> Result { - 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( - device::Index(dev_idx): device::Index, - f: impl FnOnce(&'static mut device::Device) -> T, - ) -> Result { - 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 R, R>( - f: F, - ) -> Result { - Self::lock_current_context_unchecked(|ctx| Ok(f(ctx.as_result_mut()?)))? - } - - fn lock_current_context_unchecked R, R>( - f: F, - ) -> Result { - 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( - stream: *mut stream::Stream, - f: impl FnOnce(&mut stream::StreamData) -> T, - ) -> Result { - 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)))? +impl IntoCuda for hipError_t { + fn into_cuda(self) -> CUresult { + if self.0 >= hipError_t::hipErrorUnknown.0 { + CUresult::CUDA_ERROR_UNKNOWN } else { - Self::lock(|_| { - let stream = unsafe { &mut *stream }.as_result_mut()?; - Ok(f(stream)) - })? + CUresult(self.0 as i32) } } - - fn lock_function( - func: *mut function::Function, - f: impl FnOnce(&mut function::FunctionData) -> T, - ) -> Result { - 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 +fn fold_cuda_errors(iter: impl Iterator>) -> Result<(), CUresult> { + iter.fold(Ok(()), Result::and) } -pub fn init() -> Result<(), CUresult> { - let mut global_state = GLOBAL_STATE - .lock() - .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; - if global_state.is_some() { +// very similar to lazy_static implementation, but more suitable to our use +struct Lazy { + once: Once, + value: Cell>, +} + +unsafe impl Sync for Lazy {} + +impl Lazy { + const INIT: Self = Lazy { + once: Once::new(), + value: Cell::new(MaybeUninit::uninit()), + }; + + fn init(&self, ctor: impl FnOnce() -> T) { + self.once.call_once(|| { + self.value.set(MaybeUninit::new(ctor())); + }); + } + + fn is_initalized(&self) -> bool { + self.once.is_completed() + } + + fn get<'a>(&'a self) -> Result<&'a T, CUresult> { + if self.once.is_completed() { + Ok(unsafe { &*(&*self.value.as_ptr()).as_ptr() }) + } else { + Err(CUresult::CUDA_ERROR_NOT_INITIALIZED) + } + } +} + +pub(crate) fn init(flags: u32) -> Result<(), CUresult> { + if GLOBAL_STATE.is_initalized() { 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); + let comgr = Comgr::find_and_load().map_err(comgr_error_to_cuda)?; + let comgr_version = comgr.version().map_err(comgr_error_to_cuda)?; + hip_call_cuda!(hipInit(flags)); + let mut dev_count = 0; + hip_call_cuda!(hipGetDeviceCount(&mut dev_count)); + let devices = (0..dev_count as usize) + .map(|index| device::Device::new(index)) + .collect::, _>>()?; + let global_heap = unsafe { os::heap_create() }; + if global_heap == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_OUT_OF_MEMORY); + } + let kernel_cache = create_default_cache(); + let zero_buffers = hipfix::should_zero_buffers().unwrap_or(false); + GLOBAL_STATE.init(|| GlobalState { + devices, + kernel_cache, + _dark_api_heap: global_heap, + comgr, + comgr_version, + zero_buffers, + }); Ok(()) } -macro_rules! stringify_curesult { - ($x:ident => [ $($variant:ident),+ ]) => { - match $x { - $( - CUresult::$variant => Some(concat!(stringify!($variant), "\0")), - )+ - _ => None - } - } +fn create_default_cache() -> Option { + let mut disk_cache_location = dirs::cache_dir()?; + disk_cache_location.push("ZLUDA"); + disk_cache_location.push("ComputeCache"); + fs::create_dir_all(&disk_cache_location).ok()?; + KernelCache::new(&disk_cache_location) } -pub(crate) fn get_error_string(error: CUresult, str: *mut *const i8) -> CUresult { - if str == ptr::null_mut() { +pub(crate) static MAXIMUM_PROC_VERSION: AtomicI32 = AtomicI32::new(0); + +pub(crate) unsafe fn get_proc_address_v2( + symbol: *const ::std::os::raw::c_char, + pfn: *mut *mut ::std::os::raw::c_void, + cuda_version: ::std::os::raw::c_int, + flags: cuuint64_t, + symbol_status: *mut CUdriverProcAddressQueryResult, +) -> CUresult { + if symbol == ptr::null() || pfn == ptr::null_mut() { return CUresult::CUDA_ERROR_INVALID_VALUE; } - let text = stringify_curesult!( - error => [ - CUDA_SUCCESS, - CUDA_ERROR_INVALID_VALUE, - CUDA_ERROR_OUT_OF_MEMORY, - CUDA_ERROR_NOT_INITIALIZED, - CUDA_ERROR_DEINITIALIZED, - CUDA_ERROR_PROFILER_DISABLED, - CUDA_ERROR_PROFILER_NOT_INITIALIZED, - CUDA_ERROR_PROFILER_ALREADY_STARTED, - CUDA_ERROR_PROFILER_ALREADY_STOPPED, - CUDA_ERROR_NO_DEVICE, - CUDA_ERROR_INVALID_DEVICE, - CUDA_ERROR_INVALID_IMAGE, - CUDA_ERROR_INVALID_CONTEXT, - CUDA_ERROR_CONTEXT_ALREADY_CURRENT, - CUDA_ERROR_MAP_FAILED, - CUDA_ERROR_UNMAP_FAILED, - CUDA_ERROR_ARRAY_IS_MAPPED, - CUDA_ERROR_ALREADY_MAPPED, - CUDA_ERROR_NO_BINARY_FOR_GPU, - CUDA_ERROR_ALREADY_ACQUIRED, - CUDA_ERROR_NOT_MAPPED, - CUDA_ERROR_NOT_MAPPED_AS_ARRAY, - CUDA_ERROR_NOT_MAPPED_AS_POINTER, - CUDA_ERROR_ECC_UNCORRECTABLE, - CUDA_ERROR_UNSUPPORTED_LIMIT, - CUDA_ERROR_CONTEXT_ALREADY_IN_USE, - CUDA_ERROR_PEER_ACCESS_UNSUPPORTED, - CUDA_ERROR_INVALID_PTX, - CUDA_ERROR_INVALID_GRAPHICS_CONTEXT, - CUDA_ERROR_NVLINK_UNCORRECTABLE, - CUDA_ERROR_JIT_COMPILER_NOT_FOUND, - CUDA_ERROR_INVALID_SOURCE, - CUDA_ERROR_FILE_NOT_FOUND, - CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND, - CUDA_ERROR_SHARED_OBJECT_INIT_FAILED, - CUDA_ERROR_OPERATING_SYSTEM, - CUDA_ERROR_INVALID_HANDLE, - CUDA_ERROR_ILLEGAL_STATE, - CUDA_ERROR_NOT_FOUND, - CUDA_ERROR_NOT_READY, - CUDA_ERROR_ILLEGAL_ADDRESS, - CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES, - CUDA_ERROR_LAUNCH_TIMEOUT, - CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING, - CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED, - CUDA_ERROR_PEER_ACCESS_NOT_ENABLED, - CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE, - CUDA_ERROR_CONTEXT_IS_DESTROYED, - CUDA_ERROR_ASSERT, - CUDA_ERROR_TOO_MANY_PEERS, - CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED, - CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED, - CUDA_ERROR_HARDWARE_STACK_ERROR, - CUDA_ERROR_ILLEGAL_INSTRUCTION, - CUDA_ERROR_MISALIGNED_ADDRESS, - CUDA_ERROR_INVALID_ADDRESS_SPACE, - CUDA_ERROR_INVALID_PC, - CUDA_ERROR_LAUNCH_FAILED, - CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE, - CUDA_ERROR_NOT_PERMITTED, - CUDA_ERROR_NOT_SUPPORTED, - CUDA_ERROR_SYSTEM_NOT_READY, - CUDA_ERROR_SYSTEM_DRIVER_MISMATCH, - CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE, - CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED, - CUDA_ERROR_STREAM_CAPTURE_INVALIDATED, - CUDA_ERROR_STREAM_CAPTURE_MERGE, - CUDA_ERROR_STREAM_CAPTURE_UNMATCHED, - CUDA_ERROR_STREAM_CAPTURE_UNJOINED, - CUDA_ERROR_STREAM_CAPTURE_ISOLATION, - CUDA_ERROR_STREAM_CAPTURE_IMPLICIT, - CUDA_ERROR_CAPTURED_EVENT, - CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD, - CUDA_ERROR_TIMEOUT, - CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE, - CUDA_ERROR_UNKNOWN - ] - ); - match text { - Some(text) => { - unsafe { *str = text.as_ptr() as *const _ }; - CUresult::CUDA_SUCCESS - } - None => CUresult::CUDA_ERROR_INVALID_VALUE, + MAXIMUM_PROC_VERSION.fetch_max(cuda_version, std::sync::atomic::Ordering::SeqCst); + let symbol = unsafe { CStr::from_ptr(symbol) }; + let fn_ptr = get_proc_address(symbol.to_bytes(), flags, cuda_version as u32); + let (status, result) = if fn_ptr == ptr::null_mut() { + ( + CUdriverProcAddressQueryResult::CU_GET_PROC_ADDRESS_SYMBOL_NOT_FOUND, + CUresult::CUDA_ERROR_NOT_FOUND, + ) + } else if fn_ptr == usize::MAX as _ { + ( + CUdriverProcAddressQueryResult::CU_GET_PROC_ADDRESS_VERSION_NOT_SUFFICIENT, + CUresult::CUDA_ERROR_NOT_FOUND, + ) + } else { + *pfn = fn_ptr; + ( + CUdriverProcAddressQueryResult::CU_GET_PROC_ADDRESS_SUCCESS, + CUresult::CUDA_SUCCESS, + ) + }; + if let Some(symbol_status) = symbol_status.as_mut() { + *symbol_status = status; } + result } -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 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; +fn get_proc_address(name: &[u8], flag: u64, version: u32) -> *mut ::std::os::raw::c_void { + use crate::cuda::*; + include!("../../../process_address_table/table.rs") } diff --git a/zluda/src/impl/module.rs b/zluda/src/impl/module.rs index 98580f8..6a6911a 100644 --- a/zluda/src/impl/module.rs +++ b/zluda/src/impl/module.rs @@ -1,205 +1,468 @@ -use std::{ - collections::hash_map, collections::HashMap, ffi::c_void, ffi::CStr, ffi::CString, mem, - os::raw::c_char, ptr, slice, -}; +use super::context::Context; +use super::{context, function, LiveCheck, ZludaObject}; +use crate::hip_call_cuda; +use crate::r#impl::function::FunctionData; +use crate::r#impl::{comgr_error_to_cuda, device, hipfix, GLOBAL_STATE}; +use cuda_types::{CUmoduleLoadingMode, CUresult}; +use hip_common::CompilationMode; +use hip_runtime_sys::*; +use ptx::ModuleParserExt; +use rustc_hash::FxHashMap; +use std::borrow::Cow; +use std::cmp; +use std::collections::hash_map; +use std::ffi::{CStr, CString}; +use std::ptr::{self, NonNull}; +use std::sync::Mutex; +use zluda_dark_api::{CUmoduleContent, FatbinFileKind}; -use super::{ - device, - function::Function, - function::{FunctionData, LegacyArguments}, - CUresult, GlobalState, HasLivenessCookie, LiveCheck, -}; -use ptx; +const EMPTY_MODULE: &'static str = include_str!("empty_module.ptx"); -pub type Module = LiveCheck; +pub(crate) type Module = LiveCheck; -impl HasLivenessCookie for ModuleData { +impl ZludaObject for ModuleData { #[cfg(target_pointer_width = "64")] - const COOKIE: usize = 0xf1313bd46505f98a; - + const LIVENESS_COOKIE: usize = 0xe522cee57bd3cd26; #[cfg(target_pointer_width = "32")] - const COOKIE: usize = 0xbdbe3f15; - + const LIVENESS_COOKIE: usize = 0x5f39cc5b; 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, -} - -pub struct SpirvModule { - pub binaries: Vec, - pub kernel_info: HashMap, - pub should_link_ptx_impl: Option<&'static [u8]>, - pub build_options: CString, -} - -pub struct CompiledModule { - pub base: l0::Module, - pub kernels: HashMap>, -} - -impl From> for CUresult { - fn from(_: ptx::ParseError) -> Self { - CUresult::CUDA_ERROR_INVALID_PTX - } -} - -impl From for CUresult { - fn from(_: ptx::TranslateError) -> Self { - CUresult::CUDA_ERROR_INVALID_PTX - } -} - -impl SpirvModule { - pub fn new_raw<'a>(text: *const c_char) -> Result { - 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 { - 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 { - let byte_il = unsafe { - slice::from_raw_parts( - self.binaries.as_ptr() as *const u8, - self.binaries.len() * mem::size_of::(), - ) - }; - 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())) - } - Some(ptx_impl) => { - l0::Module::build_link_spirv( - ctx, - &dev, - &[ptx_impl, byte_il], - Some(self.build_options.as_c_str()), - ) - .0 + fn drop_with_result(&mut self, by_owner: bool) -> Result<(), CUresult> { + let deregistration_err = if !by_owner { + if let Some(ctx) = self.owner { + let ctx = unsafe { LiveCheck::as_result(ctx.as_ptr())? }; + let mut ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + ctx_mutable + .modules + .remove(&unsafe { LiveCheck::from_raw(self) }); } + Ok(()) + } else { + Ok(()) }; - Ok(l0_module?) + // Crashes HIP in 5.6 and 5.7.1 + //deregistration_err.and(unsafe { hipModuleUnload(self.base) }.into_cuda().into()) + deregistration_err } } -pub fn get_function( - hfunc: *mut *mut Function, - hmod: *mut Module, - name: *const c_char, +pub(crate) struct ModuleData { + // If module is part of a library, then there's no owning context + pub(crate) owner: Option>, + pub(crate) base: hipModule_t, + functions: Mutex>>, + sm_version: u32, + device_version: u32, + hipfix_max_group_sizes: FxHashMap, + compilation_mode: CompilationMode, +} + +impl ModuleData { + pub(crate) unsafe fn alloc(self) -> *mut Module { + Box::into_raw(Box::new(Module::new(self))) + } +} + +pub(crate) unsafe fn load(module: *mut *mut Module, fname: *const i8) -> Result<(), CUresult> { + if fname == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + load_impl(module, CUmoduleContent::File(fname)) +} + +pub(crate) unsafe fn load_data( + module: *mut *mut Module, + image: *const ::std::os::raw::c_void, ) -> Result<(), CUresult> { - if hfunc == ptr::null_mut() || hmod == ptr::null_mut() || name == ptr::null() { + if image == ptr::null_mut() { 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) + load_impl( + module, + CUmoduleContent::from_ptr(image.cast()).map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?, + ) +} + +pub(crate) unsafe fn load_impl( + output: *mut *mut Module, + input: CUmoduleContent, +) -> Result<(), CUresult> { + if output == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + context::with_current(|ctx| { + let device = ctx.device; + let device = GLOBAL_STATE.get()?.device(device)?; + let isa = &device.comgr_isa; + let owner = LiveCheck::from_ref(ctx); + let module = ModuleData::alloc(load_data_any( + Some(owner), + device.compilation_mode, + isa, + input, + )?); + let mut ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + ctx_mutable.modules.insert(module); + *output = module; + Ok(()) + })? +} + +unsafe fn link_build_or_load_cuda_module( + global_state: &super::GlobalState, + compilation_mode: CompilationMode, + isa: &CStr, + input: CUmoduleContent, +) -> Result, CUresult> { + match input { + CUmoduleContent::Elf(ptr) => Ok(Cow::Borrowed(hip_common::elf::as_slice(ptr))), + CUmoduleContent::Archive(..) => return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED), + CUmoduleContent::RawText(ptr) => { + let ptx = CStr::from_ptr(ptr.cast()) + .to_str() + .map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?; + link_build_zluda_module(global_state, compilation_mode, isa, &[Cow::Borrowed(ptx)]) + .map(Cow::Owned) + } + CUmoduleContent::File(file) => { + let name = CStr::from_ptr(file) + .to_str() + .map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?; + let ptx = + std::fs::read_to_string(name).map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?; + link_build_zluda_module(global_state, compilation_mode, isa, &[Cow::Owned(ptx)]) + .map(Cow::Owned) + } + CUmoduleContent::Fatbin(files) => match files { + zluda_dark_api::CudaFatbin::Version1(module) => { + link_build_or_load_fatbin_module(global_state, compilation_mode, isa, module) + .map(Cow::Owned) } - }; - 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()) + zluda_dark_api::CudaFatbin::Version2 { + post_link, + pre_link, + } => { + if let Ok(binary) = + link_build_or_load_fatbin_module(global_state, compilation_mode, isa, post_link) + { + return Ok(Cow::Owned(binary)); + } + let ptx_files = pre_link + .iter() + .map(|module| { + let module = unsafe { module.get() } + .map_err(|_| CUresult::CUDA_ERROR_NOT_SUPPORTED)?; + match module { + zluda_dark_api::FatbinModule::Elf(_) => { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + zluda_dark_api::FatbinModule::Files(files) => { + let ptx_files = extract_ptx(files); + if ptx_files.is_empty() { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + Ok(ptx_files.into_iter().next().unwrap().0) + } + } }) - .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, - legacy_args: LegacyArguments::new(), - }))) + .collect::, _>>()?; + link_build_zluda_module(global_state, compilation_mode, isa, &*ptx_files) + .map(Cow::Owned) } - }; - Ok::<_, CUresult>(kernel as *mut _) - })??; - unsafe { *hfunc = function }; + }, + } +} + +fn link_build_or_load_fatbin_module( + global_state: &super::GlobalState, + compilation_mode: CompilationMode, + isa: &CStr, + module: zluda_dark_api::FatbinModuleHandle, +) -> Result, CUresult> { + let module = unsafe { module.get() }.map_err(|_| CUresult::CUDA_ERROR_NOT_SUPPORTED)?; + match module { + zluda_dark_api::FatbinModule::Elf(_) => { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + zluda_dark_api::FatbinModule::Files(files) => { + let ptx_files = extract_ptx(files); + for (ptx, _) in ptx_files { + if let Ok(binary) = + link_build_zluda_module(global_state, compilation_mode, isa, &[ptx]) + { + return Ok(binary); + } + } + Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + } +} + +fn extract_ptx(files: zluda_dark_api::FatbinModuleFiles) -> Vec<(Cow<'static, str>, u32)> { + let mut ptx_files = files + .filter_map(|file| { + file.ok() + .map(|file| { + if file.kind == FatbinFileKind::Ptx { + unsafe { file.get_or_decompress() } + .ok() + .map(|f| { + // TODO: implement support for envreg + // %envreg is currently used by global grid sync in PETSc on never CUDA architectures: + // auto g = cooperative_groups::this_grid(); + // g.sync(); + if memchr::memmem::find(&*f, b"%envreg").is_some() { + return None; + } + let text = match f { + Cow::Borrowed(slice) => { + Cow::Borrowed(std::str::from_utf8(slice).ok()?) + } + Cow::Owned(vec) => Cow::Owned(String::from_utf8(vec).ok()?), + }; + Some((text, file.sm_version)) + }) + .flatten() + } else { + None + } + }) + .flatten() + }) + .collect::>(); + ptx_files.sort_unstable_by_key(|(_, sm_version)| cmp::Reverse(*sm_version)); + ptx_files +} + +pub(crate) unsafe fn load_data_any( + owner: Option>, + compilation_mode: CompilationMode, + isa: &CStr, + input: CUmoduleContent, +) -> Result { + let global_state = GLOBAL_STATE.get()?; + let gpu_module = link_build_or_load_cuda_module(global_state, compilation_mode, isa, input)?; + let (hipfix_max_group_sizes, sm_version) = load_kernel_metadata(&*gpu_module)?; + let mut hip_module = ptr::null_mut(); + hip_call_cuda! { hipModuleLoadData(&mut hip_module, gpu_module.as_ptr() as _) }; + let device_version = device::COMPUTE_CAPABILITY_MAJOR * 10 + device::COMPUTE_CAPABILITY_MINOR; + Ok(ModuleData { + compilation_mode, + base: hip_module, + owner, + device_version, + sm_version, + hipfix_max_group_sizes, + functions: Mutex::new(FxHashMap::default()), + }) +} + +fn load_kernel_metadata( + gpu_module: &[u8], +) -> Result<(FxHashMap, u32), CUresult> { + let zluda_rt_section = hip_common::kernel_metadata::get_section( + hip_common::kernel_metadata::zluda::SECTION_STR, + gpu_module, + ) + .ok_or(CUresult::CUDA_ERROR_UNKNOWN)?; + let mut hipfix_max_group_sizes = FxHashMap::default(); + let sm_version = + hip_common::kernel_metadata::zluda::read(zluda_rt_section, |name, mut min, mut max| { + if min == 0 && max == 0 { + return; + } + if min == 0 { + min = 1; + } + if max == 0 { + max = u32::MAX; + } + if let Ok(name) = CString::new(name) { + hipfix_max_group_sizes.insert(name, (min, max)); + } + }) + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + Ok((hipfix_max_group_sizes, sm_version)) +} + +pub(crate) fn link_build_zluda_module( + global_state: &super::GlobalState, + compilation_mode: CompilationMode, + isa: &CStr, + ptx_text: &[Cow<'_, str>], +) -> Result, CUresult> { + if ptx_text.is_empty() { + return Err(CUresult::CUDA_ERROR_UNKNOWN); + } + if let Some(ref cache) = global_state.kernel_cache { + if let Some(binary) = + cache.try_load_program(&global_state.comgr_version, isa, ptx_text, compilation_mode) + { + return Ok(binary); + } + } + // Older CUDA applications have no notion of lazy loading + // and will eager load everything even if the module is unused. + // For this reason we fallback to empty module since that has potential + // to enable a few applications (but only in release mode) + let asts = ptx_text + .iter() + .map(|ptx_mod| { + let mut module = ptx::ModuleParser::parse_checked(&*ptx_mod); + if !cfg!(debug_assertions) { + module = module.or_else(|_| ptx::ModuleParser::parse_checked(EMPTY_MODULE)) + } + module + }) + .collect::, _>>() + .map_err(|_| CUresult::CUDA_ERROR_INVALID_PTX)?; + let mut llvm_module = ptx::to_llvm_module(compilation_mode, asts); + if !cfg!(debug_assertions) { + llvm_module = llvm_module.or_else(|_| { + ptx::to_llvm_module( + compilation_mode, + vec![ptx::ModuleParser::parse_checked(EMPTY_MODULE) + .map_err(|_| ptx::TranslateError::Todo)?], + ) + }); + } + let llvm_module = llvm_module.map_err(|_| CUresult::CUDA_ERROR_INVALID_PTX)?; + let binary = global_state + .comgr + .compile( + compilation_mode, + isa, + ptx::Module::get_bitcode_multi(std::iter::once(&llvm_module)).into_iter(), + &llvm_module.metadata.to_elf_section(), + ) + .map_err(comgr_error_to_cuda)?; + if let Some(ref cache) = global_state.kernel_cache { + cache.save_program( + &global_state.comgr_version, + isa, + ptx_text, + compilation_mode, + &binary, + ); + } + Ok(binary) +} + +pub(crate) unsafe fn unload(hmod: *mut Module) -> Result<(), CUresult> { + if hmod == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let module = LiveCheck::as_result(hmod)?; + if module.owner.is_none() { + return Err(CUresult::CUDA_ERROR_NOT_PERMITTED); + } + LiveCheck::drop_box_with_result(hmod, false) +} + +pub(crate) unsafe fn get_function( + hfunc: *mut *mut function::Function, + hmod: *mut Module, + name: *const i8, +) -> Result<(), CUresult> { + if hfunc == ptr::null_mut() || hmod == ptr::null_mut() || name == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let module = LiveCheck::as_result(hmod)?; + let name = CStr::from_ptr(name).to_owned(); + let mut functions = module + .functions + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + let function = match functions.entry(name.to_owned()) { + hash_map::Entry::Occupied(entry) => { + let function: &function::Function = &*entry.get(); + function as *const function::Function as *mut _ + } + hash_map::Entry::Vacant(entry) => { + let mut hip_func = ptr::null_mut(); + hip_call_cuda!(hipModuleGetFunction( + &mut hip_func, + module.base, + name.as_ptr() as _ + )); + let function: &function::Function = + &*entry.insert(Box::new(LiveCheck::new(FunctionData { + base: hip_func, + binary_version: module.device_version, + ptx_version: module.sm_version, + group_size: module.hipfix_max_group_sizes.get(&name).copied(), + compilation_mode: module.compilation_mode, + }))); + function as *const function::Function as *mut _ + } + }; + *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 }; +pub(crate) unsafe fn get_global( + dptr: *mut hipDeviceptr_t, + bytes: *mut usize, + hmod: *mut Module, + name: *const i8, +) -> Result<(), CUresult> { + if (dptr == ptr::null_mut() && bytes == ptr::null_mut()) || name == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + if hmod == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_HANDLE); + } + let hip_module = LiveCheck::as_result(hmod)?.base; + hip_call_cuda!(hipfix::module_get_global(dptr, bytes, hip_module, name)); Ok(()) } -pub(crate) fn unload(module: *mut Module) -> Result<(), CUresult> { - if module == ptr::null_mut() { - return Err(CUresult::CUDA_ERROR_INVALID_VALUE); +pub(crate) unsafe fn get_tex_ref( + tex_ref: *mut *mut textureReference, + hmod: *mut Module, + name: *const i8, +) -> Result<(), CUresult> { + if tex_ref == ptr::null_mut() || hmod == ptr::null_mut() || name == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_HANDLE); } - GlobalState::lock(|_| Module::destroy_impl(module))? + let hip_module = LiveCheck::as_result(hmod)?.base; + hip_call_cuda!(hipModuleGetTexRef(tex_ref, hip_module, name)); + hip_call_cuda!(hipTexRefSetFormat( + *tex_ref, + hipArray_Format::HIP_AD_FORMAT_FLOAT, + 1 + )); + Ok(()) } -pub(crate) fn load(pmod: *mut *mut Module, fname: *const i8) -> Result<(), CUresult> { - if pmod == ptr::null_mut() || fname == ptr::null() { - return Err(CUresult::CUDA_ERROR_INVALID_VALUE); - } - let path = unsafe { CStr::from_ptr(fname) }; - let path_utf8 = path - .to_str() - .map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?; - let file = std::fs::read(path_utf8).map_err(|_| CUresult::CUDA_ERROR_FILE_NOT_FOUND)?; - let module_text = std::str::from_utf8(&file).map_err(|_| CUresult::CUDA_ERROR_INVALID_PTX)?; - let spirv_data = SpirvModule::new(module_text)?; - load_data_impl(pmod, spirv_data) +const HIP_TRSF_READ_AS_INTEGER: u32 = 1; + +pub(crate) unsafe fn get_surf_ref( + texref: *mut *mut textureReference, + hmod: *mut Module, + name: *const i8, +) -> Result<(), CUresult> { + get_tex_ref(texref, hmod, name)?; + hip_call_cuda!(hipTexRefSetFlags(*texref, HIP_TRSF_READ_AS_INTEGER)); + Ok(()) +} + +pub(crate) unsafe fn get_loading_mode(result: *mut CUmoduleLoadingMode) -> CUresult { + if result == ptr::null_mut() { + CUresult::CUDA_ERROR_INVALID_VALUE + } else { + let mode = if matches!(std::env::var("CUDA_MODULE_LOADING").as_deref(), Ok("EAGER")) { + CUmoduleLoadingMode::CU_MODULE_EAGER_LOADING + } else { + CUmoduleLoadingMode::CU_MODULE_LAZY_LOADING + }; + *result = mode; + CUresult::CUDA_SUCCESS + } } diff --git a/zluda/src/impl/os_unix.rs b/zluda/src/impl/os_unix.rs new file mode 100644 index 0000000..1982450 --- /dev/null +++ b/zluda/src/impl/os_unix.rs @@ -0,0 +1,26 @@ +use std::ffi::c_void; + +pub unsafe fn heap_create() -> *mut c_void { + usize::MAX as *mut _ +} + +#[cfg(test)] +pub unsafe fn load_cuda() -> *mut c_void { + use libc; + use std::ffi::CStr; + + let result = libc::dlopen( + b"/usr/lib/x86_64-linux-gnu/libcuda.so.1\0".as_ptr() as _, + libc::RTLD_LOCAL | libc::RTLD_LAZY, + ); + if result == std::ptr::null_mut() { + panic!("{}", CStr::from_ptr(libc::dlerror()).to_string_lossy()); + } + result +} + +#[cfg(test)] +pub unsafe fn get_proc_address(handle: *mut c_void, func: &[u8]) -> *mut c_void { + use libc; + libc::dlsym(handle, func.as_ptr() as *const _) +} diff --git a/zluda/src/impl/os_win.rs b/zluda/src/impl/os_win.rs new file mode 100644 index 0000000..b4f135c --- /dev/null +++ b/zluda/src/impl/os_win.rs @@ -0,0 +1,7 @@ +use std::ffi::c_void; + +use winapi::um::{heapapi::HeapCreate, winnt::HEAP_NO_SERIALIZE}; + +pub unsafe fn heap_create() -> *mut c_void { + HeapCreate(HEAP_NO_SERIALIZE, 0, 0) +} diff --git a/zluda/src/impl/pointer.rs b/zluda/src/impl/pointer.rs new file mode 100644 index 0000000..caeacf4 --- /dev/null +++ b/zluda/src/impl/pointer.rs @@ -0,0 +1,142 @@ +use std::{ + ffi::{c_uint, c_ulonglong, c_void}, + mem, ptr, +}; + +use cuda_types::*; +use hip_runtime_sys::{ + hipDeviceptr_t, hipError_t, hipMemGetAddressRange, hipMemoryType, hipPointerGetAttributes, + hipPointer_attribute, +}; + +use crate::{hip_call_cuda, r#impl::IntoCuda}; + +pub(crate) unsafe fn get_attribute( + data: *mut c_void, + attribute: hipPointer_attribute, + ptr: hipDeviceptr_t, +) -> Result<(), CUresult> { + if data == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let mut attribs = mem::zeroed(); + hip_call_cuda! { hipPointerGetAttributes(&mut attribs, ptr.0 as _) }; + // TODO: implement HIP_POINTER_ATTRIBUTE_CONTEXT + match attribute { + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_MEMORY_TYPE => { + *(data as *mut _) = + memory_type(attribs.__bindgen_anon_1.memoryType).map_err(IntoCuda::into_cuda)?; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_DEVICE_POINTER => { + *(data as *mut _) = attribs.devicePointer; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_HOST_POINTER => { + *(data as *mut _) = attribs.hostPointer; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_IS_MANAGED => { + *(data as *mut _) = attribs.isManaged; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR => { + let mut start = hipDeviceptr_t(ptr::null_mut()); + let mut size = 0usize; + hip_call_cuda!(hipMemGetAddressRange(&mut start, &mut size, ptr)); + *(data as *mut _) = start; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_RANGE_SIZE => { + let mut start = hipDeviceptr_t(ptr::null_mut()); + let mut size = 0usize; + hip_call_cuda!(hipMemGetAddressRange(&mut start, &mut size, ptr)); + *(data as *mut _) = size; + Ok(()) + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL => { + *(data as *mut _) = attribs.device; + Ok(()) + } + _ => Err(CUresult::CUDA_ERROR_NOT_SUPPORTED), + } +} + +fn memory_type(cu: hipMemoryType) -> Result { + match cu { + hipMemoryType::hipMemoryTypeHost => Ok(CUmemorytype::CU_MEMORYTYPE_HOST), + hipMemoryType::hipMemoryTypeDevice => Ok(CUmemorytype::CU_MEMORYTYPE_DEVICE), + hipMemoryType::hipMemoryTypeArray => Ok(CUmemorytype::CU_MEMORYTYPE_ARRAY), + hipMemoryType::hipMemoryTypeUnified => Ok(CUmemorytype::CU_MEMORYTYPE_UNIFIED), + _ => Err(hipError_t::hipErrorInvalidValue), + } +} + +// "Unlike cuPointerGetAttribute, this function will not return an error when the ptr encountered is not a valid CUDA pointer. +// Instead, the attributes are assigned default NULL values and CUDA_SUCCESS is returned. " +// TODO: remove once hipDrvPointerGetAttributes works +pub(crate) unsafe fn get_attributes( + num_attributes: u32, + attributes: *mut hipPointer_attribute, + data: *mut *mut c_void, + ptr: hipDeviceptr_t, +) -> hipError_t { + if attributes == ptr::null_mut() { + return hipError_t::hipErrorInvalidValue; + } + for i in 0..num_attributes as usize { + let result = *data.add(i); + let attrib = *attributes.add(i); + if get_attribute(result, attrib, ptr).is_err() { + if let Some(result_size) = result_size(attrib) { + ptr::write_bytes(result.cast::(), 0, result_size); + } else { + return hipError_t::hipErrorNotSupported; + } + }; + } + hipError_t::hipSuccess +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct CUDA_POINTER_ATTRIBUTE_P2P_TOKENS { + p2p_token: c_ulonglong, + va_space_token: c_uint, +} + +fn result_size(attrib: hipPointer_attribute) -> Option { + Some(match attrib { + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_CONTEXT => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_MEMORY_TYPE => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_DEVICE_POINTER => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_HOST_POINTER => mem::size_of::<*mut c_void>(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_P2P_TOKENS => { + mem::size_of::() + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_SYNC_MEMOPS => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_BUFFER_ID => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_IS_MANAGED => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_IS_LEGACY_HIP_IPC_CAPABLE => { + mem::size_of::() + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR => { + mem::size_of::<*mut c_void>() + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_RANGE_SIZE => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_MAPPED => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES => { + mem::size_of::() + } + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE => { + mem::size_of::() + } + // an enum + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_ACCESS_FLAGS => mem::size_of::(), + hipPointer_attribute::HIP_POINTER_ATTRIBUTE_MEMPOOL_HANDLE => { + mem::size_of::() + } + _ => return None, + }) +} diff --git a/zluda/src/impl/stream.rs b/zluda/src/impl/stream.rs index e212dfc..fb53510 100644 --- a/zluda/src/impl/stream.rs +++ b/zluda/src/impl/stream.rs @@ -1,242 +1,195 @@ -use super::{ - context::{Context, ContextData}, - CUresult, GlobalState, -}; -use std::{mem, ptr}; - -use super::{HasLivenessCookie, LiveCheck}; - -pub type Stream = LiveCheck; - -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 { - Ok(StreamData { - context: ptr::null_mut(), - queue: l0::CommandQueue::new(ctx, dev)?, - }) - } - pub fn new(ctx: &mut ContextData) -> Result { - 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 { - 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() { - default_stream_uses_current_ctx_impl::(CU_STREAM_LEGACY); - } - - fn default_stream_uses_current_ctx_ptsd() { - default_stream_uses_current_ctx_impl::(CU_STREAM_PER_THREAD); - } - - fn default_stream_uses_current_ctx_impl(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() { - 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() { - 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() { - 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() { - 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); - } -} +use super::{context, LiveCheck, ZludaObject}; +use crate::{hip_call_cuda, r#impl::hipfix}; +use cuda_types::{CUhostFn, CUresult}; +use hip_runtime_sys::*; +use std::{ffi::c_void, ptr}; + +pub(crate) const CU_STREAM_NULL: *mut Stream = 0 as *mut _; +pub(crate) const CU_STREAM_LEGACY: *mut Stream = 1 as *mut _; +pub(crate) const CU_STREAM_PER_THREAD: *mut Stream = 2 as *mut _; + +pub(crate) type Stream = LiveCheck; + +impl ZludaObject for StreamData { + #[cfg(target_pointer_width = "64")] + const LIVENESS_COOKIE: usize = 0x512097354de18d35; + #[cfg(target_pointer_width = "32")] + const LIVENESS_COOKIE: usize = 0x77d5cc0b; + const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE; + + fn drop_with_result(&mut self, by_owner: bool) -> Result<(), CUresult> { + if !by_owner { + let ctx = unsafe { LiveCheck::as_result(self.ctx)? }; + { + let mut ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + ctx_mutable + .streams + .remove(&unsafe { LiveCheck::from_raw(&mut *self) }); + } + } + hip_call_cuda!(hipStreamDestroy(self.base)); + Ok(()) + } +} + +pub(crate) struct StreamData { + pub(crate) base: hipStream_t, + pub(crate) ctx: *mut context::Context, +} + +pub(crate) unsafe fn create_with_priority( + p_stream: *mut *mut Stream, + flags: ::std::os::raw::c_uint, + priority: ::std::os::raw::c_int, +) -> Result<(), CUresult> { + if p_stream == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let mut hip_stream = ptr::null_mut(); + hip_call_cuda!(hipStreamCreateWithPriority( + &mut hip_stream, + flags, + priority + )); + let stream = Box::into_raw(Box::new(LiveCheck::new(StreamData { + base: hip_stream, + ctx: ptr::null_mut(), + }))); + let ctx = context::with_current(|ctx| { + let mut ctx_mutable = ctx + .mutable + .lock() + .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?; + ctx_mutable.streams.insert(stream); + Ok(LiveCheck::from_raw(ctx as *const _ as _)) + })??; + (*stream).as_mut_unchecked().ctx = ctx; + *p_stream = stream; + Ok(()) +} + +pub(crate) unsafe fn get_ctx( + stream: *mut Stream, + pctx: *mut *mut context::Context, +) -> Result<(), CUresult> { + let ctx = if as_default_stream(stream).is_some() { + context::with_current(|ctx| LiveCheck::from_raw(ctx as *const _ as _))? + } else { + let stream = LiveCheck::as_result(stream)?; + stream.ctx + }; + *pctx = ctx; + Ok(()) +} + +pub(crate) unsafe fn synchronize( + stream: *mut Stream, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda!(hipStreamSynchronize(hip_stream)); + Ok(()) +} + +pub(crate) unsafe fn destroy(stream: *mut Stream) -> Result<(), CUresult> { + if as_default_stream(stream).is_some() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + LiveCheck::drop_box_with_result(stream, false) +} + +pub(crate) fn as_default_stream(stream: *mut Stream) -> Option { + match stream { + CU_STREAM_NULL | CU_STREAM_LEGACY => Some(hipStreamNull), + CU_STREAM_PER_THREAD => Some(hipStreamPerThread), + _ => None, + } +} + +pub(crate) unsafe fn as_hip_stream(stream: *mut Stream) -> Result { + Ok(match as_default_stream(stream) { + Some(s) => s, + None => LiveCheck::as_result(stream)?.base, + }) +} + +pub(crate) unsafe fn launch_host_func( + stream: *mut Stream, + fn_: CUhostFn, + user_data: *mut ::std::os::raw::c_void, +) -> Result<(), CUresult> { + let fn_ = *fn_.as_ref().ok_or(CUresult::CUDA_ERROR_INVALID_VALUE)?; + let hip_stream = as_hip_stream(stream)?; + // TODO: use hipLaunchHostFunc when it comes to Windows + //hip_call_cuda!(hipLaunchHostFunc(hip_stream, fn_, user_data)); + let callback = Box::new(HostCallback { fn_, user_data }); + hip_call_cuda!(hipStreamAddCallback( + hip_stream, + Some(steam_callback_to_host_func), + Box::into_raw(callback) as _, + 0 + )); + Ok(()) +} + +pub(crate) unsafe fn wait_event( + stream: *mut Stream, + h_event: hipEvent_t, + flags: ::std::os::raw::c_uint, + default_stream_per_thread: bool, +) -> Result<(), CUresult> { + let hip_stream = hipfix::as_hip_stream_per_thread(stream, default_stream_per_thread)?; + hip_call_cuda! { hipStreamWaitEvent(hip_stream, h_event, flags) }; + Ok(()) +} + +unsafe extern "C" fn steam_callback_to_host_func( + _stream: hipStream_t, + result: hipError_t, + callback_ptr: *mut c_void, +) { + if result != hipError_t::hipSuccess { + return; + } + let callback_ptr = &*(callback_ptr as *const HostCallback); + (callback_ptr.fn_)(callback_ptr.user_data); +} + +struct HostCallback { + fn_: unsafe extern "system" fn(userData: *mut ::std::os::raw::c_void), + user_data: *mut ::std::os::raw::c_void, +} + +pub(crate) unsafe fn query(stream: *mut Stream) -> Result<(), CUresult> { + let hip_stream = as_hip_stream(stream)?; + hip_call_cuda! { hipStreamQuery(hip_stream) }; + Ok(()) +} + +pub(crate) unsafe fn get_capture_info( + stream: *mut Stream, + capture_status_out: *mut hipStreamCaptureStatus, + id_out: *mut u64, +) -> Result<(), CUresult> { + let hip_stream = as_hip_stream(stream)?; + hip_call_cuda! { hipStreamGetCaptureInfo(hip_stream, capture_status_out, id_out) }; + Ok(()) +} + +pub(crate) unsafe fn get_flags(stream: *mut Stream, flags: *mut u32) -> Result<(), CUresult> { + let hip_stream = as_hip_stream(stream)?; + hip_call_cuda! { hipStreamGetFlags(hip_stream, flags) }; + Ok(()) +} + +pub(crate) unsafe fn is_capturing( + stream: *mut Stream, + capture_status: *mut hipStreamCaptureStatus, +) -> Result<(), CUresult> { + let hip_stream = as_hip_stream(stream)?; + hip_call_cuda! { hipStreamIsCapturing(hip_stream, capture_status) }; + Ok(()) +} diff --git a/zluda/src/impl/surface.rs b/zluda/src/impl/surface.rs new file mode 100644 index 0000000..fcf9a52 --- /dev/null +++ b/zluda/src/impl/surface.rs @@ -0,0 +1,117 @@ +use cuda_types::*; +use hip_runtime_sys::*; +use std::{mem, ptr}; + +use crate::hip_call_cuda; + +use super::{hipfix, FromCuda}; + +pub(crate) unsafe fn create( + p_surf_object: *mut hipSurfaceObject_t, + p_res_desc: *const CUDA_RESOURCE_DESC, +) -> Result<(), CUresult> { + if p_res_desc == ptr::null() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let desc = to_surface_desc(*p_res_desc)?; + hip_call_cuda!(hipCreateSurfaceObject(p_surf_object, &desc)); + Ok(()) +} + +unsafe fn to_surface_desc(res_desc: CUDA_RESOURCE_DESC) -> Result { + let res_type = mem::transmute(res_desc.resType); + let res: hipResourceDesc__bindgen_ty_1 = match res_desc.resType { + CUresourcetype::CU_RESOURCE_TYPE_ARRAY => hipResourceDesc__bindgen_ty_1 { + array: hipResourceDesc__bindgen_ty_1__bindgen_ty_1 { + array: hipfix::array::get(res_desc.res.array.hArray), + }, + }, + CUresourcetype::CU_RESOURCE_TYPE_MIPMAPPED_ARRAY => hipResourceDesc__bindgen_ty_1 { + mipmap: hipResourceDesc__bindgen_ty_1__bindgen_ty_2 { + mipmap: mem::transmute(res_desc.res.mipmap.hMipmappedArray), + }, + }, + CUresourcetype::CU_RESOURCE_TYPE_LINEAR => hipResourceDesc__bindgen_ty_1 { + linear: hipResourceDesc__bindgen_ty_1__bindgen_ty_3 { + devPtr: res_desc.res.linear.devPtr.0, + desc: channel_format_desc( + FromCuda::from_cuda(res_desc.res.linear.format), + res_desc.res.linear.numChannels, + )?, + sizeInBytes: res_desc.res.linear.sizeInBytes, + }, + }, + CUresourcetype::CU_RESOURCE_TYPE_PITCH2D => hipResourceDesc__bindgen_ty_1 { + pitch2D: hipResourceDesc__bindgen_ty_1__bindgen_ty_4 { + devPtr: res_desc.res.pitch2D.devPtr.0, + desc: channel_format_desc( + FromCuda::from_cuda(res_desc.res.pitch2D.format), + res_desc.res.pitch2D.numChannels, + )?, + width: res_desc.res.pitch2D.width, + height: res_desc.res.pitch2D.height, + pitchInBytes: res_desc.res.pitch2D.pitchInBytes, + }, + }, + _ => todo!(), + }; + Ok(hipResourceDesc { + resType: res_type, + res, + }) +} + +fn channel_format_desc( + format: hipArray_Format, + num_channels: u32, +) -> Result { + let mut bits = match num_channels { + 1 => (1, 0, 0, 0), + 2 => (1, 1, 0, 0), + 3 => (1, 1, 1, 0), + 4 => (1, 1, 1, 1), + _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), + }; + let (kind, bit_width) = match format { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT8 => { + (hipChannelFormatKind::hipChannelFormatKindUnsigned, u8::BITS) + } + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16 => ( + hipChannelFormatKind::hipChannelFormatKindUnsigned, + u16::BITS, + ), + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT32 => ( + hipChannelFormatKind::hipChannelFormatKindUnsigned, + u32::BITS, + ), + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT8 => { + (hipChannelFormatKind::hipChannelFormatKindSigned, i8::BITS) + } + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT16 => { + (hipChannelFormatKind::hipChannelFormatKindSigned, i16::BITS) + } + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT32 => { + (hipChannelFormatKind::hipChannelFormatKindSigned, i32::BITS) + } + hipArray_Format::HIP_AD_FORMAT_HALF => ( + hipChannelFormatKind::hipChannelFormatKindFloat, + mem::size_of::() as u32 * u8::BITS, + ), + hipArray_Format::HIP_AD_FORMAT_FLOAT => ( + hipChannelFormatKind::hipChannelFormatKindFloat, + mem::size_of::() as u32 * u8::BITS, + ), + _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), + }; + bits.0 *= bit_width; + bits.1 *= bit_width; + bits.2 *= bit_width; + bits.3 *= bit_width; + Ok(hipChannelFormatDesc { + x: bits.0 as i32, + y: bits.0 as i32, + z: bits.0 as i32, + w: bits.0 as i32, + f: kind, + }) +} diff --git a/zluda/src/impl/surfref.rs b/zluda/src/impl/surfref.rs new file mode 100644 index 0000000..457f9c4 --- /dev/null +++ b/zluda/src/impl/surfref.rs @@ -0,0 +1,23 @@ +use crate::{hip_call_cuda, r#impl::hipfix}; +use cuda_types::{CUarray, CUresult}; +use hip_runtime_sys::*; +use std::ptr; + +pub(crate) unsafe fn set_array( + surfref: *mut textureReference, + array: CUarray, + _flags: u32, +) -> Result<(), CUresult> { + if array == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let array = hipfix::array::get(array); + let array = array.as_mut().unwrap(); + hip_call_cuda!(hipTexRefSetFormat( + surfref, + array.Format, + array.NumChannels as i32, + )); + hip_call_cuda!(hipTexRefSetArray(surfref, array, HIP_TRSA_OVERRIDE_FORMAT)); + Ok(()) +} diff --git a/zluda/src/impl/test.rs b/zluda/src/impl/test.rs deleted file mode 100644 index b36ccd8..0000000 --- a/zluda/src/impl/test.rs +++ /dev/null @@ -1,157 +0,0 @@ -#![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::() - } - - #[test] - fn [<$func _cuda>]() { - $func::() - } - } - }; -} - -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/impl/texobj.rs b/zluda/src/impl/texobj.rs new file mode 100644 index 0000000..21eb453 --- /dev/null +++ b/zluda/src/impl/texobj.rs @@ -0,0 +1,19 @@ +use cuda_types::*; +use hip_runtime_sys::*; +use std::ptr; + +use super::hipfix; + +pub(crate) unsafe fn create( + p_tex_object: *mut hipTextureObject_t, + p_res_desc: *const CUDA_RESOURCE_DESC, + p_tex_desc: *const HIP_TEXTURE_DESC, + p_res_view_desc: *const HIP_RESOURCE_VIEW_DESC, +) -> hipError_t { + if p_res_desc == ptr::null() { + return hipError_t::hipErrorInvalidValue; + } + hipfix::array::with_resource_desc(p_res_desc, |p_res_desc| { + hipTexObjectCreate(p_tex_object, p_res_desc, p_tex_desc, p_res_view_desc) + }) +} diff --git a/zluda/src/impl/texref.rs b/zluda/src/impl/texref.rs new file mode 100644 index 0000000..307b5ba --- /dev/null +++ b/zluda/src/impl/texref.rs @@ -0,0 +1,263 @@ +use super::hipfix; +use crate::hip_call_cuda; +use cuda_types::*; +use hip_runtime_sys::*; +use std::{mem, ptr}; + +// TODO: remove this when HIP starts handling NULL here gracefully +pub(crate) unsafe fn set_address( + byte_offset: *mut usize, + tex_ref: *mut textureReference, + dptr: hipDeviceptr_t, + bytes: usize, +) -> hipError_t { + if dptr.0 == ptr::null_mut() { + return hipUnbindTexture(tex_ref); + } + let mut unused = 0; + hipTexRefSetAddress( + if byte_offset == ptr::null_mut() { + &mut unused + } else { + byte_offset + }, + tex_ref, + dptr, + bytes, + ) +} + +// TODO replace with HIP call once HIP fixes it +pub(crate) unsafe fn get_max_anisotropy( + pmax_aniso: *mut i32, + tex_ref: *mut textureReference, +) -> hipError_t { + if pmax_aniso == ptr::null_mut() || tex_ref == ptr::null_mut() { + return hipError_t::hipErrorInvalidValue; + } + *pmax_aniso = (*tex_ref).maxAnisotropy as i32; + hipError_t::hipSuccess +} + +// TODO replace with HIP call once HIP fixes it +pub(crate) unsafe fn get_mipmap_filter_mode( + pfm: *mut hipTextureFilterMode, + tex_ref: *mut textureReference, +) -> hipError_t { + if pfm == ptr::null_mut() || tex_ref == ptr::null_mut() { + return hipError_t::hipErrorInvalidValue; + } + *pfm = (*tex_ref).mipmapFilterMode; + hipError_t::hipSuccess +} + +// TODO replace with HIP call once HIP fixes it +pub(crate) unsafe fn get_mipmap_level_bias( + pbias: *mut f32, + tex_ref: *mut textureReference, +) -> hipError_t { + if pbias == ptr::null_mut() || tex_ref == ptr::null_mut() { + return hipError_t::hipErrorInvalidValue; + } + *pbias = (*tex_ref).mipmapLevelBias; + hipError_t::hipSuccess +} + +// TODO replace with HIP call once HIP fixes it +pub(crate) unsafe fn get_mipmap_level_clamp( + min_mipmap_level_clamp: *mut f32, + max_mipmap_level_clamp: *mut f32, + tex_ref: *mut textureReference, +) -> hipError_t { + if min_mipmap_level_clamp == ptr::null_mut() + || max_mipmap_level_clamp == ptr::null_mut() + || tex_ref == ptr::null_mut() + { + return hipError_t::hipErrorInvalidValue; + } + *min_mipmap_level_clamp = (*tex_ref).minMipmapLevelClamp; + *max_mipmap_level_clamp = (*tex_ref).maxMipmapLevelClamp; + hipError_t::hipSuccess +} + +// HIP_TRSA_OVERRIDE_FORMAT is required but does nothing +// HIP team refuses to fix it +pub(crate) unsafe fn set_array( + texref: *mut textureReference, + array: CUarray, + flags: u32, +) -> Result<(), CUresult> { + if (flags & !1u32) != 0 { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + let array = hipfix::array::get(array); + if let Some(array) = array.as_ref() { + hip_call_cuda!(hipTexRefSetFormat( + texref, + hipfix::get_broken_format(array.textureType, array.Format), + array.NumChannels as i32, + )); + hip_call_cuda!(hipTexRefSetArray(texref, array, HIP_TRSA_OVERRIDE_FORMAT)); + Ok(()) + } else { + Err(CUresult::CUDA_ERROR_INVALID_VALUE) + } +} + +unsafe fn reset(tex_ref: *mut textureReference) -> Result<(), CUresult> { + if tex_ref == ptr::null_mut() { + return Err(CUresult::CUDA_ERROR_INVALID_VALUE); + } + let mut res_desc = mem::zeroed(); + hip_call_cuda!(hipGetTextureObjectResourceDesc( + &mut res_desc, + (*tex_ref).textureObject + )); + match res_desc.resType { + hipResourceType::hipResourceTypeArray => { + let array = res_desc.res.array.array; + if array != ptr::null_mut() { + hip_call_cuda!(hipTexRefSetArray(tex_ref, array, HIP_TRSA_OVERRIDE_FORMAT)); + } + } + hipResourceType::hipResourceTypeLinear => { + let linear = res_desc.res.linear; + if linear.devPtr != ptr::null_mut() && linear.sizeInBytes != 0 { + let mut unused = 0usize; + hip_call_cuda!(hipTexRefSetAddress( + &mut unused, + tex_ref, + hipDeviceptr_t(linear.devPtr), + linear.sizeInBytes + )) + } + } + hipResourceType::hipResourceTypePitch2D => { + let pitch_2d: hipResourceDesc__bindgen_ty_1__bindgen_ty_4 = res_desc.res.pitch2D; + let (format, channels) = from_channel_format_desc(pitch_2d.desc)?; + let desc = HIP_ARRAY_DESCRIPTOR { + Width: pitch_2d.width, + Height: pitch_2d.height, + Format: format, + NumChannels: channels, + }; + hip_call_cuda!(hipTexRefSetAddress2D( + tex_ref, + &desc, + hipDeviceptr_t(pitch_2d.devPtr), + pitch_2d.pitchInBytes + )); + } + hipResourceType::hipResourceTypeMipmappedArray => { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED) + } + _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), + } + Ok(()) +} + +fn from_channel_format_desc( + desc: hipChannelFormatDesc, +) -> Result<(hipArray_Format, u32), CUresult> { + if desc.x != desc.y || desc.x != desc.z || desc.x != desc.w { + return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED); + } + let num_channels = + (desc.x != 0) as u32 + (desc.y != 0) as u32 + (desc.z != 0) as u32 + (desc.w != 0) as u32; + let format = match (desc.f, desc.x) { + (hipChannelFormatKind::hipChannelFormatKindUnsigned, 8) => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT8 + } + (hipChannelFormatKind::hipChannelFormatKindUnsigned, 16) => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16 + } + (hipChannelFormatKind::hipChannelFormatKindUnsigned, 32) => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT32 + } + (hipChannelFormatKind::hipChannelFormatKindSigned, 8) => { + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT8 + } + (hipChannelFormatKind::hipChannelFormatKindSigned, 16) => { + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT16 + } + (hipChannelFormatKind::hipChannelFormatKindSigned, 32) => { + hipArray_Format::HIP_AD_FORMAT_SIGNED_INT32 + } + (hipChannelFormatKind::hipChannelFormatKindFloat, 16) => { + hipArray_Format::HIP_AD_FORMAT_HALF + } + (hipChannelFormatKind::hipChannelFormatKindFloat, 32) => { + hipArray_Format::HIP_AD_FORMAT_FLOAT + } + _ => return Err(CUresult::CUDA_ERROR_INVALID_VALUE), + }; + Ok((format, num_channels)) +} + +pub(crate) unsafe fn set_address_mode( + tex_ref: *mut textureReference, + dim: i32, + am: hipTextureAddressMode, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetAddressMode(tex_ref, dim, am)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_filter_mode( + tex_ref: *mut textureReference, + fm: hipTextureFilterMode, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetFilterMode(tex_ref, fm)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_flags(tex_ref: *mut textureReference, flags: u32) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetFlags(tex_ref, flags)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_format( + tex_ref: *mut textureReference, + fmt: hipArray_Format, + num_packed_components: i32, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetFormat(tex_ref, fmt, num_packed_components)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_max_anisotropy( + tex_ref: *mut textureReference, + max_aniso: u32, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetMaxAnisotropy(tex_ref, max_aniso)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_mipmap_filter_mode( + tex_ref: *mut textureReference, + fm: hipTextureFilterMode, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetMipmapFilterMode(tex_ref, fm)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_mipmap_level_bias( + tex_ref: *mut textureReference, + bias: f32, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetMipmapLevelBias(tex_ref, bias)); + reset(tex_ref) +} + +pub(crate) unsafe fn set_mipmap_level_clamp( + tex_ref: *mut textureReference, + min_mipmap_level_clamp: f32, + max_mipmap_level_clamp: f32, +) -> Result<(), CUresult> { + hip_call_cuda!(hipTexRefSetMipmapLevelClamp( + tex_ref, + min_mipmap_level_clamp, + max_mipmap_level_clamp + )); + reset(tex_ref) +} diff --git a/zluda/src/lib.rs b/zluda/src/lib.rs index c0ddd5b..afd22e6 100644 --- a/zluda/src/lib.rs +++ b/zluda/src/lib.rs @@ -1,15 +1,40 @@ -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; -#[cfg(test)] -#[macro_use] extern crate paste; extern crate ptx; #[allow(warnings)] pub mod cuda; -mod cuda_impl; pub(crate) mod r#impl; + +use crate::r#impl::LiveCheck; +use cuda_types::CUresult; +use hip_common::zluda_ext::{CudaObjectKind, CudaResult}; +use r#impl::{context, stream}; + +const DRIVER_VERSION: i32 = 12020; + +#[no_mangle] +pub unsafe extern "C" fn zluda_get_hip_object( + cuda_object: *mut std::os::raw::c_void, + kind: CudaObjectKind, +) -> CudaResult<*const std::os::raw::c_void> { + unsafe fn zluda_get_hip_object_impl( + cuda_object: *const std::os::raw::c_void, + kind: CudaObjectKind, + ) -> Result<*const std::os::raw::c_void, CUresult> { + match kind { + CudaObjectKind::Context => { + let cuda_object = cuda_object as *mut context::Context; + let ctx = LiveCheck::as_result(cuda_object)?; + Ok(ctx.device as usize as _) + } + CudaObjectKind::Stream => { + let cuda_object = cuda_object as *mut stream::Stream; + let stream = stream::as_hip_stream(cuda_object)?; + Ok(stream as _) + } + } + } + zluda_get_hip_object_impl(cuda_object, kind).into() +} diff --git a/zluda/tests/bfi.ptx b/zluda/tests/bfi.ptx new file mode 100644 index 0000000..7c25f19 --- /dev/null +++ b/zluda/tests/bfi.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry kernel_bfi( + .param .u64 input, + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .#TYPE# a; + .reg .#TYPE# b; + .reg .b32 c; + .reg .b32 d; + .reg .#TYPE# f; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.#TYPE# a, [in_addr]; + add.u64 in_addr, in_addr, #WIDTH#; + ld.#TYPE# b, [in_addr]; + add.u64 in_addr, in_addr, #WIDTH#; + ld.b32 c, [in_addr]; + add.u64 in_addr, in_addr, #WIDTH#; + ld.b32 d, [in_addr]; + + bfi.#TYPE# f,a,b,c,d; + + st.#TYPE# [out_addr], f; + + ret; +} diff --git a/zluda/tests/bfi.rs b/zluda/tests/bfi.rs new file mode 100644 index 0000000..a5bb99a --- /dev/null +++ b/zluda/tests/bfi.rs @@ -0,0 +1,173 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use num_traits::{FromPrimitive, Num, WrappingSub}; +use rand::{Fill, Rng}; +use rand_chacha::rand_core::SeedableRng; +use std::fmt::Debug; +use std::ops::{BitAnd, BitOr, Not, Rem, Shl}; +use std::{mem, ptr}; + +mod common; + +static BFI_KERNEL: &'static str = include_str!("bfi.ptx"); + +cuda_driver_test!(bfi_b32); +unsafe fn bfi_b32(cuda: T) { + bfi::<_, u32>(cuda, "b32", "4", true) +} + +cuda_driver_test!(bfi_b64); +unsafe fn bfi_b64(cuda: T) { + bfi::<_, u64>(cuda, "b64", "8", false) +} + +unsafe fn bfi< + C: CudaDriverFns, + T: Copy + + Default + + Debug + + PartialEq + + Num + + Shl + + Not + + BitAnd + + BitOr + + Rem + + WrappingSub + + FromPrimitive + + PartialOrd, +>( + cuda: C, + type_: &str, + width: &str, + limit: bool, +) where + [T]: Fill, +{ + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut kernel = BFI_KERNEL + .replace("#TYPE#", type_) + .replace("#WIDTH#", width); + kernel.push('\0'); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut buffer_input = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_input, mem::size_of::() * 4), + CUresult::CUDA_SUCCESS + ); + let mut buffer_output = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_output, mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut result = T::default(); + let mut kernel = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"kernel_bfi\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0x1905cc2a2c4367e7); + for i in 0..1024 { + let mut input = [T::default(); 4]; + rng.fill(&mut input); + if i == 0 { + input[2] = T::zero(); + input[3] = T::from_usize(15).unwrap(); + } + if i == 2 { + input[2] = T::from_usize(15).unwrap(); + input[3] = T::zero(); + } + if i % 2 == 1 { + input[2] = input[2].rem(T::from_usize(32).unwrap()); + } + assert_eq!( + cuda.cuMemcpyHtoD_v2( + buffer_input, + &mut input as *mut _ as *mut _, + mem::size_of::() * input.len() + ), + CUresult::CUDA_SUCCESS + ); + let mut params = [&mut buffer_input, &mut buffer_output]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + params.as_mut_ptr().cast(), + ptr::null_mut() + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemcpyDtoH_v2( + &mut result as *mut _ as *mut _, + buffer_output, + mem::size_of::() + ), + CUresult::CUDA_SUCCESS + ); + let host_result = bfi_nv(input, limit); + assert_eq!(result, host_result); + } +} + +fn bfi_nv< + T: Copy + + Default + + Debug + + PartialEq + + Num + + Shl + + Not + + BitAnd + + BitOr + + Rem + + WrappingSub + + FromPrimitive + + PartialOrd, +>( + input: [T; 4], + limit: bool, +) -> T { + let insert = input[0]; + let base = input[1]; + let mut offset = input[2]; + let mut count = input[3]; + if limit { + offset = offset.rem(T::from_usize(256).unwrap()); + count = count.rem(T::from_usize(256).unwrap()); + } + let mask = shl_unbound(shl_unbound(T::one(), count).wrapping_sub(&T::one()), offset); + mask.not() + .bitand(base) + .bitor(mask.bitand(shl_unbound(insert, offset))) +} + +fn shl_unbound(t: T, amount: T) -> T +where + T: Num + Shl + FromPrimitive + PartialOrd, +{ + let limit = (mem::size_of::() * 8) - 1; + if amount > T::from_usize(limit).unwrap() { + T::zero() + } else { + t.shl(amount) + } +} diff --git a/zluda/tests/common.rs b/zluda/tests/common.rs new file mode 100644 index 0000000..eedac39 --- /dev/null +++ b/zluda/tests/common.rs @@ -0,0 +1,128 @@ +#![allow(non_snake_case)] +use cuda_base::cuda_function_declarations; +use std::ffi::c_void; + +macro_rules! unimplemented_cuda_fn { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + pub trait CudaDriverFns { + fn new() -> Self; + fn is_nvidia() -> bool; + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type; + )* + } + + #[derive(Copy, Clone)] + pub struct Cuda { + lib: *mut c_void + } + + unsafe impl Send for Cuda {} + unsafe impl Sync for Cuda {} + + impl CudaDriverFns for Cuda { + fn new() -> Self { + let lib = unsafe { os::load_cuda() }; + Self { lib } + } + fn is_nvidia() -> bool { true } + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + let fn_ptr = os::get_proc_address(self.lib, concat!(stringify!($fn_name), "\0").as_bytes()); + let cu_fn = std::mem::transmute::<_, unsafe extern $abi fn( $( $arg_id : $arg_type),* ) -> $ret_type>(fn_ptr); + cu_fn ( $( $arg_id),* ) + } + )* + } + + #[derive(Copy, Clone)] + pub struct Zluda; + + impl CudaDriverFns for Zluda { + fn new() -> Self { Self } + fn is_nvidia() -> bool { false } + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + zluda::cuda::$fn_name ( $( $arg_id),* ) + } + )* + } + }; +} + +cuda_function_declarations!(cuda_types, unimplemented_cuda_fn, UNUSED, []); + +#[macro_export] +macro_rules! cuda_driver_test { + ($func:ident) => { + paste::paste! { + #[test] + #[allow(non_snake_case)] + fn [<$func _zluda>]() { + unsafe { $func::(crate::common::Zluda::new()) } + } + + #[test] + #[allow(non_snake_case)] + fn [<$func _cuda>]() { + unsafe { $func::(crate::common::Cuda::new()) } + } + } + }; +} + +#[allow(dead_code)] +pub const CU_STREAM_LEGACY: cuda_types::CUstream = 1 as *mut _; +#[allow(dead_code)] +pub const CU_STREAM_PER_THREAD: cuda_types::CUstream = 2 as *mut _; + +#[cfg(windows)] +mod os { + use std::ffi::c_void; + + pub unsafe fn load_cuda() -> *mut c_void { + use winapi::um::libloaderapi::LoadLibraryA; + let result = LoadLibraryA(b"C:\\Windows\\System32\\nvcuda.dll\0".as_ptr() as _); + if result == std::ptr::null_mut() { + panic!("{:?}", std::io::Error::last_os_error()); + } + result as _ + } + + pub unsafe fn get_proc_address(handle: *mut c_void, func: &[u8]) -> *mut c_void { + use winapi::um::libloaderapi::GetProcAddress; + GetProcAddress(handle as _, func.as_ptr() as *const _) as _ + } +} + +#[cfg(not(windows))] +mod os { + use std::ffi::c_void; + use libc; + use std::ffi::CStr; + + #[cfg(test)] + pub unsafe fn load_cuda() -> *mut c_void { + // Ubuntu path + let mut result = libc::dlopen( + b"/usr/lib/x86_64-linux-gnu/libcuda.so.1\0".as_ptr() as _, + libc::RTLD_LOCAL | libc::RTLD_LAZY, + ); + // RHEL path + if result == std::ptr::null_mut() { + result = libc::dlopen( + b"/usr/lib64/libcuda.so.1\0".as_ptr() as _, + libc::RTLD_LOCAL | libc::RTLD_LAZY, + ); + } + if result == std::ptr::null_mut() { + panic!("{}", CStr::from_ptr(libc::dlerror()).to_string_lossy()); + } + result + } + + #[cfg(test)] + pub unsafe fn get_proc_address(handle: *mut c_void, func: &[u8]) -> *mut c_void { + libc::dlsym(handle, func.as_ptr() as *const _) + } +} diff --git a/zluda/tests/context_dark_api_primary_is_unretained.rs b/zluda/tests/context_dark_api_primary_is_unretained.rs new file mode 100644 index 0000000..56eaee6 --- /dev/null +++ b/zluda/tests/context_dark_api_primary_is_unretained.rs @@ -0,0 +1,84 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::mem; + +mod common; + +cuda_driver_test!(context_dark_api_primary_is_unretained); + +unsafe fn context_dark_api_primary_is_unretained(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let dev = CUdevice_v1(0); + let mut ctx1 = mem::zeroed(); + let mut export_table = mem::zeroed(); + assert_eq!( + cuda.cuGetExportTable( + &mut export_table, + &CUuuid { + bytes: [ + 0x6b, 0xd5, 0xfb, 0x6c, 0x5b, 0xf4, 0xe7, 0x4a, 0x89, 0x87, 0xd9, 0x39, 0x12, + 0xfd, 0x9d, 0xf9 + ] + } + ), + CUresult::CUDA_SUCCESS + ); + let get_primary_ctx = mem::transmute::< + _, + unsafe extern "system" fn(*mut CUcontext, CUdevice) -> CUresult, + >(*(export_table as *mut usize).add(2)); + assert_eq!(get_primary_ctx(&mut ctx1, dev), CUresult::CUDA_SUCCESS); + let mut api_version = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetApiVersion(ctx1, &mut api_version), + CUresult::CUDA_ERROR_INVALID_CONTEXT + ); + assert_eq!(cuda.cuCtxSetCurrent(ctx1), CUresult::CUDA_SUCCESS); + let mut device = mem::zeroed(); + assert_eq!(cuda.cuCtxGetDevice(&mut device), CUresult::CUDA_SUCCESS); + // TODO: re-enable when adding context getters + /* + let mut cache_cfg = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetCacheConfig(&mut cache_cfg), + CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + ); + let mut exec_affinity = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetExecAffinity( + &mut exec_affinity, + CUexecAffinityType::CU_EXEC_AFFINITY_TYPE_SM_COUNT + ), + CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + ); + let mut flags = mem::zeroed(); + assert_eq!(cuda.cuCtxGetFlags(&mut flags,), CUresult::CUDA_SUCCESS); + let mut stack = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetLimit(&mut stack, CUlimit::CU_LIMIT_STACK_SIZE), + CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + ); + let mut shared_mem_cfg = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetSharedMemConfig(&mut shared_mem_cfg), + CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + ); + let mut lowest_priority = mem::zeroed(); + let mut highest_priority = mem::zeroed(); + assert_eq!( + cuda.cuCtxGetStreamPriorityRange(&mut lowest_priority, &mut highest_priority), + CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + ); + */ + let mut ctx2 = mem::zeroed(); + assert_eq!( + cuda.cuDevicePrimaryCtxRetain(&mut ctx2, dev), + CUresult::CUDA_SUCCESS + ); + assert_eq!(ctx1, ctx2); + assert_eq!( + cuda.cuCtxGetApiVersion(ctx1, &mut api_version), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxGetDevice(&mut device), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/context_destroy_also_destroys_stream.rs b/zluda/tests/context_destroy_also_destroys_stream.rs new file mode 100644 index 0000000..1dea6cc --- /dev/null +++ b/zluda/tests/context_destroy_also_destroys_stream.rs @@ -0,0 +1,26 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(context_destroy_also_destroys_stream); + +unsafe fn context_destroy_also_destroys_stream(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut stream = ptr::null_mut(); + assert_eq!(cuda.cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS); + assert_eq!(cuda.cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS); + let mut _temp = ptr::null_mut(); + // CUDA segfaults here + let get_stream_ctx_err = cuda.cuStreamGetCtx(stream, &mut _temp); + assert!( + get_stream_ctx_err == CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED + || get_stream_ctx_err == CUresult::CUDA_ERROR_INVALID_HANDLE + ); +} diff --git a/zluda/tests/context_destroy_leaves_zombie.rs b/zluda/tests/context_destroy_leaves_zombie.rs new file mode 100644 index 0000000..9457749 --- /dev/null +++ b/zluda/tests/context_destroy_leaves_zombie.rs @@ -0,0 +1,54 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(context_destroy_leaves_zombie); + +unsafe fn context_destroy_leaves_zombie(cuda: T) { + assert_eq!(cuda.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!( + cuda.cuCtxCreate_v2(&mut ctx1, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx2, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx3, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS); + let mut popped_ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut popped_ctx1), + CUresult::CUDA_SUCCESS + ); + assert_eq!(popped_ctx1, ctx3); + let mut popped_ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut popped_ctx2), + CUresult::CUDA_SUCCESS + ); + assert_eq!(popped_ctx2, ctx2); + let mut popped_ctx3 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut popped_ctx3), + CUresult::CUDA_SUCCESS + ); + assert_eq!(popped_ctx3, ctx1); + let mut temp = 0; + assert_eq!( + cuda.cuCtxGetApiVersion(ctx2, &mut temp), + CUresult::CUDA_ERROR_INVALID_CONTEXT + ); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut ptr::null_mut()), + CUresult::CUDA_ERROR_INVALID_CONTEXT + ); +} diff --git a/zluda/tests/context_destroy_pops_top_of_stack.rs b/zluda/tests/context_destroy_pops_top_of_stack.rs new file mode 100644 index 0000000..f1aadf7 --- /dev/null +++ b/zluda/tests/context_destroy_pops_top_of_stack.rs @@ -0,0 +1,33 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(destroy_pops_top_of_stack); + +unsafe fn destroy_pops_top_of_stack(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx1 = ptr::null_mut(); + let mut ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx1, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx2, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS); + let mut popped_ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut popped_ctx1), + CUresult::CUDA_SUCCESS + ); + assert_eq!(popped_ctx1, ctx1); + let mut popped_ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut popped_ctx2), + CUresult::CUDA_ERROR_INVALID_CONTEXT + ); +} diff --git a/zluda/tests/context_double_destroy_fails.rs b/zluda/tests/context_double_destroy_fails.rs new file mode 100644 index 0000000..38247bb --- /dev/null +++ b/zluda/tests/context_double_destroy_fails.rs @@ -0,0 +1,23 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(double_destroy_fails); + +unsafe fn double_destroy_fails(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS); + let destroy_result = cuda.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 + ); +} diff --git a/zluda/tests/context_empty_pop_fails.rs b/zluda/tests/context_empty_pop_fails.rs new file mode 100644 index 0000000..438a18b --- /dev/null +++ b/zluda/tests/context_empty_pop_fails.rs @@ -0,0 +1,16 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(empty_pop_fails); + +unsafe fn empty_pop_fails(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxPopCurrent_v2(&mut ctx), + CUresult::CUDA_ERROR_INVALID_CONTEXT + ); +} diff --git a/zluda/tests/context_no_current_on_init.rs b/zluda/tests/context_no_current_on_init.rs new file mode 100644 index 0000000..b904f89 --- /dev/null +++ b/zluda/tests/context_no_current_on_init.rs @@ -0,0 +1,14 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(no_current_on_init); + +unsafe fn no_current_on_init(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = 1 as _; + assert_eq!(cuda.cuCtxGetCurrent(&mut ctx), CUresult::CUDA_SUCCESS); + assert_eq!(ctx, ptr::null_mut()); +} diff --git a/zluda/tests/context_push_invalid_should_crash.rs b/zluda/tests/context_push_invalid_should_crash.rs new file mode 100644 index 0000000..f1538d5 --- /dev/null +++ b/zluda/tests/context_push_invalid_should_crash.rs @@ -0,0 +1,15 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; + +mod common; + +cuda_driver_test!(context_push_invalid_should_crash); + +// This test is supposed to segfault on NV runtime, but this is impossible +// to express easily in Rust right now on Windows +unsafe fn context_push_invalid_should_crash(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut fake_ctx = vec![0usize; 32]; + let result = cuda.cuCtxPushCurrent_v2(fake_ctx.as_mut_ptr() as _); + assert_eq!(result, CUresult::CUDA_ERROR_INVALID_CONTEXT); +} diff --git a/zluda/tests/function_version.ptx b/zluda/tests/function_version.ptx new file mode 100644 index 0000000..0bec281 --- /dev/null +++ b/zluda/tests/function_version.ptx @@ -0,0 +1,5 @@ +.version 6.5 +.target sm_35 +.address_size 64 + +.entry foobar() { ret; } diff --git a/zluda/tests/function_version.rs b/zluda/tests/function_version.rs new file mode 100644 index 0000000..3238cdc --- /dev/null +++ b/zluda/tests/function_version.rs @@ -0,0 +1,67 @@ +// CUB relies on runtime reporting correct value of CU_FUNC_ATTRIBUTE_PTX_VERSION + +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(function_version); + +static KERNEL: &str = concat!(include_str!("function_version.ptx"), "\0"); + +unsafe fn function_version(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ptr::null_mut(), 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, KERNEL.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut func = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut func, module, b"foobar\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + let mut ptx_version = 0; + assert_eq!( + cuda.cuFuncGetAttribute( + &mut ptx_version, + CUfunction_attribute::CU_FUNC_ATTRIBUTE_PTX_VERSION, + func + ), + CUresult::CUDA_SUCCESS + ); + let mut kernel_binary_version = 0; + assert_eq!( + cuda.cuFuncGetAttribute( + &mut kernel_binary_version, + CUfunction_attribute::CU_FUNC_ATTRIBUTE_BINARY_VERSION, + func + ), + CUresult::CUDA_SUCCESS + ); + let mut cc_major = 0; + assert_eq!( + cuda.cuDeviceGetAttribute( + &mut cc_major, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, + CUdevice_v1(0), + ), + CUresult::CUDA_SUCCESS + ); + let mut cc_minor = 0; + assert_eq!( + cuda.cuDeviceGetAttribute( + &mut cc_minor, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, + CUdevice_v1(0), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(ptx_version, 35); + assert_eq!(kernel_binary_version, (cc_major * 10 + cc_minor)); +} diff --git a/zluda/tests/kernel_args_align.ptx b/zluda/tests/kernel_args_align.ptx new file mode 100644 index 0000000..c36ee26 --- /dev/null +++ b/zluda/tests/kernel_args_align.ptx @@ -0,0 +1,25 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry add( + .param .u32 value_arg, + .param .align 8 .b8 input[8], + .param .u64 output +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .u32 value; + .reg .u32 temp; + .reg .u32 temp2; + + ld.param.u32 value, [value_arg]; + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + + ld.u32 temp, [in_addr]; + add.u32 temp2, temp, value; + st.u32 [out_addr], temp2; + ret; +} diff --git a/zluda/tests/kernel_args_align.rs b/zluda/tests/kernel_args_align.rs new file mode 100644 index 0000000..60d7dbb --- /dev/null +++ b/zluda/tests/kernel_args_align.rs @@ -0,0 +1,81 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_args_align); + +const CU_LAUNCH_PARAM_BUFFER_POINTER: *mut c_void = 1 as *mut _; +const CU_LAUNCH_PARAM_BUFFER_SIZE: *mut c_void = 2 as *mut _; +const CU_LAUNCH_PARAM_END: *mut c_void = 0 as *mut _; + +unsafe fn kernel_args_align(cuda: T) { + let kernel = concat!(include_str!("kernel_args_align.ptx"), "\0"); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut buffer_input = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_input, 4), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemsetD32_v2(buffer_input, 2, 1), + CUresult::CUDA_SUCCESS + ); + let mut buffer_output = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_output, 4), + CUresult::CUDA_SUCCESS + ); + let mut kernel = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"add\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let x = CUdeviceptr_v2(3 as _); + let mut args = [x, buffer_input, buffer_output]; + let mut size = mem::size_of_val(&args); + let mut extra = [ + CU_LAUNCH_PARAM_BUFFER_POINTER, + args.as_mut_ptr() as *mut _ as _, + CU_LAUNCH_PARAM_BUFFER_SIZE, + &mut size as *mut _ as _, + CU_LAUNCH_PARAM_END, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + ptr::null_mut(), + extra.as_mut_ptr() + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuStreamSynchronize(ptr::null_mut()), + CUresult::CUDA_SUCCESS + ); + let mut result = 0u32; + assert_eq!( + cuda.cuMemcpyDtoH_v2(&mut result as *mut _ as _, buffer_output, 4), + CUresult::CUDA_SUCCESS + ); + assert_eq!(result, 5); +} diff --git a/zluda/tests/kernel_extra.ptx b/zluda/tests/kernel_extra.ptx new file mode 100644 index 0000000..f8a7d9f --- /dev/null +++ b/zluda/tests/kernel_extra.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/zluda/tests/kernel_extra.rs b/zluda/tests/kernel_extra.rs new file mode 100644 index 0000000..64798dc --- /dev/null +++ b/zluda/tests/kernel_extra.rs @@ -0,0 +1,70 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_extra); + +const CU_LAUNCH_PARAM_BUFFER_POINTER: *mut c_void = 1 as *mut _; +const CU_LAUNCH_PARAM_BUFFER_SIZE: *mut c_void = 2 as *mut _; +const CU_LAUNCH_PARAM_END: *mut c_void = 0 as *mut _; + +unsafe fn kernel_extra(cuda: T) { + let kernel = include_str!("kernel_extra.ptx"); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut buffer_input = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_input, 8), + CUresult::CUDA_SUCCESS + ); + let mut buffer_output = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_output, 8), + CUresult::CUDA_SUCCESS + ); + let mut kernel = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"add\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut args = [buffer_input, buffer_output]; + let mut size = mem::size_of_val(&args); + let mut extra = [ + CU_LAUNCH_PARAM_BUFFER_POINTER, + args.as_mut_ptr() as *mut _ as _, + CU_LAUNCH_PARAM_BUFFER_SIZE, + &mut size as *mut _ as _, + CU_LAUNCH_PARAM_END, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + ptr::null_mut(), + extra.as_mut_ptr() + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuStreamSynchronize(ptr::null_mut()), + CUresult::CUDA_SUCCESS + ); +} diff --git a/zluda/tests/kernel_suld.ptx b/zluda/tests/kernel_suld.ptx new file mode 100644 index 0000000..4e9b5b1 --- /dev/null +++ b/zluda/tests/kernel_suld.ptx @@ -0,0 +1,36 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .surfref image; + +.visible .entry suld( + .param .b64 output, + .param .b32 input_x, + .param .b32 input_y, + .param .b32 input_z, + .param .b64 image_bindless_param +) +{ + .reg .b32 coord_x; + .reg .b32 coord_y; + .reg .b32 coord_z; + .reg .b32 coord_depth; + .reg .u64 out_addr; + .reg .u64 image_bindless; + + ld.param.b32 coord_x, [input_x]; + ld.param.b32 coord_y, [input_y]; + ld.param.b32 coord_z, [input_z]; + ld.param.u64 out_addr, [output]; + ld.param.u64 image_bindless, [image_bindless_param]; + mov.b32 coord_depth, coord_z; + + #REG_VALUES# + + suld.b.#GEOMETRY##FORMAT#.trap #VALUES#, [#IMAGE_SRC#, #COORDINATES#]; + + st#FORMAT# [out_addr], #VALUES#; + + ret; +} diff --git a/zluda/tests/kernel_suld.rs b/zluda/tests/kernel_suld.rs new file mode 100644 index 0000000..ad6e964 --- /dev/null +++ b/zluda/tests/kernel_suld.rs @@ -0,0 +1,479 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand::distributions::Standard; +use rand::prelude::Distribution; +use rand::Rng; +use rand_chacha::rand_core::SeedableRng; +use std::fmt::Debug; +use std::fmt::{self, Write}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +const ONED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 1, + is_layered: false, + ptx_name: "1d", +}; + +const TWOD: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: false, + ptx_name: "2d", +}; + +const THREED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: false, + ptx_name: "3d", +}; + +const A1D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: true, + ptx_name: "a1d", +}; + +const A2D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: true, + ptx_name: "a2d", +}; + +struct GeometryTemplate { + geometry_dimensions: usize, + is_layered: bool, + ptx_name: &'static str, +} + +impl GeometryTemplate { + fn prepare_kernel(&self, kernel: &str) -> Result { + let coordinates = if self.is_layered { + if self.geometry_dimensions == 2 { + "{coord_depth, coord_x}" + } else if self.geometry_dimensions == 3 { + "{coord_depth, coord_x, coord_y, 0}" + } else { + unreachable!() + } + } else { + match self.geometry_dimensions { + 1 => "{coord_x}", + 2 => "{coord_x, coord_y}", + 3 => "{coord_x, coord_y, coord_z, 0}", + _ => unreachable!(), + } + }; + let mut kernel = kernel.replace("#GEOMETRY#", self.ptx_name); + kernel = kernel.replace("#COORDINATES#", coordinates); + Ok(kernel) + } + + fn set_descriptor(&self, desc: &mut CUDA_ARRAY3D_DESCRIPTOR, size: usize) { + desc.Width = size; + if self.is_layered { + desc.Flags |= CUDA_ARRAY3D_LAYERED; + desc.Depth = size; + if self.geometry_dimensions >= 3 { + desc.Height = size; + } + } else { + if self.geometry_dimensions >= 2 { + desc.Height = size; + } + if self.geometry_dimensions >= 3 { + desc.Depth = size; + } + } + } + + fn set_memcpy(&self, memcpy_desc: &mut CUDA_MEMCPY3D, size: usize, size_of_pixel: u32) { + memcpy_desc.WidthInBytes = size_of_pixel as usize * size; + if self.is_layered { + memcpy_desc.Depth = size; + if self.geometry_dimensions >= 3 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + } else { + if self.geometry_dimensions >= 2 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + if self.geometry_dimensions >= 3 { + memcpy_desc.Depth = size; + } else { + memcpy_desc.Depth = 1; + } + } + } + + fn address(&self, size: usize, x: u32, y: u32, z: u32, size_of_pixel: u32) -> usize { + match (self.is_layered, self.geometry_dimensions) { + (true, 3) => { + (z as usize * size * size) + (y as usize * size) + ((x / size_of_pixel) as usize) + } + (true, 2) => (z as usize * size) + ((x / size_of_pixel) as usize), + (false, 3) => { + (z as usize * size * size) + (y as usize * size) + ((x / size_of_pixel) as usize) + } + (false, 2) => (y as usize * size) + ((x / size_of_pixel) as usize), + (false, 1) => (x / size_of_pixel) as usize, + _ => unreachable!(), + } + } +} + +fn prepare_kernel_values( + kernel: &str, + bindless: bool, +) -> Result { + let mut param_values = String::new(); + let mut reg_values = String::new(); + let mut values = String::new(); + values.push('{'); + for dim in 0..N { + write!( + param_values, + ".param .{} param_value_{}", + U::ptx_type(), + dim + )?; + if dim != N - 1 { + param_values.push_str(","); + } + writeln!(reg_values, ".reg .{} value_{};", U::ptx_type(), dim)?; + write!(values, "value_{}", dim)?; + if dim != N - 1 { + write!(values, ",")?; + } + } + values.push('}'); + let vec_prefix = match N { + 0 | 1 => ".", + 2 => ".v2.", + 4 => ".v4.", + _ => panic!(), + }; + let mut format = vec_prefix.to_string(); + format.push_str(U::ptx_type()); + let mut kernel = kernel.replace("#PARAM_VALUES#", ¶m_values); + kernel = kernel.replace("#REG_VALUES#", ®_values); + kernel = kernel.replace("#VALUES#", &values); + kernel = kernel.replace("#FORMAT#", &format); + kernel = kernel.replace( + "#IMAGE_SRC#", + if bindless { "image_bindless" } else { "image" }, + ); + Ok(kernel) +} + +fn sizeof_pixel(format: CUarray_format, channels: u32) -> u32 { + let channel_size = match format { + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8 | CUarray_format::CU_AD_FORMAT_SIGNED_INT8 => 1, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_HALF => 2, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_FLOAT => 4, + _ => unimplemented!(), + }; + channel_size * channels +} + +macro_rules! format_to_type { + (CU_AD_FORMAT_UNSIGNED_INT8) => { + u8 + }; + (CU_AD_FORMAT_UNSIGNED_INT16) => { + i16 + }; + (CU_AD_FORMAT_UNSIGNED_INT32) => { + i32 + }; + (CU_AD_FORMAT_SIGNED_INT8) => { + i8 + }; + (CU_AD_FORMAT_SIGNED_INT16) => { + i16 + }; + (CU_AD_FORMAT_SIGNED_INT32) => { + i32 + }; + (CU_AD_FORMAT_HALF) => { + half::f16 + }; + (CU_AD_FORMAT_FLOAT) => { + f32 + }; +} + +use paste::paste; +macro_rules! generate_tests { + ($format:tt, $channels:tt, $geometry:tt, $inst_size:tt, $inst_vec:tt)=> { + generate_tests!(@level1 $format, {$channels, {$geometry, {$inst_size, {$inst_vec}}}}); + }; + (@level1 [$($format:expr),+], $rest:tt) => { + $(generate_tests!(@level2 $format, $rest);)+ + }; + (@level2 $format:expr, {[$($channels:expr),+], $rest:tt}) => { + $(generate_tests!(@level3 $format, $channels, $rest);)+ + }; + (@level3 $format:expr, $channels:expr, {[$($geometry:expr),+], $rest:tt}) => { + $(generate_tests!(@level4 $format, $channels, $geometry, $rest);)+ + }; + (@level4 $format:expr, $channels:expr, $geometry:expr, {[$($inst_size:expr),+], $rest:tt}) => { + $(generate_tests!(@level5 $format, $channels, $geometry, $inst_size, $rest);)+ + }; + (@level5 $format:expr, $channels:expr, $geometry:expr, $inst_size:expr, {[$($inst_vec:expr),+]}) => { + $( + paste! { + #[allow(non_snake_case)] + unsafe fn [] (cuda: T) { + kernel_suld_impl::(cuda, &$geometry, 0xef5864bda7b0b60f, CUarray_format:: $format, false) + } + cuda_driver_test!([]); + + #[allow(non_snake_case)] + unsafe fn [] (cuda: T) { + kernel_suld_impl::(cuda, &$geometry, 0xef5864bda7b0b60f, CUarray_format:: $format, true) + } + cuda_driver_test!([]); + } + )+ + }; +} + +generate_tests!( + [ + CU_AD_FORMAT_UNSIGNED_INT8, + CU_AD_FORMAT_UNSIGNED_INT16, + CU_AD_FORMAT_UNSIGNED_INT32, + CU_AD_FORMAT_SIGNED_INT8, + CU_AD_FORMAT_SIGNED_INT16, + CU_AD_FORMAT_SIGNED_INT32, + CU_AD_FORMAT_HALF, + CU_AD_FORMAT_FLOAT + ], + [1, 2, 4], + [ONED, TWOD, THREED, A1D, A2D], + [u8, u16, u32, u64], + [1, 2, 4] +); + +trait SustValue: Copy + Default + Debug + PartialEq { + fn ptx_type() -> &'static str; +} + +impl SustValue for u8 { + fn ptx_type() -> &'static str { + "b8" + } +} + +impl SustValue for u16 { + fn ptx_type() -> &'static str { + "b16" + } +} + +impl SustValue for u32 { + fn ptx_type() -> &'static str { + "b32" + } +} + +impl SustValue for u64 { + fn ptx_type() -> &'static str { + "b64" + } +} + +unsafe fn as_bytes_mut<'a, T>(t: &'a mut T) -> &'a mut [u8] { + std::slice::from_raw_parts_mut::(t as *mut T as _, mem::size_of::()) +} + +unsafe fn byte_fill(vec: &mut Vec, value: u8) { + let mut_view = std::slice::from_raw_parts_mut::( + vec.as_mut_ptr() as _, + mem::size_of::() * vec.len(), + ); + mut_view.fill(value); +} + +const BYTE_FILLER1: u8 = 0xff; +const BYTE_FILLER2: u8 = 0xfe; +const BYTE_FILLER3: u8 = 0xfd; + +#[repr(C)] +union UnionHack { + from: From, + to: To, +} + +unsafe fn force_transmute(f: From, filler: u8) -> To { + let mut u: UnionHack = mem::zeroed(); + as_bytes_mut(&mut u).fill(filler); + u.from = f; + u.to +} + +unsafe fn kernel_suld_impl< + T: CudaDriverFns, + Format: Default + Copy + Debug, + const CHANNELS: usize, + SustType: SustValue, + const SULD_N: usize, +>( + cuda: T, + geo: &GeometryTemplate, + seed: u64, + format: CUarray_format, + bindless: bool, +) where + Standard: Distribution, +{ + // CUDA kernels fail at runtime if the pixel is smaller than `sust` write size + if mem::size_of::() * CHANNELS < mem::size_of::() * SULD_N { + return; + } + // TODO: reenable those tests + if mem::size_of::() != mem::size_of::() || CHANNELS != SULD_N { + return; + } + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed); + let size = 4usize; + let random_size = rand::distributions::Uniform::::new(1, size as u32); + let mut kernel = include_str!("kernel_suld.ptx").to_string(); + kernel = geo.prepare_kernel(&kernel).unwrap(); + kernel = prepare_kernel_values::(&kernel, bindless).unwrap(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + // We use primary context, because creating&destroying a normal context + // means creating and destroying a thread, which is relatively slow + assert_eq!( + cuda.cuDevicePrimaryCtxRetain(&mut ctx, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxSetCurrent(ctx), CUresult::CUDA_SUCCESS); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut array = ptr::null_mut(); + let depth = size; + let width = size; + let height = size; + let mut descriptor = mem::zeroed::(); + descriptor.Flags = CUDA_ARRAY3D_SURFACE_LDST; + descriptor.Format = format; + descriptor.NumChannels = CHANNELS as u32; + geo.set_descriptor(&mut descriptor, size); + let mut host_side_data = + vec![[::default(); CHANNELS]; width * height * depth]; + byte_fill(&mut host_side_data, BYTE_FILLER1); + let sizeof_pixel = sizeof_pixel(format, CHANNELS as u32); + let x = random_size.sample(&mut rng) * sizeof_pixel; + let y = random_size.sample(&mut rng); + let z = random_size.sample(&mut rng); + let values = [rng.gen::(); SULD_N]; + let converted_values = force_transmute(values, BYTE_FILLER3); + *host_side_data.get_unchecked_mut(geo.address(size, x, y, z, sizeof_pixel)) = converted_values; + assert_eq!( + cuda.cuArray3DCreate_v2(&mut array, &descriptor), + CUresult::CUDA_SUCCESS + ); + let mut bindless_image = 0u64; + if bindless { + assert_eq!( + cuda.cuSurfObjectCreate( + &mut bindless_image, + &CUDA_RESOURCE_DESC { + resType: CUresourcetype::CU_RESOURCE_TYPE_ARRAY, + res: CUDA_RESOURCE_DESC_st__bindgen_ty_1 { + array: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_1 { hArray: array } + }, + flags: 0 + } + ), + CUresult::CUDA_SUCCESS + ); + } else { + let mut surfref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetSurfRef(&mut surfref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuSurfRefSetArray(surfref, array, 0), + CUresult::CUDA_SUCCESS + ); + } + let mut memcpy_desc = mem::zeroed::(); + geo.set_memcpy(&mut memcpy_desc, size, sizeof_pixel); + memcpy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_desc.srcHost = host_side_data.as_mut_ptr() as _; + memcpy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_desc.dstArray = array; + assert_eq!(cuda.cuMemcpy3D_v2(&memcpy_desc), CUresult::CUDA_SUCCESS); + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"suld\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut device_memory = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut device_memory, mem::size_of::() * SULD_N), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemsetD8_v2( + device_memory, + BYTE_FILLER2, + mem::size_of::() * SULD_N + ), + CUresult::CUDA_SUCCESS + ); + let mut args = vec![ + &device_memory as *const _ as *const c_void, + &x as *const _ as *const c_void, + &y as *const _ as *const _, + &z as *const _ as *const _, + &bindless_image as *const _ as *const _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); + let mut actual_values = [SustType::default(); SULD_N]; + let actual_values_buffer = as_bytes_mut(&mut actual_values); + assert_eq!( + cuda.cuMemcpyDtoH_v2( + actual_values_buffer.as_mut_ptr() as _, + device_memory, + actual_values_buffer.len(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(values, actual_values); + let mut unused = mem::zeroed(); + assert_eq!(cuda.cuCtxPopCurrent(&mut unused), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/kernel_sust.ptx b/zluda/tests/kernel_sust.ptx new file mode 100644 index 0000000..2a943ee --- /dev/null +++ b/zluda/tests/kernel_sust.ptx @@ -0,0 +1,31 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .surfref image; + +.visible .entry sust( + .param .b32 input_x, + .param .b32 input_y, + .param .b32 input_z, + .param .b64 image_bindless_param, + #PARAM_VALUES# +) +{ + .reg .b32 coord_x; + .reg .b32 coord_y; + .reg .b32 coord_z; + .reg .b32 coord_depth; + .reg .u64 image_bindless; + + ld.param.b32 coord_x, [input_x]; + ld.param.b32 coord_y, [input_y]; + ld.param.b32 coord_z, [input_z]; + ld.param.u64 image_bindless, [image_bindless_param]; + mov.b32 coord_depth, coord_z; + + #REG_VALUES# + + sust.b.#GEOMETRY##FORMAT#.trap [#IMAGE_SRC#, #COORDINATES#], #VALUES#; + ret; +} diff --git a/zluda/tests/kernel_sust.rs b/zluda/tests/kernel_sust.rs new file mode 100644 index 0000000..831e467 --- /dev/null +++ b/zluda/tests/kernel_sust.rs @@ -0,0 +1,464 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand::distributions::Standard; +use rand::prelude::Distribution; +use rand::Rng; +use rand_chacha::rand_core::SeedableRng; +use std::fmt::Debug; +use std::fmt::{self, Write}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +const ONED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 1, + is_layered: false, + ptx_name: "1d", +}; + +const TWOD: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: false, + ptx_name: "2d", +}; + +const THREED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: false, + ptx_name: "3d", +}; + +const A1D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: true, + ptx_name: "a1d", +}; + +const A2D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: true, + ptx_name: "a2d", +}; + +struct GeometryTemplate { + geometry_dimensions: usize, + is_layered: bool, + ptx_name: &'static str, +} + +impl GeometryTemplate { + fn prepare_kernel(&self, kernel: &str) -> Result { + let coordinates = if self.is_layered { + if self.geometry_dimensions == 2 { + "{coord_depth, coord_x}" + } else if self.geometry_dimensions == 3 { + "{coord_depth, coord_x, coord_y, 0}" + } else { + unreachable!() + } + } else { + match self.geometry_dimensions { + 1 => "{coord_x}", + 2 => "{coord_x, coord_y}", + 3 => "{coord_x, coord_y, coord_z, 0}", + _ => unreachable!(), + } + }; + let mut kernel = kernel.replace("#GEOMETRY#", self.ptx_name); + kernel = kernel.replace("#COORDINATES#", coordinates); + Ok(kernel) + } + + fn set_descriptor(&self, desc: &mut CUDA_ARRAY3D_DESCRIPTOR, size: usize) { + desc.Width = size; + if self.is_layered { + desc.Flags |= CUDA_ARRAY3D_LAYERED; + desc.Depth = size; + if self.geometry_dimensions >= 3 { + desc.Height = size; + } + } else { + if self.geometry_dimensions >= 2 { + desc.Height = size; + } + if self.geometry_dimensions >= 3 { + desc.Depth = size; + } + } + } + + fn set_memcpy(&self, memcpy_desc: &mut CUDA_MEMCPY3D, size: usize, size_of_pixel: u32) { + memcpy_desc.WidthInBytes = size_of_pixel as usize * size; + if self.is_layered { + memcpy_desc.Depth = size; + if self.geometry_dimensions >= 3 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + } else { + if self.geometry_dimensions >= 2 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + if self.geometry_dimensions >= 3 { + memcpy_desc.Depth = size; + } else { + memcpy_desc.Depth = 1; + } + } + } + + fn address(&self, size: usize, x: u32, y: u32, z: u32, size_of_pixel: u32) -> usize { + match (self.is_layered, self.geometry_dimensions) { + (true, 3) => { + (z as usize * size * size) + (y as usize * size) + ((x / size_of_pixel) as usize) + } + (true, 2) => (z as usize * size) + ((x / size_of_pixel) as usize), + (false, 3) => { + (z as usize * size * size) + (y as usize * size) + ((x / size_of_pixel) as usize) + } + (false, 2) => (y as usize * size) + ((x / size_of_pixel) as usize), + (false, 1) => (x / size_of_pixel) as usize, + _ => unreachable!(), + } + } +} + +fn prepare_kernel_values( + kernel: &str, + bindless: bool, +) -> Result { + let mut param_values = String::new(); + let mut reg_values = String::new(); + let mut values = String::new(); + values.push('{'); + for dim in 0..N { + write!( + param_values, + ".param .{} param_value_{}", + U::ptx_type(), + dim + )?; + if dim != N - 1 { + param_values.push_str(","); + } + writeln!(reg_values, ".reg .{} value_{};", U::ptx_type(), dim)?; + writeln!( + reg_values, + "ld.param.{0} value_{1}, [param_value_{1}];", + U::ptx_type(), + dim + )?; + write!(values, "value_{}", dim)?; + if dim != N - 1 { + write!(values, ",")?; + } + } + values.push('}'); + let vec_prefix = match N { + 0 | 1 => ".", + 2 => ".v2.", + 4 => ".v4.", + _ => panic!(), + }; + let mut format = vec_prefix.to_string(); + format.push_str(U::ptx_type()); + let mut kernel = kernel.replace("#PARAM_VALUES#", ¶m_values); + kernel = kernel.replace("#REG_VALUES#", ®_values); + kernel = kernel.replace("#VALUES#", &values); + kernel = kernel.replace("#FORMAT#", &format); + kernel = kernel.replace( + "#IMAGE_SRC#", + if bindless { "image_bindless" } else { "image" }, + ); + Ok(kernel) +} + +fn sizeof_pixel(format: CUarray_format, channels: u32) -> u32 { + let channel_size = match format { + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8 | CUarray_format::CU_AD_FORMAT_SIGNED_INT8 => 1, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_HALF => 2, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_FLOAT => 4, + _ => unimplemented!(), + }; + channel_size * channels +} + +macro_rules! format_to_type { + (CU_AD_FORMAT_UNSIGNED_INT8) => { + u8 + }; + (CU_AD_FORMAT_UNSIGNED_INT16) => { + i16 + }; + (CU_AD_FORMAT_UNSIGNED_INT32) => { + i32 + }; + (CU_AD_FORMAT_SIGNED_INT8) => { + i8 + }; + (CU_AD_FORMAT_SIGNED_INT16) => { + i16 + }; + (CU_AD_FORMAT_SIGNED_INT32) => { + i32 + }; + (CU_AD_FORMAT_HALF) => { + half::f16 + }; + (CU_AD_FORMAT_FLOAT) => { + f32 + }; +} + +use paste::paste; +macro_rules! generate_tests { + ($format:tt, $channels:tt, $geometry:tt, $inst_size:tt, $inst_vec:tt)=> { + generate_tests!(@level1 $format, {$channels, {$geometry, {$inst_size, {$inst_vec}}}}); + }; + (@level1 [$($format:expr),+], $rest:tt) => { + $(generate_tests!(@level2 $format, $rest);)+ + }; + (@level2 $format:expr, {[$($channels:expr),+], $rest:tt}) => { + $(generate_tests!(@level3 $format, $channels, $rest);)+ + }; + (@level3 $format:expr, $channels:expr, {[$($geometry:expr),+], $rest:tt}) => { + $(generate_tests!(@level4 $format, $channels, $geometry, $rest);)+ + }; + (@level4 $format:expr, $channels:expr, $geometry:expr, {[$($inst_size:expr),+], $rest:tt}) => { + $(generate_tests!(@level5 $format, $channels, $geometry, $inst_size, $rest);)+ + }; + (@level5 $format:expr, $channels:expr, $geometry:expr, $inst_size:expr, {[$($inst_vec:expr),+]}) => { + $( + paste! { + #[allow(non_snake_case)] + unsafe fn [] (cuda: T) { + kernel_sust_impl::(cuda, &$geometry, 0xef5864bda7b0b60f, CUarray_format:: $format, false) + } + cuda_driver_test!([]); + + #[allow(non_snake_case)] + unsafe fn [] (cuda: T) { + kernel_sust_impl::(cuda, &$geometry, 0xef5864bda7b0b60f, CUarray_format:: $format, true) + } + cuda_driver_test!([]); + } + )+ + }; +} + +generate_tests!( + [ + CU_AD_FORMAT_UNSIGNED_INT8, + CU_AD_FORMAT_UNSIGNED_INT16, + CU_AD_FORMAT_UNSIGNED_INT32, + CU_AD_FORMAT_SIGNED_INT8, + CU_AD_FORMAT_SIGNED_INT16, + CU_AD_FORMAT_SIGNED_INT32, + CU_AD_FORMAT_HALF, + CU_AD_FORMAT_FLOAT + ], + [1, 2, 4], + [ONED, TWOD, THREED, A1D, A2D], + [u8, u16, u32, u64], + [1, 2, 4] +); + +trait SustValue: Copy + Default + Debug + PartialEq { + fn ptx_type() -> &'static str; +} + +impl SustValue for u8 { + fn ptx_type() -> &'static str { + "b8" + } +} + +impl SustValue for u16 { + fn ptx_type() -> &'static str { + "b16" + } +} + +impl SustValue for u32 { + fn ptx_type() -> &'static str { + "b32" + } +} + +impl SustValue for u64 { + fn ptx_type() -> &'static str { + "b64" + } +} + +unsafe fn as_bytes<'a, T>(t: &'a T) -> &'a [u8] { + std::slice::from_raw_parts::(t as *const T as _, mem::size_of::()) +} + +unsafe fn byte_fill(vec: &mut Vec, value: u8) { + let mut_view = std::slice::from_raw_parts_mut::( + vec.as_mut_ptr() as _, + mem::size_of::() * vec.len(), + ); + mut_view.fill(value); +} + +fn extend_bytes_with(slice: &[u8], elm: u8, desired_length: usize) -> Vec { + let mut result = slice.to_vec(); + result.extend(std::iter::repeat(elm).take(desired_length - slice.len())); + result +} + +const BYTE_FILLER: u8 = 0x7f; + +unsafe fn kernel_sust_impl< + T: CudaDriverFns, + Format: Default + Copy + Debug, + const CHANNELS: usize, + SustType: SustValue, + const SUST_N: usize, +>( + cuda: T, + geo: &GeometryTemplate, + seed: u64, + format: CUarray_format, + bindless: bool, +) where + Standard: Distribution, +{ + // CUDA kernels fail at runtime if the pixel is smaller than `sust` write size + if mem::size_of::() * CHANNELS < mem::size_of::() * SUST_N { + return; + } + // TODO: reenable those tests + if mem::size_of::() != mem::size_of::() || CHANNELS != SUST_N { + return; + } + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed); + let size = 4usize; + let random_size = rand::distributions::Uniform::::new(1, size as u32); + let mut kernel = include_str!("kernel_sust.ptx").to_string(); + kernel = geo.prepare_kernel(&kernel).unwrap(); + kernel = prepare_kernel_values::(&kernel, bindless).unwrap(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + // We use primary context, because creating&destroying a normal context + // means creating and destroying a thread, which is relatively slow + assert_eq!( + cuda.cuDevicePrimaryCtxRetain(&mut ctx, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxSetCurrent(ctx), CUresult::CUDA_SUCCESS); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut array = ptr::null_mut(); + let depth = size; + let width = size; + let height = size; + let mut descriptor = mem::zeroed::(); + descriptor.Flags = CUDA_ARRAY3D_SURFACE_LDST; + descriptor.Format = format; + descriptor.NumChannels = CHANNELS as u32; + geo.set_descriptor(&mut descriptor, size); + let mut host_side_data = + vec![[::default(); CHANNELS]; width * height * depth]; + byte_fill(&mut host_side_data, BYTE_FILLER); + assert_eq!( + cuda.cuArray3DCreate_v2(&mut array, &descriptor), + CUresult::CUDA_SUCCESS + ); + let mut bindless_image = 0u64; + + if bindless { + assert_eq!( + cuda.cuSurfObjectCreate( + &mut bindless_image, + &CUDA_RESOURCE_DESC { + resType: CUresourcetype::CU_RESOURCE_TYPE_ARRAY, + res: CUDA_RESOURCE_DESC_st__bindgen_ty_1 { + array: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_1 { hArray: array } + }, + flags: 0 + } + ), + CUresult::CUDA_SUCCESS + ); + } else { + let mut surfref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetSurfRef(&mut surfref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuSurfRefSetArray(surfref, array, 0), + CUresult::CUDA_SUCCESS + ); + } + let sizeof_pixel = sizeof_pixel(format, CHANNELS as u32); + let mut memcpy_desc = mem::zeroed::(); + geo.set_memcpy(&mut memcpy_desc, size, sizeof_pixel); + memcpy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_desc.srcHost = host_side_data.as_mut_ptr() as _; + memcpy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_desc.dstArray = array; + assert_eq!(cuda.cuMemcpy3D_v2(&memcpy_desc), CUresult::CUDA_SUCCESS); + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"sust\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let x = random_size.sample(&mut rng) * sizeof_pixel; + let y = random_size.sample(&mut rng); + let z = random_size.sample(&mut rng); + let values = [rng.gen::(); SUST_N]; + let mut args = vec![ + &x as *const _ as *const c_void, + &y as *const _ as *const _, + &z as *const _ as *const _, + &bindless_image as *const _ as *const _, + ]; + args.extend( + values + .iter() + .map(|u: &SustType| u as *const SustType as *const c_void), + ); + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); + byte_fill(&mut host_side_data, 0xff); + memcpy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_desc.srcArray = array; + memcpy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_desc.dstHost = host_side_data.as_mut_ptr() as _; + assert_eq!(cuda.cuMemcpy3D_v2(&memcpy_desc), CUresult::CUDA_SUCCESS); + let observed = as_bytes(&host_side_data[geo.address(size, x, y, z, sizeof_pixel)]); + let expected = extend_bytes_with(as_bytes(&values), BYTE_FILLER, observed.len()); + assert_eq!(expected, &*observed); + let mut unused = mem::zeroed(); + assert_eq!(cuda.cuCtxPopCurrent(&mut unused), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/kernel_tex.ptx b/zluda/tests/kernel_tex.ptx new file mode 100644 index 0000000..b231f3c --- /dev/null +++ b/zluda/tests/kernel_tex.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_60 +.address_size 64 + +.global .texref image; + +.visible .entry tex( + .param .b64 output, + .param .#COORDINATE_TYPE# input_x, + .param .#COORDINATE_TYPE# input_y, + .param .#COORDINATE_TYPE# input_z, + .param .u32 input_depth +) +{ + .reg .u64 out_addr; + .reg .#COORDINATE_TYPE# coord_x; + .reg .#COORDINATE_TYPE# coord_y; + .reg .#COORDINATE_TYPE# coord_z; + .reg .u32 coord_depth; + + ld.param.u64 out_addr, [output]; + ld.param.#COORDINATE_TYPE# coord_x, [input_x]; + ld.param.#COORDINATE_TYPE# coord_y, [input_y]; + ld.param.#COORDINATE_TYPE# coord_z, [input_z]; + ld.param.b32 coord_depth, [input_depth]; + + #REG_VALUES# + + tex.#GEOMETRY#.v4.#VALUE_TYPE#.#COORDINATE_TYPE# #VALUES#, [image, #COORDINATES#]; + + st.global.v4.#VALUE_STORAGE_TYPE# [out_addr], #VALUES#; + + ret; +} diff --git a/zluda/tests/kernel_tex.rs b/zluda/tests/kernel_tex.rs new file mode 100644 index 0000000..6b2d1d3 --- /dev/null +++ b/zluda/tests/kernel_tex.rs @@ -0,0 +1,666 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use half::f16; +use num_traits::AsPrimitive; +use rand::prelude::Distribution; +use rand_chacha::rand_core::SeedableRng; +use std::any::Any; +use std::fmt::Debug; +use std::fmt::{self, Write}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +const ONED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 1, + is_layered: false, + ptx_name: "1d", +}; + +const TWOD: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: false, + ptx_name: "2d", +}; + +const THREED: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: false, + ptx_name: "3d", +}; + +const A1D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 2, + is_layered: true, + ptx_name: "a1d", +}; + +const A2D: GeometryTemplate = GeometryTemplate { + geometry_dimensions: 3, + is_layered: true, + ptx_name: "a2d", +}; + +struct GeometryTemplate { + geometry_dimensions: usize, + is_layered: bool, + ptx_name: &'static str, +} + +impl GeometryTemplate { + fn prepare_kernel(&self, kernel: &str) -> Result { + let coordinates = if self.is_layered { + if self.geometry_dimensions == 2 { + "{coord_depth, coord_x}" + } else if self.geometry_dimensions == 3 { + "{coord_depth, coord_x, coord_y, coord_y}" + } else { + unreachable!() + } + } else { + match self.geometry_dimensions { + 1 => "{coord_x}", + 2 => "{coord_x, coord_y}", + 3 => "{coord_x, coord_y, coord_z, coord_z}", + _ => unreachable!(), + } + }; + let mut kernel = kernel.replace("#GEOMETRY#", self.ptx_name); + kernel = kernel.replace("#COORDINATES#", coordinates); + Ok(kernel) + } + + fn set_descriptor(&self, desc: &mut CUDA_ARRAY3D_DESCRIPTOR, size: usize) { + desc.Width = size; + if self.is_layered { + desc.Flags |= CUDA_ARRAY3D_LAYERED; + desc.Depth = size; + if self.geometry_dimensions >= 3 { + desc.Height = size; + } + } else { + if self.geometry_dimensions >= 2 { + desc.Height = size; + } + if self.geometry_dimensions >= 3 { + desc.Depth = size; + } + } + } + + fn set_memcpy(&self, memcpy_desc: &mut CUDA_MEMCPY3D, size: usize, size_of_pixel: u32) { + memcpy_desc.WidthInBytes = size_of_pixel as usize * size; + if self.is_layered { + memcpy_desc.Depth = size; + if self.geometry_dimensions >= 3 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + } else { + if self.geometry_dimensions >= 2 { + memcpy_desc.Height = size; + } else { + memcpy_desc.Height = 1; + } + if self.geometry_dimensions >= 3 { + memcpy_desc.Depth = size; + } else { + memcpy_desc.Depth = 1; + } + } + } + + fn address(&self, size: usize, x: u32, y: u32, z: u32, depth: u32) -> usize { + match (self.is_layered, self.geometry_dimensions) { + (true, 3) => (depth as usize * size * size) + (y as usize * size) + (x as usize), + (true, 2) => (depth as usize * size) + (x as usize), + (false, 3) => (z as usize * size * size) + (y as usize * size) + (x as usize), + (false, 2) => (y as usize * size) + (x as usize), + (false, 1) => x as usize, + _ => unreachable!(), + } + } +} + +fn prepare_kernel_values( + kernel: &str, +) -> Result { + let coordinate_type = Coordinate::ptx_type(); + let value_type = Value::ptx_type(); + let value_storage_type = Value::ptx_storage_type(); + let mut reg_values = String::new(); + let mut values = String::new(); + values.push('{'); + for dim in 0..4 { + write!(values, "value_{}", dim)?; + if dim != 4 - 1 { + write!(values, ",")?; + } + writeln!(reg_values, ".reg .{} value_{};", Value::ptx_type(), dim)?; + } + values.push('}'); + let mut kernel = kernel.replace("#COORDINATE_TYPE#", coordinate_type); + kernel = kernel.replace("#VALUE_TYPE#", value_type); + kernel = kernel.replace("#VALUE_STORAGE_TYPE#", value_storage_type); + kernel = kernel.replace("#REG_VALUES#", ®_values); + kernel = kernel.replace("#VALUES#", &values); + Ok(kernel) +} + +macro_rules! format_to_type { + (CU_AD_FORMAT_UNSIGNED_INT8) => { + u8 + }; + (CU_AD_FORMAT_UNSIGNED_INT16) => { + u16 + }; + (CU_AD_FORMAT_UNSIGNED_INT32) => { + u32 + }; + (CU_AD_FORMAT_SIGNED_INT8) => { + i8 + }; + (CU_AD_FORMAT_SIGNED_INT16) => { + i16 + }; + (CU_AD_FORMAT_SIGNED_INT32) => { + i32 + }; + (CU_AD_FORMAT_HALF) => { + half::f16 + }; + (CU_AD_FORMAT_FLOAT) => { + f32 + }; +} + +use paste::paste; +macro_rules! generate_tests { + ($format:tt, $channels:tt, $geometry:tt, $inst_size:tt, $inst_vec:tt)=> { + generate_tests!(@level1 $format, {$channels, {$geometry, {$inst_size, {$inst_vec}}}}); + }; + (@level1 [$($format:expr),+], $rest:tt) => { + $(generate_tests!(@level2 $format, $rest);)+ + }; + (@level2 $format:expr, {[$($channels:expr),+], $rest:tt}) => { + $(generate_tests!(@level3 $format, $channels, $rest);)+ + }; + (@level3 $format:expr, $channels:expr, {[$($geometry:expr),+], $rest:tt}) => { + $(generate_tests!(@level4 $format, $channels, $geometry, $rest);)+ + }; + (@level4 $format:expr, $channels:expr, $geometry:expr, {[$($inst_size:expr),+], $rest:tt}) => { + $(generate_tests!(@level5 $format, $channels, $geometry, $inst_size, $rest);)+ + }; + (@level5 $format:expr, $channels:expr, $geometry:expr, $value_type:expr, {[$($coord_type:expr),+]}) => { + $( + paste! { + #[allow(non_snake_case)] + unsafe fn [] (cuda: T) { + kernel_tex_impl::(cuda, &$geometry, 0xef5864bda7b0b60f, CUarray_format:: $format) + } + cuda_driver_test!([]); + } + )+ + }; +} + +generate_tests!( + [ + CU_AD_FORMAT_UNSIGNED_INT8, + CU_AD_FORMAT_UNSIGNED_INT16, + CU_AD_FORMAT_UNSIGNED_INT32, + CU_AD_FORMAT_SIGNED_INT8, + CU_AD_FORMAT_SIGNED_INT16, + CU_AD_FORMAT_SIGNED_INT32, + //CU_AD_FORMAT_HALF, + CU_AD_FORMAT_FLOAT + ], + [1, 2, 4], + [ONED, TWOD, THREED, A1D, A2D], + [u32, i32, f16, f32], + [i32, f32] +); + +trait SustValue: Copy + Default + Debug + PartialEq + 'static + Any { + fn ptx_type() -> &'static str; + fn ptx_storage_type() -> &'static str { + Self::ptx_type() + } + fn gen(rng: &mut R) -> Self; +} + +impl SustValue for u8 { + fn ptx_type() -> &'static str { + "b8" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for u16 { + fn ptx_type() -> &'static str { + "b16" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for u32 { + fn ptx_type() -> &'static str { + "u32" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for u64 { + fn ptx_type() -> &'static str { + "b64" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for i8 { + fn ptx_type() -> &'static str { + "b8" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for i16 { + fn ptx_type() -> &'static str { + "b16" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for i32 { + fn ptx_type() -> &'static str { + "s32" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +impl SustValue for f16 { + fn ptx_type() -> &'static str { + "f16" + } + + fn ptx_storage_type() -> &'static str { + "b16" + } + + fn gen(rng: &mut R) -> Self { + f16::from_f32(rng.gen::()) + } +} + +impl SustValue for f32 { + fn ptx_type() -> &'static str { + "f32" + } + + fn gen(rng: &mut R) -> Self { + rng.gen::() + } +} + +unsafe fn byte_fill(vec: &mut [T], value: u8) { + let mut_view = std::slice::from_raw_parts_mut::( + vec.as_mut_ptr() as _, + mem::size_of::() * vec.len(), + ); + mut_view.fill(value); +} + +const BYTE_FILLER1: u8 = 0xff; +const BYTE_FILLER2: u8 = 0xfe; + +unsafe fn force_transmute(f: From) -> To { + if mem::size_of::() == mem::size_of::() + && mem::size_of::() == mem::size_of::() + { + return mem::transmute_copy(&f); + } + if mem::size_of::() == mem::size_of::() { + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&((value.to_f64() / f16::MAX.to_f64()) as f32)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&((*value as f64 / u8::MAX as f64) as f32)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&((*value as f64 / u16::MAX as f64) as f32)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&((*value as f64 / i8::MAX as f64) as f32)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&((*value as f64 / i16::MAX as f64) as f32)); + } + } + if mem::size_of::() == mem::size_of::() { + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f64(*value as f64 / u8::MAX as f64)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f64(*value as f64 / i8::MAX as f64)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f32(mem::transmute::<_, f32>(*value))); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f32(mem::transmute::<_, f32>(*value))); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f64(*value as f64 / u16::MAX as f64)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f64(*value as f64 / i16::MAX as f64)); + } + if let Some(value) = ::downcast_ref::(&f) { + return mem::transmute_copy(&f16::from_f32(*value)); + } + } + panic!() +} + +unsafe fn kernel_tex_impl< + T: CudaDriverFns, + Format: SustValue, + const CHANNELS: usize, + ValueType: SustValue, + CoordinateType: SustValue + 'static + AsPrimitive, +>( + cuda: T, + geo: &GeometryTemplate, + seed: u64, + format: CUarray_format, +) where + u32: AsPrimitive, + Format: AsPrimitive, +{ + // Experimentally, tex1Dfetch (aka tex.1d with s32 index) behaves like + // buffer indexing and ignores pixel channel+format information + if geo.geometry_dimensions == 1 + && CoordinateType::ptx_type() == "s32" + && (CHANNELS != 1 || mem::size_of::() != mem::size_of::()) + { + return; + } + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed); + let size = 4usize; + let random_size = rand::distributions::Uniform::::new(1, size as u32); + let _ctx = create_context::(&cuda); + let (kernel, texref) = create_kernel_texref::(&cuda, geo); + let host_side_texref = create_host_side_data::(size, &mut rng); + create_array::( + &cuda, + geo, + format, + size, + texref, + &host_side_texref, + ); + let result_buffer = allocate_result_buffer::(&cuda); + let x_u32 = random_size.sample(&mut rng); + let x = x_u32.as_(); + let y_u32 = random_size.sample(&mut rng); + let y = y_u32.as_(); + let z_u32 = random_size.sample(&mut rng); + let z = z_u32.as_(); + let depth = random_size.sample(&mut rng); + launch_kernel::(&cuda, kernel, result_buffer, x, y, z, depth); + let result = copy_results::(&cuda, result_buffer); + // we are skipping rest of the components because HIP returns trash in unused components + assert_eq!( + &to_results(host_side_texref[geo.address(size, x_u32, y_u32, z_u32, depth)])[..CHANNELS], + &result[..CHANNELS] + ); +} + +unsafe fn allocate_result_buffer(cuda: &T) -> CUdeviceptr { + let mut device_memory = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut device_memory, mem::size_of::() * 4), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemsetD8_v2(device_memory, BYTE_FILLER2, mem::size_of::() * 4), + CUresult::CUDA_SUCCESS + ); + device_memory +} + +unsafe fn create_context(cuda: &T) -> CUcontext { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + // We use primary context, because creating&destroying a normal context + // means creating and destroying a thread, which is relatively slow + assert_eq!( + cuda.cuDevicePrimaryCtxRetain(&mut ctx, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxSetCurrent(ctx), CUresult::CUDA_SUCCESS); + ctx +} + +unsafe fn create_kernel_texref< + T: CudaDriverFns, + ValueType: SustValue, + CoordinateType: SustValue, +>( + cuda: &T, + geo: &GeometryTemplate, +) -> (CUfunction, CUtexref) { + let mut kernel = include_str!("kernel_tex.ptx").to_string(); + kernel = geo.prepare_kernel(&kernel).unwrap(); + kernel = prepare_kernel_values::(&kernel).unwrap(); + kernel.push('\0'); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetTexRef(&mut texref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"tex\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + (kernel, texref) +} + +unsafe fn create_array< + T: CudaDriverFns, + Format: SustValue, + const CHANNELS: usize, + CoordinateType: SustValue, +>( + cuda: &T, + geo: &GeometryTemplate, + format: CUarray_format, + size: usize, + texref: CUtexref, + host_side_data: &[[Format; CHANNELS]], +) { + // NVIDIA texrefs have this """fun""" """feature""", where 1d tex works + // with integer indexing only if the texref has been bound to a buffer + // and float indexing only if the texref has been bound to an array + if geo.geometry_dimensions == 1 && CoordinateType::ptx_type() == "s32" { + let bytesize = mem::size_of::() * CHANNELS * size; + let mut devptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut devptr, bytesize), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemcpyHtoD_v2(devptr, host_side_data.as_ptr().cast(), bytesize), + CUresult::CUDA_SUCCESS + ); + let mut should_be_zero = 0; + assert_eq!( + cuda.cuTexRefSetAddress_v2(&mut should_be_zero, texref, devptr, bytesize), + CUresult::CUDA_SUCCESS + ); + assert_eq!(should_be_zero, 0); + } else { + let mut array = ptr::null_mut(); + let mut descriptor = mem::zeroed::(); + descriptor.Format = format; + descriptor.NumChannels = CHANNELS as u32; + geo.set_descriptor(&mut descriptor, size); + assert_eq!( + cuda.cuArray3DCreate_v2(&mut array, &descriptor), + CUresult::CUDA_SUCCESS + ); + copy_to_array::(&cuda, geo, size, host_side_data, array); + assert_eq!( + cuda.cuTexRefSetArray(texref, array, CU_TRSA_OVERRIDE_FORMAT), + CUresult::CUDA_SUCCESS + ); + } +} + +fn create_host_side_data( + size: usize, + rng: &mut R, +) -> Vec<[Format; CHANNELS]> { + let mut host_side_data = vec![[::default(); CHANNELS]; size * size * size]; + for pixel in host_side_data.iter_mut() { + for channel_element in pixel.iter_mut() { + *channel_element = Format::gen::(rng) + } + } + host_side_data +} + +unsafe fn copy_to_array( + cuda: &T, + geo: &GeometryTemplate, + size: usize, + host_side_data: &[[Format; CHANNELS]], + cu_array: CUarray, +) { + let mut memcpy_desc = mem::zeroed::(); + geo.set_memcpy( + &mut memcpy_desc, + size, + (mem::size_of::() * CHANNELS) as u32, + ); + memcpy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_desc.srcHost = host_side_data.as_ptr() as _; + memcpy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_desc.dstArray = cu_array; + assert_eq!(cuda.cuMemcpy3D_v2(&memcpy_desc), CUresult::CUDA_SUCCESS); +} + +unsafe fn launch_kernel( + cuda: &T, + kernel: CUfunction, + deviceptr: CUdeviceptr, + x: CoordinateType, + y: CoordinateType, + z: CoordinateType, + depth: u32, +) { + let mut args = vec![ + &deviceptr as *const _ as *const c_void, + &x as *const _ as *const c_void, + &y as *const _ as *const _, + &z as *const _ as *const _, + &depth as *const _ as *const _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); +} + +unsafe fn copy_results( + cuda: &T, + deviceptr: CUdeviceptr, +) -> [Value; 4] { + let mut result = [ + Value::default(), + Value::default(), + Value::default(), + Value::default(), + ]; + byte_fill(&mut result, BYTE_FILLER1); + assert_eq!( + cuda.cuMemcpyDtoH_v2( + result.as_mut_ptr() as _, + deviceptr, + mem::size_of::() * 4, + ), + CUresult::CUDA_SUCCESS + ); + result +} + +unsafe fn to_results< + Format: SustValue + AsPrimitive, + Value: SustValue, + const CHANNELS: usize, +>( + input: [Format; CHANNELS], +) -> [Value; 4] { + match &input[..] { + [x] => [ + force_transmute::<_, Value>(*x), + Value::default(), + Value::default(), + Value::default(), + ], + [x, y] => [ + force_transmute::<_, Value>(*x), + force_transmute::<_, Value>(*y), + Value::default(), + Value::default(), + ], + [x, y, z, w] => [ + force_transmute::<_, Value>(*x), + force_transmute::<_, Value>(*y), + force_transmute::<_, Value>(*z), + force_transmute::<_, Value>(*w), + ], + _ => unreachable!(), + } +} diff --git a/zluda/tests/kernel_texobj_2d.ptx b/zluda/tests/kernel_texobj_2d.ptx new file mode 100644 index 0000000..6b1d7db --- /dev/null +++ b/zluda/tests/kernel_texobj_2d.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry texobj( + .param .f32 input_x, + .param .f32 input_y, + .param .u64 image_param, + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + .reg .u64 image; + .reg .f32 x; + .reg .f32 y; + .reg .s32 r; + .reg .s32 g; + .reg .s32 b; + .reg .s32 a; + + ld.param.f32 x, [input_x]; + ld.param.f32 y, [input_y]; + ld.param.u64 image, [image_param]; + ld.param.u64 out_addr, [output]; + + tex.2d.v4.s32.f32 {r, g, b, a}, [image, {x, y}]; + st.b32 [out_addr], a; + st.b32 [out_addr+4], b; + st.b32 [out_addr+8], g; + st.b32 [out_addr+12], r; + ret; +} diff --git a/zluda/tests/kernel_texobj_2d.rs b/zluda/tests/kernel_texobj_2d.rs new file mode 100644 index 0000000..3186ab6 --- /dev/null +++ b/zluda/tests/kernel_texobj_2d.rs @@ -0,0 +1,166 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand_chacha::rand_core::{RngCore, SeedableRng}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_texobj_2d); + +unsafe fn kernel_texobj_2d(cuda: T) { + let kernel = include_str!("kernel_texobj_2d.ptx"); + let mut kernel = kernel.to_owned(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texture_memory = CUdeviceptr_v2(ptr::null_mut()); + let mut texture_pitch = 0usize; + let width = 3; + let height = 3; + assert_eq!( + cuda.cuMemAllocPitch_v2( + &mut texture_memory, + &mut texture_pitch, + width * mem::size_of::<[u8; 4]>(), + height, + 4, + ), + CUresult::CUDA_SUCCESS + ); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0xcb42848a346f8673); + let mut texture_host_side = (0..width * height) + .map(|_| rng.next_u32()) + .collect::>(); + assert_eq!( + cuda.cuMemcpy2D_v2(&CUDA_MEMCPY2D { + srcXInBytes: 0, + srcY: 0, + srcMemoryType: CUmemorytype::CU_MEMORYTYPE_HOST, + srcHost: texture_host_side.as_mut_ptr() as _, + srcDevice: CUdeviceptr_v2(ptr::null_mut()), + srcArray: ptr::null_mut(), + srcPitch: width * mem::size_of::(), + dstXInBytes: 0, + dstY: 0, + dstMemoryType: CUmemorytype::CU_MEMORYTYPE_DEVICE, + dstHost: ptr::null_mut(), + dstDevice: texture_memory, + dstArray: ptr::null_mut(), + dstPitch: texture_pitch, + WidthInBytes: width * mem::size_of::(), + Height: height, + }), + CUresult::CUDA_SUCCESS + ); + let mut texobj = mem::zeroed(); + let res_desc = CUDA_RESOURCE_DESC { + resType: CUresourcetype::CU_RESOURCE_TYPE_PITCH2D, + res: CUDA_RESOURCE_DESC_st__bindgen_ty_1 { + pitch2D: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_4 { + devPtr: texture_memory, + format: CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8, + numChannels: 4, + width, + height, + pitchInBytes: texture_pitch, + }, + }, + flags: 0, + }; + let tex_desc = CUDA_TEXTURE_DESC { + addressMode: [ + CUaddress_mode::CU_TR_ADDRESS_MODE_WRAP, + CUaddress_mode::CU_TR_ADDRESS_MODE_WRAP, + CUaddress_mode::CU_TR_ADDRESS_MODE_WRAP, + ], + filterMode: CUfilter_mode::CU_TR_FILTER_MODE_POINT, + flags: 0, + maxAnisotropy: 0, + mipmapFilterMode: CUfilter_mode::CU_TR_FILTER_MODE_POINT, + mipmapLevelBias: 0.0, + minMipmapLevelClamp: 0.0, + maxMipmapLevelClamp: 0.0, + borderColor: [0.0, 0.0, 0.0, 0.0], + reserved: mem::zeroed(), + }; + // TODO: + // HIP incorrectly disallows CUDA_RESOURCE_VIEW_DESC on non-array texture objects + /* + let view_desc = CUDA_RESOURCE_VIEW_DESC { + format: CUresourceViewFormat::CU_RES_VIEW_FORMAT_UINT_4X8, + width, + height, + depth: 1, + firstMipmapLevel: 0, + lastMipmapLevel: 0, + firstLayer: 0, + lastLayer: 0, + reserved: mem::zeroed(), + }; + */ + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"texobj\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuTexObjectCreate(&mut texobj, &res_desc, &tex_desc, ptr::null()), + CUresult::CUDA_SUCCESS + ); + let x = 1.0f32; + let y = 2.0f32; + let mut out_b = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut out_b, 4 * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut args = [ + &x as *const f32 as *const c_void, + &y as *const f32 as *const _, + &texobj as *const _ as *const _, + &out_b as *const _ as *const _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 1024, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let mut result = vec![0f32; 4usize]; + for i in 0..result.len() { + result[i] = mem::transmute(u32::MAX); + } + assert_eq!( + cuda.cuMemcpyDtoH_v2( + result.as_mut_ptr() as _, + out_b, + result.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); + let pixel = texture_host_side[width * (y as usize) + (x as usize)].to_ne_bytes(); + assert_eq!(result[0] * 255f32, pixel[3] as f32); + assert_eq!(result[1] * 255f32, pixel[2] as f32); + assert_eq!(result[2] * 255f32, pixel[1] as f32); + assert_eq!(result[3] * 255f32, pixel[0] as f32); +} diff --git a/zluda/tests/kernel_texref_1d.ptx b/zluda/tests/kernel_texref_1d.ptx new file mode 100644 index 0000000..3263e18 --- /dev/null +++ b/zluda/tests/kernel_texref_1d.ptx @@ -0,0 +1,30 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .texref image; + +.visible .entry texref_1d( + .param .s32 input_x, + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + .reg .s32 x; + .reg .f32 r; + .reg .f32 g; + .reg .f32 b; + .reg .f32 a; + + ld.param.s32 x, [input_x]; + ld.param.u64 out_addr, [output]; + + tex.1d.v4.f32.s32 {r, g, b, a}, [image, {x}]; + st.b32 [out_addr], a; + st.b32 [out_addr+4], b; + st.b32 [out_addr+8], g; + st.b32 [out_addr+12], r; + ret; +} diff --git a/zluda/tests/kernel_texref_1d.rs b/zluda/tests/kernel_texref_1d.rs new file mode 100644 index 0000000..45aee84 --- /dev/null +++ b/zluda/tests/kernel_texref_1d.rs @@ -0,0 +1,108 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand_chacha::rand_core::{RngCore, SeedableRng}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_texref_1d); + +unsafe fn kernel_texref_1d(cuda: T) { + let kernel = include_str!("kernel_texref_1d.ptx"); + let mut kernel = kernel.to_owned(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetTexRef(&mut texref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texture_memory = mem::zeroed(); + let width = 3; + assert_eq!( + cuda.cuMemAlloc_v2(&mut texture_memory, width * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0xa6bbf6cf62886047); + let texture_host_side = (0..width).map(|_| rng.next_u32()).collect::>(); + assert_eq!( + cuda.cuMemcpyHtoD_v2( + texture_memory, + texture_host_side.as_ptr() as _, + texture_host_side.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuTexRefSetFormat(texref, CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8, 4), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuTexRefSetAddress_v2( + ptr::null_mut(), + texref, + texture_memory, + width * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"texref_1d\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut out_b = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut out_b, 4 * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let x = 1i32; + let mut args = [ + &x as *const i32 as *const c_void, + &out_b as *const _ as *const _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 1024, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let mut result = vec![0f32; 4usize]; + for i in 0..result.len() { + result[i] = mem::transmute(u32::MAX); + } + assert_eq!( + cuda.cuMemcpyDtoH_v2( + result.as_mut_ptr() as _, + out_b, + result.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); + let pixel = texture_host_side[x as usize].to_ne_bytes(); + assert_eq!(result[0] * 255f32, pixel[3] as f32); + assert_eq!(result[1] * 255f32, pixel[2] as f32); + assert_eq!(result[2] * 255f32, pixel[1] as f32); + assert_eq!(result[3] * 255f32, pixel[0] as f32); +} diff --git a/zluda/tests/kernel_texref_2d.ptx b/zluda/tests/kernel_texref_2d.ptx new file mode 100644 index 0000000..b12f93c --- /dev/null +++ b/zluda/tests/kernel_texref_2d.ptx @@ -0,0 +1,33 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .texref image; + +.visible .entry texref( + .param .f32 input_x, + .param .f32 input_y, + .param .u64 output +) +{ + .reg .u64 out_addr; + .reg .u64 temp; + .reg .u64 temp2; + .reg .f32 x; + .reg .f32 y; + .reg .s32 r; + .reg .s32 g; + .reg .s32 b; + .reg .s32 a; + + ld.param.f32 x, [input_x]; + ld.param.f32 y, [input_y]; + ld.param.u64 out_addr, [output]; + + tex.2d.v4.s32.f32 {r, g, b, a}, [image, {x, y}]; + st.b32 [out_addr], a; + st.b32 [out_addr+4], b; + st.b32 [out_addr+8], g; + st.b32 [out_addr+12], r; + ret; +} diff --git a/zluda/tests/kernel_texref_2d.rs b/zluda/tests/kernel_texref_2d.rs new file mode 100644 index 0000000..9c65474 --- /dev/null +++ b/zluda/tests/kernel_texref_2d.rs @@ -0,0 +1,138 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand_chacha::rand_core::{RngCore, SeedableRng}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_texref_2d); + +unsafe fn kernel_texref_2d(cuda: T) { + let kernel = include_str!("kernel_texref_2d.ptx"); + let mut kernel = kernel.to_owned(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetTexRef(&mut texref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texture_memory = CUdeviceptr_v2(ptr::null_mut()); + let mut texture_pitch = 0usize; + let width = 3; + let height = 3; + assert_eq!( + cuda.cuMemAllocPitch_v2( + &mut texture_memory, + &mut texture_pitch, + width * mem::size_of::(), + height, + 4, + ), + CUresult::CUDA_SUCCESS + ); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0xcb42848a346f8673); + let mut texture_host_side = (0..width * height) + .map(|_| rng.next_u32()) + .collect::>(); + assert_eq!( + cuda.cuMemcpy2D_v2(&CUDA_MEMCPY2D { + srcXInBytes: 0, + srcY: 0, + srcMemoryType: CUmemorytype::CU_MEMORYTYPE_HOST, + srcHost: texture_host_side.as_mut_ptr() as _, + srcDevice: CUdeviceptr_v2(ptr::null_mut()), + srcArray: ptr::null_mut(), + srcPitch: width * mem::size_of::(), + dstXInBytes: 0, + dstY: 0, + dstMemoryType: CUmemorytype::CU_MEMORYTYPE_DEVICE, + dstHost: ptr::null_mut(), + dstDevice: texture_memory, + dstArray: ptr::null_mut(), + dstPitch: texture_pitch, + WidthInBytes: width * mem::size_of::(), + Height: height, + }), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuTexRefSetFormat(texref, CUarray_format_enum::CU_AD_FORMAT_UNSIGNED_INT8, 4), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuTexRefSetAddress2D_v3( + texref, + &CUDA_ARRAY_DESCRIPTOR { + Width: width, + Height: height, + Format: CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8, + NumChannels: 4, + }, + texture_memory, + texture_pitch, + ), + CUresult::CUDA_SUCCESS + ); + let mut kernel = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"texref\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut out_b = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut out_b, 4 * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let x = 1.0f32; + let y = 2.0f32; + let mut args = [ + &x as *const f32 as *const c_void, + &y as *const f32 as *const _, + &out_b as *const _ as *const _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 1024, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let mut result = vec![0f32; 4usize]; + for i in 0..result.len() { + result[i] = mem::transmute(u32::MAX); + } + assert_eq!( + cuda.cuMemcpyDtoH_v2( + result.as_mut_ptr() as _, + out_b, + result.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuStreamSynchronize(0 as _), CUresult::CUDA_SUCCESS); + let pixel = texture_host_side[width * (y as usize) + (x as usize)].to_ne_bytes(); + assert_eq!(result[0] * 255f32, pixel[3] as f32); + assert_eq!(result[1] * 255f32, pixel[2] as f32); + assert_eq!(result[2] * 255f32, pixel[1] as f32); + assert_eq!(result[3] * 255f32, pixel[0] as f32); +} diff --git a/zluda/tests/kernel_unused_global.ptx b/zluda/tests/kernel_unused_global.ptx new file mode 100644 index 0000000..9244f65 --- /dev/null +++ b/zluda/tests/kernel_unused_global.ptx @@ -0,0 +1,12 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.global .align 4 .b8 global_buffer[4] = {202, 29, 180, 50}; + +.visible .entry kernel( + .param .u64 input +) +{ + ret; +} diff --git a/zluda/tests/kernel_unused_global.rs b/zluda/tests/kernel_unused_global.rs new file mode 100644 index 0000000..3c67a9c --- /dev/null +++ b/zluda/tests/kernel_unused_global.rs @@ -0,0 +1,49 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{mem, ptr}; + +mod common; + +cuda_driver_test!(kernel_unused_global); + +unsafe fn kernel_unused_global(cuda: T) { + let mut kernel = include_str!("kernel_unused_global.ptx").to_string(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut buffer_ptr = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2( + &mut buffer_ptr, + ptr::null_mut(), + module, + b"global_buffer\0".as_ptr() as _ + ), + CUresult::CUDA_SUCCESS + ); + let values = [1u8, 2, 3, 4]; + assert_eq!( + cuda.cuMemcpyHtoD_v2(buffer_ptr, values.as_ptr() as _, values.len()), + CUresult::CUDA_SUCCESS + ); + let mut buffer_ptr2 = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2( + &mut buffer_ptr2, + ptr::null_mut(), + module, + b"global_buffer\0".as_ptr() as _ + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(buffer_ptr.0, buffer_ptr2.0); +} diff --git a/zluda/tests/linking.rs b/zluda/tests/linking.rs new file mode 100644 index 0000000..025d8ba --- /dev/null +++ b/zluda/tests/linking.rs @@ -0,0 +1,1109 @@ +use common::CudaDriverFns; +use cuda_types::*; +use paste::paste; +use rustc_hash::FxHashSet; +use std::fmt::Debug; +use std::hash::Hash; +use std::{mem, os::raw::c_void, ptr}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +enum Directive { + Kernel, + Method, + Global, + Shared, + Const, +} + +impl Directive { + fn to_str(self, defined: bool) -> &'static str { + match (self, defined) { + (Directive::Kernel, false) => ".entry foobar();", + (Directive::Kernel, true) => ".entry foobar() { ret; }", + (Directive::Method, false) => ".func foobar();", + (Directive::Method, true) => ".func foobar() { ret; }", + (Directive::Global, false) => ".global .b8 foobar[];", + (Directive::Global, true) => ".global .b8 foobar[1] = {1};", + (Directive::Shared, false) => ".shared .b8 foobar[];", + (Directive::Shared, true) => ".shared .b8 foobar[1];", + (Directive::Const, false) => ".const .b8 foobar[];", + (Directive::Const, true) => ".const .b8 foobar[1] = {1};", + } + } + + fn all() -> [Directive; 5] { + [ + Directive::Kernel, + Directive::Method, + Directive::Global, + Directive::Shared, + Directive::Const, + ] + } + + unsafe fn try_get(self, cuda: &T, module: CUmodule) -> Option { + match self { + Directive::Kernel => { + let mut unused = ptr::null_mut(); + Some(cuda.cuModuleGetFunction(&mut unused, module, b"foobar\0".as_ptr().cast())) + } + Directive::Method | Directive::Shared => None, + Directive::Global | Directive::Const => { + let mut unused1: CUdeviceptr_v2 = mem::zeroed(); + let mut unused2 = mem::zeroed(); + Some(cuda.cuModuleGetGlobal_v2( + &mut unused1, + &mut unused2, + module, + b"foobar\0".as_ptr().cast(), + )) + } + } + } + + fn write(self, writer: &mut impl std::fmt::Write, defined: bool, constant: u32) { + match (self, defined) { + (Directive::Method, true) => { + writeln!( + writer, + ".func (.reg .u32 result) foobar() {{ mov.u32 result, {constant}; ret; }}" + ) + } + (Directive::Method, false) => { + writeln!(writer, ".func (.reg .u32 res) foobar();") + } + (Directive::Kernel, true) => { + writeln!( + writer, + ".entry foobar(.param .u64 output) + {{ + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + st.u32 [out_addr], {constant}; + ret; + }}" + ) + } + (Directive::Kernel, false) => { + writeln!(writer, ".entry foobar(.param .u64 output);") + } + (Directive::Global, true) => { + writeln!(writer, ".global .u32 foobar[1] = {{ {constant} }};") + } + (Directive::Global, false) => { + writeln!(writer, ".global .u32 foobar[];") + } + (Directive::Const, true) => { + writeln!(writer, ".const .u32 foobar[1] = {{ {constant} }};") + } + (Directive::Const, false) => { + writeln!(writer, ".const .u32 foobar[];") + } + (Directive::Shared, _) => unimplemented!(), + } + .unwrap() + } + + fn observer_module(self) -> &'static str { + match self { + Directive::Kernel => { + ".version 6.5 + .target sm_60 + .address_size 64 + \0" + } + Directive::Method => { + ".version 6.5 + .target sm_60 + .address_size 64 + .extern .func (.reg .u32 res) foobar(); + .entry observer(.param .u64 output) + { + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + .reg .u32 constant; + call (constant), foobar, (); + st.u32 [out_addr], constant; + ret; + }\0" + } + Directive::Global => { + ".version 6.5 + .target sm_60 + .address_size 64 + .extern .global .u32 foobar[]; + .entry observer(.param .u64 output) + { + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + .reg .u32 constant; + ld.global.u32 constant, [foobar]; + st.u32 [out_addr], constant; + ret; + }\0" + } + Directive::Const => { + ".version 6.5 + .target sm_60 + .address_size 64 + .extern .const .u32 foobar[]; + .entry observer(.param .u64 output) + { + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + .reg .u32 constant; + ld.const.u32 constant, [foobar]; + st.u32 [out_addr], constant; + ret; + }\0" + } + Directive::Shared => unimplemented!(), + } + } + + fn observer_name(self) -> &'static str { + match self { + Directive::Kernel => "foobar\0", + _ => "observer\0", + } + } + + fn compiled_expected(self) -> &'static [((Linking, bool), (Linking, bool), u32)] { + match self { + Directive::Method => &[ + ((Linking::None, true), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::None, true), 3), + ((Linking::None, true), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::None, true), 3), + ((Linking::Extern, false), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::Extern, false), 3), + ((Linking::Visible, true), (Linking::Weak, true), 3), + ((Linking::Weak, true), (Linking::Visible, true), 4), + ((Linking::Weak, true), (Linking::Weak, true), 3), + ][..], + Directive::Kernel => &[ + ((Linking::None, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::None, true), 4), + ((Linking::Extern, false), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::Extern, false), 3), + ((Linking::Visible, true), (Linking::Weak, true), 3), + ((Linking::Weak, true), (Linking::Visible, true), 4), + ((Linking::Weak, true), (Linking::Weak, true), 3), + ][..], + Directive::Global => &[ + ((Linking::None, true), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::None, true), 3), + ((Linking::None, true), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::None, true), 3), + ((Linking::None, true), (Linking::Common, true), 4), + ((Linking::Common, true), (Linking::None, true), 3), + ((Linking::Extern, false), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::Common, true), 4), + ((Linking::Common, true), (Linking::Extern, false), 3), + ((Linking::Visible, true), (Linking::Weak, true), 3), + ((Linking::Weak, true), (Linking::Visible, true), 4), + ((Linking::Weak, true), (Linking::Weak, true), 3), + ((Linking::Weak, true), (Linking::Common, true), 4), + ((Linking::Common, true), (Linking::Weak, true), 3), + ][..], + Directive::Const => &[ + ((Linking::None, true), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::None, true), 3), + ((Linking::None, true), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::None, true), 3), + ((Linking::Extern, false), (Linking::Visible, true), 4), + ((Linking::Visible, true), (Linking::Extern, false), 3), + ((Linking::Extern, false), (Linking::Weak, true), 4), + ((Linking::Weak, true), (Linking::Extern, false), 3), + ((Linking::Visible, true), (Linking::Weak, true), 3), + ((Linking::Weak, true), (Linking::Visible, true), 4), + ((Linking::Weak, true), (Linking::Weak, true), 3), + ][..], + Directive::Shared => unimplemented!(), + } + } + + fn assert_exact(self) -> bool { + match self { + Directive::Kernel => false, + Directive::Method => true, + Directive::Global => false, + Directive::Const => false, + Directive::Shared => unimplemented!(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +enum Linking { + None, + Extern, + Visible, + Weak, + Common, +} + +impl Linking { + fn to_str(self) -> &'static str { + match self { + Linking::None => "", + Linking::Extern => ".extern", + Linking::Visible => ".visible", + Linking::Weak => ".weak", + Linking::Common => ".common", + } + } + + fn all() -> [Linking; 5] { + [ + Linking::None, + Linking::Extern, + Linking::Visible, + Linking::Weak, + Linking::Common, + ] + } +} + +mod common; + +const KERNEL_PRELUDE: &'static str = " +.version 6.5 +.target sm_60 +.address_size 64 +"; + +cuda_driver_test!(linking_specifiers_compile); + +unsafe fn linking_specifiers_compile(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut results = Vec::new(); + for linking in Linking::all() { + for directive in Directive::all() { + for defined in [false, true] { + let kernel = create_kernel(linking, directive, defined); + let mut module = ptr::null_mut(); + let error = cuda.cuModuleLoadData(&mut module, kernel.as_ptr().cast()); + let error2 = if error == CUresult::CUDA_SUCCESS { + directive.try_get(&cuda, module).map(|x| x.0) + } else { + None + }; + // we strictly need just return values, other arguments are a debug help + results.push((linking, directive, defined, error.0, error2)); + } + } + } + let expected = [ + (Linking::None, Directive::Kernel, false, 218, None), + (Linking::None, Directive::Kernel, true, 0, Some(0)), + (Linking::None, Directive::Method, false, 218, None), + (Linking::None, Directive::Method, true, 0, None), + (Linking::None, Directive::Global, false, 218, None), + (Linking::None, Directive::Global, true, 0, Some(0)), + (Linking::None, Directive::Shared, false, 218, None), + (Linking::None, Directive::Shared, true, 0, None), + (Linking::None, Directive::Const, false, 218, None), + (Linking::None, Directive::Const, true, 0, Some(0)), + (Linking::Extern, Directive::Kernel, false, 0, Some(500)), + (Linking::Extern, Directive::Kernel, true, 218, None), + (Linking::Extern, Directive::Method, false, 0, None), + (Linking::Extern, Directive::Method, true, 218, None), + (Linking::Extern, Directive::Global, false, 218, None), + (Linking::Extern, Directive::Global, true, 218, None), + (Linking::Extern, Directive::Shared, false, 0, None), + (Linking::Extern, Directive::Shared, true, 0, None), + (Linking::Extern, Directive::Const, false, 218, None), + (Linking::Extern, Directive::Const, true, 218, None), + (Linking::Visible, Directive::Kernel, false, 218, None), + (Linking::Visible, Directive::Kernel, true, 0, Some(0)), + (Linking::Visible, Directive::Method, false, 218, None), + (Linking::Visible, Directive::Method, true, 0, None), + (Linking::Visible, Directive::Global, false, 218, None), + (Linking::Visible, Directive::Global, true, 0, Some(0)), + (Linking::Visible, Directive::Shared, false, 218, None), + (Linking::Visible, Directive::Shared, true, 0, None), + (Linking::Visible, Directive::Const, false, 218, None), + (Linking::Visible, Directive::Const, true, 0, Some(0)), + (Linking::Weak, Directive::Kernel, false, 218, None), + (Linking::Weak, Directive::Kernel, true, 0, Some(0)), + (Linking::Weak, Directive::Method, false, 218, None), + (Linking::Weak, Directive::Method, true, 0, None), + (Linking::Weak, Directive::Global, false, 218, None), + (Linking::Weak, Directive::Global, true, 0, Some(0)), + (Linking::Weak, Directive::Shared, false, 218, None), + (Linking::Weak, Directive::Shared, true, 0, None), + (Linking::Weak, Directive::Const, false, 218, None), + (Linking::Weak, Directive::Const, true, 0, Some(0)), + (Linking::Common, Directive::Kernel, false, 218, None), + (Linking::Common, Directive::Kernel, true, 218, None), + (Linking::Common, Directive::Method, false, 218, None), + (Linking::Common, Directive::Method, true, 218, None), + (Linking::Common, Directive::Global, false, 218, None), + (Linking::Common, Directive::Global, true, 0, Some(0)), + (Linking::Common, Directive::Shared, false, 218, None), + (Linking::Common, Directive::Shared, true, 218, None), + (Linking::Common, Directive::Const, false, 218, None), + (Linking::Common, Directive::Const, true, 218, None), + ]; + assert_eq!(results, expected) +} + +fn create_kernel(linking: Linking, directive: Directive, defined: bool) -> String { + let mut kernel = KERNEL_PRELUDE.to_string(); + kernel.push_str(linking.to_str()); + kernel.push(' '); + kernel.push_str(directive.to_str(defined)); + kernel.push('\0'); + kernel +} + +fn assert_compatible( + results: Vec<(Linking, Directive, bool, i32, Option)>, + expected: [(Linking, Directive, bool, i32, Option); 50], +) { + if results.len() != expected.len() { + panic!(); + } + let mut broken = Vec::new(); + for (result, expected) in results.into_iter().zip(IntoIterator::into_iter(expected)) { + let (linking, directive, defined, build_result, load_result) = result; + let (_, _, _, expected_build, expected_load) = expected; + if expected_build == 0 { + if build_result != 0 { + broken.push(( + linking, + directive, + defined, + (build_result, load_result), + (expected_build, expected_load), + )); + continue; + } + if expected_load == Some(0) { + if load_result != Some(0) { + broken.push(( + linking, + directive, + defined, + (build_result, load_result), + (expected_build, expected_load), + )); + continue; + } + } + } + } + assert_eq!(broken, []); +} + +fn assert_compatible_compile( + compiled: &[T], + compiled_expected: &[T], +) { + let mut compiled_expected = compiled_expected.iter().cloned().collect::>(); + for entry in compiled { + compiled_expected.remove(&entry); + } + assert_eq!(compiled_expected, FxHashSet::default()); +} + +unsafe fn link_and_compile( + cuda: &T, + kernels: &[String], +) -> Result<(*mut c_void, usize), CUresult> { + let mut linker = mem::zeroed(); + assert_eq!( + cuda.cuLinkCreate_v2(0, ptr::null_mut(), ptr::null_mut(), &mut linker), + CUresult::CUDA_SUCCESS + ); + for k in kernels { + let result = cuda.cuLinkAddData_v2( + linker, + CUjitInputType::CU_JIT_INPUT_PTX, + k.as_ptr().cast_mut().cast(), + k.len(), + ptr::null_mut(), + 0, + ptr::null_mut(), + ptr::null_mut(), + ); + if result != CUresult::CUDA_SUCCESS { + return Err(result); + } + } + let mut binary = mem::zeroed(); + let mut size = 0; + let result = cuda.cuLinkComplete(linker, &mut binary, &mut size); + if result != CUresult::CUDA_SUCCESS { + return Err(result); + } + Ok((binary, size)) +} + +fn all_pairs_ordered(slice: &[T]) -> Vec<(T, T)> { + let mut result = Vec::new(); + for i in 0..slice.len() { + for j in i..slice.len() { + result.push((slice[i], slice[j])); + if slice[i] != slice[j] { + result.push((slice[j], slice[i])); + } + } + } + result +} + +macro_rules! generate_tests2 { + ([$($directive:expr),+]) => { + $( + paste! { + unsafe fn [](cuda: T) { + linking_specifiers_link2::(cuda, Directive:: $directive) + } + cuda_driver_test!([]); + } + )+ + }; +} + +generate_tests2!([Kernel, Method, Global, Const]); + +unsafe fn linking_specifiers_link2(cuda: T, directive: Directive) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut compiled = Vec::new(); + for (linking_a, linking_b) in all_pairs_ordered(&Linking::all()) { + for (defined_a, defined_b) in all_pairs_ordered(&[false, true]) { + if linking_a == Linking::Extern && defined_a + || linking_b == Linking::Extern && defined_b + || linking_a != Linking::Extern && !defined_a + || linking_b != Linking::Extern && !defined_b + { + continue; + } + let observer = directive.observer_module().to_string(); + let kernel_a = create_kernel2(directive, linking_a, defined_a, 3); + let kernel_b = create_kernel2(directive, linking_b, defined_b, 4); + if let Ok((binary, _)) = link_and_compile(&cuda, &[observer, kernel_a, kernel_b][..]) { + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, binary), + CUresult::CUDA_SUCCESS + ); + let mut function = mem::zeroed(); + if CUresult::CUDA_SUCCESS + != cuda.cuModuleGetFunction( + &mut function, + module, + directive.observer_name().as_ptr().cast(), + ) + { + continue; + } + let mut dptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut dptr, mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut args = [&mut dptr]; + let launch_result = cuda.cuLaunchKernel( + function, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + args.as_mut_ptr().cast(), + ptr::null_mut(), + ); + if launch_result != CUresult::CUDA_SUCCESS { + continue; + } + let mut result = 0u32; + assert_eq!( + cuda.cuMemcpyDtoH_v2( + &mut result as *mut _ as *mut _, + dptr, + mem::size_of::() + ), + CUresult::CUDA_SUCCESS + ); + compiled.push(((linking_a, defined_a), (linking_b, defined_b), result)); + } + } + } + let compiled_expected = directive.compiled_expected(); + // This is a workaround for NVIDIA bug, see static_kernel_cuda_bug for details + if !T::is_nvidia() && directive == Directive::Kernel { + assert_compatible_compile(&compiled, compiled_expected); + } else { + assert_eq!(compiled, compiled_expected); + } +} + +fn create_kernel2(directive: Directive, linking: Linking, defined: bool, constant: u32) -> String { + let mut kernel = KERNEL_PRELUDE.to_string(); + kernel.push_str(linking.to_str()); + kernel.push(' '); + directive.write(&mut kernel, defined, constant); + kernel.push('\0'); + kernel +} + +cuda_driver_test!(extern_definition_in_non_linking); + +unsafe fn extern_definition_in_non_linking(cuda: T) { + let global_no_init = " + .version 6.5 + .target sm_60 + .address_size 64 + .extern .global .b32 foobar;\0"; + let global_init = " + .version 6.5 + .target sm_60 + .address_size 64 + .extern .global .b32 foobar = 0;\0"; + let global_init_incomplete = " + .version 6.5 + .target sm_60 + .address_size 64 + .extern .global .b32 foobar[];\0"; + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, global_no_init.as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + cuda.cuModuleLoadData(&mut module, global_init.as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + cuda.cuModuleLoadData(&mut module, global_init_incomplete.as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); +} + +cuda_driver_test!(extern_definition_in_linking); + +unsafe fn extern_definition_in_linking(cuda: T) { + let empty_module = " + .version 6.5 + .target sm_60 + .address_size 64\0" + .to_string(); + let global_no_init = " + .version 6.5 + .target sm_60 + .address_size 64 + .extern .global .b32 foobar;\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + link_and_compile(&cuda, &[empty_module, global_no_init]).unwrap_err(), + CUresult::CUDA_SUCCESS + ); +} + +cuda_driver_test!(extern_and_static_illegal); + +unsafe fn extern_and_static_illegal(cuda: T) { + let extern_and_static = " + .version 6.5 + .target sm_60 + .address_size 64 + .extern .func foobar2(); + .func foobar2() {ret;}\0"; + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_ne!( + cuda.cuModuleLoadData(&mut module, extern_and_static.as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); +} + +cuda_driver_test!(multiple_common_fail_initializer); + +unsafe fn multiple_common_fail_initializer(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .common .global .u32 foobar = 1;\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .common .global .u32 foobar = 2;\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + link_and_compile(&cuda, &[common1, common2]).unwrap_err(), + CUresult::CUDA_SUCCESS + ); +} + +cuda_driver_test!(multiple_common); + +unsafe fn multiple_common(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .common .global .u32 foobar;\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .common .global .u64 foobar = 2;\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let (binary, _) = link_and_compile(&cuda, &[common1, common2]).unwrap(); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, binary.cast()), + CUresult::CUDA_SUCCESS + ); + let mut ptr = mem::zeroed(); + let mut size = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2(&mut ptr, &mut size, module, "foobar\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + assert_eq!(size, 8); +} + +cuda_driver_test!(alignment_and_type_are_ignored_in_globals); + +unsafe fn alignment_and_type_are_ignored_in_globals(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .global .align 8 .u32 foobar;\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .visible .global .align 16 .f32 foobar;\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let (binary, _) = link_and_compile(&cuda, &[common1, common2]).unwrap(); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, binary.cast()), + CUresult::CUDA_SUCCESS + ); + let mut ptr = mem::zeroed(); + let mut size = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2(&mut ptr, &mut size, module, "foobar\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + assert_eq!(size, 4); +} + +cuda_driver_test!(type_check_functions_ignore_align); + +unsafe fn type_check_functions_ignore_align(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func (.reg .align 8 .u32 x) foobar() { ret; }\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func (.reg .align 16 .u32 x) foobar() { ret; }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert!(link_and_compile(&cuda, &[common1, common2]).is_ok(),); +} + +cuda_driver_test!(multiple_static_functions_are_allowed); + +unsafe fn multiple_static_functions_are_allowed(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .func foobar(.param .u32 arg) { ret; }\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .func foobar() { ret; }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert!(link_and_compile(&cuda, &[common1, common2]).is_ok()); +} + +cuda_driver_test!(multiple_static_globals_are_allowed); + +unsafe fn multiple_static_globals_are_allowed(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .global .u64 foobar[1] = {1};\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .global .u32 foobar[1] = {2};\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let (binary, _) = link_and_compile(&cuda, &[common1, common2]).unwrap(); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, binary.cast()), + CUresult::CUDA_SUCCESS + ); + let mut ptr = mem::zeroed(); + let mut size = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2(&mut ptr, &mut size, module, "foobar\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + assert_eq!(size, 8); + let mut result = 0u64; + assert_eq!( + cuda.cuMemcpyDtoH_v2(&mut result as *mut _ as *mut _, ptr, size), + CUresult::CUDA_SUCCESS + ); + assert_eq!(result, 1); +} + +cuda_driver_test!(local_global_is_not_accessible); + +unsafe fn local_global_is_not_accessible(cuda: T) { + let module_ptx = " + .version 6.5 + .target sm_60 + .address_size 64 + .entry foo() { + .global .u32 bar[1] = {2}; + ret; + }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, module_ptx.as_ptr().cast_mut().cast()), + CUresult::CUDA_SUCCESS + ); + let mut ptr = mem::zeroed(); + let mut size = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetGlobal_v2(&mut ptr, &mut size, module, "bar\0".as_ptr().cast()), + CUresult::CUDA_ERROR_NOT_FOUND + ); +} + +cuda_driver_test!(weak_func); + +unsafe fn weak_func(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func (.reg .u32 result) foobar() { mov.u32 result, 1; ret; } + .entry observer1(.param .u64 output) + { + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + .reg .u32 constant; + call (constant), foobar, (); + st.u32 [out_addr], constant; + ret; + }\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func (.reg .u32 result) foobar() { mov.u32 result, 2; ret; } + .entry observer2(.param .u64 output) + { + .reg .u64 out_addr; + ld.param.u64 out_addr, [output]; + .reg .u32 constant; + call (constant), foobar, (); + st.u32 [out_addr], constant; + ret; + }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let (binary, _) = link_and_compile(&cuda, &[common1, common2]).unwrap(); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, binary.cast()), + CUresult::CUDA_SUCCESS + ); + let mut observer1 = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut observer1, module, "observer1\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + let mut observer2 = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut observer2, module, "observer2\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + let mut dptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut dptr, mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut args = [&mut dptr]; + assert_eq!( + cuda.cuLaunchKernel( + observer1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + args.as_mut_ptr().cast(), + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let mut result = 0u32; + assert_eq!( + cuda.cuMemcpyDtoH_v2(&mut result as *mut _ as *mut _, dptr, mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + assert_eq!(1, result); + let mut args = [&mut dptr]; + assert_eq!( + cuda.cuLaunchKernel( + observer2, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + args.as_mut_ptr().cast(), + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let mut result = 0u32; + assert_eq!( + cuda.cuMemcpyDtoH_v2(&mut result as *mut _ as *mut _, dptr, mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + assert_eq!(1, result); +} + +cuda_driver_test!(weak_decl_and_func); + +unsafe fn weak_decl_and_func(cuda: T) { + let common1 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func foobar();\0" + .to_string(); + let common2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .weak .func foobar() { ret; }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + link_and_compile(&cuda, &[common1, common2]).unwrap_err(), + CUresult::CUDA_SUCCESS + ); +} + +// This is a duplicate of a case in mass test `linking_specifiers_link2` +// This is evidently a CUDA bug, so I want to keep it here explicitly +cuda_driver_test!(static_kernel_cuda_bug); + +unsafe fn static_kernel_cuda_bug(cuda: T) { + let input1 = " + .version 6.5 + .target sm_60 + .address_size 64\0" + .to_string(); + let input2 = " + .version 6.5 + .target sm_60 + .address_size 64 + .entry foobar() { ret; }\0" + .to_string(); + let input3 = " + .version 6.5 + .target sm_60 + .address_size 64 + .entry foobar() { ret; }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let (cubin, _) = link_and_compile(&cuda, &[input1, input2, input3]).unwrap(); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, cubin), + CUresult::CUDA_SUCCESS + ); + let mut func = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut func, module, b"foobar\0".as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); + let mut _unused_arg = 0u64; + let mut args = [&mut _unused_arg]; + let launch_error = cuda.cuLaunchKernel( + func, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + args.as_mut_ptr().cast(), + ptr::null_mut(), + ); + if T::is_nvidia() { + assert_eq!(launch_error, CUresult::CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES); + } else { + assert_eq!(launch_error, CUresult::CUDA_SUCCESS); + } +} + +cuda_driver_test!(emit_weak_fn); + +unsafe fn emit_weak_fn(cuda: T) { + let input1 = " + .version 6.5 + .target sm_50 + .address_size 64 + + .weak .func (.reg .b32 retval) ret0(.reg .b32 input); + + .entry observer2(.param .u64 output) { + .reg .b32 reg32; + call.uni (reg32), ret0, (reg32); + ret; + } + + .weak .func (.reg .b32 retval) ret0(.reg .b32 input) + { + mov.b32 retval, 0; + ret; + }\0" + .to_string(); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, input1.as_ptr().cast()), + CUresult::CUDA_SUCCESS + ); +} diff --git a/zluda/tests/llama.bin b/zluda/tests/llama.bin new file mode 100644 index 0000000000000000000000000000000000000000..efc63ec9a72f88cf96c7ba624e597f268e782d37 GIT binary patch literal 388 zcmV-~0ek+y@>#Bb_!S5wp?J^I&gTN29v$<@RTtTS7gPisr1>RkA|-AOzn|;Cu0&8@ zt(jq)j|ZQ^2J{9K4E_sbuwp$1FXAdc&T=RwGSW!m&5dgCl`0!vB0zh4sKckBII2#S{6XzCKpCF-C=1V zmeN|l4=&t(0&zWlL1a_Dt%$2x7-3P1ijKK@#{zcgVk|02)TYgmo05eu%GBRDGv3=T zG1D{JCxFVK0FM-z4y(%BEN~(uKlSCjUOaWFnV{Ur2`Ph92Z}x5ISpZ!*es7nkqx7O z?>4Xp0$|nxIj{z+T?I^_UVM9Ml; +.reg .f32 %f<18>; +.reg .b32 %r<43>; +.reg .b64 %rd<15>; + + +ld.param.u64 %rd1, [_Z21dequantize_block_q6_KPKvPf_param_0]; +ld.param.u64 %rd2, [_Z21dequantize_block_q6_KPKvPf_param_1]; +cvta.to.global.u64 %rd3, %rd2; +cvta.to.global.u64 %rd4, %rd1; +mov.u32 %r1, %ctaid.x; +mov.u32 %r2, %tid.x; +shr.s32 %r3, %r2, 31; +shr.u32 %r4, %r3, 27; +add.s32 %r5, %r2, %r4; +shr.s32 %r6, %r5, 5; +and.b32 %r7, %r5, -32; +sub.s32 %r8, %r2, %r7; +shl.b32 %r9, %r6, 3; +shr.s32 %r10, %r8, 31; +shr.u32 %r11, %r10, 28; +add.s32 %r12, %r8, %r11; +shr.s32 %r13, %r12, 4; +add.s32 %r14, %r9, %r13; +shl.b32 %r15, %r1, 8; +shl.b32 %r16, %r6, 7; +add.s32 %r17, %r16, %r15; +add.s32 %r18, %r17, %r8; +mul.wide.s32 %rd5, %r18, 4; +add.s64 %rd6, %rd3, %rd5; +mul.wide.s32 %rd7, %r1, 210; +add.s64 %rd8, %rd4, %rd7; +ld.global.u16 %rs1, [%rd8+208]; + + { cvt.f32.f16 %f1, %rs1;} + + + shl.b32 %r19, %r6, 6; +add.s32 %r20, %r8, %r19; +cvt.s64.s32 %rd9, %r20; +add.s64 %rd10, %rd8, %rd9; +cvt.s64.s32 %rd11, %r2; +add.s64 %rd12, %rd8, %rd11; +cvt.s64.s32 %rd13, %r14; +add.s64 %rd14, %rd8, %rd13; +ld.global.s8 %rs2, [%rd14+192]; +cvt.rn.f32.s16 %f2, %rs2; +mul.f32 %f3, %f1, %f2; +ld.global.u8 %r21, [%rd10]; +and.b32 %r22, %r21, 15; +ld.global.u8 %r23, [%rd12+128]; +and.b32 %r24, %r23, 3; +bfi.b32 %r25, %r24, %r22, 4, 2; +add.s32 %r26, %r25, -32; +cvt.rn.f32.s32 %f4, %r26; +mul.f32 %f5, %f3, %f4; +st.global.f32 [%rd6], %f5; +ld.global.s8 %rs3, [%rd14+194]; +cvt.rn.f32.s16 %f6, %rs3; +mul.f32 %f7, %f1, %f6; +ld.global.u8 %r27, [%rd10+32]; +and.b32 %r28, %r27, 15; +shr.u32 %r29, %r23, 2; +bfe.u32 %r30, %r23, 2, 2; +bfi.b32 %r31, %r30, %r28, 4, 2; +add.s32 %r32, %r31, -32; +cvt.rn.f32.s32 %f8, %r32; +mul.f32 %f9, %f7, %f8; +st.global.f32 [%rd6+128], %f9; +ld.global.s8 %rs4, [%rd14+196]; +cvt.rn.f32.s16 %f10, %rs4; +mul.f32 %f11, %f1, %f10; +ld.global.u8 %r33, [%rd10]; +shr.u32 %r34, %r33, 4; +and.b32 %r35, %r23, 48; +or.b32 %r36, %r34, %r35; +add.s32 %r37, %r36, -32; +cvt.rn.f32.s32 %f12, %r37; +mul.f32 %f13, %f11, %f12; +st.global.f32 [%rd6+256], %f13; +ld.global.s8 %rs5, [%rd14+198]; +cvt.rn.f32.s16 %f14, %rs5; +mul.f32 %f15, %f1, %f14; +ld.global.u8 %r38, [%rd10+32]; +shr.u32 %r39, %r38, 4; +and.b32 %r40, %r29, 48; +or.b32 %r41, %r39, %r40; +add.s32 %r42, %r41, -32; +cvt.rn.f32.s32 %f16, %r42; +mul.f32 %f17, %f15, %f16; +st.global.f32 [%rd6+384], %f17; +ret; +} diff --git a/zluda/tests/llama.rs b/zluda/tests/llama.rs new file mode 100644 index 0000000..de73ac2 --- /dev/null +++ b/zluda/tests/llama.rs @@ -0,0 +1,84 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(llama); + +unsafe fn llama(cuda: T) { + let kernel = concat!(include_str!("llama.ptx"), "\0"); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut buffer_input = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_input, 4096), + CUresult::CUDA_SUCCESS + ); + let mut host_buffer = include_bytes!("llama.bin").to_vec(); + assert_eq!( + cuda.cuMemcpyHtoD_v2(buffer_input, host_buffer.as_ptr().cast(), host_buffer.len()), + CUresult::CUDA_SUCCESS + ); + let mut buffer_output = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut buffer_output, 97 * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut kernel = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction( + &mut kernel, + module, + b"_Z21dequantize_block_q6_KPKvPf\0".as_ptr() as _ + ), + CUresult::CUDA_SUCCESS + ); + let mut args = [ + &mut buffer_input as *mut _ as *mut c_void, + &mut buffer_output as *mut _ as _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + ptr::null_mut(), + &mut args as _, + ptr::null_mut() + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuStreamSynchronize(ptr::null_mut()), + CUresult::CUDA_SUCCESS + ); + host_buffer.fill(0); + assert_eq!( + cuda.cuMemcpyDtoH_v2( + host_buffer.as_mut_ptr().cast(), + buffer_output, + host_buffer.len() + ), + CUresult::CUDA_SUCCESS + ); + let host_buffer = host_buffer.align_to::().1; + assert_eq!(host_buffer[0], 0xBC6C7800); + assert_eq!(host_buffer[32], 0x3B260800); + assert_eq!(host_buffer[64], 0xBC301800); + assert_eq!(host_buffer[96], 0x3C0AFD00); +} diff --git a/zluda/tests/maxntid.ptx b/zluda/tests/maxntid.ptx new file mode 100644 index 0000000..8648d7b --- /dev/null +++ b/zluda/tests/maxntid.ptx @@ -0,0 +1,23 @@ +.version 6.5 +.target sm_30 +.address_size 64 + +.visible .entry add( + .param .u64 input, + .param .u64 output +) +.maxntid 32, 1, 1 +{ + .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/zluda/tests/maxntid.rs b/zluda/tests/maxntid.rs new file mode 100644 index 0000000..3da2507 --- /dev/null +++ b/zluda/tests/maxntid.rs @@ -0,0 +1,36 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(maxntid); + +unsafe fn maxntid(cuda: T) { + let kernel = include_str!("maxntid.ptx"); + let mut kernel = kernel.to_owned(); + kernel.push('\0'); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut func = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetFunction(&mut func, module, b"add\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut _unused = 0; + let mut max_blocksize = 0; + assert_eq!( + cuda.cuOccupancyMaxPotentialBlockSize(&mut _unused, &mut max_blocksize, func, None, 0, 0), + CUresult::CUDA_SUCCESS + ); + assert_eq!(max_blocksize, 32); +} diff --git a/zluda/tests/memcpy_pitch.rs b/zluda/tests/memcpy_pitch.rs new file mode 100644 index 0000000..096a4bc --- /dev/null +++ b/zluda/tests/memcpy_pitch.rs @@ -0,0 +1,147 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{mem, ptr}; + +mod common; + +cuda_driver_test!(memcpy_pitch); + +unsafe fn memcpy_pitch(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut memcpy_2d = mem::zeroed::(); + let width = 2; + let pitch = 4; + let height = 2; + let mut source = (0..pitch * height).map(|x| x as u8).collect::>(); + let mut devptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut devptr, width * height), + CUresult::CUDA_SUCCESS + ); + memcpy_2d.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_2d.srcHost = source.as_mut_ptr() as _; + memcpy_2d.srcPitch = pitch; + memcpy_2d.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_DEVICE; + memcpy_2d.dstDevice = devptr; + memcpy_2d.WidthInBytes = width; + memcpy_2d.Height = height; + assert_eq!( + cuda.cuMemcpy2DUnaligned_v2(&memcpy_2d), + CUresult::CUDA_SUCCESS + ); + let mut result = vec![0u8; width * height]; + assert_eq!( + cuda.cuMemcpyDtoH_v2(result.as_mut_ptr() as _, devptr, width * height), + CUresult::CUDA_SUCCESS + ); + assert_eq!(result, [0u8, 1, 4, 5]); +} + +cuda_driver_test!(memcpy_pitch_dst); + +unsafe fn memcpy_pitch_dst(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut memcpy_2d = mem::zeroed::(); + let width = 2; + let pitch = 4; + let height = 2; + let source = (0..width * height).map(|x| x as u8).collect::>(); + let mut devptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut devptr, pitch * height), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemsetD8_v2(devptr, 0xff, pitch * height), + CUresult::CUDA_SUCCESS + ); + memcpy_2d.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_2d.srcHost = source.as_ptr() as _; + memcpy_2d.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_DEVICE; + memcpy_2d.dstDevice = devptr; + memcpy_2d.dstPitch = pitch; + memcpy_2d.WidthInBytes = width; + memcpy_2d.Height = height; + assert_eq!( + cuda.cuMemcpy2DUnaligned_v2(&memcpy_2d), + CUresult::CUDA_SUCCESS + ); + let mut result = vec![0u8; pitch * height]; + assert_eq!( + cuda.cuMemcpyDtoH_v2(result.as_mut_ptr() as _, devptr, pitch * height), + CUresult::CUDA_SUCCESS + ); + assert_eq!(result, [0, 1, 255, 255, 2, 3, 255, 255]); +} + +cuda_driver_test!(memcpy_3d_pitch); + +unsafe fn memcpy_3d_pitch(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let width = 2; + let pitch = 4; + let height = 2; + let depth = 1; + let source = (0..pitch * height * depth) + .map(|x| x as u8) + .collect::>(); + let mut devptr = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut devptr, pitch * height * depth), + CUresult::CUDA_SUCCESS + ); + assert_eq!( + cuda.cuMemcpyHtoD_v2(devptr, source.as_ptr() as _, pitch * height * depth), + CUresult::CUDA_SUCCESS + ); + let mut array = mem::zeroed(); + let array_desc = CUDA_ARRAY3D_DESCRIPTOR { + Width: width, + Height: height, + Depth: depth, + Format: CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8, + NumChannels: 1, + Flags: 0, + }; + assert_eq!( + cuda.cuArray3DCreate_v2(&mut array, &array_desc), + CUresult::CUDA_SUCCESS + ); + let mut copy_desc = mem::zeroed::(); + copy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_DEVICE; + copy_desc.srcDevice = devptr; + copy_desc.srcPitch = pitch; + copy_desc.srcHeight = height; + copy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + copy_desc.dstArray = array; + copy_desc.WidthInBytes = width; + copy_desc.Height = height; + copy_desc.Depth = depth; + assert_eq!(cuda.cuMemcpy3D_v2(©_desc), CUresult::CUDA_SUCCESS); + let mut result = vec![0u8; width * height * depth]; + let mut backcopy_desc = mem::zeroed::(); + backcopy_desc.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + backcopy_desc.srcArray = array; + backcopy_desc.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + backcopy_desc.dstHost = result.as_mut_ptr() as _; + backcopy_desc.WidthInBytes = width; + backcopy_desc.Height = height; + backcopy_desc.Depth = depth; + assert_eq!(cuda.cuMemcpy3D_v2(&backcopy_desc), CUresult::CUDA_SUCCESS); + assert_eq!(result, [0, 1, 4, 5]); +} diff --git a/zluda/tests/module_texrefs_have_correct_format.rs b/zluda/tests/module_texrefs_have_correct_format.rs new file mode 100644 index 0000000..3eff140 --- /dev/null +++ b/zluda/tests/module_texrefs_have_correct_format.rs @@ -0,0 +1,35 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{mem, ptr}; + +mod common; + +cuda_driver_test!(module_texrefs_have_correct_format); + +unsafe fn module_texrefs_have_correct_format(cuda: T) { + let kernel = include_str!("kernel_texref_2d.ptx"); + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut module = ptr::null_mut(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut texref = ptr::null_mut(); + assert_eq!( + cuda.cuModuleGetTexRef(&mut texref, module, b"image\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut format = mem::zeroed(); + let mut channels = mem::zeroed(); + assert_eq!( + cuda.cuTexRefGetFormat(&mut format, &mut channels, texref), + CUresult::CUDA_SUCCESS + ); + assert_eq!(format, CUarray_format::CU_AD_FORMAT_FLOAT); + assert_eq!(channels, 1); +} diff --git a/zluda/tests/shuffle.ptx b/zluda/tests/shuffle.ptx new file mode 100644 index 0000000..e2dadb1 --- /dev/null +++ b/zluda/tests/shuffle.ptx @@ -0,0 +1,34 @@ +.version 6.5 +.target sm_50 +.address_size 64 + +.visible .entry shuffle( + .param .b64 input, + .param .b64 output, + .param .b32 param_b, + .param .b32 param_c +) +{ + .reg .u64 in_addr; + .reg .u64 out_addr; + .reg .b32 a; + .reg .b32 b; + .reg .b32 c; + .reg .b64 offset; + + ld.param.u64 in_addr, [input]; + ld.param.u64 out_addr, [output]; + ld.param.b32 b, [param_b]; + ld.param.b32 c, [param_c]; + + cvt.u64.u32 offset, %tid.x; + mul.lo.u64 offset, offset, 4; + add.u64 in_addr, in_addr, offset; + ld.global.u32 a, [in_addr]; + shfl.#SHUFFLE#.b32 a, a, b, c; + + add.u64 out_addr, out_addr, offset; + st.global.u32 [out_addr], a; + + ret; +} diff --git a/zluda/tests/shuffle.rs b/zluda/tests/shuffle.rs new file mode 100644 index 0000000..463367d --- /dev/null +++ b/zluda/tests/shuffle.rs @@ -0,0 +1,191 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use rand::{Rng, SeedableRng}; +use std::{ffi::c_void, mem, ptr}; + +mod common; + +cuda_driver_test!(shuffle_down); +cuda_driver_test!(shuffle_up); +cuda_driver_test!(shuffle_bfly); +cuda_driver_test!(shuffle_idx); + +const KERNEL: &'static str = include_str!("shuffle.ptx"); +const WARP_WIDTH: usize = 32; +const TEST_ITERATIONS: usize = 1000; + +unsafe fn shuffle_down(cuda: T) { + shuffle(cuda, "down", validate_down); +} + +unsafe fn shuffle_up(cuda: T) { + shuffle(cuda, "up", validate_up); +} + +unsafe fn shuffle_bfly(cuda: T) { + shuffle(cuda, "bfly", validate_bfly); +} + +unsafe fn shuffle_idx(cuda: T) { + shuffle(cuda, "idx", validate_idx); +} + +unsafe fn shuffle( + cuda: T, + shuffle_type: &'static str, + mut validate: impl FnMut(&[u32; WARP_WIDTH], u32, u32, &[u32; WARP_WIDTH]) -> bool, +) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut kernel_text = KERNEL.replace("#SHUFFLE#", shuffle_type); + kernel_text.push('\0'); + let mut module = mem::zeroed(); + assert_eq!( + cuda.cuModuleLoadData(&mut module, kernel_text.as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut kernel = mem::zeroed(); + assert_eq!( + cuda.cuModuleGetFunction(&mut kernel, module, b"shuffle\0".as_ptr() as _), + CUresult::CUDA_SUCCESS + ); + let mut input_mem = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut input_mem, WARP_WIDTH * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut output_mem = mem::zeroed(); + assert_eq!( + cuda.cuMemAlloc_v2(&mut output_mem, WARP_WIDTH * mem::size_of::()), + CUresult::CUDA_SUCCESS + ); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0x7cb9cbc7c2b95f47); + for _ in 00..TEST_ITERATIONS { + let input = rng.gen::<[u32; WARP_WIDTH]>(); + assert_eq!( + cuda.cuMemcpyHtoD_v2( + input_mem, + input.as_ptr() as _, + input.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + let mut b = rng.gen::(); + let mut c = rng.gen::(); + let mut args = [ + &mut input_mem as *mut _ as *mut c_void, + &mut output_mem as *mut _ as _, + &mut b as *mut _ as _, + &mut c as *mut _ as _, + ]; + assert_eq!( + cuda.cuLaunchKernel( + kernel, + 1, + 1, + 1, + 32, + 1, + 1, + 0, + 0 as _, + args.as_mut_ptr() as _, + ptr::null_mut(), + ), + CUresult::CUDA_SUCCESS + ); + let output = [0u32; WARP_WIDTH]; + assert_eq!( + cuda.cuMemcpyDtoH_v2( + output.as_ptr() as _, + output_mem, + output.len() * mem::size_of::(), + ), + CUresult::CUDA_SUCCESS + ); + assert_eq!(cuda.cuCtxSynchronize(), CUresult::CUDA_SUCCESS); + assert!(validate(&input, b, c, &output)); + } +} + +fn validate_down(input: &[u32; WARP_WIDTH], b: u32, c: u32, result: &[u32; WARP_WIDTH]) -> bool { + validate(mode_down, input, b, c, result) +} + +fn validate_up(input: &[u32; WARP_WIDTH], b: u32, c: u32, result: &[u32; WARP_WIDTH]) -> bool { + validate(mode_up, input, b, c, result) +} + +fn validate_bfly(input: &[u32; WARP_WIDTH], b: u32, c: u32, result: &[u32; WARP_WIDTH]) -> bool { + validate(mode_bfly, input, b, c, result) +} + +fn validate_idx(input: &[u32; WARP_WIDTH], b: u32, c: u32, result: &[u32; WARP_WIDTH]) -> bool { + validate(mode_idx, input, b, c, result) +} + +fn validate( + mut mode: impl FnMut(u32, i32, u32, u32, u32) -> (i32, bool), + input: &[u32; WARP_WIDTH], + b: u32, + c: u32, + result: &[u32; WARP_WIDTH], +) -> bool { + let bval = (b & 31) as i32; + let cval = c & 31; + let mask = (c >> 8) & 31; + let source = (0u32..WARP_WIDTH as u32) + .into_iter() + .map(|lane| input[(lane & 31) as usize]) + .collect::>(); + let max_lane = (0u32..WARP_WIDTH as u32) + .into_iter() + .map(|lane| ((lane & 31) & (mask)) | (cval & !mask)) + .collect::>(); + let min_lane = (0u32..WARP_WIDTH as u32) + .into_iter() + .map(|lane| (lane & 31) & (mask)) + .collect::>(); + let expected = (0u32..WARP_WIDTH as u32) + .into_iter() + .zip(max_lane.iter().copied()) + .zip(min_lane.iter().copied()) + .map(|((lane, max_lane), min_lane)| { + let (mut j, pval) = mode(lane, bval, mask, max_lane, min_lane); + if !pval { + j = lane as i32; + } + source[j as usize] + }) + .collect::>(); + eprintln!("{:?} {} {} {:?} {:?}", &input, b, c, &result, &expected); + expected == result +} + +fn mode_up(lane: u32, bval: i32, _mask: u32, max_lane: u32, _min_lane: u32) -> (i32, bool) { + let j = (lane as i32) - bval; + let pval = j >= max_lane as i32; + (j, pval) +} + +fn mode_down(lane: u32, bval: i32, _mask: u32, max_lane: u32, _min_lane: u32) -> (i32, bool) { + let j = (lane as i32) + bval; + let pval = j <= max_lane as i32; + (j, pval) +} + +fn mode_bfly(lane: u32, bval: i32, _mask: u32, max_lane: u32, _min_lane: u32) -> (i32, bool) { + let j = (lane as i32) ^ bval; + let pval = j <= max_lane as i32; + (j, pval) +} + +fn mode_idx(_lane: u32, bval: i32, mask: u32, max_lane: u32, min_lane: u32) -> (i32, bool) { + let j = (min_lane as i32) | (bval & !(mask as i32)); + let pval = j <= max_lane as i32; + (j, pval) +} diff --git a/zluda/tests/stream_can_destroy.rs b/zluda/tests/stream_can_destroy.rs new file mode 100644 index 0000000..1341b64 --- /dev/null +++ b/zluda/tests/stream_can_destroy.rs @@ -0,0 +1,21 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(can_destroy_stream); + +unsafe fn can_destroy_stream(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut stream = ptr::null_mut(); + assert_eq!(cuda.cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS); + assert_eq!(cuda.cuStreamDestroy_v2(stream), CUresult::CUDA_SUCCESS); + // Cleanup + assert_eq!(cuda.cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/stream_cant_destroy_default.rs b/zluda/tests/stream_cant_destroy_default.rs new file mode 100644 index 0000000..3a6ac0e --- /dev/null +++ b/zluda/tests/stream_cant_destroy_default.rs @@ -0,0 +1,22 @@ +use crate::common::{CudaDriverFns, CU_STREAM_LEGACY}; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(cant_destroy_default_stream); + +unsafe fn cant_destroy_default_stream(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_ne!( + cuda.cuStreamDestroy_v2(CU_STREAM_LEGACY as *mut _), + CUresult::CUDA_SUCCESS + ); + // Cleanup + assert_eq!(cuda.cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/stream_context_destroyed.rs b/zluda/tests/stream_context_destroyed.rs new file mode 100644 index 0000000..32d281d --- /dev/null +++ b/zluda/tests/stream_context_destroyed.rs @@ -0,0 +1,45 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(stream_context_destroyed); + +unsafe fn stream_context_destroyed(cuda: T) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut stream = ptr::null_mut(); + assert_eq!(cuda.cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS); + let mut stream_ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuStreamGetCtx(stream, &mut stream_ctx1), + CUresult::CUDA_SUCCESS + ); + assert_eq!(stream_ctx1, ctx); + assert_eq!(cuda.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 = cuda.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!( + cuda.cuStreamDestroy_v2(stream), + CUresult::CUDA_ERROR_INVALID_HANDLE + ); + // Check if creating another context is possible + let mut ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx2, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + // Cleanup + assert_eq!(cuda.cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/stream_default_uses_current_ctx_impl.rs b/zluda/tests/stream_default_uses_current_ctx_impl.rs new file mode 100644 index 0000000..0476510 --- /dev/null +++ b/zluda/tests/stream_default_uses_current_ctx_impl.rs @@ -0,0 +1,46 @@ +use common::{CudaDriverFns, CU_STREAM_LEGACY, CU_STREAM_PER_THREAD}; +use cuda_types::*; +use std::ptr; + +mod common; + +cuda_driver_test!(stream_default_uses_current_ctx_legacy); +cuda_driver_test!(stream_default_uses_current_ctx_ptsd); + +unsafe fn stream_default_uses_current_ctx_legacy(cuda: T) { + stream_default_uses_current_ctx_impl::(cuda, CU_STREAM_LEGACY); +} + +unsafe fn stream_default_uses_current_ctx_ptsd(cuda: T) { + stream_default_uses_current_ctx_impl::(cuda, CU_STREAM_PER_THREAD); +} + +unsafe fn stream_default_uses_current_ctx_impl(cuda: T, stream: CUstream) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx1, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut stream_ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuStreamGetCtx(stream, &mut stream_ctx1), + CUresult::CUDA_SUCCESS + ); + assert_eq!(ctx1, stream_ctx1); + let mut ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx2, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + assert_ne!(ctx1, ctx2); + let mut stream_ctx2 = ptr::null_mut(); + assert_eq!( + cuda.cuStreamGetCtx(stream, &mut stream_ctx2), + CUresult::CUDA_SUCCESS + ); + assert_eq!(ctx2, stream_ctx2); + // Cleanup + assert_eq!(cuda.cuCtxDestroy_v2(ctx1), CUresult::CUDA_SUCCESS); + assert_eq!(cuda.cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS); +} diff --git a/zluda/tests/stream_moves_context_to_another_thread.rs b/zluda/tests/stream_moves_context_to_another_thread.rs new file mode 100644 index 0000000..bfb2365 --- /dev/null +++ b/zluda/tests/stream_moves_context_to_another_thread.rs @@ -0,0 +1,42 @@ +use crate::common::CudaDriverFns; +use cuda_types::*; +use std::{ptr, thread}; + +mod common; + +cuda_driver_test!(stream_moves_context_to_another_thread); + +unsafe fn stream_moves_context_to_another_thread( + cuda: T, +) { + assert_eq!(cuda.cuInit(0), CUresult::CUDA_SUCCESS); + let mut ctx = ptr::null_mut(); + assert_eq!( + cuda.cuCtxCreate_v2(&mut ctx, 0, CUdevice_v1(0)), + CUresult::CUDA_SUCCESS + ); + let mut stream = ptr::null_mut(); + assert_eq!(cuda.cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS); + let mut stream_ctx1 = ptr::null_mut(); + assert_eq!( + cuda.cuStreamGetCtx(stream, &mut stream_ctx1), + CUresult::CUDA_SUCCESS + ); + assert_eq!(stream_ctx1, ctx); + let stream_ptr = stream as usize; + let cuda_ = cuda.clone(); + let stream_ctx_on_thread = thread::spawn(move || { + let mut stream_ctx2 = ptr::null_mut(); + assert_eq!( + cuda_.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!(cuda.cuStreamDestroy_v2(stream), CUresult::CUDA_SUCCESS); + assert_eq!(cuda.cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS); +} diff --git a/zluda_api/Cargo.toml b/zluda_api/Cargo.toml new file mode 100644 index 0000000..b708cbd --- /dev/null +++ b/zluda_api/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "zluda_api" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "nvapi64" +crate-type = ["cdylib"] + +[dependencies] +# winapi = { version = "0.3", features = ["d3d12", "std"] } +libloading = "0.8" +once_cell = "1.18.0" +cuda_types = { path = "../cuda_types" } + +[dependencies.windows] +version = "0.48" +features = [ + "Win32_Foundation", + "Win32_Graphics_Direct3D11", + "Win32_Graphics_Direct3D12", + "Win32_Graphics_Dxgi_Common", +] + +[package.metadata.zluda] +debug_only = true +windows_only = true diff --git a/zluda_api/README b/zluda_api/README new file mode 100644 index 0000000..1eda236 --- /dev/null +++ b/zluda_api/README @@ -0,0 +1 @@ +bindgen "src\nvapi_wrapper.h" --allowlist-var="[nN][vV].*" --allowlist-type="[nN][vV].*" --blocklist-type="[dD].*" --allowlist-function="$^" --no-derive-debug --default-enum-style=newtype --no-layout-tests --no-doc-comments -o src/nvapi.rs -- -I"C:\dev\nvapi\R530-developer-2" -x c++ diff --git a/zluda_api/src/lib.rs b/zluda_api/src/lib.rs new file mode 100644 index 0000000..0161f62 --- /dev/null +++ b/zluda_api/src/lib.rs @@ -0,0 +1,301 @@ +#![cfg(target_os = "windows")] + +#[allow(warnings)] +mod nvapi; + +use crate::nvapi::NvAPI_Status; +use cuda_types::*; +use nvapi::*; +use once_cell::sync::OnceCell; +use std::{ffi::c_void, io::Write, mem, ptr}; +use windows::Win32::Graphics::Direct3D11::*; +use windows::Win32::Graphics::Direct3D12::*; +//use winapi::um::d3d12::{ID3D12Device, ID3D12GraphicsCommandList}; + +static NVCUDA: OnceCell = OnceCell::new(); + +macro_rules! cuda { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != cuda_types::CUresult::CUDA_SUCCESS { + return NvAPI_Status::NVAPI_ERROR; + } + } + }; +} + +#[no_mangle] +pub unsafe extern "system" fn nvapi_QueryInterface(key: u32) -> *mut c_void { + let mut file = std::fs::OpenOptions::new() + .append(true) + .open(r"c:\temp\nvapi.log") + .unwrap(); + writeln!(file, "{:x}", key).unwrap(); + match key { + 0x150E828 => NvAPI_Initialize as _, + 0xe5ac921f => NvAPI_EnumPhysicalGPUs as _, + 0xD8265D24 => NvAPI_GPU_GetArchInfo as _, + 0x2926AAAD => NvAPI_SYS_GetDriverAndBranchVersion as _, + 0x4b708b54 => NvAPI_D3D_GetCurrentSLIState as _, + 0x6086bd93 => NvAPI_D3D11_IsFatbinPTXSupported as _, + 0xb672be19 => NvAPI_D3D11_CreateCubinComputeShaderWithName as _, + 0x427e236d => NvAPI_D3D11_LaunchCubinShader as _, + 0x70C07832 => NvAPI_D3D12_IsFatbinPTXSupported as _, + 0x1dc7261f => NvAPI_D3D12_CreateCubinComputeShaderWithName as _, + 0x5C52BB86 => NvAPI_D3D12_LaunchCubinShader as _, + 0x89eca416 => NvAPI_D3D11_CreateSamplerState as _, + _ => ptr::null_mut(), + } +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_Initialize() -> NvAPI_Status { + NVCUDA + .get_or_try_init(|| libloading::Library::new(r"C:\Windows\System32\nvcuda.dll")) + .unwrap(); + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_EnumPhysicalGPUs( + nvGPUHandle: *mut [NvPhysicalGpuHandle; NVAPI_MAX_PHYSICAL_GPUS as usize], + pGpuCount: *mut u32, +) -> NvAPI_Status { + (*nvGPUHandle)[0] = ptr::null_mut(); + *pGpuCount = 1; + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_GPU_GetArchInfo( + _hPhysicalGpu: NvPhysicalGpuHandle, + pGpuArchInfo: *mut NV_GPU_ARCH_INFO, +) -> NvAPI_Status { + if pGpuArchInfo == ptr::null_mut() { + return NvAPI_Status::NVAPI_INVALID_ARGUMENT; + } + let version = (*pGpuArchInfo).version; + if version_check::(version, 2).is_none() { + return NvAPI_Status::NVAPI_INCOMPATIBLE_STRUCT_VERSION; + } + *pGpuArchInfo = NV_GPU_ARCH_INFO { + version, + __bindgen_anon_1: NV_GPU_ARCH_INFO_V2__bindgen_ty_1 { + architecture_id: NV_GPU_ARCHITECTURE_ID::NV_GPU_ARCHITECTURE_GA100, + }, + __bindgen_anon_2: NV_GPU_ARCH_INFO_V2__bindgen_ty_2 { + implementation_id: NV_GPU_ARCH_IMPLEMENTATION_ID::NV_GPU_ARCH_IMPLEMENTATION_GA104, + }, + __bindgen_anon_3: NV_GPU_ARCH_INFO_V2__bindgen_ty_3 { + revision_id: NV_GPU_CHIP_REVISION::NV_GPU_CHIP_REV_A01, + }, + }; + NvAPI_Status::NVAPI_OK +} + +fn version_check(packed_version: u32, nominal_version: u32) -> Option { + let version = packed_version >> 16; + let size = (packed_version & 0xffffu32) as usize; + if mem::size_of::() > size { + return None; + } + if nominal_version != version { + return None; + } + Some(size) +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_SYS_GetDriverAndBranchVersion( + pDriverVersion: *mut u32, + szBuildBranchString: *mut NvAPI_ShortString, +) -> NvAPI_Status { + match (pDriverVersion.as_mut(), szBuildBranchString.as_mut()) { + (Some(driver_version), Some(build_string)) => { + *driver_version = 51109; + let name = slice_cast(b"r511_09\0"); + build_string[..name.len()].copy_from_slice(name); + NvAPI_Status::NVAPI_OK + } + _ => NvAPI_Status::NVAPI_INVALID_ARGUMENT, + } +} + +fn slice_cast(t: &'static [u8]) -> &'static [i8] { + unsafe { std::slice::from_raw_parts(t.as_ptr().cast(), t.len()) } +} + +struct Shader { + function: CUfunction, + block_x: u32, + block_y: u32, + block_z: u32, +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D12_IsFatbinPTXSupported( + _pDevice: *const ID3D12Device, + pSupported: *mut bool, +) -> NvAPI_Status { + *pSupported = true; + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D12_CreateCubinComputeShaderWithName( + pDevice: *const ID3D12Device, + pCubin: *const c_void, + size: u32, + block_x: u32, + block_y: u32, + block_z: u32, + pShaderName: *const i8, + phShader: *mut NVDX_ObjectHandle, +) -> NvAPI_Status { + let load_module_data = NVCUDA + .get() + .unwrap() + .get:: CUresult>(b"cuModuleLoadData") + .unwrap(); + let mut module = ptr::null_mut(); + cuda! { load_module_data(&mut module, pCubin as _) }; + let module_get_function = NVCUDA + .get() + .unwrap() + .get:: CUresult>(b"cuModuleGetFunction") + .unwrap(); + let mut function = ptr::null_mut(); + cuda! { module_get_function(&mut function, module, pShaderName) }; + *phShader = Box::into_raw(Box::new(Shader { + function, + block_x, + block_y, + block_z, + })) as _; + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D12_LaunchCubinShader( + pCommandList: *const ID3D12GraphicsCommandList, + hShader: NVDX_ObjectHandle, + gridX: u32, + gridY: u32, + gridZ: u32, + pParams: *const c_void, + paramSize: u32, +) -> NvAPI_Status { + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D11_IsFatbinPTXSupported( + _pDevice: *const ID3D11Device, + pSupported: *mut bool, +) -> NvAPI_Status { + *pSupported = true; + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D11_CreateCubinComputeShaderWithName( + _pDevice: *const ID3D11Device, + pCubin: *const c_void, + _size: u32, + block_x: u32, + block_y: u32, + block_z: u32, + pShaderName: *const i8, + phShader: *mut NVDX_ObjectHandle, +) -> NvAPI_Status { + let load_module_data = NVCUDA + .get() + .unwrap() + .get:: CUresult>(b"cuModuleLoadData") + .unwrap(); + let mut module = ptr::null_mut(); + cuda! { load_module_data(&mut module, pCubin as _) }; + let module_get_function = NVCUDA + .get() + .unwrap() + .get:: CUresult>(b"cuModuleGetFunction") + .unwrap(); + let mut function = ptr::null_mut(); + cuda! { module_get_function(&mut function, module, pShaderName) }; + *phShader = Box::into_raw(Box::new(Shader { + function, + block_x, + block_y, + block_z, + })) as _; + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D11_LaunchCubinShader( + pCommandList: *const ID3D11DeviceContext, + hShader: NVDX_ObjectHandle, + gridX: u32, + gridY: u32, + gridZ: u32, + pParams: *const c_void, + paramSize: u32, + pReadResources: *const NVDX_ObjectHandle, + numReadResources: NvU32, + pWriteResources: *const NVDX_ObjectHandle, + numWriteResources: NvU32, +) -> NvAPI_Status { + NvAPI_Status::NVAPI_OK +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D_GetCurrentSLIState( + _pDevice: *const IUnknown, + pSliState: *mut NV_GET_CURRENT_SLI_STATE_V1, +) -> NvAPI_Status { + let version = (*pSliState).version; + if let Some(size) = version_check::(version, 1) { + std::ptr::write_bytes((pSliState as *mut u8).add(4), 0u8, size - 4); + (*pSliState).maxNumAFRGroups = 1; + (*pSliState).numAFRGroups = 1; + (*pSliState).currentAFRIndex = 0; + (*pSliState).nextFrameAFRIndex = 0; + (*pSliState).previousFrameAFRIndex = 0; + (*pSliState).bIsCurAFRGroupNew = 0; + NvAPI_Status::NVAPI_OK + } else { + NvAPI_Status::NVAPI_INCOMPATIBLE_STRUCT_VERSION + } +} + +#[allow(non_snake_case)] +unsafe extern "system" fn NvAPI_D3D11_CreateSamplerState( + pDevice: *const ID3D11Device, + pSamplerDesc: *const D3D11_SAMPLER_DESC, + ppSamplerState: *mut *const ID3D11SamplerState, + pDriverHandle: *mut u32, +) -> NvAPI_Status { + let mut state = None; + (&*pDevice) + .CreateSamplerState(pSamplerDesc, Some(&mut state)) + .unwrap(); + *ppSamplerState = &state.unwrap(); + *pDriverHandle = 0; + NvAPI_Status::NVAPI_OK +} diff --git a/zluda_api/src/nvapi.rs b/zluda_api/src/nvapi.rs new file mode 100644 index 0000000..593278b --- /dev/null +++ b/zluda_api/src/nvapi.rs @@ -0,0 +1,18348 @@ +use windows::Win32::Graphics::Direct3D11::*; +use windows::Win32::Graphics::Direct3D12::*; +type D3D12_GPU_VIRTUAL_ADDRESS = u64; + +use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; + +type DWORD = u64; +type D3D11_RECT = RECT; + +/* automatically generated by rust-bindgen 0.65.1 */ + +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +#[repr(C)] +pub struct __BindgenUnionField(::std::marker::PhantomData); +impl __BindgenUnionField { + #[inline] + pub const fn new() -> Self { + __BindgenUnionField(::std::marker::PhantomData) + } + #[inline] + pub unsafe fn as_ref(&self) -> &T { + ::std::mem::transmute(self) + } + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { + ::std::mem::transmute(self) + } +} +impl ::std::default::Default for __BindgenUnionField { + #[inline] + fn default() -> Self { + Self::new() + } +} +impl ::std::clone::Clone for __BindgenUnionField { + #[inline] + fn clone(&self) -> Self { + Self::new() + } +} +impl ::std::marker::Copy for __BindgenUnionField {} +impl ::std::fmt::Debug for __BindgenUnionField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__BindgenUnionField") + } +} +impl ::std::hash::Hash for __BindgenUnionField { + fn hash(&self, _state: &mut H) {} +} +impl ::std::cmp::PartialEq for __BindgenUnionField { + fn eq(&self, _other: &__BindgenUnionField) -> bool { + true + } +} +impl ::std::cmp::Eq for __BindgenUnionField {} +pub const NVAPI_DEFAULT_HANDLE: u32 = 0; +pub const NVAPI_GENERIC_STRING_MAX: u32 = 4096; +pub const NVAPI_LONG_STRING_MAX: u32 = 256; +pub const NVAPI_SHORT_STRING_MAX: u32 = 64; +pub const NVAPI_MAX_PHYSICAL_GPUS: u32 = 64; +pub const NVAPI_MAX_PHYSICAL_BRIDGES: u32 = 100; +pub const NVAPI_PHYSICAL_GPUS: u32 = 32; +pub const NVAPI_MAX_LOGICAL_GPUS: u32 = 64; +pub const NVAPI_MAX_AVAILABLE_GPU_TOPOLOGIES: u32 = 256; +pub const NVAPI_MAX_AVAILABLE_SLI_GROUPS: u32 = 256; +pub const NVAPI_MAX_GPU_TOPOLOGIES: u32 = 64; +pub const NVAPI_MAX_GPU_PER_TOPOLOGY: u32 = 8; +pub const NVAPI_MAX_DISPLAY_HEADS: u32 = 2; +pub const NVAPI_ADVANCED_DISPLAY_HEADS: u32 = 4; +pub const NVAPI_MAX_DISPLAYS: u32 = 128; +pub const NVAPI_MAX_ACPI_IDS: u32 = 16; +pub const NVAPI_MAX_VIEW_MODES: u32 = 8; +pub const NVAPI_SYSTEM_MAX_HWBCS: u32 = 128; +pub const NVAPI_SYSTEM_HWBC_INVALID_ID: u32 = 4294967295; +pub const NV_MAX_HEADS: u32 = 4; +pub const NVAPI_MAX_HEADS_PER_GPU: u32 = 32; +pub const NV_MAX_VID_STREAMS: u32 = 4; +pub const NV_MAX_VID_STREAMS_EX: u32 = 20; +pub const NV_MAX_VID_PROFILES: u32 = 4; +pub const NVAPI_MAX_AUDIO_DEVICES: u32 = 16; +pub const NV_MOSAIC_MAX_DISPLAYS: u32 = 64; +pub const NV_EDID_V1_DATA_SIZE: u32 = 256; +pub const NV_EDID_DATA_SIZE: u32 = 256; +pub const NVAPI_MAX_VIEW_TARGET: u32 = 2; +pub const NVAPI_ADVANCED_MAX_VIEW_TARGET: u32 = 4; +pub const NV_TIMING_H_SYNC_POSITIVE: u32 = 0; +pub const NV_TIMING_H_SYNC_NEGATIVE: u32 = 1; +pub const NV_TIMING_H_SYNC_DEFAULT: u32 = 1; +pub const NV_TIMING_V_SYNC_POSITIVE: u32 = 0; +pub const NV_TIMING_V_SYNC_NEGATIVE: u32 = 1; +pub const NV_TIMING_V_SYNC_DEFAULT: u32 = 0; +pub const NV_TIMING_PROGRESSIVE: u32 = 0; +pub const NV_TIMING_INTERLACED: u32 = 1; +pub const NV_TIMING_INTERLACED_EXTRA_VBLANK_ON_FIELD2: u32 = 1; +pub const NV_TIMING_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2: u32 = 2; +pub const NVAPI_MAX_DISPLAY_PATH: u32 = 2; +pub const NVAPI_ADVANCED_MAX_DISPLAY_PATH: u32 = 4; +pub const NVAPI_UNICODE_STRING_MAX: u32 = 2048; +pub const NVAPI_BINARY_DATA_MAX: u32 = 4096; +pub const NVAPI_MAX_GPU_CLOCKS: u32 = 32; +pub const NVAPI_MAX_GPU_PUBLIC_CLOCKS: u32 = 32; +pub const NVAPI_MAX_GPU_PERF_CLOCKS: u32 = 32; +pub const NVAPI_MAX_GPU_PERF_VOLTAGES: u32 = 16; +pub const NVAPI_MAX_GPU_PERF_PSTATES: u32 = 16; +pub const NVAPI_MAX_GPU_PSTATE20_PSTATES: u32 = 16; +pub const NVAPI_MAX_GPU_PSTATE20_CLOCKS: u32 = 8; +pub const NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES: u32 = 4; +pub const NVAPI_OGLEXPERT_DETAIL_NONE: u32 = 0; +pub const NVAPI_OGLEXPERT_DETAIL_ERROR: u32 = 1; +pub const NVAPI_OGLEXPERT_DETAIL_SWFALLBACK: u32 = 2; +pub const NVAPI_OGLEXPERT_DETAIL_BASIC_INFO: u32 = 4; +pub const NVAPI_OGLEXPERT_DETAIL_DETAILED_INFO: u32 = 8; +pub const NVAPI_OGLEXPERT_DETAIL_PERFORMANCE_WARNING: u32 = 16; +pub const NVAPI_OGLEXPERT_DETAIL_QUALITY_WARNING: u32 = 32; +pub const NVAPI_OGLEXPERT_DETAIL_USAGE_WARNING: u32 = 64; +pub const NVAPI_OGLEXPERT_DETAIL_ALL: u32 = 4294967295; +pub const NVAPI_OGLEXPERT_REPORT_NONE: u32 = 0; +pub const NVAPI_OGLEXPERT_REPORT_ERROR: u32 = 1; +pub const NVAPI_OGLEXPERT_REPORT_SWFALLBACK: u32 = 2; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_VERTEX: u32 = 4; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_GEOMETRY: u32 = 8; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_XFB: u32 = 16; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_RASTER: u32 = 32; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_FRAGMENT: u32 = 64; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_ROP: u32 = 128; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_FRAMEBUFFER: u32 = 256; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_PIXEL: u32 = 512; +pub const NVAPI_OGLEXPERT_REPORT_PIPELINE_TEXTURE: u32 = 1024; +pub const NVAPI_OGLEXPERT_REPORT_OBJECT_BUFFEROBJECT: u32 = 2048; +pub const NVAPI_OGLEXPERT_REPORT_OBJECT_TEXTURE: u32 = 4096; +pub const NVAPI_OGLEXPERT_REPORT_OBJECT_PROGRAM: u32 = 8192; +pub const NVAPI_OGLEXPERT_REPORT_OBJECT_FBO: u32 = 16384; +pub const NVAPI_OGLEXPERT_REPORT_FEATURE_SLI: u32 = 32768; +pub const NVAPI_OGLEXPERT_REPORT_ALL: u32 = 4294967295; +pub const NVAPI_OGLEXPERT_OUTPUT_TO_NONE: u32 = 0; +pub const NVAPI_OGLEXPERT_OUTPUT_TO_CONSOLE: u32 = 1; +pub const NVAPI_OGLEXPERT_OUTPUT_TO_DEBUGGER: u32 = 4; +pub const NVAPI_OGLEXPERT_OUTPUT_TO_CALLBACK: u32 = 8; +pub const NVAPI_OGLEXPERT_OUTPUT_TO_ALL: u32 = 4294967295; +pub const NVAPI_MAX_SIZEOF_I2C_DATA_BUFFER: u32 = 4096; +pub const NVAPI_MAX_SIZEOF_I2C_REG_ADDRESS: u32 = 4; +pub const NVAPI_DISPLAY_DEVICE_MASK_MAX: u32 = 24; +pub const NVAPI_I2C_SPEED_DEPRECATED: u32 = 65535; +pub const NV_LICENSE_MAX_COUNT: u32 = 3; +pub const NV_LICENSE_SIGNATURE_SIZE: u32 = 128; +pub const NV_LICENSE_INFO_MAX_LENGTH: u32 = 128; +pub const NVAPI_MAX_GPU_UTILIZATIONS: u32 = 8; +pub const NVAPI_MAX_THERMAL_SENSORS_PER_GPU: u32 = 3; +pub const NV_GPU_MAX_CLOCK_FREQUENCIES: u32 = 3; +pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_PIECEWISE_LINEAR_COLOR_ENDPOINTS: u32 = 2; +pub const NV_GPU_CLIENT_ILLUM_DEVICE_NUM_DEVICES_MAX: u32 = 32; +pub const NV_GPU_CLIENT_ILLUM_ZONE_NUM_ZONES_MAX: u32 = 32; +pub const NV_SOURCE_PID_CURRENT: u32 = 0; +pub const NVAPI_MAX_MOSAIC_DISPLAY_ROWS: u32 = 8; +pub const NVAPI_MAX_MOSAIC_DISPLAY_COLUMNS: u32 = 8; +pub const NV_MOSAIC_TOPO_VALIDITY_VALID: u32 = 0; +pub const NV_MOSAIC_TOPO_VALIDITY_MISSING_GPU: u32 = 1; +pub const NV_MOSAIC_TOPO_VALIDITY_MISSING_DISPLAY: u32 = 2; +pub const NV_MOSAIC_TOPO_VALIDITY_MIXED_DISPLAY_TYPES: u32 = 4; +pub const NV_MOSAIC_DISPLAY_SETTINGS_MAX: u32 = 40; +pub const NV_MOSAIC_TOPO_IDX_DEFAULT: u32 = 0; +pub const NV_MOSAIC_TOPO_IDX_LEFT_EYE: u32 = 0; +pub const NV_MOSAIC_TOPO_IDX_RIGHT_EYE: u32 = 1; +pub const NV_MOSAIC_TOPO_NUM_EYES: u32 = 2; +pub const NV_MOSAIC_MAX_TOPO_PER_TOPO_GROUP: u32 = 2; +pub const NVAPI_MAX_MOSAIC_TOPOS: u32 = 16; +pub const NVAPI_MAX_GSYNC_DEVICES: u32 = 4; +pub const NVAPI_GSYNC_BOARD_ID_P358: u32 = 856; +pub const NVAPI_GSYNC_BOARD_ID_P2060: u32 = 8288; +pub const NVAPI_GSYNC_BOARD_ID_P2061: u32 = 8289; +pub const NVAPI_MAX_RJ45_PER_GSYNC: u32 = 2; +pub const NV_CUSTOM_SEMANTIC_MAX_LIMIT: u32 = 32; +pub const NVAPI_UAV_INFO_VER1: u32 = 1; +pub const NV_META_COMMAND_MAX_TENSOR_DIM: u32 = 5; +pub const NV_META_COMMAND_ACTIVATION_MAX_PARAMS: u32 = 2; +pub const NV_META_COMMAND_NUM_SPATIAL_DIM: u32 = 3; +pub const NVAPI_COPY_ASYNCHRONOUSLY: u32 = 1; +pub const NVAPI_COPY_P2P_READ: u32 = 2; +pub const NVAPI_CPU_RESOURCE: u32 = 4294967295; +pub const NVAPI_PRESENT_COMPOSITING_CONFIG_FLAG_USE_VIDEO_BRIDGE: u32 = 1; +pub const NVAPI_PRESENT_COMPOSITING_CONFIG_FLAG_CLEAR_OUTBANDS: u32 = 2; +pub const NVAPI_PRESENT_COMPOSITING_CONFIG_FLAG_GET_VIDEO_BRIDGE_STATUS: u32 = 2147483648; +pub const NVAPI_VIDEO_BRIDGE_STATUS_AVAILABLE: u32 = 0; +pub const NVAPI_VIDEO_BRIDGE_STATUS_NOT_AVAILABLE: u32 = 1; +pub const NVAPI_VIDEO_BRIDGE_STATUS_FAILED_ACCESS: u32 = 2; +pub const NVAPI_VIDEO_BRIDGE_STATUS_UNKNOWN: u32 = 3; +pub const NVAPI_ALL_GPUS: u32 = 0; +pub const NV_MULTIVIEW_MAX_SUPPORTED_VIEWS: u32 = 4; +pub const NV_MODIFIED_W_MAX_VIEWPORTS: u32 = 16; +pub const NV_MAX_NUM_EXCLUSIVE_SCISSOR_RECTS: u32 = 16; +pub const NV_MAX_PIXEL_SHADING_RATES: u32 = 16; +pub const NV_MAX_NUM_VIEWPORTS: u32 = 16; +pub const NV_VARIABLE_PIXEL_SHADING_TILE_WIDTH: u32 = 16; +pub const NV_VARIABLE_PIXEL_SHADING_TILE_HEIGHT: u32 = 16; +pub const NV_SMP_ASSIST_FLAGS_DEFAULT: u32 = 0; +pub const NV_SMP_ASSIST_MAX_VIEWPORTS: u32 = 16; +pub const NV_SMP_ASSIST_MINIMAL_LEVEL_NUM_EYE_INDICES: u32 = 4; +pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BYTE_ALIGNMENT: u32 = 256; +pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_OC1_MAX_SUBDIVISION_LEVEL: u32 = 12; +pub const NVVIOOWNERID_NONE: u32 = 0; +pub const NVVIO_O_READ: u32 = 0; +pub const NVVIO_O_WRITE_EXCLUSIVE: u32 = 65537; +pub const NVVIO_VALID_ACCESSRIGHTS: u32 = 65537; +pub const NVVIO_OWNERID_INITIALIZED: u32 = 2147483648; +pub const NVVIO_OWNERID_EXCLUSIVE: u32 = 1073741824; +pub const NVVIO_OWNERID_TYPEMASK: u32 = 268435455; +pub const NVAPI_MAX_VIO_DEVICES: u32 = 8; +pub const NVAPI_MAX_VIO_JACKS: u32 = 4; +pub const NVAPI_MAX_VIO_CHANNELS_PER_JACK: u32 = 2; +pub const NVAPI_MAX_VIO_STREAMS: u32 = 4; +pub const NVAPI_MIN_VIO_STREAMS: u32 = 1; +pub const NVAPI_MAX_VIO_LINKS_PER_STREAM: u32 = 2; +pub const NVAPI_MAX_FRAMELOCK_MAPPING_MODES: u32 = 20; +pub const NVAPI_GVI_MIN_RAW_CAPTURE_IMAGES: u32 = 1; +pub const NVAPI_GVI_MAX_RAW_CAPTURE_IMAGES: u32 = 32; +pub const NVAPI_GVI_DEFAULT_RAW_CAPTURE_IMAGES: u32 = 5; +pub const NVVIOCAPS_VIDOUT_SDI: u32 = 1; +pub const NVVIOCAPS_SYNC_INTERNAL: u32 = 256; +pub const NVVIOCAPS_SYNC_GENLOCK: u32 = 512; +pub const NVVIOCAPS_SYNCSRC_SDI: u32 = 4096; +pub const NVVIOCAPS_SYNCSRC_COMP: u32 = 8192; +pub const NVVIOCAPS_OUTPUTMODE_DESKTOP: u32 = 65536; +pub const NVVIOCAPS_OUTPUTMODE_OPENGL: u32 = 131072; +pub const NVVIOCAPS_VIDIN_SDI: u32 = 1048576; +pub const NVVIOCAPS_PACKED_ANC_SUPPORTED: u32 = 2097152; +pub const NVVIOCAPS_AUDIO_BLANKING_SUPPORTED: u32 = 4194304; +pub const NVVIOCLASS_SDI: u32 = 1; +pub const NVVIOBUFFERFORMAT_R8G8B8: u32 = 1; +pub const NVVIOBUFFERFORMAT_R8G8B8Z24: u32 = 2; +pub const NVVIOBUFFERFORMAT_R8G8B8A8: u32 = 4; +pub const NVVIOBUFFERFORMAT_R8G8B8A8Z24: u32 = 8; +pub const NVVIOBUFFERFORMAT_R16FPG16FPB16FP: u32 = 16; +pub const NVVIOBUFFERFORMAT_R16FPG16FPB16FPZ24: u32 = 32; +pub const NVVIOBUFFERFORMAT_R16FPG16FPB16FPA16FP: u32 = 64; +pub const NVVIOBUFFERFORMAT_R16FPG16FPB16FPA16FPZ24: u32 = 128; +pub const NVVIOCONFIG_SIGNALFORMAT: u32 = 1; +pub const NVVIOCONFIG_DATAFORMAT: u32 = 2; +pub const NVVIOCONFIG_OUTPUTREGION: u32 = 4; +pub const NVVIOCONFIG_OUTPUTAREA: u32 = 8; +pub const NVVIOCONFIG_COLORCONVERSION: u32 = 16; +pub const NVVIOCONFIG_GAMMACORRECTION: u32 = 32; +pub const NVVIOCONFIG_SYNCSOURCEENABLE: u32 = 64; +pub const NVVIOCONFIG_SYNCDELAY: u32 = 128; +pub const NVVIOCONFIG_COMPOSITESYNCTYPE: u32 = 256; +pub const NVVIOCONFIG_FRAMELOCKENABLE: u32 = 512; +pub const NVVIOCONFIG_422FILTER: u32 = 1024; +pub const NVVIOCONFIG_COMPOSITETERMINATE: u32 = 2048; +pub const NVVIOCONFIG_DATAINTEGRITYCHECK: u32 = 4096; +pub const NVVIOCONFIG_CSCOVERRIDE: u32 = 8192; +pub const NVVIOCONFIG_FLIPQUEUELENGTH: u32 = 16384; +pub const NVVIOCONFIG_ANCTIMECODEGENERATION: u32 = 32768; +pub const NVVIOCONFIG_COMPOSITE: u32 = 65536; +pub const NVVIOCONFIG_ALPHAKEYCOMPOSITE: u32 = 131072; +pub const NVVIOCONFIG_COMPOSITE_Y: u32 = 262144; +pub const NVVIOCONFIG_COMPOSITE_CR: u32 = 524288; +pub const NVVIOCONFIG_COMPOSITE_CB: u32 = 1048576; +pub const NVVIOCONFIG_FULL_COLOR_RANGE: u32 = 2097152; +pub const NVVIOCONFIG_RGB_DATA: u32 = 4194304; +pub const NVVIOCONFIG_RESERVED_SDIOUTPUTENABLE: u32 = 8388608; +pub const NVVIOCONFIG_STREAMS: u32 = 16777216; +pub const NVVIOCONFIG_ANC_PARITY_COMPUTATION: u32 = 33554432; +pub const NVVIOCONFIG_ANC_AUDIO_REPEAT: u32 = 67108864; +pub const NVVIOCONFIG_ALLFIELDS: u32 = 134217727; +pub const NVVIOCONFIG_VALIDFIELDS: u32 = 134217727; +pub const NVVIOCONFIG_DRIVERFIELDS: u32 = 16412; +pub const NVVIOCONFIG_GAMMAFIELDS: u32 = 32; +pub const NVVIOCONFIG_RMCTRLFIELDS: u32 = 2039619; +pub const NVVIOCONFIG_RMSKEWFIELDS: u32 = 128; +pub const NVVIOCONFIG_ALLOWSDIRUNNING_FIELDS: u32 = 35631232; +pub const NVVIOCONFIG_RMMODESET_FIELDS: u32 = 67109699; +pub const NVAPI_STEREO_QUADBUFFERED_API_VERSION: u32 = 2; +pub const NVAPI_SETTING_MAX_VALUES: u32 = 100; +pub const NV_GPU_CLIENT_UTIL_DOMAINS_MAX_V1: u32 = 4; +pub type ULONG = ::std::os::raw::c_ulong; +pub type BOOL = ::std::os::raw::c_int; +pub type BYTE = ::std::os::raw::c_uchar; +pub type FLOAT = f32; +pub type LPVOID = *mut ::std::os::raw::c_void; +pub type INT = ::std::os::raw::c_int; +pub type UINT = ::std::os::raw::c_uint; +pub type UINT8 = ::std::os::raw::c_uchar; +pub type UINT16 = ::std::os::raw::c_ushort; +pub type UINT64 = ::std::os::raw::c_ulonglong; +pub type ULONG_PTR = ::std::os::raw::c_ulonglong; +pub type SIZE_T = ULONG_PTR; +pub type CHAR = ::std::os::raw::c_char; +pub type LONG = ::std::os::raw::c_long; +pub type WCHAR = u16; +pub type LPCWSTR = *const WCHAR; +pub type LPSTR = *mut CHAR; +pub type LPCSTR = *const CHAR; +pub type HANDLE = *mut ::std::os::raw::c_void; +pub type HRESULT = ::std::os::raw::c_long; +#[repr(C)] +pub struct _LUID { + pub LowPart: DWORD, + pub HighPart: LONG, +} +pub type LUID = _LUID; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _GUID { + pub Data1: ::std::os::raw::c_ulong, + pub Data2: ::std::os::raw::c_ushort, + pub Data3: ::std::os::raw::c_ushort, + pub Data4: [::std::os::raw::c_uchar; 8usize], +} +pub type GUID = _GUID; +pub type IID = GUID; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MEMORY_RANGE { + pub BaseAddress: *mut ::std::os::raw::c_void, + pub Length: SIZE_T, +} +pub type NV_MEMORY_RANGE = _NV_MEMORY_RANGE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct tagRECT { + pub left: LONG, + pub top: LONG, + pub right: LONG, + pub bottom: LONG, +} +pub type RECT = tagRECT; +#[repr(C)] +pub struct _SECURITY_ATTRIBUTES { + pub nLength: DWORD, + pub lpSecurityDescriptor: LPVOID, + pub bInheritHandle: BOOL, +} +pub type SECURITY_ATTRIBUTES = _SECURITY_ATTRIBUTES; +#[repr(C)] +pub struct IUnknown__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct IUnknown { + pub vtable_: *const IUnknown__bindgen_vtable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D10Blob { + pub _base: IUnknown, +} +pub type ID3DBlob = ID3D10Blob; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11DeviceChild { + pub _base: IUnknown, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11DepthStencilState { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11BlendState { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11RasterizerState { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Resource { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Buffer { + pub _base: ID3D11Resource, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Texture1D { + pub _base: ID3D11Resource, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Texture2D { + pub _base: ID3D11Resource, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Texture3D { + pub _base: ID3D11Resource, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11View { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11ShaderResourceView { + pub _base: ID3D11View, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11RenderTargetView { + pub _base: ID3D11View, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11DepthStencilView { + pub _base: ID3D11View, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11UnorderedAccessView { + pub _base: ID3D11View, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11VertexShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11HullShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11DomainShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11GeometryShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11PixelShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11ComputeShader { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11InputLayout { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11SamplerState { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Asynchronous { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Query { + pub _base: ID3D11Asynchronous, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Predicate { + pub _base: ID3D11Query, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Counter { + pub _base: ID3D11Asynchronous, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11ClassInstance { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11ClassLinkage { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11CommandList { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11DeviceContext { + pub _base: ID3D11DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D11Device { + pub _base: IUnknown, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12Object { + pub _base: IUnknown, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12DeviceChild { + pub _base: ID3D12Object, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12RootSignature { + pub _base: ID3D12DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12Pageable { + pub _base: ID3D12DeviceChild, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12Heap { + pub _base: ID3D12Pageable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12Resource { + pub _base: ID3D12Pageable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12CommandAllocator { + pub _base: ID3D12Pageable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12PipelineState { + pub _base: ID3D12Pageable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3D12Device { + pub _base: ID3D12Object, +} +pub type NvU64 = ::std::os::raw::c_ulonglong; +pub type NvS64 = ::std::os::raw::c_longlong; +pub type NvS32 = ::std::os::raw::c_int; +pub type NvU32 = ::std::os::raw::c_ulong; +pub type NvS16 = ::std::os::raw::c_short; +pub type NvU16 = ::std::os::raw::c_ushort; +pub type NvU8 = ::std::os::raw::c_uchar; +pub type NvS8 = ::std::os::raw::c_schar; +pub type NvF32 = f32; +pub type NvF64 = f64; +pub type NvBool = NvU8; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_RECT { + pub left: NvU32, + pub top: NvU32, + pub right: NvU32, + pub bottom: NvU32, +} +pub type NV_RECT = _NV_RECT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvLogicalGpuHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvLogicalGpuHandle = *mut NvLogicalGpuHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvPhysicalGpuHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvPhysicalGpuHandle = *mut NvPhysicalGpuHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvDisplayHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvDisplayHandle = *mut NvDisplayHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvMonitorHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvMonitorHandle = *mut NvMonitorHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvUnAttachedDisplayHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvUnAttachedDisplayHandle = *mut NvUnAttachedDisplayHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvVisualComputingDeviceHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvVisualComputingDeviceHandle = *mut NvVisualComputingDeviceHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvEventHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvEventHandle = *mut NvEventHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvHICHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvHICHandle = *mut NvHICHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvGSyncDeviceHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvGSyncDeviceHandle = *mut NvGSyncDeviceHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvVioHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvVioHandle = *mut NvVioHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvTransitionHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvTransitionHandle = *mut NvTransitionHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAudioHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvAudioHandle = *mut NvAudioHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Nv3DVPContextHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type Nv3DVPContextHandle = *mut Nv3DVPContextHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Nv3DVPTransceiverHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type Nv3DVPTransceiverHandle = *mut Nv3DVPTransceiverHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Nv3DVPGlassesHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type Nv3DVPGlassesHandle = *mut Nv3DVPGlassesHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvPcfClientHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvPcfClientHandle = *mut NvPcfClientHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvSourceHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvSourceHandle = *mut NvSourceHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvTargetHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvTargetHandle = *mut NvTargetHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVDX_SwapChainHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NVDX_SwapChainHandle = *mut NVDX_SwapChainHandle__; +extern "C" { + pub static NVDX_SWAPCHAIN_NONE: NVDX_SwapChainHandle; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvPresentBarrierClientHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvPresentBarrierClientHandle = *mut NvPresentBarrierClientHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvSBox { + pub sX: NvS32, + pub sY: NvS32, + pub sWidth: NvS32, + pub sHeight: NvS32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvGUID { + pub data1: NvU32, + pub data2: NvU16, + pub data3: NvU16, + pub data4: [NvU8; 8usize], +} +pub type NvLUID = NvGUID; +pub type NvAPI_String = [::std::os::raw::c_char; 4096usize]; +pub type NvAPI_LongString = [::std::os::raw::c_char; 256usize]; +pub type NvAPI_ShortString = [::std::os::raw::c_char; 64usize]; +pub type NvAPI_UnicodeShortString = [NvU16; 64usize]; +impl _NvAPI_Status { + pub const NVAPI_OK: _NvAPI_Status = _NvAPI_Status(0); +} +impl _NvAPI_Status { + pub const NVAPI_ERROR: _NvAPI_Status = _NvAPI_Status(-1); +} +impl _NvAPI_Status { + pub const NVAPI_LIBRARY_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-2); +} +impl _NvAPI_Status { + pub const NVAPI_NO_IMPLEMENTATION: _NvAPI_Status = _NvAPI_Status(-3); +} +impl _NvAPI_Status { + pub const NVAPI_API_NOT_INITIALIZED: _NvAPI_Status = _NvAPI_Status(-4); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_ARGUMENT: _NvAPI_Status = _NvAPI_Status(-5); +} +impl _NvAPI_Status { + pub const NVAPI_NVIDIA_DEVICE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-6); +} +impl _NvAPI_Status { + pub const NVAPI_END_ENUMERATION: _NvAPI_Status = _NvAPI_Status(-7); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_HANDLE: _NvAPI_Status = _NvAPI_Status(-8); +} +impl _NvAPI_Status { + pub const NVAPI_INCOMPATIBLE_STRUCT_VERSION: _NvAPI_Status = _NvAPI_Status(-9); +} +impl _NvAPI_Status { + pub const NVAPI_HANDLE_INVALIDATED: _NvAPI_Status = _NvAPI_Status(-10); +} +impl _NvAPI_Status { + pub const NVAPI_OPENGL_CONTEXT_NOT_CURRENT: _NvAPI_Status = _NvAPI_Status(-11); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_POINTER: _NvAPI_Status = _NvAPI_Status(-14); +} +impl _NvAPI_Status { + pub const NVAPI_NO_GL_EXPERT: _NvAPI_Status = _NvAPI_Status(-12); +} +impl _NvAPI_Status { + pub const NVAPI_INSTRUMENTATION_DISABLED: _NvAPI_Status = _NvAPI_Status(-13); +} +impl _NvAPI_Status { + pub const NVAPI_NO_GL_NSIGHT: _NvAPI_Status = _NvAPI_Status(-15); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_LOGICAL_GPU_HANDLE: _NvAPI_Status = _NvAPI_Status(-100); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: _NvAPI_Status = _NvAPI_Status(-101); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_DISPLAY_HANDLE: _NvAPI_Status = _NvAPI_Status(-102); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_COMBINATION: _NvAPI_Status = _NvAPI_Status(-103); +} +impl _NvAPI_Status { + pub const NVAPI_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-104); +} +impl _NvAPI_Status { + pub const NVAPI_PORTID_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-105); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_UNATTACHED_DISPLAY_HANDLE: _NvAPI_Status = _NvAPI_Status(-106); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_PERF_LEVEL: _NvAPI_Status = _NvAPI_Status(-107); +} +impl _NvAPI_Status { + pub const NVAPI_DEVICE_BUSY: _NvAPI_Status = _NvAPI_Status(-108); +} +impl _NvAPI_Status { + pub const NVAPI_NV_PERSIST_FILE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-109); +} +impl _NvAPI_Status { + pub const NVAPI_PERSIST_DATA_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-110); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_TV_DISPLAY: _NvAPI_Status = _NvAPI_Status(-111); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_TV_DISPLAY_ON_DCONNECTOR: _NvAPI_Status = _NvAPI_Status(-112); +} +impl _NvAPI_Status { + pub const NVAPI_NO_ACTIVE_SLI_TOPOLOGY: _NvAPI_Status = _NvAPI_Status(-113); +} +impl _NvAPI_Status { + pub const NVAPI_SLI_RENDERING_MODE_NOTALLOWED: _NvAPI_Status = _NvAPI_Status(-114); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_DIGITAL_FLAT_PANEL: _NvAPI_Status = _NvAPI_Status(-115); +} +impl _NvAPI_Status { + pub const NVAPI_ARGUMENT_EXCEED_MAX_SIZE: _NvAPI_Status = _NvAPI_Status(-116); +} +impl _NvAPI_Status { + pub const NVAPI_DEVICE_SWITCHING_NOT_ALLOWED: _NvAPI_Status = _NvAPI_Status(-117); +} +impl _NvAPI_Status { + pub const NVAPI_TESTING_CLOCKS_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-118); +} +impl _NvAPI_Status { + pub const NVAPI_UNKNOWN_UNDERSCAN_CONFIG: _NvAPI_Status = _NvAPI_Status(-119); +} +impl _NvAPI_Status { + pub const NVAPI_TIMEOUT_RECONFIGURING_GPU_TOPO: _NvAPI_Status = _NvAPI_Status(-120); +} +impl _NvAPI_Status { + pub const NVAPI_DATA_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-121); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_ANALOG_DISPLAY: _NvAPI_Status = _NvAPI_Status(-122); +} +impl _NvAPI_Status { + pub const NVAPI_NO_VIDLINK: _NvAPI_Status = _NvAPI_Status(-123); +} +impl _NvAPI_Status { + pub const NVAPI_REQUIRES_REBOOT: _NvAPI_Status = _NvAPI_Status(-124); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_HYBRID_MODE: _NvAPI_Status = _NvAPI_Status(-125); +} +impl _NvAPI_Status { + pub const NVAPI_MIXED_TARGET_TYPES: _NvAPI_Status = _NvAPI_Status(-126); +} +impl _NvAPI_Status { + pub const NVAPI_SYSWOW64_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-127); +} +impl _NvAPI_Status { + pub const NVAPI_IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED: _NvAPI_Status = + _NvAPI_Status(-128); +} +impl _NvAPI_Status { + pub const NVAPI_REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS: _NvAPI_Status = _NvAPI_Status(-129); +} +impl _NvAPI_Status { + pub const NVAPI_OUT_OF_MEMORY: _NvAPI_Status = _NvAPI_Status(-130); +} +impl _NvAPI_Status { + pub const NVAPI_WAS_STILL_DRAWING: _NvAPI_Status = _NvAPI_Status(-131); +} +impl _NvAPI_Status { + pub const NVAPI_FILE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-132); +} +impl _NvAPI_Status { + pub const NVAPI_TOO_MANY_UNIQUE_STATE_OBJECTS: _NvAPI_Status = _NvAPI_Status(-133); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_CALL: _NvAPI_Status = _NvAPI_Status(-134); +} +impl _NvAPI_Status { + pub const NVAPI_D3D10_1_LIBRARY_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-135); +} +impl _NvAPI_Status { + pub const NVAPI_FUNCTION_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-136); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_USER_PRIVILEGE: _NvAPI_Status = _NvAPI_Status(-137); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_NON_PRIMARY_DISPLAY_HANDLE: _NvAPI_Status = _NvAPI_Status(-138); +} +impl _NvAPI_Status { + pub const NVAPI_EXPECTED_COMPUTE_GPU_HANDLE: _NvAPI_Status = _NvAPI_Status(-139); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_NOT_INITIALIZED: _NvAPI_Status = _NvAPI_Status(-140); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_REGISTRY_ACCESS_FAILED: _NvAPI_Status = _NvAPI_Status(-141); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_REGISTRY_PROFILE_TYPE_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-142); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_REGISTRY_VALUE_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-143); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_NOT_ENABLED: _NvAPI_Status = _NvAPI_Status(-144); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_NOT_TURNED_ON: _NvAPI_Status = _NvAPI_Status(-145); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_INVALID_DEVICE_INTERFACE: _NvAPI_Status = _NvAPI_Status(-146); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_PARAMETER_OUT_OF_RANGE: _NvAPI_Status = _NvAPI_Status(-147); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_FRUSTUM_ADJUST_MODE_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-148); +} +impl _NvAPI_Status { + pub const NVAPI_TOPO_NOT_POSSIBLE: _NvAPI_Status = _NvAPI_Status(-149); +} +impl _NvAPI_Status { + pub const NVAPI_MODE_CHANGE_FAILED: _NvAPI_Status = _NvAPI_Status(-150); +} +impl _NvAPI_Status { + pub const NVAPI_D3D11_LIBRARY_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-151); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_ADDRESS: _NvAPI_Status = _NvAPI_Status(-152); +} +impl _NvAPI_Status { + pub const NVAPI_STRING_TOO_SMALL: _NvAPI_Status = _NvAPI_Status(-153); +} +impl _NvAPI_Status { + pub const NVAPI_MATCHING_DEVICE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-154); +} +impl _NvAPI_Status { + pub const NVAPI_DRIVER_RUNNING: _NvAPI_Status = _NvAPI_Status(-155); +} +impl _NvAPI_Status { + pub const NVAPI_DRIVER_NOTRUNNING: _NvAPI_Status = _NvAPI_Status(-156); +} +impl _NvAPI_Status { + pub const NVAPI_ERROR_DRIVER_RELOAD_REQUIRED: _NvAPI_Status = _NvAPI_Status(-157); +} +impl _NvAPI_Status { + pub const NVAPI_SET_NOT_ALLOWED: _NvAPI_Status = _NvAPI_Status(-158); +} +impl _NvAPI_Status { + pub const NVAPI_ADVANCED_DISPLAY_TOPOLOGY_REQUIRED: _NvAPI_Status = _NvAPI_Status(-159); +} +impl _NvAPI_Status { + pub const NVAPI_SETTING_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-160); +} +impl _NvAPI_Status { + pub const NVAPI_SETTING_SIZE_TOO_LARGE: _NvAPI_Status = _NvAPI_Status(-161); +} +impl _NvAPI_Status { + pub const NVAPI_TOO_MANY_SETTINGS_IN_PROFILE: _NvAPI_Status = _NvAPI_Status(-162); +} +impl _NvAPI_Status { + pub const NVAPI_PROFILE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-163); +} +impl _NvAPI_Status { + pub const NVAPI_PROFILE_NAME_IN_USE: _NvAPI_Status = _NvAPI_Status(-164); +} +impl _NvAPI_Status { + pub const NVAPI_PROFILE_NAME_EMPTY: _NvAPI_Status = _NvAPI_Status(-165); +} +impl _NvAPI_Status { + pub const NVAPI_EXECUTABLE_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-166); +} +impl _NvAPI_Status { + pub const NVAPI_EXECUTABLE_ALREADY_IN_USE: _NvAPI_Status = _NvAPI_Status(-167); +} +impl _NvAPI_Status { + pub const NVAPI_DATATYPE_MISMATCH: _NvAPI_Status = _NvAPI_Status(-168); +} +impl _NvAPI_Status { + pub const NVAPI_PROFILE_REMOVED: _NvAPI_Status = _NvAPI_Status(-169); +} +impl _NvAPI_Status { + pub const NVAPI_UNREGISTERED_RESOURCE: _NvAPI_Status = _NvAPI_Status(-170); +} +impl _NvAPI_Status { + pub const NVAPI_ID_OUT_OF_RANGE: _NvAPI_Status = _NvAPI_Status(-171); +} +impl _NvAPI_Status { + pub const NVAPI_DISPLAYCONFIG_VALIDATION_FAILED: _NvAPI_Status = _NvAPI_Status(-172); +} +impl _NvAPI_Status { + pub const NVAPI_DPMST_CHANGED: _NvAPI_Status = _NvAPI_Status(-173); +} +impl _NvAPI_Status { + pub const NVAPI_INSUFFICIENT_BUFFER: _NvAPI_Status = _NvAPI_Status(-174); +} +impl _NvAPI_Status { + pub const NVAPI_ACCESS_DENIED: _NvAPI_Status = _NvAPI_Status(-175); +} +impl _NvAPI_Status { + pub const NVAPI_MOSAIC_NOT_ACTIVE: _NvAPI_Status = _NvAPI_Status(-176); +} +impl _NvAPI_Status { + pub const NVAPI_SHARE_RESOURCE_RELOCATED: _NvAPI_Status = _NvAPI_Status(-177); +} +impl _NvAPI_Status { + pub const NVAPI_REQUEST_USER_TO_DISABLE_DWM: _NvAPI_Status = _NvAPI_Status(-178); +} +impl _NvAPI_Status { + pub const NVAPI_D3D_DEVICE_LOST: _NvAPI_Status = _NvAPI_Status(-179); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_CONFIGURATION: _NvAPI_Status = _NvAPI_Status(-180); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_HANDSHAKE_NOT_DONE: _NvAPI_Status = _NvAPI_Status(-181); +} +impl _NvAPI_Status { + pub const NVAPI_EXECUTABLE_PATH_IS_AMBIGUOUS: _NvAPI_Status = _NvAPI_Status(-182); +} +impl _NvAPI_Status { + pub const NVAPI_DEFAULT_STEREO_PROFILE_IS_NOT_DEFINED: _NvAPI_Status = _NvAPI_Status(-183); +} +impl _NvAPI_Status { + pub const NVAPI_DEFAULT_STEREO_PROFILE_DOES_NOT_EXIST: _NvAPI_Status = _NvAPI_Status(-184); +} +impl _NvAPI_Status { + pub const NVAPI_CLUSTER_ALREADY_EXISTS: _NvAPI_Status = _NvAPI_Status(-185); +} +impl _NvAPI_Status { + pub const NVAPI_DPMST_DISPLAY_ID_EXPECTED: _NvAPI_Status = _NvAPI_Status(-186); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_DISPLAY_ID: _NvAPI_Status = _NvAPI_Status(-187); +} +impl _NvAPI_Status { + pub const NVAPI_STREAM_IS_OUT_OF_SYNC: _NvAPI_Status = _NvAPI_Status(-188); +} +impl _NvAPI_Status { + pub const NVAPI_INCOMPATIBLE_AUDIO_DRIVER: _NvAPI_Status = _NvAPI_Status(-189); +} +impl _NvAPI_Status { + pub const NVAPI_VALUE_ALREADY_SET: _NvAPI_Status = _NvAPI_Status(-190); +} +impl _NvAPI_Status { + pub const NVAPI_TIMEOUT: _NvAPI_Status = _NvAPI_Status(-191); +} +impl _NvAPI_Status { + pub const NVAPI_GPU_WORKSTATION_FEATURE_INCOMPLETE: _NvAPI_Status = _NvAPI_Status(-192); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_INIT_ACTIVATION_NOT_DONE: _NvAPI_Status = _NvAPI_Status(-193); +} +impl _NvAPI_Status { + pub const NVAPI_SYNC_NOT_ACTIVE: _NvAPI_Status = _NvAPI_Status(-194); +} +impl _NvAPI_Status { + pub const NVAPI_SYNC_MASTER_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-195); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_SYNC_TOPOLOGY: _NvAPI_Status = _NvAPI_Status(-196); +} +impl _NvAPI_Status { + pub const NVAPI_ECID_SIGN_ALGO_UNSUPPORTED: _NvAPI_Status = _NvAPI_Status(-197); +} +impl _NvAPI_Status { + pub const NVAPI_ECID_KEY_VERIFICATION_FAILED: _NvAPI_Status = _NvAPI_Status(-198); +} +impl _NvAPI_Status { + pub const NVAPI_FIRMWARE_OUT_OF_DATE: _NvAPI_Status = _NvAPI_Status(-199); +} +impl _NvAPI_Status { + pub const NVAPI_FIRMWARE_REVISION_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-200); +} +impl _NvAPI_Status { + pub const NVAPI_LICENSE_CALLER_AUTHENTICATION_FAILED: _NvAPI_Status = _NvAPI_Status(-201); +} +impl _NvAPI_Status { + pub const NVAPI_D3D_DEVICE_NOT_REGISTERED: _NvAPI_Status = _NvAPI_Status(-202); +} +impl _NvAPI_Status { + pub const NVAPI_RESOURCE_NOT_ACQUIRED: _NvAPI_Status = _NvAPI_Status(-203); +} +impl _NvAPI_Status { + pub const NVAPI_TIMING_NOT_SUPPORTED: _NvAPI_Status = _NvAPI_Status(-204); +} +impl _NvAPI_Status { + pub const NVAPI_HDCP_ENCRYPTION_FAILED: _NvAPI_Status = _NvAPI_Status(-205); +} +impl _NvAPI_Status { + pub const NVAPI_PCLK_LIMITATION_FAILED: _NvAPI_Status = _NvAPI_Status(-206); +} +impl _NvAPI_Status { + pub const NVAPI_NO_CONNECTOR_FOUND: _NvAPI_Status = _NvAPI_Status(-207); +} +impl _NvAPI_Status { + pub const NVAPI_HDCP_DISABLED: _NvAPI_Status = _NvAPI_Status(-208); +} +impl _NvAPI_Status { + pub const NVAPI_API_IN_USE: _NvAPI_Status = _NvAPI_Status(-209); +} +impl _NvAPI_Status { + pub const NVAPI_NVIDIA_DISPLAY_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-210); +} +impl _NvAPI_Status { + pub const NVAPI_PRIV_SEC_VIOLATION: _NvAPI_Status = _NvAPI_Status(-211); +} +impl _NvAPI_Status { + pub const NVAPI_INCORRECT_VENDOR: _NvAPI_Status = _NvAPI_Status(-212); +} +impl _NvAPI_Status { + pub const NVAPI_DISPLAY_IN_USE: _NvAPI_Status = _NvAPI_Status(-213); +} +impl _NvAPI_Status { + pub const NVAPI_UNSUPPORTED_CONFIG_NON_HDCP_HMD: _NvAPI_Status = _NvAPI_Status(-214); +} +impl _NvAPI_Status { + pub const NVAPI_MAX_DISPLAY_LIMIT_REACHED: _NvAPI_Status = _NvAPI_Status(-215); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_DIRECT_MODE_DISPLAY: _NvAPI_Status = _NvAPI_Status(-216); +} +impl _NvAPI_Status { + pub const NVAPI_GPU_IN_DEBUG_MODE: _NvAPI_Status = _NvAPI_Status(-217); +} +impl _NvAPI_Status { + pub const NVAPI_D3D_CONTEXT_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-218); +} +impl _NvAPI_Status { + pub const NVAPI_STEREO_VERSION_MISMATCH: _NvAPI_Status = _NvAPI_Status(-219); +} +impl _NvAPI_Status { + pub const NVAPI_GPU_NOT_POWERED: _NvAPI_Status = _NvAPI_Status(-220); +} +impl _NvAPI_Status { + pub const NVAPI_ERROR_DRIVER_RELOAD_IN_PROGRESS: _NvAPI_Status = _NvAPI_Status(-221); +} +impl _NvAPI_Status { + pub const NVAPI_WAIT_FOR_HW_RESOURCE: _NvAPI_Status = _NvAPI_Status(-222); +} +impl _NvAPI_Status { + pub const NVAPI_REQUIRE_FURTHER_HDCP_ACTION: _NvAPI_Status = _NvAPI_Status(-223); +} +impl _NvAPI_Status { + pub const NVAPI_DISPLAY_MUX_TRANSITION_FAILED: _NvAPI_Status = _NvAPI_Status(-224); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_DSC_VERSION: _NvAPI_Status = _NvAPI_Status(-225); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_DSC_SLICECOUNT: _NvAPI_Status = _NvAPI_Status(-226); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_DSC_OUTPUT_BPP: _NvAPI_Status = _NvAPI_Status(-227); +} +impl _NvAPI_Status { + pub const NVAPI_FAILED_TO_LOAD_FROM_DRIVER_STORE: _NvAPI_Status = _NvAPI_Status(-228); +} +impl _NvAPI_Status { + pub const NVAPI_NO_VULKAN: _NvAPI_Status = _NvAPI_Status(-229); +} +impl _NvAPI_Status { + pub const NVAPI_REQUEST_PENDING: _NvAPI_Status = _NvAPI_Status(-230); +} +impl _NvAPI_Status { + pub const NVAPI_RESOURCE_IN_USE: _NvAPI_Status = _NvAPI_Status(-231); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_IMAGE: _NvAPI_Status = _NvAPI_Status(-232); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_PTX: _NvAPI_Status = _NvAPI_Status(-233); +} +impl _NvAPI_Status { + pub const NVAPI_NVLINK_UNCORRECTABLE: _NvAPI_Status = _NvAPI_Status(-234); +} +impl _NvAPI_Status { + pub const NVAPI_JIT_COMPILER_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-235); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_SOURCE: _NvAPI_Status = _NvAPI_Status(-236); +} +impl _NvAPI_Status { + pub const NVAPI_ILLEGAL_INSTRUCTION: _NvAPI_Status = _NvAPI_Status(-237); +} +impl _NvAPI_Status { + pub const NVAPI_INVALID_PC: _NvAPI_Status = _NvAPI_Status(-238); +} +impl _NvAPI_Status { + pub const NVAPI_LAUNCH_FAILED: _NvAPI_Status = _NvAPI_Status(-239); +} +impl _NvAPI_Status { + pub const NVAPI_NOT_PERMITTED: _NvAPI_Status = _NvAPI_Status(-240); +} +impl _NvAPI_Status { + pub const NVAPI_CALLBACK_ALREADY_REGISTERED: _NvAPI_Status = _NvAPI_Status(-241); +} +impl _NvAPI_Status { + pub const NVAPI_CALLBACK_NOT_FOUND: _NvAPI_Status = _NvAPI_Status(-242); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NvAPI_Status(pub ::std::os::raw::c_int); +pub use self::_NvAPI_Status as NvAPI_Status; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_DRIVER_MEMORY_INFO_V1 { + pub version: NvU32, + pub dedicatedVideoMemory: NvU32, + pub availableDedicatedVideoMemory: NvU32, + pub systemVideoMemory: NvU32, + pub sharedSystemMemory: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_DRIVER_MEMORY_INFO_V2 { + pub version: NvU32, + pub dedicatedVideoMemory: NvU32, + pub availableDedicatedVideoMemory: NvU32, + pub systemVideoMemory: NvU32, + pub sharedSystemMemory: NvU32, + pub curAvailableDedicatedVideoMemory: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_DRIVER_MEMORY_INFO_V3 { + pub version: NvU32, + pub dedicatedVideoMemory: NvU32, + pub availableDedicatedVideoMemory: NvU32, + pub systemVideoMemory: NvU32, + pub sharedSystemMemory: NvU32, + pub curAvailableDedicatedVideoMemory: NvU32, + pub dedicatedVideoMemoryEvictionsSize: NvU32, + pub dedicatedVideoMemoryEvictionCount: NvU32, +} +pub type NV_DISPLAY_DRIVER_MEMORY_INFO = NV_DISPLAY_DRIVER_MEMORY_INFO_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_MEMORY_INFO_EX_V1 { + pub version: NvU32, + pub dedicatedVideoMemory: NvU64, + pub availableDedicatedVideoMemory: NvU64, + pub systemVideoMemory: NvU64, + pub sharedSystemMemory: NvU64, + pub curAvailableDedicatedVideoMemory: NvU64, + pub dedicatedVideoMemoryEvictionsSize: NvU64, + pub dedicatedVideoMemoryEvictionCount: NvU64, + pub dedicatedVideoMemoryPromotionsSize: NvU64, + pub dedicatedVideoMemoryPromotionCount: NvU64, +} +pub type NV_GPU_MEMORY_INFO_EX = NV_GPU_MEMORY_INFO_EX_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVDX_ObjectHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NVDX_ObjectHandle = *mut NVDX_ObjectHandle__; +extern "C" { + pub static NVDX_OBJECT_NONE: NVDX_ObjectHandle; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GET_CURRENT_SLI_STATE_V1 { + pub version: NvU32, + pub maxNumAFRGroups: NvU32, + pub numAFRGroups: NvU32, + pub currentAFRIndex: NvU32, + pub nextFrameAFRIndex: NvU32, + pub previousFrameAFRIndex: NvU32, + pub bIsCurAFRGroupNew: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GET_CURRENT_SLI_STATE_V2 { + pub version: NvU32, + pub maxNumAFRGroups: NvU32, + pub numAFRGroups: NvU32, + pub currentAFRIndex: NvU32, + pub nextFrameAFRIndex: NvU32, + pub previousFrameAFRIndex: NvU32, + pub bIsCurAFRGroupNew: NvU32, + pub numVRSLIGpus: NvU32, +} +impl _NVAPI_D3D_SETRESOURCEHINT_CATEGORY { + pub const NVAPI_D3D_SRH_CATEGORY_SLI: _NVAPI_D3D_SETRESOURCEHINT_CATEGORY = + _NVAPI_D3D_SETRESOURCEHINT_CATEGORY(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D_SETRESOURCEHINT_CATEGORY(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D_SETRESOURCEHINT_CATEGORY as NVAPI_D3D_SETRESOURCEHINT_CATEGORY; +impl _NVAPI_D3D_SETRESOURCEHINT_SLI { + pub const NVAPI_D3D_SRH_SLI_APP_CONTROLLED_INTERFRAME_CONTENT_SYNC: + _NVAPI_D3D_SETRESOURCEHINT_SLI = _NVAPI_D3D_SETRESOURCEHINT_SLI(1); +} +impl _NVAPI_D3D_SETRESOURCEHINT_SLI { + pub const NVAPI_D3D_SRH_SLI_ASK_FOR_BROADCAST_USAGE: _NVAPI_D3D_SETRESOURCEHINT_SLI = + _NVAPI_D3D_SETRESOURCEHINT_SLI(2); +} +impl _NVAPI_D3D_SETRESOURCEHINT_SLI { + pub const NVAPI_D3D_SRH_SLI_RESPECT_DRIVER_INTERFRAME_CONTENT_SYNC: + _NVAPI_D3D_SETRESOURCEHINT_SLI = _NVAPI_D3D_SETRESOURCEHINT_SLI(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D_SETRESOURCEHINT_SLI(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D_SETRESOURCEHINT_SLI as NVAPI_D3D_SETRESOURCEHINT_SLI; +impl _NVAPI_D3D_RESOURCERENDERING_FLAG { + pub const NVAPI_D3D_RR_FLAG_DEFAULTS: _NVAPI_D3D_RESOURCERENDERING_FLAG = + _NVAPI_D3D_RESOURCERENDERING_FLAG(0); +} +impl _NVAPI_D3D_RESOURCERENDERING_FLAG { + pub const NVAPI_D3D_RR_FLAG_FORCE_DISCARD_CONTENT: _NVAPI_D3D_RESOURCERENDERING_FLAG = + _NVAPI_D3D_RESOURCERENDERING_FLAG(1); +} +impl _NVAPI_D3D_RESOURCERENDERING_FLAG { + pub const NVAPI_D3D_RR_FLAG_FORCE_KEEP_CONTENT: _NVAPI_D3D_RESOURCERENDERING_FLAG = + _NVAPI_D3D_RESOURCERENDERING_FLAG(2); +} +impl _NVAPI_D3D_RESOURCERENDERING_FLAG { + pub const NVAPI_D3D_RR_FLAG_MULTI_FRAME: _NVAPI_D3D_RESOURCERENDERING_FLAG = + _NVAPI_D3D_RESOURCERENDERING_FLAG(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D_RESOURCERENDERING_FLAG(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D_RESOURCERENDERING_FLAG as NVAPI_D3D_RESOURCERENDERING_FLAG; +impl _NV_StereoActiveEye { + pub const NVAPI_STEREO_EYE_RIGHT: _NV_StereoActiveEye = _NV_StereoActiveEye(1); +} +impl _NV_StereoActiveEye { + pub const NVAPI_STEREO_EYE_LEFT: _NV_StereoActiveEye = _NV_StereoActiveEye(2); +} +impl _NV_StereoActiveEye { + pub const NVAPI_STEREO_EYE_MONO: _NV_StereoActiveEye = _NV_StereoActiveEye(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_StereoActiveEye(pub ::std::os::raw::c_int); +pub use self::_NV_StereoActiveEye as NV_STEREO_ACTIVE_EYE; +impl _NV_StereoDriverMode { + pub const NVAPI_STEREO_DRIVER_MODE_AUTOMATIC: _NV_StereoDriverMode = _NV_StereoDriverMode(0); +} +impl _NV_StereoDriverMode { + pub const NVAPI_STEREO_DRIVER_MODE_DIRECT: _NV_StereoDriverMode = _NV_StereoDriverMode(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_StereoDriverMode(pub ::std::os::raw::c_int); +pub use self::_NV_StereoDriverMode as NV_STEREO_DRIVER_MODE; +impl _NVAPI_STEREO_SURFACECREATEMODE { + pub const NVAPI_STEREO_SURFACECREATEMODE_AUTO: _NVAPI_STEREO_SURFACECREATEMODE = + _NVAPI_STEREO_SURFACECREATEMODE(0); +} +impl _NVAPI_STEREO_SURFACECREATEMODE { + pub const NVAPI_STEREO_SURFACECREATEMODE_FORCESTEREO: _NVAPI_STEREO_SURFACECREATEMODE = + _NVAPI_STEREO_SURFACECREATEMODE(1); +} +impl _NVAPI_STEREO_SURFACECREATEMODE { + pub const NVAPI_STEREO_SURFACECREATEMODE_FORCEMONO: _NVAPI_STEREO_SURFACECREATEMODE = + _NVAPI_STEREO_SURFACECREATEMODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_STEREO_SURFACECREATEMODE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_STEREO_SURFACECREATEMODE as NVAPI_STEREO_SURFACECREATEMODE; +impl NVAPI_DEVICE_FEATURE_LEVEL { + pub const NVAPI_DEVICE_FEATURE_LEVEL_NULL: NVAPI_DEVICE_FEATURE_LEVEL = + NVAPI_DEVICE_FEATURE_LEVEL(-1); +} +impl NVAPI_DEVICE_FEATURE_LEVEL { + pub const NVAPI_DEVICE_FEATURE_LEVEL_10_0: NVAPI_DEVICE_FEATURE_LEVEL = + NVAPI_DEVICE_FEATURE_LEVEL(0); +} +impl NVAPI_DEVICE_FEATURE_LEVEL { + pub const NVAPI_DEVICE_FEATURE_LEVEL_10_0_PLUS: NVAPI_DEVICE_FEATURE_LEVEL = + NVAPI_DEVICE_FEATURE_LEVEL(1); +} +impl NVAPI_DEVICE_FEATURE_LEVEL { + pub const NVAPI_DEVICE_FEATURE_LEVEL_10_1: NVAPI_DEVICE_FEATURE_LEVEL = + NVAPI_DEVICE_FEATURE_LEVEL(2); +} +impl NVAPI_DEVICE_FEATURE_LEVEL { + pub const NVAPI_DEVICE_FEATURE_LEVEL_11_0: NVAPI_DEVICE_FEATURE_LEVEL = + NVAPI_DEVICE_FEATURE_LEVEL(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NVAPI_DEVICE_FEATURE_LEVEL(pub ::std::os::raw::c_int); +impl _NV_DP_LINK_RATE { + pub const NV_DP_1_62GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(6); +} +impl _NV_DP_LINK_RATE { + pub const NV_DP_2_70GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(10); +} +impl _NV_DP_LINK_RATE { + pub const NV_DP_5_40GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(20); +} +impl _NV_DP_LINK_RATE { + pub const NV_DP_8_10GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(30); +} +impl _NV_DP_LINK_RATE { + pub const NV_EDP_2_16GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(8); +} +impl _NV_DP_LINK_RATE { + pub const NV_EDP_2_43GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(9); +} +impl _NV_DP_LINK_RATE { + pub const NV_EDP_3_24GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(12); +} +impl _NV_DP_LINK_RATE { + pub const NV_EDP_4_32GBPS: _NV_DP_LINK_RATE = _NV_DP_LINK_RATE(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_LINK_RATE(pub ::std::os::raw::c_int); +pub use self::_NV_DP_LINK_RATE as NV_DP_LINK_RATE; +impl _NV_DP_LANE_COUNT { + pub const NV_DP_1_LANE: _NV_DP_LANE_COUNT = _NV_DP_LANE_COUNT(1); +} +impl _NV_DP_LANE_COUNT { + pub const NV_DP_2_LANE: _NV_DP_LANE_COUNT = _NV_DP_LANE_COUNT(2); +} +impl _NV_DP_LANE_COUNT { + pub const NV_DP_4_LANE: _NV_DP_LANE_COUNT = _NV_DP_LANE_COUNT(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_LANE_COUNT(pub ::std::os::raw::c_int); +pub use self::_NV_DP_LANE_COUNT as NV_DP_LANE_COUNT; +impl _NV_DP_COLOR_FORMAT { + pub const NV_DP_COLOR_FORMAT_RGB: _NV_DP_COLOR_FORMAT = _NV_DP_COLOR_FORMAT(0); +} +impl _NV_DP_COLOR_FORMAT { + pub const NV_DP_COLOR_FORMAT_YCbCr422: _NV_DP_COLOR_FORMAT = _NV_DP_COLOR_FORMAT(1); +} +impl _NV_DP_COLOR_FORMAT { + pub const NV_DP_COLOR_FORMAT_YCbCr444: _NV_DP_COLOR_FORMAT = _NV_DP_COLOR_FORMAT(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_COLOR_FORMAT(pub ::std::os::raw::c_int); +pub use self::_NV_DP_COLOR_FORMAT as NV_DP_COLOR_FORMAT; +impl _NV_DP_COLORIMETRY { + pub const NV_DP_COLORIMETRY_RGB: _NV_DP_COLORIMETRY = _NV_DP_COLORIMETRY(0); +} +impl _NV_DP_COLORIMETRY { + pub const NV_DP_COLORIMETRY_YCbCr_ITU601: _NV_DP_COLORIMETRY = _NV_DP_COLORIMETRY(1); +} +impl _NV_DP_COLORIMETRY { + pub const NV_DP_COLORIMETRY_YCbCr_ITU709: _NV_DP_COLORIMETRY = _NV_DP_COLORIMETRY(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_COLORIMETRY(pub ::std::os::raw::c_int); +pub use self::_NV_DP_COLORIMETRY as NV_DP_COLORIMETRY; +impl _NV_DP_DYNAMIC_RANGE { + pub const NV_DP_DYNAMIC_RANGE_VESA: _NV_DP_DYNAMIC_RANGE = _NV_DP_DYNAMIC_RANGE(0); +} +impl _NV_DP_DYNAMIC_RANGE { + pub const NV_DP_DYNAMIC_RANGE_CEA: _NV_DP_DYNAMIC_RANGE = _NV_DP_DYNAMIC_RANGE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_DYNAMIC_RANGE(pub ::std::os::raw::c_int); +pub use self::_NV_DP_DYNAMIC_RANGE as NV_DP_DYNAMIC_RANGE; +impl _NV_DP_BPC { + pub const NV_DP_BPC_DEFAULT: _NV_DP_BPC = _NV_DP_BPC(0); +} +impl _NV_DP_BPC { + pub const NV_DP_BPC_6: _NV_DP_BPC = _NV_DP_BPC(1); +} +impl _NV_DP_BPC { + pub const NV_DP_BPC_8: _NV_DP_BPC = _NV_DP_BPC(2); +} +impl _NV_DP_BPC { + pub const NV_DP_BPC_10: _NV_DP_BPC = _NV_DP_BPC(3); +} +impl _NV_DP_BPC { + pub const NV_DP_BPC_12: _NV_DP_BPC = _NV_DP_BPC(4); +} +impl _NV_DP_BPC { + pub const NV_DP_BPC_16: _NV_DP_BPC = _NV_DP_BPC(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DP_BPC(pub ::std::os::raw::c_int); +pub use self::_NV_DP_BPC as NV_DP_BPC; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_EDID_V1 { + pub version: NvU32, + pub EDID_Data: [NvU8; 256usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_EDID_V2 { + pub version: NvU32, + pub EDID_Data: [NvU8; 256usize], + pub sizeofEDID: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_EDID_V3 { + pub version: NvU32, + pub EDID_Data: [NvU8; 256usize], + pub sizeofEDID: NvU32, + pub edidId: NvU32, + pub offset: NvU32, +} +pub type NV_EDID = NV_EDID_V3; +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_VGA_15_PIN: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(0); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_COMPOSITE: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(16); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_SVIDEO: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(17); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_HDTV_COMPONENT: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(19); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_SCART: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(20); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_COMPOSITE_SCART_ON_EIAJ4120: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(22); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_TV_HDTV_EIAJ4120: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(23); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_PC_POD_HDTV_YPRPB: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(24); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_PC_POD_SVIDEO: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(25); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_PC_POD_COMPOSITE: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(26); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DVI_I_TV_SVIDEO: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(32); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DVI_I_TV_COMPOSITE: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(33); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DVI_I: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(48); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DVI_D: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(49); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_ADC: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(50); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_LFH_DVI_I_1: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(56); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_LFH_DVI_I_2: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(57); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_SPWG: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(64); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_OEM: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(65); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DISPLAYPORT_EXTERNAL: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(70); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DISPLAYPORT_INTERNAL: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(71); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_DISPLAYPORT_MINI_EXT: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(72); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_HDMI_A: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(97); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_HDMI_C_MINI: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(99); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_1: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(100); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_2: _NV_GPU_CONNECTOR_TYPE = + _NV_GPU_CONNECTOR_TYPE(101); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_VIRTUAL_WFD: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(112); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_USB_C: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(113); +} +impl _NV_GPU_CONNECTOR_TYPE { + pub const NVAPI_GPU_CONNECTOR_UNKNOWN: _NV_GPU_CONNECTOR_TYPE = _NV_GPU_CONNECTOR_TYPE(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_CONNECTOR_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_CONNECTOR_TYPE as NV_GPU_CONNECTOR_TYPE; +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_NONE: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(0); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_NTSCM: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(1); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_NTSCJ: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(2); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_PALM: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(4); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_PALBDGH: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(8); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_PALN: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(16); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_PALNC: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(32); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_576i: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(256); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_480i: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(512); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_ED_480p: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(1024); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_ED_576p: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(2048); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_720p: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(4096); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_1080i: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(8192); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_1080p: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(16384); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_720p50: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(32768); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_1080p24: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(65536); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_1080i50: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(131072); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_1080p50: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(262144); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp30: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(524288); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp30_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(524288); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp25: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(1048576); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp25_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(1048576); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp24: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(2097152); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp24_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(2097152); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp24_SMPTE: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(4194304); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp50_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(8388608); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp60_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(9437184); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp30_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(10485760); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp25_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(11534336); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp24_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(12582912); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp50_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(13631488); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp60_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(14680064); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp24_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(16777216); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp25_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(33554432); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp30_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(67108864); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp48_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(134217728); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp50_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(150994944); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp60_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(167772160); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp100_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(184549376); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_8Kp120_7680: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(201326592); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp48_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(218103808); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp48_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(234881024); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp100_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(251658240); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp100_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(268435456); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp120_4096: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(285212672); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp120_3840: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(301989888); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp100_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(318767104); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp120_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(335544320); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp24_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(352321536); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp25_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(369098752); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp30_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(385875968); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp48_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(402653184); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp50_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(419430400); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_4Kp60_5120: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(536870912); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp24_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(553648128); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp25_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(570425344); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp30_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(587202560); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp48_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(603979776); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp50_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(620756992); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp60_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(637534208); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp100_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(654311424); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_UHD_10Kp120_10240: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(671088640); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_SD_OTHER: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(805306368); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_ED_OTHER: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(1073741824); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_HD_OTHER: _NV_DISPLAY_TV_FORMAT = + _NV_DISPLAY_TV_FORMAT(1342177280); +} +impl _NV_DISPLAY_TV_FORMAT { + pub const NV_DISPLAY_TV_FORMAT_ANY: _NV_DISPLAY_TV_FORMAT = _NV_DISPLAY_TV_FORMAT(-2147483648); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DISPLAY_TV_FORMAT(pub ::std::os::raw::c_int); +pub use self::_NV_DISPLAY_TV_FORMAT as NV_DISPLAY_TV_FORMAT; +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_STANDARD: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(0); +} +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_CLONE: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(1); +} +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_HSPAN: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(2); +} +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_VSPAN: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(3); +} +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_DUALVIEW: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(4); +} +impl _NV_TARGET_VIEW_MODE { + pub const NV_VIEW_MODE_MULTIVIEW: _NV_TARGET_VIEW_MODE = _NV_TARGET_VIEW_MODE(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_TARGET_VIEW_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_TARGET_VIEW_MODE as NV_TARGET_VIEW_MODE; +impl _NV_SCALING { + pub const NV_SCALING_DEFAULT: _NV_SCALING = _NV_SCALING(0); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCALING_TO_CLOSEST: _NV_SCALING = _NV_SCALING(1); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCALING_TO_NATIVE: _NV_SCALING = _NV_SCALING(2); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCANOUT_TO_NATIVE: _NV_SCALING = _NV_SCALING(3); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_NATIVE: _NV_SCALING = _NV_SCALING(5); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_CLOSEST: _NV_SCALING = _NV_SCALING(6); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_SCANOUT_TO_CLOSEST: _NV_SCALING = _NV_SCALING(7); +} +impl _NV_SCALING { + pub const NV_SCALING_GPU_INTEGER_ASPECT_SCALING: _NV_SCALING = _NV_SCALING(8); +} +impl _NV_SCALING { + pub const NV_SCALING_MONITOR_SCALING: _NV_SCALING = _NV_SCALING(1); +} +impl _NV_SCALING { + pub const NV_SCALING_ADAPTER_SCALING: _NV_SCALING = _NV_SCALING(2); +} +impl _NV_SCALING { + pub const NV_SCALING_CENTERED: _NV_SCALING = _NV_SCALING(3); +} +impl _NV_SCALING { + pub const NV_SCALING_ASPECT_SCALING: _NV_SCALING = _NV_SCALING(5); +} +impl _NV_SCALING { + pub const NV_SCALING_CUSTOMIZED: _NV_SCALING = _NV_SCALING(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_SCALING(pub ::std::os::raw::c_int); +pub use self::_NV_SCALING as NV_SCALING; +impl _NV_ROTATE { + pub const NV_ROTATE_0: _NV_ROTATE = _NV_ROTATE(0); +} +impl _NV_ROTATE { + pub const NV_ROTATE_90: _NV_ROTATE = _NV_ROTATE(1); +} +impl _NV_ROTATE { + pub const NV_ROTATE_180: _NV_ROTATE = _NV_ROTATE(2); +} +impl _NV_ROTATE { + pub const NV_ROTATE_270: _NV_ROTATE = _NV_ROTATE(3); +} +impl _NV_ROTATE { + pub const NV_ROTATE_IGNORED: _NV_ROTATE = _NV_ROTATE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_ROTATE(pub ::std::os::raw::c_int); +pub use self::_NV_ROTATE as NV_ROTATE; +impl _NV_FORMAT { + pub const NV_FORMAT_UNKNOWN: _NV_FORMAT = _NV_FORMAT(0); +} +impl _NV_FORMAT { + pub const NV_FORMAT_P8: _NV_FORMAT = _NV_FORMAT(41); +} +impl _NV_FORMAT { + pub const NV_FORMAT_R5G6B5: _NV_FORMAT = _NV_FORMAT(23); +} +impl _NV_FORMAT { + pub const NV_FORMAT_A8R8G8B8: _NV_FORMAT = _NV_FORMAT(21); +} +impl _NV_FORMAT { + pub const NV_FORMAT_A16B16G16R16F: _NV_FORMAT = _NV_FORMAT(113); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_FORMAT(pub ::std::os::raw::c_int); +pub use self::_NV_FORMAT as NV_FORMAT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_VIEWPORTF { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_CURRENT: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(0); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_AUTO: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(1); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_EDID: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(2); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_DMT: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(3); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_DMT_RB: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(4); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_CVT: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(5); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_CVT_RB: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(6); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_GTF: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(7); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_EIA861: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(8); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_ANALOG_TV: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(9); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_CUST: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(10); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_NV_PREDEFINED: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(11); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_NV_PSF: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(11); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_NV_ASPR: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(12); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVERRIDE_SDI: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(13); +} +impl _NV_TIMING_OVERRIDE { + pub const NV_TIMING_OVRRIDE_MAX: _NV_TIMING_OVERRIDE = _NV_TIMING_OVERRIDE(14); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_TIMING_OVERRIDE(pub ::std::os::raw::c_int); +pub use self::_NV_TIMING_OVERRIDE as NV_TIMING_OVERRIDE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct tagNV_TIMINGEXT { + pub flag: NvU32, + pub rr: NvU16, + pub rrx1k: NvU32, + pub aspect: NvU32, + pub rep: NvU16, + pub status: NvU32, + pub name: [NvU8; 40usize], +} +pub type NV_TIMINGEXT = tagNV_TIMINGEXT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_TIMING { + pub HVisible: NvU16, + pub HBorder: NvU16, + pub HFrontPorch: NvU16, + pub HSyncWidth: NvU16, + pub HTotal: NvU16, + pub HSyncPol: NvU8, + pub VVisible: NvU16, + pub VBorder: NvU16, + pub VFrontPorch: NvU16, + pub VSyncWidth: NvU16, + pub VTotal: NvU16, + pub VSyncPol: NvU8, + pub interlaced: NvU16, + pub pclk: NvU32, + pub etc: NV_TIMINGEXT, +} +pub type NV_TIMING = _NV_TIMING; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_VIEW_TARGET_INFO { + pub version: NvU32, + pub count: NvU32, + pub target: [NV_VIEW_TARGET_INFO__bindgen_ty_1; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_VIEW_TARGET_INFO__bindgen_ty_1 { + pub deviceMask: NvU32, + pub sourceId: NvU32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +impl NV_VIEW_TARGET_INFO__bindgen_ty_1 { + #[inline] + pub fn bPrimary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bPrimary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bInterlaced(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bInterlaced(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bGDIPrimary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bGDIPrimary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn bForceModeSet(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_bForceModeSet(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bPrimary: NvU32, + bInterlaced: NvU32, + bGDIPrimary: NvU32, + bForceModeSet: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bPrimary: u32 = unsafe { ::std::mem::transmute(bPrimary) }; + bPrimary as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bInterlaced: u32 = unsafe { ::std::mem::transmute(bInterlaced) }; + bInterlaced as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bGDIPrimary: u32 = unsafe { ::std::mem::transmute(bGDIPrimary) }; + bGDIPrimary as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let bForceModeSet: u32 = unsafe { ::std::mem::transmute(bForceModeSet) }; + bForceModeSet as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_PATH { + pub deviceMask: NvU32, + pub sourceId: NvU32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub connector: NV_GPU_CONNECTOR_TYPE, + pub width: NvU32, + pub height: NvU32, + pub depth: NvU32, + pub colorFormat: NV_FORMAT, + pub rotation: NV_ROTATE, + pub scaling: NV_SCALING, + pub refreshRate: NvU32, + pub _bitfield_align_2: [u8; 0], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>, + pub tvFormat: NV_DISPLAY_TV_FORMAT, + pub posx: NvU32, + pub posy: NvU32, + pub _bitfield_align_3: [u32; 0], + pub _bitfield_3: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl NV_DISPLAY_PATH { + #[inline] + pub fn bPrimary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bPrimary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(bPrimary: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bPrimary: u32 = unsafe { ::std::mem::transmute(bPrimary) }; + bPrimary as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn interlaced(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_interlaced(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_2(interlaced: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let interlaced: u32 = unsafe { ::std::mem::transmute(interlaced) }; + interlaced as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn bGDIPrimary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bGDIPrimary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_3.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bForceModeSet(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bForceModeSet(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_3.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bFocusDisplay(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bFocusDisplay(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_3.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn gpuId(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(3usize, 24u8) as u32) } + } + #[inline] + pub fn set_gpuId(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_3.set(3usize, 24u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_3( + bGDIPrimary: NvU32, + bForceModeSet: NvU32, + bFocusDisplay: NvU32, + gpuId: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bGDIPrimary: u32 = unsafe { ::std::mem::transmute(bGDIPrimary) }; + bGDIPrimary as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bForceModeSet: u32 = unsafe { ::std::mem::transmute(bForceModeSet) }; + bForceModeSet as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bFocusDisplay: u32 = unsafe { ::std::mem::transmute(bFocusDisplay) }; + bFocusDisplay as u64 + }); + __bindgen_bitfield_unit.set(3usize, 24u8, { + let gpuId: u32 = unsafe { ::std::mem::transmute(gpuId) }; + gpuId as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_PATH_INFO_V3 { + pub version: NvU32, + pub count: NvU32, + pub path: [NV_DISPLAY_PATH; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_PATH_INFO { + pub version: NvU32, + pub count: NvU32, + pub path: [NV_DISPLAY_PATH; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_POSITION { + pub x: NvS32, + pub y: NvS32, +} +pub type NV_POSITION = _NV_POSITION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_RESOLUTION { + pub width: NvU32, + pub height: NvU32, + pub colorDepth: NvU32, +} +pub type NV_RESOLUTION = _NV_RESOLUTION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1 { + pub version: NvU32, + pub rotation: NV_ROTATE, + pub scaling: NV_SCALING, + pub refreshRate1K: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub connector: NV_GPU_CONNECTOR_TYPE, + pub tvFormat: NV_DISPLAY_TV_FORMAT, + pub timingOverride: NV_TIMING_OVERRIDE, + pub timing: NV_TIMING, +} +impl _NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1 { + #[inline] + pub fn interlaced(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_interlaced(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn primary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_primary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reservedBit1(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_reservedBit1(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn disableVirtualModeSupport(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_disableVirtualModeSupport(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isPreferredUnscaledTarget(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isPreferredUnscaledTarget(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 27u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 27u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + interlaced: NvU32, + primary: NvU32, + reservedBit1: NvU32, + disableVirtualModeSupport: NvU32, + isPreferredUnscaledTarget: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let interlaced: u32 = unsafe { ::std::mem::transmute(interlaced) }; + interlaced as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let primary: u32 = unsafe { ::std::mem::transmute(primary) }; + primary as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let reservedBit1: u32 = unsafe { ::std::mem::transmute(reservedBit1) }; + reservedBit1 as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let disableVirtualModeSupport: u32 = + unsafe { ::std::mem::transmute(disableVirtualModeSupport) }; + disableVirtualModeSupport as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isPreferredUnscaledTarget: u32 = + unsafe { ::std::mem::transmute(isPreferredUnscaledTarget) }; + isPreferredUnscaledTarget as u64 + }); + __bindgen_bitfield_unit.set(5usize, 27u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1 = + _NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1; +pub type NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO = NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1 { + pub displayId: NvU32, + pub details: *mut NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO, +} +pub type NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1 = _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2 { + pub displayId: NvU32, + pub details: *mut NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO, + pub targetId: NvU32, +} +pub type NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2 = _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2; +pub type NV_DISPLAYCONFIG_PATH_TARGET_INFO = NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2; +impl _NV_DISPLAYCONFIG_SPANNING_ORIENTATION { + pub const NV_DISPLAYCONFIG_SPAN_NONE: _NV_DISPLAYCONFIG_SPANNING_ORIENTATION = + _NV_DISPLAYCONFIG_SPANNING_ORIENTATION(0); +} +impl _NV_DISPLAYCONFIG_SPANNING_ORIENTATION { + pub const NV_DISPLAYCONFIG_SPAN_HORIZONTAL: _NV_DISPLAYCONFIG_SPANNING_ORIENTATION = + _NV_DISPLAYCONFIG_SPANNING_ORIENTATION(1); +} +impl _NV_DISPLAYCONFIG_SPANNING_ORIENTATION { + pub const NV_DISPLAYCONFIG_SPAN_VERTICAL: _NV_DISPLAYCONFIG_SPANNING_ORIENTATION = + _NV_DISPLAYCONFIG_SPANNING_ORIENTATION(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DISPLAYCONFIG_SPANNING_ORIENTATION(pub ::std::os::raw::c_int); +pub use self::_NV_DISPLAYCONFIG_SPANNING_ORIENTATION as NV_DISPLAYCONFIG_SPANNING_ORIENTATION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1 { + pub resolution: NV_RESOLUTION, + pub colorFormat: NV_FORMAT, + pub position: NV_POSITION, + pub spanningOrientation: NV_DISPLAYCONFIG_SPANNING_ORIENTATION, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1 { + #[inline] + pub fn bGDIPrimary(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bGDIPrimary(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bSLIFocus(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bSLIFocus(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bGDIPrimary: NvU32, + bSLIFocus: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bGDIPrimary: u32 = unsafe { ::std::mem::transmute(bGDIPrimary) }; + bGDIPrimary as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bSLIFocus: u32 = unsafe { ::std::mem::transmute(bSLIFocus) }; + bSLIFocus as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1 = _NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_PATH_INFO_V1 { + pub version: NvU32, + pub reserved_sourceId: NvU32, + pub targetInfoCount: NvU32, + pub targetInfo: *mut NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1, + pub sourceModeInfo: *mut NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1, +} +pub type NV_DISPLAYCONFIG_PATH_INFO_V1 = _NV_DISPLAYCONFIG_PATH_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAYCONFIG_PATH_INFO { + pub version: NvU32, + pub __bindgen_anon_1: _NV_DISPLAYCONFIG_PATH_INFO__bindgen_ty_1, + pub targetInfoCount: NvU32, + pub targetInfo: *mut NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2, + pub sourceModeInfo: *mut NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub pOSAdapterID: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_DISPLAYCONFIG_PATH_INFO__bindgen_ty_1 { + pub sourceId: NvU32, + pub reserved_sourceId: NvU32, +} +impl _NV_DISPLAYCONFIG_PATH_INFO { + #[inline] + pub fn IsNonNVIDIAAdapter(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_IsNonNVIDIAAdapter(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + IsNonNVIDIAAdapter: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let IsNonNVIDIAAdapter: u32 = unsafe { ::std::mem::transmute(IsNonNVIDIAAdapter) }; + IsNonNVIDIAAdapter as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAYCONFIG_PATH_INFO_V2 = _NV_DISPLAYCONFIG_PATH_INFO; +pub type NV_DISPLAYCONFIG_PATH_INFO = NV_DISPLAYCONFIG_PATH_INFO_V2; +pub type NV_DISPLAYCONFIG_SOURCE_MODE_INFO = NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1; +impl _NV_DISPLAYCONFIG_FLAGS { + pub const NV_DISPLAYCONFIG_VALIDATE_ONLY: _NV_DISPLAYCONFIG_FLAGS = _NV_DISPLAYCONFIG_FLAGS(1); +} +impl _NV_DISPLAYCONFIG_FLAGS { + pub const NV_DISPLAYCONFIG_SAVE_TO_PERSISTENCE: _NV_DISPLAYCONFIG_FLAGS = + _NV_DISPLAYCONFIG_FLAGS(2); +} +impl _NV_DISPLAYCONFIG_FLAGS { + pub const NV_DISPLAYCONFIG_DRIVER_RELOAD_ALLOWED: _NV_DISPLAYCONFIG_FLAGS = + _NV_DISPLAYCONFIG_FLAGS(4); +} +impl _NV_DISPLAYCONFIG_FLAGS { + pub const NV_DISPLAYCONFIG_FORCE_MODE_ENUMERATION: _NV_DISPLAYCONFIG_FLAGS = + _NV_DISPLAYCONFIG_FLAGS(8); +} +impl _NV_DISPLAYCONFIG_FLAGS { + pub const NV_FORCE_COMMIT_VIDPN: _NV_DISPLAYCONFIG_FLAGS = _NV_DISPLAYCONFIG_FLAGS(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DISPLAYCONFIG_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NV_DISPLAYCONFIG_FLAGS as NV_DISPLAYCONFIG_FLAGS; +pub type NvAPI_UnicodeString = [NvU16; 2048usize]; +pub type NvAPI_LPCWSTR = *const NvU16; +impl _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID { + pub const NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE: _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID = + _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID(0); +} +impl _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID { + pub const NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_UNDEFINED: _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID = + _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID as NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID; +impl _NV_GPU_PUBLIC_CLOCK_ID { + pub const NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS: _NV_GPU_PUBLIC_CLOCK_ID = _NV_GPU_PUBLIC_CLOCK_ID(0); +} +impl _NV_GPU_PUBLIC_CLOCK_ID { + pub const NVAPI_GPU_PUBLIC_CLOCK_MEMORY: _NV_GPU_PUBLIC_CLOCK_ID = _NV_GPU_PUBLIC_CLOCK_ID(4); +} +impl _NV_GPU_PUBLIC_CLOCK_ID { + pub const NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR: _NV_GPU_PUBLIC_CLOCK_ID = + _NV_GPU_PUBLIC_CLOCK_ID(7); +} +impl _NV_GPU_PUBLIC_CLOCK_ID { + pub const NVAPI_GPU_PUBLIC_CLOCK_VIDEO: _NV_GPU_PUBLIC_CLOCK_ID = _NV_GPU_PUBLIC_CLOCK_ID(8); +} +impl _NV_GPU_PUBLIC_CLOCK_ID { + pub const NVAPI_GPU_PUBLIC_CLOCK_UNDEFINED: _NV_GPU_PUBLIC_CLOCK_ID = + _NV_GPU_PUBLIC_CLOCK_ID(32); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_PUBLIC_CLOCK_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_PUBLIC_CLOCK_ID as NV_GPU_PUBLIC_CLOCK_ID; +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P0: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(0); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P1: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(1); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P2: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(2); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P3: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(3); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P4: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(4); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P5: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(5); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P6: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(6); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P7: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(7); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P8: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(8); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P9: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(9); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P10: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(10); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P11: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(11); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P12: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(12); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P13: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(13); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P14: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(14); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_P15: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(15); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_UNDEFINED: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(16); +} +impl _NV_GPU_PERF_PSTATE_ID { + pub const NVAPI_GPU_PERF_PSTATE_ALL: _NV_GPU_PERF_PSTATE_ID = _NV_GPU_PERF_PSTATE_ID(17); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_PERF_PSTATE_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_PERF_PSTATE_ID as NV_GPU_PERF_PSTATE_ID; +impl NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID { + pub const NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_SINGLE: NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID = + NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID(0); +} +impl NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID { + pub const NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_RANGE: NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID = + NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES20_PARAM_DELTA { + pub value: NvS32, + pub valueRange: NV_GPU_PERF_PSTATES20_PARAM_DELTA__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES20_PARAM_DELTA__bindgen_ty_1 { + pub min: NvS32, + pub max: NvS32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_V1 { + pub domainId: NV_GPU_PUBLIC_CLOCK_ID, + pub typeId: NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub freqDelta_kHz: NV_GPU_PERF_PSTATES20_PARAM_DELTA, + pub data: NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1 { + pub single: NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1__bindgen_ty_1, + pub range: NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1__bindgen_ty_1 { + pub freq_kHz: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PSTATE20_CLOCK_ENTRY_V1__bindgen_ty_1__bindgen_ty_2 { + pub minFreq_kHz: NvU32, + pub maxFreq_kHz: NvU32, + pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID, + pub minVoltage_uV: NvU32, + pub maxVoltage_uV: NvU32, +} +impl NV_GPU_PSTATE20_CLOCK_ENTRY_V1 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 { + pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub volt_uV: NvU32, + pub voltDelta_uV: NV_GPU_PERF_PSTATES20_PARAM_DELTA, +} +impl NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES20_INFO_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub numPstates: NvU32, + pub numClocks: NvU32, + pub numBaseVoltages: NvU32, + pub pstates: [NV_GPU_PERF_PSTATES20_INFO_V1__bindgen_ty_1; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES20_INFO_V1__bindgen_ty_1 { + pub pstateId: NV_GPU_PERF_PSTATE_ID, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub clocks: [NV_GPU_PSTATE20_CLOCK_ENTRY_V1; 8usize], + pub baseVoltages: [NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1; 4usize], +} +impl NV_GPU_PERF_PSTATES20_INFO_V1__bindgen_ty_1 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_GPU_PERF_PSTATES20_INFO_V1 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_PERF_PSTATES20_INFO_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub numPstates: NvU32, + pub numClocks: NvU32, + pub numBaseVoltages: NvU32, + pub pstates: [_NV_GPU_PERF_PSTATES20_INFO_V2__bindgen_ty_1; 16usize], + pub ov: _NV_GPU_PERF_PSTATES20_INFO_V2__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_PERF_PSTATES20_INFO_V2__bindgen_ty_1 { + pub pstateId: NV_GPU_PERF_PSTATE_ID, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub clocks: [NV_GPU_PSTATE20_CLOCK_ENTRY_V1; 8usize], + pub baseVoltages: [NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1; 4usize], +} +impl _NV_GPU_PERF_PSTATES20_INFO_V2__bindgen_ty_1 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_PERF_PSTATES20_INFO_V2__bindgen_ty_2 { + pub numVoltages: NvU32, + pub voltages: [NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1; 4usize], +} +impl _NV_GPU_PERF_PSTATES20_INFO_V2 { + #[inline] + pub fn bIsEditable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsEditable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsEditable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsEditable: u32 = unsafe { ::std::mem::transmute(bIsEditable) }; + bIsEditable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GPU_PERF_PSTATES20_INFO_V2 = _NV_GPU_PERF_PSTATES20_INFO_V2; +pub type NV_GPU_PERF_PSTATES20_INFO = NV_GPU_PERF_PSTATES20_INFO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_DRIVER_VERSION { + pub version: NvU32, + pub drvVersion: NvU32, + pub bldChangeListNum: NvU32, + pub szBuildBranchString: NvAPI_ShortString, + pub szAdapterString: NvAPI_ShortString, +} +pub type NVAPI_OGLEXPERT_CALLBACK = ::std::option::Option< + unsafe extern "C" fn( + categoryId: ::std::os::raw::c_uint, + messageId: ::std::os::raw::c_uint, + detailLevel: ::std::os::raw::c_uint, + objectId: ::std::os::raw::c_int, + messageStr: *const ::std::os::raw::c_char, + ), +>; +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_UNINITIALIZED: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(0); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_VGA: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(1); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_COMPONENT: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(2); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_SVIDEO: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(3); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_HDMI: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(4); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_DVI: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(5); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_LVDS: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(6); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_DP: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(7); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_COMPOSITE: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(8); +} +impl NV_MONITOR_CONN_TYPE { + pub const NV_MONITOR_CONN_TYPE_UNKNOWN: NV_MONITOR_CONN_TYPE = NV_MONITOR_CONN_TYPE(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_MONITOR_CONN_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_DISPLAYIDS { + pub version: NvU32, + pub connectorType: NV_MONITOR_CONN_TYPE, + pub displayId: NvU32, + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_GPU_DISPLAYIDS { + #[inline] + pub fn isDynamic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isDynamic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMultiStreamRootNode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMultiStreamRootNode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isActive(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isActive(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn isCluster(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_isCluster(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isOSVisible(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isOSVisible(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn isWFD(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_isWFD(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn isConnected(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_isConnected(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn reservedInternal(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 10u8) as u32) } + } + #[inline] + pub fn set_reservedInternal(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 10u8, val as u64) + } + } + #[inline] + pub fn isPhysicallyConnected(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u32) } + } + #[inline] + pub fn set_isPhysicallyConnected(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 14u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 14u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isDynamic: NvU32, + isMultiStreamRootNode: NvU32, + isActive: NvU32, + isCluster: NvU32, + isOSVisible: NvU32, + isWFD: NvU32, + isConnected: NvU32, + reservedInternal: NvU32, + isPhysicallyConnected: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isDynamic: u32 = unsafe { ::std::mem::transmute(isDynamic) }; + isDynamic as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isMultiStreamRootNode: u32 = + unsafe { ::std::mem::transmute(isMultiStreamRootNode) }; + isMultiStreamRootNode as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isActive: u32 = unsafe { ::std::mem::transmute(isActive) }; + isActive as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let isCluster: u32 = unsafe { ::std::mem::transmute(isCluster) }; + isCluster as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isOSVisible: u32 = unsafe { ::std::mem::transmute(isOSVisible) }; + isOSVisible as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let isWFD: u32 = unsafe { ::std::mem::transmute(isWFD) }; + isWFD as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let isConnected: u32 = unsafe { ::std::mem::transmute(isConnected) }; + isConnected as u64 + }); + __bindgen_bitfield_unit.set(7usize, 10u8, { + let reservedInternal: u32 = unsafe { ::std::mem::transmute(reservedInternal) }; + reservedInternal as u64 + }); + __bindgen_bitfield_unit.set(17usize, 1u8, { + let isPhysicallyConnected: u32 = + unsafe { ::std::mem::transmute(isPhysicallyConnected) }; + isPhysicallyConnected as u64 + }); + __bindgen_bitfield_unit.set(18usize, 14u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GPU_DISPLAYIDS = _NV_GPU_DISPLAYIDS; +impl NV_SYSTEM_TYPE { + pub const NV_SYSTEM_TYPE_UNKNOWN: NV_SYSTEM_TYPE = NV_SYSTEM_TYPE(0); +} +impl NV_SYSTEM_TYPE { + pub const NV_SYSTEM_TYPE_LAPTOP: NV_SYSTEM_TYPE = NV_SYSTEM_TYPE(1); +} +impl NV_SYSTEM_TYPE { + pub const NV_SYSTEM_TYPE_DESKTOP: NV_SYSTEM_TYPE = NV_SYSTEM_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_SYSTEM_TYPE(pub ::std::os::raw::c_int); +impl _NV_GPU_OUTPUT_TYPE { + pub const NVAPI_GPU_OUTPUT_UNKNOWN: _NV_GPU_OUTPUT_TYPE = _NV_GPU_OUTPUT_TYPE(0); +} +impl _NV_GPU_OUTPUT_TYPE { + pub const NVAPI_GPU_OUTPUT_CRT: _NV_GPU_OUTPUT_TYPE = _NV_GPU_OUTPUT_TYPE(1); +} +impl _NV_GPU_OUTPUT_TYPE { + pub const NVAPI_GPU_OUTPUT_DFP: _NV_GPU_OUTPUT_TYPE = _NV_GPU_OUTPUT_TYPE(2); +} +impl _NV_GPU_OUTPUT_TYPE { + pub const NVAPI_GPU_OUTPUT_TV: _NV_GPU_OUTPUT_TYPE = _NV_GPU_OUTPUT_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_OUTPUT_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_OUTPUT_TYPE as NV_GPU_OUTPUT_TYPE; +impl _NV_GPU_TYPE { + pub const NV_SYSTEM_TYPE_GPU_UNKNOWN: _NV_GPU_TYPE = _NV_GPU_TYPE(0); +} +impl _NV_GPU_TYPE { + pub const NV_SYSTEM_TYPE_IGPU: _NV_GPU_TYPE = _NV_GPU_TYPE(1); +} +impl _NV_GPU_TYPE { + pub const NV_SYSTEM_TYPE_DGPU: _NV_GPU_TYPE = _NV_GPU_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_TYPE as NV_GPU_TYPE; +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_UNDEFINED: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(0); +} +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_PCI: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(1); +} +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_AGP: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(2); +} +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_PCI_EXPRESS: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(3); +} +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_FPCI: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(4); +} +impl _NV_GPU_BUS_TYPE { + pub const NVAPI_GPU_BUS_TYPE_AXI: _NV_GPU_BUS_TYPE = _NV_GPU_BUS_TYPE(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_BUS_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_BUS_TYPE as NV_GPU_BUS_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_BOARD_INFO { + pub version: NvU32, + pub BoardNum: [NvU8; 16usize], +} +pub type NV_BOARD_INFO_V1 = _NV_BOARD_INFO; +pub type NV_BOARD_INFO = NV_BOARD_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ARCH_INFO_V1 { + pub version: NvU32, + pub architecture: NvU32, + pub implementation: NvU32, + pub revision: NvU32, +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_T2X: _NV_GPU_ARCHITECTURE_ID = + _NV_GPU_ARCHITECTURE_ID(-536870880); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_T3X: _NV_GPU_ARCHITECTURE_ID = + _NV_GPU_ARCHITECTURE_ID(-536870864); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_T4X: _NV_GPU_ARCHITECTURE_ID = + _NV_GPU_ARCHITECTURE_ID(-536870848); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_T12X: _NV_GPU_ARCHITECTURE_ID = + _NV_GPU_ARCHITECTURE_ID(-536870848); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_NV40: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(64); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_NV50: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(80); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_G78: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(96); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_G80: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(128); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_G90: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(144); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GT200: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(160); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GF100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(192); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GF110: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(208); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GK100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(224); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GK110: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(240); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GK200: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(256); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GM000: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(272); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GM200: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(288); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GP100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(304); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GV100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(320); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GV110: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(336); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_TU100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(352); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_GA100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(368); +} +impl _NV_GPU_ARCHITECTURE_ID { + pub const NV_GPU_ARCHITECTURE_AD100: _NV_GPU_ARCHITECTURE_ID = _NV_GPU_ARCHITECTURE_ID(400); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_ARCHITECTURE_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_ARCHITECTURE_ID as NV_GPU_ARCHITECTURE_ID; +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_T20: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_T30: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_T35: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(5); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_T40: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_T124: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV40: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV41: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(1); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV42: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV43: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(3); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV44: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV44A: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(10); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV46: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV47: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV49: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(9); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV4B: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(11); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV4C: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(12); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV4E: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(14); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV50: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV63: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(3); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_NV67: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G84: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G86: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G92: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G94: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G96: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_G98: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT200: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT212: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT214: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT215: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(3); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT216: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(5); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT218: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_MCP77: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(10); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT21C: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(11); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_MCP79: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(12); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GT21A: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(13); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_MCP89: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(15); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF100: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF106: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(3); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF108: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(1); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF110: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF116: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF117: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF118: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GF119: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(9); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK106: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK107: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK20A: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(10); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK110: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GK208: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GM204: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GM206: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP100: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP000: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(1); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP102: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP106: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP107: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GP108: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GV100: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GV10B: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(11); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU100: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU102: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU106: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(6); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU116: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(8); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU117: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(7); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_TU000: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(1); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GA100: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(0); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GA102: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_GA104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_AD102: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(2); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_AD103: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(3); +} +impl _NV_GPU_ARCH_IMPLEMENTATION_ID { + pub const NV_GPU_ARCH_IMPLEMENTATION_AD104: _NV_GPU_ARCH_IMPLEMENTATION_ID = + _NV_GPU_ARCH_IMPLEMENTATION_ID(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_ARCH_IMPLEMENTATION_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_ARCH_IMPLEMENTATION_ID as NV_GPU_ARCH_IMPLEMENTATION_ID; +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_EMULATION_QT: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(0); +} +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_EMULATION_FPGA: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(1); +} +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_A01: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(17); +} +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_A02: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(18); +} +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_A03: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(19); +} +impl _NV_GPU_CHIP_REVISION { + pub const NV_GPU_CHIP_REV_UNKNOWN: _NV_GPU_CHIP_REVISION = _NV_GPU_CHIP_REVISION(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_CHIP_REVISION(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_CHIP_REVISION as NV_GPU_CHIP_REVISION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ARCH_INFO_V2 { + pub version: NvU32, + pub __bindgen_anon_1: NV_GPU_ARCH_INFO_V2__bindgen_ty_1, + pub __bindgen_anon_2: NV_GPU_ARCH_INFO_V2__bindgen_ty_2, + pub __bindgen_anon_3: NV_GPU_ARCH_INFO_V2__bindgen_ty_3, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_GPU_ARCH_INFO_V2__bindgen_ty_1 { + pub architecture: NvU32, + pub architecture_id: NV_GPU_ARCHITECTURE_ID, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_GPU_ARCH_INFO_V2__bindgen_ty_2 { + pub implementation: NvU32, + pub implementation_id: NV_GPU_ARCH_IMPLEMENTATION_ID, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_GPU_ARCH_INFO_V2__bindgen_ty_3 { + pub revision: NvU32, + pub revision_id: NV_GPU_CHIP_REVISION, +} +pub type NV_GPU_ARCH_INFO = NV_GPU_ARCH_INFO_V2; +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_DEFAULT: NV_I2C_SPEED = NV_I2C_SPEED(0); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_3KHZ: NV_I2C_SPEED = NV_I2C_SPEED(1); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_10KHZ: NV_I2C_SPEED = NV_I2C_SPEED(2); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_33KHZ: NV_I2C_SPEED = NV_I2C_SPEED(3); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_100KHZ: NV_I2C_SPEED = NV_I2C_SPEED(4); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_200KHZ: NV_I2C_SPEED = NV_I2C_SPEED(5); +} +impl NV_I2C_SPEED { + pub const NVAPI_I2C_SPEED_400KHZ: NV_I2C_SPEED = NV_I2C_SPEED(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_I2C_SPEED(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_I2C_INFO_V1 { + pub version: NvU32, + pub displayMask: NvU32, + pub bIsDDCPort: NvU8, + pub i2cDevAddress: NvU8, + pub pbI2cRegAddress: *mut NvU8, + pub regAddrSize: NvU32, + pub pbData: *mut NvU8, + pub cbSize: NvU32, + pub i2cSpeed: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_I2C_INFO_V2 { + pub version: NvU32, + pub displayMask: NvU32, + pub bIsDDCPort: NvU8, + pub i2cDevAddress: NvU8, + pub pbI2cRegAddress: *mut NvU8, + pub regAddrSize: NvU32, + pub pbData: *mut NvU8, + pub cbSize: NvU32, + pub i2cSpeed: NvU32, + pub i2cSpeedKhz: NV_I2C_SPEED, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_I2C_INFO_V3 { + pub version: NvU32, + pub displayMask: NvU32, + pub bIsDDCPort: NvU8, + pub i2cDevAddress: NvU8, + pub pbI2cRegAddress: *mut NvU8, + pub regAddrSize: NvU32, + pub pbData: *mut NvU8, + pub cbSize: NvU32, + pub i2cSpeed: NvU32, + pub i2cSpeedKhz: NV_I2C_SPEED, + pub portId: NvU8, + pub bIsPortIdSet: NvU32, +} +pub type NV_I2C_INFO = NV_I2C_INFO_V3; +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_SWAPGROUP: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(1); +} +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_STEREO: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(16); +} +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_WARPING: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(256); +} +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_PIXINTENSITY: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(512); +} +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_GRAYSCALE: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(1024); +} +impl NVAPI_GPU_WORKSTATION_FEATURE_MASK { + pub const NVAPI_GPU_WORKSTATION_FEATURE_MASK_BPC10: NVAPI_GPU_WORKSTATION_FEATURE_MASK = + NVAPI_GPU_WORKSTATION_FEATURE_MASK(4096); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NVAPI_GPU_WORKSTATION_FEATURE_MASK(pub ::std::os::raw::c_int); +impl _NV_GPU_HDCP_FUSE_STATE { + pub const NV_GPU_HDCP_FUSE_STATE_UNKNOWN: _NV_GPU_HDCP_FUSE_STATE = _NV_GPU_HDCP_FUSE_STATE(0); +} +impl _NV_GPU_HDCP_FUSE_STATE { + pub const NV_GPU_HDCP_FUSE_STATE_DISABLED: _NV_GPU_HDCP_FUSE_STATE = _NV_GPU_HDCP_FUSE_STATE(1); +} +impl _NV_GPU_HDCP_FUSE_STATE { + pub const NV_GPU_HDCP_FUSE_STATE_ENABLED: _NV_GPU_HDCP_FUSE_STATE = _NV_GPU_HDCP_FUSE_STATE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_HDCP_FUSE_STATE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_HDCP_FUSE_STATE as NV_GPU_HDCP_FUSE_STATE; +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_UNKNOWN: _NV_GPU_HDCP_KEY_SOURCE = _NV_GPU_HDCP_KEY_SOURCE(0); +} +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_NONE: _NV_GPU_HDCP_KEY_SOURCE = _NV_GPU_HDCP_KEY_SOURCE(1); +} +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_CRYPTO_ROM: _NV_GPU_HDCP_KEY_SOURCE = + _NV_GPU_HDCP_KEY_SOURCE(2); +} +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_SBIOS: _NV_GPU_HDCP_KEY_SOURCE = _NV_GPU_HDCP_KEY_SOURCE(3); +} +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_I2C_ROM: _NV_GPU_HDCP_KEY_SOURCE = _NV_GPU_HDCP_KEY_SOURCE(4); +} +impl _NV_GPU_HDCP_KEY_SOURCE { + pub const NV_GPU_HDCP_KEY_SOURCE_FUSES: _NV_GPU_HDCP_KEY_SOURCE = _NV_GPU_HDCP_KEY_SOURCE(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_HDCP_KEY_SOURCE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_HDCP_KEY_SOURCE as NV_GPU_HDCP_KEY_SOURCE; +impl _NV_GPU_HDCP_KEY_SOURCE_STATE { + pub const NV_GPU_HDCP_KEY_SOURCE_STATE_UNKNOWN: _NV_GPU_HDCP_KEY_SOURCE_STATE = + _NV_GPU_HDCP_KEY_SOURCE_STATE(0); +} +impl _NV_GPU_HDCP_KEY_SOURCE_STATE { + pub const NV_GPU_HDCP_KEY_SOURCE_STATE_ABSENT: _NV_GPU_HDCP_KEY_SOURCE_STATE = + _NV_GPU_HDCP_KEY_SOURCE_STATE(1); +} +impl _NV_GPU_HDCP_KEY_SOURCE_STATE { + pub const NV_GPU_HDCP_KEY_SOURCE_STATE_PRESENT: _NV_GPU_HDCP_KEY_SOURCE_STATE = + _NV_GPU_HDCP_KEY_SOURCE_STATE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_HDCP_KEY_SOURCE_STATE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_HDCP_KEY_SOURCE_STATE as NV_GPU_HDCP_KEY_SOURCE_STATE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_GET_HDCP_SUPPORT_STATUS { + pub version: NvU32, + pub hdcpFuseState: NV_GPU_HDCP_FUSE_STATE, + pub hdcpKeySource: NV_GPU_HDCP_KEY_SOURCE, + pub hdcpKeySourceState: NV_GPU_HDCP_KEY_SOURCE_STATE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_COMPUTE_GPU_TOPOLOGY_V1 { + pub version: NvU32, + pub gpuCount: NvU32, + pub computeGpus: [NV_COMPUTE_GPU_TOPOLOGY_V1__bindgen_ty_1; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_COMPUTE_GPU_TOPOLOGY_V1__bindgen_ty_1 { + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub flags: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COMPUTE_GPU { + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub flags: NvU32, +} +pub type NV_COMPUTE_GPU = _NV_COMPUTE_GPU; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COMPUTE_GPU_TOPOLOGY_V2 { + pub version: NvU32, + pub gpuCount: NvU32, + pub computeGpus: *mut NV_COMPUTE_GPU, +} +pub type NV_COMPUTE_GPU_TOPOLOGY_V2 = _NV_COMPUTE_GPU_TOPOLOGY_V2; +pub type NV_COMPUTE_GPU_TOPOLOGY = NV_COMPUTE_GPU_TOPOLOGY_V2; +impl _NV_ECC_CONFIGURATION { + pub const NV_ECC_CONFIGURATION_NOT_SUPPORTED: _NV_ECC_CONFIGURATION = _NV_ECC_CONFIGURATION(0); +} +impl _NV_ECC_CONFIGURATION { + pub const NV_ECC_CONFIGURATION_DEFERRED: _NV_ECC_CONFIGURATION = _NV_ECC_CONFIGURATION(1); +} +impl _NV_ECC_CONFIGURATION { + pub const NV_ECC_CONFIGURATION_IMMEDIATE: _NV_ECC_CONFIGURATION = _NV_ECC_CONFIGURATION(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_ECC_CONFIGURATION(pub ::std::os::raw::c_int); +pub use self::_NV_ECC_CONFIGURATION as NV_ECC_CONFIGURATION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ECC_STATUS_INFO { + pub version: NvU32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub configurationOptions: NV_ECC_CONFIGURATION, + pub _bitfield_align_2: [u8; 0], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +impl NV_GPU_ECC_STATUS_INFO { + #[inline] + pub fn isSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(isSupported: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isSupported: u32 = unsafe { ::std::mem::transmute(isSupported) }; + isSupported as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_2(isEnabled: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ECC_ERROR_INFO { + pub version: NvU32, + pub current: NV_GPU_ECC_ERROR_INFO__bindgen_ty_1, + pub aggregate: NV_GPU_ECC_ERROR_INFO__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ECC_ERROR_INFO__bindgen_ty_1 { + pub singleBitErrors: NvU64, + pub doubleBitErrors: NvU64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ECC_ERROR_INFO__bindgen_ty_2 { + pub singleBitErrors: NvU64, + pub doubleBitErrors: NvU64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_ECC_CONFIGURATION_INFO { + pub version: NvU32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +impl NV_GPU_ECC_CONFIGURATION_INFO { + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isEnabledByDefault(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabledByDefault(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEnabled: NvU32, + isEnabledByDefault: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isEnabledByDefault: u32 = unsafe { ::std::mem::transmute(isEnabledByDefault) }; + isEnabledByDefault as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_NONE: NV_QSYNC_EVENT = NV_QSYNC_EVENT(0); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_SYNC_LOSS: NV_QSYNC_EVENT = NV_QSYNC_EVENT(1); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_SYNC_GAIN: NV_QSYNC_EVENT = NV_QSYNC_EVENT(2); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_HOUSESYNC_GAIN: NV_QSYNC_EVENT = NV_QSYNC_EVENT(3); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_HOUSESYNC_LOSS: NV_QSYNC_EVENT = NV_QSYNC_EVENT(4); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_RJ45_GAIN: NV_QSYNC_EVENT = NV_QSYNC_EVENT(5); +} +impl NV_QSYNC_EVENT { + pub const NV_QSYNC_EVENT_RJ45_LOSS: NV_QSYNC_EVENT = NV_QSYNC_EVENT(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_QSYNC_EVENT(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_QSYNC_EVENT_DATA { + pub qsyncEvent: NV_QSYNC_EVENT, + pub reserved: [NvU32; 7usize], +} +pub type NVAPI_CALLBACK_QSYNCEVENT = ::std::option::Option< + unsafe extern "C" fn( + qyncEventData: NV_QSYNC_EVENT_DATA, + callbackParam: *mut ::std::os::raw::c_void, + ), +>; +impl NV_EVENT_TYPE { + pub const NV_EVENT_TYPE_NONE: NV_EVENT_TYPE = NV_EVENT_TYPE(0); +} +impl NV_EVENT_TYPE { + pub const NV_EVENT_TYPE_QSYNC: NV_EVENT_TYPE = NV_EVENT_TYPE(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_EVENT_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_EVENT_REGISTER_CALLBACK { + pub version: NvU32, + pub eventId: NV_EVENT_TYPE, + pub callbackParam: *mut ::std::os::raw::c_void, + pub nvCallBackFunc: NV_EVENT_REGISTER_CALLBACK__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_EVENT_REGISTER_CALLBACK__bindgen_ty_1 { + pub nvQSYNCEventCallback: NVAPI_CALLBACK_QSYNCEVENT, +} +impl _NV_GPU_WORKSTATION_FEATURE_TYPE { + pub const NV_GPU_WORKSTATION_FEATURE_TYPE_NVIDIA_RTX_VR_READY: + _NV_GPU_WORKSTATION_FEATURE_TYPE = _NV_GPU_WORKSTATION_FEATURE_TYPE(1); +} +impl _NV_GPU_WORKSTATION_FEATURE_TYPE { + pub const NV_GPU_WORKSTATION_FEATURE_TYPE_QUADRO_VR_READY: _NV_GPU_WORKSTATION_FEATURE_TYPE = + _NV_GPU_WORKSTATION_FEATURE_TYPE(1); +} +impl _NV_GPU_WORKSTATION_FEATURE_TYPE { + pub const NV_GPU_WORKSTATION_FEATURE_TYPE_PROVIZ: _NV_GPU_WORKSTATION_FEATURE_TYPE = + _NV_GPU_WORKSTATION_FEATURE_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_WORKSTATION_FEATURE_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_WORKSTATION_FEATURE_TYPE as NV_GPU_WORKSTATION_FEATURE_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_SCANOUT_INTENSITY_DATA_V1 { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub blendingTexture: *mut f32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_SCANOUT_INTENSITY_DATA_V2 { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub blendingTexture: *mut f32, + pub offsetTexture: *mut f32, + pub offsetTexChannels: NvU32, +} +pub type NV_SCANOUT_INTENSITY_DATA = NV_SCANOUT_INTENSITY_DATA_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SCANOUT_INTENSITY_STATE_DATA { + pub version: NvU32, + pub bEnabled: NvU32, +} +pub type NV_SCANOUT_INTENSITY_STATE_DATA = _NV_SCANOUT_INTENSITY_STATE_DATA; +impl NV_GPU_WARPING_VERTICE_FORMAT { + pub const NV_GPU_WARPING_VERTICE_FORMAT_TRIANGLESTRIP_XYUVRQ: NV_GPU_WARPING_VERTICE_FORMAT = + NV_GPU_WARPING_VERTICE_FORMAT(0); +} +impl NV_GPU_WARPING_VERTICE_FORMAT { + pub const NV_GPU_WARPING_VERTICE_FORMAT_TRIANGLES_XYUVRQ: NV_GPU_WARPING_VERTICE_FORMAT = + NV_GPU_WARPING_VERTICE_FORMAT(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_WARPING_VERTICE_FORMAT(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_SCANOUT_WARPING_DATA { + pub version: NvU32, + pub vertices: *mut f32, + pub vertexFormat: NV_GPU_WARPING_VERTICE_FORMAT, + pub numVertices: ::std::os::raw::c_int, + pub textureRect: *mut NvSBox, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SCANOUT_WARPING_STATE_DATA { + pub version: NvU32, + pub bEnabled: NvU32, +} +pub type NV_SCANOUT_WARPING_STATE_DATA = _NV_SCANOUT_WARPING_STATE_DATA; +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_WARPING_RESAMPLING_METHOD: + NV_GPU_SCANOUT_COMPOSITION_PARAMETER = NV_GPU_SCANOUT_COMPOSITION_PARAMETER(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_SCANOUT_COMPOSITION_PARAMETER(pub ::std::os::raw::c_int); +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_SET_TO_DEFAULT: + NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE(0); +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BILINEAR: + NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = + NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE(256); +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_TRIANGULAR : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (257) ; +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_BELL_SHAPED : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (258) ; +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_BSPLINE : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (259) ; +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_TRIANGULAR : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (260) ; +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_BELL_SHAPED : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (261) ; +} +impl NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE { + pub const NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE_WARPING_RESAMPLING_METHOD_BICUBIC_ADAPTIVE_BSPLINE : NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE = NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE (262) ; +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_SCANOUT_COMPOSITION_PARAMETER_VALUE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SCANOUT_INFORMATION { + pub version: NvU32, + pub sourceDesktopRect: NvSBox, + pub sourceViewportRect: NvSBox, + pub targetViewportRect: NvSBox, + pub targetDisplayWidth: NvU32, + pub targetDisplayHeight: NvU32, + pub cloneImportance: NvU32, + pub sourceToTargetRotation: NV_ROTATE, +} +pub type NV_SCANOUT_INFORMATION = _NV_SCANOUT_INFORMATION; +impl _NV_VIRTUALIZATION_MODE { + pub const NV_VIRTUALIZATION_MODE_NONE: _NV_VIRTUALIZATION_MODE = _NV_VIRTUALIZATION_MODE(0); +} +impl _NV_VIRTUALIZATION_MODE { + pub const NV_VIRTUALIZATION_MODE_NMOS: _NV_VIRTUALIZATION_MODE = _NV_VIRTUALIZATION_MODE(1); +} +impl _NV_VIRTUALIZATION_MODE { + pub const NV_VIRTUALIZATION_MODE_VGX: _NV_VIRTUALIZATION_MODE = _NV_VIRTUALIZATION_MODE(2); +} +impl _NV_VIRTUALIZATION_MODE { + pub const NV_VIRTUALIZATION_MODE_HOST_VGPU: _NV_VIRTUALIZATION_MODE = + _NV_VIRTUALIZATION_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_VIRTUALIZATION_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_VIRTUALIZATION_MODE as NV_VIRTUALIZATION_MODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_VIRTUALIZATION_INFO { + pub version: NvU32, + pub virtualizationMode: NV_VIRTUALIZATION_MODE, + pub reserved: NvU32, +} +pub type NV_GPU_VIRTUALIZATION_INFO_V1 = _NV_GPU_VIRTUALIZATION_INFO; +pub type NV_GPU_VIRTUALIZATION_INFO = NV_GPU_VIRTUALIZATION_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LOGICAL_GPU_DATA_V1 { + pub version: NvU32, + pub pOSAdapterId: *mut ::std::os::raw::c_void, + pub physicalGpuCount: NvU32, + pub physicalGpuHandles: [NvPhysicalGpuHandle; 64usize], + pub reserved: [NvU32; 8usize], +} +pub type NV_LOGICAL_GPU_DATA_V1 = _NV_LOGICAL_GPU_DATA_V1; +pub type NV_LOGICAL_GPU_DATA = NV_LOGICAL_GPU_DATA_V1; +pub type NvAPI_LicenseString = [::std::os::raw::c_char; 128usize]; +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_UNKNOWN: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(0); +} +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_VGPU: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(1); +} +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_NVIDIA_RTX: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(2); +} +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_QUADRO: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(2); +} +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_GAMING: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(3); +} +impl _NV_LICENSE_FEATURE_TYPE { + pub const NV_LICENSE_FEATURE_COMPUTE: _NV_LICENSE_FEATURE_TYPE = _NV_LICENSE_FEATURE_TYPE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_LICENSE_FEATURE_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_LICENSE_FEATURE_TYPE as NV_LICENSE_FEATURE_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSE_EXPIRY_DETAILS { + pub year: NvU32, + pub month: NvU16, + pub day: NvU16, + pub hour: NvU16, + pub min: NvU16, + pub sec: NvU16, + pub status: NvU8, +} +pub type NV_LICENSE_EXPIRY_DETAILS = _NV_LICENSE_EXPIRY_DETAILS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSE_FEATURE_DETAILS_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub featureCode: NV_LICENSE_FEATURE_TYPE, + pub licenseInfo: NvAPI_LicenseString, +} +impl _NV_LICENSE_FEATURE_DETAILS_V1 { + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEnabled: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSE_FEATURE_DETAILS_V1 = _NV_LICENSE_FEATURE_DETAILS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSE_FEATURE_DETAILS_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub featureCode: NV_LICENSE_FEATURE_TYPE, + pub licenseInfo: NvAPI_LicenseString, + pub productName: NvAPI_LicenseString, +} +impl _NV_LICENSE_FEATURE_DETAILS_V2 { + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEnabled: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSE_FEATURE_DETAILS_V2 = _NV_LICENSE_FEATURE_DETAILS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSE_FEATURE_DETAILS_V3 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub featureCode: NV_LICENSE_FEATURE_TYPE, + pub licenseInfo: NvAPI_LicenseString, + pub productName: NvAPI_LicenseString, +} +impl _NV_LICENSE_FEATURE_DETAILS_V3 { + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isFeatureEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isFeatureEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEnabled: NvU32, + isFeatureEnabled: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isFeatureEnabled: u32 = unsafe { ::std::mem::transmute(isFeatureEnabled) }; + isFeatureEnabled as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSE_FEATURE_DETAILS_V3 = _NV_LICENSE_FEATURE_DETAILS_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSE_FEATURE_DETAILS_V4 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub featureCode: NV_LICENSE_FEATURE_TYPE, + pub licenseInfo: NvAPI_LicenseString, + pub productName: NvAPI_LicenseString, + pub licenseExpiry: NV_LICENSE_EXPIRY_DETAILS, +} +impl _NV_LICENSE_FEATURE_DETAILS_V4 { + #[inline] + pub fn isEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isFeatureEnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isFeatureEnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isEnabled: NvU32, + isFeatureEnabled: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isEnabled: u32 = unsafe { ::std::mem::transmute(isEnabled) }; + isEnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isFeatureEnabled: u32 = unsafe { ::std::mem::transmute(isFeatureEnabled) }; + isFeatureEnabled as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSE_FEATURE_DETAILS_V4 = _NV_LICENSE_FEATURE_DETAILS_V4; +pub type NV_LICENSE_FEATURE_DETAILS = NV_LICENSE_FEATURE_DETAILS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSABLE_FEATURES_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub licensableFeatureCount: NvU32, + pub signature: [NvU8; 128usize], + pub licenseDetails: [NV_LICENSE_FEATURE_DETAILS_V1; 3usize], +} +impl _NV_LICENSABLE_FEATURES_V1 { + #[inline] + pub fn isLicenseSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isLicenseSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isLicenseSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isLicenseSupported: u32 = unsafe { ::std::mem::transmute(isLicenseSupported) }; + isLicenseSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSABLE_FEATURES_V1 = _NV_LICENSABLE_FEATURES_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSABLE_FEATURES_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub licensableFeatureCount: NvU32, + pub signature: [NvU8; 128usize], + pub licenseDetails: [NV_LICENSE_FEATURE_DETAILS_V2; 3usize], +} +impl _NV_LICENSABLE_FEATURES_V2 { + #[inline] + pub fn isLicenseSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isLicenseSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isLicenseSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isLicenseSupported: u32 = unsafe { ::std::mem::transmute(isLicenseSupported) }; + isLicenseSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSABLE_FEATURES_V2 = _NV_LICENSABLE_FEATURES_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSABLE_FEATURES_V3 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub licensableFeatureCount: NvU32, + pub signature: [NvU8; 128usize], + pub licenseDetails: [NV_LICENSE_FEATURE_DETAILS_V3; 3usize], +} +impl _NV_LICENSABLE_FEATURES_V3 { + #[inline] + pub fn isLicenseSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isLicenseSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isLicenseSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isLicenseSupported: u32 = unsafe { ::std::mem::transmute(isLicenseSupported) }; + isLicenseSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSABLE_FEATURES_V3 = _NV_LICENSABLE_FEATURES_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LICENSABLE_FEATURES_V4 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub licensableFeatureCount: NvU32, + pub signature: [NvU8; 128usize], + pub licenseDetails: [NV_LICENSE_FEATURE_DETAILS_V4; 3usize], +} +impl _NV_LICENSABLE_FEATURES_V4 { + #[inline] + pub fn isLicenseSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isLicenseSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isLicenseSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isLicenseSupported: u32 = unsafe { ::std::mem::transmute(isLicenseSupported) }; + isLicenseSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_LICENSABLE_FEATURES_V4 = _NV_LICENSABLE_FEATURES_V4; +pub type NV_LICENSABLE_FEATURES = NV_LICENSABLE_FEATURES_V4; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_VR_READY_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_GPU_VR_READY_V1 { + #[inline] + pub fn isVRReady(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isVRReady(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isVRReady: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isVRReady: u32 = unsafe { ::std::mem::transmute(isVRReady) }; + isVRReady as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GPU_VR_READY_V1 = _NV_GPU_VR_READY_V1; +pub type NV_GPU_VR_READY = NV_GPU_VR_READY_V1; +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_NONE: _NVAPI_GPU_PERF_DECREASE = _NVAPI_GPU_PERF_DECREASE(0); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_THERMAL_PROTECTION: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(1); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_POWER_CONTROL: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(2); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_AC_BATT: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(4); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_API_TRIGGERED: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(8); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_INSUFFICIENT_POWER: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(16); +} +impl _NVAPI_GPU_PERF_DECREASE { + pub const NV_GPU_PERF_DECREASE_REASON_UNKNOWN: _NVAPI_GPU_PERF_DECREASE = + _NVAPI_GPU_PERF_DECREASE(-2147483648); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GPU_PERF_DECREASE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GPU_PERF_DECREASE as NVAPI_GPU_PERF_DECREASE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V1 { + pub version: NvU32, + pub flags: NvU32, + pub numPstates: NvU32, + pub numClocks: NvU32, + pub pstates: [NV_GPU_PERF_PSTATES_INFO_V1__bindgen_ty_1; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V1__bindgen_ty_1 { + pub pstateId: NV_GPU_PERF_PSTATE_ID, + pub flags: NvU32, + pub clocks: [NV_GPU_PERF_PSTATES_INFO_V1__bindgen_ty_1__bindgen_ty_1; 32usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V1__bindgen_ty_1__bindgen_ty_1 { + pub domainId: NV_GPU_PUBLIC_CLOCK_ID, + pub flags: NvU32, + pub freq: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V2 { + pub version: NvU32, + pub flags: NvU32, + pub numPstates: NvU32, + pub numClocks: NvU32, + pub numVoltages: NvU32, + pub pstates: [NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1 { + pub pstateId: NV_GPU_PERF_PSTATE_ID, + pub flags: NvU32, + pub clocks: [NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1__bindgen_ty_1; 32usize], + pub voltages: [NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1__bindgen_ty_2; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1__bindgen_ty_1 { + pub domainId: NV_GPU_PUBLIC_CLOCK_ID, + pub flags: NvU32, + pub freq: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_PERF_PSTATES_INFO_V2__bindgen_ty_1__bindgen_ty_2 { + pub domainId: NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID, + pub flags: NvU32, + pub mvolt: NvU32, +} +pub type NV_GPU_PERF_PSTATES_INFO = NV_GPU_PERF_PSTATES_INFO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX { + pub version: NvU32, + pub flags: NvU32, + pub utilization: [NV_GPU_DYNAMIC_PSTATES_INFO_EX__bindgen_ty_1; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_DYNAMIC_PSTATES_INFO_EX__bindgen_ty_1 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub percentage: NvU32, +} +impl NV_GPU_DYNAMIC_PSTATES_INFO_EX__bindgen_ty_1 { + #[inline] + pub fn bIsPresent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsPresent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(bIsPresent: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsPresent: u32 = unsafe { ::std::mem::transmute(bIsPresent) }; + bIsPresent as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_NONE: NV_THERMAL_TARGET = NV_THERMAL_TARGET(0); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_GPU: NV_THERMAL_TARGET = NV_THERMAL_TARGET(1); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_MEMORY: NV_THERMAL_TARGET = NV_THERMAL_TARGET(2); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_POWER_SUPPLY: NV_THERMAL_TARGET = NV_THERMAL_TARGET(4); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_BOARD: NV_THERMAL_TARGET = NV_THERMAL_TARGET(8); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_VCD_BOARD: NV_THERMAL_TARGET = NV_THERMAL_TARGET(9); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_VCD_INLET: NV_THERMAL_TARGET = NV_THERMAL_TARGET(10); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_VCD_OUTLET: NV_THERMAL_TARGET = NV_THERMAL_TARGET(11); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_ALL: NV_THERMAL_TARGET = NV_THERMAL_TARGET(15); +} +impl NV_THERMAL_TARGET { + pub const NVAPI_THERMAL_TARGET_UNKNOWN: NV_THERMAL_TARGET = NV_THERMAL_TARGET(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_THERMAL_TARGET(pub ::std::os::raw::c_int); +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_NONE: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(0); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL: NV_THERMAL_CONTROLLER = + NV_THERMAL_CONTROLLER(1); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_ADM1032: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(2); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_MAX6649: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(3); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_MAX1617: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(4); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_LM99: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(5); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_LM89: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(6); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_LM64: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(7); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_ADT7473: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(8); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_SBMAX6649: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(9); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_VBIOSEVT: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(10); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_OS: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(11); +} +impl NV_THERMAL_CONTROLLER { + pub const NVAPI_THERMAL_CONTROLLER_UNKNOWN: NV_THERMAL_CONTROLLER = NV_THERMAL_CONTROLLER(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_THERMAL_CONTROLLER(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_THERMAL_SETTINGS_V1 { + pub version: NvU32, + pub count: NvU32, + pub sensor: [NV_GPU_THERMAL_SETTINGS_V1__bindgen_ty_1; 3usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_THERMAL_SETTINGS_V1__bindgen_ty_1 { + pub controller: NV_THERMAL_CONTROLLER, + pub defaultMinTemp: NvU32, + pub defaultMaxTemp: NvU32, + pub currentTemp: NvU32, + pub target: NV_THERMAL_TARGET, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_THERMAL_SETTINGS_V2 { + pub version: NvU32, + pub count: NvU32, + pub sensor: [NV_GPU_THERMAL_SETTINGS_V2__bindgen_ty_1; 3usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_THERMAL_SETTINGS_V2__bindgen_ty_1 { + pub controller: NV_THERMAL_CONTROLLER, + pub defaultMinTemp: NvS32, + pub defaultMaxTemp: NvS32, + pub currentTemp: NvS32, + pub target: NV_THERMAL_TARGET, +} +pub type NV_GPU_THERMAL_SETTINGS = NV_GPU_THERMAL_SETTINGS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLOCK_FREQUENCIES_V1 { + pub version: NvU32, + pub reserved: NvU32, + pub domain: [NV_GPU_CLOCK_FREQUENCIES_V1__bindgen_ty_1; 32usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLOCK_FREQUENCIES_V1__bindgen_ty_1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub frequency: NvU32, +} +impl NV_GPU_CLOCK_FREQUENCIES_V1__bindgen_ty_1 { + #[inline] + pub fn bIsPresent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsPresent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsPresent: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsPresent: u32 = unsafe { ::std::mem::transmute(bIsPresent) }; + bIsPresent as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE { + pub const NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ: NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE = + NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE(0); +} +impl NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE { + pub const NV_GPU_CLOCK_FREQUENCIES_BASE_CLOCK: NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE = + NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE(1); +} +impl NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE { + pub const NV_GPU_CLOCK_FREQUENCIES_BOOST_CLOCK: NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE = + NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE(2); +} +impl NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE { + pub const NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE_NUM: NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE = + NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLOCK_FREQUENCIES_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub domain: [NV_GPU_CLOCK_FREQUENCIES_V2__bindgen_ty_1; 32usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLOCK_FREQUENCIES_V2__bindgen_ty_1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub frequency: NvU32, +} +impl NV_GPU_CLOCK_FREQUENCIES_V2__bindgen_ty_1 { + #[inline] + pub fn bIsPresent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsPresent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsPresent: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsPresent: u32 = unsafe { ::std::mem::transmute(bIsPresent) }; + bIsPresent as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_GPU_CLOCK_FREQUENCIES_V2 { + #[inline] + pub fn ClockType(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + pub fn set_ClockType(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 20u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 20u8, val as u64) + } + } + #[inline] + pub fn reserved1(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u32) } + } + #[inline] + pub fn set_reserved1(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + ClockType: NvU32, + reserved: NvU32, + reserved1: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let ClockType: u32 = unsafe { ::std::mem::transmute(ClockType) }; + ClockType as u64 + }); + __bindgen_bitfield_unit.set(4usize, 20u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit.set(24usize, 8u8, { + let reserved1: u32 = unsafe { ::std::mem::transmute(reserved1) }; + reserved1 as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GPU_CLOCK_FREQUENCIES = NV_GPU_CLOCK_FREQUENCIES_V2; +impl _NV_GPU_ILLUMINATION_ATTRIB { + pub const NV_GPU_IA_LOGO_BRIGHTNESS: _NV_GPU_ILLUMINATION_ATTRIB = + _NV_GPU_ILLUMINATION_ATTRIB(0); +} +impl _NV_GPU_ILLUMINATION_ATTRIB { + pub const NV_GPU_IA_SLI_BRIGHTNESS: _NV_GPU_ILLUMINATION_ATTRIB = + _NV_GPU_ILLUMINATION_ATTRIB(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_ILLUMINATION_ATTRIB(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_ILLUMINATION_ATTRIB as NV_GPU_ILLUMINATION_ATTRIB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1 { + pub version: NvU32, + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub Attribute: NV_GPU_ILLUMINATION_ATTRIB, + pub bSupported: NvU32, +} +pub type NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1 = _NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1; +pub type NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM = NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_GET_ILLUMINATION_PARM_V1 { + pub version: NvU32, + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub Attribute: NV_GPU_ILLUMINATION_ATTRIB, + pub Value: NvU32, +} +pub type NV_GPU_GET_ILLUMINATION_PARM_V1 = _NV_GPU_GET_ILLUMINATION_PARM_V1; +pub type NV_GPU_GET_ILLUMINATION_PARM = NV_GPU_GET_ILLUMINATION_PARM_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_SET_ILLUMINATION_PARM_V1 { + pub version: NvU32, + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub Attribute: NV_GPU_ILLUMINATION_ATTRIB, + pub Value: NvU32, +} +pub type NV_GPU_SET_ILLUMINATION_PARM_V1 = _NV_GPU_SET_ILLUMINATION_PARM_V1; +pub type NV_GPU_SET_ILLUMINATION_PARM = NV_GPU_SET_ILLUMINATION_PARM_V1; +impl NV_GPU_CLIENT_ILLUM_CTRL_MODE { + pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_MANUAL_RGB: NV_GPU_CLIENT_ILLUM_CTRL_MODE = + NV_GPU_CLIENT_ILLUM_CTRL_MODE(0); +} +impl NV_GPU_CLIENT_ILLUM_CTRL_MODE { + pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_PIECEWISE_LINEAR_RGB: NV_GPU_CLIENT_ILLUM_CTRL_MODE = + NV_GPU_CLIENT_ILLUM_CTRL_MODE(1); +} +impl NV_GPU_CLIENT_ILLUM_CTRL_MODE { + pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_MANUAL: NV_GPU_CLIENT_ILLUM_CTRL_MODE = + NV_GPU_CLIENT_ILLUM_CTRL_MODE(0); +} +impl NV_GPU_CLIENT_ILLUM_CTRL_MODE { + pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_PIECEWISE_LINEAR: NV_GPU_CLIENT_ILLUM_CTRL_MODE = + NV_GPU_CLIENT_ILLUM_CTRL_MODE(1); +} +impl NV_GPU_CLIENT_ILLUM_CTRL_MODE { + pub const NV_GPU_CLIENT_ILLUM_CTRL_MODE_INVALID: NV_GPU_CLIENT_ILLUM_CTRL_MODE = + NV_GPU_CLIENT_ILLUM_CTRL_MODE(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLIENT_ILLUM_CTRL_MODE(pub ::std::os::raw::c_int); +impl NV_GPU_CLIENT_ILLUM_ZONE_LOCATION { + pub const NV_GPU_CLIENT_ILLUM_ZONE_LOCATION_GPU_TOP_0: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION = + NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(0); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_LOCATION { + pub const NV_GPU_CLIENT_ILLUM_ZONE_LOCATION_GPU_FRONT_0: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION = + NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(8); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_LOCATION { + pub const NV_GPU_CLIENT_ILLUM_ZONE_LOCATION_GPU_BACK_0: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION = + NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(12); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_LOCATION { + pub const NV_GPU_CLIENT_ILLUM_ZONE_LOCATION_SLI_TOP_0: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION = + NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(32); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_LOCATION { + pub const NV_GPU_CLIENT_ILLUM_ZONE_LOCATION_INVALID: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION = + NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLIENT_ILLUM_ZONE_LOCATION(pub ::std::os::raw::c_int); +impl NV_GPU_CLIENT_ILLUM_DEVICE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_DEVICE_TYPE_INVALID: NV_GPU_CLIENT_ILLUM_DEVICE_TYPE = + NV_GPU_CLIENT_ILLUM_DEVICE_TYPE(0); +} +impl NV_GPU_CLIENT_ILLUM_DEVICE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_DEVICE_TYPE_MCUV10: NV_GPU_CLIENT_ILLUM_DEVICE_TYPE = + NV_GPU_CLIENT_ILLUM_DEVICE_TYPE(1); +} +impl NV_GPU_CLIENT_ILLUM_DEVICE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_DEVICE_TYPE_GPIO_PWM_RGBW_V10: NV_GPU_CLIENT_ILLUM_DEVICE_TYPE = + NV_GPU_CLIENT_ILLUM_DEVICE_TYPE(2); +} +impl NV_GPU_CLIENT_ILLUM_DEVICE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_DEVICE_TYPE_GPIO_PWM_SINGLE_COLOR_V10: + NV_GPU_CLIENT_ILLUM_DEVICE_TYPE = NV_GPU_CLIENT_ILLUM_DEVICE_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLIENT_ILLUM_DEVICE_TYPE(pub ::std::os::raw::c_int); +impl NV_GPU_CLIENT_ILLUM_ZONE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_ZONE_TYPE_INVALID: NV_GPU_CLIENT_ILLUM_ZONE_TYPE = + NV_GPU_CLIENT_ILLUM_ZONE_TYPE(0); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_ZONE_TYPE_RGB: NV_GPU_CLIENT_ILLUM_ZONE_TYPE = + NV_GPU_CLIENT_ILLUM_ZONE_TYPE(1); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_ZONE_TYPE_COLOR_FIXED: NV_GPU_CLIENT_ILLUM_ZONE_TYPE = + NV_GPU_CLIENT_ILLUM_ZONE_TYPE(2); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_ZONE_TYPE_RGBW: NV_GPU_CLIENT_ILLUM_ZONE_TYPE = + NV_GPU_CLIENT_ILLUM_ZONE_TYPE(3); +} +impl NV_GPU_CLIENT_ILLUM_ZONE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_ZONE_TYPE_SINGLE_COLOR: NV_GPU_CLIENT_ILLUM_ZONE_TYPE = + NV_GPU_CLIENT_ILLUM_ZONE_TYPE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLIENT_ILLUM_ZONE_TYPE(pub ::std::os::raw::c_int); +impl NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_HALF_HALT: + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE = + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE(0); +} +impl NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_FULL_HALT: + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE = + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE(1); +} +impl NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_FULL_REPEAT: + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE = + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE(2); +} +impl NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE { + pub const NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_INVALID: + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE = + NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_MCUV10 { + pub i2cDevIdx: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_MCUV10 = _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_MCUV10; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_RGBW { + pub gpioPinRed: NvU8, + pub gpioPinGreen: NvU8, + pub gpioPinBlue: NvU8, + pub gpioPinWhite: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_RGBW = + _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_RGBW; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_SINGLE_COLOR { + pub gpioPinSingleColor: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_SINGLE_COLOR = + _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_SINGLE_COLOR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1 { + pub type_: NV_GPU_CLIENT_ILLUM_DEVICE_TYPE, + pub ctrlModeMask: NvU32, + pub data: _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1__bindgen_ty_1 { + pub mcuv10: NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_MCUV10, + pub gpioPwmRgbwv10: NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_RGBW, + pub gpioPwmSingleColorv10: NV_GPU_CLIENT_ILLUM_DEVICE_INFO_DATA_GPIO_PWM_SINGLE_COLOR, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1 = _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_PARAMS_V1 { + pub version: NvU32, + pub numIllumDevices: NvU32, + pub rsvd: [NvU8; 64usize], + pub devices: [NV_GPU_CLIENT_ILLUM_DEVICE_INFO_V1; 32usize], +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_PARAMS_V1 = _NV_GPU_CLIENT_ILLUM_DEVICE_INFO_PARAMS_V1; +pub type NV_GPU_CLIENT_ILLUM_DEVICE_INFO_PARAMS = NV_GPU_CLIENT_ILLUM_DEVICE_INFO_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLIENT_ILLUM_DEVICE_SYNC_V1 { + pub bSync: NvBool, + pub timeStampms: NvU64, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_V1 { + pub type_: NV_GPU_CLIENT_ILLUM_DEVICE_TYPE, + pub syncData: NV_GPU_CLIENT_ILLUM_DEVICE_SYNC_V1, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL = NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_PARAMS_V1 { + pub version: NvU32, + pub numIllumDevices: NvU32, + pub rsvd: [NvU8; 64usize], + pub devices: [NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_V1; 32usize], +} +pub type NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_PARAMS = NV_GPU_CLIENT_ILLUM_DEVICE_CONTROL_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGB { + pub rsvd: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGB = _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGBW { + pub rsvd: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGBW = _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGBW; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_SINGLE_COLOR { + pub rsvd: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_SINGLE_COLOR = + _NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_SINGLE_COLOR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1 { + pub type_: NV_GPU_CLIENT_ILLUM_ZONE_TYPE, + pub illumDeviceIdx: NvU8, + pub provIdx: NvU8, + pub zoneLocation: NV_GPU_CLIENT_ILLUM_ZONE_LOCATION, + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1__bindgen_ty_1 { + pub rgb: NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGB, + pub rgbw: NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_RGBW, + pub singleColor: NV_GPU_CLIENT_ILLUM_ZONE_INFO_DATA_SINGLE_COLOR, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1 = _NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_INFO_PARAMS_V1 { + pub version: NvU32, + pub numIllumZones: NvU32, + pub rsvd: [NvU8; 64usize], + pub zones: [NV_GPU_CLIENT_ILLUM_ZONE_INFO_V1; 32usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_PARAMS_V1 = _NV_GPU_CLIENT_ILLUM_ZONE_INFO_PARAMS_V1; +pub type NV_GPU_CLIENT_ILLUM_ZONE_INFO_PARAMS = NV_GPU_CLIENT_ILLUM_ZONE_INFO_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB_PARAMS { + pub colorR: NvU8, + pub colorG: NvU8, + pub colorB: NvU8, + pub brightnessPct: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB_PARAMS = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB_PARAMS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB { + pub rgbParams: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB_PARAMS, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR { + pub cycleType: NV_GPU_CLIENT_ILLUM_PIECEWISE_LINEAR_CYCLE_TYPE, + pub grpCount: NvU8, + pub riseTimems: NvU16, + pub fallTimems: NvU16, + pub ATimems: NvU16, + pub BTimems: NvU16, + pub grpIdleTimems: NvU16, + pub phaseOffsetms: NvU16, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGB { + pub rgbParams: [NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB_PARAMS; 2usize], + pub piecewiseLinearData: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGB = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB { + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB__bindgen_ty_1 { + pub manualRGB: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGB, + pub piecewiseLinearRGB: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGB, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB = _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED_PARAMS { + pub brightnessPct: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED_PARAMS = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED_PARAMS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED { + pub colorFixedParams: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED_PARAMS, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_COLOR_FIXED { + pub colorFixedParams: [NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED_PARAMS; 2usize], + pub piecewiseLinearData: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_COLOR_FIXED = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_COLOR_FIXED; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED { + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED__bindgen_ty_1 { + pub manualColorFixed: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_COLOR_FIXED, + pub piecewiseLinearColorFixed: + NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_COLOR_FIXED, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW_PARAMS { + pub colorR: NvU8, + pub colorG: NvU8, + pub colorB: NvU8, + pub colorW: NvU8, + pub brightnessPct: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW_PARAMS = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW_PARAMS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW { + pub rgbwParams: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW_PARAMS, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGBW { + pub rgbwParams: [NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW_PARAMS; 2usize], + pub piecewiseLinearData: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGBW = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGBW; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW { + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW__bindgen_ty_1 { + pub manualRGBW: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_RGBW, + pub piecewiseLinearRGBW: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_RGBW, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW = _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR_PARAMS { + pub brightnessPct: NvU8, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR_PARAMS = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR_PARAMS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR { + pub singleColorParams: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR_PARAMS, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_SINGLE_COLOR { + pub singleColorParams: + [NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR_PARAMS; 2usize], + pub piecewiseLinearData: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR, +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_SINGLE_COLOR = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_SINGLE_COLOR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR { + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR__bindgen_ty_1 { + pub manualSingleColor: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_MANUAL_SINGLE_COLOR, + pub piecewiseLinearSingleColor: + NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_PIECEWISE_LINEAR_SINGLE_COLOR, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR = + _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1 { + pub type_: NV_GPU_CLIENT_ILLUM_ZONE_TYPE, + pub ctrlMode: NV_GPU_CLIENT_ILLUM_CTRL_MODE, + pub data: _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1__bindgen_ty_1, + pub rsvd: [NvU8; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1__bindgen_ty_1 { + pub rgb: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGB, + pub colorFixed: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_COLOR_FIXED, + pub rgbw: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_RGBW, + pub singleColor: NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_DATA_SINGLE_COLOR, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1 = _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub numIllumZonesControl: NvU32, + pub rsvd: [NvU8; 64usize], + pub zones: [NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_V1; 32usize], +} +impl _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS_V1 { + #[inline] + pub fn bDefault(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDefault(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn rsvdField(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_rsvdField(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bDefault: NvU32, + rsvdField: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bDefault: u32 = unsafe { ::std::mem::transmute(bDefault) }; + bDefault as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let rsvdField: u32 = unsafe { ::std::mem::transmute(rsvdField) }; + rsvdField as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS_V1 = _NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS_V1; +pub type NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS = NV_GPU_CLIENT_ILLUM_ZONE_CONTROL_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAY_PORT_INFO_V1 { + pub version: NvU32, + pub dpcd_ver: NvU32, + pub maxLinkRate: NV_DP_LINK_RATE, + pub maxLaneCount: NV_DP_LANE_COUNT, + pub curLinkRate: NV_DP_LINK_RATE, + pub curLaneCount: NV_DP_LANE_COUNT, + pub colorFormat: NV_DP_COLOR_FORMAT, + pub dynamicRange: NV_DP_DYNAMIC_RANGE, + pub colorimetry: NV_DP_COLORIMETRY, + pub bpc: NV_DP_BPC, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_DISPLAY_PORT_INFO_V1 { + #[inline] + pub fn isDp(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isDp(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isInternalDp(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isInternalDp(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isColorCtrlSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isColorCtrlSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn is6BPCSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_is6BPCSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn is8BPCSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_is8BPCSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn is10BPCSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_is10BPCSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn is12BPCSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_is12BPCSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn is16BPCSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_is16BPCSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCrCb420Supported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCrCb420Supported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCrCb422Supported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCrCb422Supported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCrCb444Supported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCrCb444Supported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[inline] + pub fn isRgb444SupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } + } + #[inline] + pub fn set_isRgb444SupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCbCr444SupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCbCr444SupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCbCr422SupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCbCr422SupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[inline] + pub fn isYCbCr420SupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } + } + #[inline] + pub fn set_isYCbCr420SupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn is6BPCSupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u32) } + } + #[inline] + pub fn set_is6BPCSupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[inline] + pub fn is8BPCSupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u32) } + } + #[inline] + pub fn set_is8BPCSupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[inline] + pub fn is10BPCSupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u32) } + } + #[inline] + pub fn set_is10BPCSupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) + } + } + #[inline] + pub fn is12BPCSupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u32) } + } + #[inline] + pub fn set_is12BPCSupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 1u8, val as u64) + } + } + #[inline] + pub fn is16BPCSupportedOnCurrentMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u32) } + } + #[inline] + pub fn set_is16BPCSupportedOnCurrentMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC709Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC709Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonsYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonsYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonAdobeYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonAdobeYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonAdobeRGBCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonAdobeRGBCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonBT2020RGBCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonBT2020RGBCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonBT2020YCCCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonBT2020YCCCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonBT2020cYCCCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonBT2020cYCCCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(27usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 4u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(28usize, 4u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isDp: NvU32, + isInternalDp: NvU32, + isColorCtrlSupported: NvU32, + is6BPCSupported: NvU32, + is8BPCSupported: NvU32, + is10BPCSupported: NvU32, + is12BPCSupported: NvU32, + is16BPCSupported: NvU32, + isYCrCb420Supported: NvU32, + isYCrCb422Supported: NvU32, + isYCrCb444Supported: NvU32, + isRgb444SupportedOnCurrentMode: NvU32, + isYCbCr444SupportedOnCurrentMode: NvU32, + isYCbCr422SupportedOnCurrentMode: NvU32, + isYCbCr420SupportedOnCurrentMode: NvU32, + is6BPCSupportedOnCurrentMode: NvU32, + is8BPCSupportedOnCurrentMode: NvU32, + is10BPCSupportedOnCurrentMode: NvU32, + is12BPCSupportedOnCurrentMode: NvU32, + is16BPCSupportedOnCurrentMode: NvU32, + isMonxvYCC601Capable: NvU32, + isMonxvYCC709Capable: NvU32, + isMonsYCC601Capable: NvU32, + isMonAdobeYCC601Capable: NvU32, + isMonAdobeRGBCapable: NvU32, + isMonBT2020RGBCapable: NvU32, + isMonBT2020YCCCapable: NvU32, + isMonBT2020cYCCCapable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isDp: u32 = unsafe { ::std::mem::transmute(isDp) }; + isDp as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isInternalDp: u32 = unsafe { ::std::mem::transmute(isInternalDp) }; + isInternalDp as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isColorCtrlSupported: u32 = unsafe { ::std::mem::transmute(isColorCtrlSupported) }; + isColorCtrlSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let is6BPCSupported: u32 = unsafe { ::std::mem::transmute(is6BPCSupported) }; + is6BPCSupported as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let is8BPCSupported: u32 = unsafe { ::std::mem::transmute(is8BPCSupported) }; + is8BPCSupported as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let is10BPCSupported: u32 = unsafe { ::std::mem::transmute(is10BPCSupported) }; + is10BPCSupported as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let is12BPCSupported: u32 = unsafe { ::std::mem::transmute(is12BPCSupported) }; + is12BPCSupported as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let is16BPCSupported: u32 = unsafe { ::std::mem::transmute(is16BPCSupported) }; + is16BPCSupported as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let isYCrCb420Supported: u32 = unsafe { ::std::mem::transmute(isYCrCb420Supported) }; + isYCrCb420Supported as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let isYCrCb422Supported: u32 = unsafe { ::std::mem::transmute(isYCrCb422Supported) }; + isYCrCb422Supported as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let isYCrCb444Supported: u32 = unsafe { ::std::mem::transmute(isYCrCb444Supported) }; + isYCrCb444Supported as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let isRgb444SupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(isRgb444SupportedOnCurrentMode) }; + isRgb444SupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let isYCbCr444SupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(isYCbCr444SupportedOnCurrentMode) }; + isYCbCr444SupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let isYCbCr422SupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(isYCbCr422SupportedOnCurrentMode) }; + isYCbCr422SupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let isYCbCr420SupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(isYCbCr420SupportedOnCurrentMode) }; + isYCbCr420SupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(15usize, 1u8, { + let is6BPCSupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(is6BPCSupportedOnCurrentMode) }; + is6BPCSupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(16usize, 1u8, { + let is8BPCSupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(is8BPCSupportedOnCurrentMode) }; + is8BPCSupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(17usize, 1u8, { + let is10BPCSupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(is10BPCSupportedOnCurrentMode) }; + is10BPCSupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(18usize, 1u8, { + let is12BPCSupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(is12BPCSupportedOnCurrentMode) }; + is12BPCSupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(19usize, 1u8, { + let is16BPCSupportedOnCurrentMode: u32 = + unsafe { ::std::mem::transmute(is16BPCSupportedOnCurrentMode) }; + is16BPCSupportedOnCurrentMode as u64 + }); + __bindgen_bitfield_unit.set(20usize, 1u8, { + let isMonxvYCC601Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC601Capable) }; + isMonxvYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(21usize, 1u8, { + let isMonxvYCC709Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC709Capable) }; + isMonxvYCC709Capable as u64 + }); + __bindgen_bitfield_unit.set(22usize, 1u8, { + let isMonsYCC601Capable: u32 = unsafe { ::std::mem::transmute(isMonsYCC601Capable) }; + isMonsYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(23usize, 1u8, { + let isMonAdobeYCC601Capable: u32 = + unsafe { ::std::mem::transmute(isMonAdobeYCC601Capable) }; + isMonAdobeYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(24usize, 1u8, { + let isMonAdobeRGBCapable: u32 = unsafe { ::std::mem::transmute(isMonAdobeRGBCapable) }; + isMonAdobeRGBCapable as u64 + }); + __bindgen_bitfield_unit.set(25usize, 1u8, { + let isMonBT2020RGBCapable: u32 = + unsafe { ::std::mem::transmute(isMonBT2020RGBCapable) }; + isMonBT2020RGBCapable as u64 + }); + __bindgen_bitfield_unit.set(26usize, 1u8, { + let isMonBT2020YCCCapable: u32 = + unsafe { ::std::mem::transmute(isMonBT2020YCCCapable) }; + isMonBT2020YCCCapable as u64 + }); + __bindgen_bitfield_unit.set(27usize, 1u8, { + let isMonBT2020cYCCCapable: u32 = + unsafe { ::std::mem::transmute(isMonBT2020cYCCCapable) }; + isMonBT2020cYCCCapable as u64 + }); + __bindgen_bitfield_unit.set(28usize, 4u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAY_PORT_INFO_V1 = _NV_DISPLAY_PORT_INFO_V1; +pub type NV_DISPLAY_PORT_INFO = NV_DISPLAY_PORT_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_DISPLAY_PORT_CONFIG { + pub version: NvU32, + pub linkRate: NV_DP_LINK_RATE, + pub laneCount: NV_DP_LANE_COUNT, + pub colorFormat: NV_DP_COLOR_FORMAT, + pub dynamicRange: NV_DP_DYNAMIC_RANGE, + pub colorimetry: NV_DP_COLORIMETRY, + pub bpc: NV_DP_BPC, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +impl NV_DISPLAY_PORT_CONFIG { + #[inline] + pub fn isHPD(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isHPD(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isSetDeferred(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isSetDeferred(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isChromaLpfOff(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isChromaLpfOff(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn isDitherOff(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_isDitherOff(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn testLinkTrain(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_testLinkTrain(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn testColorChange(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_testColorChange(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isHPD: NvU32, + isSetDeferred: NvU32, + isChromaLpfOff: NvU32, + isDitherOff: NvU32, + testLinkTrain: NvU32, + testColorChange: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isHPD: u32 = unsafe { ::std::mem::transmute(isHPD) }; + isHPD as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isSetDeferred: u32 = unsafe { ::std::mem::transmute(isSetDeferred) }; + isSetDeferred as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isChromaLpfOff: u32 = unsafe { ::std::mem::transmute(isChromaLpfOff) }; + isChromaLpfOff as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let isDitherOff: u32 = unsafe { ::std::mem::transmute(isDitherOff) }; + isDitherOff as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let testLinkTrain: u32 = unsafe { ::std::mem::transmute(testLinkTrain) }; + testLinkTrain as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let testColorChange: u32 = unsafe { ::std::mem::transmute(testColorChange) }; + testColorChange as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDMI_SUPPORT_INFO_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub EDID861ExtRev: NvU32, +} +impl _NV_HDMI_SUPPORT_INFO_V1 { + #[inline] + pub fn isGpuHDMICapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isGpuHDMICapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonUnderscanCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonUnderscanCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonBasicAudioCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonBasicAudioCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonYCbCr444Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonYCbCr444Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonYCbCr422Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonYCbCr422Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC709Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC709Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonHDMI(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonHDMI(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 24u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 24u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isGpuHDMICapable: NvU32, + isMonUnderscanCapable: NvU32, + isMonBasicAudioCapable: NvU32, + isMonYCbCr444Capable: NvU32, + isMonYCbCr422Capable: NvU32, + isMonxvYCC601Capable: NvU32, + isMonxvYCC709Capable: NvU32, + isMonHDMI: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isGpuHDMICapable: u32 = unsafe { ::std::mem::transmute(isGpuHDMICapable) }; + isGpuHDMICapable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isMonUnderscanCapable: u32 = + unsafe { ::std::mem::transmute(isMonUnderscanCapable) }; + isMonUnderscanCapable as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isMonBasicAudioCapable: u32 = + unsafe { ::std::mem::transmute(isMonBasicAudioCapable) }; + isMonBasicAudioCapable as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let isMonYCbCr444Capable: u32 = unsafe { ::std::mem::transmute(isMonYCbCr444Capable) }; + isMonYCbCr444Capable as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isMonYCbCr422Capable: u32 = unsafe { ::std::mem::transmute(isMonYCbCr422Capable) }; + isMonYCbCr422Capable as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let isMonxvYCC601Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC601Capable) }; + isMonxvYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let isMonxvYCC709Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC709Capable) }; + isMonxvYCC709Capable as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let isMonHDMI: u32 = unsafe { ::std::mem::transmute(isMonHDMI) }; + isMonHDMI as u64 + }); + __bindgen_bitfield_unit.set(8usize, 24u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_HDMI_SUPPORT_INFO_V1 = _NV_HDMI_SUPPORT_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDMI_SUPPORT_INFO_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub EDID861ExtRev: NvU32, +} +impl _NV_HDMI_SUPPORT_INFO_V2 { + #[inline] + pub fn isGpuHDMICapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isGpuHDMICapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonUnderscanCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonUnderscanCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonBasicAudioCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonBasicAudioCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonYCbCr444Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonYCbCr444Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonYCbCr422Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonYCbCr422Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonxvYCC709Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonxvYCC709Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonHDMI(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonHDMI(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonsYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonsYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonAdobeYCC601Capable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonAdobeYCC601Capable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMonAdobeRGBCapable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMonAdobeRGBCapable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 21u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 21u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isGpuHDMICapable: NvU32, + isMonUnderscanCapable: NvU32, + isMonBasicAudioCapable: NvU32, + isMonYCbCr444Capable: NvU32, + isMonYCbCr422Capable: NvU32, + isMonxvYCC601Capable: NvU32, + isMonxvYCC709Capable: NvU32, + isMonHDMI: NvU32, + isMonsYCC601Capable: NvU32, + isMonAdobeYCC601Capable: NvU32, + isMonAdobeRGBCapable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isGpuHDMICapable: u32 = unsafe { ::std::mem::transmute(isGpuHDMICapable) }; + isGpuHDMICapable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isMonUnderscanCapable: u32 = + unsafe { ::std::mem::transmute(isMonUnderscanCapable) }; + isMonUnderscanCapable as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isMonBasicAudioCapable: u32 = + unsafe { ::std::mem::transmute(isMonBasicAudioCapable) }; + isMonBasicAudioCapable as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let isMonYCbCr444Capable: u32 = unsafe { ::std::mem::transmute(isMonYCbCr444Capable) }; + isMonYCbCr444Capable as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isMonYCbCr422Capable: u32 = unsafe { ::std::mem::transmute(isMonYCbCr422Capable) }; + isMonYCbCr422Capable as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let isMonxvYCC601Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC601Capable) }; + isMonxvYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let isMonxvYCC709Capable: u32 = unsafe { ::std::mem::transmute(isMonxvYCC709Capable) }; + isMonxvYCC709Capable as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let isMonHDMI: u32 = unsafe { ::std::mem::transmute(isMonHDMI) }; + isMonHDMI as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let isMonsYCC601Capable: u32 = unsafe { ::std::mem::transmute(isMonsYCC601Capable) }; + isMonsYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let isMonAdobeYCC601Capable: u32 = + unsafe { ::std::mem::transmute(isMonAdobeYCC601Capable) }; + isMonAdobeYCC601Capable as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let isMonAdobeRGBCapable: u32 = unsafe { ::std::mem::transmute(isMonAdobeRGBCapable) }; + isMonAdobeRGBCapable as u64 + }); + __bindgen_bitfield_unit.set(11usize, 21u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_HDMI_SUPPORT_INFO_V2 = _NV_HDMI_SUPPORT_INFO_V2; +pub type NV_HDMI_SUPPORT_INFO = NV_HDMI_SUPPORT_INFO_V2; +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_GET_DEFAULT: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(0); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_RESET: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(1); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_GET: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(2); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_SET: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(3); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_GET_OVERRIDE: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(4); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_SET_OVERRIDE: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(5); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_GET_PROPERTY: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(6); +} +impl NV_INFOFRAME_CMD { + pub const NV_INFOFRAME_CMD_SET_PROPERTY: NV_INFOFRAME_CMD = NV_INFOFRAME_CMD(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_CMD(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_PROPERTY_MODE { + pub const NV_INFOFRAME_PROPERTY_MODE_AUTO: NV_INFOFRAME_PROPERTY_MODE = + NV_INFOFRAME_PROPERTY_MODE(0); +} +impl NV_INFOFRAME_PROPERTY_MODE { + pub const NV_INFOFRAME_PROPERTY_MODE_ENABLE: NV_INFOFRAME_PROPERTY_MODE = + NV_INFOFRAME_PROPERTY_MODE(1); +} +impl NV_INFOFRAME_PROPERTY_MODE { + pub const NV_INFOFRAME_PROPERTY_MODE_DISABLE: NV_INFOFRAME_PROPERTY_MODE = + NV_INFOFRAME_PROPERTY_MODE(2); +} +impl NV_INFOFRAME_PROPERTY_MODE { + pub const NV_INFOFRAME_PROPERTY_MODE_ALLOW_OVERRIDE: NV_INFOFRAME_PROPERTY_MODE = + NV_INFOFRAME_PROPERTY_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_PROPERTY_MODE(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_PROPERTY_BLACKLIST { + pub const NV_INFOFRAME_PROPERTY_BLACKLIST_FALSE: NV_INFOFRAME_PROPERTY_BLACKLIST = + NV_INFOFRAME_PROPERTY_BLACKLIST(0); +} +impl NV_INFOFRAME_PROPERTY_BLACKLIST { + pub const NV_INFOFRAME_PROPERTY_BLACKLIST_TRUE: NV_INFOFRAME_PROPERTY_BLACKLIST = + NV_INFOFRAME_PROPERTY_BLACKLIST(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_PROPERTY_BLACKLIST(pub ::std::os::raw::c_int); +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct NV_INFOFRAME_PROPERTY { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl NV_INFOFRAME_PROPERTY { + #[inline] + pub fn mode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + pub fn set_mode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub fn blackList(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 2u8) as u32) } + } + #[inline] + pub fn set_blackList(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 2u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 10u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 10u8, val as u64) + } + } + #[inline] + pub fn version(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u32) } + } + #[inline] + pub fn set_version(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[inline] + pub fn length(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u32) } + } + #[inline] + pub fn set_length(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + mode: NvU32, + blackList: NvU32, + reserved: NvU32, + version: NvU32, + length: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let mode: u32 = unsafe { ::std::mem::transmute(mode) }; + mode as u64 + }); + __bindgen_bitfield_unit.set(4usize, 2u8, { + let blackList: u32 = unsafe { ::std::mem::transmute(blackList) }; + blackList as u64 + }); + __bindgen_bitfield_unit.set(6usize, 10u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let version: u32 = unsafe { ::std::mem::transmute(version) }; + version as u64 + }); + __bindgen_bitfield_unit.set(24usize, 8u8, { + let length: u32 = unsafe { ::std::mem::transmute(length) }; + length as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_NODATA: NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_OVERSCAN: + NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO = NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_UNDERSCAN: + NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO = NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_FUTURE: NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_AUTO: NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_NOT_PRESENT: + NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA = NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_VERTICAL_PRESENT: + NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA = NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_HORIZONTAL_PRESENT: + NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA = NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_BOTH_PRESENT: + NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA = NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_AUTO: NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA = + NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_AFI_ABSENT: + NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_AFI_PRESENT: + NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_AFI_AUTO: NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO = + NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_RGB: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT = NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_YCbCr422: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT = NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_YCbCr444: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT = NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_FUTURE: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT = NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT = NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_F17 { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_F17_FALSE: NV_INFOFRAME_FIELD_VALUE_AVI_F17 = + NV_INFOFRAME_FIELD_VALUE_AVI_F17(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_F17 { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_F17_TRUE: NV_INFOFRAME_FIELD_VALUE_AVI_F17 = + NV_INFOFRAME_FIELD_VALUE_AVI_F17(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_F17 { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_F17_AUTO: NV_INFOFRAME_FIELD_VALUE_AVI_F17 = + NV_INFOFRAME_FIELD_VALUE_AVI_F17(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_F17(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_NO_AFD: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE01: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE02: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE03: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_LETTERBOX_GT16x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE05: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE06: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE07: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_EQUAL_CODEDFRAME: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_4x3: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_16x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_14x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE12: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_4x3_ON_14x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_16x9_ON_14x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_16x9_ON_4x3: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_NO_DATA: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_4x3: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_16x9: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_FUTURE: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME = + NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_NO_DATA: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY = NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_SMPTE_170M: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY = NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_ITUR_BT709: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY = NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_USE_EXTENDED_COLORIMETRY: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY = NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY = NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_NO_DATA: + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING = + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_HORIZONTAL: + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING = + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_VERTICAL: + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING = + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_BOTH: + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING = + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING = + NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_DEFAULT: + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_LIMITED_RANGE: + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_FULL_RANGE: + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_RESERVED: + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_XVYCC601: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_XVYCC709: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_SYCC601: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_ADOBEYCC601: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_ADOBERGB: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED05: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED06: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED07: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY = + NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(15); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_ITC { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ITC_VIDEO_CONTENT: NV_INFOFRAME_FIELD_VALUE_AVI_ITC = + NV_INFOFRAME_FIELD_VALUE_AVI_ITC(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ITC { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ITC_ITCONTENT: NV_INFOFRAME_FIELD_VALUE_AVI_ITC = + NV_INFOFRAME_FIELD_VALUE_AVI_ITC(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_ITC { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_ITC_AUTO: NV_INFOFRAME_FIELD_VALUE_AVI_ITC = + NV_INFOFRAME_FIELD_VALUE_AVI_ITC(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_ITC(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_NONE: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X02: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X03: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X04: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X05: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X06: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X07: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X08: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X09: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X10: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED10: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED11: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED12: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED13: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED14: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED15: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION = + NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_GRAPHICS: + NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE = NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_PHOTO: + NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE = NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_CINEMA: + NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE = NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_GAME: + NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE = NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE = NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_LIMITED_RANGE: + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_FULL_RANGE: + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_RESERVED02: + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_RESERVED03: + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION { + pub const NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_AUTO: + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION = + NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION(pub ::std::os::raw::c_int); +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct NV_INFOFRAME_VIDEO { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 23usize]>, +} +impl NV_INFOFRAME_VIDEO { + #[inline] + pub fn vic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u32) } + } + #[inline] + pub fn set_vic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn pixelRepeat(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 5u8) as u32) } + } + #[inline] + pub fn set_pixelRepeat(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 5u8, val as u64) + } + } + #[inline] + pub fn colorSpace(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 3u8) as u32) } + } + #[inline] + pub fn set_colorSpace(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 3u8, val as u64) + } + } + #[inline] + pub fn colorimetry(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 3u8) as u32) } + } + #[inline] + pub fn set_colorimetry(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 3u8, val as u64) + } + } + #[inline] + pub fn extendedColorimetry(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 4u8) as u32) } + } + #[inline] + pub fn set_extendedColorimetry(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 4u8, val as u64) + } + } + #[inline] + pub fn rgbQuantizationRange(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 3u8) as u32) } + } + #[inline] + pub fn set_rgbQuantizationRange(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 3u8, val as u64) + } + } + #[inline] + pub fn yccQuantizationRange(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 3u8) as u32) } + } + #[inline] + pub fn set_yccQuantizationRange(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 3u8, val as u64) + } + } + #[inline] + pub fn itContent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 2u8) as u32) } + } + #[inline] + pub fn set_itContent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(29usize, 2u8, val as u64) + } + } + #[inline] + pub fn contentTypes(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 3u8) as u32) } + } + #[inline] + pub fn set_contentTypes(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 3u8, val as u64) + } + } + #[inline] + pub fn scanInfo(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(35usize, 3u8) as u32) } + } + #[inline] + pub fn set_scanInfo(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(35usize, 3u8, val as u64) + } + } + #[inline] + pub fn activeFormatInfoPresent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(38usize, 2u8) as u32) } + } + #[inline] + pub fn set_activeFormatInfoPresent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(38usize, 2u8, val as u64) + } + } + #[inline] + pub fn activeFormatAspectRatio(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 5u8) as u32) } + } + #[inline] + pub fn set_activeFormatAspectRatio(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(40usize, 5u8, val as u64) + } + } + #[inline] + pub fn picAspectRatio(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(45usize, 3u8) as u32) } + } + #[inline] + pub fn set_picAspectRatio(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(45usize, 3u8, val as u64) + } + } + #[inline] + pub fn nonuniformScaling(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(48usize, 3u8) as u32) } + } + #[inline] + pub fn set_nonuniformScaling(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(48usize, 3u8, val as u64) + } + } + #[inline] + pub fn barInfo(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(51usize, 3u8) as u32) } + } + #[inline] + pub fn set_barInfo(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(51usize, 3u8, val as u64) + } + } + #[inline] + pub fn top_bar(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 17u8) as u32) } + } + #[inline] + pub fn set_top_bar(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(64usize, 17u8, val as u64) + } + } + #[inline] + pub fn bottom_bar(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(96usize, 17u8) as u32) } + } + #[inline] + pub fn set_bottom_bar(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(96usize, 17u8, val as u64) + } + } + #[inline] + pub fn left_bar(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(128usize, 17u8) as u32) } + } + #[inline] + pub fn set_left_bar(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(128usize, 17u8, val as u64) + } + } + #[inline] + pub fn right_bar(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(160usize, 17u8) as u32) } + } + #[inline] + pub fn set_right_bar(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(160usize, 17u8, val as u64) + } + } + #[inline] + pub fn Future17(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(177usize, 2u8) as u32) } + } + #[inline] + pub fn set_Future17(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(177usize, 2u8, val as u64) + } + } + #[inline] + pub fn Future47(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(179usize, 2u8) as u32) } + } + #[inline] + pub fn set_Future47(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(179usize, 2u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + vic: NvU32, + pixelRepeat: NvU32, + colorSpace: NvU32, + colorimetry: NvU32, + extendedColorimetry: NvU32, + rgbQuantizationRange: NvU32, + yccQuantizationRange: NvU32, + itContent: NvU32, + contentTypes: NvU32, + scanInfo: NvU32, + activeFormatInfoPresent: NvU32, + activeFormatAspectRatio: NvU32, + picAspectRatio: NvU32, + nonuniformScaling: NvU32, + barInfo: NvU32, + top_bar: NvU32, + bottom_bar: NvU32, + left_bar: NvU32, + right_bar: NvU32, + Future17: NvU32, + Future47: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 23usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 23usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let vic: u32 = unsafe { ::std::mem::transmute(vic) }; + vic as u64 + }); + __bindgen_bitfield_unit.set(8usize, 5u8, { + let pixelRepeat: u32 = unsafe { ::std::mem::transmute(pixelRepeat) }; + pixelRepeat as u64 + }); + __bindgen_bitfield_unit.set(13usize, 3u8, { + let colorSpace: u32 = unsafe { ::std::mem::transmute(colorSpace) }; + colorSpace as u64 + }); + __bindgen_bitfield_unit.set(16usize, 3u8, { + let colorimetry: u32 = unsafe { ::std::mem::transmute(colorimetry) }; + colorimetry as u64 + }); + __bindgen_bitfield_unit.set(19usize, 4u8, { + let extendedColorimetry: u32 = unsafe { ::std::mem::transmute(extendedColorimetry) }; + extendedColorimetry as u64 + }); + __bindgen_bitfield_unit.set(23usize, 3u8, { + let rgbQuantizationRange: u32 = unsafe { ::std::mem::transmute(rgbQuantizationRange) }; + rgbQuantizationRange as u64 + }); + __bindgen_bitfield_unit.set(26usize, 3u8, { + let yccQuantizationRange: u32 = unsafe { ::std::mem::transmute(yccQuantizationRange) }; + yccQuantizationRange as u64 + }); + __bindgen_bitfield_unit.set(29usize, 2u8, { + let itContent: u32 = unsafe { ::std::mem::transmute(itContent) }; + itContent as u64 + }); + __bindgen_bitfield_unit.set(32usize, 3u8, { + let contentTypes: u32 = unsafe { ::std::mem::transmute(contentTypes) }; + contentTypes as u64 + }); + __bindgen_bitfield_unit.set(35usize, 3u8, { + let scanInfo: u32 = unsafe { ::std::mem::transmute(scanInfo) }; + scanInfo as u64 + }); + __bindgen_bitfield_unit.set(38usize, 2u8, { + let activeFormatInfoPresent: u32 = + unsafe { ::std::mem::transmute(activeFormatInfoPresent) }; + activeFormatInfoPresent as u64 + }); + __bindgen_bitfield_unit.set(40usize, 5u8, { + let activeFormatAspectRatio: u32 = + unsafe { ::std::mem::transmute(activeFormatAspectRatio) }; + activeFormatAspectRatio as u64 + }); + __bindgen_bitfield_unit.set(45usize, 3u8, { + let picAspectRatio: u32 = unsafe { ::std::mem::transmute(picAspectRatio) }; + picAspectRatio as u64 + }); + __bindgen_bitfield_unit.set(48usize, 3u8, { + let nonuniformScaling: u32 = unsafe { ::std::mem::transmute(nonuniformScaling) }; + nonuniformScaling as u64 + }); + __bindgen_bitfield_unit.set(51usize, 3u8, { + let barInfo: u32 = unsafe { ::std::mem::transmute(barInfo) }; + barInfo as u64 + }); + __bindgen_bitfield_unit.set(64usize, 17u8, { + let top_bar: u32 = unsafe { ::std::mem::transmute(top_bar) }; + top_bar as u64 + }); + __bindgen_bitfield_unit.set(96usize, 17u8, { + let bottom_bar: u32 = unsafe { ::std::mem::transmute(bottom_bar) }; + bottom_bar as u64 + }); + __bindgen_bitfield_unit.set(128usize, 17u8, { + let left_bar: u32 = unsafe { ::std::mem::transmute(left_bar) }; + left_bar as u64 + }); + __bindgen_bitfield_unit.set(160usize, 17u8, { + let right_bar: u32 = unsafe { ::std::mem::transmute(right_bar) }; + right_bar as u64 + }); + __bindgen_bitfield_unit.set(177usize, 2u8, { + let Future17: u32 = unsafe { ::std::mem::transmute(Future17) }; + Future17 as u64 + }); + __bindgen_bitfield_unit.set(179usize, 2u8, { + let Future47: u32 = unsafe { ::std::mem::transmute(Future47) }; + Future47 as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_IN_HEADER: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_2: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_3: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_4: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_5: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_6: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_7: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_8: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(15); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_IN_HEADER: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_PCM: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AC3: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MPEG1: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MP3: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MPEG2: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AACLC: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DTS: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_ATRAC: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DSD: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_EAC3: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DTSHD: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MLP: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DST: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_WMAPRO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_USE_CODING_EXTENSION_TYPE: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE = NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_IN_HEADER: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE = NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_16BITS: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE = NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_20BITS: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE = NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_24BITS: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE = NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE = NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_IN_HEADER: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_32000HZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_44100HZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_48000HZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_88200KHZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_96000KHZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_176400KHZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_192000KHZ: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY = + NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(15); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_USE_CODING_TYPE: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_HEAAC: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_HEAACV2: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_MPEGSURROUND: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE04: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE05: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE06: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE07: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE08: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE09: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE10: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE11: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE12: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE13: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE14: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE15: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE16: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(16); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE17: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(17); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE18: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(18); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE19: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(19); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE20: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(20); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE21: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(21); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE22: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(22); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE23: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(23); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE24: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(24); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE25: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(25); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE26: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(26); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE27: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(27); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE28: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(28); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE29: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(29); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE30: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(30); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE31: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(31); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(63); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(16); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(17); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(18); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(19); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(20); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(21); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(22); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(23); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(24); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(25); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(26); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(27); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(28); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(29); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(30); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(31); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_FCH_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(32); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_FCH_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(33); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_X_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(34); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_X_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(35); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(36); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(37); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_X_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(38); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_X_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(39); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_RC_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(40); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_RC_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(41); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FCH_RC_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(42); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FCH_RC_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(43); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_FCH_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(44); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_FCH_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(45); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(46); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(47); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_FC_X_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(48); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_FC_LFE_FR_FL: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(49); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION = + NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(511); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_NO_DATA: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_0DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_PLUS10DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_RESERVED03: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_0DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_1DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_2DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(2); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_3DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(3); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_4DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(4); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_5DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(5); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_6DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(6); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_7DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(7); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_8DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(8); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_9DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(9); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_10DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(10); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_11DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(11); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_12DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(12); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_13DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(13); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_14DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(14); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_15DB: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(15); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_AUTO: + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES = + NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(31); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES(pub ::std::os::raw::c_int); +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_PERMITTED: + NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX = NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX(0); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_PROHIBITED: + NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX = NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX(1); +} +impl NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX { + pub const NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_AUTO: NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX = + NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX(pub ::std::os::raw::c_int); +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct NV_INFOFRAME_AUDIO { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 14usize]>, + pub __bindgen_padding_0: u16, +} +impl NV_INFOFRAME_AUDIO { + #[inline] + pub fn codingType(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 5u8) as u32) } + } + #[inline] + pub fn set_codingType(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 5u8, val as u64) + } + } + #[inline] + pub fn codingExtensionType(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 6u8) as u32) } + } + #[inline] + pub fn set_codingExtensionType(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 6u8, val as u64) + } + } + #[inline] + pub fn sampleSize(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 3u8) as u32) } + } + #[inline] + pub fn set_sampleSize(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 3u8, val as u64) + } + } + #[inline] + pub fn sampleRate(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 4u8) as u32) } + } + #[inline] + pub fn set_sampleRate(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 4u8, val as u64) + } + } + #[inline] + pub fn channelCount(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 4u8) as u32) } + } + #[inline] + pub fn set_channelCount(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 4u8, val as u64) + } + } + #[inline] + pub fn speakerPlacement(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 9u8) as u32) } + } + #[inline] + pub fn set_speakerPlacement(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 9u8, val as u64) + } + } + #[inline] + pub fn downmixInhibit(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 2u8) as u32) } + } + #[inline] + pub fn set_downmixInhibit(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 2u8, val as u64) + } + } + #[inline] + pub fn lfePlaybackLevel(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(34usize, 3u8) as u32) } + } + #[inline] + pub fn set_lfePlaybackLevel(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(34usize, 3u8, val as u64) + } + } + #[inline] + pub fn levelShift(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(37usize, 5u8) as u32) } + } + #[inline] + pub fn set_levelShift(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(37usize, 5u8, val as u64) + } + } + #[inline] + pub fn Future12(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(42usize, 2u8) as u32) } + } + #[inline] + pub fn set_Future12(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(42usize, 2u8, val as u64) + } + } + #[inline] + pub fn Future2x(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(44usize, 4u8) as u32) } + } + #[inline] + pub fn set_Future2x(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(44usize, 4u8, val as u64) + } + } + #[inline] + pub fn Future3x(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(48usize, 4u8) as u32) } + } + #[inline] + pub fn set_Future3x(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(48usize, 4u8, val as u64) + } + } + #[inline] + pub fn Future52(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(52usize, 2u8) as u32) } + } + #[inline] + pub fn set_Future52(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(52usize, 2u8, val as u64) + } + } + #[inline] + pub fn Future6(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(54usize, 9u8) as u32) } + } + #[inline] + pub fn set_Future6(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(54usize, 9u8, val as u64) + } + } + #[inline] + pub fn Future7(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 9u8) as u32) } + } + #[inline] + pub fn set_Future7(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(64usize, 9u8, val as u64) + } + } + #[inline] + pub fn Future8(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(73usize, 9u8) as u32) } + } + #[inline] + pub fn set_Future8(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(73usize, 9u8, val as u64) + } + } + #[inline] + pub fn Future9(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(82usize, 9u8) as u32) } + } + #[inline] + pub fn set_Future9(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(82usize, 9u8, val as u64) + } + } + #[inline] + pub fn Future10(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(96usize, 9u8) as u32) } + } + #[inline] + pub fn set_Future10(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(96usize, 9u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + codingType: NvU32, + codingExtensionType: NvU32, + sampleSize: NvU32, + sampleRate: NvU32, + channelCount: NvU32, + speakerPlacement: NvU32, + downmixInhibit: NvU32, + lfePlaybackLevel: NvU32, + levelShift: NvU32, + Future12: NvU32, + Future2x: NvU32, + Future3x: NvU32, + Future52: NvU32, + Future6: NvU32, + Future7: NvU32, + Future8: NvU32, + Future9: NvU32, + Future10: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 14usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 14usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 5u8, { + let codingType: u32 = unsafe { ::std::mem::transmute(codingType) }; + codingType as u64 + }); + __bindgen_bitfield_unit.set(5usize, 6u8, { + let codingExtensionType: u32 = unsafe { ::std::mem::transmute(codingExtensionType) }; + codingExtensionType as u64 + }); + __bindgen_bitfield_unit.set(11usize, 3u8, { + let sampleSize: u32 = unsafe { ::std::mem::transmute(sampleSize) }; + sampleSize as u64 + }); + __bindgen_bitfield_unit.set(14usize, 4u8, { + let sampleRate: u32 = unsafe { ::std::mem::transmute(sampleRate) }; + sampleRate as u64 + }); + __bindgen_bitfield_unit.set(18usize, 4u8, { + let channelCount: u32 = unsafe { ::std::mem::transmute(channelCount) }; + channelCount as u64 + }); + __bindgen_bitfield_unit.set(22usize, 9u8, { + let speakerPlacement: u32 = unsafe { ::std::mem::transmute(speakerPlacement) }; + speakerPlacement as u64 + }); + __bindgen_bitfield_unit.set(32usize, 2u8, { + let downmixInhibit: u32 = unsafe { ::std::mem::transmute(downmixInhibit) }; + downmixInhibit as u64 + }); + __bindgen_bitfield_unit.set(34usize, 3u8, { + let lfePlaybackLevel: u32 = unsafe { ::std::mem::transmute(lfePlaybackLevel) }; + lfePlaybackLevel as u64 + }); + __bindgen_bitfield_unit.set(37usize, 5u8, { + let levelShift: u32 = unsafe { ::std::mem::transmute(levelShift) }; + levelShift as u64 + }); + __bindgen_bitfield_unit.set(42usize, 2u8, { + let Future12: u32 = unsafe { ::std::mem::transmute(Future12) }; + Future12 as u64 + }); + __bindgen_bitfield_unit.set(44usize, 4u8, { + let Future2x: u32 = unsafe { ::std::mem::transmute(Future2x) }; + Future2x as u64 + }); + __bindgen_bitfield_unit.set(48usize, 4u8, { + let Future3x: u32 = unsafe { ::std::mem::transmute(Future3x) }; + Future3x as u64 + }); + __bindgen_bitfield_unit.set(52usize, 2u8, { + let Future52: u32 = unsafe { ::std::mem::transmute(Future52) }; + Future52 as u64 + }); + __bindgen_bitfield_unit.set(54usize, 9u8, { + let Future6: u32 = unsafe { ::std::mem::transmute(Future6) }; + Future6 as u64 + }); + __bindgen_bitfield_unit.set(64usize, 9u8, { + let Future7: u32 = unsafe { ::std::mem::transmute(Future7) }; + Future7 as u64 + }); + __bindgen_bitfield_unit.set(73usize, 9u8, { + let Future8: u32 = unsafe { ::std::mem::transmute(Future8) }; + Future8 as u64 + }); + __bindgen_bitfield_unit.set(82usize, 9u8, { + let Future9: u32 = unsafe { ::std::mem::transmute(Future9) }; + Future9 as u64 + }); + __bindgen_bitfield_unit.set(96usize, 9u8, { + let Future10: u32 = unsafe { ::std::mem::transmute(Future10) }; + Future10 as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_INFOFRAME_DATA { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub type_: NvU8, + pub infoframe: NV_INFOFRAME_DATA__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union NV_INFOFRAME_DATA__bindgen_ty_1 { + pub property: NV_INFOFRAME_PROPERTY, + pub audio: NV_INFOFRAME_AUDIO, + pub video: NV_INFOFRAME_VIDEO, +} +impl NV_COLOR_CMD { + pub const NV_COLOR_CMD_GET: NV_COLOR_CMD = NV_COLOR_CMD(1); +} +impl NV_COLOR_CMD { + pub const NV_COLOR_CMD_SET: NV_COLOR_CMD = NV_COLOR_CMD(2); +} +impl NV_COLOR_CMD { + pub const NV_COLOR_CMD_IS_SUPPORTED_COLOR: NV_COLOR_CMD = NV_COLOR_CMD(3); +} +impl NV_COLOR_CMD { + pub const NV_COLOR_CMD_GET_DEFAULT: NV_COLOR_CMD = NV_COLOR_CMD(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_COLOR_CMD(pub ::std::os::raw::c_int); +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_RGB: NV_COLOR_FORMAT = NV_COLOR_FORMAT(0); +} +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_YUV422: NV_COLOR_FORMAT = NV_COLOR_FORMAT(1); +} +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_YUV444: NV_COLOR_FORMAT = NV_COLOR_FORMAT(2); +} +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_YUV420: NV_COLOR_FORMAT = NV_COLOR_FORMAT(3); +} +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_DEFAULT: NV_COLOR_FORMAT = NV_COLOR_FORMAT(254); +} +impl NV_COLOR_FORMAT { + pub const NV_COLOR_FORMAT_AUTO: NV_COLOR_FORMAT = NV_COLOR_FORMAT(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_COLOR_FORMAT(pub ::std::os::raw::c_int); +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_RGB: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(0); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_YCC601: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(1); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_YCC709: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(2); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_XVYCC601: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(3); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_XVYCC709: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(4); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_SYCC601: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(5); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_ADOBEYCC601: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(6); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_ADOBERGB: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(7); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_BT2020RGB: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(8); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_BT2020YCC: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(9); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_BT2020cYCC: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(10); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_DEFAULT: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(254); +} +impl NV_COLOR_COLORIMETRY { + pub const NV_COLOR_COLORIMETRY_AUTO: NV_COLOR_COLORIMETRY = NV_COLOR_COLORIMETRY(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_COLOR_COLORIMETRY(pub ::std::os::raw::c_int); +impl _NV_DYNAMIC_RANGE { + pub const NV_DYNAMIC_RANGE_VESA: _NV_DYNAMIC_RANGE = _NV_DYNAMIC_RANGE(0); +} +impl _NV_DYNAMIC_RANGE { + pub const NV_DYNAMIC_RANGE_CEA: _NV_DYNAMIC_RANGE = _NV_DYNAMIC_RANGE(1); +} +impl _NV_DYNAMIC_RANGE { + pub const NV_DYNAMIC_RANGE_AUTO: _NV_DYNAMIC_RANGE = _NV_DYNAMIC_RANGE(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DYNAMIC_RANGE(pub ::std::os::raw::c_int); +pub use self::_NV_DYNAMIC_RANGE as NV_DYNAMIC_RANGE; +impl _NV_BPC { + pub const NV_BPC_DEFAULT: _NV_BPC = _NV_BPC(0); +} +impl _NV_BPC { + pub const NV_BPC_6: _NV_BPC = _NV_BPC(1); +} +impl _NV_BPC { + pub const NV_BPC_8: _NV_BPC = _NV_BPC(2); +} +impl _NV_BPC { + pub const NV_BPC_10: _NV_BPC = _NV_BPC(3); +} +impl _NV_BPC { + pub const NV_BPC_12: _NV_BPC = _NV_BPC(4); +} +impl _NV_BPC { + pub const NV_BPC_16: _NV_BPC = _NV_BPC(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_BPC(pub ::std::os::raw::c_int); +pub use self::_NV_BPC as NV_BPC; +impl _NV_COLOR_SELECTION_POLICY { + pub const NV_COLOR_SELECTION_POLICY_USER: _NV_COLOR_SELECTION_POLICY = + _NV_COLOR_SELECTION_POLICY(0); +} +impl _NV_COLOR_SELECTION_POLICY { + pub const NV_COLOR_SELECTION_POLICY_BEST_QUALITY: _NV_COLOR_SELECTION_POLICY = + _NV_COLOR_SELECTION_POLICY(1); +} +impl _NV_COLOR_SELECTION_POLICY { + pub const NV_COLOR_SELECTION_POLICY_DEFAULT: _NV_COLOR_SELECTION_POLICY = + _NV_COLOR_SELECTION_POLICY(1); +} +impl _NV_COLOR_SELECTION_POLICY { + pub const NV_COLOR_SELECTION_POLICY_UNKNOWN: _NV_COLOR_SELECTION_POLICY = + _NV_COLOR_SELECTION_POLICY(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_COLOR_SELECTION_POLICY(pub ::std::os::raw::c_int); +pub use self::_NV_COLOR_SELECTION_POLICY as NV_COLOR_SELECTION_POLICY; +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_DEFAULT: _NV_DESKTOP_COLOR_DEPTH = _NV_DESKTOP_COLOR_DEPTH(0); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_8BPC: _NV_DESKTOP_COLOR_DEPTH = _NV_DESKTOP_COLOR_DEPTH(1); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_10BPC: _NV_DESKTOP_COLOR_DEPTH = _NV_DESKTOP_COLOR_DEPTH(2); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_16BPC_FLOAT: _NV_DESKTOP_COLOR_DEPTH = + _NV_DESKTOP_COLOR_DEPTH(3); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_16BPC_FLOAT_WCG: _NV_DESKTOP_COLOR_DEPTH = + _NV_DESKTOP_COLOR_DEPTH(4); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_16BPC_FLOAT_HDR: _NV_DESKTOP_COLOR_DEPTH = + _NV_DESKTOP_COLOR_DEPTH(5); +} +impl _NV_DESKTOP_COLOR_DEPTH { + pub const NV_DESKTOP_COLOR_DEPTH_MAX_VALUE: _NV_DESKTOP_COLOR_DEPTH = + _NV_DESKTOP_COLOR_DEPTH(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DESKTOP_COLOR_DEPTH(pub ::std::os::raw::c_int); +pub use self::_NV_DESKTOP_COLOR_DEPTH as NV_DESKTOP_COLOR_DEPTH; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V1 { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub data: _NV_COLOR_DATA_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V1__bindgen_ty_1 { + pub colorFormat: NvU8, + pub colorimetry: NvU8, +} +pub type NV_COLOR_DATA_V1 = _NV_COLOR_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V2 { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub data: _NV_COLOR_DATA_V2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V2__bindgen_ty_1 { + pub colorFormat: NvU8, + pub colorimetry: NvU8, + pub dynamicRange: NvU8, +} +pub type NV_COLOR_DATA_V2 = _NV_COLOR_DATA_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V3 { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub data: _NV_COLOR_DATA_V3__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V3__bindgen_ty_1 { + pub colorFormat: NvU8, + pub colorimetry: NvU8, + pub dynamicRange: NvU8, + pub bpc: NV_BPC, +} +pub type NV_COLOR_DATA_V3 = _NV_COLOR_DATA_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V4 { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub data: _NV_COLOR_DATA_V4__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V4__bindgen_ty_1 { + pub colorFormat: NvU8, + pub colorimetry: NvU8, + pub dynamicRange: NvU8, + pub bpc: NV_BPC, + pub colorSelectionPolicy: NV_COLOR_SELECTION_POLICY, +} +pub type NV_COLOR_DATA_V4 = _NV_COLOR_DATA_V4; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V5 { + pub version: NvU32, + pub size: NvU16, + pub cmd: NvU8, + pub data: _NV_COLOR_DATA_V5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_COLOR_DATA_V5__bindgen_ty_1 { + pub colorFormat: NvU8, + pub colorimetry: NvU8, + pub dynamicRange: NvU8, + pub bpc: NV_BPC, + pub colorSelectionPolicy: NV_COLOR_SELECTION_POLICY, + pub depth: NV_DESKTOP_COLOR_DEPTH, +} +pub type NV_COLOR_DATA_V5 = _NV_COLOR_DATA_V5; +pub type NV_COLOR_DATA = NV_COLOR_DATA_V5; +impl NV_STATIC_METADATA_DESCRIPTOR_ID { + pub const NV_STATIC_METADATA_TYPE_1: NV_STATIC_METADATA_DESCRIPTOR_ID = + NV_STATIC_METADATA_DESCRIPTOR_ID(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_STATIC_METADATA_DESCRIPTOR_ID(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub static_metadata_descriptor_id: NV_STATIC_METADATA_DESCRIPTOR_ID, + pub display_data: _NV_HDR_CAPABILITIES_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V1__bindgen_ty_1 { + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub desired_content_max_luminance: NvU16, + pub desired_content_min_luminance: NvU16, + pub desired_content_max_frame_average_luminance: NvU16, +} +impl _NV_HDR_CAPABILITIES_V1 { + #[inline] + pub fn isST2084EotfSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isST2084EotfSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalHdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalHdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isEdrSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEdrSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn driverExpandDefaultHdrParameters(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_driverExpandDefaultHdrParameters(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalSdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalSdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 27u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 27u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isST2084EotfSupported: NvU32, + isTraditionalHdrGammaSupported: NvU32, + isEdrSupported: NvU32, + driverExpandDefaultHdrParameters: NvU32, + isTraditionalSdrGammaSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isST2084EotfSupported: u32 = + unsafe { ::std::mem::transmute(isST2084EotfSupported) }; + isST2084EotfSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isTraditionalHdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalHdrGammaSupported) }; + isTraditionalHdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isEdrSupported: u32 = unsafe { ::std::mem::transmute(isEdrSupported) }; + isEdrSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let driverExpandDefaultHdrParameters: u32 = + unsafe { ::std::mem::transmute(driverExpandDefaultHdrParameters) }; + driverExpandDefaultHdrParameters as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isTraditionalSdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalSdrGammaSupported) }; + isTraditionalSdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(5usize, 27u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_HDR_CAPABILITIES_V1 = _NV_HDR_CAPABILITIES_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub static_metadata_descriptor_id: NV_STATIC_METADATA_DESCRIPTOR_ID, + pub display_data: _NV_HDR_CAPABILITIES_V2__bindgen_ty_1, + pub dv_static_metadata: _NV_HDR_CAPABILITIES_V2__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V2__bindgen_ty_1 { + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub desired_content_max_luminance: NvU16, + pub desired_content_min_luminance: NvU16, + pub desired_content_max_frame_average_luminance: NvU16, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V2__bindgen_ty_2 { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub target_min_luminance: NvU16, + pub target_max_luminance: NvU16, + pub cc_red_x: NvU16, + pub cc_red_y: NvU16, + pub cc_green_x: NvU16, + pub cc_green_y: NvU16, + pub cc_blue_x: NvU16, + pub cc_blue_y: NvU16, + pub cc_white_x: NvU16, + pub cc_white_y: NvU16, +} +impl _NV_HDR_CAPABILITIES_V2__bindgen_ty_2 { + #[inline] + pub fn VSVDB_version(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u32) } + } + #[inline] + pub fn set_VSVDB_version(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[inline] + pub fn dm_version(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 8u8) as u32) } + } + #[inline] + pub fn set_dm_version(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 8u8, val as u64) + } + } + #[inline] + pub fn supports_2160p60hz(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_2160p60hz(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_YUV422_12bit(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_YUV422_12bit(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_global_dimming(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_global_dimming(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[inline] + pub fn colorimetry(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } + } + #[inline] + pub fn set_colorimetry(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_backlight_control(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 2u8) as u32) } + } + #[inline] + pub fn set_supports_backlight_control(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 2u8, val as u64) + } + } + #[inline] + pub fn backlt_min_luma(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 2u8) as u32) } + } + #[inline] + pub fn set_backlt_min_luma(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 2u8, val as u64) + } + } + #[inline] + pub fn interface_supported_by_sink(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 2u8) as u32) } + } + #[inline] + pub fn set_interface_supported_by_sink(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 2u8, val as u64) + } + } + #[inline] + pub fn supports_10b_12b_444(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 2u8) as u32) } + } + #[inline] + pub fn set_supports_10b_12b_444(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 2u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 9u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 9u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + VSVDB_version: NvU32, + dm_version: NvU32, + supports_2160p60hz: NvU32, + supports_YUV422_12bit: NvU32, + supports_global_dimming: NvU32, + colorimetry: NvU32, + supports_backlight_control: NvU32, + backlt_min_luma: NvU32, + interface_supported_by_sink: NvU32, + supports_10b_12b_444: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let VSVDB_version: u32 = unsafe { ::std::mem::transmute(VSVDB_version) }; + VSVDB_version as u64 + }); + __bindgen_bitfield_unit.set(3usize, 8u8, { + let dm_version: u32 = unsafe { ::std::mem::transmute(dm_version) }; + dm_version as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let supports_2160p60hz: u32 = unsafe { ::std::mem::transmute(supports_2160p60hz) }; + supports_2160p60hz as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let supports_YUV422_12bit: u32 = + unsafe { ::std::mem::transmute(supports_YUV422_12bit) }; + supports_YUV422_12bit as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let supports_global_dimming: u32 = + unsafe { ::std::mem::transmute(supports_global_dimming) }; + supports_global_dimming as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let colorimetry: u32 = unsafe { ::std::mem::transmute(colorimetry) }; + colorimetry as u64 + }); + __bindgen_bitfield_unit.set(15usize, 2u8, { + let supports_backlight_control: u32 = + unsafe { ::std::mem::transmute(supports_backlight_control) }; + supports_backlight_control as u64 + }); + __bindgen_bitfield_unit.set(17usize, 2u8, { + let backlt_min_luma: u32 = unsafe { ::std::mem::transmute(backlt_min_luma) }; + backlt_min_luma as u64 + }); + __bindgen_bitfield_unit.set(19usize, 2u8, { + let interface_supported_by_sink: u32 = + unsafe { ::std::mem::transmute(interface_supported_by_sink) }; + interface_supported_by_sink as u64 + }); + __bindgen_bitfield_unit.set(21usize, 2u8, { + let supports_10b_12b_444: u32 = unsafe { ::std::mem::transmute(supports_10b_12b_444) }; + supports_10b_12b_444 as u64 + }); + __bindgen_bitfield_unit.set(23usize, 9u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +impl _NV_HDR_CAPABILITIES_V2 { + #[inline] + pub fn isST2084EotfSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isST2084EotfSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalHdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalHdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isEdrSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEdrSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn driverExpandDefaultHdrParameters(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_driverExpandDefaultHdrParameters(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalSdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalSdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn isDolbyVisionSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_isDolbyVisionSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 26u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 26u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isST2084EotfSupported: NvU32, + isTraditionalHdrGammaSupported: NvU32, + isEdrSupported: NvU32, + driverExpandDefaultHdrParameters: NvU32, + isTraditionalSdrGammaSupported: NvU32, + isDolbyVisionSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isST2084EotfSupported: u32 = + unsafe { ::std::mem::transmute(isST2084EotfSupported) }; + isST2084EotfSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isTraditionalHdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalHdrGammaSupported) }; + isTraditionalHdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isEdrSupported: u32 = unsafe { ::std::mem::transmute(isEdrSupported) }; + isEdrSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let driverExpandDefaultHdrParameters: u32 = + unsafe { ::std::mem::transmute(driverExpandDefaultHdrParameters) }; + driverExpandDefaultHdrParameters as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isTraditionalSdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalSdrGammaSupported) }; + isTraditionalSdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let isDolbyVisionSupported: u32 = + unsafe { ::std::mem::transmute(isDolbyVisionSupported) }; + isDolbyVisionSupported as u64 + }); + __bindgen_bitfield_unit.set(6usize, 26u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_HDR_CAPABILITIES_V2 = _NV_HDR_CAPABILITIES_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V3 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub static_metadata_descriptor_id: NV_STATIC_METADATA_DESCRIPTOR_ID, + pub display_data: _NV_HDR_CAPABILITIES_V3__bindgen_ty_1, + pub dv_static_metadata: _NV_HDR_CAPABILITIES_V3__bindgen_ty_2, + pub hdr10plus_vsvdb: _NV_HDR_CAPABILITIES_V3__bindgen_ty_3, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V3__bindgen_ty_1 { + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub desired_content_max_luminance: NvU16, + pub desired_content_min_luminance: NvU16, + pub desired_content_max_frame_average_luminance: NvU16, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V3__bindgen_ty_2 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub target_min_luminance: NvU16, + pub target_max_luminance: NvU16, + pub cc_red_x: NvU16, + pub cc_red_y: NvU16, + pub cc_green_x: NvU16, + pub cc_green_y: NvU16, + pub cc_blue_x: NvU16, + pub cc_blue_y: NvU16, + pub cc_white_x: NvU16, + pub cc_white_y: NvU16, +} +impl _NV_HDR_CAPABILITIES_V3__bindgen_ty_2 { + #[inline] + pub fn VSVDB_version(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u32) } + } + #[inline] + pub fn set_VSVDB_version(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) + } + } + #[inline] + pub fn dm_version(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 8u8) as u32) } + } + #[inline] + pub fn set_dm_version(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 8u8, val as u64) + } + } + #[inline] + pub fn supports_2160p60hz(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_2160p60hz(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_YUV422_12bit(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_YUV422_12bit(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_global_dimming(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } + } + #[inline] + pub fn set_supports_global_dimming(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[inline] + pub fn colorimetry(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } + } + #[inline] + pub fn set_colorimetry(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn supports_backlight_control(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 2u8) as u32) } + } + #[inline] + pub fn set_supports_backlight_control(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 2u8, val as u64) + } + } + #[inline] + pub fn backlt_min_luma(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 2u8) as u32) } + } + #[inline] + pub fn set_backlt_min_luma(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 2u8, val as u64) + } + } + #[inline] + pub fn interface_supported_by_sink(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 2u8) as u32) } + } + #[inline] + pub fn set_interface_supported_by_sink(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 2u8, val as u64) + } + } + #[inline] + pub fn supports_10b_12b_444(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 2u8) as u32) } + } + #[inline] + pub fn set_supports_10b_12b_444(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 2u8, val as u64) + } + } + #[inline] + pub fn parity(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u32) } + } + #[inline] + pub fn set_parity(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + VSVDB_version: NvU32, + dm_version: NvU32, + supports_2160p60hz: NvU32, + supports_YUV422_12bit: NvU32, + supports_global_dimming: NvU32, + colorimetry: NvU32, + supports_backlight_control: NvU32, + backlt_min_luma: NvU32, + interface_supported_by_sink: NvU32, + supports_10b_12b_444: NvU32, + parity: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let VSVDB_version: u32 = unsafe { ::std::mem::transmute(VSVDB_version) }; + VSVDB_version as u64 + }); + __bindgen_bitfield_unit.set(3usize, 8u8, { + let dm_version: u32 = unsafe { ::std::mem::transmute(dm_version) }; + dm_version as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let supports_2160p60hz: u32 = unsafe { ::std::mem::transmute(supports_2160p60hz) }; + supports_2160p60hz as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let supports_YUV422_12bit: u32 = + unsafe { ::std::mem::transmute(supports_YUV422_12bit) }; + supports_YUV422_12bit as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let supports_global_dimming: u32 = + unsafe { ::std::mem::transmute(supports_global_dimming) }; + supports_global_dimming as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let colorimetry: u32 = unsafe { ::std::mem::transmute(colorimetry) }; + colorimetry as u64 + }); + __bindgen_bitfield_unit.set(15usize, 2u8, { + let supports_backlight_control: u32 = + unsafe { ::std::mem::transmute(supports_backlight_control) }; + supports_backlight_control as u64 + }); + __bindgen_bitfield_unit.set(17usize, 2u8, { + let backlt_min_luma: u32 = unsafe { ::std::mem::transmute(backlt_min_luma) }; + backlt_min_luma as u64 + }); + __bindgen_bitfield_unit.set(19usize, 2u8, { + let interface_supported_by_sink: u32 = + unsafe { ::std::mem::transmute(interface_supported_by_sink) }; + interface_supported_by_sink as u64 + }); + __bindgen_bitfield_unit.set(21usize, 2u8, { + let supports_10b_12b_444: u32 = unsafe { ::std::mem::transmute(supports_10b_12b_444) }; + supports_10b_12b_444 as u64 + }); + __bindgen_bitfield_unit.set(23usize, 1u8, { + let parity: u32 = unsafe { ::std::mem::transmute(parity) }; + parity as u64 + }); + __bindgen_bitfield_unit.set(24usize, 8u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[repr(align(2))] +#[derive(Copy, Clone)] +pub struct _NV_HDR_CAPABILITIES_V3__bindgen_ty_3 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, +} +impl _NV_HDR_CAPABILITIES_V3__bindgen_ty_3 { + #[inline] + pub fn application_version(&self) -> NvU16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 2u8) as u16) } + } + #[inline] + pub fn set_application_version(&mut self, val: NvU16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 2u8, val as u64) + } + } + #[inline] + pub fn full_frame_peak_luminance_index(&self) -> NvU16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 2u8) as u16) } + } + #[inline] + pub fn set_full_frame_peak_luminance_index(&mut self, val: NvU16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 2u8, val as u64) + } + } + #[inline] + pub fn peak_luminance_index(&self) -> NvU16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u16) } + } + #[inline] + pub fn set_peak_luminance_index(&mut self, val: NvU16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u16) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + application_version: NvU16, + full_frame_peak_luminance_index: NvU16, + peak_luminance_index: NvU16, + reserved: NvU16, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 2u8, { + let application_version: u16 = unsafe { ::std::mem::transmute(application_version) }; + application_version as u64 + }); + __bindgen_bitfield_unit.set(2usize, 2u8, { + let full_frame_peak_luminance_index: u16 = + unsafe { ::std::mem::transmute(full_frame_peak_luminance_index) }; + full_frame_peak_luminance_index as u64 + }); + __bindgen_bitfield_unit.set(4usize, 4u8, { + let peak_luminance_index: u16 = unsafe { ::std::mem::transmute(peak_luminance_index) }; + peak_luminance_index as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let reserved: u16 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +impl _NV_HDR_CAPABILITIES_V3 { + #[inline] + pub fn isST2084EotfSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isST2084EotfSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalHdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalHdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isEdrSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_isEdrSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn driverExpandDefaultHdrParameters(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_driverExpandDefaultHdrParameters(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTraditionalSdrGammaSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_isTraditionalSdrGammaSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn isDolbyVisionSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_isDolbyVisionSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn isHdr10PlusSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_isHdr10PlusSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn isHdr10PlusGamingSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_isHdr10PlusGamingSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 24u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 24u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isST2084EotfSupported: NvU32, + isTraditionalHdrGammaSupported: NvU32, + isEdrSupported: NvU32, + driverExpandDefaultHdrParameters: NvU32, + isTraditionalSdrGammaSupported: NvU32, + isDolbyVisionSupported: NvU32, + isHdr10PlusSupported: NvU32, + isHdr10PlusGamingSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isST2084EotfSupported: u32 = + unsafe { ::std::mem::transmute(isST2084EotfSupported) }; + isST2084EotfSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isTraditionalHdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalHdrGammaSupported) }; + isTraditionalHdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isEdrSupported: u32 = unsafe { ::std::mem::transmute(isEdrSupported) }; + isEdrSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let driverExpandDefaultHdrParameters: u32 = + unsafe { ::std::mem::transmute(driverExpandDefaultHdrParameters) }; + driverExpandDefaultHdrParameters as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let isTraditionalSdrGammaSupported: u32 = + unsafe { ::std::mem::transmute(isTraditionalSdrGammaSupported) }; + isTraditionalSdrGammaSupported as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let isDolbyVisionSupported: u32 = + unsafe { ::std::mem::transmute(isDolbyVisionSupported) }; + isDolbyVisionSupported as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let isHdr10PlusSupported: u32 = unsafe { ::std::mem::transmute(isHdr10PlusSupported) }; + isHdr10PlusSupported as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let isHdr10PlusGamingSupported: u32 = + unsafe { ::std::mem::transmute(isHdr10PlusGamingSupported) }; + isHdr10PlusGamingSupported as u64 + }); + __bindgen_bitfield_unit.set(8usize, 24u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_HDR_CAPABILITIES_V3 = _NV_HDR_CAPABILITIES_V3; +pub type NV_HDR_CAPABILITIES = NV_HDR_CAPABILITIES_V3; +impl NV_HDR_CMD { + pub const NV_HDR_CMD_GET: NV_HDR_CMD = NV_HDR_CMD(0); +} +impl NV_HDR_CMD { + pub const NV_HDR_CMD_SET: NV_HDR_CMD = NV_HDR_CMD(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_HDR_CMD(pub ::std::os::raw::c_int); +impl NV_HDR_MODE { + pub const NV_HDR_MODE_OFF: NV_HDR_MODE = NV_HDR_MODE(0); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_UHDA: NV_HDR_MODE = NV_HDR_MODE(2); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_UHDA_PASSTHROUGH: NV_HDR_MODE = NV_HDR_MODE(5); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_DOLBY_VISION: NV_HDR_MODE = NV_HDR_MODE(7); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_EDR: NV_HDR_MODE = NV_HDR_MODE(3); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_SDR: NV_HDR_MODE = NV_HDR_MODE(4); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_UHDA_NB: NV_HDR_MODE = NV_HDR_MODE(6); +} +impl NV_HDR_MODE { + pub const NV_HDR_MODE_UHDBD: NV_HDR_MODE = NV_HDR_MODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_HDR_MODE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_COLOR_DATA_V1 { + pub version: NvU32, + pub cmd: NV_HDR_CMD, + pub hdrMode: NV_HDR_MODE, + pub static_metadata_descriptor_id: NV_STATIC_METADATA_DESCRIPTOR_ID, + pub mastering_display_data: _NV_HDR_COLOR_DATA_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_COLOR_DATA_V1__bindgen_ty_1 { + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub max_display_mastering_luminance: NvU16, + pub min_display_mastering_luminance: NvU16, + pub max_content_light_level: NvU16, + pub max_frame_average_light_level: NvU16, +} +pub type NV_HDR_COLOR_DATA_V1 = _NV_HDR_COLOR_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_COLOR_DATA_V2 { + pub version: NvU32, + pub cmd: NV_HDR_CMD, + pub hdrMode: NV_HDR_MODE, + pub static_metadata_descriptor_id: NV_STATIC_METADATA_DESCRIPTOR_ID, + pub mastering_display_data: _NV_HDR_COLOR_DATA_V2__bindgen_ty_1, + pub hdrColorFormat: NV_COLOR_FORMAT, + pub hdrDynamicRange: NV_DYNAMIC_RANGE, + pub hdrBpc: NV_BPC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_COLOR_DATA_V2__bindgen_ty_1 { + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub max_display_mastering_luminance: NvU16, + pub min_display_mastering_luminance: NvU16, + pub max_content_light_level: NvU16, + pub max_frame_average_light_level: NvU16, +} +pub type NV_HDR_COLOR_DATA_V2 = _NV_HDR_COLOR_DATA_V2; +pub type NV_HDR_COLOR_DATA = NV_HDR_COLOR_DATA_V2; +impl _NV_COLORSPACE_TYPE { + pub const NV_COLORSPACE_sRGB: _NV_COLORSPACE_TYPE = _NV_COLORSPACE_TYPE(0); +} +impl _NV_COLORSPACE_TYPE { + pub const NV_COLORSPACE_xRGB: _NV_COLORSPACE_TYPE = _NV_COLORSPACE_TYPE(1); +} +impl _NV_COLORSPACE_TYPE { + pub const NV_COLORSPACE_REC2100: _NV_COLORSPACE_TYPE = _NV_COLORSPACE_TYPE(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_COLORSPACE_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_COLORSPACE_TYPE as NV_COLORSPACE_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HDR_METADATA_V1 { + pub version: NvU32, + pub displayPrimary_x0: NvU16, + pub displayPrimary_y0: NvU16, + pub displayPrimary_x1: NvU16, + pub displayPrimary_y1: NvU16, + pub displayPrimary_x2: NvU16, + pub displayPrimary_y2: NvU16, + pub displayWhitePoint_x: NvU16, + pub displayWhitePoint_y: NvU16, + pub max_display_mastering_luminance: NvU16, + pub min_display_mastering_luminance: NvU16, + pub max_content_light_level: NvU16, + pub max_frame_average_light_level: NvU16, +} +pub type NV_HDR_METADATA_V1 = _NV_HDR_METADATA_V1; +pub type NV_HDR_METADATA = NV_HDR_METADATA_V1; +impl _NV_DISPLAY_OUTPUT_MODE { + pub const NV_DISPLAY_OUTPUT_MODE_SDR: _NV_DISPLAY_OUTPUT_MODE = _NV_DISPLAY_OUTPUT_MODE(0); +} +impl _NV_DISPLAY_OUTPUT_MODE { + pub const NV_DISPLAY_OUTPUT_MODE_HDR10: _NV_DISPLAY_OUTPUT_MODE = _NV_DISPLAY_OUTPUT_MODE(1); +} +impl _NV_DISPLAY_OUTPUT_MODE { + pub const NV_DISPLAY_OUTPUT_MODE_HDR10PLUS_GAMING: _NV_DISPLAY_OUTPUT_MODE = + _NV_DISPLAY_OUTPUT_MODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_DISPLAY_OUTPUT_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_DISPLAY_OUTPUT_MODE as NV_DISPLAY_OUTPUT_MODE; +impl _NV_HDR_TONEMAPPING_METHOD { + pub const NV_HDR_TONEMAPPING_APP: _NV_HDR_TONEMAPPING_METHOD = _NV_HDR_TONEMAPPING_METHOD(0); +} +impl _NV_HDR_TONEMAPPING_METHOD { + pub const NV_HDR_TONEMAPPING_GPU: _NV_HDR_TONEMAPPING_METHOD = _NV_HDR_TONEMAPPING_METHOD(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_HDR_TONEMAPPING_METHOD(pub ::std::os::raw::c_int); +pub use self::_NV_HDR_TONEMAPPING_METHOD as NV_HDR_TONEMAPPING_METHOD; +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct NV_TIMING_FLAG { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub __bindgen_anon_1: NV_TIMING_FLAG__bindgen_ty_1, + pub _bitfield_align_2: [u8; 0], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 5usize], +} +#[repr(C)] +#[repr(align(1))] +#[derive(Copy, Clone)] +pub union NV_TIMING_FLAG__bindgen_ty_1 { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, +} +impl NV_TIMING_FLAG__bindgen_ty_1 { + #[inline] + pub fn tvFormat(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u32) } + } + #[inline] + pub fn set_tvFormat(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn ceaId(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) } + } + #[inline] + pub fn set_ceaId(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn nvPsfId(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u32) } + } + #[inline] + pub fn set_nvPsfId(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + tvFormat: NvU32, + ceaId: NvU32, + nvPsfId: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let tvFormat: u32 = unsafe { ::std::mem::transmute(tvFormat) }; + tvFormat as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let ceaId: u32 = unsafe { ::std::mem::transmute(ceaId) }; + ceaId as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let nvPsfId: u32 = unsafe { ::std::mem::transmute(nvPsfId) }; + nvPsfId as u64 + }); + __bindgen_bitfield_unit + } +} +impl NV_TIMING_FLAG { + #[inline] + pub fn isInterlaced(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } + } + #[inline] + pub fn set_isInterlaced(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub fn reserved0(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 12u8) as u32) } + } + #[inline] + pub fn set_reserved0(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 12u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isInterlaced: NvU32, + reserved0: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let isInterlaced: u32 = unsafe { ::std::mem::transmute(isInterlaced) }; + isInterlaced as u64 + }); + __bindgen_bitfield_unit.set(4usize, 12u8, { + let reserved0: u32 = unsafe { ::std::mem::transmute(reserved0) }; + reserved0 as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn scaling(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 8u8) as u32) } + } + #[inline] + pub fn set_scaling(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_2(scaling: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let scaling: u32 = unsafe { ::std::mem::transmute(scaling) }; + scaling as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_TIMING_INPUT { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub rr: f32, + pub flag: NV_TIMING_FLAG, + pub type_: NV_TIMING_OVERRIDE, +} +pub type NV_TIMING_INPUT = _NV_TIMING_INPUT; +impl NV_MONITOR_CAPS_TYPE { + pub const NV_MONITOR_CAPS_TYPE_HDMI_VSDB: NV_MONITOR_CAPS_TYPE = NV_MONITOR_CAPS_TYPE(4096); +} +impl NV_MONITOR_CAPS_TYPE { + pub const NV_MONITOR_CAPS_TYPE_HDMI_VCDB: NV_MONITOR_CAPS_TYPE = NV_MONITOR_CAPS_TYPE(4097); +} +impl NV_MONITOR_CAPS_TYPE { + pub const NV_MONITOR_CAPS_TYPE_GENERIC: NV_MONITOR_CAPS_TYPE = NV_MONITOR_CAPS_TYPE(4098); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_MONITOR_CAPS_TYPE(pub ::std::os::raw::c_int); +#[repr(C, packed)] +#[derive(Copy, Clone)] +pub struct _NV_MONITOR_CAPS_VCDB { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl _NV_MONITOR_CAPS_VCDB { + #[inline] + pub fn quantizationRangeYcc(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_quantizationRangeYcc(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn quantizationRangeRgb(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } + } + #[inline] + pub fn set_quantizationRangeRgb(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn scanInfoPreferredVideoFormat(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 2u8) as u8) } + } + #[inline] + pub fn set_scanInfoPreferredVideoFormat(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 2u8, val as u64) + } + } + #[inline] + pub fn scanInfoITVideoFormats(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 2u8) as u8) } + } + #[inline] + pub fn set_scanInfoITVideoFormats(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 2u8, val as u64) + } + } + #[inline] + pub fn scanInfoCEVideoFormats(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 2u8) as u8) } + } + #[inline] + pub fn set_scanInfoCEVideoFormats(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 2u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + quantizationRangeYcc: NvU8, + quantizationRangeRgb: NvU8, + scanInfoPreferredVideoFormat: NvU8, + scanInfoITVideoFormats: NvU8, + scanInfoCEVideoFormats: NvU8, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let quantizationRangeYcc: u8 = unsafe { ::std::mem::transmute(quantizationRangeYcc) }; + quantizationRangeYcc as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let quantizationRangeRgb: u8 = unsafe { ::std::mem::transmute(quantizationRangeRgb) }; + quantizationRangeRgb as u64 + }); + __bindgen_bitfield_unit.set(2usize, 2u8, { + let scanInfoPreferredVideoFormat: u8 = + unsafe { ::std::mem::transmute(scanInfoPreferredVideoFormat) }; + scanInfoPreferredVideoFormat as u64 + }); + __bindgen_bitfield_unit.set(4usize, 2u8, { + let scanInfoITVideoFormats: u8 = + unsafe { ::std::mem::transmute(scanInfoITVideoFormats) }; + scanInfoITVideoFormats as u64 + }); + __bindgen_bitfield_unit.set(6usize, 2u8, { + let scanInfoCEVideoFormats: u8 = + unsafe { ::std::mem::transmute(scanInfoCEVideoFormats) }; + scanInfoCEVideoFormats as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MONITOR_CAPS_VCDB = _NV_MONITOR_CAPS_VCDB; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MONITOR_CAPS_VSDB { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub maxTmdsClock: NvU8, + pub _bitfield_align_2: [u8; 0], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>, + pub videoLatency: NvU8, + pub audioLatency: NvU8, + pub interlacedVideoLatency: NvU8, + pub interlacedAudioLatency: NvU8, + pub _bitfield_align_3: [u8; 0], + pub _bitfield_3: __BindgenBitfieldUnit<[u8; 2usize]>, + pub hdmi_vic: [NvU8; 7usize], + pub hdmi_3d: [NvU8; 31usize], +} +impl _NV_MONITOR_CAPS_VSDB { + #[inline] + pub fn sourcePhysicalAddressB(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u8) } + } + #[inline] + pub fn set_sourcePhysicalAddressB(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub fn sourcePhysicalAddressA(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u8) } + } + #[inline] + pub fn set_sourcePhysicalAddressA(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub fn sourcePhysicalAddressD(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u8) } + } + #[inline] + pub fn set_sourcePhysicalAddressD(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 4u8, val as u64) + } + } + #[inline] + pub fn sourcePhysicalAddressC(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 4u8) as u8) } + } + #[inline] + pub fn set_sourcePhysicalAddressC(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 4u8, val as u64) + } + } + #[inline] + pub fn supportDualDviOperation(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportDualDviOperation(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved6(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 2u8) as u8) } + } + #[inline] + pub fn set_reserved6(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 2u8, val as u64) + } + } + #[inline] + pub fn supportDeepColorYCbCr444(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportDeepColorYCbCr444(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportDeepColor30bits(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportDeepColor30bits(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportDeepColor36bits(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportDeepColor36bits(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportDeepColor48bits(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportDeepColor48bits(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportAI(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportAI(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + sourcePhysicalAddressB: NvU8, + sourcePhysicalAddressA: NvU8, + sourcePhysicalAddressD: NvU8, + sourcePhysicalAddressC: NvU8, + supportDualDviOperation: NvU8, + reserved6: NvU8, + supportDeepColorYCbCr444: NvU8, + supportDeepColor30bits: NvU8, + supportDeepColor36bits: NvU8, + supportDeepColor48bits: NvU8, + supportAI: NvU8, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let sourcePhysicalAddressB: u8 = + unsafe { ::std::mem::transmute(sourcePhysicalAddressB) }; + sourcePhysicalAddressB as u64 + }); + __bindgen_bitfield_unit.set(4usize, 4u8, { + let sourcePhysicalAddressA: u8 = + unsafe { ::std::mem::transmute(sourcePhysicalAddressA) }; + sourcePhysicalAddressA as u64 + }); + __bindgen_bitfield_unit.set(8usize, 4u8, { + let sourcePhysicalAddressD: u8 = + unsafe { ::std::mem::transmute(sourcePhysicalAddressD) }; + sourcePhysicalAddressD as u64 + }); + __bindgen_bitfield_unit.set(12usize, 4u8, { + let sourcePhysicalAddressC: u8 = + unsafe { ::std::mem::transmute(sourcePhysicalAddressC) }; + sourcePhysicalAddressC as u64 + }); + __bindgen_bitfield_unit.set(16usize, 1u8, { + let supportDualDviOperation: u8 = + unsafe { ::std::mem::transmute(supportDualDviOperation) }; + supportDualDviOperation as u64 + }); + __bindgen_bitfield_unit.set(17usize, 2u8, { + let reserved6: u8 = unsafe { ::std::mem::transmute(reserved6) }; + reserved6 as u64 + }); + __bindgen_bitfield_unit.set(19usize, 1u8, { + let supportDeepColorYCbCr444: u8 = + unsafe { ::std::mem::transmute(supportDeepColorYCbCr444) }; + supportDeepColorYCbCr444 as u64 + }); + __bindgen_bitfield_unit.set(20usize, 1u8, { + let supportDeepColor30bits: u8 = + unsafe { ::std::mem::transmute(supportDeepColor30bits) }; + supportDeepColor30bits as u64 + }); + __bindgen_bitfield_unit.set(21usize, 1u8, { + let supportDeepColor36bits: u8 = + unsafe { ::std::mem::transmute(supportDeepColor36bits) }; + supportDeepColor36bits as u64 + }); + __bindgen_bitfield_unit.set(22usize, 1u8, { + let supportDeepColor48bits: u8 = + unsafe { ::std::mem::transmute(supportDeepColor48bits) }; + supportDeepColor48bits as u64 + }); + __bindgen_bitfield_unit.set(23usize, 1u8, { + let supportAI: u8 = unsafe { ::std::mem::transmute(supportAI) }; + supportAI as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn cnc0SupportGraphicsTextContent(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_cnc0SupportGraphicsTextContent(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn cnc1SupportPhotoContent(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(1usize, 1u8) as u8) } + } + #[inline] + pub fn set_cnc1SupportPhotoContent(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn cnc2SupportCinemaContent(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(2usize, 1u8) as u8) } + } + #[inline] + pub fn set_cnc2SupportCinemaContent(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn cnc3SupportGameContent(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(3usize, 1u8) as u8) } + } + #[inline] + pub fn set_cnc3SupportGameContent(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved8(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(4usize, 1u8) as u8) } + } + #[inline] + pub fn set_reserved8(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasVicEntries(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(5usize, 1u8) as u8) } + } + #[inline] + pub fn set_hasVicEntries(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasInterlacedLatencyField(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(6usize, 1u8) as u8) } + } + #[inline] + pub fn set_hasInterlacedLatencyField(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn hasLatencyField(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_2.get(7usize, 1u8) as u8) } + } + #[inline] + pub fn set_hasLatencyField(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_2( + cnc0SupportGraphicsTextContent: NvU8, + cnc1SupportPhotoContent: NvU8, + cnc2SupportCinemaContent: NvU8, + cnc3SupportGameContent: NvU8, + reserved8: NvU8, + hasVicEntries: NvU8, + hasInterlacedLatencyField: NvU8, + hasLatencyField: NvU8, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let cnc0SupportGraphicsTextContent: u8 = + unsafe { ::std::mem::transmute(cnc0SupportGraphicsTextContent) }; + cnc0SupportGraphicsTextContent as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let cnc1SupportPhotoContent: u8 = + unsafe { ::std::mem::transmute(cnc1SupportPhotoContent) }; + cnc1SupportPhotoContent as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let cnc2SupportCinemaContent: u8 = + unsafe { ::std::mem::transmute(cnc2SupportCinemaContent) }; + cnc2SupportCinemaContent as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let cnc3SupportGameContent: u8 = + unsafe { ::std::mem::transmute(cnc3SupportGameContent) }; + cnc3SupportGameContent as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let reserved8: u8 = unsafe { ::std::mem::transmute(reserved8) }; + reserved8 as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let hasVicEntries: u8 = unsafe { ::std::mem::transmute(hasVicEntries) }; + hasVicEntries as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let hasInterlacedLatencyField: u8 = + unsafe { ::std::mem::transmute(hasInterlacedLatencyField) }; + hasInterlacedLatencyField as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let hasLatencyField: u8 = unsafe { ::std::mem::transmute(hasLatencyField) }; + hasLatencyField as u64 + }); + __bindgen_bitfield_unit + } + #[inline] + pub fn reserved13(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(0usize, 7u8) as u8) } + } + #[inline] + pub fn set_reserved13(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_3.set(0usize, 7u8, val as u64) + } + } + #[inline] + pub fn has3dEntries(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(7usize, 1u8) as u8) } + } + #[inline] + pub fn set_has3dEntries(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_3.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn hdmi3dLength(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(8usize, 5u8) as u8) } + } + #[inline] + pub fn set_hdmi3dLength(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_3.set(8usize, 5u8, val as u64) + } + } + #[inline] + pub fn hdmiVicLength(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_3.get(13usize, 3u8) as u8) } + } + #[inline] + pub fn set_hdmiVicLength(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_3.set(13usize, 3u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_3( + reserved13: NvU8, + has3dEntries: NvU8, + hdmi3dLength: NvU8, + hdmiVicLength: NvU8, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let reserved13: u8 = unsafe { ::std::mem::transmute(reserved13) }; + reserved13 as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let has3dEntries: u8 = unsafe { ::std::mem::transmute(has3dEntries) }; + has3dEntries as u64 + }); + __bindgen_bitfield_unit.set(8usize, 5u8, { + let hdmi3dLength: u8 = unsafe { ::std::mem::transmute(hdmi3dLength) }; + hdmi3dLength as u64 + }); + __bindgen_bitfield_unit.set(13usize, 3u8, { + let hdmiVicLength: u8 = unsafe { ::std::mem::transmute(hdmiVicLength) }; + hdmiVicLength as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MONITOR_CAPS_VSDB = _NV_MONITOR_CAPS_VSDB; +#[repr(C, packed)] +#[derive(Copy, Clone)] +pub struct _NV_MONITOR_CAPS_GENERIC { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl _NV_MONITOR_CAPS_GENERIC { + #[inline] + pub fn supportVRR(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportVRR(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportULMB(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } + } + #[inline] + pub fn set_supportULMB(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn isTrueGsync(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } + } + #[inline] + pub fn set_isTrueGsync(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn isRLACapable(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } + } + #[inline] + pub fn set_isRLACapable(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn currentlyCapableOfVRR(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } + } + #[inline] + pub fn set_currentlyCapableOfVRR(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 3u8) as u8) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 3u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + supportVRR: NvU8, + supportULMB: NvU8, + isTrueGsync: NvU8, + isRLACapable: NvU8, + currentlyCapableOfVRR: NvU8, + reserved: NvU8, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let supportVRR: u8 = unsafe { ::std::mem::transmute(supportVRR) }; + supportVRR as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let supportULMB: u8 = unsafe { ::std::mem::transmute(supportULMB) }; + supportULMB as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let isTrueGsync: u8 = unsafe { ::std::mem::transmute(isTrueGsync) }; + isTrueGsync as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let isRLACapable: u8 = unsafe { ::std::mem::transmute(isRLACapable) }; + isRLACapable as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let currentlyCapableOfVRR: u8 = unsafe { ::std::mem::transmute(currentlyCapableOfVRR) }; + currentlyCapableOfVRR as u64 + }); + __bindgen_bitfield_unit.set(5usize, 3u8, { + let reserved: u8 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MONITOR_CAPS_GENERIC = _NV_MONITOR_CAPS_GENERIC; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MONITOR_CAPABILITIES_V1 { + pub version: NvU32, + pub size: NvU16, + pub infoType: NvU32, + pub connectorType: NvU32, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub data: _NV_MONITOR_CAPABILITIES_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_MONITOR_CAPABILITIES_V1__bindgen_ty_1 { + pub vsdb: NV_MONITOR_CAPS_VSDB, + pub vcdb: NV_MONITOR_CAPS_VCDB, + pub caps: NV_MONITOR_CAPS_GENERIC, +} +impl _NV_MONITOR_CAPABILITIES_V1 { + #[inline] + pub fn bIsValidInfo(&self) -> NvU8 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_bIsValidInfo(&mut self, val: NvU8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(bIsValidInfo: NvU8) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsValidInfo: u8 = unsafe { ::std::mem::transmute(bIsValidInfo) }; + bIsValidInfo as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MONITOR_CAPABILITIES_V1 = _NV_MONITOR_CAPABILITIES_V1; +pub type NV_MONITOR_CAPABILITIES = NV_MONITOR_CAPABILITIES_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MONITOR_COLOR_DATA { + pub version: NvU32, + pub colorFormat: NV_DP_COLOR_FORMAT, + pub backendBitDepths: NV_DP_BPC, +} +pub type NV_MONITOR_COLOR_CAPS_V1 = _NV_MONITOR_COLOR_DATA; +pub type NV_MONITOR_COLOR_CAPS = NV_MONITOR_COLOR_CAPS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_CUSTOM_DISPLAY { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub depth: NvU32, + pub colorFormat: NV_FORMAT, + pub srcPartition: NV_VIEWPORTF, + pub xRatio: f32, + pub yRatio: f32, + pub timing: NV_TIMING, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub __bindgen_padding_0: [u8; 3usize], +} +impl NV_CUSTOM_DISPLAY { + #[inline] + pub fn hwModeSetOnly(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_hwModeSetOnly(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(hwModeSetOnly: NvU32) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let hwModeSetOnly: u32 = unsafe { ::std::mem::transmute(hwModeSetOnly) }; + hwModeSetOnly as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GET_ADAPTIVE_SYNC_DATA_V1 { + pub version: NvU32, + pub maxFrameInterval: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub lastFlipRefreshCount: NvU32, + pub lastFlipTimeStamp: NvU64, + pub reservedEx: [NvU32; 4usize], +} +impl _NV_GET_ADAPTIVE_SYNC_DATA_V1 { + #[inline] + pub fn bDisableAdaptiveSync(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDisableAdaptiveSync(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bDisableFrameSplitting(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDisableFrameSplitting(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bDisableAdaptiveSync: NvU32, + bDisableFrameSplitting: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bDisableAdaptiveSync: u32 = unsafe { ::std::mem::transmute(bDisableAdaptiveSync) }; + bDisableAdaptiveSync as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bDisableFrameSplitting: u32 = + unsafe { ::std::mem::transmute(bDisableFrameSplitting) }; + bDisableFrameSplitting as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GET_ADAPTIVE_SYNC_DATA_V1 = _NV_GET_ADAPTIVE_SYNC_DATA_V1; +pub type NV_GET_ADAPTIVE_SYNC_DATA = NV_GET_ADAPTIVE_SYNC_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SET_ADAPTIVE_SYNC_DATA_V1 { + pub version: NvU32, + pub maxFrameInterval: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub reservedEx: [NvU32; 7usize], +} +impl _NV_SET_ADAPTIVE_SYNC_DATA_V1 { + #[inline] + pub fn bDisableAdaptiveSync(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDisableAdaptiveSync(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bDisableFrameSplitting(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDisableFrameSplitting(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bDisableAdaptiveSync: NvU32, + bDisableFrameSplitting: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bDisableAdaptiveSync: u32 = unsafe { ::std::mem::transmute(bDisableAdaptiveSync) }; + bDisableAdaptiveSync as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bDisableFrameSplitting: u32 = + unsafe { ::std::mem::transmute(bDisableFrameSplitting) }; + bDisableFrameSplitting as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_SET_ADAPTIVE_SYNC_DATA_V1 = _NV_SET_ADAPTIVE_SYNC_DATA_V1; +pub type NV_SET_ADAPTIVE_SYNC_DATA = NV_SET_ADAPTIVE_SYNC_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GET_VIRTUAL_REFRESH_RATE_DATA_V1 { + pub version: NvU32, + pub frameIntervalUs: NvU32, + pub reservedEx: [NvU32; 8usize], +} +pub type NV_GET_VIRTUAL_REFRESH_RATE_DATA_V1 = _NV_GET_VIRTUAL_REFRESH_RATE_DATA_V1; +pub type NV_GET_VIRTUAL_REFRESH_RATE_DATA = NV_GET_VIRTUAL_REFRESH_RATE_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SET_VIRTUAL_REFRESH_RATE_DATA_V1 { + pub version: NvU32, + pub frameIntervalUs: NvU32, + pub reservedEx: [NvU32; 8usize], +} +pub type NV_SET_VIRTUAL_REFRESH_RATE_DATA_V1 = _NV_SET_VIRTUAL_REFRESH_RATE_DATA_V1; +pub type NV_SET_VIRTUAL_REFRESH_RATE_DATA = NV_SET_VIRTUAL_REFRESH_RATE_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_SET_PREFERRED_STEREO_DISPLAY_V1 { + pub version: NvU32, + pub displayId: NvU32, + pub reserved: NvU32, +} +pub type NV_SET_PREFERRED_STEREO_DISPLAY = NV_SET_PREFERRED_STEREO_DISPLAY_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GET_PREFERRED_STEREO_DISPLAY_V1 { + pub version: NvU32, + pub displayId: NvU32, + pub reserved: NvU32, +} +pub type NV_GET_PREFERRED_STEREO_DISPLAY = NV_GET_PREFERRED_STEREO_DISPLAY_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MANAGED_DEDICATED_DISPLAY_INFO { + pub version: NvU32, + pub displayId: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_MANAGED_DEDICATED_DISPLAY_INFO { + #[inline] + pub fn isAcquired(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isAcquired(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isMosaic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMosaic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isAcquired: NvU32, + isMosaic: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isAcquired: u32 = unsafe { ::std::mem::transmute(isAcquired) }; + isAcquired as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isMosaic: u32 = unsafe { ::std::mem::transmute(isMosaic) }; + isMosaic as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MANAGED_DEDICATED_DISPLAY_INFO_V1 = _NV_MANAGED_DEDICATED_DISPLAY_INFO; +pub type NV_MANAGED_DEDICATED_DISPLAY_INFO = NV_MANAGED_DEDICATED_DISPLAY_INFO_V1; +#[repr(C)] +pub struct _NV_DISPLAY_ID_INFO_DATA_V1 { + pub version: NvU32, + pub adapterId: LUID, + pub targetId: NvU32, + pub reserved: [NvU32; 4usize], +} +pub type NV_DISPLAY_ID_INFO_DATA_V1 = _NV_DISPLAY_ID_INFO_DATA_V1; +pub type NV_DISPLAY_ID_INFO_DATA = NV_DISPLAY_ID_INFO_DATA_V1; +#[repr(C)] +pub struct _NV_TARGET_INFO_DATA_V1 { + pub version: NvU32, + pub adapterId: LUID, + pub targetId: NvU32, + pub displayId: [NvU32; 128usize], + pub displayIdCount: NvU32, + pub reserved: [NvU32; 4usize], +} +pub type NV_TARGET_INFO_DATA_V1 = _NV_TARGET_INFO_DATA_V1; +pub type NV_TARGET_INFO_DATA = NV_TARGET_INFO_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GET_VRR_INFO_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub reservedEx: [NvU32; 4usize], +} +impl _NV_GET_VRR_INFO_V1 { + #[inline] + pub fn bIsVRREnabled(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsVRREnabled(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsVRREnabled: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsVRREnabled: u32 = unsafe { ::std::mem::transmute(bIsVRREnabled) }; + bIsVRREnabled as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GET_VRR_INFO_V1 = _NV_GET_VRR_INFO_V1; +pub type NV_GET_VRR_INFO = NV_GET_VRR_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPO_DETAILS { + pub version: NvU32, + pub hLogicalGPU: NvLogicalGpuHandle, + pub validityMask: NvU32, + pub rowCount: NvU32, + pub colCount: NvU32, + pub gpuLayout: [[NV_MOSAIC_TOPO_DETAILS__bindgen_ty_1; 8usize]; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPO_DETAILS__bindgen_ty_1 { + pub hPhysicalGPU: NvPhysicalGpuHandle, + pub displayOutputId: NvU32, + pub overlapX: NvS32, + pub overlapY: NvS32, +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_ALL: NV_MOSAIC_TOPO_TYPE = NV_MOSAIC_TOPO_TYPE(0); +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_BASIC: NV_MOSAIC_TOPO_TYPE = NV_MOSAIC_TOPO_TYPE(1); +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_PASSIVE_STEREO: NV_MOSAIC_TOPO_TYPE = NV_MOSAIC_TOPO_TYPE(2); +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_SCALED_CLONE: NV_MOSAIC_TOPO_TYPE = NV_MOSAIC_TOPO_TYPE(3); +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_PASSIVE_STEREO_SCALED_CLONE: NV_MOSAIC_TOPO_TYPE = + NV_MOSAIC_TOPO_TYPE(4); +} +impl NV_MOSAIC_TOPO_TYPE { + pub const NV_MOSAIC_TOPO_TYPE_MAX: NV_MOSAIC_TOPO_TYPE = NV_MOSAIC_TOPO_TYPE(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_MOSAIC_TOPO_TYPE(pub ::std::os::raw::c_int); +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_NONE: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(0); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_BEGIN_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(1); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x2_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(1); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x1_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(2); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x3_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(3); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_3x1_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(4); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x4_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(5); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_4x1_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(6); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x2_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(7); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x3_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(8); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x4_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(9); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_3x2_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(10); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_4x2_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(11); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x5_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(12); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x6_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(13); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_7x1_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(14); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_END_BASIC: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(23); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_BEGIN_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(24); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x2_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(24); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x1_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(25); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x3_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(26); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_3x1_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(27); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_1x4_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(28); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_4x1_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(29); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_2x2_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(30); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_END_PASSIVE_STEREO: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(34); +} +impl NV_MOSAIC_TOPO { + pub const NV_MOSAIC_TOPO_MAX: NV_MOSAIC_TOPO = NV_MOSAIC_TOPO(35); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_MOSAIC_TOPO(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPO_BRIEF { + pub version: NvU32, + pub topo: NV_MOSAIC_TOPO, + pub enabled: NvU32, + pub isPossible: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_DISPLAY_SETTING_V1 { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub bpp: NvU32, + pub freq: NvU32, +} +pub type NV_MOSAIC_DISPLAY_SETTING_V1 = _NV_MOSAIC_DISPLAY_SETTING_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_DISPLAY_SETTING_V2 { + pub version: NvU32, + pub width: NvU32, + pub height: NvU32, + pub bpp: NvU32, + pub freq: NvU32, + pub rrx1k: NvU32, +} +pub type NV_MOSAIC_DISPLAY_SETTING = NV_MOSAIC_DISPLAY_SETTING_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_SUPPORTED_TOPO_INFO_V1 { + pub version: NvU32, + pub topoBriefsCount: NvU32, + pub topoBriefs: [NV_MOSAIC_TOPO_BRIEF; 35usize], + pub displaySettingsCount: NvU32, + pub displaySettings: [NV_MOSAIC_DISPLAY_SETTING_V1; 40usize], +} +pub type NV_MOSAIC_SUPPORTED_TOPO_INFO_V1 = _NV_MOSAIC_SUPPORTED_TOPO_INFO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_SUPPORTED_TOPO_INFO_V2 { + pub version: NvU32, + pub topoBriefsCount: NvU32, + pub topoBriefs: [NV_MOSAIC_TOPO_BRIEF; 35usize], + pub displaySettingsCount: NvU32, + pub displaySettings: [NV_MOSAIC_DISPLAY_SETTING_V2; 40usize], +} +pub type NV_MOSAIC_SUPPORTED_TOPO_INFO_V2 = _NV_MOSAIC_SUPPORTED_TOPO_INFO_V2; +pub type NV_MOSAIC_SUPPORTED_TOPO_INFO = NV_MOSAIC_SUPPORTED_TOPO_INFO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPO_GROUP { + pub version: NvU32, + pub brief: NV_MOSAIC_TOPO_BRIEF, + pub count: NvU32, + pub topos: [NV_MOSAIC_TOPO_DETAILS; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_GRID_TOPO_DISPLAY_V1 { + pub displayId: NvU32, + pub overlapX: NvS32, + pub overlapY: NvS32, + pub rotation: NV_ROTATE, + pub cloneGroup: NvU32, +} +pub type NV_MOSAIC_GRID_TOPO_DISPLAY_V1 = _NV_MOSAIC_GRID_TOPO_DISPLAY_V1; +impl _NV_PIXEL_SHIFT_TYPE { + pub const NV_PIXEL_SHIFT_TYPE_NO_PIXEL_SHIFT: _NV_PIXEL_SHIFT_TYPE = _NV_PIXEL_SHIFT_TYPE(0); +} +impl _NV_PIXEL_SHIFT_TYPE { + pub const NV_PIXEL_SHIFT_TYPE_2x2_TOP_LEFT_PIXELS: _NV_PIXEL_SHIFT_TYPE = + _NV_PIXEL_SHIFT_TYPE(1); +} +impl _NV_PIXEL_SHIFT_TYPE { + pub const NV_PIXEL_SHIFT_TYPE_2x2_BOTTOM_RIGHT_PIXELS: _NV_PIXEL_SHIFT_TYPE = + _NV_PIXEL_SHIFT_TYPE(2); +} +impl _NV_PIXEL_SHIFT_TYPE { + pub const NV_PIXEL_SHIFT_TYPE_2x2_TOP_RIGHT_PIXELS: _NV_PIXEL_SHIFT_TYPE = + _NV_PIXEL_SHIFT_TYPE(4); +} +impl _NV_PIXEL_SHIFT_TYPE { + pub const NV_PIXEL_SHIFT_TYPE_2x2_BOTTOM_LEFT_PIXELS: _NV_PIXEL_SHIFT_TYPE = + _NV_PIXEL_SHIFT_TYPE(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_PIXEL_SHIFT_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_PIXEL_SHIFT_TYPE as NV_PIXEL_SHIFT_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_GRID_TOPO_DISPLAY_V2 { + pub version: NvU32, + pub displayId: NvU32, + pub overlapX: NvS32, + pub overlapY: NvS32, + pub rotation: NV_ROTATE, + pub cloneGroup: NvU32, + pub pixelShiftType: NV_PIXEL_SHIFT_TYPE, +} +pub type NV_MOSAIC_GRID_TOPO_DISPLAY_V2 = _NV_MOSAIC_GRID_TOPO_DISPLAY_V2; +pub type NV_MOSAIC_GRID_TOPO_DISPLAY = NV_MOSAIC_GRID_TOPO_DISPLAY_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_GRID_TOPO_V1 { + pub version: NvU32, + pub rows: NvU32, + pub columns: NvU32, + pub displayCount: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub displays: [NV_MOSAIC_GRID_TOPO_DISPLAY_V1; 64usize], + pub displaySettings: NV_MOSAIC_DISPLAY_SETTING_V1, +} +impl _NV_MOSAIC_GRID_TOPO_V1 { + #[inline] + pub fn applyWithBezelCorrect(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_applyWithBezelCorrect(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn immersiveGaming(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_immersiveGaming(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn baseMosaic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_baseMosaic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn driverReloadAllowed(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_driverReloadAllowed(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn acceleratePrimaryDisplay(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_acceleratePrimaryDisplay(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 27u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 27u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + applyWithBezelCorrect: NvU32, + immersiveGaming: NvU32, + baseMosaic: NvU32, + driverReloadAllowed: NvU32, + acceleratePrimaryDisplay: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let applyWithBezelCorrect: u32 = + unsafe { ::std::mem::transmute(applyWithBezelCorrect) }; + applyWithBezelCorrect as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let immersiveGaming: u32 = unsafe { ::std::mem::transmute(immersiveGaming) }; + immersiveGaming as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let baseMosaic: u32 = unsafe { ::std::mem::transmute(baseMosaic) }; + baseMosaic as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let driverReloadAllowed: u32 = unsafe { ::std::mem::transmute(driverReloadAllowed) }; + driverReloadAllowed as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let acceleratePrimaryDisplay: u32 = + unsafe { ::std::mem::transmute(acceleratePrimaryDisplay) }; + acceleratePrimaryDisplay as u64 + }); + __bindgen_bitfield_unit.set(5usize, 27u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MOSAIC_GRID_TOPO_V1 = _NV_MOSAIC_GRID_TOPO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MOSAIC_GRID_TOPO_V2 { + pub version: NvU32, + pub rows: NvU32, + pub columns: NvU32, + pub displayCount: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub displays: [NV_MOSAIC_GRID_TOPO_DISPLAY_V2; 64usize], + pub displaySettings: NV_MOSAIC_DISPLAY_SETTING_V1, +} +impl _NV_MOSAIC_GRID_TOPO_V2 { + #[inline] + pub fn applyWithBezelCorrect(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_applyWithBezelCorrect(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn immersiveGaming(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_immersiveGaming(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn baseMosaic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_baseMosaic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn driverReloadAllowed(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_driverReloadAllowed(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn acceleratePrimaryDisplay(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_acceleratePrimaryDisplay(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn pixelShift(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_pixelShift(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 26u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 26u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + applyWithBezelCorrect: NvU32, + immersiveGaming: NvU32, + baseMosaic: NvU32, + driverReloadAllowed: NvU32, + acceleratePrimaryDisplay: NvU32, + pixelShift: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let applyWithBezelCorrect: u32 = + unsafe { ::std::mem::transmute(applyWithBezelCorrect) }; + applyWithBezelCorrect as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let immersiveGaming: u32 = unsafe { ::std::mem::transmute(immersiveGaming) }; + immersiveGaming as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let baseMosaic: u32 = unsafe { ::std::mem::transmute(baseMosaic) }; + baseMosaic as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let driverReloadAllowed: u32 = unsafe { ::std::mem::transmute(driverReloadAllowed) }; + driverReloadAllowed as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let acceleratePrimaryDisplay: u32 = + unsafe { ::std::mem::transmute(acceleratePrimaryDisplay) }; + acceleratePrimaryDisplay as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let pixelShift: u32 = unsafe { ::std::mem::transmute(pixelShift) }; + pixelShift as u64 + }); + __bindgen_bitfield_unit.set(6usize, 26u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_MOSAIC_GRID_TOPO_V2 = _NV_MOSAIC_GRID_TOPO_V2; +pub type NV_MOSAIC_GRID_TOPO = NV_MOSAIC_GRID_TOPO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_DISPLAY_TOPO_STATUS { + pub version: NvU32, + pub errorFlags: NvU32, + pub warningFlags: NvU32, + pub displayCount: NvU32, + pub displays: [NV_MOSAIC_DISPLAY_TOPO_STATUS__bindgen_ty_1; 128usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_DISPLAY_TOPO_STATUS__bindgen_ty_1 { + pub displayId: NvU32, + pub errorFlags: NvU32, + pub warningFlags: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl NV_MOSAIC_DISPLAY_TOPO_STATUS__bindgen_ty_1 { + #[inline] + pub fn supportsRotation(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_supportsRotation(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + supportsRotation: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let supportsRotation: u32 = unsafe { ::std::mem::transmute(supportsRotation) }; + supportsRotation as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPOLOGY { + pub version: NvU32, + pub rowCount: NvU32, + pub colCount: NvU32, + pub gpuLayout: [[NV_MOSAIC_TOPOLOGY__bindgen_ty_1; 8usize]; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_TOPOLOGY__bindgen_ty_1 { + pub hPhysicalGPU: NvPhysicalGpuHandle, + pub displayOutputId: NvU32, + pub overlapX: NvS32, + pub overlapY: NvS32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_MOSAIC_SUPPORTED_TOPOLOGIES { + pub version: NvU32, + pub totalCount: NvU32, + pub topos: [NV_MOSAIC_TOPOLOGY; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_CAPABILITIES_V1 { + pub version: NvU32, + pub boardId: NvU32, + pub revision: NvU32, + pub capFlags: NvU32, +} +pub type NV_GSYNC_CAPABILITIES_V1 = _NV_GSYNC_CAPABILITIES_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_CAPABILITIES_V2 { + pub version: NvU32, + pub boardId: NvU32, + pub revision: NvU32, + pub capFlags: NvU32, + pub extendedRevision: NvU32, +} +pub type NV_GSYNC_CAPABILITIES_V2 = _NV_GSYNC_CAPABILITIES_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_CAPABILITIES_V3 { + pub version: NvU32, + pub boardId: NvU32, + pub revision: NvU32, + pub capFlags: NvU32, + pub extendedRevision: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub maxMulDivValue: NvU32, +} +impl _NV_GSYNC_CAPABILITIES_V3 { + #[inline] + pub fn bIsMulDivSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsMulDivSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsMulDivSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsMulDivSupported: u32 = unsafe { ::std::mem::transmute(bIsMulDivSupported) }; + bIsMulDivSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_CAPABILITIES_V3 = _NV_GSYNC_CAPABILITIES_V3; +pub type NV_GSYNC_CAPABILITIES = NV_GSYNC_CAPABILITIES_V3; +impl _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR { + pub const NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_NONE: _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR = + _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(0); +} +impl _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR { + pub const NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_PRIMARY: _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR = + _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(1); +} +impl _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR { + pub const NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_SECONDARY: _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR = + _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(2); +} +impl _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR { + pub const NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_TERTIARY: _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR = + _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(3); +} +impl _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR { + pub const NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_QUARTERNARY: _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR = + _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR as NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR; +impl _NVAPI_GSYNC_DISPLAY_SYNC_STATE { + pub const NVAPI_GSYNC_DISPLAY_SYNC_STATE_UNSYNCED: _NVAPI_GSYNC_DISPLAY_SYNC_STATE = + _NVAPI_GSYNC_DISPLAY_SYNC_STATE(0); +} +impl _NVAPI_GSYNC_DISPLAY_SYNC_STATE { + pub const NVAPI_GSYNC_DISPLAY_SYNC_STATE_SLAVE: _NVAPI_GSYNC_DISPLAY_SYNC_STATE = + _NVAPI_GSYNC_DISPLAY_SYNC_STATE(1); +} +impl _NVAPI_GSYNC_DISPLAY_SYNC_STATE { + pub const NVAPI_GSYNC_DISPLAY_SYNC_STATE_MASTER: _NVAPI_GSYNC_DISPLAY_SYNC_STATE = + _NVAPI_GSYNC_DISPLAY_SYNC_STATE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_DISPLAY_SYNC_STATE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_DISPLAY_SYNC_STATE as NVAPI_GSYNC_DISPLAY_SYNC_STATE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_GPU { + pub version: NvU32, + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub connector: NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR, + pub hProxyPhysicalGpu: NvPhysicalGpuHandle, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub __bindgen_padding_0: u32, +} +impl _NV_GSYNC_GPU { + #[inline] + pub fn isSynced(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isSynced(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1(isSynced: NvU32, reserved: NvU32) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isSynced: u32 = unsafe { ::std::mem::transmute(isSynced) }; + isSynced as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_GPU = _NV_GSYNC_GPU; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_DISPLAY { + pub version: NvU32, + pub displayId: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub syncState: NVAPI_GSYNC_DISPLAY_SYNC_STATE, +} +impl _NV_GSYNC_DISPLAY { + #[inline] + pub fn isMasterable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMasterable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isMasterable: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isMasterable: u32 = unsafe { ::std::mem::transmute(isMasterable) }; + isMasterable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_DISPLAY = _NV_GSYNC_DISPLAY; +impl _NVAPI_GSYNC_POLARITY { + pub const NVAPI_GSYNC_POLARITY_RISING_EDGE: _NVAPI_GSYNC_POLARITY = _NVAPI_GSYNC_POLARITY(0); +} +impl _NVAPI_GSYNC_POLARITY { + pub const NVAPI_GSYNC_POLARITY_FALLING_EDGE: _NVAPI_GSYNC_POLARITY = _NVAPI_GSYNC_POLARITY(1); +} +impl _NVAPI_GSYNC_POLARITY { + pub const NVAPI_GSYNC_POLARITY_BOTH_EDGES: _NVAPI_GSYNC_POLARITY = _NVAPI_GSYNC_POLARITY(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_POLARITY(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_POLARITY as NVAPI_GSYNC_POLARITY; +impl _NVAPI_GSYNC_VIDEO_MODE { + pub const NVAPI_GSYNC_VIDEO_MODE_NONE: _NVAPI_GSYNC_VIDEO_MODE = _NVAPI_GSYNC_VIDEO_MODE(0); +} +impl _NVAPI_GSYNC_VIDEO_MODE { + pub const NVAPI_GSYNC_VIDEO_MODE_TTL: _NVAPI_GSYNC_VIDEO_MODE = _NVAPI_GSYNC_VIDEO_MODE(1); +} +impl _NVAPI_GSYNC_VIDEO_MODE { + pub const NVAPI_GSYNC_VIDEO_MODE_NTSCPALSECAM: _NVAPI_GSYNC_VIDEO_MODE = + _NVAPI_GSYNC_VIDEO_MODE(2); +} +impl _NVAPI_GSYNC_VIDEO_MODE { + pub const NVAPI_GSYNC_VIDEO_MODE_HDTV: _NVAPI_GSYNC_VIDEO_MODE = _NVAPI_GSYNC_VIDEO_MODE(3); +} +impl _NVAPI_GSYNC_VIDEO_MODE { + pub const NVAPI_GSYNC_VIDEO_MODE_COMPOSITE: _NVAPI_GSYNC_VIDEO_MODE = + _NVAPI_GSYNC_VIDEO_MODE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_VIDEO_MODE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_VIDEO_MODE as NVAPI_GSYNC_VIDEO_MODE; +impl _NVAPI_GSYNC_SYNC_SOURCE { + pub const NVAPI_GSYNC_SYNC_SOURCE_VSYNC: _NVAPI_GSYNC_SYNC_SOURCE = _NVAPI_GSYNC_SYNC_SOURCE(0); +} +impl _NVAPI_GSYNC_SYNC_SOURCE { + pub const NVAPI_GSYNC_SYNC_SOURCE_HOUSESYNC: _NVAPI_GSYNC_SYNC_SOURCE = + _NVAPI_GSYNC_SYNC_SOURCE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_SYNC_SOURCE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_SYNC_SOURCE as NVAPI_GSYNC_SYNC_SOURCE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_DELAY { + pub version: NvU32, + pub numLines: NvU32, + pub numPixels: NvU32, + pub maxLines: NvU32, + pub minPixels: NvU32, +} +pub type NV_GSYNC_DELAY = _NV_GSYNC_DELAY; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_CONTROL_PARAMS_V1 { + pub version: NvU32, + pub polarity: NVAPI_GSYNC_POLARITY, + pub vmode: NVAPI_GSYNC_VIDEO_MODE, + pub interval: NvU32, + pub source: NVAPI_GSYNC_SYNC_SOURCE, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub syncSkew: NV_GSYNC_DELAY, + pub startupDelay: NV_GSYNC_DELAY, +} +impl _NV_GSYNC_CONTROL_PARAMS_V1 { + #[inline] + pub fn interlaceMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_interlaceMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn syncSourceIsOutput(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_syncSourceIsOutput(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + interlaceMode: NvU32, + syncSourceIsOutput: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let interlaceMode: u32 = unsafe { ::std::mem::transmute(interlaceMode) }; + interlaceMode as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let syncSourceIsOutput: u32 = unsafe { ::std::mem::transmute(syncSourceIsOutput) }; + syncSourceIsOutput as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_CONTROL_PARAMS_V1 = _NV_GSYNC_CONTROL_PARAMS_V1; +impl _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE { + pub const NVAPI_GSYNC_UNDEFINED_MODE: _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE = + _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE(0); +} +impl _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE { + pub const NVAPI_GSYNC_MULTIPLY_MODE: _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE = + _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE(1); +} +impl _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE { + pub const NVAPI_GSYNC_DIVIDE_MODE: _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE = + _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE as NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_CONTROL_PARAMS_V2 { + pub version: NvU32, + pub polarity: NVAPI_GSYNC_POLARITY, + pub vmode: NVAPI_GSYNC_VIDEO_MODE, + pub interval: NvU32, + pub source: NVAPI_GSYNC_SYNC_SOURCE, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub syncSkew: NV_GSYNC_DELAY, + pub startupDelay: NV_GSYNC_DELAY, + pub multiplyDivideMode: NVAPI_GSYNC_MULTIPLY_DIVIDE_MODE, + pub multiplyDivideValue: NvU8, +} +impl _NV_GSYNC_CONTROL_PARAMS_V2 { + #[inline] + pub fn interlaceMode(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_interlaceMode(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn syncSourceIsOutput(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_syncSourceIsOutput(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + interlaceMode: NvU32, + syncSourceIsOutput: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let interlaceMode: u32 = unsafe { ::std::mem::transmute(interlaceMode) }; + interlaceMode as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let syncSourceIsOutput: u32 = unsafe { ::std::mem::transmute(syncSourceIsOutput) }; + syncSourceIsOutput as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_CONTROL_PARAMS_V2 = _NV_GSYNC_CONTROL_PARAMS_V2; +pub type NV_GSYNC_CONTROL_PARAMS = NV_GSYNC_CONTROL_PARAMS_V2; +impl _NVAPI_GSYNC_DELAY_TYPE { + pub const NVAPI_GSYNC_DELAY_TYPE_UNKNOWN: _NVAPI_GSYNC_DELAY_TYPE = _NVAPI_GSYNC_DELAY_TYPE(0); +} +impl _NVAPI_GSYNC_DELAY_TYPE { + pub const NVAPI_GSYNC_DELAY_TYPE_SYNC_SKEW: _NVAPI_GSYNC_DELAY_TYPE = + _NVAPI_GSYNC_DELAY_TYPE(1); +} +impl _NVAPI_GSYNC_DELAY_TYPE { + pub const NVAPI_GSYNC_DELAY_TYPE_STARTUP: _NVAPI_GSYNC_DELAY_TYPE = _NVAPI_GSYNC_DELAY_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_DELAY_TYPE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_DELAY_TYPE as NVAPI_GSYNC_DELAY_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_STATUS { + pub version: NvU32, + pub bIsSynced: NvU32, + pub bIsStereoSynced: NvU32, + pub bIsSyncSignalAvailable: NvU32, +} +pub type NV_GSYNC_STATUS = _NV_GSYNC_STATUS; +impl _NVAPI_GSYNC_RJ45_IO { + pub const NVAPI_GSYNC_RJ45_OUTPUT: _NVAPI_GSYNC_RJ45_IO = _NVAPI_GSYNC_RJ45_IO(0); +} +impl _NVAPI_GSYNC_RJ45_IO { + pub const NVAPI_GSYNC_RJ45_INPUT: _NVAPI_GSYNC_RJ45_IO = _NVAPI_GSYNC_RJ45_IO(1); +} +impl _NVAPI_GSYNC_RJ45_IO { + pub const NVAPI_GSYNC_RJ45_UNUSED: _NVAPI_GSYNC_RJ45_IO = _NVAPI_GSYNC_RJ45_IO(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_GSYNC_RJ45_IO(pub ::std::os::raw::c_int); +pub use self::_NVAPI_GSYNC_RJ45_IO as NVAPI_GSYNC_RJ45_IO; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_STATUS_PARAMS_V1 { + pub version: NvU32, + pub refreshRate: NvU32, + pub RJ45_IO: [NVAPI_GSYNC_RJ45_IO; 2usize], + pub RJ45_Ethernet: [NvU32; 2usize], + pub houseSyncIncoming: NvU32, + pub bHouseSync: NvU32, +} +pub type NV_GSYNC_STATUS_PARAMS_V1 = _NV_GSYNC_STATUS_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GSYNC_STATUS_PARAMS_V2 { + pub version: NvU32, + pub refreshRate: NvU32, + pub RJ45_IO: [NVAPI_GSYNC_RJ45_IO; 2usize], + pub RJ45_Ethernet: [NvU32; 2usize], + pub houseSyncIncoming: NvU32, + pub bHouseSync: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_GSYNC_STATUS_PARAMS_V2 { + #[inline] + pub fn bInternalSlave(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bInternalSlave(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 31u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 31u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bInternalSlave: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bInternalSlave: u32 = unsafe { ::std::mem::transmute(bInternalSlave) }; + bInternalSlave as u64 + }); + __bindgen_bitfield_unit.set(1usize, 31u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_GSYNC_STATUS_PARAMS_V2 = _NV_GSYNC_STATUS_PARAMS_V2; +pub type NV_GSYNC_STATUS_PARAMS = NV_GSYNC_STATUS_PARAMS_V2; +impl _NVAPI_D3D11_INSERTWFI_FLAG { + pub const NVAPI_D3D_BEGIN_UAV_OVERLAP_NO_WFI: _NVAPI_D3D11_INSERTWFI_FLAG = + _NVAPI_D3D11_INSERTWFI_FLAG(0); +} +impl _NVAPI_D3D11_INSERTWFI_FLAG { + pub const NVAPI_D3D_BEGIN_UAV_OVERLAP_GFX_WFI: _NVAPI_D3D11_INSERTWFI_FLAG = + _NVAPI_D3D11_INSERTWFI_FLAG(1); +} +impl _NVAPI_D3D11_INSERTWFI_FLAG { + pub const NVAPI_D3D_BEGIN_UAV_OVERLAP_COMP_WFI: _NVAPI_D3D11_INSERTWFI_FLAG = + _NVAPI_D3D11_INSERTWFI_FLAG(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D11_INSERTWFI_FLAG(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D11_INSERTWFI_FLAG as NVAPI_D3D11_INSERTWFI_FLAG; +impl NVAPI_VSYNC_MODE { + pub const NVAPI_VSYNC_DEFAULT: NVAPI_VSYNC_MODE = NVAPI_VSYNC_MODE(0); +} +impl NVAPI_VSYNC_MODE { + pub const NVAPI_VSYNC_OFF: NVAPI_VSYNC_MODE = NVAPI_VSYNC_MODE(1); +} +impl NVAPI_VSYNC_MODE { + pub const NVAPI_VSYNC_ON: NVAPI_VSYNC_MODE = NVAPI_VSYNC_MODE(2); +} +impl NVAPI_VSYNC_MODE { + pub const NVAPI_VSYNC_ADAPTIVE: NVAPI_VSYNC_MODE = NVAPI_VSYNC_MODE(3); +} +impl NVAPI_VSYNC_MODE { + pub const NVAPI_VSYNC_ADAPTIVE_HALF_REFRESH_RATE: NVAPI_VSYNC_MODE = NVAPI_VSYNC_MODE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NVAPI_VSYNC_MODE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_JOIN_PRESENT_BARRIER_PARAMS { + pub dwVersion: NvU32, +} +pub type NV_JOIN_PRESENT_BARRIER_PARAMS = _NV_JOIN_PRESENT_BARRIER_PARAMS; +impl _NV_PRESENT_BARRIER_SYNC_MODE { + pub const PRESENT_BARRIER_NOT_JOINED: _NV_PRESENT_BARRIER_SYNC_MODE = + _NV_PRESENT_BARRIER_SYNC_MODE(0); +} +impl _NV_PRESENT_BARRIER_SYNC_MODE { + pub const PRESENT_BARRIER_SYNC_CLIENT: _NV_PRESENT_BARRIER_SYNC_MODE = + _NV_PRESENT_BARRIER_SYNC_MODE(1); +} +impl _NV_PRESENT_BARRIER_SYNC_MODE { + pub const PRESENT_BARRIER_SYNC_SYSTEM: _NV_PRESENT_BARRIER_SYNC_MODE = + _NV_PRESENT_BARRIER_SYNC_MODE(2); +} +impl _NV_PRESENT_BARRIER_SYNC_MODE { + pub const PRESENT_BARRIER_SYNC_CLUSTER: _NV_PRESENT_BARRIER_SYNC_MODE = + _NV_PRESENT_BARRIER_SYNC_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_PRESENT_BARRIER_SYNC_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_PRESENT_BARRIER_SYNC_MODE as NV_PRESENT_BARRIER_SYNC_MODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PRESENT_BARRIER_FRAME_STATISTICS { + pub dwVersion: NvU32, + pub SyncMode: NV_PRESENT_BARRIER_SYNC_MODE, + pub PresentCount: NvU32, + pub PresentInSyncCount: NvU32, + pub FlipInSyncCount: NvU32, + pub RefreshCount: NvU32, +} +pub type NV_PRESENT_BARRIER_FRAME_STATISTICS = _NV_PRESENT_BARRIER_FRAME_STATISTICS; +impl NVAPI_QUAD_FILLMODE { + pub const NVAPI_QUAD_FILLMODE_DISABLED: NVAPI_QUAD_FILLMODE = NVAPI_QUAD_FILLMODE(0); +} +impl NVAPI_QUAD_FILLMODE { + pub const NVAPI_QUAD_FILLMODE_BBOX: NVAPI_QUAD_FILLMODE = NVAPI_QUAD_FILLMODE(1); +} +impl NVAPI_QUAD_FILLMODE { + pub const NVAPI_QUAD_FILLMODE_FULL_VIEWPORT: NVAPI_QUAD_FILLMODE = NVAPI_QUAD_FILLMODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NVAPI_QUAD_FILLMODE(pub ::std::os::raw::c_int); +#[repr(C)] +pub struct NvAPI_D3D11_RASTERIZER_DESC_EX { + pub FillMode: D3D11_FILL_MODE, + pub CullMode: D3D11_CULL_MODE, + pub FrontCounterClockwise: BOOL, + pub DepthBias: INT, + pub DepthBiasClamp: FLOAT, + pub SlopeScaledDepthBias: FLOAT, + pub DepthClipEnable: BOOL, + pub ScissorEnable: BOOL, + pub MultisampleEnable: BOOL, + pub AntialiasedLineEnable: BOOL, + pub ForcedSampleCount: NvU32, + pub ProgrammableSamplePositionsEnable: bool, + pub InterleavedSamplingEnable: bool, + pub SampleCount: NvU8, + pub SamplePositionsX: [NvU8; 16usize], + pub SamplePositionsY: [NvU8; 16usize], + pub ConservativeRasterEnable: bool, + pub QuadFillMode: NVAPI_QUAD_FILLMODE, + pub PostZCoverageEnable: bool, + pub CoverageToColorEnable: bool, + pub CoverageToColorRTIndex: NvU8, + pub TargetIndepentRasterWithDepth: bool, + pub reserved: [NvU8; 63usize], +} +impl _NVAPI_ANSEL_FEATURE { + pub const NVAPI_ANSEL_FEATURE_UNKNOWN: _NVAPI_ANSEL_FEATURE = _NVAPI_ANSEL_FEATURE(0); +} +impl _NVAPI_ANSEL_FEATURE { + pub const NVAPI_ANSEL_FEATURE_BLACK_AND_WHITE: _NVAPI_ANSEL_FEATURE = _NVAPI_ANSEL_FEATURE(1); +} +impl _NVAPI_ANSEL_FEATURE { + pub const NVAPI_ANSEL_FEATURE_HUDLESS: _NVAPI_ANSEL_FEATURE = _NVAPI_ANSEL_FEATURE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_ANSEL_FEATURE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_ANSEL_FEATURE as NVAPI_ANSEL_FEATURE; +impl _NVAPI_ANSEL_FEATURE_STATE { + pub const NVAPI_ANSEL_FEATURE_STATE_UNKNOWN: _NVAPI_ANSEL_FEATURE_STATE = + _NVAPI_ANSEL_FEATURE_STATE(0); +} +impl _NVAPI_ANSEL_FEATURE_STATE { + pub const NVAPI_ANSEL_FEATURE_STATE_ENABLE: _NVAPI_ANSEL_FEATURE_STATE = + _NVAPI_ANSEL_FEATURE_STATE(1); +} +impl _NVAPI_ANSEL_FEATURE_STATE { + pub const NVAPI_ANSEL_FEATURE_STATE_DISABLE: _NVAPI_ANSEL_FEATURE_STATE = + _NVAPI_ANSEL_FEATURE_STATE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_ANSEL_FEATURE_STATE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_ANSEL_FEATURE_STATE as NVAPI_ANSEL_FEATURE_STATE; +impl _NVAPI_ANSEL_HOTKEY_MODIFIER { + pub const NVAPI_ANSEL_HOTKEY_MODIFIER_UNKNOWN: _NVAPI_ANSEL_HOTKEY_MODIFIER = + _NVAPI_ANSEL_HOTKEY_MODIFIER(0); +} +impl _NVAPI_ANSEL_HOTKEY_MODIFIER { + pub const NVAPI_ANSEL_HOTKEY_MODIFIER_CTRL: _NVAPI_ANSEL_HOTKEY_MODIFIER = + _NVAPI_ANSEL_HOTKEY_MODIFIER(1); +} +impl _NVAPI_ANSEL_HOTKEY_MODIFIER { + pub const NVAPI_ANSEL_HOTKEY_MODIFIER_SHIFT: _NVAPI_ANSEL_HOTKEY_MODIFIER = + _NVAPI_ANSEL_HOTKEY_MODIFIER(2); +} +impl _NVAPI_ANSEL_HOTKEY_MODIFIER { + pub const NVAPI_ANSEL_HOTKEY_MODIFIER_ALT: _NVAPI_ANSEL_HOTKEY_MODIFIER = + _NVAPI_ANSEL_HOTKEY_MODIFIER(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_ANSEL_HOTKEY_MODIFIER(pub ::std::os::raw::c_int); +pub use self::_NVAPI_ANSEL_HOTKEY_MODIFIER as NVAPI_ANSEL_HOTKEY_MODIFIER; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_ANSEL_FEATURE_CONFIGURATION_STRUCT { + pub featureId: NVAPI_ANSEL_FEATURE, + pub featureState: NVAPI_ANSEL_FEATURE_STATE, + pub hotkey: UINT, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_ANSEL_CONFIGURATION_STRUCT_V1 { + pub version: NvU32, + pub hotkeyModifier: NVAPI_ANSEL_HOTKEY_MODIFIER, + pub keyEnable: UINT, + pub numAnselFeatures: UINT, + pub pAnselFeatures: *mut NVAPI_ANSEL_FEATURE_CONFIGURATION_STRUCT, +} +pub type NVAPI_ANSEL_CONFIGURATION_STRUCT = NVAPI_ANSEL_CONFIGURATION_STRUCT_V1; +impl _NV_D3D11_FEATURE { + pub const NV_D3D11_FEATURE_RASTERIZER: _NV_D3D11_FEATURE = _NV_D3D11_FEATURE(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_D3D11_FEATURE(pub ::std::os::raw::c_int); +pub use self::_NV_D3D11_FEATURE as NV_D3D11_FEATURE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D11_FEATURE_DATA_RASTERIZER_SUPPORT { + pub TargetIndependentRasterWithDepth: BOOL, + pub ProgrammableSamplePositions: BOOL, + pub InterleavedSampling: BOOL, + pub ConservativeRaster: BOOL, + pub PostZCoverage: BOOL, + pub CoverageToColor: BOOL, +} +pub type NV_D3D11_FEATURE_DATA_RASTERIZER_SUPPORT = _NV_D3D11_FEATURE_DATA_RASTERIZER_SUPPORT; +impl _NV_RESOLVE_MODE { + pub const NV_RESOLVE_MODE_SAMPLE_0: _NV_RESOLVE_MODE = _NV_RESOLVE_MODE(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_RESOLVE_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_RESOLVE_MODE as NV_RESOLVE_MODE; +pub type NvAPI_D3D11_SWIZZLE_MODE = UINT; +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_POS_X: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(0); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_NEG_X: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(1); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_POS_Y: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(2); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_NEG_Y: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(3); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_POS_Z: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(4); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_NEG_Z: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(5); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_POS_W: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(6); +} +impl _NV_SWIZZLE_MODE { + pub const NV_SWIZZLE_NEG_W: _NV_SWIZZLE_MODE = _NV_SWIZZLE_MODE(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_SWIZZLE_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_SWIZZLE_MODE as NV_SWIZZLE_MODE; +impl _NV_SWIZZLE_OFFSET { + pub const NV_SWIZZLE_OFFSET_X: _NV_SWIZZLE_OFFSET = _NV_SWIZZLE_OFFSET(0); +} +impl _NV_SWIZZLE_OFFSET { + pub const NV_SWIZZLE_OFFSET_Y: _NV_SWIZZLE_OFFSET = _NV_SWIZZLE_OFFSET(4); +} +impl _NV_SWIZZLE_OFFSET { + pub const NV_SWIZZLE_OFFSET_Z: _NV_SWIZZLE_OFFSET = _NV_SWIZZLE_OFFSET(8); +} +impl _NV_SWIZZLE_OFFSET { + pub const NV_SWIZZLE_OFFSET_W: _NV_SWIZZLE_OFFSET = _NV_SWIZZLE_OFFSET(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_SWIZZLE_OFFSET(pub ::std::os::raw::c_int); +pub use self::_NV_SWIZZLE_OFFSET as NV_SWIZZLE_OFFSET; +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_NONE_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(0); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_X_RIGHT_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(1); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_VIEWPORT_MASK_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(2); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_XYZW_RIGHT_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(3); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_VIEWPORT_MASK_2_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(4); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_POSITION_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(5); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_CLIP_DISTANCE_0_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(6); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_CLIP_DISTANCE_1_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(7); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_CULL_DISTANCE_0_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(8); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_CULL_DISTANCE_1_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(9); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_GENERIC_ATTRIBUTE_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(10); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_PACKED_EYE_INDEX_SEMANTIC: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(17); +} +impl NV_CUSTOM_SEMANTIC_TYPE { + pub const NV_CUSTOM_SEMANTIC_MAX: NV_CUSTOM_SEMANTIC_TYPE = NV_CUSTOM_SEMANTIC_TYPE(32); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_CUSTOM_SEMANTIC_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_CUSTOM_SEMANTIC { + pub version: UINT, + pub NVCustomSemanticType: NV_CUSTOM_SEMANTIC_TYPE, + pub NVCustomSemanticNameString: NvAPI_LongString, + pub RegisterSpecified: BOOL, + pub RegisterNum: NvU32, + pub RegisterMask: NvU32, + pub Reserved: NvU32, +} +pub type NV_CUSTOM_SEMANTIC = _NV_CUSTOM_SEMANTIC; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_GEOMETRY_SHADER_EX_V5 { + pub version: UINT, + pub UseViewportMask: BOOL, + pub OffsetRtIndexByVpIndex: BOOL, + pub ForceFastGS: BOOL, + pub DontUseViewportOrder: BOOL, + pub UseAttributeSkipMask: BOOL, + pub UseCoordinateSwizzle: BOOL, + pub pCoordinateSwizzling: *mut NvAPI_D3D11_SWIZZLE_MODE, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub ConvertToFastGS: BOOL, + pub UseSpecificShaderExt: BOOL, +} +pub type NvAPI_D3D11_CREATE_GEOMETRY_SHADER_EX = NvAPI_D3D11_CREATE_GEOMETRY_SHADER_EX_V5; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_VERTEX_SHADER_EX_V1 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_VERTEX_SHADER_EX_V2 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_VERTEX_SHADER_EX_V3 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, + pub UseSpecificShaderExt: BOOL, +} +pub type NvAPI_D3D11_CREATE_VERTEX_SHADER_EX = NvAPI_D3D11_CREATE_VERTEX_SHADER_EX_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_HULL_SHADER_EX_V1 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_HULL_SHADER_EX_V2 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, + pub UseSpecificShaderExt: BOOL, +} +pub type NvAPI_D3D11_CREATE_HULL_SHADER_EX = NvAPI_D3D11_CREATE_HULL_SHADER_EX_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_DOMAIN_SHADER_EX_V1 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_DOMAIN_SHADER_EX_V2 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_DOMAIN_SHADER_EX_V3 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, + pub UseSpecificShaderExt: BOOL, +} +pub type NvAPI_D3D11_CREATE_DOMAIN_SHADER_EX = NvAPI_D3D11_CREATE_DOMAIN_SHADER_EX_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_PIXEL_SHADER_EX_V1 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_PIXEL_SHADER_EX_V2 { + pub version: UINT, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub __bindgen_padding_0: u32, +} +impl NvAPI_D3D11_CREATE_PIXEL_SHADER_EX_V2 { + #[inline] + pub fn bEnableSuperSamplingPredicationForVRS(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bEnableSuperSamplingPredicationForVRS(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bEnableSuperSamplingPredicationForVRSAllAttributes(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bEnableSuperSamplingPredicationForVRSAllAttributes(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bEnableSuperSamplingPredicationForVRS: NvU32, + bEnableSuperSamplingPredicationForVRSAllAttributes: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bEnableSuperSamplingPredicationForVRS: u32 = + unsafe { ::std::mem::transmute(bEnableSuperSamplingPredicationForVRS) }; + bEnableSuperSamplingPredicationForVRS as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bEnableSuperSamplingPredicationForVRSAllAttributes: u32 = unsafe { + ::std::mem::transmute(bEnableSuperSamplingPredicationForVRSAllAttributes) + }; + bEnableSuperSamplingPredicationForVRSAllAttributes as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NvAPI_D3D11_CREATE_PIXEL_SHADER_EX = NvAPI_D3D11_CREATE_PIXEL_SHADER_EX_V2; +impl _NV_FASTGS_FLAGS { + pub const NV_FASTGS_USE_VIEWPORT_MASK: _NV_FASTGS_FLAGS = _NV_FASTGS_FLAGS(1); +} +impl _NV_FASTGS_FLAGS { + pub const NV_FASTGS_OFFSET_RT_INDEX_BY_VP_INDEX: _NV_FASTGS_FLAGS = _NV_FASTGS_FLAGS(2); +} +impl _NV_FASTGS_FLAGS { + pub const NV_FASTGS_STRICT_API_ORDER: _NV_FASTGS_FLAGS = _NV_FASTGS_FLAGS(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_FASTGS_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NV_FASTGS_FLAGS as NV_FASTGS_FLAGS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvAPI_D3D11_CREATE_FASTGS_EXPLICIT_DESC_V1 { + pub version: NvU32, + pub flags: NvU32, + pub pCoordinateSwizzling: *mut NvAPI_D3D11_SWIZZLE_MODE, +} +pub type NvAPI_D3D11_CREATE_FASTGS_EXPLICIT_DESC = NvAPI_D3D11_CREATE_FASTGS_EXPLICIT_DESC_V1; +impl _NV_PSO_EXTENSION { + pub const NV_PSO_RASTER_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(0); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_REQUEST_FASTGS_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(1); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_GEOMETRY_SHADER_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(2); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_ENABLE_DEPTH_BOUND_TEST_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(3); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_EXPLICIT_FASTGS_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(4); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_SET_SHADER_EXTNENSION_SLOT_AND_SPACE: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(5); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_SET_SHADER_EXTENSION_SLOT_AND_SPACE: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(5); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_VERTEX_SHADER_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(6); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_DOMAIN_SHADER_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(7); +} +impl _NV_PSO_EXTENSION { + pub const NV_PSO_HULL_SHADER_EXTENSION: _NV_PSO_EXTENSION = _NV_PSO_EXTENSION(9); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_PSO_EXTENSION(pub ::std::os::raw::c_int); +pub use self::_NV_PSO_EXTENSION as NV_PSO_EXTENSION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_EXTENSION_DESC_V1 { + pub baseVersion: NvU32, + pub psoExtension: NV_PSO_EXTENSION, +} +pub type NVAPI_D3D12_PSO_EXTENSION_DESC = NVAPI_D3D12_PSO_EXTENSION_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_RASTERIZER_STATE_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub ProgrammableSamplePositionsEnable: bool, + pub InterleavedSamplingEnable: bool, + pub SampleCount: NvU8, + pub SamplePositionsX: [NvU8; 16usize], + pub SamplePositionsY: [NvU8; 16usize], + pub QuadFillMode: NVAPI_QUAD_FILLMODE, + pub PostZCoverageEnable: bool, + pub CoverageToColorEnable: bool, + pub CoverageToColorRTIndex: NvU8, + pub TargetIndepentRasterWithDepth: bool, + pub ForcedSampleCount: NvU8, + pub reserved: [NvU8; 62usize], +} +pub type NVAPI_D3D12_PSO_RASTERIZER_STATE_DESC = NVAPI_D3D12_PSO_RASTERIZER_STATE_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_CREATE_FASTGS_EXPLICIT_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub flags: NvU32, + pub pCoordinateSwizzling: *mut NvAPI_D3D11_SWIZZLE_MODE, +} +pub type NVAPI_D3D12_PSO_CREATE_FASTGS_EXPLICIT_DESC = + NVAPI_D3D12_PSO_CREATE_FASTGS_EXPLICIT_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_REQUEST_FAST_GEOMETRY_SHADER_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, +} +pub type NVAPI_D3D12_PSO_REQUEST_FAST_GEOMETRY_SHADER_DESC = + NVAPI_D3D12_PSO_REQUEST_FAST_GEOMETRY_SHADER_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_GEOMETRY_SHADER_DESC_V5 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub UseViewportMask: BOOL, + pub OffsetRtIndexByVpIndex: BOOL, + pub ForceFastGS: BOOL, + pub DontUseViewportOrder: BOOL, + pub UseAttributeSkipMask: BOOL, + pub UseCoordinateSwizzle: BOOL, + pub pCoordinateSwizzling: *mut NvAPI_D3D11_SWIZZLE_MODE, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub ConvertToFastGS: BOOL, + pub UseSpecificShaderExt: BOOL, +} +pub type NVAPI_D3D12_PSO_GEOMETRY_SHADER_DESC = NVAPI_D3D12_PSO_GEOMETRY_SHADER_DESC_V5; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V2 { + pub _base: NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V1, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V3 { + pub _base: NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V2, + pub UseSpecificShaderExt: BOOL, +} +pub type NVAPI_D3D12_PSO_VERTEX_SHADER_DESC = NVAPI_D3D12_PSO_VERTEX_SHADER_DESC_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_HULL_SHADER_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_HULL_SHADER_DESC_V2 { + pub _base: NVAPI_D3D12_PSO_HULL_SHADER_DESC_V1, + pub UseSpecificShaderExt: BOOL, +} +pub type NVAPI_D3D12_PSO_HULL_SHADER_DESC = NVAPI_D3D12_PSO_HULL_SHADER_DESC_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub NumCustomSemantics: NvU32, + pub pCustomSemantics: *mut NV_CUSTOM_SEMANTIC, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V2 { + pub _base: NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V1, + pub UseWithFastGS: BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V3 { + pub _base: NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V2, + pub UseSpecificShaderExt: BOOL, +} +pub type NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC = NVAPI_D3D12_PSO_DOMAIN_SHADER_DESC_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_ENABLE_DEPTH_BOUND_TEST_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub EnableDBT: bool, +} +pub type NVAPI_D3D12_PSO_ENABLE_DEPTH_BOUND_TEST_DESC = + NVAPI_D3D12_PSO_ENABLE_DEPTH_BOUND_TEST_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC_V1 { + pub _base: NVAPI_D3D12_PSO_EXTENSION_DESC, + pub version: NvU32, + pub uavSlot: NvU32, + pub registerSpace: NvU32, +} +pub type NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC = + NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC_V1; +impl _NV_COMPUTE_SHADER_DERIVATIVES { + pub const NV_COMPUTE_SHADER_DERIVATIVE_NONE: _NV_COMPUTE_SHADER_DERIVATIVES = + _NV_COMPUTE_SHADER_DERIVATIVES(0); +} +impl _NV_COMPUTE_SHADER_DERIVATIVES { + pub const NV_COMPUTE_SHADER_DERIVATIVE_GROUP_LINEAR: _NV_COMPUTE_SHADER_DERIVATIVES = + _NV_COMPUTE_SHADER_DERIVATIVES(1); +} +impl _NV_COMPUTE_SHADER_DERIVATIVES { + pub const NV_COMPUTE_SHADER_DERIVATIVE_GROUP_QUADS: _NV_COMPUTE_SHADER_DERIVATIVES = + _NV_COMPUTE_SHADER_DERIVATIVES(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_COMPUTE_SHADER_DERIVATIVES(pub ::std::os::raw::c_int); +pub use self::_NV_COMPUTE_SHADER_DERIVATIVES as NV_COMPUTE_SHADER_DERIVATIVES; +impl NV_D3D12_HEAP_FLAGS { + pub const NV_D3D12_HEAP_FLAG_NONE: NV_D3D12_HEAP_FLAGS = NV_D3D12_HEAP_FLAGS(0); +} +impl NV_D3D12_HEAP_FLAGS { + pub const NV_D3D12_HEAP_FLAG_CPUVISIBLE_VIDMEM: NV_D3D12_HEAP_FLAGS = NV_D3D12_HEAP_FLAGS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_D3D12_HEAP_FLAGS(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_HEAP_PARAMS_V1 { + pub version: NvU32, + pub NVHeapFlags: NV_D3D12_HEAP_FLAGS, +} +pub type NV_HEAP_PARAMS_V1 = _NV_HEAP_PARAMS_V1; +pub type NV_HEAP_PARAMS = NV_HEAP_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_UAV_INFO_V1 { + pub version: NvU32, + pub surfaceHandle: NvU32, + pub gpuVAStart: NvU64, + pub gpuVASize: NvU64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVAPI_UAV_INFO_V2 { + pub version: NvU32, + pub surfaceHandle: NvU32, + pub gpuVAStart: NvU64, + pub gpuVASize: NvU64, + pub outFlags: NvU64, +} +pub type NVAPI_UAV_INFO = NVAPI_UAV_INFO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_GET_GPU_VIRTUAL_ADDRESS_V1 { + pub version: NvU32, + pub hResource: NVDX_ObjectHandle, + pub gpuVAStart: NvU64, + pub gpuVASize: NvU64, +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_NONE: NV_D3D_GRAPHICS_STATES = NV_D3D_GRAPHICS_STATES(0); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_IA_VERTEX_BUFFERS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(1); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_IA_INDEX_BUFFER: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(2); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_IA_PRIMITIVE_TOPOLOGY: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(4); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_DESCRIPTOR_HEAP: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(8); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_GRAPHICS_ROOT_SIGNATURE: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(16); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_COMPUTE_ROOT_SIGNATURE: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(32); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_RS_VIEWPORTS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(64); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_RS_SCISSOR_RECTS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(128); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_PREDICATION: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(256); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_OM_RENDER_TARGETS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(512); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_OM_STENCIL_REF: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(1024); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_OM_BLEND_FACTOR: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(2048); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_PIPELINE_STATE: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(4096); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_SO_TARGETS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(8192); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_OM_DEPTH_BOUNDS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(16384); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_SAMPLE_POSITIONS: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(32768); +} +impl NV_D3D_GRAPHICS_STATES { + pub const NV_D3D_GRAPHICS_STATE_VIEW_INSTANCE_MASK: NV_D3D_GRAPHICS_STATES = + NV_D3D_GRAPHICS_STATES(65536); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_D3D_GRAPHICS_STATES(pub ::std::os::raw::c_int); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NVAPI_META_COMMAND_DESC { + pub Id: GUID, + pub Name: LPCWSTR, + pub InitializationDirtyState: NV_D3D_GRAPHICS_STATES, + pub ExecutionDirtyState: NV_D3D_GRAPHICS_STATES, +} +pub type NV_META_COMMAND_BOOL = NvU64; +impl NV_META_COMMAND_TENSOR_DATA_TYPE { + pub const NV_META_COMMAND_TENSOR_DATA_TYPE_FLOAT32: NV_META_COMMAND_TENSOR_DATA_TYPE = + NV_META_COMMAND_TENSOR_DATA_TYPE(0); +} +impl NV_META_COMMAND_TENSOR_DATA_TYPE { + pub const NV_META_COMMAND_TENSOR_DATA_TYPE_FLOAT16: NV_META_COMMAND_TENSOR_DATA_TYPE = + NV_META_COMMAND_TENSOR_DATA_TYPE(1); +} +impl NV_META_COMMAND_TENSOR_DATA_TYPE { + pub const NV_META_COMMAND_TENSOR_DATA_TYPE_UINT32: NV_META_COMMAND_TENSOR_DATA_TYPE = + NV_META_COMMAND_TENSOR_DATA_TYPE(2); +} +impl NV_META_COMMAND_TENSOR_DATA_TYPE { + pub const NV_META_COMMAND_TENSOR_DATA_TYPE_COUNT: NV_META_COMMAND_TENSOR_DATA_TYPE = + NV_META_COMMAND_TENSOR_DATA_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_TENSOR_DATA_TYPE(pub NvU64); +impl NV_META_COMMAND_TENSOR_LAYOUT { + pub const NV_META_COMMAND_TENSOR_LAYOUT_UNKNOWN: NV_META_COMMAND_TENSOR_LAYOUT = + NV_META_COMMAND_TENSOR_LAYOUT(0); +} +impl NV_META_COMMAND_TENSOR_LAYOUT { + pub const NV_META_COMMAND_TENSOR_LAYOUT_STANDARD: NV_META_COMMAND_TENSOR_LAYOUT = + NV_META_COMMAND_TENSOR_LAYOUT(1); +} +impl NV_META_COMMAND_TENSOR_LAYOUT { + pub const NV_META_COMMAND_TENSOR_LAYOUT_COUNT: NV_META_COMMAND_TENSOR_LAYOUT = + NV_META_COMMAND_TENSOR_LAYOUT(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_TENSOR_LAYOUT(pub NvU64); +impl NV_META_COMMAND_TENSOR_FLAGS { + pub const NV_META_COMMAND_TENSOR_FLAG_NONE: NV_META_COMMAND_TENSOR_FLAGS = + NV_META_COMMAND_TENSOR_FLAGS(0); +} +impl NV_META_COMMAND_TENSOR_FLAGS { + pub const NV_META_COMMAND_TENSOR_FLAG_DATA_STATIC: NV_META_COMMAND_TENSOR_FLAGS = + NV_META_COMMAND_TENSOR_FLAGS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_TENSOR_FLAGS(pub NvU64); +impl NV_META_COMMAND_PRECISION { + pub const NV_META_COMMAND_PRECISION_FLOAT32: NV_META_COMMAND_PRECISION = + NV_META_COMMAND_PRECISION(0); +} +impl NV_META_COMMAND_PRECISION { + pub const NV_META_COMMAND_PRECISION_FLOAT16: NV_META_COMMAND_PRECISION = + NV_META_COMMAND_PRECISION(1); +} +impl NV_META_COMMAND_PRECISION { + pub const NV_META_COMMAND_PRECISION_MUL_FLOAT16_ADD_FLOAT32: NV_META_COMMAND_PRECISION = + NV_META_COMMAND_PRECISION(2); +} +impl NV_META_COMMAND_PRECISION { + pub const NV_META_COMMAND_PRECISION_COUNT: NV_META_COMMAND_PRECISION = + NV_META_COMMAND_PRECISION(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_PRECISION(pub NvU64); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_TENSOR_DESC { + pub DataType: NV_META_COMMAND_TENSOR_DATA_TYPE, + pub Layout: NV_META_COMMAND_TENSOR_LAYOUT, + pub Flags: NV_META_COMMAND_TENSOR_FLAGS, + pub DimensionCount: NvU64, + pub Size: [NvU64; 5usize], + pub Stride: [NvU64; 5usize], +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_ELU: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(0); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_HARDMAX: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(1); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_HARD_SIGMOID: + NV_META_COMMAND_ACTIVATION_FUNCTION = NV_META_COMMAND_ACTIVATION_FUNCTION(2); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_IDENTITY: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(3); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_LEAKY_RELU: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(4); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_LINEAR: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(5); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_LOG_SOFTMAX: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(6); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_PARAMETERIZED_RELU: + NV_META_COMMAND_ACTIVATION_FUNCTION = NV_META_COMMAND_ACTIVATION_FUNCTION(7); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_PARAMETRIC_SOFTPLUS: + NV_META_COMMAND_ACTIVATION_FUNCTION = NV_META_COMMAND_ACTIVATION_FUNCTION(8); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_RELU: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(9); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SCALED_ELU: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(10); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SCALED_TANH: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(11); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SIGMOID: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(12); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SOFTMAX: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(13); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SOFTPLUS: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(14); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_SOFTSIGN: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(15); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_TANH: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(16); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_THRESHOLDED_RELU: + NV_META_COMMAND_ACTIVATION_FUNCTION = NV_META_COMMAND_ACTIVATION_FUNCTION(17); +} +impl NV_META_COMMAND_ACTIVATION_FUNCTION { + pub const NV_META_COMMAND_ACTIVATION_FUNCTION_COUNT: NV_META_COMMAND_ACTIVATION_FUNCTION = + NV_META_COMMAND_ACTIVATION_FUNCTION(18); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_ACTIVATION_FUNCTION(pub NvU64); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_ACTIVATION_DESC { + pub Function: NV_META_COMMAND_ACTIVATION_FUNCTION, + pub Params: [f32; 2usize], +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_OPTIONAL_TENSOR_DESC { + pub _base: NV_META_COMMAND_TENSOR_DESC, + pub IsNull: NV_META_COMMAND_BOOL, +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_OPTIONAL_ACTIVATION_DESC { + pub _base: NV_META_COMMAND_ACTIVATION_DESC, + pub IsNull: NV_META_COMMAND_BOOL, +} +impl NV_META_COMMAND_PADDING_MODE { + pub const NV_META_COMMAND_PADDING_ZEROS: NV_META_COMMAND_PADDING_MODE = + NV_META_COMMAND_PADDING_MODE(0); +} +impl NV_META_COMMAND_PADDING_MODE { + pub const NV_META_COMMAND_PADDING_MIRROR: NV_META_COMMAND_PADDING_MODE = + NV_META_COMMAND_PADDING_MODE(1); +} +impl NV_META_COMMAND_PADDING_MODE { + pub const NV_META_COMMAND_PADDING_CLAMP: NV_META_COMMAND_PADDING_MODE = + NV_META_COMMAND_PADDING_MODE(2); +} +impl NV_META_COMMAND_PADDING_MODE { + pub const NV_META_COMMAND_PADDING_CONSTANT: NV_META_COMMAND_PADDING_MODE = + NV_META_COMMAND_PADDING_MODE(3); +} +impl NV_META_COMMAND_PADDING_MODE { + pub const NV_META_COMMAND_PADDING_COUNT: NV_META_COMMAND_PADDING_MODE = + NV_META_COMMAND_PADDING_MODE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_PADDING_MODE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_PADDING_DESC { + pub Mode: NV_META_COMMAND_PADDING_MODE, + pub ConstantPadVal: f32, +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_INPUT: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(0); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_OUTPUT: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(1); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_FILTER: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(2); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_WEIGHT: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(2); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_BIAS: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(3); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_MATRIX_A: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(0); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_MATRIX_B: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(2); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_MATRIX_C: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(3); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_PERSISTENT: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(4); +} +impl NV_META_COMMAND_RESOURCE_TYPE { + pub const NV_META_COMMAND_RESOURCE_TYPE_TEMPORARY: NV_META_COMMAND_RESOURCE_TYPE = + NV_META_COMMAND_RESOURCE_TYPE(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_RESOURCE_TYPE(pub ::std::os::raw::c_int); +impl NV_META_COMMAND_CONVOLUTION_DIRECTION { + pub const NV_META_COMMAND_CONVOLUTION_DIRECTION_FORWARD: NV_META_COMMAND_CONVOLUTION_DIRECTION = + NV_META_COMMAND_CONVOLUTION_DIRECTION(0); +} +impl NV_META_COMMAND_CONVOLUTION_DIRECTION { + pub const NV_META_COMMAND_CONVOLUTION_DIRECTION_BACKWARD: + NV_META_COMMAND_CONVOLUTION_DIRECTION = NV_META_COMMAND_CONVOLUTION_DIRECTION(1); +} +impl NV_META_COMMAND_CONVOLUTION_DIRECTION { + pub const NV_META_COMMAND_CONVOLUTION_DIRECTION_COUNT: NV_META_COMMAND_CONVOLUTION_DIRECTION = + NV_META_COMMAND_CONVOLUTION_DIRECTION(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_CONVOLUTION_DIRECTION(pub NvU64); +impl NV_META_COMMAND_CONVOLUTION_MODE { + pub const NV_META_COMMAND_CONVOLUTION_MODE_CONVOLUTION: NV_META_COMMAND_CONVOLUTION_MODE = + NV_META_COMMAND_CONVOLUTION_MODE(0); +} +impl NV_META_COMMAND_CONVOLUTION_MODE { + pub const NV_META_COMMAND_CONVOLUTION_MODE_CROSS_CORRELATION: NV_META_COMMAND_CONVOLUTION_MODE = + NV_META_COMMAND_CONVOLUTION_MODE(1); +} +impl NV_META_COMMAND_CONVOLUTION_MODE { + pub const NV_META_COMMAND_CONVOLUTION_MODE_COUNT: NV_META_COMMAND_CONVOLUTION_MODE = + NV_META_COMMAND_CONVOLUTION_MODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_CONVOLUTION_MODE(pub NvU64); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_CREATE_CONVOLUTION_EX_DESC { + pub DescIn: NV_META_COMMAND_TENSOR_DESC, + pub DescFilter: NV_META_COMMAND_TENSOR_DESC, + pub DescBias: NV_META_COMMAND_OPTIONAL_TENSOR_DESC, + pub DescOut: NV_META_COMMAND_TENSOR_DESC, + pub Mode: NV_META_COMMAND_CONVOLUTION_MODE, + pub Direction: NV_META_COMMAND_CONVOLUTION_DIRECTION, + pub Precision: NV_META_COMMAND_PRECISION, + pub Activation: NV_META_COMMAND_OPTIONAL_ACTIVATION_DESC, + pub Padding: NV_META_COMMAND_PADDING_DESC, + pub PerChannelScaling: NV_META_COMMAND_BOOL, + pub Alpha1: f32, + pub Alpha2: f32, + pub Stride: [NvU64; 3usize], + pub Dilation: [NvU64; 3usize], + pub StartPadding: [NvU64; 3usize], + pub EndPadding: [NvU64; 3usize], + pub DimensionCount: NvU64, + pub GroupCount: NvU64, +} +impl NV_META_COMMAND_CONVOLUTION_POOL_MODE { + pub const NV_META_COMMAND_CONVOLUTION_POOL_MODE_NONE: NV_META_COMMAND_CONVOLUTION_POOL_MODE = + NV_META_COMMAND_CONVOLUTION_POOL_MODE(0); +} +impl NV_META_COMMAND_CONVOLUTION_POOL_MODE { + pub const NV_META_COMMAND_CONVOLUTION_POOL_MODE_REDUCTION_MAX: + NV_META_COMMAND_CONVOLUTION_POOL_MODE = NV_META_COMMAND_CONVOLUTION_POOL_MODE(1); +} +impl NV_META_COMMAND_CONVOLUTION_POOL_MODE { + pub const NV_META_COMMAND_CONVOLUTION_POOL_MODE_REDUCTION_AVG: + NV_META_COMMAND_CONVOLUTION_POOL_MODE = NV_META_COMMAND_CONVOLUTION_POOL_MODE(2); +} +impl NV_META_COMMAND_CONVOLUTION_POOL_MODE { + pub const NV_META_COMMAND_CONVOLUTION_POOL_MODE_REDUCTION_MIN: + NV_META_COMMAND_CONVOLUTION_POOL_MODE = NV_META_COMMAND_CONVOLUTION_POOL_MODE(3); +} +impl NV_META_COMMAND_CONVOLUTION_POOL_MODE { + pub const NV_META_COMMAND_CONVOLUTION_POOL_MODE_COUNT: NV_META_COMMAND_CONVOLUTION_POOL_MODE = + NV_META_COMMAND_CONVOLUTION_POOL_MODE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_CONVOLUTION_POOL_MODE(pub ::std::os::raw::c_int); +impl NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE { + pub const NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE_NONE: + NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE = NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE(0); +} +impl NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE { + pub const NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE_REPLICATE: + NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE = NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE(1); +} +impl NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE { + pub const NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE_BILINEAR: + NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE = NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE(2); +} +impl NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE { + pub const NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE_COUNT: + NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE = NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE(pub ::std::os::raw::c_int); +impl NV_META_COMMAND_CONVOLUTION_SKIP_MODE { + pub const NV_META_COMMAND_CONVOLUTION_SKIP_MODE_NONE: NV_META_COMMAND_CONVOLUTION_SKIP_MODE = + NV_META_COMMAND_CONVOLUTION_SKIP_MODE(0); +} +impl NV_META_COMMAND_CONVOLUTION_SKIP_MODE { + pub const NV_META_COMMAND_CONVOLUTION_SKIP_MODE_ADD: NV_META_COMMAND_CONVOLUTION_SKIP_MODE = + NV_META_COMMAND_CONVOLUTION_SKIP_MODE(1); +} +impl NV_META_COMMAND_CONVOLUTION_SKIP_MODE { + pub const NV_META_COMMAND_CONVOLUTION_SKIP_MODE_CONCAT: NV_META_COMMAND_CONVOLUTION_SKIP_MODE = + NV_META_COMMAND_CONVOLUTION_SKIP_MODE(2); +} +impl NV_META_COMMAND_CONVOLUTION_SKIP_MODE { + pub const NV_META_COMMAND_CONVOLUTION_SKIP_MODE_COUNT: NV_META_COMMAND_CONVOLUTION_SKIP_MODE = + NV_META_COMMAND_CONVOLUTION_SKIP_MODE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_CONVOLUTION_SKIP_MODE(pub ::std::os::raw::c_int); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_CONVOLUTION_FUSE_DESC { + pub PoolMode: NV_META_COMMAND_CONVOLUTION_POOL_MODE, + pub UpsampleMode: NV_META_COMMAND_CONVOLUTION_UPSAMPLE_MODE, + pub SkipMode: NV_META_COMMAND_CONVOLUTION_SKIP_MODE, + pub OutputPrepool: NV_META_COMMAND_BOOL, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_CREATE_CONVOLUTION_EX_FUSED_DESC { + pub _base: NV_META_COMMAND_CREATE_CONVOLUTION_EX_DESC, + pub FuseDesc: NV_META_COMMAND_CONVOLUTION_FUSE_DESC, +} +impl NV_META_COMMAND_MATRIX_TRANSFORM { + pub const NV_META_COMMAND_MATRIX_TRANSFORM_NONE: NV_META_COMMAND_MATRIX_TRANSFORM = + NV_META_COMMAND_MATRIX_TRANSFORM(0); +} +impl NV_META_COMMAND_MATRIX_TRANSFORM { + pub const NV_META_COMMAND_MATRIX_TRANSFORM_TRANSPOSE: NV_META_COMMAND_MATRIX_TRANSFORM = + NV_META_COMMAND_MATRIX_TRANSFORM(1); +} +impl NV_META_COMMAND_MATRIX_TRANSFORM { + pub const NV_META_COMMAND_MATRIX_TRANSFORM_COUNT: NV_META_COMMAND_MATRIX_TRANSFORM = + NV_META_COMMAND_MATRIX_TRANSFORM(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_META_COMMAND_MATRIX_TRANSFORM(pub NvU64); +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_META_COMMAND_CREATE_GEMM_DESC { + pub DescA: NV_META_COMMAND_TENSOR_DESC, + pub DescB: NV_META_COMMAND_TENSOR_DESC, + pub DescC: NV_META_COMMAND_OPTIONAL_TENSOR_DESC, + pub DescOut: NV_META_COMMAND_TENSOR_DESC, + pub Precision: NV_META_COMMAND_PRECISION, + pub TransA: NV_META_COMMAND_MATRIX_TRANSFORM, + pub TransB: NV_META_COMMAND_MATRIX_TRANSFORM, + pub Alpha: f32, + pub Beta: f32, + pub Activation: NV_META_COMMAND_OPTIONAL_ACTIVATION_DESC, +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_D3D11_META_COMMAND_RESOURCE { + pub __bindgen_anon_1: NV_D3D11_META_COMMAND_RESOURCE__bindgen_ty_1, + pub Offset: NvU64, +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub union NV_D3D11_META_COMMAND_RESOURCE__bindgen_ty_1 { + pub ResourceHandle: NVDX_ObjectHandle, + pub unused: NvU64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_D3D11_META_COMMAND_INITIALIZE_CONVOLUTION_EX_DESC { + pub PersistentResource: NV_D3D11_META_COMMAND_RESOURCE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_D3D11_META_COMMAND_EXECUTE_CONVOLUTION_EX_DESC { + pub InputResource: NV_D3D11_META_COMMAND_RESOURCE, + pub FilterResource: NV_D3D11_META_COMMAND_RESOURCE, + pub BiasResource: NV_D3D11_META_COMMAND_RESOURCE, + pub OutputResource: NV_D3D11_META_COMMAND_RESOURCE, + pub Alpha1Resource: NV_D3D11_META_COMMAND_RESOURCE, + pub Alpha2Resource: NV_D3D11_META_COMMAND_RESOURCE, + pub SkipConnectionResource: NV_D3D11_META_COMMAND_RESOURCE, + pub PersistentResource: NV_D3D11_META_COMMAND_RESOURCE, + pub TemporaryResource: NV_D3D11_META_COMMAND_RESOURCE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_D3D11_META_COMMAND_INITIALIZE_GEMM_DESC { + pub PersistentResource: NV_D3D11_META_COMMAND_RESOURCE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_D3D11_META_COMMAND_EXECUTE_GEMM_DESC { + pub AResource: NV_D3D11_META_COMMAND_RESOURCE, + pub BResource: NV_D3D11_META_COMMAND_RESOURCE, + pub CResource: NV_D3D11_META_COMMAND_RESOURCE, + pub OutputResource: NV_D3D11_META_COMMAND_RESOURCE, + pub PersistentResource: NV_D3D11_META_COMMAND_RESOURCE, + pub TemporaryResource: NV_D3D11_META_COMMAND_RESOURCE, +} +#[repr(C, packed(4))] +pub struct NV_D3D12_META_COMMAND_INITIALIZE_CONVOLUTION_EX_DESC { + pub PersistentResource: D3D12_GPU_VIRTUAL_ADDRESS, +} +#[repr(C, packed(4))] +pub struct NV_D3D12_META_COMMAND_EXECUTE_CONVOLUTION_EX_DESC { + pub InputResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub FilterResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub BiasResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub OutputResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub Alpha1Resource: D3D12_GPU_VIRTUAL_ADDRESS, + pub Alpha2Resource: D3D12_GPU_VIRTUAL_ADDRESS, + pub SkipConnectionResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub PersistentResource: D3D12_GPU_VIRTUAL_ADDRESS, + pub TemporaryResource: D3D12_GPU_VIRTUAL_ADDRESS, +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_D3D12_META_COMMAND_INITIALIZE_GEMM_DESC { + pub PersistentResource: NvU64, +} +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +pub struct NV_D3D12_META_COMMAND_EXECUTE_GEMM_DESC { + pub AResource: NvU64, + pub BResource: NvU64, + pub CResource: NvU64, + pub OutputResource: NvU64, + pub PersistentResource: NvU64, + pub TemporaryResource: NvU64, +} +impl NV_D3D12_RESOURCE_FLAGS { + pub const NV_D3D12_RESOURCE_FLAG_NONE: NV_D3D12_RESOURCE_FLAGS = NV_D3D12_RESOURCE_FLAGS(0); +} +impl NV_D3D12_RESOURCE_FLAGS { + pub const NV_D3D12_RESOURCE_FLAG_HTEX: NV_D3D12_RESOURCE_FLAGS = NV_D3D12_RESOURCE_FLAGS(1); +} +impl NV_D3D12_RESOURCE_FLAGS { + pub const NV_D3D12_RESOURCE_FLAG_CPUVISIBLE_VIDMEM: NV_D3D12_RESOURCE_FLAGS = + NV_D3D12_RESOURCE_FLAGS(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_D3D12_RESOURCE_FLAGS(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_RESOURCE_PARAMS_V1 { + pub version: NvU32, + pub NVResourceFlags: NV_D3D12_RESOURCE_FLAGS, +} +pub type NV_RESOURCE_PARAMS_V1 = _NV_RESOURCE_PARAMS_V1; +pub type NV_RESOURCE_PARAMS = NV_RESOURCE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MULTIGPU_CAPS_V1 { + pub multiGPUVersion: NvU32, + pub reserved: NvU32, + pub nTotalGPUs: NvU32, + pub nSLIGPUs: NvU32, + pub videoBridgePresent: NvU32, +} +pub type NV_MULTIGPU_CAPS_V1 = _NV_MULTIGPU_CAPS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MULTIGPU_CAPS_V2 { + pub multiGPUVersion: NvU32, + pub __bindgen_anon_1: _NV_MULTIGPU_CAPS_V2__bindgen_ty_1, + pub nTotalGPUs: NvU32, + pub nSLIGPUs: NvU32, + pub videoBridgePresent: NvU32, + pub NvLinkPresent: NvU32, + pub fastNvLinkReads: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_MULTIGPU_CAPS_V2__bindgen_ty_1 { + pub reserved: NvU32, + pub version: NvU32, +} +pub type NV_MULTIGPU_CAPS_V2 = _NV_MULTIGPU_CAPS_V2; +pub type NV_MULTIGPU_CAPS = NV_MULTIGPU_CAPS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V1 { + pub version: NvU32, + pub bSinglePassStereoSupported: NvU32, +} +pub type NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V1 = + _NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V2 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V2 { + #[inline] + pub fn bSinglePassStereoSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bSinglePassStereoSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bSinglePassStereoXYZWSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bSinglePassStereoXYZWSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bSinglePassStereoSupported: NvU32, + bSinglePassStereoXYZWSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bSinglePassStereoSupported: u32 = + unsafe { ::std::mem::transmute(bSinglePassStereoSupported) }; + bSinglePassStereoSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bSinglePassStereoXYZWSupported: u32 = + unsafe { ::std::mem::transmute(bSinglePassStereoXYZWSupported) }; + bSinglePassStereoXYZWSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V2 = + _NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V2; +pub type NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS = NV_QUERY_SINGLE_PASS_STEREO_SUPPORT_PARAMS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_MULTIVIEW_SUPPORT_PARAMS_V1 { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_QUERY_MULTIVIEW_SUPPORT_PARAMS_V1 { + #[inline] + pub fn bMultiViewSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bMultiViewSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bSinglePassStereoSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bSinglePassStereoSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bSinglePassStereoXYZWSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bSinglePassStereoXYZWSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 29u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 29u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bMultiViewSupported: NvU32, + bSinglePassStereoSupported: NvU32, + bSinglePassStereoXYZWSupported: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bMultiViewSupported: u32 = unsafe { ::std::mem::transmute(bMultiViewSupported) }; + bMultiViewSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bSinglePassStereoSupported: u32 = + unsafe { ::std::mem::transmute(bSinglePassStereoSupported) }; + bSinglePassStereoSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bSinglePassStereoXYZWSupported: u32 = + unsafe { ::std::mem::transmute(bSinglePassStereoXYZWSupported) }; + bSinglePassStereoXYZWSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 29u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_QUERY_MULTIVIEW_SUPPORT_PARAMS_V1 = _NV_QUERY_MULTIVIEW_SUPPORT_PARAMS_V1; +pub type NV_QUERY_MULTIVIEW_SUPPORT_PARAMS = NV_QUERY_MULTIVIEW_SUPPORT_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MULTIVIEW_PARAMS_V1 { + pub version: NvU32, + pub numViews: NvU32, + pub renderTargetIndexOffset: [NvU32; 4usize], + pub independentViewportMaskEnable: NvU8, +} +pub type NV_MULTIVIEW_PARAMS_V1 = _NV_MULTIVIEW_PARAMS_V1; +pub type NV_MULTIVIEW_PARAMS = NV_MULTIVIEW_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_MODIFIED_W_SUPPORT_PARAMS { + pub version: NvU32, + pub bModifiedWSupported: NvU32, +} +pub type NV_QUERY_MODIFIED_W_SUPPORT_PARAMS_V1 = _NV_QUERY_MODIFIED_W_SUPPORT_PARAMS; +pub type NV_QUERY_MODIFIED_W_SUPPORT_PARAMS = NV_QUERY_MODIFIED_W_SUPPORT_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MODIFIED_W_COEFFICIENTS { + pub fA: f32, + pub fB: f32, + pub fAReserved: f32, + pub fBReserved: f32, + pub fReserved: [f32; 2usize], +} +pub type NV_MODIFIED_W_COEFFICIENTS = _NV_MODIFIED_W_COEFFICIENTS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MODIFIED_W_PARAMS { + pub version: NvU32, + pub numEntries: NvU32, + pub modifiedWCoefficients: [NV_MODIFIED_W_COEFFICIENTS; 16usize], + pub id: NvU32, + pub reserved: [NvU32; 16usize], +} +pub type NV_MODIFIED_W_PARAMS_V1 = _NV_MODIFIED_W_PARAMS; +pub type NV_MODIFIED_W_PARAMS = NV_MODIFIED_W_PARAMS_V1; +#[repr(C)] +pub struct ID3DLateLatchObject_V1__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3DLateLatchObject_V1 { + pub vtable_: *const ID3DLateLatchObject_V1__bindgen_vtable, +} +pub type ID3DLateLatchObject = ID3DLateLatchObject_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D_LATELATCH_OBJECT_DESC_V1 { + pub version: NvU32, + pub numBuffers: NvU32, + pub ppBufferDesc: *mut *mut D3D11_BUFFER_DESC, + pub ppD3DLateLatchObject: *mut *mut ID3DLateLatchObject, +} +pub type NV_D3D_LATELATCH_OBJECT_DESC_V1 = _NV_D3D_LATELATCH_OBJECT_DESC_V1; +pub type NV_D3D_LATELATCH_OBJECT_DESC = NV_D3D_LATELATCH_OBJECT_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_LATELATCH_SUPPORT_PARAMS { + pub version: NvU32, + pub bLateLatchSupported: NvU32, +} +pub type NV_QUERY_LATELATCH_SUPPORT_PARAMS_V1 = _NV_QUERY_LATELATCH_SUPPORT_PARAMS; +pub type NV_QUERY_LATELATCH_SUPPORT_PARAMS = NV_QUERY_LATELATCH_SUPPORT_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D12_MOSAIC_GETCOMPANIONALLOCATIONS { + pub version: NvU32, + pub pDevice: *mut ID3D12Device, + pub pSwapChainBuffer: *mut ID3D12Resource, + pub companionBufferCount: NvU32, + pub ppCompanionResources: *mut *mut ID3D12Resource, +} +pub type NV_D3D12_MOSAIC_GETCOMPANIONALLOCATIONS_V1 = _NV_D3D12_MOSAIC_GETCOMPANIONALLOCATIONS; +pub type NV_D3D12_MOSAIC_GETCOMPANIONALLOCATIONS = NV_D3D12_MOSAIC_GETCOMPANIONALLOCATIONS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D12_MOSAIC_GETVIEWPORTANDGPUPARTITIONS { + pub version: NvU32, + pub pDevice: *mut ID3D12Device, + pub pSwapChainBuffer: *mut ID3D12Resource, + pub pPartitionCount: *mut NvU32, + pub pViewport: *mut RECT, + pub pNodeMask: *mut NvU32, +} +pub type NV_D3D12_MOSAIC_GETVIEWPORTANDGPUPARTITIONS_V1 = + _NV_D3D12_MOSAIC_GETVIEWPORTANDGPUPARTITIONS; +pub type NV_D3D12_MOSAIC_GETVIEWPORTANDGPUPARTITIONS = + NV_D3D12_MOSAIC_GETVIEWPORTANDGPUPARTITIONS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D1x_GRAPHICS_CAPS_V1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub reserved: [NvU32; 7usize], +} +impl _NV_D3D1x_GRAPHICS_CAPS_V1 { + #[inline] + pub fn bExclusiveScissorRectsSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bExclusiveScissorRectsSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bVariablePixelRateShadingSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bVariablePixelRateShadingSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reservedBits(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reservedBits(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bExclusiveScissorRectsSupported: NvU32, + bVariablePixelRateShadingSupported: NvU32, + reservedBits: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bExclusiveScissorRectsSupported: u32 = + unsafe { ::std::mem::transmute(bExclusiveScissorRectsSupported) }; + bExclusiveScissorRectsSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bVariablePixelRateShadingSupported: u32 = + unsafe { ::std::mem::transmute(bVariablePixelRateShadingSupported) }; + bVariablePixelRateShadingSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reservedBits: u32 = unsafe { ::std::mem::transmute(reservedBits) }; + reservedBits as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_D3D1x_GRAPHICS_CAPS_V1 = _NV_D3D1x_GRAPHICS_CAPS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D1x_GRAPHICS_CAPS_V2 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub majorSMVersion: NvU16, + pub minorSMVersion: NvU16, + pub reserved: [NvU32; 14usize], +} +impl _NV_D3D1x_GRAPHICS_CAPS_V2 { + #[inline] + pub fn bExclusiveScissorRectsSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bExclusiveScissorRectsSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bVariablePixelRateShadingSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bVariablePixelRateShadingSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bFastUAVClearSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bFastUAVClearSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn reservedBits(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 29u8) as u32) } + } + #[inline] + pub fn set_reservedBits(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 29u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bExclusiveScissorRectsSupported: NvU32, + bVariablePixelRateShadingSupported: NvU32, + bFastUAVClearSupported: NvU32, + reservedBits: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bExclusiveScissorRectsSupported: u32 = + unsafe { ::std::mem::transmute(bExclusiveScissorRectsSupported) }; + bExclusiveScissorRectsSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bVariablePixelRateShadingSupported: u32 = + unsafe { ::std::mem::transmute(bVariablePixelRateShadingSupported) }; + bVariablePixelRateShadingSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bFastUAVClearSupported: u32 = + unsafe { ::std::mem::transmute(bFastUAVClearSupported) }; + bFastUAVClearSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 29u8, { + let reservedBits: u32 = unsafe { ::std::mem::transmute(reservedBits) }; + reservedBits as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_D3D1x_GRAPHICS_CAPS_V2 = _NV_D3D1x_GRAPHICS_CAPS_V2; +pub type NV_D3D1x_GRAPHICS_CAPS = NV_D3D1x_GRAPHICS_CAPS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D12_GRAPHICS_CAPS_V1 { + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub majorSMVersion: NvU16, + pub minorSMVersion: NvU16, + pub reserved: [NvU32; 6usize], +} +impl _NV_D3D12_GRAPHICS_CAPS_V1 { + #[inline] + pub fn bExclusiveScissorRectsSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bExclusiveScissorRectsSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bVariablePixelRateShadingSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bVariablePixelRateShadingSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bFastUAVClearSupported(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bFastUAVClearSupported(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn reservedBits(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 29u8) as u32) } + } + #[inline] + pub fn set_reservedBits(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 29u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bExclusiveScissorRectsSupported: NvU32, + bVariablePixelRateShadingSupported: NvU32, + bFastUAVClearSupported: NvU32, + reservedBits: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bExclusiveScissorRectsSupported: u32 = + unsafe { ::std::mem::transmute(bExclusiveScissorRectsSupported) }; + bExclusiveScissorRectsSupported as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bVariablePixelRateShadingSupported: u32 = + unsafe { ::std::mem::transmute(bVariablePixelRateShadingSupported) }; + bVariablePixelRateShadingSupported as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bFastUAVClearSupported: u32 = + unsafe { ::std::mem::transmute(bFastUAVClearSupported) }; + bFastUAVClearSupported as u64 + }); + __bindgen_bitfield_unit.set(3usize, 29u8, { + let reservedBits: u32 = unsafe { ::std::mem::transmute(reservedBits) }; + reservedBits as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_D3D12_GRAPHICS_CAPS_V1 = _NV_D3D12_GRAPHICS_CAPS_V1; +pub type NV_D3D12_GRAPHICS_CAPS = NV_D3D12_GRAPHICS_CAPS_V1; +#[repr(C)] +pub struct _NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC_V1 { + pub enableExclusiveScissorRect: bool, + pub scissorRect: D3D11_RECT, +} +pub type NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC_V1 = _NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D11_EXCLUSIVE_SCISSOR_RECTS_DESC_V1 { + pub version: NvU32, + pub numRects: NvU32, + pub pRects: *mut NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC_V1, +} +pub type NV_D3D11_EXCLUSIVE_SCISSOR_RECTS_DESC_V1 = _NV_D3D11_EXCLUSIVE_SCISSOR_RECTS_DESC_V1; +pub type NV_D3D11_EXCLUSIVE_SCISSOR_RECTS_DESC = NV_D3D11_EXCLUSIVE_SCISSOR_RECTS_DESC_V1; +pub type NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC = NV_D3D11_EXCLUSIVE_SCISSOR_RECT_DESC_V1; +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X0_CULL_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(0); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X16_PER_RASTER_PIXEL: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(1); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X8_PER_RASTER_PIXEL: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(2); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X4_PER_RASTER_PIXEL: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(3); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X2_PER_RASTER_PIXEL: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(4); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_RASTER_PIXEL: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(5); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_2X1_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(6); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_1X2_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(7); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_2X2_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(8); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_4X2_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(9); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_2X4_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(10); +} +impl NV_PIXEL_SHADING_RATE { + pub const NV_PIXEL_X1_PER_4X4_RASTER_PIXELS: NV_PIXEL_SHADING_RATE = NV_PIXEL_SHADING_RATE(11); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_PIXEL_SHADING_RATE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D11_VIEWPORT_SHADING_RATE_DESC_V1 { + pub enableVariablePixelShadingRate: bool, + pub shadingRateTable: [NV_PIXEL_SHADING_RATE; 16usize], +} +pub type NV_D3D11_VIEWPORT_SHADING_RATE_DESC_V1 = _NV_D3D11_VIEWPORT_SHADING_RATE_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D11_VIEWPORTS_SHADING_RATE_DESC_V1 { + pub version: NvU32, + pub numViewports: NvU32, + pub pViewports: *mut NV_D3D11_VIEWPORT_SHADING_RATE_DESC_V1, +} +pub type NV_D3D11_VIEWPORTS_SHADING_RATE_DESC_V1 = _NV_D3D11_VIEWPORTS_SHADING_RATE_DESC_V1; +pub type NV_D3D11_VIEWPORTS_SHADING_RATE_DESC = NV_D3D11_VIEWPORTS_SHADING_RATE_DESC_V1; +pub type NV_D3D11_VIEWPORT_SHADING_RATE_DESC = NV_D3D11_VIEWPORT_SHADING_RATE_DESC_V1; +impl _NV_SRRV_DIMENSION { + pub const NV_SRRV_DIMENSION_TEXTURE2D: _NV_SRRV_DIMENSION = _NV_SRRV_DIMENSION(4); +} +impl _NV_SRRV_DIMENSION { + pub const NV_SRRV_DIMENSION_TEXTURE2DARRAY: _NV_SRRV_DIMENSION = _NV_SRRV_DIMENSION(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_SRRV_DIMENSION(pub ::std::os::raw::c_int); +pub use self::_NV_SRRV_DIMENSION as NV_SRRV_DIMENSION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_TEX2D_SRRV { + pub MipSlice: UINT, +} +pub type NV_TEX2D_SRRV = _NV_TEX2D_SRRV; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_TEX2D_ARRAY_SRRV { + pub MipSlice: UINT, + pub FirstArraySlice: UINT, + pub ArraySize: UINT, +} +pub type NV_TEX2D_ARRAY_SRRV = _NV_TEX2D_ARRAY_SRRV; +#[repr(C)] +pub struct _NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1 { + pub version: NvU32, + pub Format: DXGI_FORMAT, + pub ViewDimension: NV_SRRV_DIMENSION, + pub __bindgen_anon_1: _NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1__bindgen_ty_1 { + pub Texture2D: NV_TEX2D_SRRV, + pub Texture2DArray: NV_TEX2D_ARRAY_SRRV, +} +pub type NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1 = _NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1; +pub type NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC = NV_D3D11_SHADING_RATE_RESOURCE_VIEW_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_1x2 { + pub X1: _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X1, + pub X2: _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X2, + pub X4: _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X4, + pub X8: _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X8, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X1 { + pub Y: [NvU8; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X2 { + pub YS: [[NvU8; 2usize]; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X4 { + pub YS: [[NvU8; 4usize]; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_1x2_NV_PIXEL_SRSO_1x2_X8 { + pub YS: [[NvU8; 8usize]; 2usize], +} +pub type NV_PIXEL_SRSO_1x2 = _NV_PIXEL_SRSO_1x2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x1 { + pub X1: _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X1, + pub X2: _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X2, + pub X4: _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X4, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X1 { + pub X: [NvU8; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X2 { + pub XS: [[NvU8; 2usize]; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x1_NV_PIXEL_SRSO_2x1_X4 { + pub XS: [[NvU8; 4usize]; 2usize], +} +pub type NV_PIXEL_SRSO_2x1 = _NV_PIXEL_SRSO_2x1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x2 { + pub X1: _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X1, + pub X2: _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X2, + pub X4: _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X4, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X1 { + pub YX: [[NvU8; 2usize]; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X2 { + pub YXS: [[[NvU8; 2usize]; 2usize]; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x2_NV_PIXEL_SRSO_2x2_X4 { + pub YXS: [[[NvU8; 4usize]; 2usize]; 2usize], +} +pub type NV_PIXEL_SRSO_2x2 = _NV_PIXEL_SRSO_2x2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x4 { + pub X1: _NV_PIXEL_SRSO_2x4_NV_PIXEL_SRSO_2x4_X1, + pub X2: _NV_PIXEL_SRSO_2x4_NV_PIXEL_SRSO_2x4_X2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x4_NV_PIXEL_SRSO_2x4_X1 { + pub YX: [[NvU8; 2usize]; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_2x4_NV_PIXEL_SRSO_2x4_X2 { + pub YXS: [[[NvU8; 2usize]; 2usize]; 4usize], +} +pub type NV_PIXEL_SRSO_2x4 = _NV_PIXEL_SRSO_2x4; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_4x2 { + pub X1: _NV_PIXEL_SRSO_4x2_NV_PIXEL_SRSO_4x2_X1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_4x2_NV_PIXEL_SRSO_4x2_X1 { + pub YX: [[NvU8; 4usize]; 2usize], +} +pub type NV_PIXEL_SRSO_4x2 = _NV_PIXEL_SRSO_4x2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_4x4 { + pub X1: _NV_PIXEL_SRSO_4x4_NV_PIXEL_SRSO_4x4_X1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SRSO_4x4_NV_PIXEL_SRSO_4x4_X1 { + pub YX: [[NvU8; 4usize]; 4usize], +} +pub type NV_PIXEL_SRSO_4x4 = _NV_PIXEL_SRSO_4x4; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_PIXEL_SHADING_RATE_SAMPLE_ORDER_TABLE_V1 { + pub version: NvU32, + pub Pixel_1x2: NV_PIXEL_SRSO_1x2, + pub Pixel_2x1: NV_PIXEL_SRSO_2x1, + pub Pixel_2x2: NV_PIXEL_SRSO_2x2, + pub Pixel_2x4: NV_PIXEL_SRSO_2x4, + pub Pixel_4x2: NV_PIXEL_SRSO_4x2, + pub Pixel_4x4: NV_PIXEL_SRSO_4x4, +} +pub type NV_PIXEL_SHADING_RATE_SAMPLE_ORDER_TABLE_V1 = _NV_PIXEL_SHADING_RATE_SAMPLE_ORDER_TABLE_V1; +pub type NV_PIXEL_SHADING_RATE_SAMPLE_ORDER_TABLE = NV_PIXEL_SHADING_RATE_SAMPLE_ORDER_TABLE_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_LATCH_GAZE_PARAMS_V1 { + pub version: NvU32, + pub flags: NvU32, +} +pub type NV_VRS_HELPER_LATCH_GAZE_PARAMS_V1 = _NV_VRS_HELPER_LATCH_GAZE_PARAMS_V1; +pub type NV_VRS_HELPER_LATCH_GAZE_PARAMS = NV_VRS_HELPER_LATCH_GAZE_PARAMS_V1; +impl _NV_VRS_CONTENT_TYPE { + pub const NV_VRS_CONTENT_TYPE_INVALID: _NV_VRS_CONTENT_TYPE = _NV_VRS_CONTENT_TYPE(0); +} +impl _NV_VRS_CONTENT_TYPE { + pub const NV_VRS_CONTENT_TYPE_FOVEATED_RENDERING: _NV_VRS_CONTENT_TYPE = + _NV_VRS_CONTENT_TYPE(1); +} +impl _NV_VRS_CONTENT_TYPE { + pub const NV_VRS_CONTENT_TYPE_MAX: _NV_VRS_CONTENT_TYPE = _NV_VRS_CONTENT_TYPE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_VRS_CONTENT_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_VRS_CONTENT_TYPE as NV_VRS_CONTENT_TYPE; +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_INVALID: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(0); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_HIGHEST_PERFORMANCE: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(1); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_HIGH_PERFORMANCE: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(2); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_BALANCED: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(3); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_HIGH_QUALITY: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(4); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_HIGHEST_QUALITY: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(5); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_CUSTOM: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(6); +} +impl _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET { + pub const NV_FOVEATED_RENDERING_SHADING_RATE_PRESET_MAX: + _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET = _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_FOVEATED_RENDERING_SHADING_RATE_PRESET(pub ::std::os::raw::c_int); +pub use self::_NV_FOVEATED_RENDERING_SHADING_RATE_PRESET as NV_FOVEATED_RENDERING_SHADING_RATE_PRESET; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC_V1 { + pub version: NvU32, + pub InnerMostRegionShadingRate: NV_PIXEL_SHADING_RATE, + pub MiddleRegionShadingRate: NV_PIXEL_SHADING_RATE, + pub PeripheralRegionShadingRate: NV_PIXEL_SHADING_RATE, +} +pub type NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC_V1 = + _NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC_V1; +pub type NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC = + NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC_V1; +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_INVALID: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(0); +} +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_WIDE: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(1); +} +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_BALANCED: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(2); +} +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_NARROW: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(3); +} +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_CUSTOM: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(4); +} +impl _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET { + pub const NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET_MAX: + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET = + _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET(pub ::std::os::raw::c_int); +pub use self::_NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET as NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC_V1 { + pub version: NvU32, + pub fInnermostRadii: [f32; 2usize], + pub fMiddleRadii: [f32; 2usize], + pub fPeripheralRadii: [f32; 2usize], +} +pub type NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC_V1 = + _NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC_V1; +pub type NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC = + NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_DESC_V1 { + pub version: NvU32, + pub flags: NvU32, + pub ShadingRatePreset: NV_FOVEATED_RENDERING_SHADING_RATE_PRESET, + pub ShadingRateCustomPresetDesc: NV_FOVEATED_RENDERING_CUSTOM_SHADING_RATE_PRESET_DESC_V1, + pub FoveationPatternPreset: NV_FOVEATED_RENDERING_FOVEATION_PATTERN_PRESET, + pub FoveationPatternCustomPresetDesc: + NV_FOVEATED_RENDERING_CUSTOM_FOVEATION_PATTERN_PRESET_DESC_V1, + pub GazeDataDeviceId: NvU32, +} +pub type NV_FOVEATED_RENDERING_DESC_V1 = _NV_FOVEATED_RENDERING_DESC_V1; +pub type NV_FOVEATED_RENDERING_DESC = NV_FOVEATED_RENDERING_DESC_V1; +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_INVALID: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(0); +} +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_MONO: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(1); +} +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_LEFT_EYE: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(2); +} +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_RIGHT_EYE: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(3); +} +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_STEREO: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(4); +} +impl _NV_VRS_RENDER_MODE { + pub const NV_VRS_RENDER_MODE_MAX: _NV_VRS_RENDER_MODE = _NV_VRS_RENDER_MODE(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_VRS_RENDER_MODE(pub ::std::os::raw::c_int); +pub use self::_NV_VRS_RENDER_MODE as NV_VRS_RENDER_MODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_ENABLE_PARAMS_V1 { + pub version: NvU32, + pub flags: NvU32, + pub RenderMode: NV_VRS_RENDER_MODE, + pub ContentType: NV_VRS_CONTENT_TYPE, + pub sFoveatedRenderingDesc: NV_FOVEATED_RENDERING_DESC_V1, +} +pub type NV_VRS_HELPER_ENABLE_PARAMS_V1 = _NV_VRS_HELPER_ENABLE_PARAMS_V1; +pub type NV_VRS_HELPER_ENABLE_PARAMS = NV_VRS_HELPER_ENABLE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_DISABLE_PARAMS_V1 { + pub version: NvU32, + pub reserved: NvU32, +} +pub type NV_VRS_HELPER_DISABLE_PARAMS_V1 = _NV_VRS_HELPER_DISABLE_PARAMS_V1; +pub type NV_VRS_HELPER_DISABLE_PARAMS = NV_VRS_HELPER_DISABLE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_GET_SHADING_RATE_RESOURCE_PARAMS_V1 { + pub version: NvU32, + pub ppShadingRateResource: *mut *mut IUnknown, + pub shadingRateTable: [NV_PIXEL_SHADING_RATE; 16usize], +} +pub type NV_VRS_HELPER_GET_SHADING_RATE_RESOURCE_PARAMS_V1 = + _NV_VRS_HELPER_GET_SHADING_RATE_RESOURCE_PARAMS_V1; +pub type NV_VRS_HELPER_GET_SHADING_RATE_RESOURCE_PARAMS = + NV_VRS_HELPER_GET_SHADING_RATE_RESOURCE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_PURGE_INTERNAL_RESOURCES_PARAMS_V1 { + pub version: NvU32, + pub reserved: NvU32, +} +pub type NV_VRS_HELPER_PURGE_INTERNAL_RESOURCES_PARAMS_V1 = + _NV_VRS_HELPER_PURGE_INTERNAL_RESOURCES_PARAMS_V1; +pub type NV_VRS_HELPER_PURGE_INTERNAL_RESOURCES_PARAMS = + NV_VRS_HELPER_PURGE_INTERNAL_RESOURCES_PARAMS_V1; +#[repr(C)] +pub struct ID3DNvVRSHelper_V1__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3DNvVRSHelper_V1 { + pub vtable_: *const ID3DNvVRSHelper_V1__bindgen_vtable, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VRS_HELPER_INIT_PARAMS_V1 { + pub version: NvU32, + pub flags: NvU32, + pub ppVRSHelper: *mut *mut ID3DNvVRSHelper_V1, +} +pub type NV_VRS_HELPER_INIT_PARAMS_V1 = _NV_VRS_HELPER_INIT_PARAMS_V1; +pub type NV_VRS_HELPER_INIT_PARAMS = NV_VRS_HELPER_INIT_PARAMS_V1; +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_ORIGIN_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = _NV_GAZE_DATA_VALIDITY_FLAGS(1); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_DIRECTION_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(2); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_LOCATION_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(4); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_VELOCITY_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(8); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_PUPIL_DIAMETER_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(16); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_EYE_OPENNESS_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(32); +} +impl _NV_GAZE_DATA_VALIDITY_FLAGS { + pub const NV_GAZE_EYE_SACCADE_DATA_VALID: _NV_GAZE_DATA_VALIDITY_FLAGS = + _NV_GAZE_DATA_VALIDITY_FLAGS(64); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GAZE_DATA_VALIDITY_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NV_GAZE_DATA_VALIDITY_FLAGS as NV_GAZE_DATA_VALIDITY_FLAGS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE { + pub version: NvU32, + pub GazeDataValidityFlags: NvU32, + pub fGazeOrigin_mm: [f32; 3usize], + pub fGazeDirection: [f32; 3usize], + pub fGazeNormalizedLocation: [f32; 2usize], + pub fGazeVelocity: [f32; 2usize], + pub fPupilDiameter_mm: f32, + pub fEyeOpenness: f32, + pub bInSaccade: BOOL, +} +pub type NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE_V1 = _NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE; +pub type NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE = NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS { + pub version: NvU32, + pub flags: NvU32, + pub Timestamp: NvU64, + pub __bindgen_anon_1: _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS__bindgen_ty_1 { + pub sMonoData: NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE_V1, + pub sStereoData: _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS__bindgen_ty_1__bindgen_ty_1 { + pub sLeftEye: NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE_V1, + pub sRightEye: NV_FOVEATED_RENDERING_GAZE_DATA_PER_EYE_V1, +} +pub type NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS_V1 = + _NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS; +pub type NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS = + NV_FOVEATED_RENDERING_UPDATE_GAZE_DATA_PARAMS_V1; +#[repr(C)] +pub struct ID3DNvGazeHandler_V2__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3DNvGazeHandler_V2 { + pub vtable_: *const ID3DNvGazeHandler_V2__bindgen_vtable, +} +#[repr(C)] +pub struct ID3DNvGazeHandler_V1__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3DNvGazeHandler_V1 { + pub vtable_: *const ID3DNvGazeHandler_V1__bindgen_vtable, +} +impl _NV_GAZE_DATA_TYPE { + pub const NV_GAZE_DATA_INVALID: _NV_GAZE_DATA_TYPE = _NV_GAZE_DATA_TYPE(0); +} +impl _NV_GAZE_DATA_TYPE { + pub const NV_GAZE_DATA_MONO: _NV_GAZE_DATA_TYPE = _NV_GAZE_DATA_TYPE(1); +} +impl _NV_GAZE_DATA_TYPE { + pub const NV_GAZE_DATA_STEREO: _NV_GAZE_DATA_TYPE = _NV_GAZE_DATA_TYPE(2); +} +impl _NV_GAZE_DATA_TYPE { + pub const NV_GAZE_DATA_MAX: _NV_GAZE_DATA_TYPE = _NV_GAZE_DATA_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GAZE_DATA_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_GAZE_DATA_TYPE as NV_GAZE_DATA_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GAZE_HANDLER_INIT_PARAMS_V2 { + pub version: NvU32, + pub GazeDataDeviceId: NvU32, + pub GazeDataType: NV_GAZE_DATA_TYPE, + pub flags: NvU32, + pub fHorizontalFOV: f32, + pub fVericalFOV: f32, + pub ppNvGazeHandler: *mut *mut ID3DNvGazeHandler_V2, +} +pub type NV_GAZE_HANDLER_INIT_PARAMS_V2 = _NV_GAZE_HANDLER_INIT_PARAMS_V2; +pub type NV_GAZE_HANDLER_INIT_PARAMS = NV_GAZE_HANDLER_INIT_PARAMS_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GAZE_HANDLER_INIT_PARAMS_V1 { + pub version: NvU32, + pub GazeDataDeviceId: NvU32, + pub GazeDataType: NV_GAZE_DATA_TYPE, + pub flags: NvU32, + pub fHorizontalFOV: f32, + pub fVericalFOV: f32, + pub ppNvGazeHandler: *mut *mut ID3DNvGazeHandler_V1, +} +pub type NV_GAZE_HANDLER_INIT_PARAMS_V1 = _NV_GAZE_HANDLER_INIT_PARAMS_V1; +impl NV_SMP_ASSIST_TYPE { + pub const NV_SMP_ASSIST_NONE: NV_SMP_ASSIST_TYPE = NV_SMP_ASSIST_TYPE(0); +} +impl NV_SMP_ASSIST_TYPE { + pub const NV_SMP_ASSIST_MRS: NV_SMP_ASSIST_TYPE = NV_SMP_ASSIST_TYPE(1); +} +impl NV_SMP_ASSIST_TYPE { + pub const NV_SMP_ASSIST_LMS: NV_SMP_ASSIST_TYPE = NV_SMP_ASSIST_TYPE(2); +} +impl NV_SMP_ASSIST_TYPE { + pub const NV_SMP_ASSIST_NUM_TYPES: NV_SMP_ASSIST_TYPE = NV_SMP_ASSIST_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_SMP_ASSIST_TYPE(pub ::std::os::raw::c_int); +impl NV_SMP_ASSIST_LEVEL { + pub const NV_SMP_ASSIST_LEVEL_FULL: NV_SMP_ASSIST_LEVEL = NV_SMP_ASSIST_LEVEL(0); +} +impl NV_SMP_ASSIST_LEVEL { + pub const NV_SMP_ASSIST_LEVEL_PARTIAL: NV_SMP_ASSIST_LEVEL = NV_SMP_ASSIST_LEVEL(1); +} +impl NV_SMP_ASSIST_LEVEL { + pub const NV_SMP_ASSIST_LEVEL_MINIMAL: NV_SMP_ASSIST_LEVEL = NV_SMP_ASSIST_LEVEL(2); +} +impl NV_SMP_ASSIST_LEVEL { + pub const NV_SMP_ASSIST_NUM_LEVELS: NV_SMP_ASSIST_LEVEL = NV_SMP_ASSIST_LEVEL(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_SMP_ASSIST_LEVEL(pub ::std::os::raw::c_int); +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_BALANCED: NV_MRS_CONFIG = NV_MRS_CONFIG(0); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_AGGRESSIVE: NV_MRS_CONFIG = NV_MRS_CONFIG(1); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_OCULUSRIFT_CV1_CONSERVATIVE: NV_MRS_CONFIG = NV_MRS_CONFIG(2); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_OCULUSRIFT_CV1_BALANCED: NV_MRS_CONFIG = NV_MRS_CONFIG(3); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_OCULUSRIFT_CV1_AGGRESSIVE: NV_MRS_CONFIG = NV_MRS_CONFIG(4); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_HTC_VIVE_CONSERVATIVE: NV_MRS_CONFIG = NV_MRS_CONFIG(5); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_HTC_VIVE_BALANCED: NV_MRS_CONFIG = NV_MRS_CONFIG(6); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_CONFIG_HTC_VIVE_AGGRESSIVE: NV_MRS_CONFIG = NV_MRS_CONFIG(7); +} +impl NV_MRS_CONFIG { + pub const NV_MRS_NUM_CONFIGS: NV_MRS_CONFIG = NV_MRS_CONFIG(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_MRS_CONFIG(pub ::std::os::raw::c_int); +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_OCULUSRIFT_CV1_CONSERVATIVE: NV_LMS_CONFIG = NV_LMS_CONFIG(0); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_OCULUSRIFT_CV1_BALANCED: NV_LMS_CONFIG = NV_LMS_CONFIG(1); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_OCULUSRIFT_CV1_AGGRESSIVE: NV_LMS_CONFIG = NV_LMS_CONFIG(2); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_HTC_VIVE_CONSERVATIVE: NV_LMS_CONFIG = NV_LMS_CONFIG(3); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_HTC_VIVE_BALANCED: NV_LMS_CONFIG = NV_LMS_CONFIG(4); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_CONFIG_HTC_VIVE_AGGRESSIVE: NV_LMS_CONFIG = NV_LMS_CONFIG(5); +} +impl NV_LMS_CONFIG { + pub const NV_LMS_NUM_CONFIGS: NV_LMS_CONFIG = NV_LMS_CONFIG(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_LMS_CONFIG(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MRS_CUSTOM_CONFIG_V1 { + pub centerWidth: f32, + pub centerHeight: f32, + pub centerX: f32, + pub centerY: f32, + pub densityScaleX: [f32; 3usize], + pub densityScaleY: [f32; 3usize], +} +pub type NV_MRS_CUSTOM_CONFIG_V1 = _NV_MRS_CUSTOM_CONFIG_V1; +pub type NV_MRS_CUSTOM_CONFIG = NV_MRS_CUSTOM_CONFIG_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_MRS_INSTANCED_STEREO_CONFIG_V1 { + pub centerWidth: [f32; 2usize], + pub centerHeight: f32, + pub centerX: [f32; 2usize], + pub centerY: f32, + pub densityScaleX: [f32; 5usize], + pub densityScaleY: [f32; 3usize], +} +pub type NV_MRS_INSTANCED_STEREO_CONFIG_V1 = _NV_MRS_INSTANCED_STEREO_CONFIG_V1; +pub type NV_MRS_INSTANCED_STEREO_CONFIG = NV_MRS_INSTANCED_STEREO_CONFIG_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LMS_CUSTOM_CONFIG_V1 { + pub warpLeft: f32, + pub warpRight: f32, + pub warpUp: f32, + pub warpDown: f32, + pub relativeSizeLeft: f32, + pub relativeSizeRight: f32, + pub relativeSizeUp: f32, + pub relativeSizeDown: f32, +} +pub type NV_LMS_CUSTOM_CONFIG_V1 = _NV_LMS_CUSTOM_CONFIG_V1; +pub type NV_LMS_CUSTOM_CONFIG = NV_LMS_CUSTOM_CONFIG_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LMS_INSTANCED_STEREO_CONFIG_V1 { + pub sLeftConfig: NV_LMS_CUSTOM_CONFIG_V1, + pub sRightConfig: NV_LMS_CUSTOM_CONFIG_V1, +} +pub type NV_LMS_INSTANCED_STEREO_CONFIG_V1 = _NV_LMS_INSTANCED_STEREO_CONFIG_V1; +pub type NV_LMS_INSTANCED_STEREO_CONFIG = NV_LMS_INSTANCED_STEREO_CONFIG_V1; +impl _NV_SMP_ASSIST_EYE_INDEX { + pub const NV_SMP_ASSIST_EYE_INDEX_MONO: _NV_SMP_ASSIST_EYE_INDEX = _NV_SMP_ASSIST_EYE_INDEX(0); +} +impl _NV_SMP_ASSIST_EYE_INDEX { + pub const NV_SMP_ASSIST_EYE_INDEX_LEFT_EYE: _NV_SMP_ASSIST_EYE_INDEX = + _NV_SMP_ASSIST_EYE_INDEX(1); +} +impl _NV_SMP_ASSIST_EYE_INDEX { + pub const NV_SMP_ASSIST_EYE_INDEX_RIGHT_EYE: _NV_SMP_ASSIST_EYE_INDEX = + _NV_SMP_ASSIST_EYE_INDEX(2); +} +impl _NV_SMP_ASSIST_EYE_INDEX { + pub const NV_SMP_ASSIST_EYE_INDEX_INSTANCED_STEREO: _NV_SMP_ASSIST_EYE_INDEX = + _NV_SMP_ASSIST_EYE_INDEX(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_SMP_ASSIST_EYE_INDEX(pub ::std::os::raw::c_int); +pub use self::_NV_SMP_ASSIST_EYE_INDEX as NV_SMP_ASSIST_EYE_INDEX; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_CUSTOM_RECTS_V1 { + pub numViewports: [NvU32; 4usize], + pub pViewports: [*mut D3D11_VIEWPORT; 4usize], + pub pScissors: [*mut D3D11_RECT; 4usize], +} +pub type NV_CUSTOM_RECTS_V1 = _NV_CUSTOM_RECTS_V1; +pub type NV_CUSTOM_RECTS = NV_CUSTOM_RECTS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_ENABLE_PARAMS_V1 { + pub version: NvU32, + pub eEyeIndex: NV_SMP_ASSIST_EYE_INDEX, +} +pub type NV_SMP_ASSIST_ENABLE_PARAMS_V1 = _NV_SMP_ASSIST_ENABLE_PARAMS_V1; +pub type NV_SMP_ASSIST_ENABLE_PARAMS = NV_SMP_ASSIST_ENABLE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_DISABLE_PARAMS_V1 { + pub version: NvU32, + pub Reserved: NvU32, +} +pub type NV_SMP_ASSIST_DISABLE_PARAMS_V1 = _NV_SMP_ASSIST_DISABLE_PARAMS_V1; +pub type NV_SMP_ASSIST_DISABLE_PARAMS = NV_SMP_ASSIST_DISABLE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_FASTGSCBDATA_V1 { + pub NDCSplitsX: [f32; 2usize], + pub NDCSplitsY: [f32; 2usize], +} +pub type NV_SMP_ASSIST_FASTGSCBDATA_V1 = _NV_SMP_ASSIST_FASTGSCBDATA_V1; +pub type NV_SMP_ASSIST_FASTGSCBDATA = NV_SMP_ASSIST_FASTGSCBDATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO_V1 { + pub NDCSplitsX: [f32; 4usize], + pub NDCSplitsY: [f32; 2usize], +} +pub type NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO_V1 = + _NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO_V1; +pub type NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO = + NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_REMAPCBDATA_V1 { + pub ClipToWindowSplitsX: [f32; 2usize], + pub ClipToWindowSplitsY: [f32; 2usize], + pub ClipToWindowX: [[f32; 2usize]; 3usize], + pub ClipToWindowY: [[f32; 2usize]; 3usize], + pub ClipToWindowZ: [f32; 2usize], + pub WindowToClipSplitsX: [f32; 2usize], + pub WindowToClipSplitsY: [f32; 2usize], + pub WindowToClipX: [[f32; 2usize]; 3usize], + pub WindowToClipY: [[f32; 2usize]; 3usize], + pub WindowToClipZ: [f32; 2usize], + pub BoundingRectOriginX: f32, + pub BoundingRectOriginY: f32, + pub BoundingRectSizeWidth: f32, + pub BoundingRectSizeHeight: f32, + pub BoundingRectSizeInvWidth: f32, + pub BoundingRectSizeInvHeight: f32, + pub Padding: [f32; 2usize], +} +pub type NV_SMP_ASSIST_REMAPCBDATA_V1 = _NV_SMP_ASSIST_REMAPCBDATA_V1; +pub type NV_SMP_ASSIST_REMAPCBDATA = NV_SMP_ASSIST_REMAPCBDATA_V1; +#[repr(C)] +pub struct _NV_SMP_ASSIST_GET_CONSTANTS_V3 { + pub version: NvU32, + pub eEyeIndex: NV_SMP_ASSIST_EYE_INDEX, + pub numViewports: NvU32, + pub pViewports: *mut D3D11_VIEWPORT, + pub pScissors: *mut D3D11_RECT, + pub eSMPAssistType: NV_SMP_ASSIST_TYPE, + pub eSMPAssistLevel: NV_SMP_ASSIST_LEVEL, + pub __bindgen_anon_1: _NV_SMP_ASSIST_GET_CONSTANTS_V3__bindgen_ty_1, + pub projectionSizeWidth: f32, + pub projectionSizeHeight: f32, + pub pFastGSCBData: *mut NV_SMP_ASSIST_FASTGSCBDATA_V1, + pub pRemapCBData: *mut NV_SMP_ASSIST_REMAPCBDATA_V1, + pub boundingViewport: D3D11_VIEWPORT, + pub boundingScissor: D3D11_RECT, + pub __bindgen_anon_2: _NV_SMP_ASSIST_GET_CONSTANTS_V3__bindgen_ty_2, + pub pFastGSCBDataMRS_IS: *mut NV_SMP_ASSIST_FASTGSCBDATA_MRS_INSTANCED_STEREO_V1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_SMP_ASSIST_GET_CONSTANTS_V3__bindgen_ty_1 { + pub sMRSConfig: NV_MRS_CUSTOM_CONFIG_V1, + pub sLMSConfig: NV_LMS_CUSTOM_CONFIG_V1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_SMP_ASSIST_GET_CONSTANTS_V3__bindgen_ty_2 { + pub sMRS_ISConfig: NV_MRS_INSTANCED_STEREO_CONFIG_V1, + pub sLMS_ISConfig: NV_LMS_INSTANCED_STEREO_CONFIG_V1, +} +pub type NV_SMP_ASSIST_GET_CONSTANTS_V3 = _NV_SMP_ASSIST_GET_CONSTANTS_V3; +pub type NV_SMP_ASSIST_GET_CONSTANTS = NV_SMP_ASSIST_GET_CONSTANTS_V3; +#[repr(C)] +pub struct _NV_SMP_ASSIST_SETUP_PARAMS_V1 { + pub version: NvU32, + pub __bindgen_anon_1: _NV_SMP_ASSIST_SETUP_PARAMS_V1__bindgen_ty_1, + pub resolutionScale: f32, + pub boundingBox: D3D11_VIEWPORT, + pub vpOffsets: [f32; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_SMP_ASSIST_SETUP_PARAMS_V1__bindgen_ty_1 { + pub eMRSConfig: NV_MRS_CONFIG, + pub eLMSConfig: NV_LMS_CONFIG, + pub sMRSCustomConfig: NV_MRS_CUSTOM_CONFIG_V1, + pub sLMSCustomConfig: NV_LMS_CUSTOM_CONFIG_V1, + pub sCustomRects: NV_CUSTOM_RECTS_V1, +} +pub type NV_SMP_ASSIST_SETUP_PARAMS_V1 = _NV_SMP_ASSIST_SETUP_PARAMS_V1; +pub type NV_SMP_ASSIST_SETUP_PARAMS = NV_SMP_ASSIST_SETUP_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS_V1 { + pub version: NvU32, + pub eSMPAssistType: NV_SMP_ASSIST_TYPE, + pub leftCoeffs: [f32; 4usize], + pub leftConst: f32, + pub rightCoeffs: [f32; 4usize], + pub rightConst: f32, +} +pub type NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS_V1 = + _NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS_V1; +pub type NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS = + NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS_V1; +#[repr(C)] +pub struct ID3DNvSMPAssist_V1__bindgen_vtable(::std::os::raw::c_void); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ID3DNvSMPAssist_V1 { + pub vtable_: *const ID3DNvSMPAssist_V1__bindgen_vtable, +} +pub type ID3DNvSMPAssist = ID3DNvSMPAssist_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SMP_ASSIST_INITIALIZE_PARAMS_V1 { + pub version: NvU32, + pub eSMPAssistType: NV_SMP_ASSIST_TYPE, + pub eSMPAssistLevel: NV_SMP_ASSIST_LEVEL, + pub flags: NvU32, + pub ppD3DNvSMPAssist: *mut *mut ID3DNvSMPAssist, +} +pub type NV_SMP_ASSIST_INITIALIZE_PARAMS_V1 = _NV_SMP_ASSIST_INITIALIZE_PARAMS_V1; +pub type NV_SMP_ASSIST_INITIALIZE_PARAMS = NV_SMP_ASSIST_INITIALIZE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS_V1 { + pub version: NvU32, + pub eSMPAssistType: NV_SMP_ASSIST_TYPE, + pub eSMPAssistLevel: NV_SMP_ASSIST_LEVEL, + pub bSMPAssistSupported: NvBool, +} +pub type NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS_V1 = _NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS_V1; +pub type NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS = NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GET_SLEEP_STATUS_PARAMS { + pub version: NvU32, + pub bLowLatencyMode: NvBool, + pub bFsVrr: NvBool, + pub bCplVsyncOn: NvBool, + pub rsvd: [NvU8; 126usize], +} +pub type NV_GET_SLEEP_STATUS_PARAMS_V1 = _NV_GET_SLEEP_STATUS_PARAMS; +pub type NV_GET_SLEEP_STATUS_PARAMS = NV_GET_SLEEP_STATUS_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SET_SLEEP_MODE_PARAMS { + pub version: NvU32, + pub bLowLatencyMode: NvBool, + pub bLowLatencyBoost: NvBool, + pub minimumIntervalUs: NvU32, + pub bUseMarkersToOptimize: NvBool, + pub rsvd: [NvU8; 31usize], +} +pub type NV_SET_SLEEP_MODE_PARAMS_V1 = _NV_SET_SLEEP_MODE_PARAMS; +pub type NV_SET_SLEEP_MODE_PARAMS = NV_SET_SLEEP_MODE_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_SET_REFLEX_SYNC_PARAMS { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub vblankIntervalUs: NvU32, + pub timeInQueueUs: NvS32, + pub timeInQueueUsTarget: NvU32, + pub rsvd: [NvU8; 28usize], +} +impl _NV_SET_REFLEX_SYNC_PARAMS { + #[inline] + pub fn bEnable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bEnable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bDisable(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bDisable(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn flagsRsvd(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_flagsRsvd(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bEnable: NvU32, + bDisable: NvU32, + flagsRsvd: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bEnable: u32 = unsafe { ::std::mem::transmute(bEnable) }; + bEnable as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bDisable: u32 = unsafe { ::std::mem::transmute(bDisable) }; + bDisable as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let flagsRsvd: u32 = unsafe { ::std::mem::transmute(flagsRsvd) }; + flagsRsvd as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_SET_REFLEX_SYNC_PARAMS_V1 = _NV_SET_REFLEX_SYNC_PARAMS; +pub type NV_SET_REFLEX_SYNC_PARAMS = NV_SET_REFLEX_SYNC_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LATENCY_RESULT_PARAMS { + pub version: NvU32, + pub frameReport: [_NV_LATENCY_RESULT_PARAMS_FrameReport; 64usize], + pub rsvd: [NvU8; 32usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LATENCY_RESULT_PARAMS_FrameReport { + pub frameID: NvU64, + pub inputSampleTime: NvU64, + pub simStartTime: NvU64, + pub simEndTime: NvU64, + pub renderSubmitStartTime: NvU64, + pub renderSubmitEndTime: NvU64, + pub presentStartTime: NvU64, + pub presentEndTime: NvU64, + pub driverStartTime: NvU64, + pub driverEndTime: NvU64, + pub osRenderQueueStartTime: NvU64, + pub osRenderQueueEndTime: NvU64, + pub gpuRenderStartTime: NvU64, + pub gpuRenderEndTime: NvU64, + pub gpuActiveRenderTimeUs: NvU32, + pub gpuFrameTimeUs: NvU32, + pub rsvd: [NvU8; 120usize], +} +pub type NV_LATENCY_RESULT_PARAMS_V1 = _NV_LATENCY_RESULT_PARAMS; +pub type NV_LATENCY_RESULT_PARAMS = NV_LATENCY_RESULT_PARAMS_V1; +impl NV_LATENCY_MARKER_TYPE { + pub const SIMULATION_START: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(0); +} +impl NV_LATENCY_MARKER_TYPE { + pub const SIMULATION_END: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(1); +} +impl NV_LATENCY_MARKER_TYPE { + pub const RENDERSUBMIT_START: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(2); +} +impl NV_LATENCY_MARKER_TYPE { + pub const RENDERSUBMIT_END: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(3); +} +impl NV_LATENCY_MARKER_TYPE { + pub const PRESENT_START: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(4); +} +impl NV_LATENCY_MARKER_TYPE { + pub const PRESENT_END: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(5); +} +impl NV_LATENCY_MARKER_TYPE { + pub const INPUT_SAMPLE: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(6); +} +impl NV_LATENCY_MARKER_TYPE { + pub const TRIGGER_FLASH: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(7); +} +impl NV_LATENCY_MARKER_TYPE { + pub const PC_LATENCY_PING: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(8); +} +impl NV_LATENCY_MARKER_TYPE { + pub const OUT_OF_BAND_RENDERSUBMIT_START: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(9); +} +impl NV_LATENCY_MARKER_TYPE { + pub const OUT_OF_BAND_RENDERSUBMIT_END: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(10); +} +impl NV_LATENCY_MARKER_TYPE { + pub const OUT_OF_BAND_PRESENT_START: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(11); +} +impl NV_LATENCY_MARKER_TYPE { + pub const OUT_OF_BAND_PRESENT_END: NV_LATENCY_MARKER_TYPE = NV_LATENCY_MARKER_TYPE(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_LATENCY_MARKER_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_LATENCY_MARKER_PARAMS { + pub version: NvU32, + pub frameID: NvU64, + pub markerType: NV_LATENCY_MARKER_TYPE, + pub rsvd: [NvU8; 64usize], +} +pub type NV_LATENCY_MARKER_PARAMS_V1 = _NV_LATENCY_MARKER_PARAMS; +pub type NV_LATENCY_MARKER_PARAMS = NV_LATENCY_MARKER_PARAMS_V1; +pub type NV_ASYNC_FRAME_MARKER_PARAMS_V1 = NV_LATENCY_MARKER_PARAMS_V1; +pub type NV_ASYNC_FRAME_MARKER_PARAMS = NV_ASYNC_FRAME_MARKER_PARAMS_V1; +impl NV_OUT_OF_BAND_CQ_TYPE { + pub const OUT_OF_BAND_RENDER: NV_OUT_OF_BAND_CQ_TYPE = NV_OUT_OF_BAND_CQ_TYPE(0); +} +impl NV_OUT_OF_BAND_CQ_TYPE { + pub const OUT_OF_BAND_PRESENT: NV_OUT_OF_BAND_CQ_TYPE = NV_OUT_OF_BAND_CQ_TYPE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_OUT_OF_BAND_CQ_TYPE(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_DIM3 { + pub x: NvU32, + pub y: NvU32, + pub z: NvU32, +} +pub type NVAPI_DIM3 = _NVAPI_DIM3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_CU_KERNEL_LAUNCH_PARAMS { + pub hFunction: NVDX_ObjectHandle, + pub gridDim: NVAPI_DIM3, + pub blockDim: NVAPI_DIM3, + pub dynSharedMemBytes: NvU32, + pub pParams: *const ::std::os::raw::c_void, + pub paramSize: NvU32, +} +pub type NVAPI_CU_KERNEL_LAUNCH_PARAMS = _NVAPI_CU_KERNEL_LAUNCH_PARAMS; +impl _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS { + pub const NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAP_NONE: + _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS = + _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS(0); +} +impl _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS { + pub const NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAP_STANDARD: + _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS = + _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS as NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS(0); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS; +impl _NVAPI_D3D12_RAYTRACING_CAPS_TYPE { + pub const NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING: + _NVAPI_D3D12_RAYTRACING_CAPS_TYPE = _NVAPI_D3D12_RAYTRACING_CAPS_TYPE(0); +} +impl _NVAPI_D3D12_RAYTRACING_CAPS_TYPE { + pub const NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP: _NVAPI_D3D12_RAYTRACING_CAPS_TYPE = + _NVAPI_D3D12_RAYTRACING_CAPS_TYPE(1); +} +impl _NVAPI_D3D12_RAYTRACING_CAPS_TYPE { + pub const NVAPI_D3D12_RAYTRACING_CAPS_TYPE_INVALID: _NVAPI_D3D12_RAYTRACING_CAPS_TYPE = + _NVAPI_D3D12_RAYTRACING_CAPS_TYPE(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_CAPS_TYPE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_CAPS_TYPE as NVAPI_D3D12_RAYTRACING_CAPS_TYPE; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAG_NONE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS(0); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAG_PREFER_FAST_TRACE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS(1); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAG_PREFER_FAST_BUILD: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT_OC1_2_STATE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT(1); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT_OC1_4_STATE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_USAGE_COUNT { + pub count: NvU32, + pub subdivisionLevel: NvU32, + pub format: NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_FORMAT, +} +pub type NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_USAGE_COUNT = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_USAGE_COUNT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_DESC { + pub byteOffset: NvU32, + pub subdivisionLevel: NvU16, + pub format: NvU16, +} +pub type NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_DESC = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_DESC; +#[repr(C)] +pub struct _NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_INPUTS { + pub flags: NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_BUILD_FLAGS, + pub numOMMUsageCounts: NvU32, + pub pOMMUsageCounts: *const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_USAGE_COUNT, + pub inputBuffer: D3D12_GPU_VIRTUAL_ADDRESS, + pub perOMMDescs: D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE, +} +pub type NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_INPUTS = + _NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_INPUTS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO { + pub resultDataMaxSizeInBytes: NvU64, + pub scratchDataSizeInBytes: NvU64, +} +pub type NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS_V1 { + pub version: NvU32, + pub pDesc: *const NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_INPUTS, + pub pInfo: *mut NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO, +} +pub type NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS_V1 = + _NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS_V1; +pub type NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS = + NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS_V1; +impl _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS { + pub const NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS_NONE: + _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS = _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS(0); +} +impl _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS { + pub const NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS_ENABLE_OMM_SUPPORT: + _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS = _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS as NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_V1 { + pub version: NvU32, + pub flags: NvU32, +} +pub type NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_V1 = + _NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_V1; +pub type NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS = + NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_V1; +impl _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX { + pub const NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_ACCELERATION_STRUCTURE_EX: + _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX = _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX(0); +} +impl _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX { + pub const NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_OPACITY_MICROMAP_ARRAY_EX: + _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX = _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX as NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX; +#[repr(C)] +pub struct _NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_V1 { + pub version: NvU32, + pub serializedDataType: NVAPI_D3D12_SERIALIZED_DATA_TYPE_EX, + pub pIdentifierToCheck: *const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER, + pub checkStatus: D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS, +} +pub type NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_V1 = + _NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_V1; +pub type NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS = + NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_V1; +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(0); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(1); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(2); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(4); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(8); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(16); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(32); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_UPDATE_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(64); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DISABLE_OMMS_EX: + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = + _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(128); +} +impl _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_OPACITY_STATES_UPDATE_EX : _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX (256) ; +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX as NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX; +impl _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX { + pub const NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES_EX: + _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX = _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX(0); +} +impl _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX { + pub const NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS_EX: + _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX = _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX(1); +} +impl _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX { + pub const NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX: + _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX = _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX as NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX(-1); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX(-2); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX(-3); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX(-4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_SPECIAL_INDEX; +#[repr(C)] +pub struct _NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_ATTACHMENT_DESC { + pub opacityMicromapIndexBuffer: D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE, + pub opacityMicromapIndexFormat: DXGI_FORMAT, + pub opacityMicromapBaseLocation: NvU32, + pub opacityMicromapArray: D3D12_GPU_VIRTUAL_ADDRESS, + pub numOMMUsageCounts: NvU32, + pub pOMMUsageCounts: *const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_USAGE_COUNT, +} +pub type NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_ATTACHMENT_DESC = + _NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_ATTACHMENT_DESC; +#[repr(C)] +pub struct _NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_TRIANGLES_DESC { + pub triangles: D3D12_RAYTRACING_GEOMETRY_TRIANGLES_DESC, + pub ommAttachment: NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_ATTACHMENT_DESC, +} +pub type NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_TRIANGLES_DESC = + _NVAPI_D3D12_RAYTRACING_GEOMETRY_OMM_TRIANGLES_DESC; +#[repr(C)] +pub struct _NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX { + pub type_: NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_EX, + pub flags: D3D12_RAYTRACING_GEOMETRY_FLAGS, + pub __bindgen_anon_1: _NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX__bindgen_ty_1, +} +#[repr(C)] +pub struct _NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX__bindgen_ty_1 { + pub triangles: __BindgenUnionField, + pub aabbs: __BindgenUnionField, + pub ommTriangles: __BindgenUnionField, + pub bindgen_union_field: [u64; 12usize], +} +pub type NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX = _NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX; +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_NONE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(0); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(1); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(2); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(4); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(8); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OMM_2_STATE_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(16); +} +impl _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX { + pub const NVAPI_D3D12_RAYTRACING_INSTANCE_FLAG_DISABLE_OMMS_EX: + _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX = _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(32); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX as NVAPI_D3D12_RAYTRACING_INSTANCE_FLAGS_EX; +#[repr(C)] +pub struct _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX { + pub type_: D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE, + pub flags: NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS_EX, + pub numDescs: NvU32, + pub descsLayout: D3D12_ELEMENTS_LAYOUT, + pub geometryDescStrideInBytes: NvU32, + pub __bindgen_anon_1: + _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX__bindgen_ty_1, +} +#[repr(C)] +pub struct _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX__bindgen_ty_1 { + pub instanceDescs: __BindgenUnionField, + pub pGeometryDescs: __BindgenUnionField<*const NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX>, + pub ppGeometryDescs: __BindgenUnionField<*const *const NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX>, + pub bindgen_union_field: u64, +} +pub type NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX = + _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_V1 { + pub version: NvU32, + pub pDesc: *const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX, + pub pInfo: *mut D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO, +} +pub type NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_V1 = + _NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_V1; +pub type NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS = + NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_V1; +#[repr(C)] +pub struct _NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_DESC { + pub destOpacityMicromapArrayData: D3D12_GPU_VIRTUAL_ADDRESS, + pub inputs: NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_INPUTS, + pub scratchOpacityMicromapArrayData: D3D12_GPU_VIRTUAL_ADDRESS, +} +pub type NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_DESC = + _NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_DESC; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_CURRENT_SIZE_DESC { + pub currentSizeInBytes: NvU64, +} +pub type NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_CURRENT_SIZE_DESC = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_CURRENT_SIZE_DESC; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_CURRENT_SIZE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE( + pub ::std::os::raw::c_int, +); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE; +#[repr(C)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_DESC { + pub destBuffer: D3D12_GPU_VIRTUAL_ADDRESS, + pub infoType: NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_TYPE, +} +pub type NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_DESC = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_DESC; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1 { + pub version: NvU32, + pub pDesc: *const NVAPI_D3D12_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_DESC, + pub numPostbuildInfoDescs: NvU32, + pub pPostbuildInfoDescs: + *const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_DESC, +} +pub type NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1 = + _NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1; +pub type NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS = + NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1; +#[repr(C)] +pub struct _NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1 { + pub version: NvU32, + pub opacityMicromapArray: D3D12_GPU_VIRTUAL_ADDRESS, +} +pub type NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1 = + _NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1; +pub type NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS = + NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS_V1 { + pub version: NvU32, + pub pDesc: *const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_DESC, + pub numSources: NvU32, + pub pSources: *const D3D12_GPU_VIRTUAL_ADDRESS, +} +pub type NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS_V1 = + _NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS_V1; +pub type NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS = + NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS_V1; +#[repr(C)] +pub struct _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX { + pub destAccelerationStructureData: D3D12_GPU_VIRTUAL_ADDRESS, + pub inputs: NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX, + pub sourceAccelerationStructureData: D3D12_GPU_VIRTUAL_ADDRESS, + pub scratchAccelerationStructureData: D3D12_GPU_VIRTUAL_ADDRESS, +} +pub type NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX = + _NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_V1 { + pub version: NvU32, + pub pDesc: *const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX, + pub numPostbuildInfoDescs: NvU32, + pub pPostbuildInfoDescs: *const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC, +} +pub type NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_V1 = + _NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_V1; +pub type NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS = + NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_V1; +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE_TRANSPARENT: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE(0); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE_OPAQUE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE(1); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE_UNKNOWN_TRANSPARENT: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE(2); +} +impl _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE { + pub const NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE_UNKNOWN_OPAQUE: + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE = + _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE(pub ::std::os::raw::c_int); +pub use self::_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE as NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_STATE; +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_NONE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(0); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_FORCE_OPAQUE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(1); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_FORCE_NON_OPAQUE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(2); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH_EX: _NVAPI_RAY_FLAGS_EX = + _NVAPI_RAY_FLAGS_EX(4); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_SKIP_CLOSEST_HIT_SHADER_EX: _NVAPI_RAY_FLAGS_EX = + _NVAPI_RAY_FLAGS_EX(8); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_CULL_BACK_FACING_TRIANGLES_EX: _NVAPI_RAY_FLAGS_EX = + _NVAPI_RAY_FLAGS_EX(16); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES_EX: _NVAPI_RAY_FLAGS_EX = + _NVAPI_RAY_FLAGS_EX(32); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_CULL_OPAQUE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(64); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_CULL_NON_OPAQUE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(128); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_SKIP_TRIANGLES_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(256); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES_EX: _NVAPI_RAY_FLAGS_EX = + _NVAPI_RAY_FLAGS_EX(512); +} +impl _NVAPI_RAY_FLAGS_EX { + pub const NVAPI_RAY_FLAG_FORCE_OMM_2_STATE_EX: _NVAPI_RAY_FLAGS_EX = _NVAPI_RAY_FLAGS_EX(1024); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_RAY_FLAGS_EX(pub ::std::os::raw::c_int); +pub use self::_NVAPI_RAY_FLAGS_EX as NVAPI_RAY_FLAG_EX; +impl _NV_D3D12_WORKSTATION_FEATURE_TYPE { + pub const NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER: + _NV_D3D12_WORKSTATION_FEATURE_TYPE = _NV_D3D12_WORKSTATION_FEATURE_TYPE(1); +} +impl _NV_D3D12_WORKSTATION_FEATURE_TYPE { + pub const NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT: + _NV_D3D12_WORKSTATION_FEATURE_TYPE = _NV_D3D12_WORKSTATION_FEATURE_TYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_D3D12_WORKSTATION_FEATURE_TYPE(pub ::std::os::raw::c_int); +pub use self::_NV_D3D12_WORKSTATION_FEATURE_TYPE as NV_D3D12_WORKSTATION_FEATURE_TYPE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D12_WORKSTATION_FEATURE_RDMA_PROPERTIES { + pub rdmaHeapSize: NvU64, +} +pub type NV_D3D12_WORKSTATION_FEATURE_RDMA_PROPERTIES = + _NV_D3D12_WORKSTATION_FEATURE_RDMA_PROPERTIES; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_D3D12_WORKSTATION_FEATURE_PROPERTIES { + pub version: NvU32, + pub workstationFeatureType: NV_D3D12_WORKSTATION_FEATURE_TYPE, + pub supported: NvBool, + pub __bindgen_anon_1: _NV_D3D12_WORKSTATION_FEATURE_PROPERTIES__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NV_D3D12_WORKSTATION_FEATURE_PROPERTIES__bindgen_ty_1 { + pub rdmaInfo: NV_D3D12_WORKSTATION_FEATURE_RDMA_PROPERTIES, +} +pub type NVAPI_D3D12_WORKSTATION_FEATURE_PROPERTIES_PARAMS_V1 = + _NV_D3D12_WORKSTATION_FEATURE_PROPERTIES; +pub type NVVIOOWNERID = NvU32; +impl _NVVIOOWNERTYPE { + pub const NVVIOOWNERTYPE_NONE: _NVVIOOWNERTYPE = _NVVIOOWNERTYPE(0); +} +impl _NVVIOOWNERTYPE { + pub const NVVIOOWNERTYPE_APPLICATION: _NVVIOOWNERTYPE = _NVVIOOWNERTYPE(1); +} +impl _NVVIOOWNERTYPE { + pub const NVVIOOWNERTYPE_DESKTOP: _NVVIOOWNERTYPE = _NVVIOOWNERTYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOOWNERTYPE(pub ::std::os::raw::c_int); +pub use self::_NVVIOOWNERTYPE as NVVIOOWNERTYPE; +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_NONE: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(0); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_487I_59_94_SMPTE259_NTSC: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(1); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_576I_50_00_SMPTE259_PAL: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(2); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1035I_60_00_SMPTE260: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(3); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1035I_59_94_SMPTE260: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(4); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_50_00_SMPTE295: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(5); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(6); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(7); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(8); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(9); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(10); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(11); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(12); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_23_976_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(13); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_60_00_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(14); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_59_94_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(15); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_50_00_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(16); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_48_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(17); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_47_96_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(18); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_30_00_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(19); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_29_97_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(20); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_25_00_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(21); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_24_00_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(22); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_720P_23_98_SMPTE296: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(23); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_30_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(24); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_29_97_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(25); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_60_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(26); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_59_94_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(27); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_25_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(28); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_50_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(29); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_24_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(30); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_23_98_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(31); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_48_00_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(32); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_47_96_SMPTE372: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(33); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080PSF_25_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(34); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080PSF_29_97_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(35); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080PSF_30_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(36); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080PSF_24_00_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(37); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080PSF_23_98_SMPTE274: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(38); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_A: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(39); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_A: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(40); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_A: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(41); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(42); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(43); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_60_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(44); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(45); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(46); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_50_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(47); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(48); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_30_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(49); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(50); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_25_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(51); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(52); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_24_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(53); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_48_00_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(54); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_48_00_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(55); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(56); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(57); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_59_94_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(58); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(59); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_29_97_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(60); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080P_23_98_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(61); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048P_23_98_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(62); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_1080I_47_96_SMPTE274_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(63); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_2048I_47_96_SMPTE372_3G_LEVEL_B: _NVVIOSIGNALFORMAT = + _NVVIOSIGNALFORMAT(64); +} +impl _NVVIOSIGNALFORMAT { + pub const NVVIOSIGNALFORMAT_END: _NVVIOSIGNALFORMAT = _NVVIOSIGNALFORMAT(65); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOSIGNALFORMAT(pub ::std::os::raw::c_int); +pub use self::_NVVIOSIGNALFORMAT as NVVIOSIGNALFORMAT; +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE259: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(0); +} +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE260: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(1); +} +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE274: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(2); +} +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE295: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(3); +} +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE296: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(4); +} +impl _NVVIOVIDEOSTANDARD { + pub const NVVIOVIDEOSTANDARD_SMPTE372: _NVVIOVIDEOSTANDARD = _NVVIOVIDEOSTANDARD(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOVIDEOSTANDARD(pub ::std::os::raw::c_int); +pub use self::_NVVIOVIDEOSTANDARD as NVVIOVIDEOSTANDARD; +impl _NVVIOVIDEOTYPE { + pub const NVVIOVIDEOTYPE_SD: _NVVIOVIDEOTYPE = _NVVIOVIDEOTYPE(0); +} +impl _NVVIOVIDEOTYPE { + pub const NVVIOVIDEOTYPE_HD: _NVVIOVIDEOTYPE = _NVVIOVIDEOTYPE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOVIDEOTYPE(pub ::std::os::raw::c_int); +pub use self::_NVVIOVIDEOTYPE as NVVIOVIDEOTYPE; +impl _NVVIOINTERLACEMODE { + pub const NVVIOINTERLACEMODE_PROGRESSIVE: _NVVIOINTERLACEMODE = _NVVIOINTERLACEMODE(0); +} +impl _NVVIOINTERLACEMODE { + pub const NVVIOINTERLACEMODE_INTERLACE: _NVVIOINTERLACEMODE = _NVVIOINTERLACEMODE(1); +} +impl _NVVIOINTERLACEMODE { + pub const NVVIOINTERLACEMODE_PSF: _NVVIOINTERLACEMODE = _NVVIOINTERLACEMODE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOINTERLACEMODE(pub ::std::os::raw::c_int); +pub use self::_NVVIOINTERLACEMODE as NVVIOINTERLACEMODE; +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_UNKNOWN: _NVVIODATAFORMAT = _NVVIODATAFORMAT(-1); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8_TO_YCRCB444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(0); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8A8_TO_YCRCBA4444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(1); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8Z10_TO_YCRCBZ4444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(2); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8_TO_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(3); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8A8_TO_YCRCBA4224: _NVVIODATAFORMAT = _NVVIODATAFORMAT(4); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R8G8B8Z10_TO_YCRCBZ4224: _NVVIODATAFORMAT = _NVVIODATAFORMAT(5); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X8X8X8_444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(6); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X8X8X8A8_4444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(7); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X8X8X8Z10_4444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(8); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X10X10X10_444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(9); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X10X8X8_444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(10); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X10X8X8A10_4444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(11); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X10X8X8Z10_4444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(12); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_DUAL_R8G8B8_TO_DUAL_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(13); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_DUAL_X8X8X8_TO_DUAL_422_PASSTHRU: _NVVIODATAFORMAT = + _NVVIODATAFORMAT(14); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R10G10B10_TO_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(15); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R10G10B10_TO_YCRCB444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(16); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X12X12X12_444_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(17); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_X12X12X12_422_PASSTHRU: _NVVIODATAFORMAT = _NVVIODATAFORMAT(18); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_Y10CR10CB10_TO_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(19); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_Y8CR8CB8_TO_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(20); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_Y10CR8CB8A10_TO_YCRCBA4224: _NVVIODATAFORMAT = _NVVIODATAFORMAT(21); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R10G10B10_TO_RGB444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(22); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R12G12B12_TO_YCRCB444: _NVVIODATAFORMAT = _NVVIODATAFORMAT(23); +} +impl _NVVIODATAFORMAT { + pub const NVVIODATAFORMAT_R12G12B12_TO_YCRCB422: _NVVIODATAFORMAT = _NVVIODATAFORMAT(24); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIODATAFORMAT(pub ::std::os::raw::c_int); +pub use self::_NVVIODATAFORMAT as NVVIODATAFORMAT; +impl _NVVIOOUTPUTAREA { + pub const NVVIOOUTPUTAREA_FULLSIZE: _NVVIOOUTPUTAREA = _NVVIOOUTPUTAREA(0); +} +impl _NVVIOOUTPUTAREA { + pub const NVVIOOUTPUTAREA_SAFEACTION: _NVVIOOUTPUTAREA = _NVVIOOUTPUTAREA(1); +} +impl _NVVIOOUTPUTAREA { + pub const NVVIOOUTPUTAREA_SAFETITLE: _NVVIOOUTPUTAREA = _NVVIOOUTPUTAREA(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOOUTPUTAREA(pub ::std::os::raw::c_int); +pub use self::_NVVIOOUTPUTAREA as NVVIOOUTPUTAREA; +impl _NVVIOSYNCSOURCE { + pub const NVVIOSYNCSOURCE_SDISYNC: _NVVIOSYNCSOURCE = _NVVIOSYNCSOURCE(0); +} +impl _NVVIOSYNCSOURCE { + pub const NVVIOSYNCSOURCE_COMPSYNC: _NVVIOSYNCSOURCE = _NVVIOSYNCSOURCE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOSYNCSOURCE(pub ::std::os::raw::c_int); +pub use self::_NVVIOSYNCSOURCE as NVVIOSYNCSOURCE; +impl _NVVIOCOMPSYNCTYPE { + pub const NVVIOCOMPSYNCTYPE_AUTO: _NVVIOCOMPSYNCTYPE = _NVVIOCOMPSYNCTYPE(0); +} +impl _NVVIOCOMPSYNCTYPE { + pub const NVVIOCOMPSYNCTYPE_BILEVEL: _NVVIOCOMPSYNCTYPE = _NVVIOCOMPSYNCTYPE(1); +} +impl _NVVIOCOMPSYNCTYPE { + pub const NVVIOCOMPSYNCTYPE_TRILEVEL: _NVVIOCOMPSYNCTYPE = _NVVIOCOMPSYNCTYPE(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOCOMPSYNCTYPE(pub ::std::os::raw::c_int); +pub use self::_NVVIOCOMPSYNCTYPE as NVVIOCOMPSYNCTYPE; +impl _NVVIOINPUTOUTPUTSTATUS { + pub const NVINPUTOUTPUTSTATUS_OFF: _NVVIOINPUTOUTPUTSTATUS = _NVVIOINPUTOUTPUTSTATUS(0); +} +impl _NVVIOINPUTOUTPUTSTATUS { + pub const NVINPUTOUTPUTSTATUS_ERROR: _NVVIOINPUTOUTPUTSTATUS = _NVVIOINPUTOUTPUTSTATUS(1); +} +impl _NVVIOINPUTOUTPUTSTATUS { + pub const NVINPUTOUTPUTSTATUS_SDI_SD: _NVVIOINPUTOUTPUTSTATUS = _NVVIOINPUTOUTPUTSTATUS(2); +} +impl _NVVIOINPUTOUTPUTSTATUS { + pub const NVINPUTOUTPUTSTATUS_SDI_HD: _NVVIOINPUTOUTPUTSTATUS = _NVVIOINPUTOUTPUTSTATUS(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOINPUTOUTPUTSTATUS(pub ::std::os::raw::c_int); +pub use self::_NVVIOINPUTOUTPUTSTATUS as NVVIOINPUTOUTPUTSTATUS; +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_OFF: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(0); +} +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_ERROR: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(1); +} +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_SYNCLOSS: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(2); +} +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_COMPOSITE: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(3); +} +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_SDI_SD: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(4); +} +impl _NVVIOSYNCSTATUS { + pub const NVVIOSYNCSTATUS_SDI_HD: _NVVIOSYNCSTATUS = _NVVIOSYNCSTATUS(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOSYNCSTATUS(pub ::std::os::raw::c_int); +pub use self::_NVVIOSYNCSTATUS as NVVIOSYNCSTATUS; +impl _NVVIOCAPTURESTATUS { + pub const NVVIOSTATUS_STOPPED: _NVVIOCAPTURESTATUS = _NVVIOCAPTURESTATUS(0); +} +impl _NVVIOCAPTURESTATUS { + pub const NVVIOSTATUS_RUNNING: _NVVIOCAPTURESTATUS = _NVVIOCAPTURESTATUS(1); +} +impl _NVVIOCAPTURESTATUS { + pub const NVVIOSTATUS_ERROR: _NVVIOCAPTURESTATUS = _NVVIOCAPTURESTATUS(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOCAPTURESTATUS(pub ::std::os::raw::c_int); +pub use self::_NVVIOCAPTURESTATUS as NVVIOCAPTURESTATUS; +impl _NVVIOSTATUSTYPE { + pub const NVVIOSTATUSTYPE_IN: _NVVIOSTATUSTYPE = _NVVIOSTATUSTYPE(0); +} +impl _NVVIOSTATUSTYPE { + pub const NVVIOSTATUSTYPE_OUT: _NVVIOSTATUSTYPE = _NVVIOSTATUSTYPE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOSTATUSTYPE(pub ::std::os::raw::c_int); +pub use self::_NVVIOSTATUSTYPE as NVVIOSTATUSTYPE; +impl _NVVIOCONFIGTYPE { + pub const NVVIOCONFIGTYPE_IN: _NVVIOCONFIGTYPE = _NVVIOCONFIGTYPE(0); +} +impl _NVVIOCONFIGTYPE { + pub const NVVIOCONFIGTYPE_OUT: _NVVIOCONFIGTYPE = _NVVIOCONFIGTYPE(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOCONFIGTYPE(pub ::std::os::raw::c_int); +pub use self::_NVVIOCONFIGTYPE as NVVIOCONFIGTYPE; +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_UNKNOWN: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(0); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_YCBCR: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(1); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_YCBCRA: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(2); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_YCBCRD: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(3); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_GBR: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(4); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_GBRA: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(5); +} +impl _NVVIOCOLORSPACE { + pub const NVVIOCOLORSPACE_GBRD: _NVVIOCOLORSPACE = _NVVIOCOLORSPACE(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOCOLORSPACE(pub ::std::os::raw::c_int); +pub use self::_NVVIOCOLORSPACE as NVVIOCOLORSPACE; +impl _NVVIOCOMPONENTSAMPLING { + pub const NVVIOCOMPONENTSAMPLING_UNKNOWN: _NVVIOCOMPONENTSAMPLING = _NVVIOCOMPONENTSAMPLING(0); +} +impl _NVVIOCOMPONENTSAMPLING { + pub const NVVIOCOMPONENTSAMPLING_4444: _NVVIOCOMPONENTSAMPLING = _NVVIOCOMPONENTSAMPLING(1); +} +impl _NVVIOCOMPONENTSAMPLING { + pub const NVVIOCOMPONENTSAMPLING_4224: _NVVIOCOMPONENTSAMPLING = _NVVIOCOMPONENTSAMPLING(2); +} +impl _NVVIOCOMPONENTSAMPLING { + pub const NVVIOCOMPONENTSAMPLING_444: _NVVIOCOMPONENTSAMPLING = _NVVIOCOMPONENTSAMPLING(3); +} +impl _NVVIOCOMPONENTSAMPLING { + pub const NVVIOCOMPONENTSAMPLING_422: _NVVIOCOMPONENTSAMPLING = _NVVIOCOMPONENTSAMPLING(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOCOMPONENTSAMPLING(pub ::std::os::raw::c_int); +pub use self::_NVVIOCOMPONENTSAMPLING as NVVIOCOMPONENTSAMPLING; +impl _NVVIOBITSPERCOMPONENT { + pub const NVVIOBITSPERCOMPONENT_UNKNOWN: _NVVIOBITSPERCOMPONENT = _NVVIOBITSPERCOMPONENT(0); +} +impl _NVVIOBITSPERCOMPONENT { + pub const NVVIOBITSPERCOMPONENT_8: _NVVIOBITSPERCOMPONENT = _NVVIOBITSPERCOMPONENT(1); +} +impl _NVVIOBITSPERCOMPONENT { + pub const NVVIOBITSPERCOMPONENT_10: _NVVIOBITSPERCOMPONENT = _NVVIOBITSPERCOMPONENT(2); +} +impl _NVVIOBITSPERCOMPONENT { + pub const NVVIOBITSPERCOMPONENT_12: _NVVIOBITSPERCOMPONENT = _NVVIOBITSPERCOMPONENT(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOBITSPERCOMPONENT(pub ::std::os::raw::c_int); +pub use self::_NVVIOBITSPERCOMPONENT as NVVIOBITSPERCOMPONENT; +impl _NVVIOLINKID { + pub const NVVIOLINKID_UNKNOWN: _NVVIOLINKID = _NVVIOLINKID(0); +} +impl _NVVIOLINKID { + pub const NVVIOLINKID_A: _NVVIOLINKID = _NVVIOLINKID(1); +} +impl _NVVIOLINKID { + pub const NVVIOLINKID_B: _NVVIOLINKID = _NVVIOLINKID(2); +} +impl _NVVIOLINKID { + pub const NVVIOLINKID_C: _NVVIOLINKID = _NVVIOLINKID(3); +} +impl _NVVIOLINKID { + pub const NVVIOLINKID_D: _NVVIOLINKID = _NVVIOLINKID(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOLINKID(pub ::std::os::raw::c_int); +pub use self::_NVVIOLINKID as NVVIOLINKID; +impl _NVVIOANCPARITYCOMPUTATION { + pub const NVVIOANCPARITYCOMPUTATION_AUTO: _NVVIOANCPARITYCOMPUTATION = + _NVVIOANCPARITYCOMPUTATION(0); +} +impl _NVVIOANCPARITYCOMPUTATION { + pub const NVVIOANCPARITYCOMPUTATION_ON: _NVVIOANCPARITYCOMPUTATION = + _NVVIOANCPARITYCOMPUTATION(1); +} +impl _NVVIOANCPARITYCOMPUTATION { + pub const NVVIOANCPARITYCOMPUTATION_OFF: _NVVIOANCPARITYCOMPUTATION = + _NVVIOANCPARITYCOMPUTATION(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOANCPARITYCOMPUTATION(pub ::std::os::raw::c_int); +pub use self::_NVVIOANCPARITYCOMPUTATION as NVVIOANCPARITYCOMPUTATION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCAPS { + pub version: NvU32, + pub adapterName: NvAPI_String, + pub adapterClass: NvU32, + pub adapterCaps: NvU32, + pub dipSwitch: NvU32, + pub dipSwitchReserved: NvU32, + pub boardID: NvU32, + pub driver: _NVVIOCAPS__bindgen_ty_1, + pub firmWare: _NVVIOCAPS__bindgen_ty_2, + pub ownerId: NVVIOOWNERID, + pub ownerType: NVVIOOWNERTYPE, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCAPS__bindgen_ty_1 { + pub majorVersion: NvU32, + pub minorVersion: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCAPS__bindgen_ty_2 { + pub majorVersion: NvU32, + pub minorVersion: NvU32, +} +pub type NVVIOCAPS = _NVVIOCAPS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCHANNELSTATUS { + pub smpte352: NvU32, + pub signalFormat: NVVIOSIGNALFORMAT, + pub bitsPerComponent: NVVIOBITSPERCOMPONENT, + pub samplingFormat: NVVIOCOMPONENTSAMPLING, + pub colorSpace: NVVIOCOLORSPACE, + pub linkID: NVVIOLINKID, +} +pub type NVVIOCHANNELSTATUS = _NVVIOCHANNELSTATUS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOINPUTSTATUS { + pub vidIn: [[NVVIOCHANNELSTATUS; 2usize]; 4usize], + pub captureStatus: NVVIOCAPTURESTATUS, +} +pub type NVVIOINPUTSTATUS = _NVVIOINPUTSTATUS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOOUTPUTSTATUS { + pub vid1Out: NVVIOINPUTOUTPUTSTATUS, + pub vid2Out: NVVIOINPUTOUTPUTSTATUS, + pub sdiSyncIn: NVVIOSYNCSTATUS, + pub compSyncIn: NVVIOSYNCSTATUS, + pub syncEnable: NvU32, + pub syncSource: NVVIOSYNCSOURCE, + pub syncFormat: NVVIOSIGNALFORMAT, + pub frameLockEnable: NvU32, + pub outputVideoLocked: NvU32, + pub dataIntegrityCheckErrorCount: NvU32, + pub dataIntegrityCheckEnabled: NvU32, + pub dataIntegrityCheckFailed: NvU32, + pub uSyncSourceLocked: NvU32, + pub uPowerOn: NvU32, +} +pub type NVVIOOUTPUTSTATUS = _NVVIOOUTPUTSTATUS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOSTATUS { + pub version: NvU32, + pub nvvioStatusType: NVVIOSTATUSTYPE, + pub vioStatus: _NVVIOSTATUS__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVVIOSTATUS__bindgen_ty_1 { + pub inStatus: NVVIOINPUTSTATUS, + pub outStatus: NVVIOOUTPUTSTATUS, +} +pub type NVVIOSTATUS = _NVVIOSTATUS; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOOUTPUTREGION { + pub x: NvU32, + pub y: NvU32, + pub width: NvU32, + pub height: NvU32, +} +pub type NVVIOOUTPUTREGION = _NVVIOOUTPUTREGION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOGAMMARAMP8 { + pub uRed: [NvU16; 256usize], + pub uGreen: [NvU16; 256usize], + pub uBlue: [NvU16; 256usize], +} +pub type NVVIOGAMMARAMP8 = _NVVIOGAMMARAMP8; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOGAMMARAMP10 { + pub uRed: [NvU16; 1024usize], + pub uGreen: [NvU16; 1024usize], + pub uBlue: [NvU16; 1024usize], +} +pub type NVVIOGAMMARAMP10 = _NVVIOGAMMARAMP10; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOSYNCDELAY { + pub version: NvU32, + pub horizontalDelay: NvU32, + pub verticalDelay: NvU32, +} +pub type NVVIOSYNCDELAY = _NVVIOSYNCDELAY; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOVIDEOMODE { + pub horizontalPixels: NvU32, + pub verticalLines: NvU32, + pub fFrameRate: f32, + pub interlaceMode: NVVIOINTERLACEMODE, + pub videoStandard: NVVIOVIDEOSTANDARD, + pub videoType: NVVIOVIDEOTYPE, +} +pub type NVVIOVIDEOMODE = _NVVIOVIDEOMODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOSIGNALFORMATDETAIL { + pub signalFormat: NVVIOSIGNALFORMAT, + pub videoMode: NVVIOVIDEOMODE, +} +pub type NVVIOSIGNALFORMATDETAIL = _NVVIOSIGNALFORMATDETAIL; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIODATAFORMATDETAIL { + pub dataFormat: NVVIODATAFORMAT, + pub vioCaps: NvU32, +} +pub type NVVIODATAFORMATDETAIL = _NVVIODATAFORMATDETAIL; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCOLORCONVERSION { + pub version: NvU32, + pub colorMatrix: [[f32; 3usize]; 3usize], + pub colorOffset: [f32; 3usize], + pub colorScale: [f32; 3usize], + pub compositeSafe: NvU32, +} +pub type NVVIOCOLORCONVERSION = _NVVIOCOLORCONVERSION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOGAMMACORRECTION { + pub version: NvU32, + pub vioGammaCorrectionType: NvU32, + pub gammaRamp: _NVVIOGAMMACORRECTION__bindgen_ty_1, + pub fGammaValueR: f32, + pub fGammaValueG: f32, + pub fGammaValueB: f32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVVIOGAMMACORRECTION__bindgen_ty_1 { + pub gammaRamp8: NVVIOGAMMARAMP8, + pub gammaRamp10: NVVIOGAMMARAMP10, +} +pub type NVVIOGAMMACORRECTION = _NVVIOGAMMACORRECTION; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCOMPOSITERANGE { + pub uRange: NvU32, + pub uEnabled: NvU32, + pub uMin: NvU32, + pub uMax: NvU32, +} +pub type NVVIOCOMPOSITERANGE = _NVVIOCOMPOSITERANGE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOOUTPUTCONFIG_V1 { + pub signalFormat: NVVIOSIGNALFORMAT, + pub dataFormat: NVVIODATAFORMAT, + pub outputRegion: NVVIOOUTPUTREGION, + pub outputArea: NVVIOOUTPUTAREA, + pub colorConversion: NVVIOCOLORCONVERSION, + pub gammaCorrection: NVVIOGAMMACORRECTION, + pub syncEnable: NvU32, + pub syncSource: NVVIOSYNCSOURCE, + pub syncDelay: NVVIOSYNCDELAY, + pub compositeSyncType: NVVIOCOMPSYNCTYPE, + pub frameLockEnable: NvU32, + pub psfSignalFormat: NvU32, + pub enable422Filter: NvU32, + pub compositeTerminate: NvU32, + pub enableDataIntegrityCheck: NvU32, + pub cscOverride: NvU32, + pub flipQueueLength: NvU32, + pub enableANCTimeCodeGeneration: NvU32, + pub enableComposite: NvU32, + pub enableAlphaKeyComposite: NvU32, + pub compRange: NVVIOCOMPOSITERANGE, + pub reservedData: [NvU8; 256usize], + pub enableFullColorRange: NvU32, + pub enableRGBData: NvU32, +} +pub type NVVIOOUTPUTCONFIG_V1 = _NVVIOOUTPUTCONFIG_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOOUTPUTCONFIG_V2 { + pub signalFormat: NVVIOSIGNALFORMAT, + pub dataFormat: NVVIODATAFORMAT, + pub outputRegion: NVVIOOUTPUTREGION, + pub outputArea: NVVIOOUTPUTAREA, + pub colorConversion: NVVIOCOLORCONVERSION, + pub gammaCorrection: NVVIOGAMMACORRECTION, + pub syncEnable: NvU32, + pub syncSource: NVVIOSYNCSOURCE, + pub syncDelay: NVVIOSYNCDELAY, + pub compositeSyncType: NVVIOCOMPSYNCTYPE, + pub frameLockEnable: NvU32, + pub psfSignalFormat: NvU32, + pub enable422Filter: NvU32, + pub compositeTerminate: NvU32, + pub enableDataIntegrityCheck: NvU32, + pub cscOverride: NvU32, + pub flipQueueLength: NvU32, + pub enableANCTimeCodeGeneration: NvU32, + pub enableComposite: NvU32, + pub enableAlphaKeyComposite: NvU32, + pub compRange: NVVIOCOMPOSITERANGE, + pub reservedData: [NvU8; 256usize], + pub enableFullColorRange: NvU32, + pub enableRGBData: NvU32, + pub ancParityComputation: NVVIOANCPARITYCOMPUTATION, +} +pub type NVVIOOUTPUTCONFIG_V2 = _NVVIOOUTPUTCONFIG_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOOUTPUTCONFIG_V3 { + pub signalFormat: NVVIOSIGNALFORMAT, + pub dataFormat: NVVIODATAFORMAT, + pub outputRegion: NVVIOOUTPUTREGION, + pub outputArea: NVVIOOUTPUTAREA, + pub colorConversion: NVVIOCOLORCONVERSION, + pub gammaCorrection: NVVIOGAMMACORRECTION, + pub syncEnable: NvU32, + pub syncSource: NVVIOSYNCSOURCE, + pub syncDelay: NVVIOSYNCDELAY, + pub compositeSyncType: NVVIOCOMPSYNCTYPE, + pub frameLockEnable: NvU32, + pub psfSignalFormat: NvU32, + pub enable422Filter: NvU32, + pub compositeTerminate: NvU32, + pub enableDataIntegrityCheck: NvU32, + pub cscOverride: NvU32, + pub flipQueueLength: NvU32, + pub enableANCTimeCodeGeneration: NvU32, + pub enableComposite: NvU32, + pub enableAlphaKeyComposite: NvU32, + pub compRange: NVVIOCOMPOSITERANGE, + pub reservedData: [NvU8; 256usize], + pub enableFullColorRange: NvU32, + pub enableRGBData: NvU32, + pub ancParityComputation: NVVIOANCPARITYCOMPUTATION, + pub enableAudioBlanking: NvU32, +} +pub type NVVIOOUTPUTCONFIG_V3 = _NVVIOOUTPUTCONFIG_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOSTREAM { + pub bitsPerComponent: NvU32, + pub sampling: NVVIOCOMPONENTSAMPLING, + pub expansionEnable: NvU32, + pub numLinks: NvU32, + pub links: [_NVVIOSTREAM__bindgen_ty_1; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOSTREAM__bindgen_ty_1 { + pub jack: NvU32, + pub channel: NvU32, +} +pub type NVVIOSTREAM = _NVVIOSTREAM; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOINPUTCONFIG { + pub numRawCaptureImages: NvU32, + pub signalFormat: NVVIOSIGNALFORMAT, + pub numStreams: NvU32, + pub streams: [NVVIOSTREAM; 4usize], + pub bTestMode: NvU32, +} +pub type NVVIOINPUTCONFIG = _NVVIOINPUTCONFIG; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCONFIG_V1 { + pub version: NvU32, + pub fields: NvU32, + pub nvvioConfigType: NVVIOCONFIGTYPE, + pub vioConfig: _NVVIOCONFIG_V1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVVIOCONFIG_V1__bindgen_ty_1 { + pub inConfig: NVVIOINPUTCONFIG, + pub outConfig: NVVIOOUTPUTCONFIG_V1, +} +pub type NVVIOCONFIG_V1 = _NVVIOCONFIG_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCONFIG_V2 { + pub version: NvU32, + pub fields: NvU32, + pub nvvioConfigType: NVVIOCONFIGTYPE, + pub vioConfig: _NVVIOCONFIG_V2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVVIOCONFIG_V2__bindgen_ty_1 { + pub inConfig: NVVIOINPUTCONFIG, + pub outConfig: NVVIOOUTPUTCONFIG_V2, +} +pub type NVVIOCONFIG_V2 = _NVVIOCONFIG_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOCONFIG_V3 { + pub version: NvU32, + pub fields: NvU32, + pub nvvioConfigType: NVVIOCONFIGTYPE, + pub vioConfig: _NVVIOCONFIG_V3__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVVIOCONFIG_V3__bindgen_ty_1 { + pub inConfig: NVVIOINPUTCONFIG, + pub outConfig: NVVIOOUTPUTCONFIG_V3, +} +pub type NVVIOCONFIG_V3 = _NVVIOCONFIG_V3; +pub type NVVIOOUTPUTCONFIG = NVVIOOUTPUTCONFIG_V3; +pub type NVVIOCONFIG = NVVIOCONFIG_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NVVIOTOPOLOGYTARGET { + pub hPhysicalGpu: NvPhysicalGpuHandle, + pub hVioHandle: NvVioHandle, + pub vioId: NvU32, + pub outputId: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_VIO_TOPOLOGY { + pub version: NvU32, + pub vioTotalDeviceCount: NvU32, + pub vioTarget: [NVVIOTOPOLOGYTARGET; 8usize], +} +pub type NV_VIO_TOPOLOGY = _NV_VIO_TOPOLOGY; +pub type NVVIOTOPOLOGY = _NV_VIO_TOPOLOGY; +impl _NVVIOPCILINKRATE { + pub const NVVIOPCILINKRATE_UNKNOWN: _NVVIOPCILINKRATE = _NVVIOPCILINKRATE(0); +} +impl _NVVIOPCILINKRATE { + pub const NVVIOPCILINKRATE_GEN1: _NVVIOPCILINKRATE = _NVVIOPCILINKRATE(1); +} +impl _NVVIOPCILINKRATE { + pub const NVVIOPCILINKRATE_GEN2: _NVVIOPCILINKRATE = _NVVIOPCILINKRATE(2); +} +impl _NVVIOPCILINKRATE { + pub const NVVIOPCILINKRATE_GEN3: _NVVIOPCILINKRATE = _NVVIOPCILINKRATE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOPCILINKRATE(pub ::std::os::raw::c_int); +pub use self::_NVVIOPCILINKRATE as NVVIOPCILINKRATE; +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_UNKNOWN: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(0); +} +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_x1: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(1); +} +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_x2: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(2); +} +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_x4: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(4); +} +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_x8: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(8); +} +impl _NVVIOPCILINKWIDTH { + pub const NVVIOPCILINKWIDTH_x16: _NVVIOPCILINKWIDTH = _NVVIOPCILINKWIDTH(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVVIOPCILINKWIDTH(pub ::std::os::raw::c_int); +pub use self::_NVVIOPCILINKWIDTH as NVVIOPCILINKWIDTH; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVVIOPCIINFO { + pub version: NvU32, + pub pciDeviceId: NvU32, + pub pciSubSystemId: NvU32, + pub pciRevisionId: NvU32, + pub pciDomain: NvU32, + pub pciBus: NvU32, + pub pciSlot: NvU32, + pub pciLinkWidth: NVVIOPCILINKWIDTH, + pub pciLinkRate: NVVIOPCILINKRATE, +} +pub type NVVIOPCIINFO_V1 = _NVVIOPCIINFO; +pub type NVVIOPCIINFO = NVVIOPCIINFO_V1; +impl _NV_StereoRegistryProfileType { + pub const NVAPI_STEREO_DEFAULT_REGISTRY_PROFILE: _NV_StereoRegistryProfileType = + _NV_StereoRegistryProfileType(0); +} +impl _NV_StereoRegistryProfileType { + pub const NVAPI_STEREO_DX9_REGISTRY_PROFILE: _NV_StereoRegistryProfileType = + _NV_StereoRegistryProfileType(1); +} +impl _NV_StereoRegistryProfileType { + pub const NVAPI_STEREO_DX10_REGISTRY_PROFILE: _NV_StereoRegistryProfileType = + _NV_StereoRegistryProfileType(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_StereoRegistryProfileType(pub ::std::os::raw::c_int); +pub use self::_NV_StereoRegistryProfileType as NV_STEREO_REGISTRY_PROFILE_TYPE; +impl _NV_StereoRegistryID { + pub const NVAPI_CONVERGENCE_ID: _NV_StereoRegistryID = _NV_StereoRegistryID(0); +} +impl _NV_StereoRegistryID { + pub const NVAPI_FRUSTUM_ADJUST_MODE_ID: _NV_StereoRegistryID = _NV_StereoRegistryID(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_StereoRegistryID(pub ::std::os::raw::c_int); +pub use self::_NV_StereoRegistryID as NV_STEREO_REGISTRY_ID; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVAPI_STEREO_CAPS { + pub version: NvU32, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub reserved2: [NvU32; 3usize], +} +impl _NVAPI_STEREO_CAPS { + #[inline] + pub fn supportsWindowedModeOff(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_supportsWindowedModeOff(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportsWindowedModeAutomatic(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_supportsWindowedModeAutomatic(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn supportsWindowedModePersistent(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_supportsWindowedModePersistent(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 29u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 29u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + supportsWindowedModeOff: NvU32, + supportsWindowedModeAutomatic: NvU32, + supportsWindowedModePersistent: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let supportsWindowedModeOff: u32 = + unsafe { ::std::mem::transmute(supportsWindowedModeOff) }; + supportsWindowedModeOff as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let supportsWindowedModeAutomatic: u32 = + unsafe { ::std::mem::transmute(supportsWindowedModeAutomatic) }; + supportsWindowedModeAutomatic as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let supportsWindowedModePersistent: u32 = + unsafe { ::std::mem::transmute(supportsWindowedModePersistent) }; + supportsWindowedModePersistent as u64 + }); + __bindgen_bitfield_unit.set(3usize, 29u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NVAPI_STEREO_CAPS_V1 = _NVAPI_STEREO_CAPS; +pub type NVAPI_STEREO_CAPS = NVAPI_STEREO_CAPS_V1; +impl _NV_FrustumAdjustMode { + pub const NVAPI_NO_FRUSTUM_ADJUST: _NV_FrustumAdjustMode = _NV_FrustumAdjustMode(0); +} +impl _NV_FrustumAdjustMode { + pub const NVAPI_FRUSTUM_STRETCH: _NV_FrustumAdjustMode = _NV_FrustumAdjustMode(1); +} +impl _NV_FrustumAdjustMode { + pub const NVAPI_FRUSTUM_CLEAR_EDGES: _NV_FrustumAdjustMode = _NV_FrustumAdjustMode(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_FrustumAdjustMode(pub ::std::os::raw::c_int); +pub use self::_NV_FrustumAdjustMode as NV_FRUSTUM_ADJUST_MODE; +impl _NVAPI_STEREO_INIT_ACTIVATION_FLAGS { + pub const NVAPI_STEREO_INIT_ACTIVATION_IMMEDIATE: _NVAPI_STEREO_INIT_ACTIVATION_FLAGS = + _NVAPI_STEREO_INIT_ACTIVATION_FLAGS(0); +} +impl _NVAPI_STEREO_INIT_ACTIVATION_FLAGS { + pub const NVAPI_STEREO_INIT_ACTIVATION_DELAYED: _NVAPI_STEREO_INIT_ACTIVATION_FLAGS = + _NVAPI_STEREO_INIT_ACTIVATION_FLAGS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVAPI_STEREO_INIT_ACTIVATION_FLAGS(pub ::std::os::raw::c_int); +pub use self::_NVAPI_STEREO_INIT_ACTIVATION_FLAGS as NVAPI_STEREO_INIT_ACTIVATION_FLAGS; +impl _NV_StereoSwapChainMode { + pub const NVAPI_STEREO_SWAPCHAIN_DEFAULT: _NV_StereoSwapChainMode = _NV_StereoSwapChainMode(0); +} +impl _NV_StereoSwapChainMode { + pub const NVAPI_STEREO_SWAPCHAIN_STEREO: _NV_StereoSwapChainMode = _NV_StereoSwapChainMode(1); +} +impl _NV_StereoSwapChainMode { + pub const NVAPI_STEREO_SWAPCHAIN_MONO: _NV_StereoSwapChainMode = _NV_StereoSwapChainMode(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_StereoSwapChainMode(pub ::std::os::raw::c_int); +pub use self::_NV_StereoSwapChainMode as NV_STEREO_SWAPCHAIN_MODE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvDRSSessionHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvDRSSessionHandle = *mut NvDRSSessionHandle__; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NvDRSProfileHandle__ { + pub unused: ::std::os::raw::c_int, +} +pub type NvDRSProfileHandle = *mut NvDRSProfileHandle__; +impl _NVDRS_SETTING_TYPE { + pub const NVDRS_DWORD_TYPE: _NVDRS_SETTING_TYPE = _NVDRS_SETTING_TYPE(0); +} +impl _NVDRS_SETTING_TYPE { + pub const NVDRS_BINARY_TYPE: _NVDRS_SETTING_TYPE = _NVDRS_SETTING_TYPE(1); +} +impl _NVDRS_SETTING_TYPE { + pub const NVDRS_STRING_TYPE: _NVDRS_SETTING_TYPE = _NVDRS_SETTING_TYPE(2); +} +impl _NVDRS_SETTING_TYPE { + pub const NVDRS_WSTRING_TYPE: _NVDRS_SETTING_TYPE = _NVDRS_SETTING_TYPE(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVDRS_SETTING_TYPE(pub ::std::os::raw::c_int); +pub use self::_NVDRS_SETTING_TYPE as NVDRS_SETTING_TYPE; +impl _NVDRS_SETTING_LOCATION { + pub const NVDRS_CURRENT_PROFILE_LOCATION: _NVDRS_SETTING_LOCATION = _NVDRS_SETTING_LOCATION(0); +} +impl _NVDRS_SETTING_LOCATION { + pub const NVDRS_GLOBAL_PROFILE_LOCATION: _NVDRS_SETTING_LOCATION = _NVDRS_SETTING_LOCATION(1); +} +impl _NVDRS_SETTING_LOCATION { + pub const NVDRS_BASE_PROFILE_LOCATION: _NVDRS_SETTING_LOCATION = _NVDRS_SETTING_LOCATION(2); +} +impl _NVDRS_SETTING_LOCATION { + pub const NVDRS_DEFAULT_PROFILE_LOCATION: _NVDRS_SETTING_LOCATION = _NVDRS_SETTING_LOCATION(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NVDRS_SETTING_LOCATION(pub ::std::os::raw::c_int); +pub use self::_NVDRS_SETTING_LOCATION as NVDRS_SETTING_LOCATION; +#[repr(C)] +#[repr(align(4))] +#[derive(Copy, Clone)] +pub struct _NVDRS_GPU_SUPPORT { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NVDRS_GPU_SUPPORT { + #[inline] + pub fn geforce(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_geforce(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn quadro(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_quadro(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn nvs(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_nvs(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved4(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved4(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved5(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved5(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved6(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved6(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved7(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved7(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved8(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved8(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved9(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved9(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved10(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved10(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved11(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved11(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved12(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved12(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved13(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved13(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved14(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved14(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved15(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved15(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved16(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved16(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved17(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved17(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved18(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved18(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved19(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved19(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved20(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved20(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved21(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved21(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved22(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved22(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved23(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved23(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved24(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved24(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved25(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved25(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved26(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved26(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved27(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved27(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved28(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved28(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(27usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved29(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved29(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(28usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved30(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved30(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(29usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved31(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved31(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(30usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved32(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u32) } + } + #[inline] + pub fn set_reserved32(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + geforce: NvU32, + quadro: NvU32, + nvs: NvU32, + reserved4: NvU32, + reserved5: NvU32, + reserved6: NvU32, + reserved7: NvU32, + reserved8: NvU32, + reserved9: NvU32, + reserved10: NvU32, + reserved11: NvU32, + reserved12: NvU32, + reserved13: NvU32, + reserved14: NvU32, + reserved15: NvU32, + reserved16: NvU32, + reserved17: NvU32, + reserved18: NvU32, + reserved19: NvU32, + reserved20: NvU32, + reserved21: NvU32, + reserved22: NvU32, + reserved23: NvU32, + reserved24: NvU32, + reserved25: NvU32, + reserved26: NvU32, + reserved27: NvU32, + reserved28: NvU32, + reserved29: NvU32, + reserved30: NvU32, + reserved31: NvU32, + reserved32: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let geforce: u32 = unsafe { ::std::mem::transmute(geforce) }; + geforce as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let quadro: u32 = unsafe { ::std::mem::transmute(quadro) }; + quadro as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let nvs: u32 = unsafe { ::std::mem::transmute(nvs) }; + nvs as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let reserved4: u32 = unsafe { ::std::mem::transmute(reserved4) }; + reserved4 as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let reserved5: u32 = unsafe { ::std::mem::transmute(reserved5) }; + reserved5 as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let reserved6: u32 = unsafe { ::std::mem::transmute(reserved6) }; + reserved6 as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let reserved7: u32 = unsafe { ::std::mem::transmute(reserved7) }; + reserved7 as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let reserved8: u32 = unsafe { ::std::mem::transmute(reserved8) }; + reserved8 as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let reserved9: u32 = unsafe { ::std::mem::transmute(reserved9) }; + reserved9 as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let reserved10: u32 = unsafe { ::std::mem::transmute(reserved10) }; + reserved10 as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let reserved11: u32 = unsafe { ::std::mem::transmute(reserved11) }; + reserved11 as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let reserved12: u32 = unsafe { ::std::mem::transmute(reserved12) }; + reserved12 as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let reserved13: u32 = unsafe { ::std::mem::transmute(reserved13) }; + reserved13 as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let reserved14: u32 = unsafe { ::std::mem::transmute(reserved14) }; + reserved14 as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let reserved15: u32 = unsafe { ::std::mem::transmute(reserved15) }; + reserved15 as u64 + }); + __bindgen_bitfield_unit.set(15usize, 1u8, { + let reserved16: u32 = unsafe { ::std::mem::transmute(reserved16) }; + reserved16 as u64 + }); + __bindgen_bitfield_unit.set(16usize, 1u8, { + let reserved17: u32 = unsafe { ::std::mem::transmute(reserved17) }; + reserved17 as u64 + }); + __bindgen_bitfield_unit.set(17usize, 1u8, { + let reserved18: u32 = unsafe { ::std::mem::transmute(reserved18) }; + reserved18 as u64 + }); + __bindgen_bitfield_unit.set(18usize, 1u8, { + let reserved19: u32 = unsafe { ::std::mem::transmute(reserved19) }; + reserved19 as u64 + }); + __bindgen_bitfield_unit.set(19usize, 1u8, { + let reserved20: u32 = unsafe { ::std::mem::transmute(reserved20) }; + reserved20 as u64 + }); + __bindgen_bitfield_unit.set(20usize, 1u8, { + let reserved21: u32 = unsafe { ::std::mem::transmute(reserved21) }; + reserved21 as u64 + }); + __bindgen_bitfield_unit.set(21usize, 1u8, { + let reserved22: u32 = unsafe { ::std::mem::transmute(reserved22) }; + reserved22 as u64 + }); + __bindgen_bitfield_unit.set(22usize, 1u8, { + let reserved23: u32 = unsafe { ::std::mem::transmute(reserved23) }; + reserved23 as u64 + }); + __bindgen_bitfield_unit.set(23usize, 1u8, { + let reserved24: u32 = unsafe { ::std::mem::transmute(reserved24) }; + reserved24 as u64 + }); + __bindgen_bitfield_unit.set(24usize, 1u8, { + let reserved25: u32 = unsafe { ::std::mem::transmute(reserved25) }; + reserved25 as u64 + }); + __bindgen_bitfield_unit.set(25usize, 1u8, { + let reserved26: u32 = unsafe { ::std::mem::transmute(reserved26) }; + reserved26 as u64 + }); + __bindgen_bitfield_unit.set(26usize, 1u8, { + let reserved27: u32 = unsafe { ::std::mem::transmute(reserved27) }; + reserved27 as u64 + }); + __bindgen_bitfield_unit.set(27usize, 1u8, { + let reserved28: u32 = unsafe { ::std::mem::transmute(reserved28) }; + reserved28 as u64 + }); + __bindgen_bitfield_unit.set(28usize, 1u8, { + let reserved29: u32 = unsafe { ::std::mem::transmute(reserved29) }; + reserved29 as u64 + }); + __bindgen_bitfield_unit.set(29usize, 1u8, { + let reserved30: u32 = unsafe { ::std::mem::transmute(reserved30) }; + reserved30 as u64 + }); + __bindgen_bitfield_unit.set(30usize, 1u8, { + let reserved31: u32 = unsafe { ::std::mem::transmute(reserved31) }; + reserved31 as u64 + }); + __bindgen_bitfield_unit.set(31usize, 1u8, { + let reserved32: u32 = unsafe { ::std::mem::transmute(reserved32) }; + reserved32 as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NVDRS_GPU_SUPPORT = _NVDRS_GPU_SUPPORT; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_BINARY_SETTING { + pub valueLength: NvU32, + pub valueData: [NvU8; 4096usize], +} +pub type NVDRS_BINARY_SETTING = _NVDRS_BINARY_SETTING; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_SETTING_VALUES { + pub version: NvU32, + pub numSettingValues: NvU32, + pub settingType: NVDRS_SETTING_TYPE, + pub __bindgen_anon_1: _NVDRS_SETTING_VALUES__bindgen_ty_1, + pub settingValues: [_NVDRS_SETTING_VALUES__bindgen_ty_2; 100usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVDRS_SETTING_VALUES__bindgen_ty_1 { + pub u32DefaultValue: NvU32, + pub binaryDefaultValue: NVDRS_BINARY_SETTING, + pub wszDefaultValue: NvAPI_UnicodeString, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVDRS_SETTING_VALUES__bindgen_ty_2 { + pub u32Value: NvU32, + pub binaryValue: NVDRS_BINARY_SETTING, + pub wszValue: NvAPI_UnicodeString, +} +pub type NVDRS_SETTING_VALUES = _NVDRS_SETTING_VALUES; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_SETTING_V1 { + pub version: NvU32, + pub settingName: NvAPI_UnicodeString, + pub settingId: NvU32, + pub settingType: NVDRS_SETTING_TYPE, + pub settingLocation: NVDRS_SETTING_LOCATION, + pub isCurrentPredefined: NvU32, + pub isPredefinedValid: NvU32, + pub __bindgen_anon_1: _NVDRS_SETTING_V1__bindgen_ty_1, + pub __bindgen_anon_2: _NVDRS_SETTING_V1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVDRS_SETTING_V1__bindgen_ty_1 { + pub u32PredefinedValue: NvU32, + pub binaryPredefinedValue: NVDRS_BINARY_SETTING, + pub wszPredefinedValue: NvAPI_UnicodeString, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union _NVDRS_SETTING_V1__bindgen_ty_2 { + pub u32CurrentValue: NvU32, + pub binaryCurrentValue: NVDRS_BINARY_SETTING, + pub wszCurrentValue: NvAPI_UnicodeString, +} +pub type NVDRS_SETTING_V1 = _NVDRS_SETTING_V1; +pub type NVDRS_SETTING = NVDRS_SETTING_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_APPLICATION_V1 { + pub version: NvU32, + pub isPredefined: NvU32, + pub appName: NvAPI_UnicodeString, + pub userFriendlyName: NvAPI_UnicodeString, + pub launcher: NvAPI_UnicodeString, +} +pub type NVDRS_APPLICATION_V1 = _NVDRS_APPLICATION_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_APPLICATION_V2 { + pub version: NvU32, + pub isPredefined: NvU32, + pub appName: NvAPI_UnicodeString, + pub userFriendlyName: NvAPI_UnicodeString, + pub launcher: NvAPI_UnicodeString, + pub fileInFolder: NvAPI_UnicodeString, +} +pub type NVDRS_APPLICATION_V2 = _NVDRS_APPLICATION_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_APPLICATION_V3 { + pub version: NvU32, + pub isPredefined: NvU32, + pub appName: NvAPI_UnicodeString, + pub userFriendlyName: NvAPI_UnicodeString, + pub launcher: NvAPI_UnicodeString, + pub fileInFolder: NvAPI_UnicodeString, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NVDRS_APPLICATION_V3 { + #[inline] + pub fn isMetro(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMetro(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isCommandLine(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isCommandLine(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isMetro: NvU32, + isCommandLine: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isMetro: u32 = unsafe { ::std::mem::transmute(isMetro) }; + isMetro as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isCommandLine: u32 = unsafe { ::std::mem::transmute(isCommandLine) }; + isCommandLine as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NVDRS_APPLICATION_V3 = _NVDRS_APPLICATION_V3; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_APPLICATION_V4 { + pub version: NvU32, + pub isPredefined: NvU32, + pub appName: NvAPI_UnicodeString, + pub userFriendlyName: NvAPI_UnicodeString, + pub launcher: NvAPI_UnicodeString, + pub fileInFolder: NvAPI_UnicodeString, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub commandLine: NvAPI_UnicodeString, +} +impl _NVDRS_APPLICATION_V4 { + #[inline] + pub fn isMetro(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_isMetro(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn isCommandLine(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_isCommandLine(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + isMetro: NvU32, + isCommandLine: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let isMetro: u32 = unsafe { ::std::mem::transmute(isMetro) }; + isMetro as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let isCommandLine: u32 = unsafe { ::std::mem::transmute(isCommandLine) }; + isCommandLine as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NVDRS_APPLICATION_V4 = _NVDRS_APPLICATION_V4; +pub type NVDRS_APPLICATION = NVDRS_APPLICATION_V4; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NVDRS_PROFILE_V1 { + pub version: NvU32, + pub profileName: NvAPI_UnicodeString, + pub gpuSupport: NVDRS_GPU_SUPPORT, + pub isPredefined: NvU32, + pub numOfApps: NvU32, + pub numOfSettings: NvU32, +} +pub type NVDRS_PROFILE_V1 = _NVDRS_PROFILE_V1; +pub type NVDRS_PROFILE = NVDRS_PROFILE_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_CHIPSET_INFO_v4 { + pub version: NvU32, + pub vendorId: NvU32, + pub deviceId: NvU32, + pub szVendorName: NvAPI_ShortString, + pub szChipsetName: NvAPI_ShortString, + pub flags: NvU32, + pub subSysVendorId: NvU32, + pub subSysDeviceId: NvU32, + pub szSubSysVendorName: NvAPI_ShortString, + pub HBvendorId: NvU32, + pub HBdeviceId: NvU32, + pub HBsubSysVendorId: NvU32, + pub HBsubSysDeviceId: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_CHIPSET_INFO_v3 { + pub version: NvU32, + pub vendorId: NvU32, + pub deviceId: NvU32, + pub szVendorName: NvAPI_ShortString, + pub szChipsetName: NvAPI_ShortString, + pub flags: NvU32, + pub subSysVendorId: NvU32, + pub subSysDeviceId: NvU32, + pub szSubSysVendorName: NvAPI_ShortString, +} +impl NV_CHIPSET_INFO_FLAGS { + pub const NV_CHIPSET_INFO_HYBRID: NV_CHIPSET_INFO_FLAGS = NV_CHIPSET_INFO_FLAGS(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct NV_CHIPSET_INFO_FLAGS(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_CHIPSET_INFO_v2 { + pub version: NvU32, + pub vendorId: NvU32, + pub deviceId: NvU32, + pub szVendorName: NvAPI_ShortString, + pub szChipsetName: NvAPI_ShortString, + pub flags: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_CHIPSET_INFO_v1 { + pub version: NvU32, + pub vendorId: NvU32, + pub deviceId: NvU32, + pub szVendorName: NvAPI_ShortString, + pub szChipsetName: NvAPI_ShortString, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct NV_LID_DOCK_PARAMS { + pub version: NvU32, + pub currentLidState: NvU32, + pub currentDockState: NvU32, + pub currentLidPolicy: NvU32, + pub currentDockPolicy: NvU32, + pub forcedLidMechanismPresent: NvU32, + pub forcedDockMechanismPresent: NvU32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAY_DRIVER_INFO { + pub version: NvU32, + pub driverVersion: NvU32, + pub szBuildBranch: NvAPI_ShortString, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +impl _NV_DISPLAY_DRIVER_INFO { + #[inline] + pub fn bIsDCHDriver(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsDCHDriver(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIAStudioPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIAStudioPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIAGameReadyPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIAGameReadyPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIARTXProductionBranchPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIARTXProductionBranchPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIARTXNewFeatureBranchPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIARTXNewFeatureBranchPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 27u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 27u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsDCHDriver: NvU32, + bIsNVIDIAStudioPackage: NvU32, + bIsNVIDIAGameReadyPackage: NvU32, + bIsNVIDIARTXProductionBranchPackage: NvU32, + bIsNVIDIARTXNewFeatureBranchPackage: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsDCHDriver: u32 = unsafe { ::std::mem::transmute(bIsDCHDriver) }; + bIsDCHDriver as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bIsNVIDIAStudioPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIAStudioPackage) }; + bIsNVIDIAStudioPackage as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bIsNVIDIAGameReadyPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIAGameReadyPackage) }; + bIsNVIDIAGameReadyPackage as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let bIsNVIDIARTXProductionBranchPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIARTXProductionBranchPackage) }; + bIsNVIDIARTXProductionBranchPackage as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let bIsNVIDIARTXNewFeatureBranchPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIARTXNewFeatureBranchPackage) }; + bIsNVIDIARTXNewFeatureBranchPackage as u64 + }); + __bindgen_bitfield_unit.set(5usize, 27u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAY_DRIVER_INFO_V1 = _NV_DISPLAY_DRIVER_INFO; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_DISPLAY_DRIVER_INFO_V2 { + pub version: NvU32, + pub driverVersion: NvU32, + pub szBuildBranch: NvAPI_ShortString, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub szBuildBaseBranch: NvAPI_ShortString, + pub reservedEx: NvU32, +} +impl _NV_DISPLAY_DRIVER_INFO_V2 { + #[inline] + pub fn bIsDCHDriver(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsDCHDriver(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIAStudioPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIAStudioPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIAGameReadyPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIAGameReadyPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIARTXProductionBranchPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIARTXProductionBranchPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn bIsNVIDIARTXNewFeatureBranchPackage(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } + } + #[inline] + pub fn set_bIsNVIDIARTXNewFeatureBranchPackage(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn reserved(&self) -> NvU32 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 27u8) as u32) } + } + #[inline] + pub fn set_reserved(&mut self, val: NvU32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 27u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + bIsDCHDriver: NvU32, + bIsNVIDIAStudioPackage: NvU32, + bIsNVIDIAGameReadyPackage: NvU32, + bIsNVIDIARTXProductionBranchPackage: NvU32, + bIsNVIDIARTXNewFeatureBranchPackage: NvU32, + reserved: NvU32, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let bIsDCHDriver: u32 = unsafe { ::std::mem::transmute(bIsDCHDriver) }; + bIsDCHDriver as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let bIsNVIDIAStudioPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIAStudioPackage) }; + bIsNVIDIAStudioPackage as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let bIsNVIDIAGameReadyPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIAGameReadyPackage) }; + bIsNVIDIAGameReadyPackage as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let bIsNVIDIARTXProductionBranchPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIARTXProductionBranchPackage) }; + bIsNVIDIARTXProductionBranchPackage as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let bIsNVIDIARTXNewFeatureBranchPackage: u32 = + unsafe { ::std::mem::transmute(bIsNVIDIARTXNewFeatureBranchPackage) }; + bIsNVIDIARTXNewFeatureBranchPackage as u64 + }); + __bindgen_bitfield_unit.set(5usize, 27u8, { + let reserved: u32 = unsafe { ::std::mem::transmute(reserved) }; + reserved as u64 + }); + __bindgen_bitfield_unit + } +} +pub type NV_DISPLAY_DRIVER_INFO_V2 = _NV_DISPLAY_DRIVER_INFO_V2; +pub type NV_DISPLAY_DRIVER_INFO = NV_DISPLAY_DRIVER_INFO_V2; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_CLIENT_CALLBACK_SETTINGS_SUPER_V1 { + pub pCallbackParam: *mut ::std::os::raw::c_void, + pub rsvd: [NvU8; 64usize], +} +pub type NV_CLIENT_CALLBACK_SETTINGS_SUPER_V1 = _NV_CLIENT_CALLBACK_SETTINGS_SUPER_V1; +pub type NV_GPU_CLIENT_CALLBACK_SETTINGS_SUPER_V1 = NV_CLIENT_CALLBACK_SETTINGS_SUPER_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_PERIODIC_CALLBACK_SETTINGS_SUPER_V1 { + pub super_: NV_GPU_CLIENT_CALLBACK_SETTINGS_SUPER_V1, + pub callbackPeriodms: NvU32, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_PERIODIC_CALLBACK_SETTINGS_SUPER_V1 = + _NV_GPU_CLIENT_PERIODIC_CALLBACK_SETTINGS_SUPER_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_CALLBACK_DATA_SUPER_V1 { + pub pCallbackParam: *mut ::std::os::raw::c_void, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_CALLBACK_DATA_SUPER_V1 = _NV_GPU_CLIENT_CALLBACK_DATA_SUPER_V1; +impl _NV_GPU_CLIENT_UTIL_DOMAIN_ID { + pub const NV_GPU_CLIENT_UTIL_DOMAIN_GRAPHICS: _NV_GPU_CLIENT_UTIL_DOMAIN_ID = + _NV_GPU_CLIENT_UTIL_DOMAIN_ID(0); +} +impl _NV_GPU_CLIENT_UTIL_DOMAIN_ID { + pub const NV_GPU_CLIENT_UTIL_DOMAIN_FRAME_BUFFER: _NV_GPU_CLIENT_UTIL_DOMAIN_ID = + _NV_GPU_CLIENT_UTIL_DOMAIN_ID(1); +} +impl _NV_GPU_CLIENT_UTIL_DOMAIN_ID { + pub const NV_GPU_CLIENT_UTIL_DOMAIN_VIDEO: _NV_GPU_CLIENT_UTIL_DOMAIN_ID = + _NV_GPU_CLIENT_UTIL_DOMAIN_ID(2); +} +impl _NV_GPU_CLIENT_UTIL_DOMAIN_ID { + pub const NV_GPU_CLIENT_UTIL_DOMAIN_RSVD: _NV_GPU_CLIENT_UTIL_DOMAIN_ID = + _NV_GPU_CLIENT_UTIL_DOMAIN_ID(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct _NV_GPU_CLIENT_UTIL_DOMAIN_ID(pub ::std::os::raw::c_int); +pub use self::_NV_GPU_CLIENT_UTIL_DOMAIN_ID as NV_GPU_CLIENT_UTIL_DOMAIN_ID; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_UTILIZATION_DATA_V1 { + pub utilId: NV_GPU_CLIENT_UTIL_DOMAIN_ID, + pub utilizationPercent: NvU32, + pub rsvd: [NvU8; 61usize], +} +pub type NV_GPU_CLIENT_UTILIZATION_DATA_V1 = _NV_GPU_CLIENT_UTILIZATION_DATA_V1; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_CALLBACK_UTILIZATION_DATA_V1 { + pub super_: NV_GPU_CLIENT_CALLBACK_DATA_SUPER_V1, + pub numUtils: NvU32, + pub timestamp: NvU64, + pub rsvd: [NvU8; 64usize], + pub utils: [NV_GPU_CLIENT_UTILIZATION_DATA_V1; 4usize], +} +pub type NV_GPU_CLIENT_CALLBACK_UTILIZATION_DATA_V1 = _NV_GPU_CLIENT_CALLBACK_UTILIZATION_DATA_V1; +pub type NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_V1 = ::std::option::Option< + unsafe extern "C" fn( + hPhysicalGpu: NvPhysicalGpuHandle, + pData: *mut NV_GPU_CLIENT_CALLBACK_UTILIZATION_DATA_V1, + ), +>; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_SETTINGS_V1 { + pub version: NvU32, + pub super_: NV_GPU_CLIENT_PERIODIC_CALLBACK_SETTINGS_SUPER_V1, + pub callback: NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_V1, + pub rsvd: [NvU8; 64usize], +} +pub type NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_SETTINGS_V1 = + _NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_SETTINGS_V1; +pub type NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_SETTINGS = + NV_GPU_CLIENT_UTILIZATION_PERIODIC_CALLBACK_SETTINGS_V1; diff --git a/zluda_api/src/nvapi_wrapper.h b/zluda_api/src/nvapi_wrapper.h new file mode 100644 index 0000000..8f40caa --- /dev/null +++ b/zluda_api/src/nvapi_wrapper.h @@ -0,0 +1,14 @@ +#define __in +#define __out +#define __inout +#define __in_opt +#define __out_opt +#define __inout_opt +#define __in_ecount(x) +#define __inout_ecount_part_opt(x,y) +#define __out_ecount_full_opt(x) +#define __inout_ecount_full(x) +#include +#include +#include +#include \ No newline at end of file diff --git a/zluda_blas/Cargo.toml b/zluda_blas/Cargo.toml new file mode 100644 index 0000000..8cc41fd --- /dev/null +++ b/zluda_blas/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "zluda_blas" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "cublas" +crate-type = ["cdylib"] + +[dependencies] +rocblas-sys = { path = "../rocblas-sys" } +rocsolver-sys = { path = "../rocsolver-sys" } +hip_common = { path = "../hip_common" } +zluda_dark_api = { path = "../zluda_dark_api" } +cuda_types = { path = "../cuda_types" } + +[package.metadata.zluda] +linux_only = true +linux_names = ["libcublas.so.10", "libcublas.so.11"] +dump_names = ["libcublas.so"] diff --git a/zluda_blas/README b/zluda_blas/README new file mode 100644 index 0000000..4b969fb --- /dev/null +++ b/zluda_blas/README @@ -0,0 +1,2 @@ +bindgen /usr/local/cuda/targets/x86_64-linux/include/cublas.h -o src/cublas.rs --allowlist-function="^cublas.*" --size_t-is-usize --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +sed -i -e 's/extern "C" {//g' -e 's/-> cublasStatus_t;/-> cublasStatus_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' src/cublas.rs \ No newline at end of file diff --git a/zluda_blas/build/wrapper.h b/zluda_blas/build/wrapper.h new file mode 100644 index 0000000..4150b8d --- /dev/null +++ b/zluda_blas/build/wrapper.h @@ -0,0 +1,2 @@ +#include +#include \ No newline at end of file diff --git a/zluda_blas/src/cublas.rs b/zluda_blas/src/cublas.rs new file mode 100644 index 0000000..b0bf587 --- /dev/null +++ b/zluda_blas/src/cublas.rs @@ -0,0 +1,6870 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[repr(align(8))] +#[derive(Copy, Clone)] +pub struct float2 { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub struct double2 { + pub x: f64, + pub y: f64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUstream_st { + _unused: [u8; 0], +} +#[doc = " CUDA stream"] +pub type cudaStream_t = *mut CUstream_st; +impl cudaDataType_t { + pub const CUDA_R_16F: cudaDataType_t = cudaDataType_t(2); +} +impl cudaDataType_t { + pub const CUDA_C_16F: cudaDataType_t = cudaDataType_t(6); +} +impl cudaDataType_t { + pub const CUDA_R_16BF: cudaDataType_t = cudaDataType_t(14); +} +impl cudaDataType_t { + pub const CUDA_C_16BF: cudaDataType_t = cudaDataType_t(15); +} +impl cudaDataType_t { + pub const CUDA_R_32F: cudaDataType_t = cudaDataType_t(0); +} +impl cudaDataType_t { + pub const CUDA_C_32F: cudaDataType_t = cudaDataType_t(4); +} +impl cudaDataType_t { + pub const CUDA_R_64F: cudaDataType_t = cudaDataType_t(1); +} +impl cudaDataType_t { + pub const CUDA_C_64F: cudaDataType_t = cudaDataType_t(5); +} +impl cudaDataType_t { + pub const CUDA_R_4I: cudaDataType_t = cudaDataType_t(16); +} +impl cudaDataType_t { + pub const CUDA_C_4I: cudaDataType_t = cudaDataType_t(17); +} +impl cudaDataType_t { + pub const CUDA_R_4U: cudaDataType_t = cudaDataType_t(18); +} +impl cudaDataType_t { + pub const CUDA_C_4U: cudaDataType_t = cudaDataType_t(19); +} +impl cudaDataType_t { + pub const CUDA_R_8I: cudaDataType_t = cudaDataType_t(3); +} +impl cudaDataType_t { + pub const CUDA_C_8I: cudaDataType_t = cudaDataType_t(7); +} +impl cudaDataType_t { + pub const CUDA_R_8U: cudaDataType_t = cudaDataType_t(8); +} +impl cudaDataType_t { + pub const CUDA_C_8U: cudaDataType_t = cudaDataType_t(9); +} +impl cudaDataType_t { + pub const CUDA_R_16I: cudaDataType_t = cudaDataType_t(20); +} +impl cudaDataType_t { + pub const CUDA_C_16I: cudaDataType_t = cudaDataType_t(21); +} +impl cudaDataType_t { + pub const CUDA_R_16U: cudaDataType_t = cudaDataType_t(22); +} +impl cudaDataType_t { + pub const CUDA_C_16U: cudaDataType_t = cudaDataType_t(23); +} +impl cudaDataType_t { + pub const CUDA_R_32I: cudaDataType_t = cudaDataType_t(10); +} +impl cudaDataType_t { + pub const CUDA_C_32I: cudaDataType_t = cudaDataType_t(11); +} +impl cudaDataType_t { + pub const CUDA_R_32U: cudaDataType_t = cudaDataType_t(12); +} +impl cudaDataType_t { + pub const CUDA_C_32U: cudaDataType_t = cudaDataType_t(13); +} +impl cudaDataType_t { + pub const CUDA_R_64I: cudaDataType_t = cudaDataType_t(24); +} +impl cudaDataType_t { + pub const CUDA_C_64I: cudaDataType_t = cudaDataType_t(25); +} +impl cudaDataType_t { + pub const CUDA_R_64U: cudaDataType_t = cudaDataType_t(26); +} +impl cudaDataType_t { + pub const CUDA_C_64U: cudaDataType_t = cudaDataType_t(27); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E4M3: cudaDataType_t = cudaDataType_t(28); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E5M2: cudaDataType_t = cudaDataType_t(29); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDataType_t(pub ::std::os::raw::c_uint); +pub use self::cudaDataType_t as cudaDataType; +impl libraryPropertyType_t { + pub const MAJOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(0); +} +impl libraryPropertyType_t { + pub const MINOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(1); +} +impl libraryPropertyType_t { + pub const PATCH_LEVEL: libraryPropertyType_t = libraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::libraryPropertyType_t as libraryPropertyType; +pub type cuFloatComplex = float2; +pub type cuDoubleComplex = double2; +pub type cuComplex = cuFloatComplex; +impl cublasStatus_t { + pub const CUBLAS_STATUS_SUCCESS: cublasStatus_t = cublasStatus_t(0); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_NOT_INITIALIZED: cublasStatus_t = cublasStatus_t(1); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_ALLOC_FAILED: cublasStatus_t = cublasStatus_t(3); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_INVALID_VALUE: cublasStatus_t = cublasStatus_t(7); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_ARCH_MISMATCH: cublasStatus_t = cublasStatus_t(8); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_MAPPING_ERROR: cublasStatus_t = cublasStatus_t(11); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_EXECUTION_FAILED: cublasStatus_t = cublasStatus_t(13); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_INTERNAL_ERROR: cublasStatus_t = cublasStatus_t(14); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_NOT_SUPPORTED: cublasStatus_t = cublasStatus_t(15); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_LICENSE_ERROR: cublasStatus_t = cublasStatus_t(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasStatus_t(pub ::std::os::raw::c_uint); +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_LOWER: cublasFillMode_t = cublasFillMode_t(0); +} +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_UPPER: cublasFillMode_t = cublasFillMode_t(1); +} +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_FULL: cublasFillMode_t = cublasFillMode_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasFillMode_t(pub ::std::os::raw::c_uint); +impl cublasDiagType_t { + pub const CUBLAS_DIAG_NON_UNIT: cublasDiagType_t = cublasDiagType_t(0); +} +impl cublasDiagType_t { + pub const CUBLAS_DIAG_UNIT: cublasDiagType_t = cublasDiagType_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasDiagType_t(pub ::std::os::raw::c_uint); +impl cublasSideMode_t { + pub const CUBLAS_SIDE_LEFT: cublasSideMode_t = cublasSideMode_t(0); +} +impl cublasSideMode_t { + pub const CUBLAS_SIDE_RIGHT: cublasSideMode_t = cublasSideMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasSideMode_t(pub ::std::os::raw::c_uint); +impl cublasOperation_t { + pub const CUBLAS_OP_N: cublasOperation_t = cublasOperation_t(0); +} +impl cublasOperation_t { + pub const CUBLAS_OP_T: cublasOperation_t = cublasOperation_t(1); +} +impl cublasOperation_t { + pub const CUBLAS_OP_C: cublasOperation_t = cublasOperation_t(2); +} +impl cublasOperation_t { + pub const CUBLAS_OP_HERMITAN: cublasOperation_t = cublasOperation_t(2); +} +impl cublasOperation_t { + pub const CUBLAS_OP_CONJG: cublasOperation_t = cublasOperation_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasOperation_t(pub ::std::os::raw::c_uint); +impl cublasPointerMode_t { + pub const CUBLAS_POINTER_MODE_HOST: cublasPointerMode_t = cublasPointerMode_t(0); +} +impl cublasPointerMode_t { + pub const CUBLAS_POINTER_MODE_DEVICE: cublasPointerMode_t = cublasPointerMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasPointerMode_t(pub ::std::os::raw::c_uint); +impl cublasAtomicsMode_t { + pub const CUBLAS_ATOMICS_NOT_ALLOWED: cublasAtomicsMode_t = cublasAtomicsMode_t(0); +} +impl cublasAtomicsMode_t { + pub const CUBLAS_ATOMICS_ALLOWED: cublasAtomicsMode_t = cublasAtomicsMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasAtomicsMode_t(pub ::std::os::raw::c_uint); +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DFALT: cublasGemmAlgo_t = cublasGemmAlgo_t(-1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DEFAULT: cublasGemmAlgo_t = cublasGemmAlgo_t(-1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO0: cublasGemmAlgo_t = cublasGemmAlgo_t(0); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO1: cublasGemmAlgo_t = cublasGemmAlgo_t(1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO2: cublasGemmAlgo_t = cublasGemmAlgo_t(2); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO3: cublasGemmAlgo_t = cublasGemmAlgo_t(3); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO4: cublasGemmAlgo_t = cublasGemmAlgo_t(4); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO5: cublasGemmAlgo_t = cublasGemmAlgo_t(5); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO6: cublasGemmAlgo_t = cublasGemmAlgo_t(6); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO7: cublasGemmAlgo_t = cublasGemmAlgo_t(7); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO8: cublasGemmAlgo_t = cublasGemmAlgo_t(8); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO9: cublasGemmAlgo_t = cublasGemmAlgo_t(9); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO10: cublasGemmAlgo_t = cublasGemmAlgo_t(10); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO11: cublasGemmAlgo_t = cublasGemmAlgo_t(11); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO12: cublasGemmAlgo_t = cublasGemmAlgo_t(12); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO13: cublasGemmAlgo_t = cublasGemmAlgo_t(13); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO14: cublasGemmAlgo_t = cublasGemmAlgo_t(14); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO15: cublasGemmAlgo_t = cublasGemmAlgo_t(15); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO16: cublasGemmAlgo_t = cublasGemmAlgo_t(16); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO17: cublasGemmAlgo_t = cublasGemmAlgo_t(17); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO18: cublasGemmAlgo_t = cublasGemmAlgo_t(18); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO19: cublasGemmAlgo_t = cublasGemmAlgo_t(19); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO20: cublasGemmAlgo_t = cublasGemmAlgo_t(20); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO21: cublasGemmAlgo_t = cublasGemmAlgo_t(21); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO22: cublasGemmAlgo_t = cublasGemmAlgo_t(22); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO23: cublasGemmAlgo_t = cublasGemmAlgo_t(23); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DEFAULT_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(99); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DFALT_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(99); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO0_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(100); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO1_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(101); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO2_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(102); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO3_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(103); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO4_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(104); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO5_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(105); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO6_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(106); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO7_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(107); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO8_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(108); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO9_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(109); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO10_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(110); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO11_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(111); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO12_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(112); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO13_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(113); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO14_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(114); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO15_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(115); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasGemmAlgo_t(pub ::std::os::raw::c_int); +impl cublasMath_t { + pub const CUBLAS_DEFAULT_MATH: cublasMath_t = cublasMath_t(0); +} +impl cublasMath_t { + pub const CUBLAS_TENSOR_OP_MATH: cublasMath_t = cublasMath_t(1); +} +impl cublasMath_t { + pub const CUBLAS_PEDANTIC_MATH: cublasMath_t = cublasMath_t(2); +} +impl cublasMath_t { + pub const CUBLAS_TF32_TENSOR_OP_MATH: cublasMath_t = cublasMath_t(3); +} +impl cublasMath_t { + pub const CUBLAS_MATH_DISALLOW_REDUCED_PRECISION_REDUCTION: cublasMath_t = cublasMath_t(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasMath_t(pub ::std::os::raw::c_uint); +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_16F: cublasComputeType_t = cublasComputeType_t(64); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_16F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(65); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F: cublasComputeType_t = cublasComputeType_t(68); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(69); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_16F: cublasComputeType_t = cublasComputeType_t(74); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_16BF: cublasComputeType_t = cublasComputeType_t(75); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_TF32: cublasComputeType_t = cublasComputeType_t(77); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_64F: cublasComputeType_t = cublasComputeType_t(70); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_64F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(71); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32I: cublasComputeType_t = cublasComputeType_t(72); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32I_PEDANTIC: cublasComputeType_t = cublasComputeType_t(73); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasComputeType_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasContext { + _unused: [u8; 0], +} +pub type cublasHandle_t = *mut cublasContext; + +#[no_mangle] +pub unsafe extern "system" fn cublasCreate_v2(handle: *mut cublasHandle_t) -> cublasStatus_t { + crate::create(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDestroy_v2(handle: cublasHandle_t) -> cublasStatus_t { + crate::destroy(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetVersion_v2( + handle: cublasHandle_t, + version: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetProperty( + type_: libraryPropertyType, + value: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetCudartVersion() -> usize { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetWorkspace_v2( + handle: cublasHandle_t, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, +) -> cublasStatus_t { + crate::set_workspace(handle, workspace, workspaceSizeInBytes) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetStream_v2( + handle: cublasHandle_t, + streamId: cudaStream_t, +) -> cublasStatus_t { + crate::set_stream(handle, streamId) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetStream_v2( + handle: cublasHandle_t, + streamId: *mut cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetPointerMode_v2( + handle: cublasHandle_t, + mode: *mut cublasPointerMode_t, +) -> cublasStatus_t { + crate::get_pointer_mode(handle, mode) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetPointerMode_v2( + handle: cublasHandle_t, + mode: cublasPointerMode_t, +) -> cublasStatus_t { + crate::set_pointer_mode(handle, mode) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetAtomicsMode( + handle: cublasHandle_t, + mode: *mut cublasAtomicsMode_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetAtomicsMode( + handle: cublasHandle_t, + mode: cublasAtomicsMode_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetMathMode( + handle: cublasHandle_t, + mode: *mut cublasMath_t, +) -> cublasStatus_t { + *mode = cublasMath_t::CUBLAS_DEFAULT_MATH; + cublasStatus_t::CUBLAS_STATUS_SUCCESS +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetMathMode( + handle: cublasHandle_t, + mode: cublasMath_t, +) -> cublasStatus_t { + crate::set_math_mode(handle, mode) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetSmCountTarget( + handle: cublasHandle_t, + smCountTarget: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetSmCountTarget( + handle: cublasHandle_t, + smCountTarget: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetStatusName( + status: cublasStatus_t, +) -> *const ::std::os::raw::c_char { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetStatusString( + status: cublasStatus_t, +) -> *const ::std::os::raw::c_char { + unimplemented!() +} + +pub type cublasLogCallback = + ::std::option::Option; + +#[no_mangle] +pub unsafe extern "system" fn cublasLoggerConfigure( + logIsOn: ::std::os::raw::c_int, + logToStdOut: ::std::os::raw::c_int, + logToStdErr: ::std::os::raw::c_int, + logFileName: *const ::std::os::raw::c_char, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetLoggerCallback( + userCallback: cublasLogCallback, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetLoggerCallback( + userCallback: *mut cublasLogCallback, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetVector( + n: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + incx: ::std::os::raw::c_int, + devicePtr: *mut ::std::os::raw::c_void, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetVector( + n: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetMatrix( + rows: ::std::os::raw::c_int, + cols: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + A: *const ::std::os::raw::c_void, + lda: ::std::os::raw::c_int, + B: *mut ::std::os::raw::c_void, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetMatrix( + rows: ::std::os::raw::c_int, + cols: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + A: *const ::std::os::raw::c_void, + lda: ::std::os::raw::c_int, + B: *mut ::std::os::raw::c_void, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetVectorAsync( + n: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + hostPtr: *const ::std::os::raw::c_void, + incx: ::std::os::raw::c_int, + devicePtr: *mut ::std::os::raw::c_void, + incy: ::std::os::raw::c_int, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetVectorAsync( + n: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + devicePtr: *const ::std::os::raw::c_void, + incx: ::std::os::raw::c_int, + hostPtr: *mut ::std::os::raw::c_void, + incy: ::std::os::raw::c_int, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetMatrixAsync( + rows: ::std::os::raw::c_int, + cols: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + A: *const ::std::os::raw::c_void, + lda: ::std::os::raw::c_int, + B: *mut ::std::os::raw::c_void, + ldb: ::std::os::raw::c_int, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetMatrixAsync( + rows: ::std::os::raw::c_int, + cols: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + A: *const ::std::os::raw::c_void, + lda: ::std::os::raw::c_int, + B: *mut ::std::os::raw::c_void, + ldb: ::std::os::raw::c_int, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasXerbla( + srName: *const ::std::os::raw::c_char, + info: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasNrm2Ex( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_void, + resultType: cudaDataType, + executionType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSnrm2_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + result: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDnrm2_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + result: *mut f64, +) -> cublasStatus_t { + crate::dnrm_v2(handle, n, x, incx, result) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScnrm2_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + result: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDznrm2_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + result: *mut f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDotEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *const ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_void, + resultType: cudaDataType, + executionType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDotcEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *const ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_void, + resultType: cudaDataType, + executionType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSdot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + result: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDdot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + result: *mut f64, +) -> cublasStatus_t { + crate::ddot_v2(handle, n, x, incx, y, incy, result) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCdotu_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + result: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCdotc_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + result: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdotu_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + result: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdotc_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + result: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScalEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + alphaType: cudaDataType, + x: *mut ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + executionType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dscal_v2(handle, n, alpha, x, incx) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdscal_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasAxpyEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + alphaType: cudaDataType, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSaxpy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDaxpy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::daxpy_v2(handle, n, alpha, x, incx, y, incy) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCaxpy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZaxpy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCopyEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScopy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDcopy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCcopy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZcopy_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSswap_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDswap_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dswap(handle, n, x, incx, y, incy) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCswap_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZswap_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSwapEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIsamax_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIdamax_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::idamax_v2(handle, n, x, incx, result) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIcamax_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIzamax_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIamaxEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIsamin_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIdamin_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIcamin_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIzamin_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIaminEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasAsumEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + result: *mut ::std::os::raw::c_void, + resultType: cudaDataType, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSasum_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + result: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDasum_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + result: *mut f64, +) -> cublasStatus_t { + crate::dasum_v2(handle, n, x, incx, result) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScasum_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + result: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDzasum_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + result: *mut f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, + c: *const f32, + s: *const f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, + c: *const f64, + s: *const f64, +) -> cublasStatus_t { + crate::drot_v2(handle, n, x, incx, y, incy, c, s) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, + c: *const f32, + s: *const cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, + c: *const f32, + s: *const f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + c: *const f64, + s: *const cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdrot_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + c: *const f64, + s: *const f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasRotEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, + c: *const ::std::os::raw::c_void, + s: *const ::std::os::raw::c_void, + csType: cudaDataType, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotg_v2( + handle: cublasHandle_t, + a: *mut f32, + b: *mut f32, + c: *mut f32, + s: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotg_v2( + handle: cublasHandle_t, + a: *mut f64, + b: *mut f64, + c: *mut f64, + s: *mut f64, +) -> cublasStatus_t { + crate::drotg(handle, a, b, c, s) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCrotg_v2( + handle: cublasHandle_t, + a: *mut cuComplex, + b: *mut cuComplex, + c: *mut f32, + s: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZrotg_v2( + handle: cublasHandle_t, + a: *mut cuDoubleComplex, + b: *mut cuDoubleComplex, + c: *mut f64, + s: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasRotgEx( + handle: cublasHandle_t, + a: *mut ::std::os::raw::c_void, + b: *mut ::std::os::raw::c_void, + abType: cudaDataType, + c: *mut ::std::os::raw::c_void, + s: *mut ::std::os::raw::c_void, + csType: cudaDataType, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotm_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, + param: *const f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotm_v2( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, + param: *const f64, +) -> cublasStatus_t { + crate::drotm(handle, n, x, incx, y, incy, param) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasRotmEx( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + x: *mut ::std::os::raw::c_void, + xType: cudaDataType, + incx: ::std::os::raw::c_int, + y: *mut ::std::os::raw::c_void, + yType: cudaDataType, + incy: ::std::os::raw::c_int, + param: *const ::std::os::raw::c_void, + paramType: cudaDataType, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotmg_v2( + handle: cublasHandle_t, + d1: *mut f32, + d2: *mut f32, + x1: *mut f32, + y1: *const f32, + param: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotmg_v2( + handle: cublasHandle_t, + d1: *mut f64, + d2: *mut f64, + x1: *mut f64, + y1: *const f64, + param: *mut f64, +) -> cublasStatus_t { + crate::drotmg(handle, d1, d2, x1, y1, param) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasRotmgEx( + handle: cublasHandle_t, + d1: *mut ::std::os::raw::c_void, + d1Type: cudaDataType, + d2: *mut ::std::os::raw::c_void, + d2Type: cudaDataType, + x1: *mut ::std::os::raw::c_void, + x1Type: cudaDataType, + y1: *const ::std::os::raw::c_void, + y1Type: cudaDataType, + param: *mut ::std::os::raw::c_void, + paramType: cudaDataType, + executiontype: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::sgemv(handle, trans, m, n, alpha, A, lda, x, incx, beta, y, incy) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dgemv_v2(handle, trans, m, n, alpha, A, lda, x, incx, beta, y, incy) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgbmv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgbmv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgbmv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgbmv_v2( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStpsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtpsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtpsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtpsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + AP: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStbsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtbsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtbsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtbsv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsymv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsymv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsymv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsymv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChemv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhemv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhbmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + AP: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + AP: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + AP: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpmv_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + AP: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSger_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDger_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dger(handle, m, n, alpha, x, incx, y, incy, A, lda) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgeru_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgerc_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgeru_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgerc_v2( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + AP: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + AP: *mut f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + AP: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpr_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + AP: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + AP: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + AP: *mut f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + AP: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpr2_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + AP: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemvBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + Aarray: *const *const f32, + lda: ::std::os::raw::c_int, + xarray: *const *const f32, + incx: ::std::os::raw::c_int, + beta: *const f32, + yarray: *const *mut f32, + incy: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemvBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + Aarray: *const *const f64, + lda: ::std::os::raw::c_int, + xarray: *const *const f64, + incx: ::std::os::raw::c_int, + beta: *const f64, + yarray: *const *mut f64, + incy: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemvBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + Aarray: *const *const cuComplex, + lda: ::std::os::raw::c_int, + xarray: *const *const cuComplex, + incx: ::std::os::raw::c_int, + beta: *const cuComplex, + yarray: *const *mut cuComplex, + incy: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemvBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + Aarray: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + xarray: *const *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + yarray: *const *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemvStridedBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + x: *const f32, + incx: ::std::os::raw::c_int, + stridex: ::std::os::raw::c_longlong, + beta: *const f32, + y: *mut f32, + incy: ::std::os::raw::c_int, + stridey: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemvStridedBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + x: *const f64, + incx: ::std::os::raw::c_int, + stridex: ::std::os::raw::c_longlong, + beta: *const f64, + y: *mut f64, + incy: ::std::os::raw::c_int, + stridey: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemvStridedBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + stridex: ::std::os::raw::c_longlong, + beta: *const cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, + stridey: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemvStridedBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + stridex: ::std::os::raw::c_longlong, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + stridey: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemm_v2( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::sgemm_v2( + handle, transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemm_v2( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dgemm( + handle, transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm_v2( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm3m( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm3mEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + B: *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemm_v2( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemm3m( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemmEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + B: *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::sgemm_ex( + handle, transa, transb, m, n, k, alpha, A, Atype, lda, B, Btype, ldb, beta, C, Ctype, ldc, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGemmEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + B: *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + beta: *const ::std::os::raw::c_void, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, + computeType: cublasComputeType_t, + algo: cublasGemmAlgo_t, +) -> cublasStatus_t { + crate::gemm_ex( + handle, + transa, + transb, + m, + n, + k, + alpha, + A, + Atype, + lda, + B, + Btype, + ldb, + beta, + C, + Ctype, + ldc, + computeType, + algo, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemmEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + B: *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasUint8gemmBias( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + transc: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const ::std::os::raw::c_uchar, + A_bias: ::std::os::raw::c_int, + lda: ::std::os::raw::c_int, + B: *const ::std::os::raw::c_uchar, + B_bias: ::std::os::raw::c_int, + ldb: ::std::os::raw::c_int, + C: *mut ::std::os::raw::c_uchar, + C_bias: ::std::os::raw::c_int, + ldc: ::std::os::raw::c_int, + C_mult: ::std::os::raw::c_int, + C_shift: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyrk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyrk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyrk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyrk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyrkEx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyrk3mEx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCherk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + beta: *const f32, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZherk_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + beta: *const f64, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCherkEx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + beta: *const f32, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCherk3mEx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + beta: *const f32, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyr2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyr2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher2k_v2( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyrkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyrkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyrkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyrkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCherkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZherkx( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsymm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsymm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsymm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsymm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChemm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhemm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrsm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *mut f32, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrsm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *mut f64, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dtrsm(handle, side, uplo, trans, diag, m, n, alpha, A, lda, B, ldb) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrsm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrsm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrmm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrmm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dtrmm_v2( + handle, side, uplo, trans, diag, m, n, alpha, A, lda, B, ldb, C, ldc, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrmm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrmm_v2( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemmBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + Aarray: *const *const f32, + lda: ::std::os::raw::c_int, + Barray: *const *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + Carray: *const *mut f32, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemmBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + Aarray: *const *const f64, + lda: ::std::os::raw::c_int, + Barray: *const *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + Carray: *const *mut f64, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemmBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + Aarray: *const *const cuComplex, + lda: ::std::os::raw::c_int, + Barray: *const *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + Carray: *const *mut cuComplex, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm3mBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + Aarray: *const *const cuComplex, + lda: ::std::os::raw::c_int, + Barray: *const *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + Carray: *const *mut cuComplex, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemmBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + Aarray: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + Barray: *const *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + Carray: *const *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGemmBatchedEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + Aarray: *const *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + Barray: *const *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + beta: *const ::std::os::raw::c_void, + Carray: *const *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, + computeType: cublasComputeType_t, + algo: cublasGemmAlgo_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGemmStridedBatchedEx( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + Atype: cudaDataType, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const ::std::os::raw::c_void, + Btype: cudaDataType, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const ::std::os::raw::c_void, + C: *mut ::std::os::raw::c_void, + Ctype: cudaDataType, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, + computeType: cublasComputeType_t, + algo: cublasGemmAlgo_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemmStridedBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const f32, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::sgemm_strided_batch( + handle, transa, transb, m, n, k, alpha, A, lda, strideA, B, ldb, strideB, beta, C, ldc, + strideC, batchCount, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemmStridedBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const f64, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::dgemm_strided_batch( + handle, transa, transb, m, n, k, alpha, A, lda, strideA, B, ldb, strideB, beta, C, ldc, + strideC, batchCount, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemmStridedBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::cgemm_strided_batch( + handle, transa, transb, m, n, k, alpha, A, lda, strideA, B, ldb, strideB, beta, C, ldc, + strideC, batchCount, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm3mStridedBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemmStridedBatched( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + strideA: ::std::os::raw::c_longlong, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + strideB: ::std::os::raw::c_longlong, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, + strideC: ::std::os::raw::c_longlong, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::zgemm_strided_batch( + handle, transa, transb, m, n, k, alpha, A, lda, strideA, B, ldb, strideB, beta, C, ldc, + strideC, batchCount, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgeam( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + beta: *const f32, + B: *const f32, + ldb: ::std::os::raw::c_int, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgeam( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + beta: *const f64, + B: *const f64, + ldb: ::std::os::raw::c_int, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgeam( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + beta: *const cuComplex, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgeam( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgetrfBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *mut f32, + lda: ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgetrfBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *mut f64, + lda: ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgetrfBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *mut cuComplex, + lda: ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::cgetrf_batched(handle, n, A, lda, P, info, batchSize) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgetrfBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::zgetrf_batched(handle, n, A, lda, P, info, batchSize) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgetriBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const f32, + lda: ::std::os::raw::c_int, + P: *const ::std::os::raw::c_int, + C: *const *mut f32, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgetriBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const f64, + lda: ::std::os::raw::c_int, + P: *const ::std::os::raw::c_int, + C: *const *mut f64, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgetriBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const cuComplex, + lda: ::std::os::raw::c_int, + P: *const ::std::os::raw::c_int, + C: *const *mut cuComplex, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::cgetri_batched(handle, n, A, lda, P, C, ldc, info, batchSize) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgetriBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + P: *const ::std::os::raw::c_int, + C: *const *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::zgetri_batched(handle, n, A, lda, P, C, ldc, info, batchSize) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgetrsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *const f32, + lda: ::std::os::raw::c_int, + devIpiv: *const ::std::os::raw::c_int, + Barray: *const *mut f32, + ldb: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgetrsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *const f64, + lda: ::std::os::raw::c_int, + devIpiv: *const ::std::os::raw::c_int, + Barray: *const *mut f64, + ldb: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgetrsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *const cuComplex, + lda: ::std::os::raw::c_int, + devIpiv: *const ::std::os::raw::c_int, + Barray: *const *mut cuComplex, + ldb: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgetrsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + devIpiv: *const ::std::os::raw::c_int, + Barray: *const *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrsmBatched( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const *const f32, + lda: ::std::os::raw::c_int, + B: *const *mut f32, + ldb: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrsmBatched( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const *const f64, + lda: ::std::os::raw::c_int, + B: *const *mut f64, + ldb: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrsmBatched( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const *mut cuComplex, + ldb: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrsmBatched( + handle: cublasHandle_t, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, + batchCount: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSmatinvBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const f32, + lda: ::std::os::raw::c_int, + Ainv: *const *mut f32, + lda_inv: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDmatinvBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const f64, + lda: ::std::os::raw::c_int, + Ainv: *const *mut f64, + lda_inv: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCmatinvBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const cuComplex, + lda: ::std::os::raw::c_int, + Ainv: *const *mut cuComplex, + lda_inv: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZmatinvBatched( + handle: cublasHandle_t, + n: ::std::os::raw::c_int, + A: *const *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + Ainv: *const *mut cuDoubleComplex, + lda_inv: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgeqrfBatched( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + Aarray: *const *mut f32, + lda: ::std::os::raw::c_int, + TauArray: *const *mut f32, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgeqrfBatched( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + Aarray: *const *mut f64, + lda: ::std::os::raw::c_int, + TauArray: *const *mut f64, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgeqrfBatched( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + Aarray: *const *mut cuComplex, + lda: ::std::os::raw::c_int, + TauArray: *const *mut cuComplex, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgeqrfBatched( + handle: cublasHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + Aarray: *const *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, + TauArray: *const *mut cuDoubleComplex, + info: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgelsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *mut f32, + lda: ::std::os::raw::c_int, + Carray: *const *mut f32, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + devInfoArray: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgelsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *mut f64, + lda: ::std::os::raw::c_int, + Carray: *const *mut f64, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + devInfoArray: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgelsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *mut cuComplex, + lda: ::std::os::raw::c_int, + Carray: *const *mut cuComplex, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + devInfoArray: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgelsBatched( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + Aarray: *const *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, + Carray: *const *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, + info: *mut ::std::os::raw::c_int, + devInfoArray: *mut ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSdgmm( + handle: cublasHandle_t, + mode: cublasSideMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDdgmm( + handle: cublasHandle_t, + mode: cublasSideMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCdgmm( + handle: cublasHandle_t, + mode: cublasSideMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdgmm( + handle: cublasHandle_t, + mode: cublasSideMode_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStpttr( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + AP: *const f32, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtpttr( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + AP: *const f64, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtpttr( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + AP: *const cuComplex, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtpttr( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + AP: *const cuDoubleComplex, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrttp( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + AP: *mut f32, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrttp( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + AP: *mut f64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrttp( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + AP: *mut cuComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrttp( + handle: cublasHandle_t, + uplo: cublasFillMode_t, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + AP: *mut cuDoubleComplex, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasInit() -> cublasStatus_t { + crate::init() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasShutdown() -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetError() -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasGetVersion( + version: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasAlloc( + n: ::std::os::raw::c_int, + elemSize: ::std::os::raw::c_int, + devicePtr: *mut *mut ::std::os::raw::c_void, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasFree(devicePtr: *mut ::std::os::raw::c_void) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSetKernelStream(stream: cudaStream_t) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSnrm2( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, +) -> f32 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDnrm2( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, +) -> f64 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScnrm2( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, +) -> f32 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDznrm2( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> f64 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSdot( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, +) -> f32 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDdot( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, +) -> f64 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCdotu( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, +) -> cuComplex { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCdotc( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, +) -> cuComplex { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdotu( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cuDoubleComplex { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdotc( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, +) -> cuDoubleComplex { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSscal( + n: ::std::os::raw::c_int, + alpha: f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDscal( + n: ::std::os::raw::c_int, + alpha: f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCscal( + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZscal( + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsscal( + n: ::std::os::raw::c_int, + alpha: f32, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdscal( + n: ::std::os::raw::c_int, + alpha: f64, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSaxpy( + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDaxpy( + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCaxpy( + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZaxpy( + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScopy( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDcopy( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCcopy( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZcopy( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSswap( + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDswap( + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCswap( + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZswap( + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIsamax( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIdamax( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIcamax( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIzamax( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIsamin( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIdamin( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIcamin( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasIzamin( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> ::std::os::raw::c_int { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSasum( + n: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, +) -> f32 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDasum( + n: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, +) -> f64 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasScasum( + n: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, +) -> f32 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDzasum( + n: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, +) -> f64 { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrot( + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, + sc: f32, + ss: f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrot( + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, + sc: f64, + ss: f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCrot( + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, + c: f32, + s: cuComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZrot( + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + sc: f64, + cs: cuDoubleComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsrot( + n: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, + c: f32, + s: f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZdrot( + n: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, + c: f64, + s: f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotg(sa: *mut f32, sb: *mut f32, sc: *mut f32, ss: *mut f32) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotg(sa: *mut f64, sb: *mut f64, sc: *mut f64, ss: *mut f64) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCrotg( + ca: *mut cuComplex, + cb: cuComplex, + sc: *mut f32, + cs: *mut cuComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZrotg( + ca: *mut cuDoubleComplex, + cb: cuDoubleComplex, + sc: *mut f64, + cs: *mut cuDoubleComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotm( + n: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, + y: *mut f32, + incy: ::std::os::raw::c_int, + sparam: *const f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotm( + n: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, + y: *mut f64, + incy: ::std::os::raw::c_int, + sparam: *const f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSrotmg( + sd1: *mut f32, + sd2: *mut f32, + sx1: *mut f32, + sy1: *const f32, + sparam: *mut f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDrotmg( + sd1: *mut f64, + sd2: *mut f64, + sx1: *mut f64, + sy1: *const f64, + sparam: *mut f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgbmv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgbmv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgbmv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgbmv( + trans: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kl: ::std::os::raw::c_int, + ku: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStbmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtbmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtbmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtbmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStpmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtpmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtpmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtpmv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStpsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const f32, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtpsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const f64, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtpsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const cuComplex, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtpsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + AP: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStbsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *mut f32, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtbsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *mut f64, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtbsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *mut cuComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtbsv( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *mut cuDoubleComplex, + incx: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsymv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsymv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChemv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhemv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsbmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsbmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChbmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhbmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + AP: *const f32, + x: *const f32, + incx: ::std::os::raw::c_int, + beta: f32, + y: *mut f32, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + AP: *const f64, + x: *const f64, + incx: ::std::os::raw::c_int, + beta: f64, + y: *mut f64, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuComplex, + AP: *const cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + beta: cuComplex, + y: *mut cuComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpmv( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + AP: *const cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + beta: cuDoubleComplex, + y: *mut cuDoubleComplex, + incy: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSger( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDger( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgeru( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgerc( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgeru( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgerc( + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + AP: *mut f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + AP: *mut f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + AP: *mut cuComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpr( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + AP: *mut cuDoubleComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSspr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f32, + x: *const f32, + incx: ::std::os::raw::c_int, + y: *const f32, + incy: ::std::os::raw::c_int, + AP: *mut f32, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDspr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: f64, + x: *const f64, + incx: ::std::os::raw::c_int, + y: *const f64, + incy: ::std::os::raw::c_int, + AP: *mut f64, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChpr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuComplex, + x: *const cuComplex, + incx: ::std::os::raw::c_int, + y: *const cuComplex, + incy: ::std::os::raw::c_int, + AP: *mut cuComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhpr2( + uplo: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + x: *const cuDoubleComplex, + incx: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + incy: ::std::os::raw::c_int, + AP: *mut cuDoubleComplex, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSgemm( + transa: ::std::os::raw::c_char, + transb: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDgemm( + transa: ::std::os::raw::c_char, + transb: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCgemm( + transa: ::std::os::raw::c_char, + transb: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZgemm( + transa: ::std::os::raw::c_char, + transb: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyrk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + beta: f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyrk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + beta: f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyrk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + beta: cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyrk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + beta: cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCherk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f32, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + beta: f32, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZherk( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f64, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + beta: f64, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsyr2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsyr2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsyr2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsyr2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCher2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: f32, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZher2k( + uplo: ::std::os::raw::c_char, + trans: ::std::os::raw::c_char, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: f64, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasSsymm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDsymm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCsymm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZsymm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasChemm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZhemm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrsm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *mut f32, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrsm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *mut f64, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrsm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrsm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasStrmm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f32, + A: *const f32, + lda: ::std::os::raw::c_int, + B: *mut f32, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasDtrmm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: f64, + A: *const f64, + lda: ::std::os::raw::c_int, + B: *mut f64, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasCtrmm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasZtrmm( + side: ::std::os::raw::c_char, + uplo: ::std::os::raw::c_char, + transa: ::std::os::raw::c_char, + diag: ::std::os::raw::c_char, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, +) { + unimplemented!() +} diff --git a/zluda_blas/src/lib.rs b/zluda_blas/src/lib.rs new file mode 100644 index 0000000..0d50a99 --- /dev/null +++ b/zluda_blas/src/lib.rs @@ -0,0 +1,918 @@ +#![allow(warnings)] +mod cublas; + +pub use cublas::*; + +use cuda_types::*; +use rocblas_sys::*; +use rocsolver_sys::{ + rocsolver_cgetrf_batched, rocsolver_cgetri_batched, rocsolver_cgetri_outofplace_batched, + rocsolver_zgetrf_batched, rocsolver_zgetri_batched, rocsolver_zgetri_outofplace_batched, +}; +use std::{mem, ptr}; + +#[cfg(debug_assertions)] +pub(crate) fn unsupported() -> cublasStatus_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unsupported() -> cublasStatus_t { + cublasStatus_t::CUBLAS_STATUS_NOT_SUPPORTED +} + +fn to_cuda(status: rocblas_sys::rocblas_status) -> cublasStatus_t { + match status { + rocblas_sys::rocblas_status::rocblas_status_success => { + cublasStatus_t::CUBLAS_STATUS_SUCCESS + } + _ => cublasStatus_t::CUBLAS_STATUS_INTERNAL_ERROR, + } +} + +fn to_cuda_solver(status: rocsolver_sys::rocblas_status) -> cublasStatus_t { + match status { + rocsolver_sys::rocblas_status::rocblas_status_success => { + cublasStatus_t::CUBLAS_STATUS_SUCCESS + } + _ => cublasStatus_t::CUBLAS_STATUS_INTERNAL_ERROR, + } +} + +unsafe fn create(handle: *mut cublasHandle_t) -> cublasStatus_t { + to_cuda(rocblas_sys::rocblas_create_handle(handle as _)) +} + +unsafe fn sgemv( + handle: cublasHandle_t, + trans: cublasOperation_t, + m: i32, + n: i32, + alpha: *const f32, + a: *const f32, + lda: i32, + x: *const f32, + incx: i32, + beta: *const f32, + y: *mut f32, + incy: i32, +) -> cublasStatus_t { + let trans = op_from_cuda(trans); + to_cuda(rocblas_sgemv( + handle as _, + trans, + m, + n, + alpha, + a, + lda, + x, + incx, + beta, + y, + incy, + )) +} + +fn op_from_cuda(trans: cublasOperation_t) -> rocblas_operation { + match trans { + cublasOperation_t::CUBLAS_OP_N => rocblas_operation::rocblas_operation_none, + cublasOperation_t::CUBLAS_OP_T => rocblas_operation::rocblas_operation_transpose, + cublasOperation_t::CUBLAS_OP_C => rocblas_operation::rocblas_operation_conjugate_transpose, + _ => panic!(), + } +} + +unsafe fn destroy(handle: cublasHandle_t) -> cublasStatus_t { + to_cuda(rocblas_destroy_handle(handle as _)) +} + +unsafe fn sgemm_ex( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const f32, + a: *const std::ffi::c_void, + atype: cudaDataType, + lda: i32, + b: *const std::ffi::c_void, + btype: cudaDataType, + ldb: i32, + beta: *const f32, + c: *mut std::ffi::c_void, + ctype: cudaDataType, + ldc: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + let a_type = type_from_cuda(atype); + let b_type = type_from_cuda(btype); + let c_type = type_from_cuda(ctype); + to_cuda(rocblas_gemm_ex( + handle as _, + transa, + transb, + m, + n, + k, + alpha as _, + a as _, + a_type, + lda, + b as _, + b_type, + ldb, + beta as _, + c as _, + c_type, + ldc, + c as _, + c_type, + ldc, + rocblas_datatype::rocblas_datatype_f32_r, + rocblas_gemm_algo::rocblas_gemm_algo_standard, + 0, + 0, + )) +} + +fn type_from_cuda(type_: cudaDataType_t) -> rocblas_datatype { + match type_ { + cudaDataType_t::CUDA_R_16F => rocblas_datatype::rocblas_datatype_f16_r, + cudaDataType_t::CUDA_R_32F => rocblas_datatype::rocblas_datatype_f32_r, + cudaDataType_t::CUDA_R_64F => rocblas_datatype::rocblas_datatype_f64_r, + cudaDataType_t::CUDA_C_16F => rocblas_datatype::rocblas_datatype_f16_c, + cudaDataType_t::CUDA_C_32F => rocblas_datatype::rocblas_datatype_f32_c, + cudaDataType_t::CUDA_C_64F => rocblas_datatype::rocblas_datatype_f64_c, + cudaDataType_t::CUDA_R_8I => rocblas_datatype::rocblas_datatype_i8_r, + cudaDataType_t::CUDA_R_8U => rocblas_datatype::rocblas_datatype_u8_r, + cudaDataType_t::CUDA_R_32I => rocblas_datatype::rocblas_datatype_i32_r, + cudaDataType_t::CUDA_R_32U => rocblas_datatype::rocblas_datatype_u32_r, + cudaDataType_t::CUDA_C_8I => rocblas_datatype::rocblas_datatype_i8_c, + cudaDataType_t::CUDA_C_8U => rocblas_datatype::rocblas_datatype_u8_c, + cudaDataType_t::CUDA_C_32I => rocblas_datatype::rocblas_datatype_i32_c, + cudaDataType_t::CUDA_C_32U => rocblas_datatype::rocblas_datatype_u32_c, + cudaDataType_t::CUDA_R_16BF => rocblas_datatype::rocblas_datatype_bf16_r, + cudaDataType_t::CUDA_C_16BF => rocblas_datatype::rocblas_datatype_bf16_c, + _ => panic!(), + } +} + +unsafe fn set_stream(handle: cublasHandle_t, stream_id: cudaStream_t) -> cublasStatus_t { + let lib = hip_common::zluda_ext::get_cuda_library().unwrap(); + let cu_get_export_table = lib + .get:: CUresult>(b"cuGetExportTable\0") + .unwrap(); + let mut export_table = ptr::null(); + (cu_get_export_table)(&mut export_table, &zluda_dark_api::ZludaExt::GUID); + let zluda_ext = zluda_dark_api::ZludaExt::new(export_table); + let stream: Result<_, _> = zluda_ext.get_hip_stream(stream_id as _).into(); + to_cuda(rocblas_set_stream(handle as _, stream.unwrap() as _)) +} + +fn set_math_mode(handle: cublasHandle_t, mode: cublasMath_t) -> cublasStatus_t { + // llama.cpp uses CUBLAS_TF32_TENSOR_OP_MATH + cublasStatus_t::CUBLAS_STATUS_SUCCESS +} + +unsafe fn sgemm_v2( + handle: cublasHandle_t, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const f32, + a: *const f32, + lda: i32, + b: *const f32, + ldb: i32, + beta: *const f32, + c: *mut f32, + ldc: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_sgemm( + handle as _, + transa, + transb, + m, + n, + k, + alpha, + a, + lda, + b, + ldb, + beta, + c, + ldc, + )) +} + +unsafe fn init() -> cublasStatus_t { + rocblas_initialize(); + cublasStatus_t::CUBLAS_STATUS_SUCCESS +} + +unsafe fn dasum_v2( + handle: *mut cublasContext, + n: i32, + x: *const f64, + incx: i32, + result: *mut f64, +) -> cublasStatus_t { + to_cuda(rocblas_dasum(handle as _, n, x, incx, result)) +} + +unsafe fn daxpy_v2( + handle: *mut cublasContext, + n: i32, + alpha: *const f64, + x: *const f64, + incx: i32, + y: *mut f64, + incy: i32, +) -> cublasStatus_t { + to_cuda(rocblas_daxpy(handle as _, n, alpha, x, incx, y, incy)) +} + +unsafe fn ddot_v2( + handle: *mut cublasContext, + n: i32, + x: *const f64, + incx: i32, + y: *const f64, + incy: i32, + result: *mut f64, +) -> cublasStatus_t { + to_cuda(rocblas_ddot(handle as _, n, x, incx, y, incy, result)) +} + +unsafe fn dscal_v2( + handle: *mut cublasContext, + n: i32, + alpha: *const f64, + x: *mut f64, + incx: i32, +) -> cublasStatus_t { + to_cuda(rocblas_dscal(handle as _, n, alpha, x, incx)) +} + +unsafe fn dnrm_v2( + handle: *mut cublasContext, + n: i32, + x: *const f64, + incx: i32, + result: *mut f64, +) -> cublasStatus_t { + to_cuda(rocblas_dnrm2(handle.cast(), n, x, incx, result)) +} + +unsafe fn idamax_v2( + handle: *mut cublasContext, + n: i32, + x: *const f64, + incx: i32, + result: *mut i32, +) -> cublasStatus_t { + to_cuda(rocblas_idamax(handle.cast(), n, x, incx, result)) +} + +unsafe fn set_workspace( + handle: *mut cublasContext, + workspace: *mut std::ffi::c_void, + workspace_size_in_bytes: usize, +) -> cublasStatus_t { + to_cuda(rocblas_set_workspace( + handle.cast(), + workspace, + workspace_size_in_bytes, + )) +} + +unsafe fn gemm_ex( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const std::ffi::c_void, + a: *const std::ffi::c_void, + atype: cudaDataType_t, + lda: i32, + b: *const std::ffi::c_void, + btype: cudaDataType_t, + ldb: i32, + beta: *const std::ffi::c_void, + c: *mut std::ffi::c_void, + ctype: cudaDataType_t, + ldc: i32, + compute_type: cublasComputeType_t, + algo: cublasGemmAlgo_t, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + let atype = type_from_cuda(atype); + let btype = type_from_cuda(btype); + let ctype = type_from_cuda(ctype); + let compute_type = to_compute_type(compute_type); + let algo = to_algo(algo); + to_cuda(rocblas_gemm_ex( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha, + a, + atype, + lda, + b, + btype, + ldb, + beta, + c, + ctype, + ldc, + c, + ctype, + ldc, + compute_type, + algo, + 0, + 0, + )) +} + +fn to_algo(algo: cublasGemmAlgo_t) -> rocblas_gemm_algo_ { + // only option + rocblas_gemm_algo::rocblas_gemm_algo_standard +} + +fn to_compute_type(compute_type: cublasComputeType_t) -> rocblas_datatype { + match compute_type { + cublasComputeType_t::CUBLAS_COMPUTE_16F + | cublasComputeType_t::CUBLAS_COMPUTE_16F_PEDANTIC + | cublasComputeType_t::CUBLAS_COMPUTE_32F_FAST_16F => { + rocblas_datatype::rocblas_datatype_f16_r + } + cublasComputeType_t::CUBLAS_COMPUTE_32F + | cublasComputeType_t::CUBLAS_COMPUTE_32F_PEDANTIC + | cublasComputeType_t::CUBLAS_COMPUTE_32F_FAST_TF32 => { + rocblas_datatype::rocblas_datatype_f32_r + } + cublasComputeType_t::CUBLAS_COMPUTE_32F_FAST_16BF => { + rocblas_datatype::rocblas_datatype_bf16_r + } + cublasComputeType_t::CUBLAS_COMPUTE_64F + | cublasComputeType_t::CUBLAS_COMPUTE_64F_PEDANTIC => { + rocblas_datatype::rocblas_datatype_f64_r + } + cublasComputeType_t::CUBLAS_COMPUTE_32I + | cublasComputeType_t::CUBLAS_COMPUTE_32I_PEDANTIC => { + rocblas_datatype::rocblas_datatype_i32_r + } + _ => panic!(), + } +} + +unsafe fn zgemm_strided_batch( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const double2, + a: *const double2, + lda: i32, + stride_a: i64, + b: *const double2, + ldb: i32, + stride_b: i64, + beta: *const double2, + c: *mut double2, + ldc: i32, + stride_c: i64, + batch_count: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_zgemm_strided_batched( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha.cast(), + a.cast(), + lda, + stride_a, + b.cast(), + ldb, + stride_b, + beta.cast(), + c.cast(), + ldc, + stride_c, + batch_count, + )) +} + +unsafe fn cgemm_strided_batch( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const float2, + a: *const float2, + lda: i32, + stride_a: i64, + b: *const float2, + ldb: i32, + stride_b: i64, + beta: *const float2, + c: *mut float2, + ldc: i32, + stride_c: i64, + batch_count: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_cgemm_strided_batched( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha.cast(), + a.cast(), + lda, + stride_a, + b.cast(), + ldb, + stride_b, + beta.cast(), + c.cast(), + ldc, + stride_c, + batch_count, + )) +} + +unsafe fn dgemm_strided_batch( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const f64, + a: *const f64, + lda: i32, + stride_a: i64, + b: *const f64, + ldb: i32, + stride_b: i64, + beta: *const f64, + c: *mut f64, + ldc: i32, + stride_c: i64, + batch_count: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_dgemm_strided_batched( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha, + a, + lda, + stride_a, + b, + ldb, + stride_b, + beta, + c, + ldc, + stride_c, + batch_count, + )) +} + +unsafe fn sgemm_strided_batch( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const f32, + a: *const f32, + lda: i32, + stride_a: i64, + b: *const f32, + ldb: i32, + stride_b: i64, + beta: *const f32, + c: *mut f32, + ldc: i32, + stride_c: i64, + batch_count: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_sgemm_strided_batched( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha, + a, + lda, + stride_a, + b, + ldb, + stride_b, + beta, + c, + ldc, + stride_c, + batch_count, + )) +} + +unsafe fn zgetrf_batched( + handle: *mut cublasContext, + n: i32, + a: *const *mut double2, + lda: i32, + p: *mut i32, + info: *mut i32, + batch_size: i32, +) -> cublasStatus_t { + to_cuda_solver(rocsolver_zgetrf_batched( + handle.cast(), + n, + n, + a.cast(), + lda, + p, + n as i64, + info, + batch_size, + )) +} + +unsafe fn cgetrf_batched( + handle: *mut cublasContext, + n: i32, + a: *const *mut float2, + lda: i32, + p: *mut i32, + info: *mut i32, + batch_size: i32, +) -> cublasStatus_t { + to_cuda_solver(rocsolver_cgetrf_batched( + handle.cast(), + n, + n, + a.cast(), + lda, + p, + n as i64, + info, + batch_size, + )) +} + +unsafe fn zgetri_batched( + handle: *mut cublasContext, + n: i32, + a: *const *const double2, + lda: i32, + p: *const i32, + c: *const *mut double2, + ldc: i32, + info: *mut i32, + batch_size: i32, +) -> cublasStatus_t { + to_cuda_solver(rocsolver_zgetri_outofplace_batched( + handle.cast(), + n, + a.cast(), + lda, + p.cast_mut(), + n as i64, + c.cast(), + ldc, + info, + batch_size, + )) +} + +unsafe fn cgetri_batched( + handle: *mut cublasContext, + n: i32, + a: *const *const float2, + lda: i32, + p: *const i32, + c: *const *mut float2, + ldc: i32, + info: *mut i32, + batch_size: i32, +) -> cublasStatus_t { + to_cuda_solver(rocsolver_cgetri_outofplace_batched( + handle.cast(), + n, + a.cast(), + lda, + p.cast_mut(), + n as i64, + c.cast(), + ldc, + info, + batch_size, + )) +} + +unsafe fn dtrmm_v2( + handle: *mut cublasContext, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + transa: cublasOperation_t, + diag: cublasDiagType_t, + m: i32, + n: i32, + alpha: *const f64, + a: *const f64, + lda: i32, + b: *const f64, + ldb: i32, + c: *mut f64, + ldc: i32, +) -> cublasStatus_t { + let side = to_side(side); + let uplo = to_fill(uplo); + let transa = op_from_cuda(transa); + let diag = to_diag(diag); + to_cuda(rocblas_dtrmm_outofplace( + handle.cast(), + side, + uplo, + transa, + diag, + m, + n, + alpha, + a, + lda, + b, + ldb, + c, + ldc, + )) +} + +fn to_side(side: cublasSideMode_t) -> rocblas_side { + match side { + cublasSideMode_t::CUBLAS_SIDE_LEFT => rocblas_side::rocblas_side_left, + cublasSideMode_t::CUBLAS_SIDE_RIGHT => rocblas_side::rocblas_side_right, + _ => panic!(), + } +} + +fn to_fill(uplo: cublasFillMode_t) -> rocblas_fill { + match uplo { + cublasFillMode_t::CUBLAS_FILL_MODE_LOWER => rocblas_fill::rocblas_fill_lower, + cublasFillMode_t::CUBLAS_FILL_MODE_UPPER => rocblas_fill::rocblas_fill_upper, + cublasFillMode_t::CUBLAS_FILL_MODE_FULL => rocblas_fill::rocblas_fill_full, + _ => panic!(), + } +} + +fn to_diag(diag: cublasDiagType_t) -> rocblas_diagonal { + match diag { + cublasDiagType_t::CUBLAS_DIAG_NON_UNIT => rocblas_diagonal::rocblas_diagonal_non_unit, + cublasDiagType_t::CUBLAS_DIAG_UNIT => rocblas_diagonal::rocblas_diagonal_unit, + _ => panic!(), + } +} + +unsafe fn dgemv_v2( + handle: *mut cublasContext, + trans: cublasOperation_t, + m: i32, + n: i32, + alpha: *const f64, + a: *const f64, + lda: i32, + x: *const f64, + incx: i32, + beta: *const f64, + y: *mut f64, + incy: i32, +) -> cublasStatus_t { + let trans: rocblas_operation = op_from_cuda(trans); + to_cuda(rocblas_dgemv( + handle.cast(), + trans, + m, + n, + alpha, + a, + lda, + x, + incx, + beta, + y, + incy, + )) +} + +unsafe fn get_pointer_mode( + handle: cublasHandle_t, + mode: *mut cublasPointerMode_t, +) -> cublasStatus_t { + to_cuda(rocblas_get_pointer_mode(handle.cast(), mode.cast())) +} + +unsafe fn set_pointer_mode(handle: cublasHandle_t, mode: cublasPointerMode_t) -> cublasStatus_t { + to_cuda(rocblas_set_pointer_mode( + handle.cast(), + rocblas_pointer_mode_(mode.0), + )) +} + +unsafe fn drot_v2( + handle: *mut cublasContext, + n: i32, + x: *mut f64, + incx: i32, + y: *mut f64, + incy: i32, + c: *const f64, + s: *const f64, +) -> cublasStatus_t { + to_cuda(rocblas_drot(handle.cast(), n, x, incx, y, incy, c, s)) +} + +unsafe fn drotg( + handle: *mut cublasContext, + a: *mut f64, + b: *mut f64, + c: *mut f64, + s: *mut f64, +) -> cublasStatus_t { + to_cuda(rocblas_drotg(handle.cast(), a, b, c, s)) +} + +unsafe fn drotm( + handle: *mut cublasContext, + n: i32, + x: *mut f64, + incx: i32, + y: *mut f64, + incy: i32, + param: *const f64, +) -> cublasStatus_t { + to_cuda(rocblas_drotm(handle.cast(), n, x, incx, y, incy, param)) +} + +unsafe fn drotmg( + handle: *mut cublasContext, + d1: *mut f64, + d2: *mut f64, + x1: *mut f64, + y1: *const f64, + param: *mut f64, +) -> cublasStatus_t { + to_cuda(rocblas_drotmg(handle.cast(), d1, d2, x1, y1, param)) +} + +unsafe fn dswap( + handle: *mut cublasContext, + n: i32, + x: *mut f64, + incx: i32, + y: *mut f64, + incy: i32, +) -> cublasStatus_t { + to_cuda(rocblas_dswap(handle.cast(), n, x, incx, y, incy)) +} + +unsafe fn dger( + handle: *mut cublasContext, + m: i32, + n: i32, + alpha: *const f64, + x: *const f64, + incx: i32, + y: *const f64, + incy: i32, + a: *mut f64, + lda: i32, +) -> cublasStatus_t { + to_cuda(rocblas_dger( + handle.cast(), + m, + n, + alpha, + x, + incx, + y, + incy, + a, + lda, + )) +} + +unsafe fn dgemm( + handle: *mut cublasContext, + transa: cublasOperation_t, + transb: cublasOperation_t, + m: i32, + n: i32, + k: i32, + alpha: *const f64, + a: *const f64, + lda: i32, + b: *const f64, + ldb: i32, + beta: *const f64, + c: *mut f64, + ldc: i32, +) -> cublasStatus_t { + let transa = op_from_cuda(transa); + let transb = op_from_cuda(transb); + to_cuda(rocblas_dgemm( + handle.cast(), + transa, + transb, + m, + n, + k, + alpha, + a, + lda, + b, + ldb, + beta, + c, + ldc, + )) +} + +unsafe fn dtrsm( + handle: *mut cublasContext, + side: cublasSideMode_t, + uplo: cublasFillMode_t, + trans: cublasOperation_t, + diag: cublasDiagType_t, + m: i32, + n: i32, + alpha: *const f64, + a: *const f64, + lda: i32, + b: *mut f64, + ldb: i32, +) -> cublasStatus_t { + let side = to_side(side); + let uplo = to_fill(uplo); + let trans = op_from_cuda(trans); + let diag = to_diag(diag); + to_cuda(rocblas_dtrsm( + handle.cast(), + side, + uplo, + trans, + diag, + m, + n, + alpha, + a, + lda, + b, + ldb, + )) +} diff --git a/zluda_blaslt/Cargo.toml b/zluda_blaslt/Cargo.toml new file mode 100644 index 0000000..b2f31d2 --- /dev/null +++ b/zluda_blaslt/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "zluda_blaslt" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "cublasLt" +crate-type = ["cdylib"] + +[dependencies] +hipblaslt-sys = { path = "../hipblaslt-sys" } +cuda_types = { path = "../cuda_types" } +hip_common = { path = "../hip_common" } +zluda_dark_api = { path = "../zluda_dark_api" } + +[package.metadata.zluda] +linux_only = true +linux_names = ["libcublasLt.so.11"] +dump_names = ["libcublasLt.so"] diff --git a/zluda_blaslt/README b/zluda_blaslt/README new file mode 100644 index 0000000..49dceea --- /dev/null +++ b/zluda_blaslt/README @@ -0,0 +1,2 @@ +bindgen /usr/local/cuda/targets/x86_64-linux/include/cublasLt.h -o src/cublaslt.rs --allowlist-function="^cublasLt.*" --blocklist-function="^cublasLtLoggerSetFile$" --allowlist-type="cu.*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +sed -i -e 's/extern "C" {//g' -e 's/-> cublasStatus_t;/-> cublasStatus_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' src/cublaslt.rs \ No newline at end of file diff --git a/zluda_blaslt/src/cublaslt.rs b/zluda_blaslt/src/cublaslt.rs new file mode 100644 index 0000000..bba58e3 --- /dev/null +++ b/zluda_blaslt/src/cublaslt.rs @@ -0,0 +1,5372 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[repr(align(8))] +#[derive(Copy, Clone)] +pub struct float2 { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub struct double2 { + pub x: f64, + pub y: f64, +} +#[doc = " *\n *\n *"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct dim3 { + pub x: ::std::os::raw::c_uint, + pub y: ::std::os::raw::c_uint, + pub z: ::std::os::raw::c_uint, +} +impl cudaError { + #[doc = " The API call returned with no errors. In the case of query calls, this\n also means that the operation being queried is complete (see\n ::cudaEventQuery() and ::cudaStreamQuery())."] + pub const cudaSuccess: cudaError = cudaError(0); +} +impl cudaError { + #[doc = " This indicates that one or more of the parameters passed to the API call\n is not within an acceptable range of values."] + pub const cudaErrorInvalidValue: cudaError = cudaError(1); +} +impl cudaError { + #[doc = " The API call failed because it was unable to allocate enough memory to\n perform the requested operation."] + pub const cudaErrorMemoryAllocation: cudaError = cudaError(2); +} +impl cudaError { + #[doc = " The API call failed because the CUDA driver and runtime could not be\n initialized."] + pub const cudaErrorInitializationError: cudaError = cudaError(3); +} +impl cudaError { + #[doc = " This indicates that a CUDA Runtime API call cannot be executed because\n it is being called during process shut down, at a point in time after\n CUDA driver has been unloaded."] + pub const cudaErrorCudartUnloading: cudaError = cudaError(4); +} +impl cudaError { + #[doc = " This indicates profiler is not initialized for this run. This can\n happen when the application is running with external profiling tools\n like visual profiler."] + pub const cudaErrorProfilerDisabled: cudaError = cudaError(5); +} +impl cudaError { + #[doc = " \\deprecated\n This error return is deprecated as of CUDA 5.0. It is no longer an error\n to attempt to enable/disable the profiling via ::cudaProfilerStart or\n ::cudaProfilerStop without initialization."] + pub const cudaErrorProfilerNotInitialized: cudaError = cudaError(6); +} +impl cudaError { + #[doc = " \\deprecated\n This error return is deprecated as of CUDA 5.0. It is no longer an error\n to call cudaProfilerStart() when profiling is already enabled."] + pub const cudaErrorProfilerAlreadyStarted: cudaError = cudaError(7); +} +impl cudaError { + #[doc = " \\deprecated\n This error return is deprecated as of CUDA 5.0. It is no longer an error\n to call cudaProfilerStop() when profiling is already disabled."] + pub const cudaErrorProfilerAlreadyStopped: cudaError = cudaError(8); +} +impl cudaError { + #[doc = " This indicates that a kernel launch is requesting resources that can\n never be satisfied by the current device. Requesting more shared memory\n per block than the device supports will trigger this error, as will\n requesting too many threads or blocks. See ::cudaDeviceProp for more\n device limitations."] + pub const cudaErrorInvalidConfiguration: cudaError = cudaError(9); +} +impl cudaError { + #[doc = " This indicates that one or more of the pitch-related parameters passed\n to the API call is not within the acceptable range for pitch."] + pub const cudaErrorInvalidPitchValue: cudaError = cudaError(12); +} +impl cudaError { + #[doc = " This indicates that the symbol name/identifier passed to the API call\n is not a valid name or identifier."] + pub const cudaErrorInvalidSymbol: cudaError = cudaError(13); +} +impl cudaError { + #[doc = " This indicates that at least one host pointer passed to the API call is\n not a valid host pointer.\n \\deprecated\n This error return is deprecated as of CUDA 10.1."] + pub const cudaErrorInvalidHostPointer: cudaError = cudaError(16); +} +impl cudaError { + #[doc = " This indicates that at least one device pointer passed to the API call is\n not a valid device pointer.\n \\deprecated\n This error return is deprecated as of CUDA 10.1."] + pub const cudaErrorInvalidDevicePointer: cudaError = cudaError(17); +} +impl cudaError { + #[doc = " This indicates that the texture passed to the API call is not a valid\n texture."] + pub const cudaErrorInvalidTexture: cudaError = cudaError(18); +} +impl cudaError { + #[doc = " This indicates that the texture binding is not valid. This occurs if you\n call ::cudaGetTextureAlignmentOffset() with an unbound texture."] + pub const cudaErrorInvalidTextureBinding: cudaError = cudaError(19); +} +impl cudaError { + #[doc = " This indicates that the channel descriptor passed to the API call is not\n valid. This occurs if the format is not one of the formats specified by\n ::cudaChannelFormatKind, or if one of the dimensions is invalid."] + pub const cudaErrorInvalidChannelDescriptor: cudaError = cudaError(20); +} +impl cudaError { + #[doc = " This indicates that the direction of the memcpy passed to the API call is\n not one of the types specified by ::cudaMemcpyKind."] + pub const cudaErrorInvalidMemcpyDirection: cudaError = cudaError(21); +} +impl cudaError { + #[doc = " This indicated that the user has taken the address of a constant variable,\n which was forbidden up until the CUDA 3.1 release.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Variables in constant\n memory may now have their address taken by the runtime via\n ::cudaGetSymbolAddress()."] + pub const cudaErrorAddressOfConstant: cudaError = cudaError(22); +} +impl cudaError { + #[doc = " This indicated that a texture fetch was not able to be performed.\n This was previously used for device emulation of texture operations.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorTextureFetchFailed: cudaError = cudaError(23); +} +impl cudaError { + #[doc = " This indicated that a texture was not bound for access.\n This was previously used for device emulation of texture operations.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorTextureNotBound: cudaError = cudaError(24); +} +impl cudaError { + #[doc = " This indicated that a synchronization operation had failed.\n This was previously used for some device emulation functions.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorSynchronizationError: cudaError = cudaError(25); +} +impl cudaError { + #[doc = " This indicates that a non-float texture was being accessed with linear\n filtering. This is not supported by CUDA."] + pub const cudaErrorInvalidFilterSetting: cudaError = cudaError(26); +} +impl cudaError { + #[doc = " This indicates that an attempt was made to read a non-float texture as a\n normalized float. This is not supported by CUDA."] + pub const cudaErrorInvalidNormSetting: cudaError = cudaError(27); +} +impl cudaError { + #[doc = " Mixing of device and device emulation code was not allowed.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorMixedDeviceExecution: cudaError = cudaError(28); +} +impl cudaError { + #[doc = " This indicates that the API call is not yet implemented. Production\n releases of CUDA will never return this error.\n \\deprecated\n This error return is deprecated as of CUDA 4.1."] + pub const cudaErrorNotYetImplemented: cudaError = cudaError(31); +} +impl cudaError { + #[doc = " This indicated that an emulated device pointer exceeded the 32-bit address\n range.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorMemoryValueTooLarge: cudaError = cudaError(32); +} +impl cudaError { + #[doc = " This indicates that the CUDA driver that the application has loaded is a\n stub library. Applications that run with the stub rather than a real\n driver loaded will result in CUDA API returning this error."] + pub const cudaErrorStubLibrary: cudaError = cudaError(34); +} +impl cudaError { + #[doc = " This indicates that the installed NVIDIA CUDA driver is older than the\n CUDA runtime library. This is not a supported configuration. Users should\n install an updated NVIDIA display driver to allow the application to run."] + pub const cudaErrorInsufficientDriver: cudaError = cudaError(35); +} +impl cudaError { + #[doc = " This indicates that the API call requires a newer CUDA driver than the one\n currently installed. Users should install an updated NVIDIA CUDA driver\n to allow the API call to succeed."] + pub const cudaErrorCallRequiresNewerDriver: cudaError = cudaError(36); +} +impl cudaError { + #[doc = " This indicates that the surface passed to the API call is not a valid\n surface."] + pub const cudaErrorInvalidSurface: cudaError = cudaError(37); +} +impl cudaError { + #[doc = " This indicates that multiple global or constant variables (across separate\n CUDA source files in the application) share the same string name."] + pub const cudaErrorDuplicateVariableName: cudaError = cudaError(43); +} +impl cudaError { + #[doc = " This indicates that multiple textures (across separate CUDA source\n files in the application) share the same string name."] + pub const cudaErrorDuplicateTextureName: cudaError = cudaError(44); +} +impl cudaError { + #[doc = " This indicates that multiple surfaces (across separate CUDA source\n files in the application) share the same string name."] + pub const cudaErrorDuplicateSurfaceName: cudaError = cudaError(45); +} +impl cudaError { + #[doc = " This indicates that all CUDA devices are busy or unavailable at the current\n time. Devices are often busy/unavailable due to use of\n ::cudaComputeModeProhibited, ::cudaComputeModeExclusiveProcess, or when long\n running CUDA kernels have filled up the GPU and are blocking new work\n from starting. They can also be unavailable due to memory constraints\n on a device that already has active CUDA work being performed."] + pub const cudaErrorDevicesUnavailable: cudaError = cudaError(46); +} +impl cudaError { + #[doc = " This indicates that the current context is not compatible with this\n the CUDA Runtime. This can only occur if you are using CUDA\n Runtime/Driver interoperability and have created an existing Driver\n context using the driver API. The Driver context may be incompatible\n either because the Driver context was created using an older version\n of the API, because the Runtime API call expects a primary driver\n context and the Driver context is not primary, or because the Driver\n context has been destroyed. Please see \\ref CUDART_DRIVER \"Interactions\n with the CUDA Driver API\" for more information."] + pub const cudaErrorIncompatibleDriverContext: cudaError = cudaError(49); +} +impl cudaError { + #[doc = " The device function being invoked (usually via ::cudaLaunchKernel()) was not\n previously configured via the ::cudaConfigureCall() function."] + pub const cudaErrorMissingConfiguration: cudaError = cudaError(52); +} +impl cudaError { + #[doc = " This indicated that a previous kernel launch failed. This was previously\n used for device emulation of kernel launches.\n \\deprecated\n This error return is deprecated as of CUDA 3.1. Device emulation mode was\n removed with the CUDA 3.1 release."] + pub const cudaErrorPriorLaunchFailure: cudaError = cudaError(53); +} +impl cudaError { + #[doc = " This error indicates that a device runtime grid launch did not occur\n because the depth of the child grid would exceed the maximum supported\n number of nested grid launches."] + pub const cudaErrorLaunchMaxDepthExceeded: cudaError = cudaError(65); +} +impl cudaError { + #[doc = " This error indicates that a grid launch did not occur because the kernel\n uses file-scoped textures which are unsupported by the device runtime.\n Kernels launched via the device runtime only support textures created with\n the Texture Object API's."] + pub const cudaErrorLaunchFileScopedTex: cudaError = cudaError(66); +} +impl cudaError { + #[doc = " This error indicates that a grid launch did not occur because the kernel\n uses file-scoped surfaces which are unsupported by the device runtime.\n Kernels launched via the device runtime only support surfaces created with\n the Surface Object API's."] + pub const cudaErrorLaunchFileScopedSurf: cudaError = cudaError(67); +} +impl cudaError { + #[doc = " This error indicates that a call to ::cudaDeviceSynchronize made from\n the device runtime failed because the call was made at grid depth greater\n than than either the default (2 levels of grids) or user specified device\n limit ::cudaLimitDevRuntimeSyncDepth. To be able to synchronize on\n launched grids at a greater depth successfully, the maximum nested\n depth at which ::cudaDeviceSynchronize will be called must be specified\n with the ::cudaLimitDevRuntimeSyncDepth limit to the ::cudaDeviceSetLimit\n api before the host-side launch of a kernel using the device runtime.\n Keep in mind that additional levels of sync depth require the runtime\n to reserve large amounts of device memory that cannot be used for\n user allocations."] + pub const cudaErrorSyncDepthExceeded: cudaError = cudaError(68); +} +impl cudaError { + #[doc = " This error indicates that a device runtime grid launch failed because\n the launch would exceed the limit ::cudaLimitDevRuntimePendingLaunchCount.\n For this launch to proceed successfully, ::cudaDeviceSetLimit must be\n called to set the ::cudaLimitDevRuntimePendingLaunchCount to be higher\n than the upper bound of outstanding launches that can be issued to the\n device runtime. Keep in mind that raising the limit of pending device\n runtime launches will require the runtime to reserve device memory that\n cannot be used for user allocations."] + pub const cudaErrorLaunchPendingCountExceeded: cudaError = cudaError(69); +} +impl cudaError { + #[doc = " The requested device function does not exist or is not compiled for the\n proper device architecture."] + pub const cudaErrorInvalidDeviceFunction: cudaError = cudaError(98); +} +impl cudaError { + #[doc = " This indicates that no CUDA-capable devices were detected by the installed\n CUDA driver."] + pub const cudaErrorNoDevice: cudaError = cudaError(100); +} +impl cudaError { + #[doc = " This indicates that the device ordinal supplied by the user does not\n correspond to a valid CUDA device or that the action requested is\n invalid for the specified device."] + pub const cudaErrorInvalidDevice: cudaError = cudaError(101); +} +impl cudaError { + #[doc = " This indicates that the device doesn't have a valid Grid License."] + pub const cudaErrorDeviceNotLicensed: cudaError = cudaError(102); +} +impl cudaError { + #[doc = " By default, the CUDA runtime may perform a minimal set of self-tests,\n as well as CUDA driver tests, to establish the validity of both.\n Introduced in CUDA 11.2, this error return indicates that at least one\n of these tests has failed and the validity of either the runtime\n or the driver could not be established."] + pub const cudaErrorSoftwareValidityNotEstablished: cudaError = cudaError(103); +} +impl cudaError { + #[doc = " This indicates an internal startup failure in the CUDA runtime."] + pub const cudaErrorStartupFailure: cudaError = cudaError(127); +} +impl cudaError { + #[doc = " This indicates that the device kernel image is invalid."] + pub const cudaErrorInvalidKernelImage: cudaError = cudaError(200); +} +impl cudaError { + #[doc = " This most frequently indicates that there is no context bound to the\n current thread. This can also be returned if the context passed to an\n API call is not a valid handle (such as a context that has had\n ::cuCtxDestroy() invoked on it). This can also be returned if a user\n mixes different API versions (i.e. 3010 context with 3020 API calls).\n See ::cuCtxGetApiVersion() for more details."] + pub const cudaErrorDeviceUninitialized: cudaError = cudaError(201); +} +impl cudaError { + #[doc = " This indicates that the buffer object could not be mapped."] + pub const cudaErrorMapBufferObjectFailed: cudaError = cudaError(205); +} +impl cudaError { + #[doc = " This indicates that the buffer object could not be unmapped."] + pub const cudaErrorUnmapBufferObjectFailed: cudaError = cudaError(206); +} +impl cudaError { + #[doc = " This indicates that the specified array is currently mapped and thus\n cannot be destroyed."] + pub const cudaErrorArrayIsMapped: cudaError = cudaError(207); +} +impl cudaError { + #[doc = " This indicates that the resource is already mapped."] + pub const cudaErrorAlreadyMapped: cudaError = cudaError(208); +} +impl cudaError { + #[doc = " This indicates that there is no kernel image available that is suitable\n for the device. This can occur when a user specifies code generation\n options for a particular CUDA source file that do not include the\n corresponding device configuration."] + pub const cudaErrorNoKernelImageForDevice: cudaError = cudaError(209); +} +impl cudaError { + #[doc = " This indicates that a resource has already been acquired."] + pub const cudaErrorAlreadyAcquired: cudaError = cudaError(210); +} +impl cudaError { + #[doc = " This indicates that a resource is not mapped."] + pub const cudaErrorNotMapped: cudaError = cudaError(211); +} +impl cudaError { + #[doc = " This indicates that a mapped resource is not available for access as an\n array."] + pub const cudaErrorNotMappedAsArray: cudaError = cudaError(212); +} +impl cudaError { + #[doc = " This indicates that a mapped resource is not available for access as a\n pointer."] + pub const cudaErrorNotMappedAsPointer: cudaError = cudaError(213); +} +impl cudaError { + #[doc = " This indicates that an uncorrectable ECC error was detected during\n execution."] + pub const cudaErrorECCUncorrectable: cudaError = cudaError(214); +} +impl cudaError { + #[doc = " This indicates that the ::cudaLimit passed to the API call is not\n supported by the active device."] + pub const cudaErrorUnsupportedLimit: cudaError = cudaError(215); +} +impl cudaError { + #[doc = " This indicates that a call tried to access an exclusive-thread device that\n is already in use by a different thread."] + pub const cudaErrorDeviceAlreadyInUse: cudaError = cudaError(216); +} +impl cudaError { + #[doc = " This error indicates that P2P access is not supported across the given\n devices."] + pub const cudaErrorPeerAccessUnsupported: cudaError = cudaError(217); +} +impl cudaError { + #[doc = " A PTX compilation failed. The runtime may fall back to compiling PTX if\n an application does not contain a suitable binary for the current device."] + pub const cudaErrorInvalidPtx: cudaError = cudaError(218); +} +impl cudaError { + #[doc = " This indicates an error with the OpenGL or DirectX context."] + pub const cudaErrorInvalidGraphicsContext: cudaError = cudaError(219); +} +impl cudaError { + #[doc = " This indicates that an uncorrectable NVLink error was detected during the\n execution."] + pub const cudaErrorNvlinkUncorrectable: cudaError = cudaError(220); +} +impl cudaError { + #[doc = " This indicates that the PTX JIT compiler library was not found. The JIT Compiler\n library is used for PTX compilation. The runtime may fall back to compiling PTX\n if an application does not contain a suitable binary for the current device."] + pub const cudaErrorJitCompilerNotFound: cudaError = cudaError(221); +} +impl cudaError { + #[doc = " This indicates that the provided PTX was compiled with an unsupported toolchain.\n The most common reason for this, is the PTX was generated by a compiler newer\n than what is supported by the CUDA driver and PTX JIT compiler."] + pub const cudaErrorUnsupportedPtxVersion: cudaError = cudaError(222); +} +impl cudaError { + #[doc = " This indicates that the JIT compilation was disabled. The JIT compilation compiles\n PTX. The runtime may fall back to compiling PTX if an application does not contain\n a suitable binary for the current device."] + pub const cudaErrorJitCompilationDisabled: cudaError = cudaError(223); +} +impl cudaError { + #[doc = " This indicates that the provided execution affinity is not supported by the device."] + pub const cudaErrorUnsupportedExecAffinity: cudaError = cudaError(224); +} +impl cudaError { + #[doc = " This indicates that the device kernel source is invalid."] + pub const cudaErrorInvalidSource: cudaError = cudaError(300); +} +impl cudaError { + #[doc = " This indicates that the file specified was not found."] + pub const cudaErrorFileNotFound: cudaError = cudaError(301); +} +impl cudaError { + #[doc = " This indicates that a link to a shared object failed to resolve."] + pub const cudaErrorSharedObjectSymbolNotFound: cudaError = cudaError(302); +} +impl cudaError { + #[doc = " This indicates that initialization of a shared object failed."] + pub const cudaErrorSharedObjectInitFailed: cudaError = cudaError(303); +} +impl cudaError { + #[doc = " This error indicates that an OS call failed."] + pub const cudaErrorOperatingSystem: cudaError = cudaError(304); +} +impl cudaError { + #[doc = " This indicates that a resource handle passed to the API call was not\n valid. Resource handles are opaque types like ::cudaStream_t and\n ::cudaEvent_t."] + pub const cudaErrorInvalidResourceHandle: cudaError = cudaError(400); +} +impl cudaError { + #[doc = " This indicates that a resource required by the API call is not in a\n valid state to perform the requested operation."] + pub const cudaErrorIllegalState: cudaError = cudaError(401); +} +impl cudaError { + #[doc = " This indicates that a named symbol was not found. Examples of symbols\n are global/constant variable names, driver function names, texture names,\n and surface names."] + pub const cudaErrorSymbolNotFound: cudaError = cudaError(500); +} +impl cudaError { + #[doc = " This indicates that asynchronous operations issued previously have not\n completed yet. This result is not actually an error, but must be indicated\n differently than ::cudaSuccess (which indicates completion). Calls that\n may return this value include ::cudaEventQuery() and ::cudaStreamQuery()."] + pub const cudaErrorNotReady: cudaError = cudaError(600); +} +impl cudaError { + #[doc = " The device encountered a load or store instruction on an invalid memory address.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorIllegalAddress: cudaError = cudaError(700); +} +impl cudaError { + #[doc = " This indicates that a launch did not occur because it did not have\n appropriate resources. Although this error is similar to\n ::cudaErrorInvalidConfiguration, this error usually indicates that the\n user has attempted to pass too many arguments to the device kernel, or the\n kernel launch specifies too many threads for the kernel's register count."] + pub const cudaErrorLaunchOutOfResources: cudaError = cudaError(701); +} +impl cudaError { + #[doc = " This indicates that the device kernel took too long to execute. This can\n only occur if timeouts are enabled - see the device property\n \\ref ::cudaDeviceProp::kernelExecTimeoutEnabled \"kernelExecTimeoutEnabled\"\n for more information.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorLaunchTimeout: cudaError = cudaError(702); +} +impl cudaError { + #[doc = " This error indicates a kernel launch that uses an incompatible texturing\n mode."] + pub const cudaErrorLaunchIncompatibleTexturing: cudaError = cudaError(703); +} +impl cudaError { + #[doc = " This error indicates that a call to ::cudaDeviceEnablePeerAccess() is\n trying to re-enable peer addressing on from a context which has already\n had peer addressing enabled."] + pub const cudaErrorPeerAccessAlreadyEnabled: cudaError = cudaError(704); +} +impl cudaError { + #[doc = " This error indicates that ::cudaDeviceDisablePeerAccess() is trying to\n disable peer addressing which has not been enabled yet via\n ::cudaDeviceEnablePeerAccess()."] + pub const cudaErrorPeerAccessNotEnabled: cudaError = cudaError(705); +} +impl cudaError { + #[doc = " This indicates that the user has called ::cudaSetValidDevices(),\n ::cudaSetDeviceFlags(), ::cudaD3D9SetDirect3DDevice(),\n ::cudaD3D10SetDirect3DDevice, ::cudaD3D11SetDirect3DDevice(), or\n ::cudaVDPAUSetVDPAUDevice() after initializing the CUDA runtime by\n calling non-device management operations (allocating memory and\n launching kernels are examples of non-device management operations).\n This error can also be returned if using runtime/driver\n interoperability and there is an existing ::CUcontext active on the\n host thread."] + pub const cudaErrorSetOnActiveProcess: cudaError = cudaError(708); +} +impl cudaError { + #[doc = " This error indicates that the context current to the calling thread\n has been destroyed using ::cuCtxDestroy, or is a primary context which\n has not yet been initialized."] + pub const cudaErrorContextIsDestroyed: cudaError = cudaError(709); +} +impl cudaError { + #[doc = " An assert triggered in device code during kernel execution. The device\n cannot be used again. All existing allocations are invalid. To continue\n using CUDA, the process must be terminated and relaunched."] + pub const cudaErrorAssert: cudaError = cudaError(710); +} +impl cudaError { + #[doc = " This error indicates that the hardware resources required to enable\n peer access have been exhausted for one or more of the devices\n passed to ::cudaEnablePeerAccess()."] + pub const cudaErrorTooManyPeers: cudaError = cudaError(711); +} +impl cudaError { + #[doc = " This error indicates that the memory range passed to ::cudaHostRegister()\n has already been registered."] + pub const cudaErrorHostMemoryAlreadyRegistered: cudaError = cudaError(712); +} +impl cudaError { + #[doc = " This error indicates that the pointer passed to ::cudaHostUnregister()\n does not correspond to any currently registered memory region."] + pub const cudaErrorHostMemoryNotRegistered: cudaError = cudaError(713); +} +impl cudaError { + #[doc = " Device encountered an error in the call stack during kernel execution,\n possibly due to stack corruption or exceeding the stack size limit.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorHardwareStackError: cudaError = cudaError(714); +} +impl cudaError { + #[doc = " The device encountered an illegal instruction during kernel execution\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorIllegalInstruction: cudaError = cudaError(715); +} +impl cudaError { + #[doc = " The device encountered a load or store instruction\n on a memory address which is not aligned.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorMisalignedAddress: cudaError = cudaError(716); +} +impl cudaError { + #[doc = " While executing a kernel, the device encountered an instruction\n which can only operate on memory locations in certain address spaces\n (global, shared, or local), but was supplied a memory address not\n belonging to an allowed address space.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorInvalidAddressSpace: cudaError = cudaError(717); +} +impl cudaError { + #[doc = " The device encountered an invalid program counter.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorInvalidPc: cudaError = cudaError(718); +} +impl cudaError { + #[doc = " An exception occurred on the device while executing a kernel. Common\n causes include dereferencing an invalid device pointer and accessing\n out of bounds shared memory. Less common cases can be system specific - more\n information about these cases can be found in the system specific user guide.\n This leaves the process in an inconsistent state and any further CUDA work\n will return the same error. To continue using CUDA, the process must be terminated\n and relaunched."] + pub const cudaErrorLaunchFailure: cudaError = cudaError(719); +} +impl cudaError { + #[doc = " This error indicates that the number of blocks launched per grid for a kernel that was\n launched via either ::cudaLaunchCooperativeKernel or ::cudaLaunchCooperativeKernelMultiDevice\n exceeds the maximum number of blocks as allowed by ::cudaOccupancyMaxActiveBlocksPerMultiprocessor\n or ::cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors\n as specified by the device attribute ::cudaDevAttrMultiProcessorCount."] + pub const cudaErrorCooperativeLaunchTooLarge: cudaError = cudaError(720); +} +impl cudaError { + #[doc = " This error indicates the attempted operation is not permitted."] + pub const cudaErrorNotPermitted: cudaError = cudaError(800); +} +impl cudaError { + #[doc = " This error indicates the attempted operation is not supported\n on the current system or device."] + pub const cudaErrorNotSupported: cudaError = cudaError(801); +} +impl cudaError { + #[doc = " This error indicates that the system is not yet ready to start any CUDA\n work. To continue using CUDA, verify the system configuration is in a\n valid state and all required driver daemons are actively running.\n More information about this error can be found in the system specific\n user guide."] + pub const cudaErrorSystemNotReady: cudaError = cudaError(802); +} +impl cudaError { + #[doc = " This error indicates that there is a mismatch between the versions of\n the display driver and the CUDA driver. Refer to the compatibility documentation\n for supported versions."] + pub const cudaErrorSystemDriverMismatch: cudaError = cudaError(803); +} +impl cudaError { + #[doc = " This error indicates that the system was upgraded to run with forward compatibility\n but the visible hardware detected by CUDA does not support this configuration.\n Refer to the compatibility documentation for the supported hardware matrix or ensure\n that only supported hardware is visible during initialization via the CUDA_VISIBLE_DEVICES\n environment variable."] + pub const cudaErrorCompatNotSupportedOnDevice: cudaError = cudaError(804); +} +impl cudaError { + #[doc = " This error indicates that the MPS client failed to connect to the MPS control daemon or the MPS server."] + pub const cudaErrorMpsConnectionFailed: cudaError = cudaError(805); +} +impl cudaError { + #[doc = " This error indicates that the remote procedural call between the MPS server and the MPS client failed."] + pub const cudaErrorMpsRpcFailure: cudaError = cudaError(806); +} +impl cudaError { + #[doc = " This error indicates that the MPS server is not ready to accept new MPS client requests.\n This error can be returned when the MPS server is in the process of recovering from a fatal failure."] + pub const cudaErrorMpsServerNotReady: cudaError = cudaError(807); +} +impl cudaError { + #[doc = " This error indicates that the hardware resources required to create MPS client have been exhausted."] + pub const cudaErrorMpsMaxClientsReached: cudaError = cudaError(808); +} +impl cudaError { + #[doc = " This error indicates the the hardware resources required to device connections have been exhausted."] + pub const cudaErrorMpsMaxConnectionsReached: cudaError = cudaError(809); +} +impl cudaError { + #[doc = " This error indicates that the MPS client has been terminated by the server. To continue using CUDA, the process must be terminated and relaunched."] + pub const cudaErrorMpsClientTerminated: cudaError = cudaError(810); +} +impl cudaError { + #[doc = " The operation is not permitted when the stream is capturing."] + pub const cudaErrorStreamCaptureUnsupported: cudaError = cudaError(900); +} +impl cudaError { + #[doc = " The current capture sequence on the stream has been invalidated due to\n a previous error."] + pub const cudaErrorStreamCaptureInvalidated: cudaError = cudaError(901); +} +impl cudaError { + #[doc = " The operation would have resulted in a merge of two independent capture\n sequences."] + pub const cudaErrorStreamCaptureMerge: cudaError = cudaError(902); +} +impl cudaError { + #[doc = " The capture was not initiated in this stream."] + pub const cudaErrorStreamCaptureUnmatched: cudaError = cudaError(903); +} +impl cudaError { + #[doc = " The capture sequence contains a fork that was not joined to the primary\n stream."] + pub const cudaErrorStreamCaptureUnjoined: cudaError = cudaError(904); +} +impl cudaError { + #[doc = " A dependency would have been created which crosses the capture sequence\n boundary. Only implicit in-stream ordering dependencies are allowed to\n cross the boundary."] + pub const cudaErrorStreamCaptureIsolation: cudaError = cudaError(905); +} +impl cudaError { + #[doc = " The operation would have resulted in a disallowed implicit dependency on\n a current capture sequence from cudaStreamLegacy."] + pub const cudaErrorStreamCaptureImplicit: cudaError = cudaError(906); +} +impl cudaError { + #[doc = " The operation is not permitted on an event which was last recorded in a\n capturing stream."] + pub const cudaErrorCapturedEvent: cudaError = cudaError(907); +} +impl cudaError { + #[doc = " A stream capture sequence not initiated with the ::cudaStreamCaptureModeRelaxed\n argument to ::cudaStreamBeginCapture was passed to ::cudaStreamEndCapture in a\n different thread."] + pub const cudaErrorStreamCaptureWrongThread: cudaError = cudaError(908); +} +impl cudaError { + #[doc = " This indicates that the wait operation has timed out."] + pub const cudaErrorTimeout: cudaError = cudaError(909); +} +impl cudaError { + #[doc = " This error indicates that the graph update was not performed because it included\n changes which violated constraints specific to instantiated graph update."] + pub const cudaErrorGraphExecUpdateFailure: cudaError = cudaError(910); +} +impl cudaError { + #[doc = " This indicates that an async error has occurred in a device outside of CUDA.\n If CUDA was waiting for an external device's signal before consuming shared data,\n the external device signaled an error indicating that the data is not valid for\n consumption. This leaves the process in an inconsistent state and any further CUDA\n work will return the same error. To continue using CUDA, the process must be\n terminated and relaunched."] + pub const cudaErrorExternalDevice: cudaError = cudaError(911); +} +impl cudaError { + #[doc = " This indicates that a kernel launch error has occurred due to cluster\n misconfiguration."] + pub const cudaErrorInvalidClusterSize: cudaError = cudaError(912); +} +impl cudaError { + #[doc = " This indicates that an unknown internal error has occurred."] + pub const cudaErrorUnknown: cudaError = cudaError(999); +} +impl cudaError { + #[doc = " Any unhandled CUDA driver error is added to this value and returned via\n the runtime. Production releases of CUDA should not return such errors.\n \\deprecated\n This error return is deprecated as of CUDA 4.1."] + pub const cudaErrorApiFailureBase: cudaError = cudaError(10000); +} +#[repr(transparent)] +#[doc = " CUDA error types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaError(pub ::std::os::raw::c_uint); +impl cudaChannelFormatKind { + #[doc = "< Signed channel format"] + pub const cudaChannelFormatKindSigned: cudaChannelFormatKind = cudaChannelFormatKind(0); +} +impl cudaChannelFormatKind { + #[doc = "< Unsigned channel format"] + pub const cudaChannelFormatKindUnsigned: cudaChannelFormatKind = cudaChannelFormatKind(1); +} +impl cudaChannelFormatKind { + #[doc = "< Float channel format"] + pub const cudaChannelFormatKindFloat: cudaChannelFormatKind = cudaChannelFormatKind(2); +} +impl cudaChannelFormatKind { + #[doc = "< No channel format"] + pub const cudaChannelFormatKindNone: cudaChannelFormatKind = cudaChannelFormatKind(3); +} +impl cudaChannelFormatKind { + #[doc = "< Unsigned 8-bit integers, planar 4:2:0 YUV format"] + pub const cudaChannelFormatKindNV12: cudaChannelFormatKind = cudaChannelFormatKind(4); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel unsigned 8-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized8X1: cudaChannelFormatKind = + cudaChannelFormatKind(5); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel unsigned 8-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized8X2: cudaChannelFormatKind = + cudaChannelFormatKind(6); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned 8-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized8X4: cudaChannelFormatKind = + cudaChannelFormatKind(7); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel unsigned 16-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized16X1: cudaChannelFormatKind = + cudaChannelFormatKind(8); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel unsigned 16-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized16X2: cudaChannelFormatKind = + cudaChannelFormatKind(9); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned 16-bit normalized integer"] + pub const cudaChannelFormatKindUnsignedNormalized16X4: cudaChannelFormatKind = + cudaChannelFormatKind(10); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel signed 8-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized8X1: cudaChannelFormatKind = + cudaChannelFormatKind(11); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel signed 8-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized8X2: cudaChannelFormatKind = + cudaChannelFormatKind(12); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel signed 8-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized8X4: cudaChannelFormatKind = + cudaChannelFormatKind(13); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel signed 16-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized16X1: cudaChannelFormatKind = + cudaChannelFormatKind(14); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel signed 16-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized16X2: cudaChannelFormatKind = + cudaChannelFormatKind(15); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel signed 16-bit normalized integer"] + pub const cudaChannelFormatKindSignedNormalized16X4: cudaChannelFormatKind = + cudaChannelFormatKind(16); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC1 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed1: cudaChannelFormatKind = + cudaChannelFormatKind(17); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC1 compression) format with sRGB encoding"] + pub const cudaChannelFormatKindUnsignedBlockCompressed1SRGB: cudaChannelFormatKind = + cudaChannelFormatKind(18); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC2 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed2: cudaChannelFormatKind = + cudaChannelFormatKind(19); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC2 compression) format with sRGB encoding"] + pub const cudaChannelFormatKindUnsignedBlockCompressed2SRGB: cudaChannelFormatKind = + cudaChannelFormatKind(20); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC3 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed3: cudaChannelFormatKind = + cudaChannelFormatKind(21); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC3 compression) format with sRGB encoding"] + pub const cudaChannelFormatKindUnsignedBlockCompressed3SRGB: cudaChannelFormatKind = + cudaChannelFormatKind(22); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel unsigned normalized block-compressed (BC4 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed4: cudaChannelFormatKind = + cudaChannelFormatKind(23); +} +impl cudaChannelFormatKind { + #[doc = "< 1 channel signed normalized block-compressed (BC4 compression) format"] + pub const cudaChannelFormatKindSignedBlockCompressed4: cudaChannelFormatKind = + cudaChannelFormatKind(24); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel unsigned normalized block-compressed (BC5 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed5: cudaChannelFormatKind = + cudaChannelFormatKind(25); +} +impl cudaChannelFormatKind { + #[doc = "< 2 channel signed normalized block-compressed (BC5 compression) format"] + pub const cudaChannelFormatKindSignedBlockCompressed5: cudaChannelFormatKind = + cudaChannelFormatKind(26); +} +impl cudaChannelFormatKind { + #[doc = "< 3 channel unsigned half-float block-compressed (BC6H compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed6H: cudaChannelFormatKind = + cudaChannelFormatKind(27); +} +impl cudaChannelFormatKind { + #[doc = "< 3 channel signed half-float block-compressed (BC6H compression) format"] + pub const cudaChannelFormatKindSignedBlockCompressed6H: cudaChannelFormatKind = + cudaChannelFormatKind(28); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC7 compression) format"] + pub const cudaChannelFormatKindUnsignedBlockCompressed7: cudaChannelFormatKind = + cudaChannelFormatKind(29); +} +impl cudaChannelFormatKind { + #[doc = "< 4 channel unsigned normalized block-compressed (BC7 compression) format with sRGB encoding"] + pub const cudaChannelFormatKindUnsignedBlockCompressed7SRGB: cudaChannelFormatKind = + cudaChannelFormatKind(30); +} +#[repr(transparent)] +#[doc = " Channel format kind"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaChannelFormatKind(pub ::std::os::raw::c_uint); +#[doc = " CUDA Channel format descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaChannelFormatDesc { + #[doc = "< x"] + pub x: ::std::os::raw::c_int, + #[doc = "< y"] + pub y: ::std::os::raw::c_int, + #[doc = "< z"] + pub z: ::std::os::raw::c_int, + #[doc = "< w"] + pub w: ::std::os::raw::c_int, + #[doc = "< Channel format kind"] + pub f: cudaChannelFormatKind, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaArray { + _unused: [u8; 0], +} +#[doc = " CUDA array"] +pub type cudaArray_t = *mut cudaArray; +#[doc = " CUDA array (as source copy argument)"] +pub type cudaArray_const_t = *const cudaArray; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMipmappedArray { + _unused: [u8; 0], +} +#[doc = " CUDA mipmapped array"] +pub type cudaMipmappedArray_t = *mut cudaMipmappedArray; +#[doc = " CUDA mipmapped array (as source argument)"] +pub type cudaMipmappedArray_const_t = *const cudaMipmappedArray; +#[doc = " Sparse CUDA array and CUDA mipmapped array properties"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaArraySparseProperties { + pub tileExtent: cudaArraySparseProperties__bindgen_ty_1, + #[doc = "< First mip level at which the mip tail begins"] + pub miptailFirstLevel: ::std::os::raw::c_uint, + #[doc = "< Total size of the mip tail."] + pub miptailSize: ::std::os::raw::c_ulonglong, + #[doc = "< Flags will either be zero or ::cudaArraySparsePropertiesSingleMipTail"] + pub flags: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaArraySparseProperties__bindgen_ty_1 { + #[doc = "< Tile width in elements"] + pub width: ::std::os::raw::c_uint, + #[doc = "< Tile height in elements"] + pub height: ::std::os::raw::c_uint, + #[doc = "< Tile depth in elements"] + pub depth: ::std::os::raw::c_uint, +} +#[doc = " CUDA array and CUDA mipmapped array memory requirements"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaArrayMemoryRequirements { + #[doc = "< Total size of the array."] + pub size: usize, + #[doc = "< Alignment necessary for mapping the array."] + pub alignment: usize, + pub reserved: [::std::os::raw::c_uint; 4usize], +} +impl cudaMemoryType { + #[doc = "< Unregistered memory"] + pub const cudaMemoryTypeUnregistered: cudaMemoryType = cudaMemoryType(0); +} +impl cudaMemoryType { + #[doc = "< Host memory"] + pub const cudaMemoryTypeHost: cudaMemoryType = cudaMemoryType(1); +} +impl cudaMemoryType { + #[doc = "< Device memory"] + pub const cudaMemoryTypeDevice: cudaMemoryType = cudaMemoryType(2); +} +impl cudaMemoryType { + #[doc = "< Managed memory"] + pub const cudaMemoryTypeManaged: cudaMemoryType = cudaMemoryType(3); +} +#[repr(transparent)] +#[doc = " CUDA memory types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemoryType(pub ::std::os::raw::c_uint); +impl cudaMemcpyKind { + #[doc = "< Host -> Host"] + pub const cudaMemcpyHostToHost: cudaMemcpyKind = cudaMemcpyKind(0); +} +impl cudaMemcpyKind { + #[doc = "< Host -> Device"] + pub const cudaMemcpyHostToDevice: cudaMemcpyKind = cudaMemcpyKind(1); +} +impl cudaMemcpyKind { + #[doc = "< Device -> Host"] + pub const cudaMemcpyDeviceToHost: cudaMemcpyKind = cudaMemcpyKind(2); +} +impl cudaMemcpyKind { + #[doc = "< Device -> Device"] + pub const cudaMemcpyDeviceToDevice: cudaMemcpyKind = cudaMemcpyKind(3); +} +impl cudaMemcpyKind { + #[doc = "< Direction of the transfer is inferred from the pointer values. Requires unified virtual addressing"] + pub const cudaMemcpyDefault: cudaMemcpyKind = cudaMemcpyKind(4); +} +#[repr(transparent)] +#[doc = " CUDA memory copy types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemcpyKind(pub ::std::os::raw::c_uint); +#[doc = " CUDA Pitched memory pointer\n\n \\sa ::make_cudaPitchedPtr"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaPitchedPtr { + #[doc = "< Pointer to allocated memory"] + pub ptr: *mut ::std::os::raw::c_void, + #[doc = "< Pitch of allocated memory in bytes"] + pub pitch: usize, + #[doc = "< Logical width of allocation in elements"] + pub xsize: usize, + #[doc = "< Logical height of allocation in elements"] + pub ysize: usize, +} +#[doc = " CUDA extent\n\n \\sa ::make_cudaExtent"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExtent { + #[doc = "< Width in elements when referring to array memory, in bytes when referring to linear memory"] + pub width: usize, + #[doc = "< Height in elements"] + pub height: usize, + #[doc = "< Depth in elements"] + pub depth: usize, +} +#[doc = " CUDA 3D position\n\n \\sa ::make_cudaPos"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaPos { + #[doc = "< x"] + pub x: usize, + #[doc = "< y"] + pub y: usize, + #[doc = "< z"] + pub z: usize, +} +#[doc = " CUDA 3D memory copying parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemcpy3DParms { + #[doc = "< Source memory address"] + pub srcArray: cudaArray_t, + #[doc = "< Source position offset"] + pub srcPos: cudaPos, + #[doc = "< Pitched source memory address"] + pub srcPtr: cudaPitchedPtr, + #[doc = "< Destination memory address"] + pub dstArray: cudaArray_t, + #[doc = "< Destination position offset"] + pub dstPos: cudaPos, + #[doc = "< Pitched destination memory address"] + pub dstPtr: cudaPitchedPtr, + #[doc = "< Requested memory copy size"] + pub extent: cudaExtent, + #[doc = "< Type of transfer"] + pub kind: cudaMemcpyKind, +} +#[doc = " CUDA 3D cross-device memory copying parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemcpy3DPeerParms { + #[doc = "< Source memory address"] + pub srcArray: cudaArray_t, + #[doc = "< Source position offset"] + pub srcPos: cudaPos, + #[doc = "< Pitched source memory address"] + pub srcPtr: cudaPitchedPtr, + #[doc = "< Source device"] + pub srcDevice: ::std::os::raw::c_int, + #[doc = "< Destination memory address"] + pub dstArray: cudaArray_t, + #[doc = "< Destination position offset"] + pub dstPos: cudaPos, + #[doc = "< Pitched destination memory address"] + pub dstPtr: cudaPitchedPtr, + #[doc = "< Destination device"] + pub dstDevice: ::std::os::raw::c_int, + #[doc = "< Requested memory copy size"] + pub extent: cudaExtent, +} +#[doc = " CUDA Memset node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemsetParams { + #[doc = "< Destination device pointer"] + pub dst: *mut ::std::os::raw::c_void, + #[doc = "< Pitch of destination device pointer. Unused if height is 1"] + pub pitch: usize, + #[doc = "< Value to be set"] + pub value: ::std::os::raw::c_uint, + #[doc = "< Size of each element in bytes. Must be 1, 2, or 4."] + pub elementSize: ::std::os::raw::c_uint, + #[doc = "< Width of the row in elements"] + pub width: usize, + #[doc = "< Number of rows"] + pub height: usize, +} +impl cudaAccessProperty { + #[doc = "< Normal cache persistence."] + pub const cudaAccessPropertyNormal: cudaAccessProperty = cudaAccessProperty(0); +} +impl cudaAccessProperty { + #[doc = "< Streaming access is less likely to persit from cache."] + pub const cudaAccessPropertyStreaming: cudaAccessProperty = cudaAccessProperty(1); +} +impl cudaAccessProperty { + #[doc = "< Persisting access is more likely to persist in cache."] + pub const cudaAccessPropertyPersisting: cudaAccessProperty = cudaAccessProperty(2); +} +#[repr(transparent)] +#[doc = " Specifies performance hint with ::cudaAccessPolicyWindow for hitProp and missProp members."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaAccessProperty(pub ::std::os::raw::c_uint); +#[doc = " Specifies an access policy for a window, a contiguous extent of memory\n beginning at base_ptr and ending at base_ptr + num_bytes.\n Partition into many segments and assign segments such that.\n sum of \"hit segments\" / window == approx. ratio.\n sum of \"miss segments\" / window == approx 1-ratio.\n Segments and ratio specifications are fitted to the capabilities of\n the architecture.\n Accesses in a hit segment apply the hitProp access policy.\n Accesses in a miss segment apply the missProp access policy."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaAccessPolicyWindow { + #[doc = "< Starting address of the access policy window. CUDA driver may align it."] + pub base_ptr: *mut ::std::os::raw::c_void, + #[doc = "< Size in bytes of the window policy. CUDA driver may restrict the maximum size and alignment."] + pub num_bytes: usize, + #[doc = "< hitRatio specifies percentage of lines assigned hitProp, rest are assigned missProp."] + pub hitRatio: f32, + #[doc = "< ::CUaccessProperty set for hit."] + pub hitProp: cudaAccessProperty, + #[doc = "< ::CUaccessProperty set for miss. Must be either NORMAL or STREAMING."] + pub missProp: cudaAccessProperty, +} +#[doc = " CUDA host function\n \\param userData Argument value passed to the function"] +pub type cudaHostFn_t = + ::std::option::Option; +#[doc = " CUDA host node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaHostNodeParams { + #[doc = "< The function to call when the node executes"] + pub fn_: cudaHostFn_t, + #[doc = "< Argument to pass to the function"] + pub userData: *mut ::std::os::raw::c_void, +} +impl cudaStreamCaptureStatus { + #[doc = "< Stream is not capturing"] + pub const cudaStreamCaptureStatusNone: cudaStreamCaptureStatus = cudaStreamCaptureStatus(0); +} +impl cudaStreamCaptureStatus { + #[doc = "< Stream is actively capturing"] + pub const cudaStreamCaptureStatusActive: cudaStreamCaptureStatus = cudaStreamCaptureStatus(1); +} +impl cudaStreamCaptureStatus { + #[doc = "< Stream is part of a capture sequence that\nhas been invalidated, but not terminated"] + pub const cudaStreamCaptureStatusInvalidated: cudaStreamCaptureStatus = + cudaStreamCaptureStatus(2); +} +#[repr(transparent)] +#[doc = " Possible stream capture statuses returned by ::cudaStreamIsCapturing"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaStreamCaptureStatus(pub ::std::os::raw::c_uint); +impl cudaStreamCaptureMode { + pub const cudaStreamCaptureModeGlobal: cudaStreamCaptureMode = cudaStreamCaptureMode(0); +} +impl cudaStreamCaptureMode { + pub const cudaStreamCaptureModeThreadLocal: cudaStreamCaptureMode = cudaStreamCaptureMode(1); +} +impl cudaStreamCaptureMode { + pub const cudaStreamCaptureModeRelaxed: cudaStreamCaptureMode = cudaStreamCaptureMode(2); +} +#[repr(transparent)] +#[doc = " Possible modes for stream capture thread interactions. For more details see\n ::cudaStreamBeginCapture and ::cudaThreadExchangeStreamCaptureMode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaStreamCaptureMode(pub ::std::os::raw::c_uint); +impl cudaSynchronizationPolicy { + pub const cudaSyncPolicyAuto: cudaSynchronizationPolicy = cudaSynchronizationPolicy(1); +} +impl cudaSynchronizationPolicy { + pub const cudaSyncPolicySpin: cudaSynchronizationPolicy = cudaSynchronizationPolicy(2); +} +impl cudaSynchronizationPolicy { + pub const cudaSyncPolicyYield: cudaSynchronizationPolicy = cudaSynchronizationPolicy(3); +} +impl cudaSynchronizationPolicy { + pub const cudaSyncPolicyBlockingSync: cudaSynchronizationPolicy = cudaSynchronizationPolicy(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaSynchronizationPolicy(pub ::std::os::raw::c_uint); +impl cudaClusterSchedulingPolicy { + #[doc = "< the default policy"] + pub const cudaClusterSchedulingPolicyDefault: cudaClusterSchedulingPolicy = + cudaClusterSchedulingPolicy(0); +} +impl cudaClusterSchedulingPolicy { + #[doc = "< spread the blocks within a cluster to the SMs"] + pub const cudaClusterSchedulingPolicySpread: cudaClusterSchedulingPolicy = + cudaClusterSchedulingPolicy(1); +} +impl cudaClusterSchedulingPolicy { + #[doc = "< allow the hardware to load-balance the blocks in a cluster to the SMs"] + pub const cudaClusterSchedulingPolicyLoadBalancing: cudaClusterSchedulingPolicy = + cudaClusterSchedulingPolicy(2); +} +#[repr(transparent)] +#[doc = " Cluster scheduling policies. These may be passed to ::cudaFuncSetAttribute"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaClusterSchedulingPolicy(pub ::std::os::raw::c_uint); +impl cudaStreamUpdateCaptureDependenciesFlags { + #[doc = "< Add new nodes to the dependency set"] + pub const cudaStreamAddCaptureDependencies: cudaStreamUpdateCaptureDependenciesFlags = + cudaStreamUpdateCaptureDependenciesFlags(0); +} +impl cudaStreamUpdateCaptureDependenciesFlags { + #[doc = "< Replace the dependency set with the new nodes"] + pub const cudaStreamSetCaptureDependencies: cudaStreamUpdateCaptureDependenciesFlags = + cudaStreamUpdateCaptureDependenciesFlags(1); +} +#[repr(transparent)] +#[doc = " Flags for ::cudaStreamUpdateCaptureDependencies"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaStreamUpdateCaptureDependenciesFlags(pub ::std::os::raw::c_uint); +impl cudaUserObjectFlags { + #[doc = "< Indicates the destructor execution is not synchronized by any CUDA handle."] + pub const cudaUserObjectNoDestructorSync: cudaUserObjectFlags = cudaUserObjectFlags(1); +} +#[repr(transparent)] +#[doc = " Flags for user objects for graphs"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaUserObjectFlags(pub ::std::os::raw::c_uint); +impl cudaUserObjectRetainFlags { + #[doc = "< Transfer references from the caller rather than creating new references."] + pub const cudaGraphUserObjectMove: cudaUserObjectRetainFlags = cudaUserObjectRetainFlags(1); +} +#[repr(transparent)] +#[doc = " Flags for retaining user object references for graphs"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaUserObjectRetainFlags(pub ::std::os::raw::c_uint); +#[doc = " CUDA graphics interop resource"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaGraphicsResource { + _unused: [u8; 0], +} +impl cudaGraphicsRegisterFlags { + #[doc = "< Default"] + pub const cudaGraphicsRegisterFlagsNone: cudaGraphicsRegisterFlags = + cudaGraphicsRegisterFlags(0); +} +impl cudaGraphicsRegisterFlags { + #[doc = "< CUDA will not write to this resource"] + pub const cudaGraphicsRegisterFlagsReadOnly: cudaGraphicsRegisterFlags = + cudaGraphicsRegisterFlags(1); +} +impl cudaGraphicsRegisterFlags { + #[doc = "< CUDA will only write to and will not read from this resource"] + pub const cudaGraphicsRegisterFlagsWriteDiscard: cudaGraphicsRegisterFlags = + cudaGraphicsRegisterFlags(2); +} +impl cudaGraphicsRegisterFlags { + #[doc = "< CUDA will bind this resource to a surface reference"] + pub const cudaGraphicsRegisterFlagsSurfaceLoadStore: cudaGraphicsRegisterFlags = + cudaGraphicsRegisterFlags(4); +} +impl cudaGraphicsRegisterFlags { + #[doc = "< CUDA will perform texture gather operations on this resource"] + pub const cudaGraphicsRegisterFlagsTextureGather: cudaGraphicsRegisterFlags = + cudaGraphicsRegisterFlags(8); +} +#[repr(transparent)] +#[doc = " CUDA graphics interop register flags"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphicsRegisterFlags(pub ::std::os::raw::c_uint); +impl cudaGraphicsMapFlags { + #[doc = "< Default; Assume resource can be read/written"] + pub const cudaGraphicsMapFlagsNone: cudaGraphicsMapFlags = cudaGraphicsMapFlags(0); +} +impl cudaGraphicsMapFlags { + #[doc = "< CUDA will not write to this resource"] + pub const cudaGraphicsMapFlagsReadOnly: cudaGraphicsMapFlags = cudaGraphicsMapFlags(1); +} +impl cudaGraphicsMapFlags { + #[doc = "< CUDA will only write to and will not read from this resource"] + pub const cudaGraphicsMapFlagsWriteDiscard: cudaGraphicsMapFlags = cudaGraphicsMapFlags(2); +} +#[repr(transparent)] +#[doc = " CUDA graphics interop map flags"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphicsMapFlags(pub ::std::os::raw::c_uint); +impl cudaGraphicsCubeFace { + #[doc = "< Positive X face of cubemap"] + pub const cudaGraphicsCubeFacePositiveX: cudaGraphicsCubeFace = cudaGraphicsCubeFace(0); +} +impl cudaGraphicsCubeFace { + #[doc = "< Negative X face of cubemap"] + pub const cudaGraphicsCubeFaceNegativeX: cudaGraphicsCubeFace = cudaGraphicsCubeFace(1); +} +impl cudaGraphicsCubeFace { + #[doc = "< Positive Y face of cubemap"] + pub const cudaGraphicsCubeFacePositiveY: cudaGraphicsCubeFace = cudaGraphicsCubeFace(2); +} +impl cudaGraphicsCubeFace { + #[doc = "< Negative Y face of cubemap"] + pub const cudaGraphicsCubeFaceNegativeY: cudaGraphicsCubeFace = cudaGraphicsCubeFace(3); +} +impl cudaGraphicsCubeFace { + #[doc = "< Positive Z face of cubemap"] + pub const cudaGraphicsCubeFacePositiveZ: cudaGraphicsCubeFace = cudaGraphicsCubeFace(4); +} +impl cudaGraphicsCubeFace { + #[doc = "< Negative Z face of cubemap"] + pub const cudaGraphicsCubeFaceNegativeZ: cudaGraphicsCubeFace = cudaGraphicsCubeFace(5); +} +#[repr(transparent)] +#[doc = " CUDA graphics interop array indices for cube maps"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphicsCubeFace(pub ::std::os::raw::c_uint); +impl cudaResourceType { + #[doc = "< Array resource"] + pub const cudaResourceTypeArray: cudaResourceType = cudaResourceType(0); +} +impl cudaResourceType { + #[doc = "< Mipmapped array resource"] + pub const cudaResourceTypeMipmappedArray: cudaResourceType = cudaResourceType(1); +} +impl cudaResourceType { + #[doc = "< Linear resource"] + pub const cudaResourceTypeLinear: cudaResourceType = cudaResourceType(2); +} +impl cudaResourceType { + #[doc = "< Pitch 2D resource"] + pub const cudaResourceTypePitch2D: cudaResourceType = cudaResourceType(3); +} +#[repr(transparent)] +#[doc = " CUDA resource types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaResourceType(pub ::std::os::raw::c_uint); +impl cudaResourceViewFormat { + #[doc = "< No resource view format (use underlying resource format)"] + pub const cudaResViewFormatNone: cudaResourceViewFormat = cudaResourceViewFormat(0); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel unsigned 8-bit integers"] + pub const cudaResViewFormatUnsignedChar1: cudaResourceViewFormat = cudaResourceViewFormat(1); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel unsigned 8-bit integers"] + pub const cudaResViewFormatUnsignedChar2: cudaResourceViewFormat = cudaResourceViewFormat(2); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel unsigned 8-bit integers"] + pub const cudaResViewFormatUnsignedChar4: cudaResourceViewFormat = cudaResourceViewFormat(3); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel signed 8-bit integers"] + pub const cudaResViewFormatSignedChar1: cudaResourceViewFormat = cudaResourceViewFormat(4); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel signed 8-bit integers"] + pub const cudaResViewFormatSignedChar2: cudaResourceViewFormat = cudaResourceViewFormat(5); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel signed 8-bit integers"] + pub const cudaResViewFormatSignedChar4: cudaResourceViewFormat = cudaResourceViewFormat(6); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel unsigned 16-bit integers"] + pub const cudaResViewFormatUnsignedShort1: cudaResourceViewFormat = cudaResourceViewFormat(7); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel unsigned 16-bit integers"] + pub const cudaResViewFormatUnsignedShort2: cudaResourceViewFormat = cudaResourceViewFormat(8); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel unsigned 16-bit integers"] + pub const cudaResViewFormatUnsignedShort4: cudaResourceViewFormat = cudaResourceViewFormat(9); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel signed 16-bit integers"] + pub const cudaResViewFormatSignedShort1: cudaResourceViewFormat = cudaResourceViewFormat(10); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel signed 16-bit integers"] + pub const cudaResViewFormatSignedShort2: cudaResourceViewFormat = cudaResourceViewFormat(11); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel signed 16-bit integers"] + pub const cudaResViewFormatSignedShort4: cudaResourceViewFormat = cudaResourceViewFormat(12); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel unsigned 32-bit integers"] + pub const cudaResViewFormatUnsignedInt1: cudaResourceViewFormat = cudaResourceViewFormat(13); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel unsigned 32-bit integers"] + pub const cudaResViewFormatUnsignedInt2: cudaResourceViewFormat = cudaResourceViewFormat(14); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel unsigned 32-bit integers"] + pub const cudaResViewFormatUnsignedInt4: cudaResourceViewFormat = cudaResourceViewFormat(15); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel signed 32-bit integers"] + pub const cudaResViewFormatSignedInt1: cudaResourceViewFormat = cudaResourceViewFormat(16); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel signed 32-bit integers"] + pub const cudaResViewFormatSignedInt2: cudaResourceViewFormat = cudaResourceViewFormat(17); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel signed 32-bit integers"] + pub const cudaResViewFormatSignedInt4: cudaResourceViewFormat = cudaResourceViewFormat(18); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel 16-bit floating point"] + pub const cudaResViewFormatHalf1: cudaResourceViewFormat = cudaResourceViewFormat(19); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel 16-bit floating point"] + pub const cudaResViewFormatHalf2: cudaResourceViewFormat = cudaResourceViewFormat(20); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel 16-bit floating point"] + pub const cudaResViewFormatHalf4: cudaResourceViewFormat = cudaResourceViewFormat(21); +} +impl cudaResourceViewFormat { + #[doc = "< 1 channel 32-bit floating point"] + pub const cudaResViewFormatFloat1: cudaResourceViewFormat = cudaResourceViewFormat(22); +} +impl cudaResourceViewFormat { + #[doc = "< 2 channel 32-bit floating point"] + pub const cudaResViewFormatFloat2: cudaResourceViewFormat = cudaResourceViewFormat(23); +} +impl cudaResourceViewFormat { + #[doc = "< 4 channel 32-bit floating point"] + pub const cudaResViewFormatFloat4: cudaResourceViewFormat = cudaResourceViewFormat(24); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 1"] + pub const cudaResViewFormatUnsignedBlockCompressed1: cudaResourceViewFormat = + cudaResourceViewFormat(25); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 2"] + pub const cudaResViewFormatUnsignedBlockCompressed2: cudaResourceViewFormat = + cudaResourceViewFormat(26); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 3"] + pub const cudaResViewFormatUnsignedBlockCompressed3: cudaResourceViewFormat = + cudaResourceViewFormat(27); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 4 unsigned"] + pub const cudaResViewFormatUnsignedBlockCompressed4: cudaResourceViewFormat = + cudaResourceViewFormat(28); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 4 signed"] + pub const cudaResViewFormatSignedBlockCompressed4: cudaResourceViewFormat = + cudaResourceViewFormat(29); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 5 unsigned"] + pub const cudaResViewFormatUnsignedBlockCompressed5: cudaResourceViewFormat = + cudaResourceViewFormat(30); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 5 signed"] + pub const cudaResViewFormatSignedBlockCompressed5: cudaResourceViewFormat = + cudaResourceViewFormat(31); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 6 unsigned half-float"] + pub const cudaResViewFormatUnsignedBlockCompressed6H: cudaResourceViewFormat = + cudaResourceViewFormat(32); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 6 signed half-float"] + pub const cudaResViewFormatSignedBlockCompressed6H: cudaResourceViewFormat = + cudaResourceViewFormat(33); +} +impl cudaResourceViewFormat { + #[doc = "< Block compressed 7"] + pub const cudaResViewFormatUnsignedBlockCompressed7: cudaResourceViewFormat = + cudaResourceViewFormat(34); +} +#[repr(transparent)] +#[doc = " CUDA texture resource view formats"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaResourceViewFormat(pub ::std::os::raw::c_uint); +#[doc = " CUDA resource descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceDesc { + #[doc = "< Resource type"] + pub resType: cudaResourceType, + pub res: cudaResourceDesc__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaResourceDesc__bindgen_ty_1 { + pub array: cudaResourceDesc__bindgen_ty_1__bindgen_ty_1, + pub mipmap: cudaResourceDesc__bindgen_ty_1__bindgen_ty_2, + pub linear: cudaResourceDesc__bindgen_ty_1__bindgen_ty_3, + pub pitch2D: cudaResourceDesc__bindgen_ty_1__bindgen_ty_4, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceDesc__bindgen_ty_1__bindgen_ty_1 { + #[doc = "< CUDA array"] + pub array: cudaArray_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceDesc__bindgen_ty_1__bindgen_ty_2 { + #[doc = "< CUDA mipmapped array"] + pub mipmap: cudaMipmappedArray_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceDesc__bindgen_ty_1__bindgen_ty_3 { + #[doc = "< Device pointer"] + pub devPtr: *mut ::std::os::raw::c_void, + #[doc = "< Channel descriptor"] + pub desc: cudaChannelFormatDesc, + #[doc = "< Size in bytes"] + pub sizeInBytes: usize, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceDesc__bindgen_ty_1__bindgen_ty_4 { + #[doc = "< Device pointer"] + pub devPtr: *mut ::std::os::raw::c_void, + #[doc = "< Channel descriptor"] + pub desc: cudaChannelFormatDesc, + #[doc = "< Width of the array in elements"] + pub width: usize, + #[doc = "< Height of the array in elements"] + pub height: usize, + #[doc = "< Pitch between two rows in bytes"] + pub pitchInBytes: usize, +} +#[doc = " CUDA resource view descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaResourceViewDesc { + #[doc = "< Resource view format"] + pub format: cudaResourceViewFormat, + #[doc = "< Width of the resource view"] + pub width: usize, + #[doc = "< Height of the resource view"] + pub height: usize, + #[doc = "< Depth of the resource view"] + pub depth: usize, + #[doc = "< First defined mipmap level"] + pub firstMipmapLevel: ::std::os::raw::c_uint, + #[doc = "< Last defined mipmap level"] + pub lastMipmapLevel: ::std::os::raw::c_uint, + #[doc = "< First layer index"] + pub firstLayer: ::std::os::raw::c_uint, + #[doc = "< Last layer index"] + pub lastLayer: ::std::os::raw::c_uint, +} +#[doc = " CUDA pointer attributes"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaPointerAttributes { + #[doc = " The type of memory - ::cudaMemoryTypeUnregistered, ::cudaMemoryTypeHost,\n ::cudaMemoryTypeDevice or ::cudaMemoryTypeManaged."] + pub type_: cudaMemoryType, + #[doc = " The device against which the memory was allocated or registered.\n If the memory type is ::cudaMemoryTypeDevice then this identifies\n the device on which the memory referred physically resides. If\n the memory type is ::cudaMemoryTypeHost or::cudaMemoryTypeManaged then\n this identifies the device which was current when the memory was allocated\n or registered (and if that device is deinitialized then this allocation\n will vanish with that device's state)."] + pub device: ::std::os::raw::c_int, + #[doc = " The address which may be dereferenced on the current device to access\n the memory or NULL if no such address exists."] + pub devicePointer: *mut ::std::os::raw::c_void, + #[doc = " The address which may be dereferenced on the host to access the\n memory or NULL if no such address exists.\n\n \\note CUDA doesn't check if unregistered memory is allocated so this field\n may contain invalid pointer if an invalid pointer has been passed to CUDA."] + pub hostPointer: *mut ::std::os::raw::c_void, +} +#[doc = " CUDA function attributes"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaFuncAttributes { + #[doc = " The size in bytes of statically-allocated shared memory per block\n required by this function. This does not include dynamically-allocated\n shared memory requested by the user at runtime."] + pub sharedSizeBytes: usize, + #[doc = " The size in bytes of user-allocated constant memory required by this\n function."] + pub constSizeBytes: usize, + #[doc = " The size in bytes of local memory used by each thread of this function."] + pub localSizeBytes: usize, + #[doc = " The maximum number of threads per block, beyond which a launch of the\n function would fail. This number depends on both the function and the\n device on which the function is currently loaded."] + pub maxThreadsPerBlock: ::std::os::raw::c_int, + #[doc = " The number of registers used by each thread of this function."] + pub numRegs: ::std::os::raw::c_int, + #[doc = " The PTX virtual architecture version for which the function was\n compiled. This value is the major PTX version * 10 + the minor PTX\n version, so a PTX version 1.3 function would return the value 13."] + pub ptxVersion: ::std::os::raw::c_int, + #[doc = " The binary architecture version for which the function was compiled.\n This value is the major binary version * 10 + the minor binary version,\n so a binary version 1.3 function would return the value 13."] + pub binaryVersion: ::std::os::raw::c_int, + #[doc = " The attribute to indicate whether the function has been compiled with\n user specified option \"-Xptxas --dlcm=ca\" set."] + pub cacheModeCA: ::std::os::raw::c_int, + #[doc = " The maximum size in bytes of dynamic shared memory per block for\n this function. Any launch must have a dynamic shared memory size\n smaller than this value."] + pub maxDynamicSharedSizeBytes: ::std::os::raw::c_int, + #[doc = " On devices where the L1 cache and shared memory use the same hardware resources,\n this sets the shared memory carveout preference, in percent of the maximum shared memory.\n Refer to ::cudaDevAttrMaxSharedMemoryPerMultiprocessor.\n This is only a hint, and the driver can choose a different ratio if required to execute the function.\n See ::cudaFuncSetAttribute"] + pub preferredShmemCarveout: ::std::os::raw::c_int, +} +impl cudaFuncAttribute { + #[doc = "< Maximum dynamic shared memory size"] + pub const cudaFuncAttributeMaxDynamicSharedMemorySize: cudaFuncAttribute = cudaFuncAttribute(8); +} +impl cudaFuncAttribute { + #[doc = "< Preferred shared memory-L1 cache split"] + pub const cudaFuncAttributePreferredSharedMemoryCarveout: cudaFuncAttribute = + cudaFuncAttribute(9); +} +impl cudaFuncAttribute { + #[doc = "< Indicator to enforce valid cluster dimension specification on kernel launch"] + pub const cudaFuncAttributeClusterDimMustBeSet: cudaFuncAttribute = cudaFuncAttribute(10); +} +impl cudaFuncAttribute { + #[doc = "< Required cluster width"] + pub const cudaFuncAttributeRequiredClusterWidth: cudaFuncAttribute = cudaFuncAttribute(11); +} +impl cudaFuncAttribute { + #[doc = "< Required cluster height"] + pub const cudaFuncAttributeRequiredClusterHeight: cudaFuncAttribute = cudaFuncAttribute(12); +} +impl cudaFuncAttribute { + #[doc = "< Required cluster depth"] + pub const cudaFuncAttributeRequiredClusterDepth: cudaFuncAttribute = cudaFuncAttribute(13); +} +impl cudaFuncAttribute { + #[doc = "< Whether non-portable cluster scheduling policy is supported"] + pub const cudaFuncAttributeNonPortableClusterSizeAllowed: cudaFuncAttribute = + cudaFuncAttribute(14); +} +impl cudaFuncAttribute { + #[doc = "< Required cluster scheduling policy preference"] + pub const cudaFuncAttributeClusterSchedulingPolicyPreference: cudaFuncAttribute = + cudaFuncAttribute(15); +} +impl cudaFuncAttribute { + pub const cudaFuncAttributeMax: cudaFuncAttribute = cudaFuncAttribute(16); +} +#[repr(transparent)] +#[doc = " CUDA function attributes that can be set using ::cudaFuncSetAttribute"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaFuncAttribute(pub ::std::os::raw::c_uint); +impl cudaFuncCache { + #[doc = "< Default function cache configuration, no preference"] + pub const cudaFuncCachePreferNone: cudaFuncCache = cudaFuncCache(0); +} +impl cudaFuncCache { + #[doc = "< Prefer larger shared memory and smaller L1 cache"] + pub const cudaFuncCachePreferShared: cudaFuncCache = cudaFuncCache(1); +} +impl cudaFuncCache { + #[doc = "< Prefer larger L1 cache and smaller shared memory"] + pub const cudaFuncCachePreferL1: cudaFuncCache = cudaFuncCache(2); +} +impl cudaFuncCache { + #[doc = "< Prefer equal size L1 cache and shared memory"] + pub const cudaFuncCachePreferEqual: cudaFuncCache = cudaFuncCache(3); +} +#[repr(transparent)] +#[doc = " CUDA function cache configurations"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaFuncCache(pub ::std::os::raw::c_uint); +impl cudaSharedMemConfig { + pub const cudaSharedMemBankSizeDefault: cudaSharedMemConfig = cudaSharedMemConfig(0); +} +impl cudaSharedMemConfig { + pub const cudaSharedMemBankSizeFourByte: cudaSharedMemConfig = cudaSharedMemConfig(1); +} +impl cudaSharedMemConfig { + pub const cudaSharedMemBankSizeEightByte: cudaSharedMemConfig = cudaSharedMemConfig(2); +} +#[repr(transparent)] +#[doc = " CUDA shared memory configuration"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaSharedMemConfig(pub ::std::os::raw::c_uint); +impl cudaSharedCarveout { + #[doc = "< No preference for shared memory or L1 (default)"] + pub const cudaSharedmemCarveoutDefault: cudaSharedCarveout = cudaSharedCarveout(-1); +} +impl cudaSharedCarveout { + #[doc = "< Prefer maximum available shared memory, minimum L1 cache"] + pub const cudaSharedmemCarveoutMaxShared: cudaSharedCarveout = cudaSharedCarveout(100); +} +impl cudaSharedCarveout { + #[doc = "< Prefer maximum available L1 cache, minimum shared memory"] + pub const cudaSharedmemCarveoutMaxL1: cudaSharedCarveout = cudaSharedCarveout(0); +} +#[repr(transparent)] +#[doc = " Shared memory carveout configurations. These may be passed to cudaFuncSetAttribute"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaSharedCarveout(pub ::std::os::raw::c_int); +impl cudaComputeMode { + #[doc = "< Default compute mode (Multiple threads can use ::cudaSetDevice() with this device)"] + pub const cudaComputeModeDefault: cudaComputeMode = cudaComputeMode(0); +} +impl cudaComputeMode { + #[doc = "< Compute-exclusive-thread mode (Only one thread in one process will be able to use ::cudaSetDevice() with this device)"] + pub const cudaComputeModeExclusive: cudaComputeMode = cudaComputeMode(1); +} +impl cudaComputeMode { + #[doc = "< Compute-prohibited mode (No threads can use ::cudaSetDevice() with this device)"] + pub const cudaComputeModeProhibited: cudaComputeMode = cudaComputeMode(2); +} +impl cudaComputeMode { + #[doc = "< Compute-exclusive-process mode (Many threads in one process will be able to use ::cudaSetDevice() with this device)"] + pub const cudaComputeModeExclusiveProcess: cudaComputeMode = cudaComputeMode(3); +} +#[repr(transparent)] +#[doc = " CUDA device compute modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaComputeMode(pub ::std::os::raw::c_uint); +impl cudaLimit { + #[doc = "< GPU thread stack size"] + pub const cudaLimitStackSize: cudaLimit = cudaLimit(0); +} +impl cudaLimit { + #[doc = "< GPU printf FIFO size"] + pub const cudaLimitPrintfFifoSize: cudaLimit = cudaLimit(1); +} +impl cudaLimit { + #[doc = "< GPU malloc heap size"] + pub const cudaLimitMallocHeapSize: cudaLimit = cudaLimit(2); +} +impl cudaLimit { + #[doc = "< GPU device runtime synchronize depth"] + pub const cudaLimitDevRuntimeSyncDepth: cudaLimit = cudaLimit(3); +} +impl cudaLimit { + #[doc = "< GPU device runtime pending launch count"] + pub const cudaLimitDevRuntimePendingLaunchCount: cudaLimit = cudaLimit(4); +} +impl cudaLimit { + #[doc = "< A value between 0 and 128 that indicates the maximum fetch granularity of L2 (in Bytes). This is a hint"] + pub const cudaLimitMaxL2FetchGranularity: cudaLimit = cudaLimit(5); +} +impl cudaLimit { + #[doc = "< A size in bytes for L2 persisting lines cache size"] + pub const cudaLimitPersistingL2CacheSize: cudaLimit = cudaLimit(6); +} +#[repr(transparent)] +#[doc = " CUDA Limits"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaLimit(pub ::std::os::raw::c_uint); +impl cudaMemoryAdvise { + #[doc = "< Data will mostly be read and only occassionally be written to"] + pub const cudaMemAdviseSetReadMostly: cudaMemoryAdvise = cudaMemoryAdvise(1); +} +impl cudaMemoryAdvise { + #[doc = "< Undo the effect of ::cudaMemAdviseSetReadMostly"] + pub const cudaMemAdviseUnsetReadMostly: cudaMemoryAdvise = cudaMemoryAdvise(2); +} +impl cudaMemoryAdvise { + #[doc = "< Set the preferred location for the data as the specified device"] + pub const cudaMemAdviseSetPreferredLocation: cudaMemoryAdvise = cudaMemoryAdvise(3); +} +impl cudaMemoryAdvise { + #[doc = "< Clear the preferred location for the data"] + pub const cudaMemAdviseUnsetPreferredLocation: cudaMemoryAdvise = cudaMemoryAdvise(4); +} +impl cudaMemoryAdvise { + #[doc = "< Data will be accessed by the specified device, so prevent page faults as much as possible"] + pub const cudaMemAdviseSetAccessedBy: cudaMemoryAdvise = cudaMemoryAdvise(5); +} +impl cudaMemoryAdvise { + #[doc = "< Let the Unified Memory subsystem decide on the page faulting policy for the specified device"] + pub const cudaMemAdviseUnsetAccessedBy: cudaMemoryAdvise = cudaMemoryAdvise(6); +} +#[repr(transparent)] +#[doc = " CUDA Memory Advise values"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemoryAdvise(pub ::std::os::raw::c_uint); +impl cudaMemRangeAttribute { + #[doc = "< Whether the range will mostly be read and only occassionally be written to"] + pub const cudaMemRangeAttributeReadMostly: cudaMemRangeAttribute = cudaMemRangeAttribute(1); +} +impl cudaMemRangeAttribute { + #[doc = "< The preferred location of the range"] + pub const cudaMemRangeAttributePreferredLocation: cudaMemRangeAttribute = + cudaMemRangeAttribute(2); +} +impl cudaMemRangeAttribute { + #[doc = "< Memory range has ::cudaMemAdviseSetAccessedBy set for specified device"] + pub const cudaMemRangeAttributeAccessedBy: cudaMemRangeAttribute = cudaMemRangeAttribute(3); +} +impl cudaMemRangeAttribute { + #[doc = "< The last location to which the range was prefetched"] + pub const cudaMemRangeAttributeLastPrefetchLocation: cudaMemRangeAttribute = + cudaMemRangeAttribute(4); +} +#[repr(transparent)] +#[doc = " CUDA range attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemRangeAttribute(pub ::std::os::raw::c_uint); +impl cudaOutputMode { + #[doc = "< Output mode Key-Value pair format."] + pub const cudaKeyValuePair: cudaOutputMode = cudaOutputMode(0); +} +impl cudaOutputMode { + #[doc = "< Output mode Comma separated values format."] + pub const cudaCSV: cudaOutputMode = cudaOutputMode(1); +} +#[repr(transparent)] +#[doc = " CUDA Profiler Output modes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaOutputMode(pub ::std::os::raw::c_uint); +impl cudaFlushGPUDirectRDMAWritesOptions { + #[doc = "< ::cudaDeviceFlushGPUDirectRDMAWrites() and its CUDA Driver API counterpart are supported on the device."] + pub const cudaFlushGPUDirectRDMAWritesOptionHost: cudaFlushGPUDirectRDMAWritesOptions = + cudaFlushGPUDirectRDMAWritesOptions(1); +} +impl cudaFlushGPUDirectRDMAWritesOptions { + #[doc = "< The ::CU_STREAM_WAIT_VALUE_FLUSH flag and the ::CU_STREAM_MEM_OP_FLUSH_REMOTE_WRITES MemOp are supported on the CUDA device."] + pub const cudaFlushGPUDirectRDMAWritesOptionMemOps: cudaFlushGPUDirectRDMAWritesOptions = + cudaFlushGPUDirectRDMAWritesOptions(2); +} +#[repr(transparent)] +#[doc = " CUDA GPUDirect RDMA flush writes APIs supported on the device"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaFlushGPUDirectRDMAWritesOptions(pub ::std::os::raw::c_uint); +impl cudaGPUDirectRDMAWritesOrdering { + #[doc = "< The device does not natively support ordering of GPUDirect RDMA writes. ::cudaFlushGPUDirectRDMAWrites() can be leveraged if supported."] + pub const cudaGPUDirectRDMAWritesOrderingNone: cudaGPUDirectRDMAWritesOrdering = + cudaGPUDirectRDMAWritesOrdering(0); +} +impl cudaGPUDirectRDMAWritesOrdering { + #[doc = "< Natively, the device can consistently consume GPUDirect RDMA writes, although other CUDA devices may not."] + pub const cudaGPUDirectRDMAWritesOrderingOwner: cudaGPUDirectRDMAWritesOrdering = + cudaGPUDirectRDMAWritesOrdering(100); +} +impl cudaGPUDirectRDMAWritesOrdering { + #[doc = "< Any CUDA device in the system can consistently consume GPUDirect RDMA writes to this device."] + pub const cudaGPUDirectRDMAWritesOrderingAllDevices: cudaGPUDirectRDMAWritesOrdering = + cudaGPUDirectRDMAWritesOrdering(200); +} +#[repr(transparent)] +#[doc = " CUDA GPUDirect RDMA flush writes ordering features of the device"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGPUDirectRDMAWritesOrdering(pub ::std::os::raw::c_uint); +impl cudaFlushGPUDirectRDMAWritesScope { + #[doc = "< Blocks until remote writes are visible to the CUDA device context owning the data."] + pub const cudaFlushGPUDirectRDMAWritesToOwner: cudaFlushGPUDirectRDMAWritesScope = + cudaFlushGPUDirectRDMAWritesScope(100); +} +impl cudaFlushGPUDirectRDMAWritesScope { + #[doc = "< Blocks until remote writes are visible to all CUDA device contexts."] + pub const cudaFlushGPUDirectRDMAWritesToAllDevices: cudaFlushGPUDirectRDMAWritesScope = + cudaFlushGPUDirectRDMAWritesScope(200); +} +#[repr(transparent)] +#[doc = " CUDA GPUDirect RDMA flush writes scopes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaFlushGPUDirectRDMAWritesScope(pub ::std::os::raw::c_uint); +impl cudaFlushGPUDirectRDMAWritesTarget { + #[doc = "< Sets the target for ::cudaDeviceFlushGPUDirectRDMAWrites() to the currently active CUDA device context."] + pub const cudaFlushGPUDirectRDMAWritesTargetCurrentDevice: cudaFlushGPUDirectRDMAWritesTarget = + cudaFlushGPUDirectRDMAWritesTarget(0); +} +#[repr(transparent)] +#[doc = " CUDA GPUDirect RDMA flush writes targets"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaFlushGPUDirectRDMAWritesTarget(pub ::std::os::raw::c_uint); +impl cudaDeviceAttr { + #[doc = "< Maximum number of threads per block"] + pub const cudaDevAttrMaxThreadsPerBlock: cudaDeviceAttr = cudaDeviceAttr(1); +} +impl cudaDeviceAttr { + #[doc = "< Maximum block dimension X"] + pub const cudaDevAttrMaxBlockDimX: cudaDeviceAttr = cudaDeviceAttr(2); +} +impl cudaDeviceAttr { + #[doc = "< Maximum block dimension Y"] + pub const cudaDevAttrMaxBlockDimY: cudaDeviceAttr = cudaDeviceAttr(3); +} +impl cudaDeviceAttr { + #[doc = "< Maximum block dimension Z"] + pub const cudaDevAttrMaxBlockDimZ: cudaDeviceAttr = cudaDeviceAttr(4); +} +impl cudaDeviceAttr { + #[doc = "< Maximum grid dimension X"] + pub const cudaDevAttrMaxGridDimX: cudaDeviceAttr = cudaDeviceAttr(5); +} +impl cudaDeviceAttr { + #[doc = "< Maximum grid dimension Y"] + pub const cudaDevAttrMaxGridDimY: cudaDeviceAttr = cudaDeviceAttr(6); +} +impl cudaDeviceAttr { + #[doc = "< Maximum grid dimension Z"] + pub const cudaDevAttrMaxGridDimZ: cudaDeviceAttr = cudaDeviceAttr(7); +} +impl cudaDeviceAttr { + #[doc = "< Maximum shared memory available per block in bytes"] + pub const cudaDevAttrMaxSharedMemoryPerBlock: cudaDeviceAttr = cudaDeviceAttr(8); +} +impl cudaDeviceAttr { + #[doc = "< Memory available on device for __constant__ variables in a CUDA C kernel in bytes"] + pub const cudaDevAttrTotalConstantMemory: cudaDeviceAttr = cudaDeviceAttr(9); +} +impl cudaDeviceAttr { + #[doc = "< Warp size in threads"] + pub const cudaDevAttrWarpSize: cudaDeviceAttr = cudaDeviceAttr(10); +} +impl cudaDeviceAttr { + #[doc = "< Maximum pitch in bytes allowed by memory copies"] + pub const cudaDevAttrMaxPitch: cudaDeviceAttr = cudaDeviceAttr(11); +} +impl cudaDeviceAttr { + #[doc = "< Maximum number of 32-bit registers available per block"] + pub const cudaDevAttrMaxRegistersPerBlock: cudaDeviceAttr = cudaDeviceAttr(12); +} +impl cudaDeviceAttr { + #[doc = "< Peak clock frequency in kilohertz"] + pub const cudaDevAttrClockRate: cudaDeviceAttr = cudaDeviceAttr(13); +} +impl cudaDeviceAttr { + #[doc = "< Alignment requirement for textures"] + pub const cudaDevAttrTextureAlignment: cudaDeviceAttr = cudaDeviceAttr(14); +} +impl cudaDeviceAttr { + #[doc = "< Device can possibly copy memory and execute a kernel concurrently"] + pub const cudaDevAttrGpuOverlap: cudaDeviceAttr = cudaDeviceAttr(15); +} +impl cudaDeviceAttr { + #[doc = "< Number of multiprocessors on device"] + pub const cudaDevAttrMultiProcessorCount: cudaDeviceAttr = cudaDeviceAttr(16); +} +impl cudaDeviceAttr { + #[doc = "< Specifies whether there is a run time limit on kernels"] + pub const cudaDevAttrKernelExecTimeout: cudaDeviceAttr = cudaDeviceAttr(17); +} +impl cudaDeviceAttr { + #[doc = "< Device is integrated with host memory"] + pub const cudaDevAttrIntegrated: cudaDeviceAttr = cudaDeviceAttr(18); +} +impl cudaDeviceAttr { + #[doc = "< Device can map host memory into CUDA address space"] + pub const cudaDevAttrCanMapHostMemory: cudaDeviceAttr = cudaDeviceAttr(19); +} +impl cudaDeviceAttr { + #[doc = "< Compute mode (See ::cudaComputeMode for details)"] + pub const cudaDevAttrComputeMode: cudaDeviceAttr = cudaDeviceAttr(20); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 1D texture width"] + pub const cudaDevAttrMaxTexture1DWidth: cudaDeviceAttr = cudaDeviceAttr(21); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D texture width"] + pub const cudaDevAttrMaxTexture2DWidth: cudaDeviceAttr = cudaDeviceAttr(22); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D texture height"] + pub const cudaDevAttrMaxTexture2DHeight: cudaDeviceAttr = cudaDeviceAttr(23); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D texture width"] + pub const cudaDevAttrMaxTexture3DWidth: cudaDeviceAttr = cudaDeviceAttr(24); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D texture height"] + pub const cudaDevAttrMaxTexture3DHeight: cudaDeviceAttr = cudaDeviceAttr(25); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D texture depth"] + pub const cudaDevAttrMaxTexture3DDepth: cudaDeviceAttr = cudaDeviceAttr(26); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D layered texture width"] + pub const cudaDevAttrMaxTexture2DLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(27); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D layered texture height"] + pub const cudaDevAttrMaxTexture2DLayeredHeight: cudaDeviceAttr = cudaDeviceAttr(28); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a 2D layered texture"] + pub const cudaDevAttrMaxTexture2DLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(29); +} +impl cudaDeviceAttr { + #[doc = "< Alignment requirement for surfaces"] + pub const cudaDevAttrSurfaceAlignment: cudaDeviceAttr = cudaDeviceAttr(30); +} +impl cudaDeviceAttr { + #[doc = "< Device can possibly execute multiple kernels concurrently"] + pub const cudaDevAttrConcurrentKernels: cudaDeviceAttr = cudaDeviceAttr(31); +} +impl cudaDeviceAttr { + #[doc = "< Device has ECC support enabled"] + pub const cudaDevAttrEccEnabled: cudaDeviceAttr = cudaDeviceAttr(32); +} +impl cudaDeviceAttr { + #[doc = "< PCI bus ID of the device"] + pub const cudaDevAttrPciBusId: cudaDeviceAttr = cudaDeviceAttr(33); +} +impl cudaDeviceAttr { + #[doc = "< PCI device ID of the device"] + pub const cudaDevAttrPciDeviceId: cudaDeviceAttr = cudaDeviceAttr(34); +} +impl cudaDeviceAttr { + #[doc = "< Device is using TCC driver model"] + pub const cudaDevAttrTccDriver: cudaDeviceAttr = cudaDeviceAttr(35); +} +impl cudaDeviceAttr { + #[doc = "< Peak memory clock frequency in kilohertz"] + pub const cudaDevAttrMemoryClockRate: cudaDeviceAttr = cudaDeviceAttr(36); +} +impl cudaDeviceAttr { + #[doc = "< Global memory bus width in bits"] + pub const cudaDevAttrGlobalMemoryBusWidth: cudaDeviceAttr = cudaDeviceAttr(37); +} +impl cudaDeviceAttr { + #[doc = "< Size of L2 cache in bytes"] + pub const cudaDevAttrL2CacheSize: cudaDeviceAttr = cudaDeviceAttr(38); +} +impl cudaDeviceAttr { + #[doc = "< Maximum resident threads per multiprocessor"] + pub const cudaDevAttrMaxThreadsPerMultiProcessor: cudaDeviceAttr = cudaDeviceAttr(39); +} +impl cudaDeviceAttr { + #[doc = "< Number of asynchronous engines"] + pub const cudaDevAttrAsyncEngineCount: cudaDeviceAttr = cudaDeviceAttr(40); +} +impl cudaDeviceAttr { + #[doc = "< Device shares a unified address space with the host"] + pub const cudaDevAttrUnifiedAddressing: cudaDeviceAttr = cudaDeviceAttr(41); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 1D layered texture width"] + pub const cudaDevAttrMaxTexture1DLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(42); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a 1D layered texture"] + pub const cudaDevAttrMaxTexture1DLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(43); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D texture width if cudaArrayTextureGather is set"] + pub const cudaDevAttrMaxTexture2DGatherWidth: cudaDeviceAttr = cudaDeviceAttr(45); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D texture height if cudaArrayTextureGather is set"] + pub const cudaDevAttrMaxTexture2DGatherHeight: cudaDeviceAttr = cudaDeviceAttr(46); +} +impl cudaDeviceAttr { + #[doc = "< Alternate maximum 3D texture width"] + pub const cudaDevAttrMaxTexture3DWidthAlt: cudaDeviceAttr = cudaDeviceAttr(47); +} +impl cudaDeviceAttr { + #[doc = "< Alternate maximum 3D texture height"] + pub const cudaDevAttrMaxTexture3DHeightAlt: cudaDeviceAttr = cudaDeviceAttr(48); +} +impl cudaDeviceAttr { + #[doc = "< Alternate maximum 3D texture depth"] + pub const cudaDevAttrMaxTexture3DDepthAlt: cudaDeviceAttr = cudaDeviceAttr(49); +} +impl cudaDeviceAttr { + #[doc = "< PCI domain ID of the device"] + pub const cudaDevAttrPciDomainId: cudaDeviceAttr = cudaDeviceAttr(50); +} +impl cudaDeviceAttr { + #[doc = "< Pitch alignment requirement for textures"] + pub const cudaDevAttrTexturePitchAlignment: cudaDeviceAttr = cudaDeviceAttr(51); +} +impl cudaDeviceAttr { + #[doc = "< Maximum cubemap texture width/height"] + pub const cudaDevAttrMaxTextureCubemapWidth: cudaDeviceAttr = cudaDeviceAttr(52); +} +impl cudaDeviceAttr { + #[doc = "< Maximum cubemap layered texture width/height"] + pub const cudaDevAttrMaxTextureCubemapLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(53); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a cubemap layered texture"] + pub const cudaDevAttrMaxTextureCubemapLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(54); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 1D surface width"] + pub const cudaDevAttrMaxSurface1DWidth: cudaDeviceAttr = cudaDeviceAttr(55); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D surface width"] + pub const cudaDevAttrMaxSurface2DWidth: cudaDeviceAttr = cudaDeviceAttr(56); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D surface height"] + pub const cudaDevAttrMaxSurface2DHeight: cudaDeviceAttr = cudaDeviceAttr(57); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D surface width"] + pub const cudaDevAttrMaxSurface3DWidth: cudaDeviceAttr = cudaDeviceAttr(58); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D surface height"] + pub const cudaDevAttrMaxSurface3DHeight: cudaDeviceAttr = cudaDeviceAttr(59); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 3D surface depth"] + pub const cudaDevAttrMaxSurface3DDepth: cudaDeviceAttr = cudaDeviceAttr(60); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 1D layered surface width"] + pub const cudaDevAttrMaxSurface1DLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(61); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a 1D layered surface"] + pub const cudaDevAttrMaxSurface1DLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(62); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D layered surface width"] + pub const cudaDevAttrMaxSurface2DLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(63); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D layered surface height"] + pub const cudaDevAttrMaxSurface2DLayeredHeight: cudaDeviceAttr = cudaDeviceAttr(64); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a 2D layered surface"] + pub const cudaDevAttrMaxSurface2DLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(65); +} +impl cudaDeviceAttr { + #[doc = "< Maximum cubemap surface width"] + pub const cudaDevAttrMaxSurfaceCubemapWidth: cudaDeviceAttr = cudaDeviceAttr(66); +} +impl cudaDeviceAttr { + #[doc = "< Maximum cubemap layered surface width"] + pub const cudaDevAttrMaxSurfaceCubemapLayeredWidth: cudaDeviceAttr = cudaDeviceAttr(67); +} +impl cudaDeviceAttr { + #[doc = "< Maximum layers in a cubemap layered surface"] + pub const cudaDevAttrMaxSurfaceCubemapLayeredLayers: cudaDeviceAttr = cudaDeviceAttr(68); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 1D linear texture width"] + pub const cudaDevAttrMaxTexture1DLinearWidth: cudaDeviceAttr = cudaDeviceAttr(69); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D linear texture width"] + pub const cudaDevAttrMaxTexture2DLinearWidth: cudaDeviceAttr = cudaDeviceAttr(70); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D linear texture height"] + pub const cudaDevAttrMaxTexture2DLinearHeight: cudaDeviceAttr = cudaDeviceAttr(71); +} +impl cudaDeviceAttr { + #[doc = "< Maximum 2D linear texture pitch in bytes"] + pub const cudaDevAttrMaxTexture2DLinearPitch: cudaDeviceAttr = cudaDeviceAttr(72); +} +impl cudaDeviceAttr { + #[doc = "< Maximum mipmapped 2D texture width"] + pub const cudaDevAttrMaxTexture2DMipmappedWidth: cudaDeviceAttr = cudaDeviceAttr(73); +} +impl cudaDeviceAttr { + #[doc = "< Maximum mipmapped 2D texture height"] + pub const cudaDevAttrMaxTexture2DMipmappedHeight: cudaDeviceAttr = cudaDeviceAttr(74); +} +impl cudaDeviceAttr { + #[doc = "< Major compute capability version number"] + pub const cudaDevAttrComputeCapabilityMajor: cudaDeviceAttr = cudaDeviceAttr(75); +} +impl cudaDeviceAttr { + #[doc = "< Minor compute capability version number"] + pub const cudaDevAttrComputeCapabilityMinor: cudaDeviceAttr = cudaDeviceAttr(76); +} +impl cudaDeviceAttr { + #[doc = "< Maximum mipmapped 1D texture width"] + pub const cudaDevAttrMaxTexture1DMipmappedWidth: cudaDeviceAttr = cudaDeviceAttr(77); +} +impl cudaDeviceAttr { + #[doc = "< Device supports stream priorities"] + pub const cudaDevAttrStreamPrioritiesSupported: cudaDeviceAttr = cudaDeviceAttr(78); +} +impl cudaDeviceAttr { + #[doc = "< Device supports caching globals in L1"] + pub const cudaDevAttrGlobalL1CacheSupported: cudaDeviceAttr = cudaDeviceAttr(79); +} +impl cudaDeviceAttr { + #[doc = "< Device supports caching locals in L1"] + pub const cudaDevAttrLocalL1CacheSupported: cudaDeviceAttr = cudaDeviceAttr(80); +} +impl cudaDeviceAttr { + #[doc = "< Maximum shared memory available per multiprocessor in bytes"] + pub const cudaDevAttrMaxSharedMemoryPerMultiprocessor: cudaDeviceAttr = cudaDeviceAttr(81); +} +impl cudaDeviceAttr { + #[doc = "< Maximum number of 32-bit registers available per multiprocessor"] + pub const cudaDevAttrMaxRegistersPerMultiprocessor: cudaDeviceAttr = cudaDeviceAttr(82); +} +impl cudaDeviceAttr { + #[doc = "< Device can allocate managed memory on this system"] + pub const cudaDevAttrManagedMemory: cudaDeviceAttr = cudaDeviceAttr(83); +} +impl cudaDeviceAttr { + #[doc = "< Device is on a multi-GPU board"] + pub const cudaDevAttrIsMultiGpuBoard: cudaDeviceAttr = cudaDeviceAttr(84); +} +impl cudaDeviceAttr { + #[doc = "< Unique identifier for a group of devices on the same multi-GPU board"] + pub const cudaDevAttrMultiGpuBoardGroupID: cudaDeviceAttr = cudaDeviceAttr(85); +} +impl cudaDeviceAttr { + #[doc = "< Link between the device and the host supports native atomic operations"] + pub const cudaDevAttrHostNativeAtomicSupported: cudaDeviceAttr = cudaDeviceAttr(86); +} +impl cudaDeviceAttr { + #[doc = "< Ratio of single precision performance (in floating-point operations per second) to double precision performance"] + pub const cudaDevAttrSingleToDoublePrecisionPerfRatio: cudaDeviceAttr = cudaDeviceAttr(87); +} +impl cudaDeviceAttr { + #[doc = "< Device supports coherently accessing pageable memory without calling cudaHostRegister on it"] + pub const cudaDevAttrPageableMemoryAccess: cudaDeviceAttr = cudaDeviceAttr(88); +} +impl cudaDeviceAttr { + #[doc = "< Device can coherently access managed memory concurrently with the CPU"] + pub const cudaDevAttrConcurrentManagedAccess: cudaDeviceAttr = cudaDeviceAttr(89); +} +impl cudaDeviceAttr { + #[doc = "< Device supports Compute Preemption"] + pub const cudaDevAttrComputePreemptionSupported: cudaDeviceAttr = cudaDeviceAttr(90); +} +impl cudaDeviceAttr { + #[doc = "< Device can access host registered memory at the same virtual address as the CPU"] + pub const cudaDevAttrCanUseHostPointerForRegisteredMem: cudaDeviceAttr = cudaDeviceAttr(91); +} +impl cudaDeviceAttr { + pub const cudaDevAttrReserved92: cudaDeviceAttr = cudaDeviceAttr(92); +} +impl cudaDeviceAttr { + pub const cudaDevAttrReserved93: cudaDeviceAttr = cudaDeviceAttr(93); +} +impl cudaDeviceAttr { + pub const cudaDevAttrReserved94: cudaDeviceAttr = cudaDeviceAttr(94); +} +impl cudaDeviceAttr { + #[doc = "< Device supports launching cooperative kernels via ::cudaLaunchCooperativeKernel"] + pub const cudaDevAttrCooperativeLaunch: cudaDeviceAttr = cudaDeviceAttr(95); +} +impl cudaDeviceAttr { + #[doc = "< Deprecated, cudaLaunchCooperativeKernelMultiDevice is deprecated."] + pub const cudaDevAttrCooperativeMultiDeviceLaunch: cudaDeviceAttr = cudaDeviceAttr(96); +} +impl cudaDeviceAttr { + #[doc = "< The maximum optin shared memory per block. This value may vary by chip. See ::cudaFuncSetAttribute"] + pub const cudaDevAttrMaxSharedMemoryPerBlockOptin: cudaDeviceAttr = cudaDeviceAttr(97); +} +impl cudaDeviceAttr { + #[doc = "< Device supports flushing of outstanding remote writes."] + pub const cudaDevAttrCanFlushRemoteWrites: cudaDeviceAttr = cudaDeviceAttr(98); +} +impl cudaDeviceAttr { + #[doc = "< Device supports host memory registration via ::cudaHostRegister."] + pub const cudaDevAttrHostRegisterSupported: cudaDeviceAttr = cudaDeviceAttr(99); +} +impl cudaDeviceAttr { + #[doc = "< Device accesses pageable memory via the host's page tables."] + pub const cudaDevAttrPageableMemoryAccessUsesHostPageTables: cudaDeviceAttr = + cudaDeviceAttr(100); +} +impl cudaDeviceAttr { + #[doc = "< Host can directly access managed memory on the device without migration."] + pub const cudaDevAttrDirectManagedMemAccessFromHost: cudaDeviceAttr = cudaDeviceAttr(101); +} +impl cudaDeviceAttr { + #[doc = "< Maximum number of blocks per multiprocessor"] + pub const cudaDevAttrMaxBlocksPerMultiprocessor: cudaDeviceAttr = cudaDeviceAttr(106); +} +impl cudaDeviceAttr { + #[doc = "< Maximum L2 persisting lines capacity setting in bytes."] + pub const cudaDevAttrMaxPersistingL2CacheSize: cudaDeviceAttr = cudaDeviceAttr(108); +} +impl cudaDeviceAttr { + #[doc = "< Maximum value of cudaAccessPolicyWindow::num_bytes."] + pub const cudaDevAttrMaxAccessPolicyWindowSize: cudaDeviceAttr = cudaDeviceAttr(109); +} +impl cudaDeviceAttr { + #[doc = "< Shared memory reserved by CUDA driver per block in bytes"] + pub const cudaDevAttrReservedSharedMemoryPerBlock: cudaDeviceAttr = cudaDeviceAttr(111); +} +impl cudaDeviceAttr { + #[doc = "< Device supports sparse CUDA arrays and sparse CUDA mipmapped arrays"] + pub const cudaDevAttrSparseCudaArraySupported: cudaDeviceAttr = cudaDeviceAttr(112); +} +impl cudaDeviceAttr { + #[doc = "< Device supports using the ::cudaHostRegister flag cudaHostRegisterReadOnly to register memory that must be mapped as read-only to the GPU"] + pub const cudaDevAttrHostRegisterReadOnlySupported: cudaDeviceAttr = cudaDeviceAttr(113); +} +impl cudaDeviceAttr { + #[doc = "< External timeline semaphore interop is supported on the device"] + pub const cudaDevAttrTimelineSemaphoreInteropSupported: cudaDeviceAttr = cudaDeviceAttr(114); +} +impl cudaDeviceAttr { + #[doc = "< Deprecated, External timeline semaphore interop is supported on the device"] + pub const cudaDevAttrMaxTimelineSemaphoreInteropSupported: cudaDeviceAttr = cudaDeviceAttr(114); +} +impl cudaDeviceAttr { + #[doc = "< Device supports using the ::cudaMallocAsync and ::cudaMemPool family of APIs"] + pub const cudaDevAttrMemoryPoolsSupported: cudaDeviceAttr = cudaDeviceAttr(115); +} +impl cudaDeviceAttr { + #[doc = "< Device supports GPUDirect RDMA APIs, like nvidia_p2p_get_pages (see https://docs.nvidia.com/cuda/gpudirect-rdma for more information)"] + pub const cudaDevAttrGPUDirectRDMASupported: cudaDeviceAttr = cudaDeviceAttr(116); +} +impl cudaDeviceAttr { + #[doc = "< The returned attribute shall be interpreted as a bitmask, where the individual bits are listed in the ::cudaFlushGPUDirectRDMAWritesOptions enum"] + pub const cudaDevAttrGPUDirectRDMAFlushWritesOptions: cudaDeviceAttr = cudaDeviceAttr(117); +} +impl cudaDeviceAttr { + #[doc = "< GPUDirect RDMA writes to the device do not need to be flushed for consumers within the scope indicated by the returned attribute. See ::cudaGPUDirectRDMAWritesOrdering for the numerical values returned here."] + pub const cudaDevAttrGPUDirectRDMAWritesOrdering: cudaDeviceAttr = cudaDeviceAttr(118); +} +impl cudaDeviceAttr { + #[doc = "< Handle types supported with mempool based IPC"] + pub const cudaDevAttrMemoryPoolSupportedHandleTypes: cudaDeviceAttr = cudaDeviceAttr(119); +} +impl cudaDeviceAttr { + #[doc = "< Indicates device supports cluster launch"] + pub const cudaDevAttrClusterLaunch: cudaDeviceAttr = cudaDeviceAttr(120); +} +impl cudaDeviceAttr { + #[doc = "< Device supports deferred mapping CUDA arrays and CUDA mipmapped arrays"] + pub const cudaDevAttrDeferredMappingCudaArraySupported: cudaDeviceAttr = cudaDeviceAttr(121); +} +impl cudaDeviceAttr { + pub const cudaDevAttrMax: cudaDeviceAttr = cudaDeviceAttr(122); +} +#[repr(transparent)] +#[doc = " CUDA device attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDeviceAttr(pub ::std::os::raw::c_uint); +impl cudaMemPoolAttr { + #[doc = " (value type = int)\n Allow cuMemAllocAsync to use memory asynchronously freed\n in another streams as long as a stream ordering dependency\n of the allocating stream on the free action exists.\n Cuda events and null stream interactions can create the required\n stream ordered dependencies. (default enabled)"] + pub const cudaMemPoolReuseFollowEventDependencies: cudaMemPoolAttr = cudaMemPoolAttr(1); +} +impl cudaMemPoolAttr { + #[doc = " (value type = int)\n Allow reuse of already completed frees when there is no dependency\n between the free and allocation. (default enabled)"] + pub const cudaMemPoolReuseAllowOpportunistic: cudaMemPoolAttr = cudaMemPoolAttr(2); +} +impl cudaMemPoolAttr { + #[doc = " (value type = int)\n Allow cuMemAllocAsync to insert new stream dependencies\n in order to establish the stream ordering required to reuse\n a piece of memory released by cuFreeAsync (default enabled)."] + pub const cudaMemPoolReuseAllowInternalDependencies: cudaMemPoolAttr = cudaMemPoolAttr(3); +} +impl cudaMemPoolAttr { + #[doc = " (value type = cuuint64_t)\n Amount of reserved memory in bytes to hold onto before trying\n to release memory back to the OS. When more than the release\n threshold bytes of memory are held by the memory pool, the\n allocator will try to release memory back to the OS on the\n next call to stream, event or context synchronize. (default 0)"] + pub const cudaMemPoolAttrReleaseThreshold: cudaMemPoolAttr = cudaMemPoolAttr(4); +} +impl cudaMemPoolAttr { + #[doc = " (value type = cuuint64_t)\n Amount of backing memory currently allocated for the mempool."] + pub const cudaMemPoolAttrReservedMemCurrent: cudaMemPoolAttr = cudaMemPoolAttr(5); +} +impl cudaMemPoolAttr { + #[doc = " (value type = cuuint64_t)\n High watermark of backing memory allocated for the mempool since the\n last time it was reset. High watermark can only be reset to zero."] + pub const cudaMemPoolAttrReservedMemHigh: cudaMemPoolAttr = cudaMemPoolAttr(6); +} +impl cudaMemPoolAttr { + #[doc = " (value type = cuuint64_t)\n Amount of memory from the pool that is currently in use by the application."] + pub const cudaMemPoolAttrUsedMemCurrent: cudaMemPoolAttr = cudaMemPoolAttr(7); +} +impl cudaMemPoolAttr { + #[doc = " (value type = cuuint64_t)\n High watermark of the amount of memory from the pool that was in use by the application since\n the last time it was reset. High watermark can only be reset to zero."] + pub const cudaMemPoolAttrUsedMemHigh: cudaMemPoolAttr = cudaMemPoolAttr(8); +} +#[repr(transparent)] +#[doc = " CUDA memory pool attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemPoolAttr(pub ::std::os::raw::c_uint); +impl cudaMemLocationType { + pub const cudaMemLocationTypeInvalid: cudaMemLocationType = cudaMemLocationType(0); +} +impl cudaMemLocationType { + #[doc = "< Location is a device location, thus id is a device ordinal"] + pub const cudaMemLocationTypeDevice: cudaMemLocationType = cudaMemLocationType(1); +} +#[repr(transparent)] +#[doc = " Specifies the type of location"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemLocationType(pub ::std::os::raw::c_uint); +#[doc = " Specifies a memory location.\n\n To specify a gpu, set type = ::cudaMemLocationTypeDevice and set id = the gpu's device ordinal."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemLocation { + #[doc = "< Specifies the location type, which modifies the meaning of id."] + pub type_: cudaMemLocationType, + #[doc = "< identifier for a given this location's ::CUmemLocationType."] + pub id: ::std::os::raw::c_int, +} +impl cudaMemAccessFlags { + #[doc = "< Default, make the address range not accessible"] + pub const cudaMemAccessFlagsProtNone: cudaMemAccessFlags = cudaMemAccessFlags(0); +} +impl cudaMemAccessFlags { + #[doc = "< Make the address range read accessible"] + pub const cudaMemAccessFlagsProtRead: cudaMemAccessFlags = cudaMemAccessFlags(1); +} +impl cudaMemAccessFlags { + #[doc = "< Make the address range read-write accessible"] + pub const cudaMemAccessFlagsProtReadWrite: cudaMemAccessFlags = cudaMemAccessFlags(3); +} +#[repr(transparent)] +#[doc = " Specifies the memory protection flags for mapping."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemAccessFlags(pub ::std::os::raw::c_uint); +#[doc = " Memory access descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemAccessDesc { + #[doc = "< Location on which the request is to change it's accessibility"] + pub location: cudaMemLocation, + #[doc = "< ::CUmemProt accessibility flags to set on the request"] + pub flags: cudaMemAccessFlags, +} +impl cudaMemAllocationType { + pub const cudaMemAllocationTypeInvalid: cudaMemAllocationType = cudaMemAllocationType(0); +} +impl cudaMemAllocationType { + #[doc = " This allocation type is 'pinned', i.e. cannot migrate from its current\n location while the application is actively using it"] + pub const cudaMemAllocationTypePinned: cudaMemAllocationType = cudaMemAllocationType(1); +} +impl cudaMemAllocationType { + #[doc = " This allocation type is 'pinned', i.e. cannot migrate from its current\n location while the application is actively using it"] + pub const cudaMemAllocationTypeMax: cudaMemAllocationType = cudaMemAllocationType(2147483647); +} +#[repr(transparent)] +#[doc = " Defines the allocation types available"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemAllocationType(pub ::std::os::raw::c_uint); +impl cudaMemAllocationHandleType { + #[doc = "< Does not allow any export mechanism. >"] + pub const cudaMemHandleTypeNone: cudaMemAllocationHandleType = cudaMemAllocationHandleType(0); +} +impl cudaMemAllocationHandleType { + #[doc = "< Allows a file descriptor to be used for exporting. Permitted only on POSIX systems. (int)"] + pub const cudaMemHandleTypePosixFileDescriptor: cudaMemAllocationHandleType = + cudaMemAllocationHandleType(1); +} +impl cudaMemAllocationHandleType { + #[doc = "< Allows a Win32 NT handle to be used for exporting. (HANDLE)"] + pub const cudaMemHandleTypeWin32: cudaMemAllocationHandleType = cudaMemAllocationHandleType(2); +} +impl cudaMemAllocationHandleType { + #[doc = "< Allows a Win32 KMT handle to be used for exporting. (D3DKMT_HANDLE)"] + pub const cudaMemHandleTypeWin32Kmt: cudaMemAllocationHandleType = + cudaMemAllocationHandleType(4); +} +#[repr(transparent)] +#[doc = " Flags for specifying particular handle types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaMemAllocationHandleType(pub ::std::os::raw::c_uint); +#[doc = " Specifies the properties of allocations made from the pool."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemPoolProps { + #[doc = "< Allocation type. Currently must be specified as cudaMemAllocationTypePinned"] + pub allocType: cudaMemAllocationType, + #[doc = "< Handle types that will be supported by allocations from the pool."] + pub handleTypes: cudaMemAllocationHandleType, + #[doc = "< Location allocations should reside."] + pub location: cudaMemLocation, + #[doc = " Windows-specific LPSECURITYATTRIBUTES required when\n ::cudaMemHandleTypeWin32 is specified. This security attribute defines\n the scope of which exported allocations may be tranferred to other\n processes. In all other cases, this field is required to be zero."] + pub win32SecurityAttributes: *mut ::std::os::raw::c_void, + #[doc = "< reserved for future use, must be 0"] + pub reserved: [::std::os::raw::c_uchar; 64usize], +} +#[doc = " Opaque data for exporting a pool allocation"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemPoolPtrExportData { + pub reserved: [::std::os::raw::c_uchar; 64usize], +} +#[doc = " Memory allocation node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaMemAllocNodeParams { + #[doc = "< in: array of memory access descriptors. Used to describe peer GPU access"] + pub poolProps: cudaMemPoolProps, + #[doc = "< in: number of memory access descriptors. Must not exceed the number of GPUs."] + pub accessDescs: *const cudaMemAccessDesc, + #[doc = "< in: Number of `accessDescs`s"] + pub accessDescCount: usize, + #[doc = "< in: size in bytes of the requested allocation"] + pub bytesize: usize, + #[doc = "< out: address of the allocation returned by CUDA"] + pub dptr: *mut ::std::os::raw::c_void, +} +impl cudaGraphMemAttributeType { + #[doc = " (value type = cuuint64_t)\n Amount of memory, in bytes, currently associated with graphs."] + pub const cudaGraphMemAttrUsedMemCurrent: cudaGraphMemAttributeType = + cudaGraphMemAttributeType(0); +} +impl cudaGraphMemAttributeType { + #[doc = " (value type = cuuint64_t)\n High watermark of memory, in bytes, associated with graphs since the\n last time it was reset. High watermark can only be reset to zero."] + pub const cudaGraphMemAttrUsedMemHigh: cudaGraphMemAttributeType = cudaGraphMemAttributeType(1); +} +impl cudaGraphMemAttributeType { + #[doc = " (value type = cuuint64_t)\n Amount of memory, in bytes, currently allocated for use by\n the CUDA graphs asynchronous allocator."] + pub const cudaGraphMemAttrReservedMemCurrent: cudaGraphMemAttributeType = + cudaGraphMemAttributeType(2); +} +impl cudaGraphMemAttributeType { + #[doc = " (value type = cuuint64_t)\n High watermark of memory, in bytes, currently allocated for use by\n the CUDA graphs asynchronous allocator."] + pub const cudaGraphMemAttrReservedMemHigh: cudaGraphMemAttributeType = + cudaGraphMemAttributeType(3); +} +#[repr(transparent)] +#[doc = " Graph memory attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphMemAttributeType(pub ::std::os::raw::c_uint); +impl cudaDeviceP2PAttr { + #[doc = "< A relative value indicating the performance of the link between two devices"] + pub const cudaDevP2PAttrPerformanceRank: cudaDeviceP2PAttr = cudaDeviceP2PAttr(1); +} +impl cudaDeviceP2PAttr { + #[doc = "< Peer access is enabled"] + pub const cudaDevP2PAttrAccessSupported: cudaDeviceP2PAttr = cudaDeviceP2PAttr(2); +} +impl cudaDeviceP2PAttr { + #[doc = "< Native atomic operation over the link supported"] + pub const cudaDevP2PAttrNativeAtomicSupported: cudaDeviceP2PAttr = cudaDeviceP2PAttr(3); +} +impl cudaDeviceP2PAttr { + #[doc = "< Accessing CUDA arrays over the link supported"] + pub const cudaDevP2PAttrCudaArrayAccessSupported: cudaDeviceP2PAttr = cudaDeviceP2PAttr(4); +} +#[repr(transparent)] +#[doc = " CUDA device P2P attributes"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDeviceP2PAttr(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUuuid_st { + pub bytes: [::std::os::raw::c_char; 16usize], +} +pub type cudaUUID_t = CUuuid_st; +#[doc = " CUDA device properties"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaDeviceProp { + #[doc = "< ASCII string identifying device"] + pub name: [::std::os::raw::c_char; 256usize], + #[doc = "< 16-byte unique identifier"] + pub uuid: cudaUUID_t, + #[doc = "< 8-byte locally unique identifier. Value is undefined on TCC and non-Windows platforms"] + pub luid: [::std::os::raw::c_char; 8usize], + #[doc = "< LUID device node mask. Value is undefined on TCC and non-Windows platforms"] + pub luidDeviceNodeMask: ::std::os::raw::c_uint, + #[doc = "< Global memory available on device in bytes"] + pub totalGlobalMem: usize, + #[doc = "< Shared memory available per block in bytes"] + pub sharedMemPerBlock: usize, + #[doc = "< 32-bit registers available per block"] + pub regsPerBlock: ::std::os::raw::c_int, + #[doc = "< Warp size in threads"] + pub warpSize: ::std::os::raw::c_int, + #[doc = "< Maximum pitch in bytes allowed by memory copies"] + pub memPitch: usize, + #[doc = "< Maximum number of threads per block"] + pub maxThreadsPerBlock: ::std::os::raw::c_int, + #[doc = "< Maximum size of each dimension of a block"] + pub maxThreadsDim: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum size of each dimension of a grid"] + pub maxGridSize: [::std::os::raw::c_int; 3usize], + #[doc = "< Clock frequency in kilohertz"] + pub clockRate: ::std::os::raw::c_int, + #[doc = "< Constant memory available on device in bytes"] + pub totalConstMem: usize, + #[doc = "< Major compute capability"] + pub major: ::std::os::raw::c_int, + #[doc = "< Minor compute capability"] + pub minor: ::std::os::raw::c_int, + #[doc = "< Alignment requirement for textures"] + pub textureAlignment: usize, + #[doc = "< Pitch alignment requirement for texture references bound to pitched memory"] + pub texturePitchAlignment: usize, + #[doc = "< Device can concurrently copy memory and execute a kernel. Deprecated. Use instead asyncEngineCount."] + pub deviceOverlap: ::std::os::raw::c_int, + #[doc = "< Number of multiprocessors on device"] + pub multiProcessorCount: ::std::os::raw::c_int, + #[doc = "< Specified whether there is a run time limit on kernels"] + pub kernelExecTimeoutEnabled: ::std::os::raw::c_int, + #[doc = "< Device is integrated as opposed to discrete"] + pub integrated: ::std::os::raw::c_int, + #[doc = "< Device can map host memory with cudaHostAlloc/cudaHostGetDevicePointer"] + pub canMapHostMemory: ::std::os::raw::c_int, + #[doc = "< Compute mode (See ::cudaComputeMode)"] + pub computeMode: ::std::os::raw::c_int, + #[doc = "< Maximum 1D texture size"] + pub maxTexture1D: ::std::os::raw::c_int, + #[doc = "< Maximum 1D mipmapped texture size"] + pub maxTexture1DMipmap: ::std::os::raw::c_int, + #[doc = "< Deprecated, do not use. Use cudaDeviceGetTexture1DLinearMaxWidth() or cuDeviceGetTexture1DLinearMaxWidth() instead."] + pub maxTexture1DLinear: ::std::os::raw::c_int, + #[doc = "< Maximum 2D texture dimensions"] + pub maxTexture2D: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 2D mipmapped texture dimensions"] + pub maxTexture2DMipmap: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum dimensions (width, height, pitch) for 2D textures bound to pitched memory"] + pub maxTexture2DLinear: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum 2D texture dimensions if texture gather operations have to be performed"] + pub maxTexture2DGather: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 3D texture dimensions"] + pub maxTexture3D: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum alternate 3D texture dimensions"] + pub maxTexture3DAlt: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum Cubemap texture dimensions"] + pub maxTextureCubemap: ::std::os::raw::c_int, + #[doc = "< Maximum 1D layered texture dimensions"] + pub maxTexture1DLayered: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 2D layered texture dimensions"] + pub maxTexture2DLayered: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum Cubemap layered texture dimensions"] + pub maxTextureCubemapLayered: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 1D surface size"] + pub maxSurface1D: ::std::os::raw::c_int, + #[doc = "< Maximum 2D surface dimensions"] + pub maxSurface2D: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 3D surface dimensions"] + pub maxSurface3D: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum 1D layered surface dimensions"] + pub maxSurface1DLayered: [::std::os::raw::c_int; 2usize], + #[doc = "< Maximum 2D layered surface dimensions"] + pub maxSurface2DLayered: [::std::os::raw::c_int; 3usize], + #[doc = "< Maximum Cubemap surface dimensions"] + pub maxSurfaceCubemap: ::std::os::raw::c_int, + #[doc = "< Maximum Cubemap layered surface dimensions"] + pub maxSurfaceCubemapLayered: [::std::os::raw::c_int; 2usize], + #[doc = "< Alignment requirements for surfaces"] + pub surfaceAlignment: usize, + #[doc = "< Device can possibly execute multiple kernels concurrently"] + pub concurrentKernels: ::std::os::raw::c_int, + #[doc = "< Device has ECC support enabled"] + pub ECCEnabled: ::std::os::raw::c_int, + #[doc = "< PCI bus ID of the device"] + pub pciBusID: ::std::os::raw::c_int, + #[doc = "< PCI device ID of the device"] + pub pciDeviceID: ::std::os::raw::c_int, + #[doc = "< PCI domain ID of the device"] + pub pciDomainID: ::std::os::raw::c_int, + #[doc = "< 1 if device is a Tesla device using TCC driver, 0 otherwise"] + pub tccDriver: ::std::os::raw::c_int, + #[doc = "< Number of asynchronous engines"] + pub asyncEngineCount: ::std::os::raw::c_int, + #[doc = "< Device shares a unified address space with the host"] + pub unifiedAddressing: ::std::os::raw::c_int, + #[doc = "< Peak memory clock frequency in kilohertz"] + pub memoryClockRate: ::std::os::raw::c_int, + #[doc = "< Global memory bus width in bits"] + pub memoryBusWidth: ::std::os::raw::c_int, + #[doc = "< Size of L2 cache in bytes"] + pub l2CacheSize: ::std::os::raw::c_int, + #[doc = "< Device's maximum l2 persisting lines capacity setting in bytes"] + pub persistingL2CacheMaxSize: ::std::os::raw::c_int, + #[doc = "< Maximum resident threads per multiprocessor"] + pub maxThreadsPerMultiProcessor: ::std::os::raw::c_int, + #[doc = "< Device supports stream priorities"] + pub streamPrioritiesSupported: ::std::os::raw::c_int, + #[doc = "< Device supports caching globals in L1"] + pub globalL1CacheSupported: ::std::os::raw::c_int, + #[doc = "< Device supports caching locals in L1"] + pub localL1CacheSupported: ::std::os::raw::c_int, + #[doc = "< Shared memory available per multiprocessor in bytes"] + pub sharedMemPerMultiprocessor: usize, + #[doc = "< 32-bit registers available per multiprocessor"] + pub regsPerMultiprocessor: ::std::os::raw::c_int, + #[doc = "< Device supports allocating managed memory on this system"] + pub managedMemory: ::std::os::raw::c_int, + #[doc = "< Device is on a multi-GPU board"] + pub isMultiGpuBoard: ::std::os::raw::c_int, + #[doc = "< Unique identifier for a group of devices on the same multi-GPU board"] + pub multiGpuBoardGroupID: ::std::os::raw::c_int, + #[doc = "< Link between the device and the host supports native atomic operations"] + pub hostNativeAtomicSupported: ::std::os::raw::c_int, + #[doc = "< Ratio of single precision performance (in floating-point operations per second) to double precision performance"] + pub singleToDoublePrecisionPerfRatio: ::std::os::raw::c_int, + #[doc = "< Device supports coherently accessing pageable memory without calling cudaHostRegister on it"] + pub pageableMemoryAccess: ::std::os::raw::c_int, + #[doc = "< Device can coherently access managed memory concurrently with the CPU"] + pub concurrentManagedAccess: ::std::os::raw::c_int, + #[doc = "< Device supports Compute Preemption"] + pub computePreemptionSupported: ::std::os::raw::c_int, + #[doc = "< Device can access host registered memory at the same virtual address as the CPU"] + pub canUseHostPointerForRegisteredMem: ::std::os::raw::c_int, + #[doc = "< Device supports launching cooperative kernels via ::cudaLaunchCooperativeKernel"] + pub cooperativeLaunch: ::std::os::raw::c_int, + #[doc = "< Deprecated, cudaLaunchCooperativeKernelMultiDevice is deprecated."] + pub cooperativeMultiDeviceLaunch: ::std::os::raw::c_int, + #[doc = "< Per device maximum shared memory per block usable by special opt in"] + pub sharedMemPerBlockOptin: usize, + #[doc = "< Device accesses pageable memory via the host's page tables"] + pub pageableMemoryAccessUsesHostPageTables: ::std::os::raw::c_int, + #[doc = "< Host can directly access managed memory on the device without migration."] + pub directManagedMemAccessFromHost: ::std::os::raw::c_int, + #[doc = "< Maximum number of resident blocks per multiprocessor"] + pub maxBlocksPerMultiProcessor: ::std::os::raw::c_int, + #[doc = "< The maximum value of ::cudaAccessPolicyWindow::num_bytes."] + pub accessPolicyMaxWindowSize: ::std::os::raw::c_int, + #[doc = "< Shared memory reserved by CUDA driver per block in bytes"] + pub reservedSharedMemPerBlock: usize, +} +#[doc = " CUDA IPC event handle"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaIpcEventHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +#[doc = " CUDA IPC event handle"] +pub type cudaIpcEventHandle_t = cudaIpcEventHandle_st; +#[doc = " CUDA IPC memory handle"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaIpcMemHandle_st { + pub reserved: [::std::os::raw::c_char; 64usize], +} +#[doc = " CUDA IPC memory handle"] +pub type cudaIpcMemHandle_t = cudaIpcMemHandle_st; +impl cudaExternalMemoryHandleType { + #[doc = " Handle is an opaque file descriptor"] + pub const cudaExternalMemoryHandleTypeOpaqueFd: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(1); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is an opaque shared NT handle"] + pub const cudaExternalMemoryHandleTypeOpaqueWin32: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(2); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is an opaque, globally shared handle"] + pub const cudaExternalMemoryHandleTypeOpaqueWin32Kmt: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(3); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is a D3D12 heap object"] + pub const cudaExternalMemoryHandleTypeD3D12Heap: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(4); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is a D3D12 committed resource"] + pub const cudaExternalMemoryHandleTypeD3D12Resource: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(5); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is a shared NT handle to a D3D11 resource"] + pub const cudaExternalMemoryHandleTypeD3D11Resource: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(6); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is a globally shared handle to a D3D11 resource"] + pub const cudaExternalMemoryHandleTypeD3D11ResourceKmt: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(7); +} +impl cudaExternalMemoryHandleType { + #[doc = " Handle is an NvSciBuf object"] + pub const cudaExternalMemoryHandleTypeNvSciBuf: cudaExternalMemoryHandleType = + cudaExternalMemoryHandleType(8); +} +#[repr(transparent)] +#[doc = " External memory handle types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaExternalMemoryHandleType(pub ::std::os::raw::c_uint); +#[doc = " External memory handle descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalMemoryHandleDesc { + #[doc = " Type of the handle"] + pub type_: cudaExternalMemoryHandleType, + pub handle: cudaExternalMemoryHandleDesc__bindgen_ty_1, + #[doc = " Size of the memory allocation"] + pub size: ::std::os::raw::c_ulonglong, + #[doc = " Flags must either be zero or ::cudaExternalMemoryDedicated"] + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalMemoryHandleDesc__bindgen_ty_1 { + #[doc = " File descriptor referencing the memory object. Valid\n when type is\n ::cudaExternalMemoryHandleTypeOpaqueFd"] + pub fd: ::std::os::raw::c_int, + pub win32: cudaExternalMemoryHandleDesc__bindgen_ty_1__bindgen_ty_1, + #[doc = " A handle representing NvSciBuf Object. Valid when type\n is ::cudaExternalMemoryHandleTypeNvSciBuf"] + pub nvSciBufObject: *const ::std::os::raw::c_void, +} +#[doc = " Win32 handle referencing the semaphore object. Valid when\n type is one of the following:\n - ::cudaExternalMemoryHandleTypeOpaqueWin32\n - ::cudaExternalMemoryHandleTypeOpaqueWin32Kmt\n - ::cudaExternalMemoryHandleTypeD3D12Heap\n - ::cudaExternalMemoryHandleTypeD3D12Resource\n - ::cudaExternalMemoryHandleTypeD3D11Resource\n - ::cudaExternalMemoryHandleTypeD3D11ResourceKmt\n Exactly one of 'handle' and 'name' must be non-NULL. If\n type is one of the following:\n ::cudaExternalMemoryHandleTypeOpaqueWin32Kmt\n ::cudaExternalMemoryHandleTypeD3D11ResourceKmt\n then 'name' must be NULL."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalMemoryHandleDesc__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Valid NT handle. Must be NULL if 'name' is non-NULL"] + pub handle: *mut ::std::os::raw::c_void, + #[doc = " Name of a valid memory object.\n Must be NULL if 'handle' is non-NULL."] + pub name: *const ::std::os::raw::c_void, +} +#[doc = " External memory buffer descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalMemoryBufferDesc { + #[doc = " Offset into the memory object where the buffer's base is"] + pub offset: ::std::os::raw::c_ulonglong, + #[doc = " Size of the buffer"] + pub size: ::std::os::raw::c_ulonglong, + #[doc = " Flags reserved for future use. Must be zero."] + pub flags: ::std::os::raw::c_uint, +} +#[doc = " External memory mipmap descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalMemoryMipmappedArrayDesc { + #[doc = " Offset into the memory object where the base level of the\n mipmap chain is."] + pub offset: ::std::os::raw::c_ulonglong, + #[doc = " Format of base level of the mipmap chain"] + pub formatDesc: cudaChannelFormatDesc, + #[doc = " Dimensions of base level of the mipmap chain"] + pub extent: cudaExtent, + #[doc = " Flags associated with CUDA mipmapped arrays.\n See ::cudaMallocMipmappedArray"] + pub flags: ::std::os::raw::c_uint, + #[doc = " Total number of levels in the mipmap chain"] + pub numLevels: ::std::os::raw::c_uint, +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is an opaque file descriptor"] + pub const cudaExternalSemaphoreHandleTypeOpaqueFd: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(1); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is an opaque shared NT handle"] + pub const cudaExternalSemaphoreHandleTypeOpaqueWin32: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(2); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is an opaque, globally shared handle"] + pub const cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(3); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is a shared NT handle referencing a D3D12 fence object"] + pub const cudaExternalSemaphoreHandleTypeD3D12Fence: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(4); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is a shared NT handle referencing a D3D11 fence object"] + pub const cudaExternalSemaphoreHandleTypeD3D11Fence: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(5); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Opaque handle to NvSciSync Object"] + pub const cudaExternalSemaphoreHandleTypeNvSciSync: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(6); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is a shared NT handle referencing a D3D11 keyed mutex object"] + pub const cudaExternalSemaphoreHandleTypeKeyedMutex: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(7); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is a shared KMT handle referencing a D3D11 keyed mutex object"] + pub const cudaExternalSemaphoreHandleTypeKeyedMutexKmt: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(8); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is an opaque handle file descriptor referencing a timeline semaphore"] + pub const cudaExternalSemaphoreHandleTypeTimelineSemaphoreFd: cudaExternalSemaphoreHandleType = + cudaExternalSemaphoreHandleType(9); +} +impl cudaExternalSemaphoreHandleType { + #[doc = " Handle is an opaque handle file descriptor referencing a timeline semaphore"] + pub const cudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32: + cudaExternalSemaphoreHandleType = cudaExternalSemaphoreHandleType(10); +} +#[repr(transparent)] +#[doc = " External semaphore handle types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaExternalSemaphoreHandleType(pub ::std::os::raw::c_uint); +#[doc = " External semaphore handle descriptor"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreHandleDesc { + #[doc = " Type of the handle"] + pub type_: cudaExternalSemaphoreHandleType, + pub handle: cudaExternalSemaphoreHandleDesc__bindgen_ty_1, + #[doc = " Flags reserved for the future. Must be zero."] + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalSemaphoreHandleDesc__bindgen_ty_1 { + #[doc = " File descriptor referencing the semaphore object. Valid when\n type is one of the following:\n - ::cudaExternalSemaphoreHandleTypeOpaqueFd\n - ::cudaExternalSemaphoreHandleTypeTimelineSemaphoreFd"] + pub fd: ::std::os::raw::c_int, + pub win32: cudaExternalSemaphoreHandleDesc__bindgen_ty_1__bindgen_ty_1, + #[doc = " Valid NvSciSyncObj. Must be non NULL"] + pub nvSciSyncObj: *const ::std::os::raw::c_void, +} +#[doc = " Win32 handle referencing the semaphore object. Valid when\n type is one of the following:\n - ::cudaExternalSemaphoreHandleTypeOpaqueWin32\n - ::cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt\n - ::cudaExternalSemaphoreHandleTypeD3D12Fence\n - ::cudaExternalSemaphoreHandleTypeD3D11Fence\n - ::cudaExternalSemaphoreHandleTypeKeyedMutex\n - ::cudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32\n Exactly one of 'handle' and 'name' must be non-NULL. If\n type is one of the following:\n ::cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt\n ::cudaExternalSemaphoreHandleTypeKeyedMutexKmt\n then 'name' must be NULL."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreHandleDesc__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Valid NT handle. Must be NULL if 'name' is non-NULL"] + pub handle: *mut ::std::os::raw::c_void, + #[doc = " Name of a valid synchronization primitive.\n Must be NULL if 'handle' is non-NULL."] + pub name: *const ::std::os::raw::c_void, +} +#[doc = " External semaphore signal parameters(deprecated)"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams_v1 { + pub params: cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1, + #[doc = " Only when ::cudaExternalSemaphoreSignalParams is used to\n signal a ::cudaExternalSemaphore_t of type\n ::cudaExternalSemaphoreHandleTypeNvSciSync, the valid flag is\n ::cudaExternalSemaphoreSignalSkipNvSciBufMemSync: which indicates\n that while signaling the ::cudaExternalSemaphore_t, no memory\n synchronization operations should be performed for any external memory\n object imported as ::cudaExternalMemoryHandleTypeNvSciBuf.\n For all other types of ::cudaExternalSemaphore_t, flags must be zero."] + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1 { + pub fence: cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_1, + pub nvSciSync: cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_2, + pub keyedMutex: cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_3, +} +#[doc = " Parameters for fence objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Value of fence to be signaled"] + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_2 { + #[doc = " Pointer to NvSciSyncFence. Valid if ::cudaExternalSemaphoreHandleType\n is of type ::cudaExternalSemaphoreHandleTypeNvSciSync."] + pub fence: *mut ::std::os::raw::c_void, + pub reserved: ::std::os::raw::c_ulonglong, +} +#[doc = " Parameters for keyed mutex objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams_v1__bindgen_ty_1__bindgen_ty_3 { + pub key: ::std::os::raw::c_ulonglong, +} +#[doc = " External semaphore wait parameters(deprecated)"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams_v1 { + pub params: cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1, + #[doc = " Only when ::cudaExternalSemaphoreSignalParams is used to\n signal a ::cudaExternalSemaphore_t of type\n ::cudaExternalSemaphoreHandleTypeNvSciSync, the valid flag is\n ::cudaExternalSemaphoreSignalSkipNvSciBufMemSync: which indicates\n that while waiting for the ::cudaExternalSemaphore_t, no memory\n synchronization operations should be performed for any external memory\n object imported as ::cudaExternalMemoryHandleTypeNvSciBuf.\n For all other types of ::cudaExternalSemaphore_t, flags must be zero."] + pub flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1 { + pub fence: cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_1, + pub nvSciSync: cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_2, + pub keyedMutex: cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_3, +} +#[doc = " Parameters for fence objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Value of fence to be waited on"] + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_2 { + #[doc = " Pointer to NvSciSyncFence. Valid if ::cudaExternalSemaphoreHandleType\n is of type ::cudaExternalSemaphoreHandleTypeNvSciSync."] + pub fence: *mut ::std::os::raw::c_void, + pub reserved: ::std::os::raw::c_ulonglong, +} +#[doc = " Parameters for keyed mutex objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams_v1__bindgen_ty_1__bindgen_ty_3 { + #[doc = " Value of key to acquire the mutex with"] + pub key: ::std::os::raw::c_ulonglong, + #[doc = " Timeout in milliseconds to wait to acquire the mutex"] + pub timeoutMs: ::std::os::raw::c_uint, +} +#[doc = " External semaphore signal parameters, compatible with driver type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams { + pub params: cudaExternalSemaphoreSignalParams__bindgen_ty_1, + #[doc = " Only when ::cudaExternalSemaphoreSignalParams is used to\n signal a ::cudaExternalSemaphore_t of type\n ::cudaExternalSemaphoreHandleTypeNvSciSync, the valid flag is\n ::cudaExternalSemaphoreSignalSkipNvSciBufMemSync: which indicates\n that while signaling the ::cudaExternalSemaphore_t, no memory\n synchronization operations should be performed for any external memory\n object imported as ::cudaExternalMemoryHandleTypeNvSciBuf.\n For all other types of ::cudaExternalSemaphore_t, flags must be zero."] + pub flags: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams__bindgen_ty_1 { + pub fence: cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_1, + pub nvSciSync: cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_2, + pub keyedMutex: cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_3, + pub reserved: [::std::os::raw::c_uint; 12usize], +} +#[doc = " Parameters for fence objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Value of fence to be signaled"] + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_2 { + #[doc = " Pointer to NvSciSyncFence. Valid if ::cudaExternalSemaphoreHandleType\n is of type ::cudaExternalSemaphoreHandleTypeNvSciSync."] + pub fence: *mut ::std::os::raw::c_void, + pub reserved: ::std::os::raw::c_ulonglong, +} +#[doc = " Parameters for keyed mutex objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalParams__bindgen_ty_1__bindgen_ty_3 { + pub key: ::std::os::raw::c_ulonglong, +} +#[doc = " External semaphore wait parameters, compatible with driver type"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams { + pub params: cudaExternalSemaphoreWaitParams__bindgen_ty_1, + #[doc = " Only when ::cudaExternalSemaphoreSignalParams is used to\n signal a ::cudaExternalSemaphore_t of type\n ::cudaExternalSemaphoreHandleTypeNvSciSync, the valid flag is\n ::cudaExternalSemaphoreSignalSkipNvSciBufMemSync: which indicates\n that while waiting for the ::cudaExternalSemaphore_t, no memory\n synchronization operations should be performed for any external memory\n object imported as ::cudaExternalMemoryHandleTypeNvSciBuf.\n For all other types of ::cudaExternalSemaphore_t, flags must be zero."] + pub flags: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 16usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams__bindgen_ty_1 { + pub fence: cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_1, + pub nvSciSync: cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_2, + pub keyedMutex: cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_3, + pub reserved: [::std::os::raw::c_uint; 10usize], +} +#[doc = " Parameters for fence objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_1 { + #[doc = " Value of fence to be waited on"] + pub value: ::std::os::raw::c_ulonglong, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_2 { + #[doc = " Pointer to NvSciSyncFence. Valid if ::cudaExternalSemaphoreHandleType\n is of type ::cudaExternalSemaphoreHandleTypeNvSciSync."] + pub fence: *mut ::std::os::raw::c_void, + pub reserved: ::std::os::raw::c_ulonglong, +} +#[doc = " Parameters for keyed mutex objects"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitParams__bindgen_ty_1__bindgen_ty_3 { + #[doc = " Value of key to acquire the mutex with"] + pub key: ::std::os::raw::c_ulonglong, + #[doc = " Timeout in milliseconds to wait to acquire the mutex"] + pub timeoutMs: ::std::os::raw::c_uint, +} +#[doc = " CUDA Error types"] +pub use self::cudaError as cudaError_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUstream_st { + _unused: [u8; 0], +} +#[doc = " CUDA stream"] +pub type cudaStream_t = *mut CUstream_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUevent_st { + _unused: [u8; 0], +} +#[doc = " CUDA event types"] +pub type cudaEvent_t = *mut CUevent_st; +#[doc = " CUDA graphics resource types"] +pub type cudaGraphicsResource_t = *mut cudaGraphicsResource; +#[doc = " CUDA output file modes"] +pub use self::cudaOutputMode as cudaOutputMode_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUexternalMemory_st { + _unused: [u8; 0], +} +#[doc = " CUDA external memory"] +pub type cudaExternalMemory_t = *mut CUexternalMemory_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUexternalSemaphore_st { + _unused: [u8; 0], +} +#[doc = " CUDA external semaphore"] +pub type cudaExternalSemaphore_t = *mut CUexternalSemaphore_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUgraph_st { + _unused: [u8; 0], +} +#[doc = " CUDA graph"] +pub type cudaGraph_t = *mut CUgraph_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUgraphNode_st { + _unused: [u8; 0], +} +#[doc = " CUDA graph node."] +pub type cudaGraphNode_t = *mut CUgraphNode_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUuserObject_st { + _unused: [u8; 0], +} +#[doc = " CUDA user object for graphs"] +pub type cudaUserObject_t = *mut CUuserObject_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUfunc_st { + _unused: [u8; 0], +} +#[doc = " CUDA function"] +pub type cudaFunction_t = *mut CUfunc_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUmemPoolHandle_st { + _unused: [u8; 0], +} +#[doc = " CUDA memory pool"] +pub type cudaMemPool_t = *mut CUmemPoolHandle_st; +impl cudaCGScope { + #[doc = "< Invalid cooperative group scope"] + pub const cudaCGScopeInvalid: cudaCGScope = cudaCGScope(0); +} +impl cudaCGScope { + #[doc = "< Scope represented by a grid_group"] + pub const cudaCGScopeGrid: cudaCGScope = cudaCGScope(1); +} +impl cudaCGScope { + #[doc = "< Scope represented by a multi_grid_group"] + pub const cudaCGScopeMultiGrid: cudaCGScope = cudaCGScope(2); +} +#[repr(transparent)] +#[doc = " CUDA cooperative group scope"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaCGScope(pub ::std::os::raw::c_uint); +#[doc = " CUDA launch parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLaunchParams { + #[doc = "< Device function symbol"] + pub func: *mut ::std::os::raw::c_void, + #[doc = "< Grid dimentions"] + pub gridDim: dim3, + #[doc = "< Block dimentions"] + pub blockDim: dim3, + #[doc = "< Arguments"] + pub args: *mut *mut ::std::os::raw::c_void, + #[doc = "< Shared memory"] + pub sharedMem: usize, + #[doc = "< Stream identifier"] + pub stream: cudaStream_t, +} +#[doc = " CUDA GPU kernel node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaKernelNodeParams { + #[doc = "< Kernel to launch"] + pub func: *mut ::std::os::raw::c_void, + #[doc = "< Grid dimensions"] + pub gridDim: dim3, + #[doc = "< Block dimensions"] + pub blockDim: dim3, + #[doc = "< Dynamic shared-memory size per thread block in bytes"] + pub sharedMemBytes: ::std::os::raw::c_uint, + #[doc = "< Array of pointers to individual kernel arguments"] + pub kernelParams: *mut *mut ::std::os::raw::c_void, + #[doc = "< Pointer to kernel arguments in the \"extra\" format"] + pub extra: *mut *mut ::std::os::raw::c_void, +} +#[doc = " External semaphore signal node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreSignalNodeParams { + #[doc = "< Array of external semaphore handles."] + pub extSemArray: *mut cudaExternalSemaphore_t, + #[doc = "< Array of external semaphore signal parameters."] + pub paramsArray: *const cudaExternalSemaphoreSignalParams, + #[doc = "< Number of handles and parameters supplied in extSemArray and paramsArray."] + pub numExtSems: ::std::os::raw::c_uint, +} +#[doc = " External semaphore wait node parameters"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaExternalSemaphoreWaitNodeParams { + #[doc = "< Array of external semaphore handles."] + pub extSemArray: *mut cudaExternalSemaphore_t, + #[doc = "< Array of external semaphore wait parameters."] + pub paramsArray: *const cudaExternalSemaphoreWaitParams, + #[doc = "< Number of handles and parameters supplied in extSemArray and paramsArray."] + pub numExtSems: ::std::os::raw::c_uint, +} +impl cudaGraphNodeType { + #[doc = "< GPU kernel node"] + pub const cudaGraphNodeTypeKernel: cudaGraphNodeType = cudaGraphNodeType(0); +} +impl cudaGraphNodeType { + #[doc = "< Memcpy node"] + pub const cudaGraphNodeTypeMemcpy: cudaGraphNodeType = cudaGraphNodeType(1); +} +impl cudaGraphNodeType { + #[doc = "< Memset node"] + pub const cudaGraphNodeTypeMemset: cudaGraphNodeType = cudaGraphNodeType(2); +} +impl cudaGraphNodeType { + #[doc = "< Host (executable) node"] + pub const cudaGraphNodeTypeHost: cudaGraphNodeType = cudaGraphNodeType(3); +} +impl cudaGraphNodeType { + #[doc = "< Node which executes an embedded graph"] + pub const cudaGraphNodeTypeGraph: cudaGraphNodeType = cudaGraphNodeType(4); +} +impl cudaGraphNodeType { + #[doc = "< Empty (no-op) node"] + pub const cudaGraphNodeTypeEmpty: cudaGraphNodeType = cudaGraphNodeType(5); +} +impl cudaGraphNodeType { + #[doc = "< External event wait node"] + pub const cudaGraphNodeTypeWaitEvent: cudaGraphNodeType = cudaGraphNodeType(6); +} +impl cudaGraphNodeType { + #[doc = "< External event record node"] + pub const cudaGraphNodeTypeEventRecord: cudaGraphNodeType = cudaGraphNodeType(7); +} +impl cudaGraphNodeType { + #[doc = "< External semaphore signal node"] + pub const cudaGraphNodeTypeExtSemaphoreSignal: cudaGraphNodeType = cudaGraphNodeType(8); +} +impl cudaGraphNodeType { + #[doc = "< External semaphore wait node"] + pub const cudaGraphNodeTypeExtSemaphoreWait: cudaGraphNodeType = cudaGraphNodeType(9); +} +impl cudaGraphNodeType { + #[doc = "< Memory allocation node"] + pub const cudaGraphNodeTypeMemAlloc: cudaGraphNodeType = cudaGraphNodeType(10); +} +impl cudaGraphNodeType { + #[doc = "< Memory free node"] + pub const cudaGraphNodeTypeMemFree: cudaGraphNodeType = cudaGraphNodeType(11); +} +impl cudaGraphNodeType { + pub const cudaGraphNodeTypeCount: cudaGraphNodeType = cudaGraphNodeType(12); +} +#[repr(transparent)] +#[doc = " CUDA Graph node types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphNodeType(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUgraphExec_st { + _unused: [u8; 0], +} +#[doc = " CUDA executable (launchable) graph"] +pub type cudaGraphExec_t = *mut CUgraphExec_st; +impl cudaGraphExecUpdateResult { + #[doc = "< The update succeeded"] + pub const cudaGraphExecUpdateSuccess: cudaGraphExecUpdateResult = cudaGraphExecUpdateResult(0); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed for an unexpected reason which is described in the return value of the function"] + pub const cudaGraphExecUpdateError: cudaGraphExecUpdateResult = cudaGraphExecUpdateResult(1); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because the topology changed"] + pub const cudaGraphExecUpdateErrorTopologyChanged: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(2); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because a node type changed"] + pub const cudaGraphExecUpdateErrorNodeTypeChanged: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(3); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because the function of a kernel node changed (CUDA driver < 11.2)"] + pub const cudaGraphExecUpdateErrorFunctionChanged: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(4); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because the parameters changed in a way that is not supported"] + pub const cudaGraphExecUpdateErrorParametersChanged: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(5); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because something about the node is not supported"] + pub const cudaGraphExecUpdateErrorNotSupported: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(6); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because the function of a kernel node changed in an unsupported way"] + pub const cudaGraphExecUpdateErrorUnsupportedFunctionChange: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(7); +} +impl cudaGraphExecUpdateResult { + #[doc = "< The update failed because the node attributes changed in a way that is not supported"] + pub const cudaGraphExecUpdateErrorAttributesChanged: cudaGraphExecUpdateResult = + cudaGraphExecUpdateResult(8); +} +#[repr(transparent)] +#[doc = " CUDA Graph Update error types"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphExecUpdateResult(pub ::std::os::raw::c_uint); +impl cudaGetDriverEntryPointFlags { + #[doc = "< Default search mode for driver symbols."] + pub const cudaEnableDefault: cudaGetDriverEntryPointFlags = cudaGetDriverEntryPointFlags(0); +} +impl cudaGetDriverEntryPointFlags { + #[doc = "< Search for legacy versions of driver symbols."] + pub const cudaEnableLegacyStream: cudaGetDriverEntryPointFlags = + cudaGetDriverEntryPointFlags(1); +} +impl cudaGetDriverEntryPointFlags { + #[doc = "< Search for per-thread versions of driver symbols."] + pub const cudaEnablePerThreadDefaultStream: cudaGetDriverEntryPointFlags = + cudaGetDriverEntryPointFlags(2); +} +#[repr(transparent)] +#[doc = " Flags to specify search options to be used with ::cudaGetDriverEntryPoint\n For more details see ::cuGetProcAddress"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGetDriverEntryPointFlags(pub ::std::os::raw::c_uint); +impl cudaGraphDebugDotFlags { + #[doc = "< Output all debug data as if every debug flag is enabled"] + pub const cudaGraphDebugDotFlagsVerbose: cudaGraphDebugDotFlags = cudaGraphDebugDotFlags(1); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaKernelNodeParams to output"] + pub const cudaGraphDebugDotFlagsKernelNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(4); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaMemcpy3DParms to output"] + pub const cudaGraphDebugDotFlagsMemcpyNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(8); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaMemsetParams to output"] + pub const cudaGraphDebugDotFlagsMemsetNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(16); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaHostNodeParams to output"] + pub const cudaGraphDebugDotFlagsHostNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(32); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaEvent_t handle from record and wait nodes to output"] + pub const cudaGraphDebugDotFlagsEventNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(64); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaExternalSemaphoreSignalNodeParams values to output"] + pub const cudaGraphDebugDotFlagsExtSemasSignalNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(128); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaExternalSemaphoreWaitNodeParams to output"] + pub const cudaGraphDebugDotFlagsExtSemasWaitNodeParams: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(256); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds cudaKernelNodeAttrID values to output"] + pub const cudaGraphDebugDotFlagsKernelNodeAttributes: cudaGraphDebugDotFlags = + cudaGraphDebugDotFlags(512); +} +impl cudaGraphDebugDotFlags { + #[doc = "< Adds node handles and every kernel function handle to output"] + pub const cudaGraphDebugDotFlagsHandles: cudaGraphDebugDotFlags = cudaGraphDebugDotFlags(1024); +} +#[repr(transparent)] +#[doc = " CUDA Graph debug write options"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphDebugDotFlags(pub ::std::os::raw::c_uint); +impl cudaGraphInstantiateFlags { + #[doc = "< Automatically free memory allocated in a graph before relaunching."] + pub const cudaGraphInstantiateFlagAutoFreeOnLaunch: cudaGraphInstantiateFlags = + cudaGraphInstantiateFlags(1); +} +impl cudaGraphInstantiateFlags { + #[doc = "< Run the graph using the per-node priority attributes rather than the\npriority of the stream it is launched into."] + pub const cudaGraphInstantiateFlagUseNodePriority: cudaGraphInstantiateFlags = + cudaGraphInstantiateFlags(8); +} +#[repr(transparent)] +#[doc = " Flags for instantiating a graph"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaGraphInstantiateFlags(pub ::std::os::raw::c_uint); +impl cudaLaunchAttributeID { + #[doc = "< Ignored entry, for convenient composition"] + pub const cudaLaunchAttributeIgnore: cudaLaunchAttributeID = cudaLaunchAttributeID(0); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for streams, graph nodes, launches."] + pub const cudaLaunchAttributeAccessPolicyWindow: cudaLaunchAttributeID = + cudaLaunchAttributeID(1); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for graph nodes, launches."] + pub const cudaLaunchAttributeCooperative: cudaLaunchAttributeID = cudaLaunchAttributeID(2); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for streams."] + pub const cudaLaunchAttributeSynchronizationPolicy: cudaLaunchAttributeID = + cudaLaunchAttributeID(3); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for graph nodes, launches."] + pub const cudaLaunchAttributeClusterDimension: cudaLaunchAttributeID = cudaLaunchAttributeID(4); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for graph nodes, launches."] + pub const cudaLaunchAttributeClusterSchedulingPolicyPreference: cudaLaunchAttributeID = + cudaLaunchAttributeID(5); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for launches. Setting\nprogrammaticStreamSerializationAllowed to non-0\nsignals that the kernel will use programmatic\nmeans to resolve its stream dependency, so that\nthe CUDA runtime should opportunistically allow\nthe grid's execution to overlap with the previous\nkernel in the stream, if that kernel requests the\noverlap."] + pub const cudaLaunchAttributeProgrammaticStreamSerialization: cudaLaunchAttributeID = + cudaLaunchAttributeID(6); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for launches. Event recorded through this launch\nattribute is guaranteed to only trigger after all\nblock in the associated kernel trigger the event. A\nblock can trigger the event through PTX\ngriddepcontrol.launch_dependents. A trigger can also\nbe inserted at the beginning of each block's execution\nif triggerAtBlockStart is set to non-0. Note that\ndependents (including the CPU thread calling\ncudaEventSynchronize()) are not guaranteed to observe\nthe release precisely when it is released. For\nexample, cudaEventSynchronize() may only observe the\nevent trigger long after the associated kernel has\ncompleted. This recording type is primarily meant for\nestablishing programmatic dependency between device\ntasks. The event supplied must not be an interprocess\nor interop event. The event must disable timing\n(i.e. created with ::cudaEventDisableTiming flag\nset)."] + pub const cudaLaunchAttributeProgrammaticEvent: cudaLaunchAttributeID = + cudaLaunchAttributeID(7); +} +impl cudaLaunchAttributeID { + #[doc = "< Valid for graph nodes."] + pub const cudaLaunchAttributePriority: cudaLaunchAttributeID = cudaLaunchAttributeID(8); +} +#[repr(transparent)] +#[doc = " Launch attributes enum; used as id field of ::cudaLaunchAttribute"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaLaunchAttributeID(pub ::std::os::raw::c_uint); +#[doc = " Launch attributes union; used as value field of ::cudaLaunchAttribute"] +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudaLaunchAttributeValue { + pub pad: [::std::os::raw::c_char; 64usize], + pub accessPolicyWindow: cudaAccessPolicyWindow, + pub cooperative: ::std::os::raw::c_int, + pub syncPolicy: cudaSynchronizationPolicy, + pub clusterDim: cudaLaunchAttributeValue__bindgen_ty_1, + pub clusterSchedulingPolicyPreference: cudaClusterSchedulingPolicy, + pub programmaticStreamSerializationAllowed: ::std::os::raw::c_int, + pub programmaticEvent: cudaLaunchAttributeValue__bindgen_ty_2, + pub priority: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLaunchAttributeValue__bindgen_ty_1 { + pub x: ::std::os::raw::c_uint, + pub y: ::std::os::raw::c_uint, + pub z: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLaunchAttributeValue__bindgen_ty_2 { + pub event: cudaEvent_t, + pub flags: ::std::os::raw::c_int, + pub triggerAtBlockStart: ::std::os::raw::c_int, +} +#[doc = " Launch attribute"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLaunchAttribute_st { + pub id: cudaLaunchAttributeID, + pub pad: [::std::os::raw::c_char; 4usize], + pub val: cudaLaunchAttributeValue, +} +#[doc = " Launch attribute"] +pub type cudaLaunchAttribute = cudaLaunchAttribute_st; +#[doc = " CUDA extensible launch configuration"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLaunchConfig_st { + #[doc = "< Grid dimentions"] + pub gridDim: dim3, + #[doc = "< Block dimentions"] + pub blockDim: dim3, + #[doc = "< Dynamic shared-memory size per thread block in bytes"] + pub dynamicSmemBytes: usize, + #[doc = "< Stream identifier"] + pub stream: cudaStream_t, + #[doc = "< nullable if numAttrs == 0"] + pub attrs: *mut cudaLaunchAttribute, + #[doc = "< Number of attributes populated in attrs"] + pub numAttrs: ::std::os::raw::c_uint, +} +#[doc = " CUDA extensible launch configuration"] +pub type cudaLaunchConfig_t = cudaLaunchConfig_st; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type cuFloatComplex = float2; +pub type cuDoubleComplex = double2; +pub type cuComplex = cuFloatComplex; +impl cudaDataType_t { + pub const CUDA_R_16F: cudaDataType_t = cudaDataType_t(2); +} +impl cudaDataType_t { + pub const CUDA_C_16F: cudaDataType_t = cudaDataType_t(6); +} +impl cudaDataType_t { + pub const CUDA_R_16BF: cudaDataType_t = cudaDataType_t(14); +} +impl cudaDataType_t { + pub const CUDA_C_16BF: cudaDataType_t = cudaDataType_t(15); +} +impl cudaDataType_t { + pub const CUDA_R_32F: cudaDataType_t = cudaDataType_t(0); +} +impl cudaDataType_t { + pub const CUDA_C_32F: cudaDataType_t = cudaDataType_t(4); +} +impl cudaDataType_t { + pub const CUDA_R_64F: cudaDataType_t = cudaDataType_t(1); +} +impl cudaDataType_t { + pub const CUDA_C_64F: cudaDataType_t = cudaDataType_t(5); +} +impl cudaDataType_t { + pub const CUDA_R_4I: cudaDataType_t = cudaDataType_t(16); +} +impl cudaDataType_t { + pub const CUDA_C_4I: cudaDataType_t = cudaDataType_t(17); +} +impl cudaDataType_t { + pub const CUDA_R_4U: cudaDataType_t = cudaDataType_t(18); +} +impl cudaDataType_t { + pub const CUDA_C_4U: cudaDataType_t = cudaDataType_t(19); +} +impl cudaDataType_t { + pub const CUDA_R_8I: cudaDataType_t = cudaDataType_t(3); +} +impl cudaDataType_t { + pub const CUDA_C_8I: cudaDataType_t = cudaDataType_t(7); +} +impl cudaDataType_t { + pub const CUDA_R_8U: cudaDataType_t = cudaDataType_t(8); +} +impl cudaDataType_t { + pub const CUDA_C_8U: cudaDataType_t = cudaDataType_t(9); +} +impl cudaDataType_t { + pub const CUDA_R_16I: cudaDataType_t = cudaDataType_t(20); +} +impl cudaDataType_t { + pub const CUDA_C_16I: cudaDataType_t = cudaDataType_t(21); +} +impl cudaDataType_t { + pub const CUDA_R_16U: cudaDataType_t = cudaDataType_t(22); +} +impl cudaDataType_t { + pub const CUDA_C_16U: cudaDataType_t = cudaDataType_t(23); +} +impl cudaDataType_t { + pub const CUDA_R_32I: cudaDataType_t = cudaDataType_t(10); +} +impl cudaDataType_t { + pub const CUDA_C_32I: cudaDataType_t = cudaDataType_t(11); +} +impl cudaDataType_t { + pub const CUDA_R_32U: cudaDataType_t = cudaDataType_t(12); +} +impl cudaDataType_t { + pub const CUDA_C_32U: cudaDataType_t = cudaDataType_t(13); +} +impl cudaDataType_t { + pub const CUDA_R_64I: cudaDataType_t = cudaDataType_t(24); +} +impl cudaDataType_t { + pub const CUDA_C_64I: cudaDataType_t = cudaDataType_t(25); +} +impl cudaDataType_t { + pub const CUDA_R_64U: cudaDataType_t = cudaDataType_t(26); +} +impl cudaDataType_t { + pub const CUDA_C_64U: cudaDataType_t = cudaDataType_t(27); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E4M3: cudaDataType_t = cudaDataType_t(28); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E5M2: cudaDataType_t = cudaDataType_t(29); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDataType_t(pub ::std::os::raw::c_uint); +pub use self::cudaDataType_t as cudaDataType; +impl libraryPropertyType_t { + pub const MAJOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(0); +} +impl libraryPropertyType_t { + pub const MINOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(1); +} +impl libraryPropertyType_t { + pub const PATCH_LEVEL: libraryPropertyType_t = libraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::libraryPropertyType_t as libraryPropertyType; +impl cublasStatus_t { + pub const CUBLAS_STATUS_SUCCESS: cublasStatus_t = cublasStatus_t(0); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_NOT_INITIALIZED: cublasStatus_t = cublasStatus_t(1); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_ALLOC_FAILED: cublasStatus_t = cublasStatus_t(3); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_INVALID_VALUE: cublasStatus_t = cublasStatus_t(7); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_ARCH_MISMATCH: cublasStatus_t = cublasStatus_t(8); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_MAPPING_ERROR: cublasStatus_t = cublasStatus_t(11); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_EXECUTION_FAILED: cublasStatus_t = cublasStatus_t(13); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_INTERNAL_ERROR: cublasStatus_t = cublasStatus_t(14); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_NOT_SUPPORTED: cublasStatus_t = cublasStatus_t(15); +} +impl cublasStatus_t { + pub const CUBLAS_STATUS_LICENSE_ERROR: cublasStatus_t = cublasStatus_t(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasStatus_t(pub ::std::os::raw::c_uint); +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_LOWER: cublasFillMode_t = cublasFillMode_t(0); +} +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_UPPER: cublasFillMode_t = cublasFillMode_t(1); +} +impl cublasFillMode_t { + pub const CUBLAS_FILL_MODE_FULL: cublasFillMode_t = cublasFillMode_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasFillMode_t(pub ::std::os::raw::c_uint); +impl cublasDiagType_t { + pub const CUBLAS_DIAG_NON_UNIT: cublasDiagType_t = cublasDiagType_t(0); +} +impl cublasDiagType_t { + pub const CUBLAS_DIAG_UNIT: cublasDiagType_t = cublasDiagType_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasDiagType_t(pub ::std::os::raw::c_uint); +impl cublasSideMode_t { + pub const CUBLAS_SIDE_LEFT: cublasSideMode_t = cublasSideMode_t(0); +} +impl cublasSideMode_t { + pub const CUBLAS_SIDE_RIGHT: cublasSideMode_t = cublasSideMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasSideMode_t(pub ::std::os::raw::c_uint); +impl cublasOperation_t { + pub const CUBLAS_OP_N: cublasOperation_t = cublasOperation_t(0); +} +impl cublasOperation_t { + pub const CUBLAS_OP_T: cublasOperation_t = cublasOperation_t(1); +} +impl cublasOperation_t { + pub const CUBLAS_OP_C: cublasOperation_t = cublasOperation_t(2); +} +impl cublasOperation_t { + pub const CUBLAS_OP_HERMITAN: cublasOperation_t = cublasOperation_t(2); +} +impl cublasOperation_t { + pub const CUBLAS_OP_CONJG: cublasOperation_t = cublasOperation_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasOperation_t(pub ::std::os::raw::c_uint); +impl cublasPointerMode_t { + pub const CUBLAS_POINTER_MODE_HOST: cublasPointerMode_t = cublasPointerMode_t(0); +} +impl cublasPointerMode_t { + pub const CUBLAS_POINTER_MODE_DEVICE: cublasPointerMode_t = cublasPointerMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasPointerMode_t(pub ::std::os::raw::c_uint); +impl cublasAtomicsMode_t { + pub const CUBLAS_ATOMICS_NOT_ALLOWED: cublasAtomicsMode_t = cublasAtomicsMode_t(0); +} +impl cublasAtomicsMode_t { + pub const CUBLAS_ATOMICS_ALLOWED: cublasAtomicsMode_t = cublasAtomicsMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasAtomicsMode_t(pub ::std::os::raw::c_uint); +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DFALT: cublasGemmAlgo_t = cublasGemmAlgo_t(-1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DEFAULT: cublasGemmAlgo_t = cublasGemmAlgo_t(-1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO0: cublasGemmAlgo_t = cublasGemmAlgo_t(0); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO1: cublasGemmAlgo_t = cublasGemmAlgo_t(1); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO2: cublasGemmAlgo_t = cublasGemmAlgo_t(2); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO3: cublasGemmAlgo_t = cublasGemmAlgo_t(3); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO4: cublasGemmAlgo_t = cublasGemmAlgo_t(4); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO5: cublasGemmAlgo_t = cublasGemmAlgo_t(5); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO6: cublasGemmAlgo_t = cublasGemmAlgo_t(6); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO7: cublasGemmAlgo_t = cublasGemmAlgo_t(7); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO8: cublasGemmAlgo_t = cublasGemmAlgo_t(8); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO9: cublasGemmAlgo_t = cublasGemmAlgo_t(9); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO10: cublasGemmAlgo_t = cublasGemmAlgo_t(10); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO11: cublasGemmAlgo_t = cublasGemmAlgo_t(11); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO12: cublasGemmAlgo_t = cublasGemmAlgo_t(12); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO13: cublasGemmAlgo_t = cublasGemmAlgo_t(13); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO14: cublasGemmAlgo_t = cublasGemmAlgo_t(14); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO15: cublasGemmAlgo_t = cublasGemmAlgo_t(15); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO16: cublasGemmAlgo_t = cublasGemmAlgo_t(16); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO17: cublasGemmAlgo_t = cublasGemmAlgo_t(17); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO18: cublasGemmAlgo_t = cublasGemmAlgo_t(18); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO19: cublasGemmAlgo_t = cublasGemmAlgo_t(19); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO20: cublasGemmAlgo_t = cublasGemmAlgo_t(20); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO21: cublasGemmAlgo_t = cublasGemmAlgo_t(21); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO22: cublasGemmAlgo_t = cublasGemmAlgo_t(22); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO23: cublasGemmAlgo_t = cublasGemmAlgo_t(23); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DEFAULT_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(99); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_DFALT_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(99); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO0_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(100); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO1_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(101); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO2_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(102); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO3_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(103); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO4_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(104); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO5_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(105); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO6_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(106); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO7_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(107); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO8_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(108); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO9_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(109); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO10_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(110); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO11_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(111); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO12_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(112); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO13_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(113); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO14_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(114); +} +impl cublasGemmAlgo_t { + pub const CUBLAS_GEMM_ALGO15_TENSOR_OP: cublasGemmAlgo_t = cublasGemmAlgo_t(115); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasGemmAlgo_t(pub ::std::os::raw::c_int); +impl cublasMath_t { + pub const CUBLAS_DEFAULT_MATH: cublasMath_t = cublasMath_t(0); +} +impl cublasMath_t { + pub const CUBLAS_TENSOR_OP_MATH: cublasMath_t = cublasMath_t(1); +} +impl cublasMath_t { + pub const CUBLAS_PEDANTIC_MATH: cublasMath_t = cublasMath_t(2); +} +impl cublasMath_t { + pub const CUBLAS_TF32_TENSOR_OP_MATH: cublasMath_t = cublasMath_t(3); +} +impl cublasMath_t { + pub const CUBLAS_MATH_DISALLOW_REDUCED_PRECISION_REDUCTION: cublasMath_t = cublasMath_t(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasMath_t(pub ::std::os::raw::c_uint); +pub use self::cudaDataType as cublasDataType_t; +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_16F: cublasComputeType_t = cublasComputeType_t(64); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_16F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(65); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F: cublasComputeType_t = cublasComputeType_t(68); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(69); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_16F: cublasComputeType_t = cublasComputeType_t(74); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_16BF: cublasComputeType_t = cublasComputeType_t(75); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32F_FAST_TF32: cublasComputeType_t = cublasComputeType_t(77); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_64F: cublasComputeType_t = cublasComputeType_t(70); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_64F_PEDANTIC: cublasComputeType_t = cublasComputeType_t(71); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32I: cublasComputeType_t = cublasComputeType_t(72); +} +impl cublasComputeType_t { + pub const CUBLAS_COMPUTE_32I_PEDANTIC: cublasComputeType_t = cublasComputeType_t(73); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasComputeType_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasContext { + _unused: [u8; 0], +} +pub type cublasHandle_t = *mut cublasContext; +pub type cublasLogCallback = + ::std::option::Option; +pub type FILE = _IO_FILE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_marker { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_codecvt { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_wide_data { + _unused: [u8; 0], +} +pub type _IO_lock_t = ::std::os::raw::c_void; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_FILE { + pub _flags: ::std::os::raw::c_int, + pub _IO_read_ptr: *mut ::std::os::raw::c_char, + pub _IO_read_end: *mut ::std::os::raw::c_char, + pub _IO_read_base: *mut ::std::os::raw::c_char, + pub _IO_write_base: *mut ::std::os::raw::c_char, + pub _IO_write_ptr: *mut ::std::os::raw::c_char, + pub _IO_write_end: *mut ::std::os::raw::c_char, + pub _IO_buf_base: *mut ::std::os::raw::c_char, + pub _IO_buf_end: *mut ::std::os::raw::c_char, + pub _IO_save_base: *mut ::std::os::raw::c_char, + pub _IO_backup_base: *mut ::std::os::raw::c_char, + pub _IO_save_end: *mut ::std::os::raw::c_char, + pub _markers: *mut _IO_marker, + pub _chain: *mut _IO_FILE, + pub _fileno: ::std::os::raw::c_int, + pub _flags2: ::std::os::raw::c_int, + pub _old_offset: __off_t, + pub _cur_column: ::std::os::raw::c_ushort, + pub _vtable_offset: ::std::os::raw::c_schar, + pub _shortbuf: [::std::os::raw::c_char; 1usize], + pub _lock: *mut _IO_lock_t, + pub _offset: __off64_t, + pub _codecvt: *mut _IO_codecvt, + pub _wide_data: *mut _IO_wide_data, + pub _freeres_list: *mut _IO_FILE, + pub _freeres_buf: *mut ::std::os::raw::c_void, + pub __pad5: usize, + pub _mode: ::std::os::raw::c_int, + pub _unused2: [::std::os::raw::c_char; 20usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtContext { + _unused: [u8; 0], +} +#[doc = " Opaque structure holding CUBLASLT context"] +pub type cublasLtHandle_t = *mut cublasLtContext; + +#[no_mangle] +pub unsafe extern "system" fn cublasLtCreate(lightHandle: *mut cublasLtHandle_t) -> cublasStatus_t { + crate::create(lightHandle) +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtDestroy(lightHandle: cublasLtHandle_t) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtGetStatusName( + status: cublasStatus_t, +) -> *const ::std::os::raw::c_char { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtGetStatusString( + status: cublasStatus_t, +) -> *const ::std::os::raw::c_char { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtGetVersion() -> usize { + crate::get_version() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtGetCudartVersion() -> usize { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtGetProperty( + type_: libraryPropertyType, + value: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtHeuristicsCacheGetCapacity( + capacity: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cublasLtHeuristicsCacheSetCapacity( + capacity: usize, +) -> cublasStatus_t { + crate::unsupported() +} +#[doc = " Semi-opaque descriptor for matrix memory layout"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatrixLayoutOpaque_t { + pub data: [u64; 8usize], +} +#[doc = " Opaque descriptor for matrix memory layout"] +pub type cublasLtMatrixLayout_t = *mut cublasLtMatrixLayoutOpaque_t; +#[doc = " Semi-opaque algorithm descriptor (to avoid complicated alloc/free schemes)\n\n This structure can be trivially serialized and later restored for use with the same version of cuBLAS library to save\n on selecting the right configuration again."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatmulAlgo_t { + pub data: [u64; 8usize], +} +#[doc = " Semi-opaque descriptor for cublasLtMatmul() operation details"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatmulDescOpaque_t { + pub data: [u64; 23usize], +} +#[doc = " Opaque descriptor for cublasLtMatmul() operation details"] +pub type cublasLtMatmulDesc_t = *mut cublasLtMatmulDescOpaque_t; +#[doc = " Semi-opaque descriptor for cublasLtMatrixTransform() operation details"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatrixTransformDescOpaque_t { + pub data: [u64; 8usize], +} +#[doc = " Opaque descriptor for cublasLtMatrixTransform() operation details"] +pub type cublasLtMatrixTransformDesc_t = *mut cublasLtMatrixTransformDescOpaque_t; +#[doc = " Semi-opaque descriptor for cublasLtMatmulPreference() operation details"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatmulPreferenceOpaque_t { + pub data: [u64; 10usize], +} +#[doc = " Opaque descriptor for cublasLtMatmulAlgoGetHeuristic() configuration"] +pub type cublasLtMatmulPreference_t = *mut cublasLtMatmulPreferenceOpaque_t; +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_UNDEFINED: cublasLtMatmulTile_t = cublasLtMatmulTile_t(0); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_8x8: cublasLtMatmulTile_t = cublasLtMatmulTile_t(1); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_8x16: cublasLtMatmulTile_t = cublasLtMatmulTile_t(2); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_16x8: cublasLtMatmulTile_t = cublasLtMatmulTile_t(3); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_8x32: cublasLtMatmulTile_t = cublasLtMatmulTile_t(4); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_16x16: cublasLtMatmulTile_t = cublasLtMatmulTile_t(5); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_32x8: cublasLtMatmulTile_t = cublasLtMatmulTile_t(6); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_8x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(7); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_16x32: cublasLtMatmulTile_t = cublasLtMatmulTile_t(8); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_32x16: cublasLtMatmulTile_t = cublasLtMatmulTile_t(9); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x8: cublasLtMatmulTile_t = cublasLtMatmulTile_t(10); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_32x32: cublasLtMatmulTile_t = cublasLtMatmulTile_t(11); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_32x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(12); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x32: cublasLtMatmulTile_t = cublasLtMatmulTile_t(13); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_32x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(14); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(15); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x32: cublasLtMatmulTile_t = cublasLtMatmulTile_t(16); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(17); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(18); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x256: cublasLtMatmulTile_t = cublasLtMatmulTile_t(19); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(20); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_256x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(21); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x512: cublasLtMatmulTile_t = cublasLtMatmulTile_t(22); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x256: cublasLtMatmulTile_t = cublasLtMatmulTile_t(23); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_256x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(24); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_512x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(25); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_64x96: cublasLtMatmulTile_t = cublasLtMatmulTile_t(26); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_96x64: cublasLtMatmulTile_t = cublasLtMatmulTile_t(27); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_96x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(28); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x160: cublasLtMatmulTile_t = cublasLtMatmulTile_t(29); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_160x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(30); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_192x128: cublasLtMatmulTile_t = cublasLtMatmulTile_t(31); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x192: cublasLtMatmulTile_t = cublasLtMatmulTile_t(32); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_128x96: cublasLtMatmulTile_t = cublasLtMatmulTile_t(33); +} +impl cublasLtMatmulTile_t { + pub const CUBLASLT_MATMUL_TILE_END: cublasLtMatmulTile_t = cublasLtMatmulTile_t(34); +} +#[repr(transparent)] +#[doc = " Tile size (in C/D matrix Rows x Cols)\n\n General order of tile IDs is sorted by size first and by first dimension second."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulTile_t(pub ::std::os::raw::c_uint); +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_UNDEFINED: cublasLtMatmulStages_t = cublasLtMatmulStages_t(0); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x1: cublasLtMatmulStages_t = cublasLtMatmulStages_t(1); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x2: cublasLtMatmulStages_t = cublasLtMatmulStages_t(2); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x3: cublasLtMatmulStages_t = cublasLtMatmulStages_t(3); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x4: cublasLtMatmulStages_t = cublasLtMatmulStages_t(4); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x5: cublasLtMatmulStages_t = cublasLtMatmulStages_t(5); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x6: cublasLtMatmulStages_t = cublasLtMatmulStages_t(6); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x1: cublasLtMatmulStages_t = cublasLtMatmulStages_t(7); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x2: cublasLtMatmulStages_t = cublasLtMatmulStages_t(8); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x3: cublasLtMatmulStages_t = cublasLtMatmulStages_t(9); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x4: cublasLtMatmulStages_t = cublasLtMatmulStages_t(10); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x5: cublasLtMatmulStages_t = cublasLtMatmulStages_t(11); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x6: cublasLtMatmulStages_t = cublasLtMatmulStages_t(12); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x1: cublasLtMatmulStages_t = cublasLtMatmulStages_t(13); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x2: cublasLtMatmulStages_t = cublasLtMatmulStages_t(14); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x3: cublasLtMatmulStages_t = cublasLtMatmulStages_t(15); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x4: cublasLtMatmulStages_t = cublasLtMatmulStages_t(16); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x5: cublasLtMatmulStages_t = cublasLtMatmulStages_t(17); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x6: cublasLtMatmulStages_t = cublasLtMatmulStages_t(18); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x1: cublasLtMatmulStages_t = cublasLtMatmulStages_t(19); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x2: cublasLtMatmulStages_t = cublasLtMatmulStages_t(20); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x3: cublasLtMatmulStages_t = cublasLtMatmulStages_t(21); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x4: cublasLtMatmulStages_t = cublasLtMatmulStages_t(22); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x5: cublasLtMatmulStages_t = cublasLtMatmulStages_t(23); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128x6: cublasLtMatmulStages_t = cublasLtMatmulStages_t(24); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32x10: cublasLtMatmulStages_t = cublasLtMatmulStages_t(25); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_8x4: cublasLtMatmulStages_t = cublasLtMatmulStages_t(26); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x10: cublasLtMatmulStages_t = cublasLtMatmulStages_t(27); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_8x5: cublasLtMatmulStages_t = cublasLtMatmulStages_t(28); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16x80: cublasLtMatmulStages_t = cublasLtMatmulStages_t(29); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64x80: cublasLtMatmulStages_t = cublasLtMatmulStages_t(30); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_8x3: cublasLtMatmulStages_t = cublasLtMatmulStages_t(31); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_8xAUTO: cublasLtMatmulStages_t = cublasLtMatmulStages_t(32); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_16xAUTO: cublasLtMatmulStages_t = cublasLtMatmulStages_t(33); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_32xAUTO: cublasLtMatmulStages_t = cublasLtMatmulStages_t(34); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_64xAUTO: cublasLtMatmulStages_t = cublasLtMatmulStages_t(35); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_128xAUTO: cublasLtMatmulStages_t = cublasLtMatmulStages_t(36); +} +impl cublasLtMatmulStages_t { + pub const CUBLASLT_MATMUL_STAGES_END: cublasLtMatmulStages_t = cublasLtMatmulStages_t(37); +} +#[repr(transparent)] +#[doc = " Size and number of stages in which elements are read into shared memory\n\n General order of stages IDs is sorted by stage size first and by number of stages second."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulStages_t(pub ::std::os::raw::c_uint); +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_AUTO: cublasLtClusterShape_t = cublasLtClusterShape_t(0); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(2); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(3); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_4x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(4); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(5); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(6); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_4x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(7); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x4x1: cublasLtClusterShape_t = cublasLtClusterShape_t(8); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x4x1: cublasLtClusterShape_t = cublasLtClusterShape_t(9); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_4x4x1: cublasLtClusterShape_t = cublasLtClusterShape_t(10); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_8x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(11); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x8x1: cublasLtClusterShape_t = cublasLtClusterShape_t(12); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_8x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(13); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x8x1: cublasLtClusterShape_t = cublasLtClusterShape_t(14); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_16x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(15); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x16x1: cublasLtClusterShape_t = cublasLtClusterShape_t(16); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_3x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(17); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_5x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(18); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_6x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(19); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_7x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(20); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_9x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(21); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_10x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(22); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_11x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(23); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_12x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(24); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_13x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(25); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_14x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(26); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_15x1x1: cublasLtClusterShape_t = cublasLtClusterShape_t(27); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_3x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(28); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_5x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(29); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_6x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(30); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_7x2x1: cublasLtClusterShape_t = cublasLtClusterShape_t(31); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x3x1: cublasLtClusterShape_t = cublasLtClusterShape_t(32); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x3x1: cublasLtClusterShape_t = cublasLtClusterShape_t(33); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_3x3x1: cublasLtClusterShape_t = cublasLtClusterShape_t(34); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_4x3x1: cublasLtClusterShape_t = cublasLtClusterShape_t(35); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_5x3x1: cublasLtClusterShape_t = cublasLtClusterShape_t(36); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_3x4x1: cublasLtClusterShape_t = cublasLtClusterShape_t(37); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x5x1: cublasLtClusterShape_t = cublasLtClusterShape_t(38); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x5x1: cublasLtClusterShape_t = cublasLtClusterShape_t(39); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_3x5x1: cublasLtClusterShape_t = cublasLtClusterShape_t(40); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x6x1: cublasLtClusterShape_t = cublasLtClusterShape_t(41); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x6x1: cublasLtClusterShape_t = cublasLtClusterShape_t(42); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x7x1: cublasLtClusterShape_t = cublasLtClusterShape_t(43); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_2x7x1: cublasLtClusterShape_t = cublasLtClusterShape_t(44); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x9x1: cublasLtClusterShape_t = cublasLtClusterShape_t(45); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x10x1: cublasLtClusterShape_t = cublasLtClusterShape_t(46); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x11x1: cublasLtClusterShape_t = cublasLtClusterShape_t(47); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x12x1: cublasLtClusterShape_t = cublasLtClusterShape_t(48); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x13x1: cublasLtClusterShape_t = cublasLtClusterShape_t(49); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x14x1: cublasLtClusterShape_t = cublasLtClusterShape_t(50); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_1x15x1: cublasLtClusterShape_t = cublasLtClusterShape_t(51); +} +impl cublasLtClusterShape_t { + #[doc = " Let library pick cluster shape automatically"] + pub const CUBLASLT_CLUSTER_SHAPE_END: cublasLtClusterShape_t = cublasLtClusterShape_t(52); +} +#[repr(transparent)] +#[doc = " Thread Block Cluster size\n\n Typically dimensioned similar to cublasLtMatmulTile_t, with the third coordinate unused at this time."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtClusterShape_t(pub ::std::os::raw::c_uint); +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_UNDEFINED: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(0); +} +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_MMA884: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(1); +} +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_MMA1684: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(2); +} +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_MMA1688: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(3); +} +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_MMA16816: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(4); +} +impl cublasLtMatmulInnerShape_t { + pub const CUBLASLT_MATMUL_INNER_SHAPE_END: cublasLtMatmulInnerShape_t = + cublasLtMatmulInnerShape_t(5); +} +#[repr(transparent)] +#[doc = " Inner size of the kernel\n\n Represents various aspects of internal kernel design, that don't impact CUDA grid size but may have other more subtle\n effects.\n"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulInnerShape_t(pub ::std::os::raw::c_uint); +impl cublasLtPointerMode_t { + #[doc = " matches CUBLAS_POINTER_MODE_HOST, pointer targets a single value host memory"] + pub const CUBLASLT_POINTER_MODE_HOST: cublasLtPointerMode_t = cublasLtPointerMode_t(0); +} +impl cublasLtPointerMode_t { + #[doc = " matches CUBLAS_POINTER_MODE_DEVICE, pointer targets a single value device memory"] + pub const CUBLASLT_POINTER_MODE_DEVICE: cublasLtPointerMode_t = cublasLtPointerMode_t(1); +} +impl cublasLtPointerMode_t { + #[doc = " pointer targets an array in device memory"] + pub const CUBLASLT_POINTER_MODE_DEVICE_VECTOR: cublasLtPointerMode_t = cublasLtPointerMode_t(2); +} +impl cublasLtPointerMode_t { + #[doc = " alpha pointer targets an array in device memory, beta is zero. Note:\nCUBLASLT_MATMUL_DESC_ALPHA_VECTOR_BATCH_STRIDE is not supported, must be 0."] + pub const CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_ZERO: cublasLtPointerMode_t = + cublasLtPointerMode_t(3); +} +impl cublasLtPointerMode_t { + #[doc = " alpha pointer targets an array in device memory, beta is a single value in host memory."] + pub const CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_HOST: cublasLtPointerMode_t = + cublasLtPointerMode_t(4); +} +#[repr(transparent)] +#[doc = " Pointer mode to use for alpha/beta"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtPointerMode_t(pub ::std::os::raw::c_uint); +impl cublasLtPointerModeMask_t { + #[doc = " no initial filtering is performed when querying pointer mode capabilities, will use gemm pointer mode defined in\noperation description"] + pub const CUBLASLT_POINTER_MODE_MASK_NO_FILTERING: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(0); +} +impl cublasLtPointerModeMask_t { + #[doc = " see CUBLASLT_POINTER_MODE_HOST"] + pub const CUBLASLT_POINTER_MODE_MASK_HOST: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(1); +} +impl cublasLtPointerModeMask_t { + #[doc = " see CUBLASLT_POINTER_MODE_DEVICE"] + pub const CUBLASLT_POINTER_MODE_MASK_DEVICE: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(2); +} +impl cublasLtPointerModeMask_t { + #[doc = " see CUBLASLT_POINTER_MODE_DEVICE_VECTOR"] + pub const CUBLASLT_POINTER_MODE_MASK_DEVICE_VECTOR: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(4); +} +impl cublasLtPointerModeMask_t { + #[doc = " see CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_ZERO"] + pub const CUBLASLT_POINTER_MODE_MASK_ALPHA_DEVICE_VECTOR_BETA_ZERO: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(8); +} +impl cublasLtPointerModeMask_t { + #[doc = " see CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_HOST"] + pub const CUBLASLT_POINTER_MODE_MASK_ALPHA_DEVICE_VECTOR_BETA_HOST: cublasLtPointerModeMask_t = + cublasLtPointerModeMask_t(16); +} +#[repr(transparent)] +#[doc = " Mask to define and query pointer mode capability"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtPointerModeMask_t(pub ::std::os::raw::c_uint); +pub type cublasLtNumericalImplFlags_t = u64; + +#[doc = " Execute matrix multiplication (D = alpha * op(A) * op(B) + beta * C).\n\n \\retval CUBLAS_STATUS_NOT_INITIALIZED if cuBLASLt handle has not been initialized\n \\retval CUBLAS_STATUS_INVALID_VALUE if parameters are in conflict or in an impossible configuration; e.g.\n when workspaceSizeInBytes is less than workspace required by configured\n algo\n \\retval CUBLAS_STATUS_NOT_SUPPORTED if current implementation on selected device doesn't support configured\n operation\n \\retval CUBLAS_STATUS_ARCH_MISMATCH if configured operation cannot be run using selected device\n \\retval CUBLAS_STATUS_EXECUTION_FAILED if cuda reported execution error from the device\n \\retval CUBLAS_STATUS_SUCCESS if the operation completed successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmul( + lightHandle: cublasLtHandle_t, + computeDesc: cublasLtMatmulDesc_t, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + Adesc: cublasLtMatrixLayout_t, + B: *const ::std::os::raw::c_void, + Bdesc: cublasLtMatrixLayout_t, + beta: *const ::std::os::raw::c_void, + C: *const ::std::os::raw::c_void, + Cdesc: cublasLtMatrixLayout_t, + D: *mut ::std::os::raw::c_void, + Ddesc: cublasLtMatrixLayout_t, + algo: *const cublasLtMatmulAlgo_t, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::matmul( + lightHandle, + computeDesc, + alpha, + A, + Adesc, + B, + Bdesc, + beta, + C, + Cdesc, + D, + Ddesc, + algo, + workspace, + workspaceSizeInBytes, + stream, + ) +} + +#[doc = " Matrix layout conversion helper (C = alpha * op(A) + beta * op(B))\n\n Can be used to change memory order of data or to scale and shift the values.\n\n \\retval CUBLAS_STATUS_NOT_INITIALIZED if cuBLASLt handle has not been initialized\n \\retval CUBLAS_STATUS_INVALID_VALUE if parameters are in conflict or in an impossible configuration; e.g.\n when A is not NULL, but Adesc is NULL\n \\retval CUBLAS_STATUS_NOT_SUPPORTED if current implementation on selected device doesn't support configured\n operation\n \\retval CUBLAS_STATUS_ARCH_MISMATCH if configured operation cannot be run using selected device\n \\retval CUBLAS_STATUS_EXECUTION_FAILED if cuda reported execution error from the device\n \\retval CUBLAS_STATUS_SUCCESS if the operation completed successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransform( + lightHandle: cublasLtHandle_t, + transformDesc: cublasLtMatrixTransformDesc_t, + alpha: *const ::std::os::raw::c_void, + A: *const ::std::os::raw::c_void, + Adesc: cublasLtMatrixLayout_t, + beta: *const ::std::os::raw::c_void, + B: *const ::std::os::raw::c_void, + Bdesc: cublasLtMatrixLayout_t, + C: *mut ::std::os::raw::c_void, + Cdesc: cublasLtMatrixLayout_t, + stream: cudaStream_t, +) -> cublasStatus_t { + crate::unsupported() +} +impl cublasLtOrder_t { + #[doc = " Column-major\n\n Leading dimension is the stride (in elements) to the beginning of next column in memory."] + pub const CUBLASLT_ORDER_COL: cublasLtOrder_t = cublasLtOrder_t(0); +} +impl cublasLtOrder_t { + #[doc = " Row major\n\n Leading dimension is the stride (in elements) to the beginning of next row in memory."] + pub const CUBLASLT_ORDER_ROW: cublasLtOrder_t = cublasLtOrder_t(1); +} +impl cublasLtOrder_t { + #[doc = " Column-major ordered tiles of 32 columns.\n\n Leading dimension is the stride (in elements) to the beginning of next group of 32-columns. E.g. if matrix has 33\n columns and 2 rows, ld must be at least (32) * 2 = 64."] + pub const CUBLASLT_ORDER_COL32: cublasLtOrder_t = cublasLtOrder_t(2); +} +impl cublasLtOrder_t { + #[doc = " Column-major ordered tiles of composite tiles with total 32 columns and 8 rows, tile composed of interleaved\n inner tiles of 4 columns within 4 even or odd rows in an alternating pattern.\n\n Leading dimension is the stride (in elements) to the beginning of the first 32 column x 8 row tile for the next\n 32-wide group of columns. E.g. if matrix has 33 columns and 1 row, ld must be at least (32 * 8) * 1 = 256."] + pub const CUBLASLT_ORDER_COL4_4R2_8C: cublasLtOrder_t = cublasLtOrder_t(3); +} +impl cublasLtOrder_t { + #[doc = " Column-major ordered tiles of composite tiles with total 32 columns ands 32 rows.\n Element offset within the tile is calculated as (((row%8)/2*4+row/8)*2+row%2)*32+col.\n\n Leading dimension is the stride (in elements) to the beginning of the first 32 column x 32 row tile for the next\n 32-wide group of columns. E.g. if matrix has 33 columns and 1 row, ld must be at least (32*32)*1 = 1024."] + pub const CUBLASLT_ORDER_COL32_2R_4R4: cublasLtOrder_t = cublasLtOrder_t(4); +} +#[repr(transparent)] +#[doc = " Enum for data ordering"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtOrder_t(pub ::std::os::raw::c_uint); +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Data type, see cudaDataType.\n\n uint32_t"] + pub const CUBLASLT_MATRIX_LAYOUT_TYPE: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(0); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Memory order of the data, see cublasLtOrder_t.\n\n int32_t, default: CUBLASLT_ORDER_COL"] + pub const CUBLASLT_MATRIX_LAYOUT_ORDER: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(1); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Number of rows.\n\n Usually only values that can be expressed as int32_t are supported.\n\n uint64_t"] + pub const CUBLASLT_MATRIX_LAYOUT_ROWS: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(2); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Number of columns.\n\n Usually only values that can be expressed as int32_t are supported.\n\n uint64_t"] + pub const CUBLASLT_MATRIX_LAYOUT_COLS: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(3); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Matrix leading dimension.\n\n For CUBLASLT_ORDER_COL this is stride (in elements) of matrix column, for more details and documentation for\n other memory orders see documentation for cublasLtOrder_t values.\n\n Currently only non-negative values are supported, must be large enough so that matrix memory locations are not\n overlapping (e.g. greater or equal to CUBLASLT_MATRIX_LAYOUT_ROWS in case of CUBLASLT_ORDER_COL).\n\n int64_t;"] + pub const CUBLASLT_MATRIX_LAYOUT_LD: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(4); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Number of matmul operations to perform in the batch.\n\n See also CUBLASLT_ALGO_CAP_STRIDED_BATCH_SUPPORT\n\n int32_t, default: 1"] + pub const CUBLASLT_MATRIX_LAYOUT_BATCH_COUNT: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(5); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Stride (in elements) to the next matrix for strided batch operation.\n\n When matrix type is planar-complex (CUBLASLT_MATRIX_LAYOUT_PLANE_OFFSET != 0), batch stride\n is interpreted by cublasLtMatmul() in number of real valued sub-elements. E.g. for data of type CUDA_C_16F,\n offset of 1024B is encoded as a stride of value 512 (since each element of the real and imaginary matrices\n is a 2B (16bit) floating point type).\n\n NOTE: A bug in cublasLtMatrixTransform() causes it to interpret the batch stride for a planar-complex matrix\n as if it was specified in number of complex elements. Therefore an offset of 1024B must be encoded as stride\n value 256 when calling cublasLtMatrixTransform() (each complex element is 4B with real and imaginary values 2B\n each). This behavior is expected to be corrected in the next major cuBLAS version.\n\n int64_t, default: 0"] + pub const CUBLASLT_MATRIX_LAYOUT_STRIDED_BATCH_OFFSET: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(6); +} +impl cublasLtMatrixLayoutAttribute_t { + #[doc = " Stride (in bytes) to the imaginary plane for planar complex layout.\n\n int64_t, default: 0 - 0 means that layout is regular (real and imaginary parts of complex numbers are interleaved\n in memory in each element)"] + pub const CUBLASLT_MATRIX_LAYOUT_PLANE_OFFSET: cublasLtMatrixLayoutAttribute_t = + cublasLtMatrixLayoutAttribute_t(7); +} +#[repr(transparent)] +#[doc = " Attributes of memory layout"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatrixLayoutAttribute_t(pub ::std::os::raw::c_uint); + +#[doc = " Internal. Do not use directly."] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixLayoutInit_internal( + matLayout: cublasLtMatrixLayout_t, + size: usize, + type_: cudaDataType, + rows: u64, + cols: u64, + ld: i64, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Create new matrix layout descriptor.\n\n \\retval CUBLAS_STATUS_ALLOC_FAILED if memory could not be allocated\n \\retval CUBLAS_STATUS_SUCCESS if desciptor was created successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixLayoutCreate( + matLayout: *mut cublasLtMatrixLayout_t, + type_: cudaDataType, + rows: u64, + cols: u64, + ld: i64, +) -> cublasStatus_t { + crate::matrix_layout_create(matLayout, type_, rows, cols, ld) +} + +#[doc = " Destroy matrix layout descriptor.\n\n \\retval CUBLAS_STATUS_SUCCESS if operation was successful"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixLayoutDestroy( + matLayout: cublasLtMatrixLayout_t, +) -> cublasStatus_t { + crate::matrix_layout_destroy(matLayout) +} + +#[doc = " Set matrix layout descriptor attribute.\n\n \\param[in] matLayout The descriptor\n \\param[in] attr The attribute\n \\param[in] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixLayoutSetAttribute( + matLayout: cublasLtMatrixLayout_t, + attr: cublasLtMatrixLayoutAttribute_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, +) -> cublasStatus_t { + crate::matrix_layout_set_attribute(matLayout, attr, buf, sizeInBytes) +} + +#[doc = " Get matrix layout descriptor attribute.\n\n \\param[in] matLayout The descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number of\n bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixLayoutGetAttribute( + matLayout: cublasLtMatrixLayout_t, + attr: cublasLtMatrixLayoutAttribute_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Compute type, see cudaDataType. Defines data type used for multiply and accumulate operations and the\n accumulator during matrix multiplication.\n\n int32_t"] + pub const CUBLASLT_MATMUL_DESC_COMPUTE_TYPE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(0); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Scale type, see cudaDataType. Defines data type of alpha and beta. Accumulator and value from matrix C are\n typically converted to scale type before final scaling. Value is then converted from scale type to type of matrix\n D before being stored in memory.\n\n int32_t, default: same as CUBLASLT_MATMUL_DESC_COMPUTE_TYPE"] + pub const CUBLASLT_MATMUL_DESC_SCALE_TYPE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(1); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Pointer mode of alpha and beta, see cublasLtPointerMode_t. When CUBLASLT_POINTER_MODE_DEVICE_VECTOR is in use,\n alpha/beta vector lenghts must match number of output matrix rows.\n\n int32_t, default: CUBLASLT_POINTER_MODE_HOST"] + pub const CUBLASLT_MATMUL_DESC_POINTER_MODE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(2); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Transform of matrix A, see cublasOperation_t.\n\n int32_t, default: CUBLAS_OP_N"] + pub const CUBLASLT_MATMUL_DESC_TRANSA: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(3); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Transform of matrix B, see cublasOperation_t.\n\n int32_t, default: CUBLAS_OP_N"] + pub const CUBLASLT_MATMUL_DESC_TRANSB: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(4); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Transform of matrix C, see cublasOperation_t.\n\n Currently only CUBLAS_OP_N is supported.\n\n int32_t, default: CUBLAS_OP_N"] + pub const CUBLASLT_MATMUL_DESC_TRANSC: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(5); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Matrix fill mode, see cublasFillMode_t.\n\n int32_t, default: CUBLAS_FILL_MODE_FULL"] + pub const CUBLASLT_MATMUL_DESC_FILL_MODE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(6); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Epilogue function, see cublasLtEpilogue_t.\n\n uint32_t, default: CUBLASLT_EPILOGUE_DEFAULT"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(7); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Bias or bias gradient vector pointer in the device memory.\n\n Bias case. See CUBLASLT_EPILOGUE_BIAS.\n For bias data type see CUBLASLT_MATMUL_DESC_BIAS_DATA_TYPE.\n\n Bias vector length must match matrix D rows count.\n\n Bias gradient case. See CUBLASLT_EPILOGUE_DRELU_BGRAD and CUBLASLT_EPILOGUE_DGELU_BGRAD.\n Bias gradient vector elements are the same type as the output elements\n (Ctype) with the exception of IMMA kernels (see above).\n\n Routines that don't dereference this pointer, like cublasLtMatmulAlgoGetHeuristic()\n depend on its value to determine expected pointer alignment.\n\n Bias case: const void *, default: NULL\n Bias gradient case: void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_BIAS_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(8); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Batch stride for bias or bias gradient vector.\n\n Used together with CUBLASLT_MATMUL_DESC_BIAS_POINTER when matrix D's CUBLASLT_MATRIX_LAYOUT_BATCH_COUNT > 1.\n\n int64_t, default: 0"] + pub const CUBLASLT_MATMUL_DESC_BIAS_BATCH_STRIDE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(10); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Pointer for epilogue auxiliary buffer.\n\n - Output vector for ReLu bit-mask in forward pass when CUBLASLT_EPILOGUE_RELU_AUX\n or CUBLASLT_EPILOGUE_RELU_AUX_BIAS epilogue is used.\n - Input vector for ReLu bit-mask in backward pass when\n CUBLASLT_EPILOGUE_DRELU_BGRAD epilogue is used.\n\n - Output of GELU input matrix in forward pass when\n CUBLASLT_EPILOGUE_GELU_AUX_BIAS epilogue is used.\n - Input of GELU input matrix for backward pass when\n CUBLASLT_EPILOGUE_DGELU_BGRAD epilogue is used.\n\n For aux data type see CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_DATA_TYPE.\n\n Routines that don't dereference this pointer, like cublasLtMatmulAlgoGetHeuristic()\n depend on its value to determine expected pointer alignment.\n\n Requires setting CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_LD attribute.\n\n Forward pass: void *, default: NULL\n Backward pass: const void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(11); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Leading dimension for epilogue auxiliary buffer.\n\n - ReLu bit-mask matrix leading dimension in elements (i.e. bits)\n when CUBLASLT_EPILOGUE_RELU_AUX, CUBLASLT_EPILOGUE_RELU_AUX_BIAS or CUBLASLT_EPILOGUE_DRELU_BGRAD epilogue is\n used. Must be divisible by 128 and be no less than the number of rows in the output matrix.\n\n - GELU input matrix leading dimension in elements\n when CUBLASLT_EPILOGUE_GELU_AUX_BIAS or CUBLASLT_EPILOGUE_DGELU_BGRAD epilogue used.\n Must be divisible by 8 and be no less than the number of rows in the output matrix.\n\n int64_t, default: 0"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_LD: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(12); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Batch stride for epilogue auxiliary buffer.\n\n - ReLu bit-mask matrix batch stride in elements (i.e. bits)\n when CUBLASLT_EPILOGUE_RELU_AUX, CUBLASLT_EPILOGUE_RELU_AUX_BIAS or CUBLASLT_EPILOGUE_DRELU_BGRAD epilogue is\n used. Must be divisible by 128.\n\n - GELU input matrix batch stride in elements\n when CUBLASLT_EPILOGUE_GELU_AUX_BIAS or CUBLASLT_EPILOGUE_DGELU_BGRAD epilogue used.\n Must be divisible by 8.\n\n int64_t, default: 0"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_BATCH_STRIDE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(13); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Batch stride for alpha vector.\n\n Used together with CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_HOST when matrix D's\n CUBLASLT_MATRIX_LAYOUT_BATCH_COUNT > 1. If CUBLASLT_POINTER_MODE_ALPHA_DEVICE_VECTOR_BETA_ZERO is set then\n CUBLASLT_MATMUL_DESC_ALPHA_VECTOR_BATCH_STRIDE must be set to 0 as this mode doesnt supported batched alpha vector.\n\n int64_t, default: 0"] + pub const CUBLASLT_MATMUL_DESC_ALPHA_VECTOR_BATCH_STRIDE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(14); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Number of SMs to target for parallel execution. Optimizes heuristics for execution on a different number of SMs\n when user expects a concurrent stream to be using some of the device resources.\n\n int32_t, default: 0 - use the number reported by the device."] + pub const CUBLASLT_MATMUL_DESC_SM_COUNT_TARGET: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(15); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the scale factor value that converts data in matrix A to the compute data type range.\n\n The scaling factor value must have the same type as the compute type.\n\n If not specified, or set to NULL, the scaling factor is assumed to be 1.\n\n If set for an unsupported matrix data, scale, and compute type combination, calling cublasLtMatmul()\n will return CUBLAS_INVALID_VALUE.\n\n const void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_A_SCALE_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(17); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the scale factor value to convert data in matrix B to compute data type range.\n\n The scaling factor value must have the same type as the compute type.\n\n If not specified, or set to NULL, the scaling factor is assumed to be 1.\n\n If set for an unsupported matrix data, scale, and compute type combination, calling cublasLtMatmul()\n will return CUBLAS_INVALID_VALUE.\n\n const void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_B_SCALE_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(18); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the scale factor value to convert data in matrix C to compute data type range.\n\n The scaling factor value must have the same type as the compute type.\n\n If not specified, or set to NULL, the scaling factor is assumed to be 1.\n\n If set for an unsupported matrix data, scale, and compute type combination, calling cublasLtMatmul()\n will return CUBLAS_INVALID_VALUE.\n\n const void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_C_SCALE_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(19); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the scale factor value to convert data in matrix D to compute data type range.\n\n The scaling factor value must have the same type as the compute type.\n\n If not specified, or set to NULL, the scaling factor is assumed to be 1.\n\n If set for an unsupported matrix data, scale, and compute type combination, calling cublasLtMatmul()\n will return CUBLAS_INVALID_VALUE.\n\n const void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_D_SCALE_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(20); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the memory location that on completion will be set to the maximum of absolute values in the\n output matrix.\n\n The computed value has the same type as the compute type.\n\n If not specified or set to NULL, the maximum absolute value is not computed. If set for an unsupported matrix\n data, scale, and compute type combination, calling cublasLtMatmul() will return CUBLAS_INVALID_VALUE.\n\n void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_AMAX_D_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(21); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Type of the data to be stored to the memory pointed to by CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER.\n\n If unset, the data type defaults to the type of elements of the output matrix with some exceptions, see details\n below.\n\n ReLu uses a bit-mask.\n\n GELU input matrix elements type is the same as the type of elements of\n the output matrix with some exceptions, see details below.\n\n For fp8 kernels with output type CUDA_R_8F_E4M3 the aux data type can be CUDA_R_8F_E4M3 or CUDA_R_16F with some\n restrictions. See https://docs.nvidia.com/cuda/cublas/index.html#cublasLtMatmulDescAttributes_t for more details.\n\n If set for an unsupported matrix data, scale, and compute type combination, calling cublasLtMatmul()\n will return CUBLAS_INVALID_VALUE.\n\n int32_t based on cudaDataType, default: -1"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_DATA_TYPE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(22); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the scaling factor value to convert results from compute type data range to storage\n data range in the auxiliary matrix that is set via CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER.\n\n The scaling factor value must have the same type as the compute type.\n\n If not specified, or set to NULL, the scaling factor is assumed to be 1. If set for an unsupported matrix data,\n scale, and compute type combination, calling cublasLtMatmul() will return CUBLAS_INVALID_VALUE.\n\n void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_SCALE_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(23); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Device pointer to the memory location that on completion will be set to the maximum of absolute values in the\n buffer that is set via CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER.\n\n The computed value has the same type as the compute type.\n\n If not specified or set to NULL, the maximum absolute value is not computed. If set for an unsupported matrix\n data, scale, and compute type combination, calling cublasLtMatmul() will return CUBLAS_INVALID_VALUE.\n\n void *, default: NULL"] + pub const CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_AMAX_POINTER: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(24); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Flag for managing fp8 fast accumulation mode.\n When enabled, problem execution might be faster but at the cost of lower accuracy because intermediate results\n will not periodically be promoted to a higher precision.\n\n int8_t, default: 0 - fast accumulation mode is disabled."] + pub const CUBLASLT_MATMUL_DESC_FAST_ACCUM: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(25); +} +impl cublasLtMatmulDescAttributes_t { + #[doc = " Type of bias or bias gradient vector in the device memory.\n\n Bias case: see CUBLASLT_EPILOGUE_BIAS.\n\n Bias vector elements are the same type as the elements of output matrix (Dtype) with the following exceptions:\n - IMMA kernels with computeType=CUDA_R_32I and Ctype=CUDA_R_8I where the bias vector elements\n are the same type as alpha, beta (CUBLASLT_MATMUL_DESC_SCALE_TYPE=CUDA_R_32F)\n - fp8 kernels with an output type of CUDA_R_32F, CUDA_R_8F_E4M3 or CUDA_R_8F_E5M2, See\n https://docs.nvidia.com/cuda/cublas/index.html#cublasLtMatmul for details.\n\n int32_t based on cudaDataType, default: -1"] + pub const CUBLASLT_MATMUL_DESC_BIAS_DATA_TYPE: cublasLtMatmulDescAttributes_t = + cublasLtMatmulDescAttributes_t(26); +} +#[repr(transparent)] +#[doc = " Matmul descriptor attributes to define details of the operation."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulDescAttributes_t(pub ::std::os::raw::c_uint); + +#[doc = " Internal. Do not use directly."] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulDescInit_internal( + matmulDesc: cublasLtMatmulDesc_t, + size: usize, + computeType: cublasComputeType_t, + scaleType: cudaDataType_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Create new matmul operation descriptor.\n\n \\retval CUBLAS_STATUS_ALLOC_FAILED if memory could not be allocated\n \\retval CUBLAS_STATUS_SUCCESS if desciptor was created successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulDescCreate( + matmulDesc: *mut cublasLtMatmulDesc_t, + computeType: cublasComputeType_t, + scaleType: cudaDataType_t, +) -> cublasStatus_t { + crate::matmul_desc_create(matmulDesc, computeType, scaleType) +} + +#[doc = " Destroy matmul operation descriptor.\n\n \\retval CUBLAS_STATUS_SUCCESS if operation was successful"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulDescDestroy( + matmulDesc: cublasLtMatmulDesc_t, +) -> cublasStatus_t { + crate::matmul_desc_destroy(matmulDesc) +} + +#[doc = " Set matmul operation descriptor attribute.\n\n \\param[in] matmulDesc The descriptor\n \\param[in] attr The attribute\n \\param[in] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulDescSetAttribute( + matmulDesc: cublasLtMatmulDesc_t, + attr: cublasLtMatmulDescAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, +) -> cublasStatus_t { + crate::matmul_desc_set_attribute(matmulDesc, attr, buf, sizeInBytes) +} + +#[doc = " Get matmul operation descriptor attribute.\n\n \\param[in] matmulDesc The descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number of\n bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulDescGetAttribute( + matmulDesc: cublasLtMatmulDesc_t, + attr: cublasLtMatmulDescAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::matmul_desc_get_attribute(matmulDesc, attr, buf, sizeInBytes, sizeWritten) +} +impl cublasLtMatrixTransformDescAttributes_t { + #[doc = " Scale type, see cudaDataType. Inputs are converted to scale type for scaling and summation and results are then\n converted to output type to store in memory.\n\n int32_t"] + pub const CUBLASLT_MATRIX_TRANSFORM_DESC_SCALE_TYPE: cublasLtMatrixTransformDescAttributes_t = + cublasLtMatrixTransformDescAttributes_t(0); +} +impl cublasLtMatrixTransformDescAttributes_t { + #[doc = " Pointer mode of alpha and beta, see cublasLtPointerMode_t.\n\n int32_t, default: CUBLASLT_POINTER_MODE_HOST"] + pub const CUBLASLT_MATRIX_TRANSFORM_DESC_POINTER_MODE: cublasLtMatrixTransformDescAttributes_t = + cublasLtMatrixTransformDescAttributes_t(1); +} +impl cublasLtMatrixTransformDescAttributes_t { + #[doc = " Transform of matrix A, see cublasOperation_t.\n\n int32_t, default: CUBLAS_OP_N"] + pub const CUBLASLT_MATRIX_TRANSFORM_DESC_TRANSA: cublasLtMatrixTransformDescAttributes_t = + cublasLtMatrixTransformDescAttributes_t(2); +} +impl cublasLtMatrixTransformDescAttributes_t { + #[doc = " Transform of matrix B, see cublasOperation_t.\n\n int32_t, default: CUBLAS_OP_N"] + pub const CUBLASLT_MATRIX_TRANSFORM_DESC_TRANSB: cublasLtMatrixTransformDescAttributes_t = + cublasLtMatrixTransformDescAttributes_t(3); +} +#[repr(transparent)] +#[doc = " Matrix transform descriptor attributes to define details of the operation."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatrixTransformDescAttributes_t(pub ::std::os::raw::c_uint); + +#[doc = " Internal. Do not use directly."] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransformDescInit_internal( + transformDesc: cublasLtMatrixTransformDesc_t, + size: usize, + scaleType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Create new matrix transform operation descriptor.\n\n \\retval CUBLAS_STATUS_ALLOC_FAILED if memory could not be allocated\n \\retval CUBLAS_STATUS_SUCCESS if desciptor was created successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransformDescCreate( + transformDesc: *mut cublasLtMatrixTransformDesc_t, + scaleType: cudaDataType, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Destroy matrix transform operation descriptor.\n\n \\retval CUBLAS_STATUS_SUCCESS if operation was successful"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransformDescDestroy( + transformDesc: cublasLtMatrixTransformDesc_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Set matrix transform operation descriptor attribute.\n\n \\param[in] transformDesc The descriptor\n \\param[in] attr The attribute\n \\param[in] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransformDescSetAttribute( + transformDesc: cublasLtMatrixTransformDesc_t, + attr: cublasLtMatrixTransformDescAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Get matrix transform operation descriptor attribute.\n\n \\param[in] transformDesc The descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number\n of bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatrixTransformDescGetAttribute( + transformDesc: cublasLtMatrixTransformDesc_t, + attr: cublasLtMatrixTransformDescAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} +impl cublasLt3mMode_t { + pub const CUBLASLT_3M_MODE_DISALLOWED: cublasLt3mMode_t = cublasLt3mMode_t(0); +} +impl cublasLt3mMode_t { + pub const CUBLASLT_3M_MODE_ALLOWED: cublasLt3mMode_t = cublasLt3mMode_t(1); +} +#[repr(transparent)] +#[doc = " For computation with complex numbers, this enum allows to apply the Gauss Complexity reduction algorithm"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLt3mMode_t(pub ::std::os::raw::c_uint); +impl cublasLtReductionScheme_t { + #[doc = " No reduction scheme, dot-product shall be performed in one sequence."] + pub const CUBLASLT_REDUCTION_SCHEME_NONE: cublasLtReductionScheme_t = + cublasLtReductionScheme_t(0); +} +impl cublasLtReductionScheme_t { + #[doc = " Reduction is performed \"in place\" - using the output buffer (and output data type) and counters (in workspace) to\n guarantee the sequentiality."] + pub const CUBLASLT_REDUCTION_SCHEME_INPLACE: cublasLtReductionScheme_t = + cublasLtReductionScheme_t(1); +} +impl cublasLtReductionScheme_t { + #[doc = " Intermediate results are stored in compute type in the workspace and reduced in a separate step."] + pub const CUBLASLT_REDUCTION_SCHEME_COMPUTE_TYPE: cublasLtReductionScheme_t = + cublasLtReductionScheme_t(2); +} +impl cublasLtReductionScheme_t { + #[doc = " Intermediate results are stored in output type in the workspace and reduced in a separate step."] + pub const CUBLASLT_REDUCTION_SCHEME_OUTPUT_TYPE: cublasLtReductionScheme_t = + cublasLtReductionScheme_t(4); +} +impl cublasLtReductionScheme_t { + #[doc = " Intermediate results are stored in output type in the workspace and reduced in a separate step."] + pub const CUBLASLT_REDUCTION_SCHEME_MASK: cublasLtReductionScheme_t = + cublasLtReductionScheme_t(7); +} +#[repr(transparent)] +#[doc = " Reduction scheme for portions of the dot-product calculated in parallel (a. k. a. \"split - K\")."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtReductionScheme_t(pub ::std::os::raw::c_uint); +impl cublasLtEpilogue_t { + #[doc = " No special postprocessing, just scale and quantize results if necessary."] + pub const CUBLASLT_EPILOGUE_DEFAULT: cublasLtEpilogue_t = cublasLtEpilogue_t(1); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu, apply ReLu point-wise transform to the results (x:=max(x, 0))."] + pub const CUBLASLT_EPILOGUE_RELU: cublasLtEpilogue_t = cublasLtEpilogue_t(2); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu, apply ReLu point-wise transform to the results (x:=max(x, 0)).\n\n This epilogue mode produces an extra output, a ReLu bit-mask matrix,\n see CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_RELU_AUX: cublasLtEpilogue_t = cublasLtEpilogue_t(130); +} +impl cublasLtEpilogue_t { + #[doc = " Bias, apply (broadcasted) Bias from bias vector. Bias vector length must match matrix D rows, it must be packed\n (stride between vector elements is 1). Bias vector is broadcasted to all columns and added before applying final\n postprocessing."] + pub const CUBLASLT_EPILOGUE_BIAS: cublasLtEpilogue_t = cublasLtEpilogue_t(4); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu and Bias, apply Bias and then ReLu transform"] + pub const CUBLASLT_EPILOGUE_RELU_BIAS: cublasLtEpilogue_t = cublasLtEpilogue_t(6); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu and Bias, apply Bias and then ReLu transform\n\n This epilogue mode produces an extra output, a ReLu bit-mask matrix,\n see CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_RELU_AUX_BIAS: cublasLtEpilogue_t = cublasLtEpilogue_t(134); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu and Bias, apply Bias and then ReLu transform\n\n This epilogue mode produces an extra output, a ReLu bit-mask matrix,\n see CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_DRELU: cublasLtEpilogue_t = cublasLtEpilogue_t(136); +} +impl cublasLtEpilogue_t { + #[doc = " ReLu and Bias, apply Bias and then ReLu transform\n\n This epilogue mode produces an extra output, a ReLu bit-mask matrix,\n see CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_DRELU_BGRAD: cublasLtEpilogue_t = cublasLtEpilogue_t(152); +} +impl cublasLtEpilogue_t { + #[doc = " GELU, apply GELU point-wise transform to the results (x:=GELU(x))."] + pub const CUBLASLT_EPILOGUE_GELU: cublasLtEpilogue_t = cublasLtEpilogue_t(32); +} +impl cublasLtEpilogue_t { + #[doc = " GELU, apply GELU point-wise transform to the results (x:=GELU(x)).\n\n This epilogue mode outputs GELU input as a separate matrix (useful for training).\n See CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_GELU_AUX: cublasLtEpilogue_t = cublasLtEpilogue_t(160); +} +impl cublasLtEpilogue_t { + #[doc = " GELU and Bias, apply Bias and then GELU transform"] + pub const CUBLASLT_EPILOGUE_GELU_BIAS: cublasLtEpilogue_t = cublasLtEpilogue_t(36); +} +impl cublasLtEpilogue_t { + #[doc = " GELU and Bias, apply Bias and then GELU transform\n\n This epilogue mode outputs GELU input as a separate matrix (useful for training).\n See CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_GELU_AUX_BIAS: cublasLtEpilogue_t = cublasLtEpilogue_t(164); +} +impl cublasLtEpilogue_t { + #[doc = " GELU and Bias, apply Bias and then GELU transform\n\n This epilogue mode outputs GELU input as a separate matrix (useful for training).\n See CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_DGELU: cublasLtEpilogue_t = cublasLtEpilogue_t(192); +} +impl cublasLtEpilogue_t { + #[doc = " GELU and Bias, apply Bias and then GELU transform\n\n This epilogue mode outputs GELU input as a separate matrix (useful for training).\n See CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_POINTER."] + pub const CUBLASLT_EPILOGUE_DGELU_BGRAD: cublasLtEpilogue_t = cublasLtEpilogue_t(208); +} +impl cublasLtEpilogue_t { + #[doc = " Bias gradient based on the input matrix A.\n\n The bias size corresponds to the number of rows of the matrix D.\n The reduction happens over the GEMM's \"k\" dimension.\n\n Stores Bias gradient in the auxiliary output\n (see CUBLASLT_MATMUL_DESC_BIAS_POINTER)."] + pub const CUBLASLT_EPILOGUE_BGRADA: cublasLtEpilogue_t = cublasLtEpilogue_t(256); +} +impl cublasLtEpilogue_t { + #[doc = " Bias gradient based on the input matrix B.\n\n The bias size corresponds to the number of columns of the matrix D.\n The reduction happens over the GEMM's \"k\" dimension.\n\n Stores Bias gradient in the auxiliary output\n (see CUBLASLT_MATMUL_DESC_BIAS_POINTER)."] + pub const CUBLASLT_EPILOGUE_BGRADB: cublasLtEpilogue_t = cublasLtEpilogue_t(512); +} +#[repr(transparent)] +#[doc = " Postprocessing options for the epilogue"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtEpilogue_t(pub ::std::os::raw::c_uint); +impl cublasLtMatmulSearch_t { + #[doc = " ask heuristics for best algo for given usecase"] + pub const CUBLASLT_SEARCH_BEST_FIT: cublasLtMatmulSearch_t = cublasLtMatmulSearch_t(0); +} +impl cublasLtMatmulSearch_t { + #[doc = " only try to find best config for preconfigured algo id"] + pub const CUBLASLT_SEARCH_LIMITED_BY_ALGO_ID: cublasLtMatmulSearch_t = + cublasLtMatmulSearch_t(1); +} +impl cublasLtMatmulSearch_t { + #[doc = " reserved for future use"] + pub const CUBLASLT_SEARCH_RESERVED_02: cublasLtMatmulSearch_t = cublasLtMatmulSearch_t(2); +} +impl cublasLtMatmulSearch_t { + #[doc = " reserved for future use"] + pub const CUBLASLT_SEARCH_RESERVED_03: cublasLtMatmulSearch_t = cublasLtMatmulSearch_t(3); +} +impl cublasLtMatmulSearch_t { + #[doc = " reserved for future use"] + pub const CUBLASLT_SEARCH_RESERVED_04: cublasLtMatmulSearch_t = cublasLtMatmulSearch_t(4); +} +impl cublasLtMatmulSearch_t { + #[doc = " reserved for future use"] + pub const CUBLASLT_SEARCH_RESERVED_05: cublasLtMatmulSearch_t = cublasLtMatmulSearch_t(5); +} +#[repr(transparent)] +#[doc = " Matmul heuristic search mode"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulSearch_t(pub ::std::os::raw::c_uint); +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Search mode, see cublasLtMatmulSearch_t.\n\n uint32_t, default: CUBLASLT_SEARCH_BEST_FIT"] + pub const CUBLASLT_MATMUL_PREF_SEARCH_MODE: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(0); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Maximum allowed workspace size in bytes.\n\n uint64_t, default: 0 - no workspace allowed"] + pub const CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(1); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Math mode mask, see cublasMath_t.\n\n Only algorithms with CUBLASLT_ALGO_CAP_MATHMODE_IMPL that is not masked out by this attribute are allowed.\n\n uint32_t, default: 1 (allows both default and tensor op math)\n DEPRECATED, will be removed in a future release, see cublasLtNumericalImplFlags_t for replacement"] + pub const CUBLASLT_MATMUL_PREF_MATH_MODE_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(2); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Reduction scheme mask, see cublasLtReductionScheme_t. Filters heuristic result to only include algo configs that\n use one of the required modes.\n\n E.g. mask value of 0x03 will allow only INPLACE and COMPUTE_TYPE reduction schemes.\n\n uint32_t, default: CUBLASLT_REDUCTION_SCHEME_MASK (allows all reduction schemes)"] + pub const CUBLASLT_MATMUL_PREF_REDUCTION_SCHEME_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(3); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Gaussian mode mask, see cublasLt3mMode_t.\n\n Only algorithms with CUBLASLT_ALGO_CAP_GAUSSIAN_IMPL that is not masked out by this attribute are allowed.\n\n uint32_t, default: CUBLASLT_3M_MODE_ALLOWED (allows both gaussian and non-gaussian algorithms)\n DEPRECATED, will be removed in a future release, see cublasLtNumericalImplFlags_t for replacement"] + pub const CUBLASLT_MATMUL_PREF_GAUSSIAN_MODE_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(4); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Minimum buffer alignment for matrix A (in bytes).\n\n Selecting a smaller value will exclude algorithms that can not work with matrix A that is not as strictly aligned\n as they need.\n\n uint32_t, default: 256"] + pub const CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_A_BYTES: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(5); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Minimum buffer alignment for matrix B (in bytes).\n\n Selecting a smaller value will exclude algorithms that can not work with matrix B that is not as strictly aligned\n as they need.\n\n uint32_t, default: 256"] + pub const CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_B_BYTES: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(6); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Minimum buffer alignment for matrix C (in bytes).\n\n Selecting a smaller value will exclude algorithms that can not work with matrix C that is not as strictly aligned\n as they need.\n\n uint32_t, default: 256"] + pub const CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_C_BYTES: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(7); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Minimum buffer alignment for matrix D (in bytes).\n\n Selecting a smaller value will exclude algorithms that can not work with matrix D that is not as strictly aligned\n as they need.\n\n uint32_t, default: 256"] + pub const CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_D_BYTES: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(8); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Maximum wave count.\n\n See cublasLtMatmulHeuristicResult_t::wavesCount.\n\n Selecting a non-zero value will exclude algorithms that report device utilization higher than specified.\n\n float, default: 0.0f"] + pub const CUBLASLT_MATMUL_PREF_MAX_WAVES_COUNT: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(9); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Pointer mode mask, see cublasLtPointerModeMask_t. Filters heuristic result to only include algorithms that support\n all required modes.\n\n uint32_t, default: (CUBLASLT_POINTER_MODE_MASK_HOST | CUBLASLT_POINTER_MODE_MASK_DEVICE) (only allows algorithms\n that support both regular host and device pointers)"] + pub const CUBLASLT_MATMUL_PREF_POINTER_MODE_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(10); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Epilogue selector mask, see cublasLtEpilogue_t. Filters heuristic result to only include algorithms that support\n all required operations.\n\n uint32_t, default: CUBLASLT_EPILOGUE_DEFAULT (only allows algorithms that support default epilogue)"] + pub const CUBLASLT_MATMUL_PREF_EPILOGUE_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(11); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Numerical implementation details mask, see cublasLtNumericalImplFlags_t. Filters heuristic result to only include\n algorithms that use the allowed implementations.\n\n uint64_t, default: uint64_t(-1) (allow everything)"] + pub const CUBLASLT_MATMUL_PREF_IMPL_MASK: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(12); +} +impl cublasLtMatmulPreferenceAttributes_t { + #[doc = " Number of SMs to target for parallel execution. Optimizes heuristics for execution on a different number of SMs\n when user expects a concurrent stream to be using some of the device resources.\n\n Overrides the SM count target set in the matrix multiplication descriptor (see cublasLtMatmulDescAttributes_t).\n\n int32_t, default: 0 - use the number reported by the device.\n DEPRECATED, will be removed in a future release, see cublasLtMatmulDescAttributes_t for replacement"] + pub const CUBLASLT_MATMUL_PREF_SM_COUNT_TARGET: cublasLtMatmulPreferenceAttributes_t = + cublasLtMatmulPreferenceAttributes_t(13); +} +#[repr(transparent)] +#[doc = " Algo search preference to fine tune the heuristic function."] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulPreferenceAttributes_t(pub ::std::os::raw::c_uint); + +#[doc = " Internal. Do not use directly."] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulPreferenceInit_internal( + pref: cublasLtMatmulPreference_t, + size: usize, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Create new matmul heuristic search preference descriptor.\n\n \\retval CUBLAS_STATUS_ALLOC_FAILED if memory could not be allocated\n \\retval CUBLAS_STATUS_SUCCESS if desciptor was created successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulPreferenceCreate( + pref: *mut cublasLtMatmulPreference_t, +) -> cublasStatus_t { + crate::matmul_preference_create(pref) +} + +#[doc = " Destroy matmul heuristic search preference descriptor.\n\n \\retval CUBLAS_STATUS_SUCCESS if operation was successful"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulPreferenceDestroy( + pref: cublasLtMatmulPreference_t, +) -> cublasStatus_t { + crate::matmul_preference_destroy(pref) +} + +#[doc = " Set matmul heuristic search preference descriptor attribute.\n\n \\param[in] pref The descriptor\n \\param[in] attr The attribute\n \\param[in] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulPreferenceSetAttribute( + pref: cublasLtMatmulPreference_t, + attr: cublasLtMatmulPreferenceAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, +) -> cublasStatus_t { + crate::matmul_preference_set_attribute(pref, attr, buf, sizeInBytes) +} + +#[doc = " Get matmul heuristic search preference descriptor attribute.\n\n \\param[in] pref The descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number of\n bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulPreferenceGetAttribute( + pref: cublasLtMatmulPreference_t, + attr: cublasLtMatmulPreferenceAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} +#[doc = " Results structure used by cublasLtMatmulGetAlgo.\n\n Holds returned configured algo descriptor and its runtime properties."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cublasLtMatmulHeuristicResult_t { + #[doc = " Matmul algorithm descriptor.\n\n Must be initialized with cublasLtMatmulAlgoInit() if preferences' CUBLASLT_MATMUL_PERF_SEARCH_MODE is set to\n CUBLASLT_SEARCH_LIMITED_BY_ALGO_ID"] + pub algo: cublasLtMatmulAlgo_t, + #[doc = " Actual size of workspace memory required."] + pub workspaceSize: usize, + #[doc = " Result status, other fields are only valid if after call to cublasLtMatmulAlgoGetHeuristic() this member is set to\n CUBLAS_STATUS_SUCCESS."] + pub state: cublasStatus_t, + #[doc = " Waves count - a device utilization metric.\n\n wavesCount value of 1.0f suggests that when kernel is launched it will fully occupy the GPU."] + pub wavesCount: f32, + pub reserved: [::std::os::raw::c_int; 4usize], +} + +#[doc = " Query cublasLt heuristic for algorithm appropriate for given use case.\n\n \\param[in] lightHandle Pointer to the allocated cuBLASLt handle for the cuBLASLt\n context. See cublasLtHandle_t.\n \\param[in] operationDesc Handle to the matrix multiplication descriptor.\n \\param[in] Adesc Handle to the layout descriptors for matrix A.\n \\param[in] Bdesc Handle to the layout descriptors for matrix B.\n \\param[in] Cdesc Handle to the layout descriptors for matrix C.\n \\param[in] Ddesc Handle to the layout descriptors for matrix D.\n \\param[in] preference Pointer to the structure holding the heuristic search\n preferences descriptor. See cublasLtMatrixLayout_t.\n \\param[in] requestedAlgoCount Size of heuristicResultsArray (in elements) and requested\n maximum number of algorithms to return.\n \\param[in, out] heuristicResultsArray Output algorithms and associated runtime characteristics,\n ordered in increasing estimated compute time.\n \\param[out] returnAlgoCount The number of heuristicResultsArray elements written.\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if requestedAlgoCount is less or equal to zero\n \\retval CUBLAS_STATUS_NOT_SUPPORTED if no heuristic function available for current configuration\n \\retval CUBLAS_STATUS_SUCCESS if query was successful, inspect\n heuristicResultsArray[0 to (returnAlgoCount - 1)].state\n for detail status of results"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoGetHeuristic( + lightHandle: cublasLtHandle_t, + operationDesc: cublasLtMatmulDesc_t, + Adesc: cublasLtMatrixLayout_t, + Bdesc: cublasLtMatrixLayout_t, + Cdesc: cublasLtMatrixLayout_t, + Ddesc: cublasLtMatrixLayout_t, + preference: cublasLtMatmulPreference_t, + requestedAlgoCount: ::std::os::raw::c_int, + heuristicResultsArray: *mut cublasLtMatmulHeuristicResult_t, + returnAlgoCount: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::matmul_algo_get_heuristic( + lightHandle, + operationDesc, + Adesc, + Bdesc, + Cdesc, + Ddesc, + preference, + requestedAlgoCount, + heuristicResultsArray, + returnAlgoCount, + ) +} + +#[doc = " Routine to get all algo IDs that can potentially run\n\n \\param[in] int requestedAlgoCount requested number of algos (must be less or equal to size of algoIdsA\n (in elements)) \\param[out] algoIdsA array to write algoIds to \\param[out] returnAlgoCount number of algoIds\n actually written\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if requestedAlgoCount is less or equal to zero\n \\retval CUBLAS_STATUS_SUCCESS if query was successful, inspect returnAlgoCount to get actual number of IDs\n available"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoGetIds( + lightHandle: cublasLtHandle_t, + computeType: cublasComputeType_t, + scaleType: cudaDataType_t, + Atype: cudaDataType_t, + Btype: cudaDataType_t, + Ctype: cudaDataType_t, + Dtype: cudaDataType_t, + requestedAlgoCount: ::std::os::raw::c_int, + algoIdsArray: *mut ::std::os::raw::c_int, + returnAlgoCount: *mut ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Initialize algo structure\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if algo is NULL or algoId is outside of recognized range\n \\retval CUBLAS_STATUS_NOT_SUPPORTED if algoId is not supported for given combination of data types\n \\retval CUBLAS_STATUS_SUCCESS if the structure was successfully initialized"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoInit( + lightHandle: cublasLtHandle_t, + computeType: cublasComputeType_t, + scaleType: cudaDataType_t, + Atype: cudaDataType_t, + Btype: cudaDataType_t, + Ctype: cudaDataType_t, + Dtype: cudaDataType_t, + algoId: ::std::os::raw::c_int, + algo: *mut cublasLtMatmulAlgo_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Check configured algo descriptor for correctness and support on current device.\n\n Result includes required workspace size and calculated wave count.\n\n CUBLAS_STATUS_SUCCESS doesn't fully guarantee algo will run (will fail if e.g. buffers are not correctly aligned);\n but if cublasLtMatmulAlgoCheck fails, the algo will not run.\n\n \\param[in] algo algo configuration to check\n \\param[out] result result structure to report algo runtime characteristics; algo field is never updated\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if matrix layout descriptors or operation descriptor don't match algo\n descriptor\n \\retval CUBLAS_STATUS_NOT_SUPPORTED if algo configuration or data type combination is not currently supported on\n given device\n \\retval CUBLAS_STATUS_ARCH_MISMATCH if algo configuration cannot be run using the selected device\n \\retval CUBLAS_STATUS_SUCCESS if check was successful"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoCheck( + lightHandle: cublasLtHandle_t, + operationDesc: cublasLtMatmulDesc_t, + Adesc: cublasLtMatrixLayout_t, + Bdesc: cublasLtMatrixLayout_t, + Cdesc: cublasLtMatrixLayout_t, + Ddesc: cublasLtMatrixLayout_t, + algo: *const cublasLtMatmulAlgo_t, + result: *mut cublasLtMatmulHeuristicResult_t, +) -> cublasStatus_t { + crate::unsupported() +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " support for split K, see CUBLASLT_ALGO_CONFIG_SPLITK_NUM\n\n int32_t, 0 means no support, supported otherwise"] + pub const CUBLASLT_ALGO_CAP_SPLITK_SUPPORT: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(0); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " reduction scheme mask, see cublasLtReductionScheme_t; shows supported reduction schemes, if reduction scheme is\n not masked out it is supported.\n\n e.g. int isReductionSchemeComputeTypeSupported ? (reductionSchemeMask & CUBLASLT_REDUCTION_SCHEME_COMPUTE_TYPE) ==\n CUBLASLT_REDUCTION_SCHEME_COMPUTE_TYPE ? 1 : 0;\n\n uint32_t"] + pub const CUBLASLT_ALGO_CAP_REDUCTION_SCHEME_MASK: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(1); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " support for cta swizzling, see CUBLASLT_ALGO_CONFIG_CTA_SWIZZLING\n\n uint32_t, 0 means no support, 1 means supported value of 1, other values are reserved"] + pub const CUBLASLT_ALGO_CAP_CTA_SWIZZLING_SUPPORT: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(2); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " support strided batch\n\n int32_t, 0 means no support, supported otherwise"] + pub const CUBLASLT_ALGO_CAP_STRIDED_BATCH_SUPPORT: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(3); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " support results out of place (D != C in D = alpha.A.B + beta.C)\n\n int32_t, 0 means no support, supported otherwise"] + pub const CUBLASLT_ALGO_CAP_OUT_OF_PLACE_RESULT_SUPPORT: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(4); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " syrk/herk support (on top of regular gemm)\n\n int32_t, 0 means no support, supported otherwise"] + pub const CUBLASLT_ALGO_CAP_UPLO_SUPPORT: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(5); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " tile ids possible to use, see cublasLtMatmulTile_t; if no tile ids are supported use\n CUBLASLT_MATMUL_TILE_UNDEFINED\n\n use cublasLtMatmulAlgoCapGetAttribute() with sizeInBytes=0 to query actual count\n\n array of uint32_t"] + pub const CUBLASLT_ALGO_CAP_TILE_IDS: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(6); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " custom option range is from 0 to CUBLASLT_ALGO_CAP_CUSTOM_OPTION_MAX (inclusive), see\n CUBLASLT_ALGO_CONFIG_CUSTOM_OPTION\n\n int32_t"] + pub const CUBLASLT_ALGO_CAP_CUSTOM_OPTION_MAX: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(7); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " whether algorithm is using regular compute or tensor operations\n\n int32_t 0 means regular compute, 1 means tensor operations;\n DEPRECATED"] + pub const CUBLASLT_ALGO_CAP_MATHMODE_IMPL: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(8); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " whether algorithm implements gaussian optimization of complex matrix multiplication, see cublasMath_t\n\n int32_t 0 means regular compute, 1 means gaussian;\n DEPRECATED"] + pub const CUBLASLT_ALGO_CAP_GAUSSIAN_IMPL: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(9); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " whether algorithm supports custom (not COL or ROW memory order), see cublasLtOrder_t\n\n int32_t 0 means only COL and ROW memory order is allowed, non-zero means that algo might have different\n requirements;"] + pub const CUBLASLT_ALGO_CAP_CUSTOM_MEMORY_ORDER: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(10); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " bitmask enumerating pointer modes algorithm supports\n\n uint32_t, see cublasLtPointerModeMask_t"] + pub const CUBLASLT_ALGO_CAP_POINTER_MODE_MASK: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(11); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " bitmask enumerating kinds of postprocessing algorithm supports in the epilogue\n\n uint32_t, see cublasLtEpilogue_t"] + pub const CUBLASLT_ALGO_CAP_EPILOGUE_MASK: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(12); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " stages ids possible to use, see cublasLtMatmulStages_t; if no stages ids are supported use\n CUBLASLT_MATMUL_STAGES_UNDEFINED\n\n use cublasLtMatmulAlgoCapGetAttribute() with sizeInBytes=0 to query actual count\n\n array of uint32_t"] + pub const CUBLASLT_ALGO_CAP_STAGES_IDS: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(13); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " support for nagative ld for all of the matrices\n\n int32_t 0 means no support, supported otherwise"] + pub const CUBLASLT_ALGO_CAP_LD_NEGATIVE: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(14); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " details about algorithm's implementation that affect it's numerical behavior\n\n uint64_t, see cublasLtNumericalImplFlags_t"] + pub const CUBLASLT_ALGO_CAP_NUMERICAL_IMPL_FLAGS: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(15); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " minimum alignment required for A matrix in bytes\n (required for buffer pointer, leading dimension, and possibly other strides defined for matrix memory order)\n\n uint32_t"] + pub const CUBLASLT_ALGO_CAP_MIN_ALIGNMENT_A_BYTES: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(16); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " minimum alignment required for B matrix in bytes\n (required for buffer pointer, leading dimension, and possibly other strides defined for matrix memory order)\n\n uint32_t"] + pub const CUBLASLT_ALGO_CAP_MIN_ALIGNMENT_B_BYTES: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(17); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " minimum alignment required for C matrix in bytes\n (required for buffer pointer, leading dimension, and possibly other strides defined for matrix memory order)\n\n uint32_t"] + pub const CUBLASLT_ALGO_CAP_MIN_ALIGNMENT_C_BYTES: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(18); +} +impl cublasLtMatmulAlgoCapAttributes_t { + #[doc = " minimum alignment required for D matrix in bytes\n (required for buffer pointer, leading dimension, and possibly other strides defined for matrix memory order)\n\n uint32_t"] + pub const CUBLASLT_ALGO_CAP_MIN_ALIGNMENT_D_BYTES: cublasLtMatmulAlgoCapAttributes_t = + cublasLtMatmulAlgoCapAttributes_t(19); +} +#[repr(transparent)] +#[doc = " Capabilities Attributes that can be retrieved from an initialized Algo structure"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulAlgoCapAttributes_t(pub ::std::os::raw::c_uint); + +#[doc = " Get algo capability attribute.\n\n E.g. to get list of supported Tile IDs:\n cublasLtMatmulTile_t tiles[CUBLASLT_MATMUL_TILE_END];\n size_t num_tiles, size_written;\n if (cublasLtMatmulAlgoCapGetAttribute(algo, CUBLASLT_ALGO_CAP_TILE_IDS, tiles, sizeof(tiles), size_written) ==\n CUBLAS_STATUS_SUCCESS) { num_tiles = size_written / sizeof(tiles[0]);\n }\n\n \\param[in] algo The algo descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number of\n bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoCapGetAttribute( + algo: *const cublasLtMatmulAlgo_t, + attr: cublasLtMatmulAlgoCapAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " algorithm index, see cublasLtMatmulAlgoGetIds()\n\n readonly, set by cublasLtMatmulAlgoInit()\n int32_t"] + pub const CUBLASLT_ALGO_CONFIG_ID: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(0); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " tile id, see cublasLtMatmulTile_t\n\n uint32_t, default: CUBLASLT_MATMUL_TILE_UNDEFINED"] + pub const CUBLASLT_ALGO_CONFIG_TILE_ID: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(1); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " Number of K splits. If the number of K splits is greater than one, SPLITK_NUM parts\n of matrix multiplication will be computed in parallel. The results will be accumulated\n according to CUBLASLT_ALGO_CONFIG_REDUCTION_SCHEME\n\n int32_t, default: 1"] + pub const CUBLASLT_ALGO_CONFIG_SPLITK_NUM: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(2); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " reduction scheme, see cublasLtReductionScheme_t\n\n uint32_t, default: CUBLASLT_REDUCTION_SCHEME_NONE"] + pub const CUBLASLT_ALGO_CONFIG_REDUCTION_SCHEME: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(3); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " cta swizzling, change mapping from CUDA grid coordinates to parts of the matrices\n\n possible values: 0, 1, other values reserved\n\n uint32_t, default: 0"] + pub const CUBLASLT_ALGO_CONFIG_CTA_SWIZZLING: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(4); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " custom option, each algorithm can support some custom options that don't fit description of the other config\n attributes, see CUBLASLT_ALGO_CAP_CUSTOM_OPTION_MAX to get accepted range for any specific case\n\n uint32_t, default: 0"] + pub const CUBLASLT_ALGO_CONFIG_CUSTOM_OPTION: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(5); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " stages id, see cublasLtMatmulStages_t\n\n uint32_t, default: CUBLASLT_MATMUL_STAGES_UNDEFINED"] + pub const CUBLASLT_ALGO_CONFIG_STAGES_ID: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(6); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " inner shape id, see cublasLtMatmulInnerShape_t\n\n uint16_t, default: 0 (CUBLASLT_MATMUL_INNER_SHAPE_UNDEFINED)"] + pub const CUBLASLT_ALGO_CONFIG_INNER_SHAPE_ID: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(7); +} +impl cublasLtMatmulAlgoConfigAttributes_t { + #[doc = " Thread Block Cluster shape id, see cublasLtClusterShape_t. Defines cluster size to use.\n\n uint16_t, default: 0 (CUBLASLT_CLUSTER_SHAPE_AUTO)"] + pub const CUBLASLT_ALGO_CONFIG_CLUSTER_SHAPE_ID: cublasLtMatmulAlgoConfigAttributes_t = + cublasLtMatmulAlgoConfigAttributes_t(8); +} +#[repr(transparent)] +#[doc = " Algo Configuration Attributes that can be set according to the Algo capabilities"] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cublasLtMatmulAlgoConfigAttributes_t(pub ::std::os::raw::c_uint); + +#[doc = " Set algo configuration attribute.\n\n \\param[in] algo The algo descriptor\n \\param[in] attr The attribute\n \\param[in] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoConfigSetAttribute( + algo: *mut cublasLtMatmulAlgo_t, + attr: cublasLtMatmulAlgoConfigAttributes_t, + buf: *const ::std::os::raw::c_void, + sizeInBytes: usize, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Get algo configuration attribute.\n\n \\param[in] algo The algo descriptor\n \\param[in] attr The attribute\n \\param[out] buf memory address containing the new value\n \\param[in] sizeInBytes size of buf buffer for verification (in bytes)\n \\param[out] sizeWritten only valid when return value is CUBLAS_STATUS_SUCCESS. If sizeInBytes is non-zero: number of\n bytes actually written, if sizeInBytes is 0: number of bytes needed to write full contents\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if sizeInBytes is 0 and sizeWritten is NULL, or if sizeInBytes is non-zero\n and buf is NULL or sizeInBytes doesn't match size of internal storage for\n selected attribute\n \\retval CUBLAS_STATUS_SUCCESS if attribute's value was successfully written to user memory"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtMatmulAlgoConfigGetAttribute( + algo: *const cublasLtMatmulAlgo_t, + attr: cublasLtMatmulAlgoConfigAttributes_t, + buf: *mut ::std::os::raw::c_void, + sizeInBytes: usize, + sizeWritten: *mut usize, +) -> cublasStatus_t { + crate::unsupported() +} +#[doc = " Experimental: Logger callback type."] +pub type cublasLtLoggerCallback_t = ::std::option::Option< + unsafe extern "C" fn( + logLevel: ::std::os::raw::c_int, + functionName: *const ::std::os::raw::c_char, + message: *const ::std::os::raw::c_char, + ), +>; + +#[doc = " Experimental: Logger callback setter.\n\n \\param[in] callback a user defined callback function to be called by the logger\n\n \\retval CUBLAS_STATUS_SUCCESS if callback was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtLoggerSetCallback( + callback: cublasLtLoggerCallback_t, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Experimental: Open log file.\n\n \\param[in] logFile log file path. if the log file does not exist, it will be created\n\n \\retval CUBLAS_STATUS_SUCCESS if log file was created successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtLoggerOpenFile( + logFile: *const ::std::os::raw::c_char, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Experimental: Log level setter.\n\n \\param[in] level log level, should be one of the following:\n 0. Off\n 1. Errors\n 2. Performance Trace\n 3. Performance Hints\n 4. Heuristics Trace\n 5. API Trace\n\n \\retval CUBLAS_STATUS_INVALID_VALUE if log level is not one of the above levels\n\n \\retval CUBLAS_STATUS_SUCCESS if log level was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtLoggerSetLevel( + level: ::std::os::raw::c_int, +) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Experimental: Log mask setter.\n\n \\param[in] mask log mask, should be a combination of the following masks:\n 0. Off\n 1. Errors\n 2. Performance Trace\n 4. Performance Hints\n 8. Heuristics Trace\n 16. API Trace\n\n \\retval CUBLAS_STATUS_SUCCESS if log mask was set successfully"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtLoggerSetMask(mask: ::std::os::raw::c_int) -> cublasStatus_t { + crate::unsupported() +} + +#[doc = " Experimental: Disable logging for the entire session.\n\n \\retval CUBLAS_STATUS_SUCCESS if disabled logging"] +#[no_mangle] +pub unsafe extern "system" fn cublasLtLoggerForceDisable() -> cublasStatus_t { + crate::unsupported() +} diff --git a/zluda_blaslt/src/lib.rs b/zluda_blaslt/src/lib.rs new file mode 100644 index 0000000..26d7eeb --- /dev/null +++ b/zluda_blaslt/src/lib.rs @@ -0,0 +1,313 @@ +#[allow(warnings)] +mod cublaslt; +use std::ptr; + +pub use cublaslt::*; + +use hipblaslt_sys::*; + +#[cfg(debug_assertions)] +pub(crate) fn unsupported() -> cublasStatus_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unsupported() -> cublasStatus_t { + cublasStatus_t::CUBLAS_STATUS_NOT_SUPPORTED +} + +// Not in the headers, but exported by library and used (by cuBLAS?) +#[no_mangle] +pub unsafe extern "system" fn cublasLtCtxInit( + _arg1: usize, + _arg2: usize, + _arg3: usize, + _arg4: usize, + _arg5: usize, + _arg6: usize, +) -> cublasStatus_t { + cublasStatus_t::CUBLAS_STATUS_SUCCESS +} + +unsafe fn create(handle: *mut cublasLtHandle_t) -> cublasStatus_t { + to_cuda(hipblasLtCreate(handle.cast())) +} + +fn to_cuda(result: hipblasStatus_t) -> cublasStatus_t { + match result { + hipblasStatus_t::HIPBLAS_STATUS_SUCCESS => cublasStatus_t::CUBLAS_STATUS_SUCCESS, + _ => cublasStatus_t::CUBLAS_STATUS_INVALID_VALUE, + } +} + +fn get_version() -> usize { + 111103 +} + +unsafe fn matmul( + light_handle: *mut cublasLtContext, + compute_desc: *mut cublasLtMatmulDescOpaque_t, + alpha: *const std::ffi::c_void, + a: *const std::ffi::c_void, + adesc: *mut cublasLtMatrixLayoutOpaque_t, + b: *const std::ffi::c_void, + bdesc: *mut cublasLtMatrixLayoutOpaque_t, + beta: *const std::ffi::c_void, + c: *const std::ffi::c_void, + cdesc: *mut cublasLtMatrixLayoutOpaque_t, + d: *mut std::ffi::c_void, + ddesc: *mut cublasLtMatrixLayoutOpaque_t, + algo: *const cublasLtMatmulAlgo_t, + workspace: *mut std::ffi::c_void, + workspace_size_in_bytes: usize, + stream: *mut CUstream_st, +) -> cublasStatus_t { + let stream = to_stream(stream); + to_cuda(hipblasLtMatmul( + light_handle.cast(), + compute_desc.cast(), + alpha, + a, + adesc.cast(), + b, + bdesc.cast(), + beta, + c, + cdesc.cast(), + d, + ddesc.cast(), + algo.cast(), + workspace, + workspace_size_in_bytes, + stream, + )) +} + +unsafe fn to_stream(stream: cudaStream_t) -> hipStream_t { + use cuda_types::*; + let lib = hip_common::zluda_ext::get_cuda_library().unwrap(); + let cu_get_export_table = lib + .get:: CUresult>(b"cuGetExportTable\0") + .unwrap(); + let mut export_table = ptr::null(); + let error = (cu_get_export_table)(&mut export_table, &zluda_dark_api::ZludaExt::GUID); + assert_eq!(error, CUresult::CUDA_SUCCESS); + let zluda_ext = zluda_dark_api::ZludaExt::new(export_table); + let maybe_hip_stream: Result<_, _> = zluda_ext.get_hip_stream(stream as _).into(); + maybe_hip_stream.unwrap() as _ +} + +unsafe fn matmul_algo_get_heuristic( + light_handle: *mut cublasLtContext, + operation_desc: *mut cublasLtMatmulDescOpaque_t, + adesc: *mut cublasLtMatrixLayoutOpaque_t, + bdesc: *mut cublasLtMatrixLayoutOpaque_t, + cdesc: *mut cublasLtMatrixLayoutOpaque_t, + ddesc: *mut cublasLtMatrixLayoutOpaque_t, + preference: *mut cublasLtMatmulPreferenceOpaque_t, + requested_algo_count: i32, + heuristic_results_array: *mut cublasLtMatmulHeuristicResult_t, + return_algo_count: *mut i32, +) -> cublasStatus_t { + to_cuda(hipblasLtMatmulAlgoGetHeuristic( + light_handle.cast(), + operation_desc.cast(), + adesc.cast(), + bdesc.cast(), + cdesc.cast(), + ddesc.cast(), + preference.cast(), + requested_algo_count, + heuristic_results_array.cast(), + return_algo_count, + )) +} + +unsafe fn matmul_desc_create( + matmul_desc: *mut *mut cublasLtMatmulDescOpaque_t, + compute_type: cublasComputeType_t, + scale_type: cudaDataType_t, +) -> cublasStatus_t { + if compute_type != cublasComputeType_t::CUBLAS_COMPUTE_32F { + return cublasStatus_t::CUBLAS_STATUS_NOT_SUPPORTED; + } + let scale_type = data_type(scale_type); + to_cuda(hipblasLtMatmulDescCreate( + matmul_desc.cast(), + hipblasLtComputeType_t::HIPBLASLT_COMPUTE_F32, + scale_type, + )) +} + +fn data_type(data_type: cudaDataType_t) -> hipblasDatatype_t { + match data_type { + cudaDataType_t::CUDA_R_16F => hipblasDatatype_t::HIPBLAS_R_16F, + cudaDataType_t::CUDA_R_32F => hipblasDatatype_t::HIPBLAS_R_32F, + cudaDataType_t::CUDA_R_64F => hipblasDatatype_t::HIPBLAS_R_64F, + cudaDataType_t::CUDA_R_8I => hipblasDatatype_t::HIPBLAS_R_8I, + cudaDataType_t::CUDA_R_8U => hipblasDatatype_t::HIPBLAS_R_8U, + cudaDataType_t::CUDA_R_32I => hipblasDatatype_t::HIPBLAS_R_32I, + cudaDataType_t::CUDA_R_32U => hipblasDatatype_t::HIPBLAS_R_32U, + cudaDataType_t::CUDA_R_16BF => hipblasDatatype_t::HIPBLAS_R_16B, + _ => panic!(), + } +} + +unsafe fn matmul_desc_set_attribute( + matmul_desc: *mut cublasLtMatmulDescOpaque_t, + attr: cublasLtMatmulDescAttributes_t, + buf: *const std::ffi::c_void, + size_in_bytes: usize, +) -> cublasStatus_t { + let attr = to_attrib(attr); + to_cuda(hipblasLtMatmulDescSetAttribute( + matmul_desc.cast(), + attr, + buf.cast(), + size_in_bytes, + )) +} + +fn to_attrib(attr: cublasLtMatmulDescAttributes_t) -> hipblasLtMatmulDescAttributes_t { + match attr { + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_TRANSA => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_TRANSA + } + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_TRANSB => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_TRANSB + } + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_EPILOGUE => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_EPILOGUE + } + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_BIAS_POINTER => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_BIAS_POINTER + } + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_BIAS_DATA_TYPE => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_BIAS_DATA_TYPE + } + cublasLtMatmulDescAttributes_t::CUBLASLT_MATMUL_DESC_D_SCALE_POINTER => { + hipblasLtMatmulDescAttributes_t::HIPBLASLT_MATMUL_DESC_D_SCALE_POINTER + } + _ => panic!(), + } +} + +unsafe fn matrix_layout_create( + mat_layout: *mut *mut cublasLtMatrixLayoutOpaque_t, + type_: cudaDataType_t, + rows: u64, + cols: u64, + ld: i64, +) -> cublasStatus_t { + let type_ = data_type(type_); + to_cuda(hipblasLtMatrixLayoutCreate( + mat_layout.cast(), + type_, + rows, + cols, + ld, + )) +} + +unsafe fn matmul_desc_destroy(matmul_desc: *mut cublasLtMatmulDescOpaque_t) -> cublasStatus_t { + to_cuda(hipblasLtMatmulDescDestroy(matmul_desc.cast())) +} + +unsafe fn matmul_desc_get_attribute( + matmul_desc: *mut cublasLtMatmulDescOpaque_t, + attr: cublasLtMatmulDescAttributes_t, + buf: *mut std::ffi::c_void, + size_in_bytes: usize, + size_written: *mut usize, +) -> cublasStatus_t { + let attr = to_attrib(attr); + to_cuda(hipblasLtMatmulDescGetAttribute( + matmul_desc.cast(), + attr, + buf, + size_in_bytes, + size_written, + )) +} + +unsafe fn matmul_preference_create( + pref: *mut *mut cublasLtMatmulPreferenceOpaque_t, +) -> cublasStatus_t { + to_cuda(hipblasLtMatmulPreferenceCreate(pref.cast())) +} + +unsafe fn matmul_preference_destroy(pref: *mut cublasLtMatmulPreferenceOpaque_t) -> cublasStatus_t { + to_cuda(hipblasLtMatmulPreferenceDestroy(pref.cast())) +} + +unsafe fn matmul_preference_set_attribute( + pref: *mut cublasLtMatmulPreferenceOpaque_t, + attr: cublasLtMatmulPreferenceAttributes_t, + buf: *const std::ffi::c_void, + size_in_bytes: usize, +) -> cublasStatus_t { + if matches!( + attr, + cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_A_BYTES + | cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_B_BYTES + | cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_C_BYTES + | cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_MIN_ALIGNMENT_D_BYTES + ) { + return cublasStatus_t::CUBLAS_STATUS_SUCCESS; + } + let attr = to_preference_attrib(attr); + to_cuda(hipblasLtMatmulPreferenceSetAttribute( + pref.cast(), + attr, + buf, + size_in_bytes, + )) +} + +fn to_preference_attrib( + attr: cublasLtMatmulPreferenceAttributes_t, +) -> hipblasLtMatmulPreferenceAttributes_t { + match attr { + cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_SEARCH_MODE => { + hipblasLtMatmulPreferenceAttributes_t::HIPBLASLT_MATMUL_PREF_SEARCH_MODE + } + cublasLtMatmulPreferenceAttributes_t::CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES => { + hipblasLtMatmulPreferenceAttributes_t::HIPBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES + } + _ => panic!("{}", attr.0), + } +} + +unsafe fn matrix_layout_destroy(mat_layout: *mut cublasLtMatrixLayoutOpaque_t) -> cublasStatus_t { + to_cuda(hipblasLtMatrixLayoutDestroy(mat_layout.cast())) +} + +unsafe fn matrix_layout_set_attribute( + mat_layout: *mut cublasLtMatrixLayoutOpaque_t, + attr: cublasLtMatrixLayoutAttribute_t, + buf: *const std::ffi::c_void, + size_in_bytes: usize, +) -> cublasStatus_t { + let attr = to_matrix_attrib(attr); + to_cuda(hipblasLtMatrixLayoutSetAttribute( + mat_layout.cast(), + attr, + buf, + size_in_bytes, + )) +} + +fn to_matrix_attrib(attr: cublasLtMatrixLayoutAttribute_t) -> hipblasLtMatrixLayoutAttribute_t { + match attr { + cublasLtMatrixLayoutAttribute_t::CUBLASLT_MATRIX_LAYOUT_BATCH_COUNT => { + hipblasLtMatrixLayoutAttribute_t::HIPBLASLT_MATRIX_LAYOUT_BATCH_COUNT + } + cublasLtMatrixLayoutAttribute_t::CUBLASLT_MATRIX_LAYOUT_STRIDED_BATCH_OFFSET => { + hipblasLtMatrixLayoutAttribute_t::HIPBLASLT_MATRIX_LAYOUT_STRIDED_BATCH_OFFSET + } + _ => panic!(), + } +} diff --git a/zluda_ccl/Cargo.toml b/zluda_ccl/Cargo.toml new file mode 100644 index 0000000..c429a00 --- /dev/null +++ b/zluda_ccl/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "zluda_ccl" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "nccl" +crate-type = ["cdylib"] + +[dependencies] + +[package.metadata.zluda] +linux_only = true +linux_names = ["libnccl.so.2"] +dump_names = ["libnccl.so"] diff --git a/zluda_ccl/README b/zluda_ccl/README new file mode 100644 index 0000000..8ca1a60 --- /dev/null +++ b/zluda_ccl/README @@ -0,0 +1,2 @@ +bindgen /usr/include/nccl.h -o src/nccl.rs --allowlist-function="^p?nccl.*" --must-use-type "ncclResult_t" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +sed -i -e 's/extern "C" {//g' -e 's/-> ncclResult_t;/-> ncclResult_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "C" fn /g' src/nccl.rs \ No newline at end of file diff --git a/zluda_ccl/src/lib.rs b/zluda_ccl/src/lib.rs new file mode 100644 index 0000000..3de34d9 --- /dev/null +++ b/zluda_ccl/src/lib.rs @@ -0,0 +1,13 @@ +#[allow(warnings)] +mod nccl; +pub use nccl::*; + +#[cfg(debug_assertions)] +pub(crate) fn unsupported() -> ncclResult_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unsupported() -> ncclResult_t { + ncclResult_t::ncclInternalError +} diff --git a/zluda_ccl/src/nccl.rs b/zluda_ccl/src/nccl.rs new file mode 100644 index 0000000..5d3addc --- /dev/null +++ b/zluda_ccl/src/nccl.rs @@ -0,0 +1,666 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUstream_st { + _unused: [u8; 0], +} +#[doc = " CUDA stream"] +pub type cudaStream_t = *mut CUstream_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ncclComm { + _unused: [u8; 0], +} +pub type ncclComm_t = *mut ncclComm; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ncclUniqueId { + pub internal: [::std::os::raw::c_char; 128usize], +} +impl ncclResult_t { + pub const ncclSuccess: ncclResult_t = ncclResult_t(0); +} +impl ncclResult_t { + pub const ncclUnhandledCudaError: ncclResult_t = ncclResult_t(1); +} +impl ncclResult_t { + pub const ncclSystemError: ncclResult_t = ncclResult_t(2); +} +impl ncclResult_t { + pub const ncclInternalError: ncclResult_t = ncclResult_t(3); +} +impl ncclResult_t { + pub const ncclInvalidArgument: ncclResult_t = ncclResult_t(4); +} +impl ncclResult_t { + pub const ncclInvalidUsage: ncclResult_t = ncclResult_t(5); +} +impl ncclResult_t { + pub const ncclRemoteError: ncclResult_t = ncclResult_t(6); +} +impl ncclResult_t { + pub const ncclInProgress: ncclResult_t = ncclResult_t(7); +} +impl ncclResult_t { + pub const ncclNumResults: ncclResult_t = ncclResult_t(8); +} +#[repr(transparent)] +#[must_use] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ncclResult_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ncclConfig_v21700 { + pub size: usize, + pub magic: ::std::os::raw::c_uint, + pub version: ::std::os::raw::c_uint, + pub blocking: ::std::os::raw::c_int, + pub cgaClusterSize: ::std::os::raw::c_int, + pub minCTAs: ::std::os::raw::c_int, + pub maxCTAs: ::std::os::raw::c_int, + pub netName: *const ::std::os::raw::c_char, + pub splitShare: ::std::os::raw::c_int, +} +pub type ncclConfig_t = ncclConfig_v21700; + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclGetVersion(version: *mut ::std::os::raw::c_int) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclGetVersion(version: *mut ::std::os::raw::c_int) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclGetUniqueId(uniqueId: *mut ncclUniqueId) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclGetUniqueId(uniqueId: *mut ncclUniqueId) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommInitRankConfig( + comm: *mut ncclComm_t, + nranks: ::std::os::raw::c_int, + commId: ncclUniqueId, + rank: ::std::os::raw::c_int, + config: *mut ncclConfig_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommInitRankConfig( + comm: *mut ncclComm_t, + nranks: ::std::os::raw::c_int, + commId: ncclUniqueId, + rank: ::std::os::raw::c_int, + config: *mut ncclConfig_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommInitRank( + comm: *mut ncclComm_t, + nranks: ::std::os::raw::c_int, + commId: ncclUniqueId, + rank: ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommInitRank( + comm: *mut ncclComm_t, + nranks: ::std::os::raw::c_int, + commId: ncclUniqueId, + rank: ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommInitAll( + comm: *mut ncclComm_t, + ndev: ::std::os::raw::c_int, + devlist: *const ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommInitAll( + comm: *mut ncclComm_t, + ndev: ::std::os::raw::c_int, + devlist: *const ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommFinalize(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommFinalize(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommDestroy(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommDestroy(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommAbort(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommAbort(comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommSplit( + comm: ncclComm_t, + color: ::std::os::raw::c_int, + key: ::std::os::raw::c_int, + newcomm: *mut ncclComm_t, + config: *mut ncclConfig_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommSplit( + comm: ncclComm_t, + color: ::std::os::raw::c_int, + key: ::std::os::raw::c_int, + newcomm: *mut ncclComm_t, + config: *mut ncclConfig_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[no_mangle] +pub extern "C" fn ncclGetErrorString(result: ncclResult_t) -> *const ::std::os::raw::c_char { + "\0".as_ptr().cast() +} + +#[no_mangle] +pub extern "C" fn pncclGetErrorString(result: ncclResult_t) -> *const ::std::os::raw::c_char { + "\0".as_ptr().cast() +} + +#[no_mangle] +pub extern "C" fn ncclGetLastError(comm: ncclComm_t) -> *const ::std::os::raw::c_char { + "\0".as_ptr().cast() +} + +#[no_mangle] +pub extern "C" fn pncclGetLastError(comm: ncclComm_t) -> *const ::std::os::raw::c_char { + "\0".as_ptr().cast() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommGetAsyncError( + comm: ncclComm_t, + asyncError: *mut ncclResult_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommGetAsyncError( + comm: ncclComm_t, + asyncError: *mut ncclResult_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommCount( + comm: ncclComm_t, + count: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommCount( + comm: ncclComm_t, + count: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommCuDevice( + comm: ncclComm_t, + device: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommCuDevice( + comm: ncclComm_t, + device: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclCommUserRank( + comm: ncclComm_t, + rank: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclCommUserRank( + comm: ncclComm_t, + rank: *mut ::std::os::raw::c_int, +) -> ncclResult_t { + crate::unsupported() +} +impl ncclRedOp_t { + pub const ncclSum: ncclRedOp_t = ncclRedOp_t(0); +} +impl ncclRedOp_t { + pub const ncclProd: ncclRedOp_t = ncclRedOp_t(1); +} +impl ncclRedOp_t { + pub const ncclMax: ncclRedOp_t = ncclRedOp_t(2); +} +impl ncclRedOp_t { + pub const ncclMin: ncclRedOp_t = ncclRedOp_t(3); +} +impl ncclRedOp_t { + pub const ncclAvg: ncclRedOp_t = ncclRedOp_t(4); +} +impl ncclRedOp_t { + pub const ncclNumOps: ncclRedOp_t = ncclRedOp_t(5); +} +impl ncclRedOp_t { + pub const ncclMaxRedOp: ncclRedOp_t = ncclRedOp_t(2147483647); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ncclRedOp_t(pub ::std::os::raw::c_uint); +impl ncclDataType_t { + pub const ncclInt8: ncclDataType_t = ncclDataType_t(0); +} +impl ncclDataType_t { + pub const ncclChar: ncclDataType_t = ncclDataType_t(0); +} +impl ncclDataType_t { + pub const ncclUint8: ncclDataType_t = ncclDataType_t(1); +} +impl ncclDataType_t { + pub const ncclInt32: ncclDataType_t = ncclDataType_t(2); +} +impl ncclDataType_t { + pub const ncclInt: ncclDataType_t = ncclDataType_t(2); +} +impl ncclDataType_t { + pub const ncclUint32: ncclDataType_t = ncclDataType_t(3); +} +impl ncclDataType_t { + pub const ncclInt64: ncclDataType_t = ncclDataType_t(4); +} +impl ncclDataType_t { + pub const ncclUint64: ncclDataType_t = ncclDataType_t(5); +} +impl ncclDataType_t { + pub const ncclFloat16: ncclDataType_t = ncclDataType_t(6); +} +impl ncclDataType_t { + pub const ncclHalf: ncclDataType_t = ncclDataType_t(6); +} +impl ncclDataType_t { + pub const ncclFloat32: ncclDataType_t = ncclDataType_t(7); +} +impl ncclDataType_t { + pub const ncclFloat: ncclDataType_t = ncclDataType_t(7); +} +impl ncclDataType_t { + pub const ncclFloat64: ncclDataType_t = ncclDataType_t(8); +} +impl ncclDataType_t { + pub const ncclDouble: ncclDataType_t = ncclDataType_t(8); +} +impl ncclDataType_t { + pub const ncclNumTypes: ncclDataType_t = ncclDataType_t(9); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ncclDataType_t(pub ::std::os::raw::c_uint); +impl ncclScalarResidence_t { + pub const ncclScalarDevice: ncclScalarResidence_t = ncclScalarResidence_t(0); +} +impl ncclScalarResidence_t { + pub const ncclScalarHostImmediate: ncclScalarResidence_t = ncclScalarResidence_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct ncclScalarResidence_t(pub ::std::os::raw::c_uint); + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclRedOpCreatePreMulSum( + op: *mut ncclRedOp_t, + scalar: *mut ::std::os::raw::c_void, + datatype: ncclDataType_t, + residence: ncclScalarResidence_t, + comm: ncclComm_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclRedOpCreatePreMulSum( + op: *mut ncclRedOp_t, + scalar: *mut ::std::os::raw::c_void, + datatype: ncclDataType_t, + residence: ncclScalarResidence_t, + comm: ncclComm_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclRedOpDestroy(op: ncclRedOp_t, comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclRedOpDestroy(op: ncclRedOp_t, comm: ncclComm_t) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclReduce( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclReduce( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclBcast( + buff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclBcast( + buff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclBroadcast( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclBroadcast( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + root: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclAllReduce( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclAllReduce( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclReduceScatter( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + recvcount: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclReduceScatter( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + recvcount: usize, + datatype: ncclDataType_t, + op: ncclRedOp_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclAllGather( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + sendcount: usize, + datatype: ncclDataType_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclAllGather( + sendbuff: *const ::std::os::raw::c_void, + recvbuff: *mut ::std::os::raw::c_void, + sendcount: usize, + datatype: ncclDataType_t, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclSend( + sendbuff: *const ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + peer: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclSend( + sendbuff: *const ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + peer: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclRecv( + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + peer: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclRecv( + recvbuff: *mut ::std::os::raw::c_void, + count: usize, + datatype: ncclDataType_t, + peer: ::std::os::raw::c_int, + comm: ncclComm_t, + stream: cudaStream_t, +) -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclGroupStart() -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclGroupStart() -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn ncclGroupEnd() -> ncclResult_t { + crate::unsupported() +} + +#[must_use] +#[no_mangle] +pub extern "C" fn pncclGroupEnd() -> ncclResult_t { + crate::unsupported() +} diff --git a/zluda_dark_api/Cargo.toml b/zluda_dark_api/Cargo.toml new file mode 100644 index 0000000..0aef25e --- /dev/null +++ b/zluda_dark_api/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "zluda_dark_api" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] + +[dependencies] +cuda_types = { path = "../cuda_types" } +hip_common = { path = "../hip_common" } +bitflags = "2.4" +either = "1.9" +bit-vec = "0.6.3" +paste = "1.0" +lz4-sys = "1.9" +thread-id = "4.1.0" +# we don't need elf32, but goblin has a bug where elf64 does not build without elf32 +goblin = { version = "0.5.1", default-features = false, features = ["elf64", "elf32"] } diff --git a/zluda_dark_api/src/lib.rs b/zluda_dark_api/src/lib.rs new file mode 100644 index 0000000..6849e0e --- /dev/null +++ b/zluda_dark_api/src/lib.rs @@ -0,0 +1,1165 @@ +// This module covers all known dark api functions. It exists to force +// convergence between main implementation and dumper implementation +use bit_vec::BitVec; +use bitflags::bitflags; +use cuda_types::*; +use hip_common::zluda_ext::CudaResult; +use paste::paste; +use std::{ + borrow::Cow, + ffi::c_void, + fmt::Display, + mem, + os::raw::{c_int, c_uchar, c_uint, c_ulong, c_ushort}, + ptr, slice, +}; + +macro_rules! dark_api_fn_decl { + (SIZE_OF) => { }; + (NULL) => { }; + ($fn_:ident ( $($arg_name:ident: $arg_ty:ty),* ) -> $ret_ty:ty) => { + #[allow(non_snake_case)] + unsafe extern "system" fn $fn_( + $($arg_name : $arg_ty,)* + ) -> $ret_ty; + } +} + +macro_rules! dark_api_fn_dump_decl { + ($name:ident $idx:literal $fn_:ident $( ( $($arg_name:ident: $arg_ty:ty),* ) -> $ret_ty:ty )?) => { }; + (#[dump] $name:ident $idx:literal $fn_:ident ( $($arg_name:ident: $arg_ty:ty),* ) -> $ret_ty:ty) => { + #[allow(non_snake_case)] + unsafe extern "system" fn $fn_( + $($arg_name : $arg_ty,)* + ) -> $ret_ty { + paste!( Self:: [<$fn_ _impl>] )(&CudaDarkApiTable::$name, $idx, $($arg_name,)* ) + } + + paste!{ + #[allow(non_snake_case)] + unsafe fn [<$fn_ _impl>] (guid: &[u8; 16], idx: usize, $($arg_name : $arg_ty,)*) -> $ret_ty; + } + }; +} + +macro_rules! dark_api_fn_dump_match { + ($T:ident $fn_:ident) => { + None + }; + (#[dump] $T:ident $fn_:ident) => { + Some($T::$fn_ as *const c_void) + }; +} + +macro_rules! dark_api_table_setter { + (SIZE_OF, $table_len:literal, $api:ty) => {{ + (std::mem::size_of::() * $table_len) as *const () + }}; + (NULL, $table_len:literal, $api:ty) => {{ + std::ptr::null() + }}; + ($fn_:ident, $table_len:literal, $api:ty) => {{ + <$api as CudaDarkApi>::$fn_ as *const () + }}; +} + +macro_rules! dark_api_fn_passthrough { + ($idx:literal, SIZE_OF) => { }; + ($idx:literal, NULL) => { }; + ($idx:literal, $fn_:ident ( $($arg_name:ident: $arg_ty:ty),* ) -> $ret_ty:ty) => { + #[allow(non_snake_case)] + pub unsafe fn $fn_( + &self, + $($arg_name : $arg_ty,)* + ) -> $ret_ty { + let ptr = self.ptr as *mut *mut c_void; + let ptr = ptr.add($idx); + let fn_ = std::mem::transmute::<_, unsafe extern "system" fn( $($arg_ty,)* ) -> $ret_ty >(*ptr); + (fn_)( $($arg_name,)* ) + } + } +} + +macro_rules! dark_api_table { + ($($guid:expr => $name:ident [$table_len:literal] { + $( $(#[$attr:ident])? $idx:literal =>$fn_:ident $( ( $($arg_name:ident: $arg_ty:ty),* ) -> $ret_ty:ty )? ),* + }),+) => { + pub trait CudaDarkApi { + $($( + dark_api_fn_decl!($fn_ $( ( $($arg_name: $arg_ty),* ) -> $ret_ty )?); + )*)+ + } + + #[allow(non_snake_case)] + pub struct CudaDarkApiTable { + $(pub $name: [*const (); $table_len],)+ + } + + unsafe impl Sync for CudaDarkApiTable {} + + impl CudaDarkApiTable { + $(const $name: [u8; 16] = $guid;)+ + } + + impl CudaDarkApiTable { + pub fn get(&self, guid: &[u8; 16]) -> Option<&[*const ()]> { + match guid { + $(&Self::$name => { + Some(&self.$name[..]) + })+ + _ => None + } + } + } + + pub const fn init_dark_api() -> CudaDarkApiTable { + let mut table = CudaDarkApiTable { + $($name: [std::ptr::null(); $table_len],)+ + }; + $($( + table.$name[$idx] = dark_api_table_setter!($fn_, $table_len, T); + )*)+ + table + } + + pub trait CudaDarkApiDump { + $($( + dark_api_fn_dump_decl!( $(#[$attr])? $name $idx $fn_ $( ( $($arg_name: $arg_ty),* ) -> $ret_ty )?); + )*)+ + } + + pub fn get_dark_api_fn(guid: &[u8; 16], idx: usize) -> Option<*const c_void> { + match (guid, idx) { + $($( + (&CudaDarkApiTable::$name, $idx) => dark_api_fn_dump_match!($(#[$attr])? T $fn_ ), + )*)+ + _ => None + } + } + + #[allow(non_snake_case)] + pub struct CudaDarkApiKnownExports { + empty: BitVec, + $($name: BitVec,)+ + } + + impl CudaDarkApiKnownExports { + pub fn new() -> Self { + Self { + empty: BitVec::new(), + $( + $name: { + let mut set = BitVec::from_elem($table_len, false); + $( set.set($idx, true); )* + set + }, + )+ + } + } + + pub fn known(&self, guid: &[u8; 16] ) -> impl ExactSizeIterator + '_ { + let set = match guid { + $( + &CudaDarkApiTable::$name => { + &self.$name + } + )+ + _ => &self.empty + }; + set.iter() + } + } + + $( + paste! { + pub struct [<$name:camel>] { + #[allow(dead_code)] + ptr: *const c_void + } + + impl [<$name:camel>] { + pub const GUID: CUuuid = CUuuid { bytes: $guid }; + + pub unsafe fn new(ptr: *const c_void) -> Self { + Self { + ptr + } + } + $( + dark_api_fn_passthrough!($idx, $fn_ $( ( $($arg_name: $arg_ty),* ) -> $ret_ty )?); + )* + } + } + )+ + }; +} + +dark_api_table!( + [0x6b, 0xd5, 0xfb, 0x6c, 0x5b, 0xf4, 0xe7, 0x4a, 0x89, 0x87, 0xd9, 0x39, 0x12, 0xfd, 0x9d, 0xf9] + => CUDART_INTERFACE [10] { + 0 => SIZE_OF, + #[dump] + 1 => get_module_from_cubin( + module: *mut CUmodule, + fatbinc_wrapper: *const FatbincWrapper + ) -> CUresult, + 2 => get_primary_context(pctx: *mut CUcontext, dev: CUdevice) -> CUresult, + #[dump] + 6 => get_module_from_cubin_ex1( + module: *mut CUmodule, + fatbinc_wrapper: *const FatbincWrapper, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: usize + ) -> CUresult, + 7 => cudart_interface_fn7(arg1: usize) -> (), + // From the assembly it looks like arg5 is a count of something in arg3 and arg4 + #[dump] + 8 => get_module_from_cubin_ex2( + fatbin_header: *const FatbinHeader, + module: *mut CUmodule, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: c_uint + ) -> CUresult, + #[dump] + 9 => launch_kernel( + f: CUfunction, + grid_dim_x: ::std::os::raw::c_uint, + grid_dim_y: ::std::os::raw::c_uint, + grid_dim_z: ::std::os::raw::c_uint, + block_dim_x: ::std::os::raw::c_uint, + block_dim_y: ::std::os::raw::c_uint, + block_dim_z: ::std::os::raw::c_uint, + shared_mem_bytes: ::std::os::raw::c_uint, + stream: CUstream, + extra: *mut *mut ::std::os::raw::c_void + ) -> CUresult + }, + [0xa0, 0x94, 0x79, 0x8c, 0x2e, 0x74, 0x2e, 0x74, 0x93, 0xf2, 0x08, 0x00, 0x20, 0x0c, 0x0a, 0x66] + => TOOLS_RUNTIME_CALLBACK_HOOKS [7] { + 0 => SIZE_OF, + // Both of those return some prealloacted buffers to be used by tooling? + 2 => tools_runtime_callback_hooks_fn2(ptr: *mut *mut usize, size: *mut usize) -> (), + 6 => tools_runtime_callback_hooks_fn6(ptr: *mut *mut u8, size: *mut usize) -> () + }, + [0x42, 0xd8, 0x5a, 0x81, 0x23, 0xf6, 0xcb, 0x47, 0x82, 0x98, 0xf6, 0xe7, 0x8a, 0x3a, 0xec, 0xdc] + => TOOLS_TLS [3] { + 0 => SIZE_OF + }, + [0xc6, 0x93, 0x33, 0x6e, 0x11, 0x21, 0xdf, 0x11, 0xa8, 0xc3, 0x68, 0xf3, 0x55, 0xd8, 0x95, 0x93] + => CONTEXT_LOCAL_STORAGE_INTERFACE_V0301 [4] { + 0 => context_local_storage_insert( + key: CUcontext, + mgr: *mut c_void, + value: *mut c_void, + // clsContextDestroyCallback, have to be called on cuDevicePrimaryCtxReset + dtor_cb: Option< + extern "system" fn( + CUcontext, + *mut c_void, + *mut c_void, + ) + > + ) -> CUresult, + // some kind of dtor + 1 => context_local_storage_remove(arg1: usize, arg2: usize) -> CUresult, + 2 => context_local_storage_get( + result: *mut *mut c_void, + cu_ctx: CUcontext, + key: *mut c_void + ) -> CUresult, + 3 => NULL + }, + // This fn table is used by PhysX + [0x0C, 0xA5, 0x0B, 0x8C, 0x10, 0x04, 0x92, 0x9A, 0x89, 0xA7, 0xD0, 0xDF, 0x10, 0xE7, 0x72, 0x86] + => CTX_CREATE_BYPASS [2] { + 0 => SIZE_OF, + #[dump] + 1 => ctx_create_v2_bypass( + pctx: *mut CUcontext, + flags: c_uint, + dev: CUdevice + ) -> CUresult + }, + [0x19, 0x5B, 0xCB, 0xF4, 0xD6, 0x7D, 0x02, 0x4A, 0xAC, 0xC5, 0x1D, 0x29, 0xCE, 0xA6, 0x31, 0xAE] + => HEAP_ACCESS [3] { + 0 => SIZE_OF, + 1 => heap_alloc( + halloc_ptr: *mut *mut HeapAllocRecord, + param1: usize, + param2: usize + ) -> CUresult, + 2 => heap_free(halloc: *mut HeapAllocRecord, param2: *mut usize) -> CUresult + }, + // This fn table is used by OptiX + [0xB1u8, 0x05, 0x41, 0xE1, 0xF7, 0xC7, 0xC7, 0x4A, 0x9F, 0x64, 0xF2, 0x23, 0xBE, 0x99, 0xF1, 0xE2] + => DEVICE_EXTENDED_RT [26] { + 0 => SIZE_OF, + 5 => device_get_attribute_ex( + dev: CUdevice, + attribute: c_uint, + unknown: c_int, + result: *mut [usize; 2] + ) -> CUresult, + // I don't know what this function does, but on my GTX 1060 it returns 0 + 13 => device_get_something( + result: *mut c_uchar, + dev: CUdevice + ) -> CUresult + }, + // This fn table is used by DLSS + [0x7f, 0x92, 0x12, 0xd6, 0x26, 0x1d, 0xdd, 0x4d, 0x8a, 0xf6, 0x38, 0xdd, 0x1a, 0xeb, 0x10, 0xae] + => DLSS [58] { + 0 => SIZE_OF, + #[dump] + 3 => dlss_cuInit() -> CUresult, + #[dump] + 7 => dlss_start1( + retval1: *mut *mut c_void, + arg2: *mut c_void, + arg3: *mut c_void, + arg4: *mut c_void, + // pointer to fn table in libnvidia-glcore.so + arg5: *mut c_void + ) -> CUresult, + #[dump] + 9 => dlss_start2( + handle: *mut c_void, + arg2: *mut u32 + ) -> CUresult, + #[dump] + 12 => dlss_module_load( + context: CUcontext, + result: *mut CUmodule, + fatbin: *mut c_void, + arg4: u32, + arg5: *mut c_void, + arg6: *mut c_void + ) -> CUresult, + #[dump] + 14 => dlss_module_get_function( + result: *mut CUfunction, + module: CUmodule, + name: *const i8 + ) -> CUresult, + #[dump] + 22 => dlss_feature_evaluate2( + handle1: *mut c_void, + handle2: *mut c_void, + handle3: *mut c_void, + arg4: u8, + handle5: *mut c_void, + arg6: u32 + ) -> CUresult, + #[dump] + 37 => dlss_feature_evaluate1( + retval1: *mut u32, + retval2: *mut u32, + retval3: *mut u32, + handle: *mut c_void + ) -> CUresult, + #[dump] + 39 => dlss_feature_evaluate_init( + retval1: *mut *mut c_void, + handle: *mut c_void, + retval2: *mut *mut c_void + ) -> CUresult + }, + [0x26, 0x3e, 0x88, 0x60, 0x7c, 0xd2, 0x61, 0x43, 0x92, 0xf6, 0xbb, 0xd5, 0x00, 0x6d, 0xfa, 0x7e] + => CONTEXT_WRAPPER [3] { + 0 => SIZE_OF, + // This function is present at least from 12.3 and the pseudocode is: + // let ctx = get_current_if_null(ctx); + // if ctx.unknown_flag == 1 { + // *wrapped = 1; + // if unwrapped_ctx != ptr::null_mut() { + // *unwrapped_ctx = ctx.unwrapped_ctx; + // } + // } else { + // *wrapped = 0; + // } + // This pattern is present in other parts of the driver (cuCtxDestroy_v2). + // Not sure how can one create context with `unknown_flag` set. + // Different variant of cuCtxCreate and primary context all have this flag unset. + // Maybe interop context? + #[dump] + 2 => unwrap_context( + ctx: CUcontext, + wrapped: *mut u32, + unwrapped_ctx: *mut CUcontext + ) -> CUresult + }, + // Functions used by NVIDIA CUDA runtime to detect presence of ZLUDA and fail if it's found + [0xd4, 0x08, 0x20, 0x55, 0xbd, 0xe6, 0x70, 0x4b, 0x8d, 0x34, 0xba, 0x12, 0x3c, 0x66, 0xe1, 0xf2] + => ANTI_ZLUDA [3] { + 0 => SIZE_OF, + #[dump] + 1 => zluda_check( + arg1: u32, // runtime version? + timestamp: u64, // UNIX time in seconds + result: *mut u128 + ) -> CUresult + }, + // This table is used by ZLUDA, it's *not* exported by NVIDIA CUDA. It's necessary for library interop, + // e.g. zluda_blas, when wrapping rocblas needs to extract HIP stream from ZLUDA stream + // Alternatively we could have ZLUDA library just export the functions, but + // that is not transparent to the tooling (zluda_dump). Every function would need to be + // exported twice: firstly from ZLUDA proper and then again for passthrough in zluda_dump + [0x70, 0xe1, 0xfa, 0xee, 0x26, 0x8, 0x40, 0x25, 0x82, 0xa7, 0xe0, 0xbc, 0xc1, 0x2e, 0xcc, 0x60] + => ZLUDA_EXT [2] { + 0 => SIZE_OF, + 1 => get_hip_stream(stream: CUstream) -> CudaResult<*const std::os::raw::c_void> + } +); + +pub const ELF_MAGIC: c_uint = unsafe { std::mem::transmute(*b"\x7FELF") }; +pub const FATBINC_MAGIC: c_uint = 0x466243B1; +pub const FATBINC_VERSION_V1: c_uint = 0x1; +pub const FATBINC_VERSION_V2: c_uint = 0x2; + +#[repr(C)] +pub struct FatbincWrapper { + magic: c_uint, + version: c_uint, + data: *const FatbinHeader, + filename_or_fatbins: *const c_void, +} + +pub const FATBIN_MAGIC: c_uint = 0xBA55ED50; +pub const FATBIN_VERSION: c_ushort = 0x01; + +#[repr(C, align(8))] +pub 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 +} + +pub const FATBIN_FILE_HEADER_KIND_PTX: c_ushort = 0x01; +pub const FATBIN_FILE_HEADER_KIND_ELF: c_ushort = 0x02; +pub const FATBIN_FILE_HEADER_VERSION_CURRENT: c_ushort = 0x101; + +// assembly file header is a bit different, but we don't care +#[repr(C)] +pub struct FatbinFileHeader { + pub kind: c_ushort, + pub version: c_ushort, + pub header_size: c_uint, + pub padded_payload_size: c_uint, + pub unknown0: c_uint, // might be part of padded_payload_size + + pub payload_size: c_uint, + pub unknown1: c_uint, // probably bitness in case of PTX, nothing for ELF + pub ptx_version: c_uint, // (major * 0x10000) + minor + pub sm_version: c_uint, + + pub file_name_offset: c_uint, // optional + pub file_name_len: c_uint, // optional + pub flags: FatbinFileHeaderFlags, + + pub unknown6: u64, + pub uncompressed_payload: u64, + // pub ptxas_arg_offset: c_uint, // optional + // pub ptxas_arg_len: c_uint, // optional +} + +bitflags! { + #[repr(transparent)] + pub struct FatbinFileHeaderFlags: u64 { + const Is64Bit = 0x0000000000000001; + const Debug = 0x0000000000000002; + const Linux = 0x0000000000000010; + const Mac = 0x0000000000000020; + const Windows = 0x0000000000000040; + const OptMask = 0x0000000000000f00; + const CompressedOld = 0x0000000000001000; + const CompressedNew = 0x0000000000002000; + + const _ = !0; + } +} + +pub enum ContextState {} + +pub enum ContextStateManager {} + +#[repr(C)] +pub struct HeapAllocRecord { + param1: usize, + param2: usize, + _unknown: usize, + global_heap: *mut c_void, +} + +#[derive(Clone, Copy)] +pub enum AnyUInt { + U16(u16), + U32(u32), + U64(u64), + USize(usize), +} + +impl Display for AnyUInt { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AnyUInt::U16(x) => write!(f, "{:#x}", x), + AnyUInt::U32(x) => write!(f, "{:#x}", x), + AnyUInt::U64(x) => write!(f, "{:#x}", x), + AnyUInt::USize(x) => write!(f, "{:#x}", x), + } + } +} + +impl std::fmt::Debug for AnyUInt { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::fmt(self, f) + } +} + +#[derive(Debug)] +pub struct UnexpectedFieldError { + pub name: &'static str, + pub expected: Vec, + pub observed: AnyUInt, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum FatbinFileKind { + Ptx, + Elf, + Archive, +} + +impl FatbinFileKind { + pub fn file_extension(self) -> &'static str { + match self { + FatbinFileKind::Ptx => "ptx", + FatbinFileKind::Elf => "elf", + FatbinFileKind::Archive => "a", + } + } +} + +pub enum CudaFatbin { + Version1(FatbinModuleHandle), + Version2 { + post_link: FatbinModuleHandle, + pre_link: &'static [FatbinModuleHandle], + }, +} + +impl CudaFatbin { + pub unsafe fn from_wrapper( + fatbinc_wrapper: *const FatbincWrapper, + ) -> Result { + let fatbinc_wrapper = &*fatbinc_wrapper; + let magic = fatbinc_wrapper.magic; + if magic != FATBINC_MAGIC { + return Err(UnexpectedFieldError { + name: "FATBINC_MAGIC", + expected: vec![AnyUInt::U32(FATBINC_MAGIC)], + observed: AnyUInt::U32(magic), + }); + } + let version = fatbinc_wrapper.version; + Ok(match version { + FATBINC_VERSION_V1 => CudaFatbin::Version1(FatbinModuleHandle(fatbinc_wrapper.data)), + FATBINC_VERSION_V2 => { + let len = slice_length(fatbinc_wrapper.filename_or_fatbins.cast()); + let pre_link = + std::slice::from_raw_parts(fatbinc_wrapper.filename_or_fatbins.cast(), len); + let post_link = FatbinModuleHandle(fatbinc_wrapper.data); + CudaFatbin::Version2 { + post_link, + pre_link, + } + } + _ => { + return Err(UnexpectedFieldError { + name: "FATBINC_VERSION", + expected: vec![ + AnyUInt::U32(FATBINC_VERSION_V1), + AnyUInt::U32(FATBINC_VERSION_V2), + ], + observed: AnyUInt::U32(version), + }); + } + }) + } + + pub unsafe fn from_header(fatbin_header: *const FatbinHeader) -> Self { + CudaFatbin::Version1(FatbinModuleHandle(fatbin_header)) + } +} + +pub enum CUmoduleContent { + RawText(*const u8), + Archive(&'static [u8]), + File(*const i8), + Fatbin(CudaFatbin), + Elf(*const u8), +} + +impl CUmoduleContent { + pub unsafe fn from_ptr(ptr: *const u8) -> Result { + Ok(if (ptr as usize % 4) != 0 { + CUmoduleContent::RawText(ptr) + } else if *(ptr as *const u32) == FATBINC_MAGIC { + CUmoduleContent::Fatbin(CudaFatbin::from_wrapper(ptr as *const FatbincWrapper)?) + } else if *(ptr as *const u32) == FATBIN_MAGIC { + CUmoduleContent::Fatbin(CudaFatbin::from_header(ptr as *const FatbinHeader)) + } else if *(ptr as *const u32) == ELF_MAGIC { + CUmoduleContent::Elf(ptr) + } else { + CUmoduleContent::RawText(ptr) + }) + } +} + +unsafe fn slice_length(ptr: *const *const c_void) -> usize { + let mut current = ptr; + while *current != ptr::null() { + current = current.add(1); + } + current.offset_from(ptr) as usize +} + +#[repr(transparent)] +pub struct FatbinModuleHandle(*const FatbinHeader); + +impl FatbinModuleHandle { + pub unsafe fn get(&self) -> Result { + let fatbin_header = &*self.0; + let magic = fatbin_header.magic; + if magic == ELF_MAGIC { + return Ok(FatbinModule::Elf(self.0 as _)); + } else if magic != FATBIN_MAGIC { + return Err(UnexpectedFieldError { + name: "FATBIN_MAGIC", + expected: vec![AnyUInt::U32(FATBIN_MAGIC), AnyUInt::U32(ELF_MAGIC)], + observed: AnyUInt::U32(magic), + }); + } + let version = fatbin_header.version; + if version != FATBIN_VERSION { + return Err(UnexpectedFieldError { + name: "FATBIN_VERSION", + expected: vec![AnyUInt::U16(FATBIN_VERSION)], + observed: AnyUInt::U16(version), + }); + } + let current = (self.0 as *const u8).add(fatbin_header.header_size as usize); + let end = current.add(fatbin_header.files_size as usize); + Ok(FatbinModule::Files(FatbinModuleFiles { current, end })) + } +} + +pub struct FatbinModuleFiles { + current: *const u8, + end: *const u8, +} + +impl Iterator for FatbinModuleFiles { + type Item = Result; + + fn next(&mut self) -> Option { + if self.current < self.end { + let fatbin_file = unsafe { &*(self.current as *const FatbinFileHeader) }; + self.current = unsafe { + self.current.add( + fatbin_file.header_size as usize + fatbin_file.padded_payload_size as usize, + ) + }; + Some(unsafe { FatbinFile::try_new(fatbin_file) }) + } else { + None + } + } +} + +pub enum FatbinModule { + Elf(*const u8), + Files(FatbinModuleFiles), +} + +pub struct FatbinFile { + data: *const u8, + pub kind: FatbinFileKind, + pub compressed: bool, + pub sm_version: u32, + padded_payload_size: usize, + payload_size: usize, + uncompressed_payload: usize, +} + +impl FatbinFile { + unsafe fn try_new(fatbin_file: &FatbinFileHeader) -> Result { + let fatbin_file_version = fatbin_file.version; + if fatbin_file_version != FATBIN_FILE_HEADER_VERSION_CURRENT { + return Err(UnexpectedFieldError { + name: "FATBIN_FILE_HEADER_VERSION", + expected: vec![AnyUInt::U16(FATBIN_FILE_HEADER_VERSION_CURRENT)], + observed: AnyUInt::U16(fatbin_file_version), + }); + } + let raw_fatbin_file_kind = (*fatbin_file).kind; + let kind = match raw_fatbin_file_kind { + FATBIN_FILE_HEADER_KIND_PTX => FatbinFileKind::Ptx, + FATBIN_FILE_HEADER_KIND_ELF => FatbinFileKind::Elf, + _ => { + return Err(UnexpectedFieldError { + name: "FATBIN_FILE_HEADER_KIND", + expected: vec![ + AnyUInt::U16(FATBIN_FILE_HEADER_KIND_ELF), + AnyUInt::U16(FATBIN_FILE_HEADER_KIND_PTX), + ], + observed: AnyUInt::U16(raw_fatbin_file_kind), + }); + } + }; + if fatbin_file + .flags + .contains(FatbinFileHeaderFlags::CompressedOld) + { + return Err(UnexpectedFieldError { + name: "FATBIN_FILE_HEADER_FLAGS", + expected: vec![ + AnyUInt::U64(FatbinFileHeaderFlags::empty().bits()), + AnyUInt::U64(FatbinFileHeaderFlags::CompressedNew.bits()), + ], + observed: AnyUInt::U64(fatbin_file.flags.bits()), + }); + } + let compressed = fatbin_file + .flags + .contains(FatbinFileHeaderFlags::CompressedNew); + let data = (fatbin_file as *const _ as *const u8).add(fatbin_file.header_size as usize); + let padded_payload_size = fatbin_file.padded_payload_size as usize; + let payload_size = fatbin_file.payload_size as usize; + let uncompressed_payload = fatbin_file.uncompressed_payload as usize; + let sm_version = fatbin_file.sm_version; + Ok(Self { + data, + kind, + compressed, + padded_payload_size, + payload_size, + uncompressed_payload, + sm_version, + }) + } + + // Returning static lifetime here because all known uses of this are related to fatbin files that + // are constants inside files + pub unsafe fn get_or_decompress(&self) -> Result, Lz4DecompressionFailure> { + if self.compressed { + match self.decompress_kernel_module() { + Some(mut decompressed) => { + if self.kind == FatbinFileKind::Ptx { + decompressed.pop(); // remove trailing zero + } + Ok(Cow::Owned(decompressed)) + } + None => Err(Lz4DecompressionFailure), + } + } else { + Ok(Cow::Borrowed(slice::from_raw_parts( + self.data, + self.padded_payload_size as usize, + ))) + } + } + + const MAX_MODULE_DECOMPRESSION_BOUND: usize = 64 * 1024 * 1024; + + unsafe fn decompress_kernel_module(&self) -> Option> { + let decompressed_size = usize::max(1024, self.uncompressed_payload as usize); + let mut decompressed_vec = vec![0u8; decompressed_size]; + loop { + match lz4_sys::LZ4_decompress_safe( + self.data.cast(), + decompressed_vec.as_mut_ptr() as *mut _, + self.payload_size as c_int, + decompressed_vec.len() as c_int, + ) { + error if error < 0 => { + let new_size = decompressed_vec.len() * 2; + if new_size > Self::MAX_MODULE_DECOMPRESSION_BOUND { + return None; + } + decompressed_vec.resize(decompressed_vec.len() * 2, 0); + } + real_decompressed_size => { + decompressed_vec.truncate(real_decompressed_size as usize); + return Some(decompressed_vec); + } + } + } + } +} + +#[derive(Debug)] +pub struct Lz4DecompressionFailure; + +pub fn anti_zluda_hash AntiZludaHashInputDevice>( + return_known_value: bool, + input: AntiZludaHashInput, + dev_getter: F, +) -> u128 { + anti_zluda_hash_impl( + return_known_value, + input, + dev_getter, + std::process::id(), + thread_id::get() as u32, + ) +} + +const ANTI_ZLUDA_HASH_TABLE_PART1: [u8; 64] = [ + 0x6b, 0xcf, 0x32, 0x0f, 0xa4, 0x49, 0xd3, 0xa8, 0x33, 0xf8, 0xd0, 0x8e, 0x12, 0x4e, 0xa8, 0x00, + 0xeb, 0x94, 0x2c, 0x8f, 0x34, 0x49, 0xde, 0xf6, 0xbf, 0x29, 0x91, 0x20, 0xc7, 0x65, 0xf6, 0xba, + 0x78, 0x5c, 0x66, 0x27, 0xa7, 0xb2, 0x73, 0x92, 0xdb, 0x22, 0x1e, 0x20, 0x14, 0x6f, 0x87, 0xff, + 0xa5, 0xc3, 0x18, 0x01, 0x66, 0x64, 0xa5, 0x0e, 0x70, 0x51, 0x52, 0xa7, 0x80, 0x4b, 0xdf, 0xef, +]; + +pub struct AntiZludaHashInput { + pub cudart_export_table: *mut c_void, + pub anti_zluda_export_table: *mut c_void, + pub fn_ptr: *mut c_void, + pub device_count: u32, + pub driver_version: u32, + pub rt_version: u32, + pub timestamp: u64, +} + +#[derive(Clone)] +pub struct AntiZludaHashInputDevice { + pub guid: CUuuid, + pub pci_domain: u32, + pub pci_bus: u32, + pub pci_device: u32, +} + +fn anti_zluda_hash_impl AntiZludaHashInputDevice>( + return_known_value: bool, + input: AntiZludaHashInput, + dev_getter: F, + process_id: u32, + thread_id: u32, +) -> u128 { + if return_known_value { + 0x8ED383AA1F4CD1E83341181C03CB675Cu128 + } else if input.rt_version % 10 < 2 { + let result = 0x8ED383AA1F4CD1E83341181C03CB675Cu128; + if input.rt_version % 10 == 1 { + let mut result = result.to_le_bytes(); + result[7] = 24; + u128::from_le_bytes(result) + } else { + result + } + } else { + let mut result = [0u8; 66]; + let mut aux = [0u8; 16]; + anti_zluda_hash_impl_part1(&mut aux); + anti_zluda_hash_impl_part2(&mut result, aux); + anti_zluda_hash_impl_part3(&mut result, &input, process_id, thread_id); + anti_zluda_hash_impl_part4(&mut result, &input, dev_getter); + anti_zluda_hash_impl_part5(&mut result); + anti_zluda_hash_round_v2(&mut result, 48); + anti_zluda_hash_impl_part6(&mut result, aux); + anti_zluda_hash_impl_part5(&mut result); + anti_zluda_hash_round_v2(&mut result, 48); + let mut output = [0u8; 16]; + output.copy_from_slice(&result[..16]); + u128::from_le_bytes(output) + } +} + +fn anti_zluda_hash_impl_part6(result: &mut [u8; 66], aux: [u8; 16]) { + let mut v30 = [0u8; 16]; + v30.copy_from_slice(&result[..16]); + result[48..].fill(0u8); + result[..16].fill(0u8); + for i in 0..16 { + anti_zluda_hash_round_v1(result, aux[i] ^ 0x5C); + } + for i in 0..16 { + anti_zluda_hash_round_v1(result, v30[i]); + } +} + +fn anti_zluda_hash_impl_part5(result: &mut [u8; 66]) { + let rounds = 16u8.wrapping_sub(result[64]); + if result[64] != 16 { + for _ in 0..rounds { + anti_zluda_hash_round_v1(result, rounds); + } + } +} + +fn anti_zluda_hash_impl_part4 AntiZludaHashInputDevice>( + result: &mut [u8; 66], + input: &AntiZludaHashInput, + mut dev_getter: F, +) { + for dev in 0..input.device_count { + let dev_input = dev_getter(dev); + let part4_input = AntiZludaHashPart4Input { + guid: dev_input.guid, + pci_domain: dev_input.pci_domain, + pci_bus: dev_input.pci_bus, + pci_device: dev_input.pci_device, + }; + let part4_input = unsafe { mem::transmute::<_, [u8; 28]>(part4_input) }; + for i in 0..28 { + anti_zluda_hash_round_v1(result, part4_input[i]); + } + } +} + +#[repr(C, packed)] +struct AntiZludaHashPart4Input { + guid: CUuuid, + pci_domain: u32, + pci_bus: u32, + pci_device: u32, +} + +fn anti_zluda_hash_impl_part3( + result: &mut [u8; 66], + input: &AntiZludaHashInput, + process_id: u32, + thread_id: u32, +) { + let input = AntiZludaHashPart3Input { + cudart_export_table: input.cudart_export_table, + anti_zluda_export_table: input.anti_zluda_export_table, + fn_ptr: input.fn_ptr, + driver_version: input.driver_version, + rt_version: input.rt_version, + timestamp: input.timestamp, + process_id: process_id, + thread_id: thread_id, + }; + let input = unsafe { mem::transmute::<_, [u8; 48]>(input) }; + for i in 0..48 { + anti_zluda_hash_round_v1(result, input[i]); + } +} + +#[repr(C)] +struct AntiZludaHashPart3Input { + driver_version: u32, + rt_version: u32, + process_id: u32, + thread_id: u32, + cudart_export_table: *mut c_void, + anti_zluda_export_table: *mut c_void, + fn_ptr: *mut c_void, + timestamp: u64, +} + +fn anti_zluda_hash_impl_part2(result: &mut [u8; 66], aux: [u8; 16]) { + for i in 0..16 { + anti_zluda_hash_round_v1(result, aux[i] ^ 0x36); + } +} + +fn anti_zluda_hash_impl_part1(aux: &mut [u8; 16]) { + let mut i = 13usize; + let mut temp: u8 = 0x8b; + loop { + let part1 = ANTI_ZLUDA_HASH_TABLE_PART1[i + 16] + ^ ANTI_ZLUDA_HASH_TABLE_PART1[i + 32] + ^ ANTI_ZLUDA_HASH_TABLE_PART1[i + 48]; + let part2 = temp ^ ANTI_ZLUDA_HASH_TABLE_PART1[i] ^ ANTI_ZLUDA_HASH_TABLE_PART1[i + 16]; + temp = !(part1 ^ temp); + let offset = part2 as usize >> 4; + i = (part2 & 0xF) as usize; + aux[offset] = part1; + if i == 13 { + break; + } + } +} + +const ANTI_ZLUDA_HASH_ROUND_TABLE: [u8; 256] = [ + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, + 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, + 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, + 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, + 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, + 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, + 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, + 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, + 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, + 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, + 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, + 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, + 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14, +]; + +fn anti_zluda_hash_round_v1(input: &mut [u8], constant: u8) { + let mut current_index = input[64] as usize; + input[current_index + 32] = input[current_index] ^ constant; + input[current_index + 16] = constant; + input[current_index + 48] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[(input[65] ^ constant) as usize]; + let temp = input[current_index + 48]; + current_index = set_byte_0(current_index, ((current_index + 1) & 0xF) as u8); + input[65] = temp; + input[64] = current_index as u8; + if current_index as u8 == 0 { + let mut i = 0u8; + for j in 0u8..18 { + let mut offset = 2; + for _ in 0..2 { + offset += 24; + input[offset - 26] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[i as usize]; + input[offset - 25] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 26] as usize]; + input[offset - 24] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 25] as usize]; + input[offset - 23] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 24] as usize]; + input[offset - 22] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 23] as usize]; + input[offset - 21] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 22] as usize]; + input[offset - 20] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 21] as usize]; + input[offset - 19] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 20] as usize]; + input[offset - 18] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 19] as usize]; + input[offset - 17] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 18] as usize]; + input[offset - 16] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 17] as usize]; + input[offset - 15] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 16] as usize]; + input[offset - 14] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 15] as usize]; + input[offset - 13] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 14] as usize]; + input[offset - 12] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 13] as usize]; + input[offset - 11] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 12] as usize]; + input[offset - 10] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 11] as usize]; + input[offset - 9] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 10] as usize]; + input[offset - 8] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 9] as usize]; + input[offset - 7] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 8] as usize]; + input[offset - 6] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 7] as usize]; + input[offset - 5] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 6] as usize]; + input[offset - 4] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 5] as usize]; + input[offset - 3] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 4] as usize]; + i = input[offset - 3]; + } + i = i.wrapping_add(j); + } + } +} + +fn anti_zluda_hash_round_v2(input: &mut [u8], input2_start: usize) { + for i in 0..16 { + let index_2 = input[input2_start + i] as usize; + let mut index_1 = input[64] as usize; + input[index_1 + 32] = input[index_1] ^ input[input2_start + i]; + input[index_1 + 16] = index_2 as u8; + input[index_1 + 48] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[index_2 ^ input[65] as usize]; + let index_3 = input[index_1 + 48]; + index_1 = set_byte_0(index_1, ((index_1 + 1) & 0xF) as u8); + input[64] = index_1 as u8; + input[65] = index_3; + if index_1 == 0 { + let mut temp = 0u8; + for j in 0..18 { + let mut offset = 2; + for _ in 0..2 { + offset += 24; + input[offset - 26] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[temp as usize]; + input[offset - 25] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 26] as usize]; + input[offset - 24] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 25] as usize]; + input[offset - 23] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 24] as usize]; + input[offset - 22] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 23] as usize]; + input[offset - 21] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 22] as usize]; + input[offset - 20] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 21] as usize]; + input[offset - 19] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 20] as usize]; + input[offset - 18] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 19] as usize]; + input[offset - 17] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 18] as usize]; + input[offset - 16] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 17] as usize]; + input[offset - 15] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 16] as usize]; + input[offset - 14] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 15] as usize]; + input[offset - 13] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 14] as usize]; + input[offset - 12] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 13] as usize]; + input[offset - 11] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 12] as usize]; + input[offset - 10] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 11] as usize]; + input[offset - 9] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 10] as usize]; + input[offset - 8] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 9] as usize]; + input[offset - 7] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 8] as usize]; + input[offset - 6] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 7] as usize]; + input[offset - 5] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 6] as usize]; + input[offset - 4] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 5] as usize]; + input[offset - 3] ^= ANTI_ZLUDA_HASH_ROUND_TABLE[input[offset - 4] as usize]; + temp = input[offset - 3]; + } + temp = temp.wrapping_add(j); + } + } + } +} + +fn set_byte_0(x: usize, y: u8) -> usize { + let mut x = x.to_le_bytes(); + x[0] = y; + usize::from_le_bytes(x) +} + +#[cfg(test)] +mod tests { + use cuda_types::CUuuid; + + use crate::{ + anti_zluda_hash_impl, anti_zluda_hash_round_v1, AntiZludaHashInput, + AntiZludaHashInputDevice, + }; + + #[test] + fn anti_zluda_hash_round_sample() { + let mut input: [u8; 66] = [ + 0x8B, 0x21, 0x9A, 0x49, 0xE8, 0x6D, 0x1A, 0xEE, 0xF2, 0x37, 0xF9, 0xB5, 0x4A, 0x8C, + 0x3C, 0x75, 0xF4, 0x1E, 0xEE, 0x21, 0xCF, 0x29, 0x8A, 0xE5, 0x13, 0x83, 0xF4, 0xEC, + 0x33, 0x04, 0xE2, 0xFD, 0x7F, 0x2F, 0x09, 0x01, 0x4F, 0xF7, 0x68, 0x6D, 0x69, 0x46, + 0x43, 0x7E, 0xB6, 0x2B, 0x21, 0xED, 0xB6, 0xA1, 0x10, 0x86, 0x0E, 0x60, 0x44, 0x1E, + 0x70, 0x5F, 0x67, 0xD1, 0xEB, 0x67, 0xA1, 0x3D, 0x01, 0xB6, + ]; + anti_zluda_hash_round_v1(&mut input, 0x2e); + let expected: [u8; 66] = [ + 0x8B, 0x21, 0x9A, 0x49, 0xE8, 0x6D, 0x1A, 0xEE, 0xF2, 0x37, 0xF9, 0xB5, 0x4A, 0x8C, + 0x3C, 0x75, 0xF4, 0x2E, 0xEE, 0x21, 0xCF, 0x29, 0x8A, 0xE5, 0x13, 0x83, 0xF4, 0xEC, + 0x33, 0x04, 0xE2, 0xFD, 0x7F, 0x0F, 0x09, 0x01, 0x4F, 0xF7, 0x68, 0x6D, 0x69, 0x46, + 0x43, 0x7E, 0xB6, 0x2B, 0x21, 0xED, 0xB6, 0xBD, 0x10, 0x86, 0x0E, 0x60, 0x44, 0x1E, + 0x70, 0x5F, 0x67, 0xD1, 0xEB, 0x67, 0xA1, 0x3D, 0x02, 0xBD, + ]; + assert_eq!(input, expected); + } + + #[test] + fn anti_zluda_hash_impl_sample() { + let process_id = 0x0000000000004D08; + let thread_id = 0x0000000000002B78; + let dev_getter = |_| AntiZludaHashInputDevice { + pci_domain: 0, + pci_bus: 4, + pci_device: 0, + guid: CUuuid { + bytes: [ + 0x67, 0x22, 0xCB, 0xCF, 0xC6, 0x61, 0xF2, 0x92, 0x74, 0xD6, 0xED, 0x23, 0x2A, + 0x32, 0x13, 0x1C, + ], + }, + }; + let input = AntiZludaHashInput { + cudart_export_table: 0x00007FF8C80717F0u64 as _, + anti_zluda_export_table: 0x00007FF8C825E4B0u64 as _, + fn_ptr: 0x00007FF8C7DD0AD0u64 as _, + device_count: 1, + driver_version: 12020, + rt_version: 0x2B4A, + timestamp: 0x0000000064A365EE, + }; + let result = anti_zluda_hash_impl(false, input, dev_getter, process_id, thread_id); + assert_eq!(result, 0xEAF1313342BFCD84A7C34628F214707A); + } +} diff --git a/zluda_dnn/Cargo.toml b/zluda_dnn/Cargo.toml new file mode 100644 index 0000000..1ba5dce --- /dev/null +++ b/zluda_dnn/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "zluda_dnn" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "cudnn" +crate-type = ["cdylib"] + +[dependencies] +miopen-sys = { path = "../miopen-sys" } +hip_runtime-sys = { path = "../hip_runtime-sys" } + +[package.metadata.zluda] +linux_only = true +linux_names = ["libcudnn.so.7", "libcudnn.so.8"] +dump_names = ["libcudnn.so"] diff --git a/zluda_dnn/README b/zluda_dnn/README new file mode 100644 index 0000000..427d08f --- /dev/null +++ b/zluda_dnn/README @@ -0,0 +1,6 @@ +bindgen /usr/include/x86_64-linux-gnu/cudnn_v7.h -o src/cudnn_types_v7.rs --allowlist-type="^cudnn.*reference_t$" --blocklist-function="^.*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +bindgen /usr/include/x86_64-linux-gnu/cudnn_v8.h -o src/cudnn_types_v8.rs --allowlist-type="^libraryPropertyType$" --allowlist-type="^cudnn.*" --blocklist-function=".*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include -Ibuild +bindgen /usr/include/x86_64-linux-gnu/cudnn_v7.h -o src/cudnn_v7.rs --blocklist-type=".*" --allowlist-function="^cudnnGetConvolutionBackwardDataAlgorithm$" --allowlist-function="^cudnnGetConvolutionBackwardFilterAlgorithm$" --allowlist-function="^cudnnGetConvolutionForwardAlgorithm$" --allowlist-function="^cudnnSetRNNDescriptor$" --allowlist-function="^cudnnSetRNNDescriptor_v5$" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +bindgen /usr/include/x86_64-linux-gnu/cudnn_v8.h -o src/cudnn_v8.rs --blocklist-type=".*" --allowlist-function="^cudnn.*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include -I../zluda_dnn/build +sed -i -e 's/extern "C" {//g' -e 's/-> cudnnStatus_t;/-> cudnnStatus_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub unsafe extern "system" fn /g' src/cudnn_v7.rs +sed -i -e 's/extern "C" {//g' -e 's/-> cudnnStatus_t;/-> cudnnStatus_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub unsafe extern "system" fn /g' src/cudnn_v8.rs \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_adv_infer.h b/zluda_dnn/build/cudnn_adv_infer.h new file mode 100644 index 0000000..e284a2f --- /dev/null +++ b/zluda_dnn/build/cudnn_adv_infer.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_adv_train.h b/zluda_dnn/build/cudnn_adv_train.h new file mode 100644 index 0000000..7de0769 --- /dev/null +++ b/zluda_dnn/build/cudnn_adv_train.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_backend.h b/zluda_dnn/build/cudnn_backend.h new file mode 100644 index 0000000..fe6827c --- /dev/null +++ b/zluda_dnn/build/cudnn_backend.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_cnn_infer.h b/zluda_dnn/build/cudnn_cnn_infer.h new file mode 100644 index 0000000..12ab232 --- /dev/null +++ b/zluda_dnn/build/cudnn_cnn_infer.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_cnn_train.h b/zluda_dnn/build/cudnn_cnn_train.h new file mode 100644 index 0000000..ed445a0 --- /dev/null +++ b/zluda_dnn/build/cudnn_cnn_train.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_ops_infer.h b/zluda_dnn/build/cudnn_ops_infer.h new file mode 100644 index 0000000..a194d09 --- /dev/null +++ b/zluda_dnn/build/cudnn_ops_infer.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/build/cudnn_ops_train.h b/zluda_dnn/build/cudnn_ops_train.h new file mode 100644 index 0000000..b7a6aad --- /dev/null +++ b/zluda_dnn/build/cudnn_ops_train.h @@ -0,0 +1 @@ +#include diff --git a/zluda_dnn/build/cudnn_version.h b/zluda_dnn/build/cudnn_version.h new file mode 100644 index 0000000..75b2982 --- /dev/null +++ b/zluda_dnn/build/cudnn_version.h @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/zluda_dnn/src/cudnn_types_v7.rs b/zluda_dnn/src/cudnn_types_v7.rs new file mode 100644 index 0000000..5f86e51 --- /dev/null +++ b/zluda_dnn/src/cudnn_types_v7.rs @@ -0,0 +1,47 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +impl cudnnConvolutionFwdPreference_t { + pub const CUDNN_CONVOLUTION_FWD_NO_WORKSPACE: cudnnConvolutionFwdPreference_t = + cudnnConvolutionFwdPreference_t(0); +} +impl cudnnConvolutionFwdPreference_t { + pub const CUDNN_CONVOLUTION_FWD_PREFER_FASTEST: cudnnConvolutionFwdPreference_t = + cudnnConvolutionFwdPreference_t(1); +} +impl cudnnConvolutionFwdPreference_t { + pub const CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT: cudnnConvolutionFwdPreference_t = + cudnnConvolutionFwdPreference_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionFwdPreference_t(pub ::std::os::raw::c_uint); +impl cudnnConvolutionBwdFilterPreference_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_NO_WORKSPACE: cudnnConvolutionBwdFilterPreference_t = + cudnnConvolutionBwdFilterPreference_t(0); +} +impl cudnnConvolutionBwdFilterPreference_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_PREFER_FASTEST: cudnnConvolutionBwdFilterPreference_t = + cudnnConvolutionBwdFilterPreference_t(1); +} +impl cudnnConvolutionBwdFilterPreference_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT: + cudnnConvolutionBwdFilterPreference_t = cudnnConvolutionBwdFilterPreference_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionBwdFilterPreference_t(pub ::std::os::raw::c_uint); +impl cudnnConvolutionBwdDataPreference_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_NO_WORKSPACE: cudnnConvolutionBwdDataPreference_t = + cudnnConvolutionBwdDataPreference_t(0); +} +impl cudnnConvolutionBwdDataPreference_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST: cudnnConvolutionBwdDataPreference_t = + cudnnConvolutionBwdDataPreference_t(1); +} +impl cudnnConvolutionBwdDataPreference_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT: + cudnnConvolutionBwdDataPreference_t = cudnnConvolutionBwdDataPreference_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionBwdDataPreference_t(pub ::std::os::raw::c_uint); diff --git a/zluda_dnn/src/cudnn_types_v8.rs b/zluda_dnn/src/cudnn_types_v8.rs new file mode 100644 index 0000000..b6b5ebd --- /dev/null +++ b/zluda_dnn/src/cudnn_types_v8.rs @@ -0,0 +1,2813 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUstream_st { + _unused: [u8; 0], +} +#[doc = " CUDA stream"] +pub type cudaStream_t = *mut CUstream_st; +impl libraryPropertyType_t { + pub const MAJOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(0); +} +impl libraryPropertyType_t { + pub const MINOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(1); +} +impl libraryPropertyType_t { + pub const PATCH_LEVEL: libraryPropertyType_t = libraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::libraryPropertyType_t as libraryPropertyType; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnContext { + _unused: [u8; 0], +} +pub type cudnnHandle_t = *mut cudnnContext; +impl cudnnStatus_t { + pub const CUDNN_STATUS_SUCCESS: cudnnStatus_t = cudnnStatus_t(0); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_NOT_INITIALIZED: cudnnStatus_t = cudnnStatus_t(1); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_ALLOC_FAILED: cudnnStatus_t = cudnnStatus_t(2); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_BAD_PARAM: cudnnStatus_t = cudnnStatus_t(3); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_INTERNAL_ERROR: cudnnStatus_t = cudnnStatus_t(4); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_INVALID_VALUE: cudnnStatus_t = cudnnStatus_t(5); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_ARCH_MISMATCH: cudnnStatus_t = cudnnStatus_t(6); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_MAPPING_ERROR: cudnnStatus_t = cudnnStatus_t(7); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_EXECUTION_FAILED: cudnnStatus_t = cudnnStatus_t(8); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_NOT_SUPPORTED: cudnnStatus_t = cudnnStatus_t(9); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_LICENSE_ERROR: cudnnStatus_t = cudnnStatus_t(10); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_RUNTIME_PREREQUISITE_MISSING: cudnnStatus_t = cudnnStatus_t(11); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_RUNTIME_IN_PROGRESS: cudnnStatus_t = cudnnStatus_t(12); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_RUNTIME_FP_OVERFLOW: cudnnStatus_t = cudnnStatus_t(13); +} +impl cudnnStatus_t { + pub const CUDNN_STATUS_VERSION_MISMATCH: cudnnStatus_t = cudnnStatus_t(14); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnStatus_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnRuntimeTag_t { + _unused: [u8; 0], +} +impl cudnnErrQueryMode_t { + pub const CUDNN_ERRQUERY_RAWCODE: cudnnErrQueryMode_t = cudnnErrQueryMode_t(0); +} +impl cudnnErrQueryMode_t { + pub const CUDNN_ERRQUERY_NONBLOCKING: cudnnErrQueryMode_t = cudnnErrQueryMode_t(1); +} +impl cudnnErrQueryMode_t { + pub const CUDNN_ERRQUERY_BLOCKING: cudnnErrQueryMode_t = cudnnErrQueryMode_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnErrQueryMode_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnTensorStruct { + _unused: [u8; 0], +} +pub type cudnnTensorDescriptor_t = *mut cudnnTensorStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnPoolingStruct { + _unused: [u8; 0], +} +pub type cudnnPoolingDescriptor_t = *mut cudnnPoolingStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnFilterStruct { + _unused: [u8; 0], +} +pub type cudnnFilterDescriptor_t = *mut cudnnFilterStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnLRNStruct { + _unused: [u8; 0], +} +pub type cudnnLRNDescriptor_t = *mut cudnnLRNStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnActivationStruct { + _unused: [u8; 0], +} +pub type cudnnActivationDescriptor_t = *mut cudnnActivationStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnSpatialTransformerStruct { + _unused: [u8; 0], +} +pub type cudnnSpatialTransformerDescriptor_t = *mut cudnnSpatialTransformerStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnOpTensorStruct { + _unused: [u8; 0], +} +pub type cudnnOpTensorDescriptor_t = *mut cudnnOpTensorStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnReduceTensorStruct { + _unused: [u8; 0], +} +pub type cudnnReduceTensorDescriptor_t = *mut cudnnReduceTensorStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnCTCLossStruct { + _unused: [u8; 0], +} +pub type cudnnCTCLossDescriptor_t = *mut cudnnCTCLossStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnTensorTransformStruct { + _unused: [u8; 0], +} +pub type cudnnTensorTransformDescriptor_t = *mut cudnnTensorTransformStruct; +impl cudnnDataType_t { + pub const CUDNN_DATA_FLOAT: cudnnDataType_t = cudnnDataType_t(0); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_DOUBLE: cudnnDataType_t = cudnnDataType_t(1); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_HALF: cudnnDataType_t = cudnnDataType_t(2); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_INT8: cudnnDataType_t = cudnnDataType_t(3); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_INT32: cudnnDataType_t = cudnnDataType_t(4); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_INT8x4: cudnnDataType_t = cudnnDataType_t(5); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_UINT8: cudnnDataType_t = cudnnDataType_t(6); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_UINT8x4: cudnnDataType_t = cudnnDataType_t(7); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_INT8x32: cudnnDataType_t = cudnnDataType_t(8); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_BFLOAT16: cudnnDataType_t = cudnnDataType_t(9); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_INT64: cudnnDataType_t = cudnnDataType_t(10); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_BOOLEAN: cudnnDataType_t = cudnnDataType_t(11); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_FP8_E4M3: cudnnDataType_t = cudnnDataType_t(12); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_FP8_E5M2: cudnnDataType_t = cudnnDataType_t(13); +} +impl cudnnDataType_t { + pub const CUDNN_DATA_FAST_FLOAT_FOR_FP8: cudnnDataType_t = cudnnDataType_t(14); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnDataType_t(pub ::std::os::raw::c_uint); +impl cudnnMathType_t { + pub const CUDNN_DEFAULT_MATH: cudnnMathType_t = cudnnMathType_t(0); +} +impl cudnnMathType_t { + pub const CUDNN_TENSOR_OP_MATH: cudnnMathType_t = cudnnMathType_t(1); +} +impl cudnnMathType_t { + pub const CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION: cudnnMathType_t = cudnnMathType_t(2); +} +impl cudnnMathType_t { + pub const CUDNN_FMA_MATH: cudnnMathType_t = cudnnMathType_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnMathType_t(pub ::std::os::raw::c_uint); +impl cudnnNanPropagation_t { + pub const CUDNN_NOT_PROPAGATE_NAN: cudnnNanPropagation_t = cudnnNanPropagation_t(0); +} +impl cudnnNanPropagation_t { + pub const CUDNN_PROPAGATE_NAN: cudnnNanPropagation_t = cudnnNanPropagation_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnNanPropagation_t(pub ::std::os::raw::c_uint); +impl cudnnDeterminism_t { + pub const CUDNN_NON_DETERMINISTIC: cudnnDeterminism_t = cudnnDeterminism_t(0); +} +impl cudnnDeterminism_t { + pub const CUDNN_DETERMINISTIC: cudnnDeterminism_t = cudnnDeterminism_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnDeterminism_t(pub ::std::os::raw::c_uint); +impl cudnnTensorFormat_t { + pub const CUDNN_TENSOR_NCHW: cudnnTensorFormat_t = cudnnTensorFormat_t(0); +} +impl cudnnTensorFormat_t { + pub const CUDNN_TENSOR_NHWC: cudnnTensorFormat_t = cudnnTensorFormat_t(1); +} +impl cudnnTensorFormat_t { + pub const CUDNN_TENSOR_NCHW_VECT_C: cudnnTensorFormat_t = cudnnTensorFormat_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnTensorFormat_t(pub ::std::os::raw::c_uint); +impl cudnnFoldingDirection_t { + pub const CUDNN_TRANSFORM_FOLD: cudnnFoldingDirection_t = cudnnFoldingDirection_t(0); +} +impl cudnnFoldingDirection_t { + pub const CUDNN_TRANSFORM_UNFOLD: cudnnFoldingDirection_t = cudnnFoldingDirection_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnFoldingDirection_t(pub ::std::os::raw::c_uint); +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_ADD: cudnnOpTensorOp_t = cudnnOpTensorOp_t(0); +} +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_MUL: cudnnOpTensorOp_t = cudnnOpTensorOp_t(1); +} +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_MIN: cudnnOpTensorOp_t = cudnnOpTensorOp_t(2); +} +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_MAX: cudnnOpTensorOp_t = cudnnOpTensorOp_t(3); +} +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_SQRT: cudnnOpTensorOp_t = cudnnOpTensorOp_t(4); +} +impl cudnnOpTensorOp_t { + pub const CUDNN_OP_TENSOR_NOT: cudnnOpTensorOp_t = cudnnOpTensorOp_t(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnOpTensorOp_t(pub ::std::os::raw::c_uint); +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_ADD: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(0); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_MUL: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(1); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_MIN: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(2); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_MAX: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(3); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_AMAX: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(4); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_AVG: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(5); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_NORM1: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(6); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_NORM2: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(7); +} +impl cudnnReduceTensorOp_t { + pub const CUDNN_REDUCE_TENSOR_MUL_NO_ZEROS: cudnnReduceTensorOp_t = cudnnReduceTensorOp_t(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnReduceTensorOp_t(pub ::std::os::raw::c_uint); +impl cudnnReduceTensorIndices_t { + pub const CUDNN_REDUCE_TENSOR_NO_INDICES: cudnnReduceTensorIndices_t = + cudnnReduceTensorIndices_t(0); +} +impl cudnnReduceTensorIndices_t { + pub const CUDNN_REDUCE_TENSOR_FLATTENED_INDICES: cudnnReduceTensorIndices_t = + cudnnReduceTensorIndices_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnReduceTensorIndices_t(pub ::std::os::raw::c_uint); +impl cudnnIndicesType_t { + pub const CUDNN_32BIT_INDICES: cudnnIndicesType_t = cudnnIndicesType_t(0); +} +impl cudnnIndicesType_t { + pub const CUDNN_64BIT_INDICES: cudnnIndicesType_t = cudnnIndicesType_t(1); +} +impl cudnnIndicesType_t { + pub const CUDNN_16BIT_INDICES: cudnnIndicesType_t = cudnnIndicesType_t(2); +} +impl cudnnIndicesType_t { + pub const CUDNN_8BIT_INDICES: cudnnIndicesType_t = cudnnIndicesType_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnIndicesType_t(pub ::std::os::raw::c_uint); +impl cudnnSoftmaxAlgorithm_t { + pub const CUDNN_SOFTMAX_FAST: cudnnSoftmaxAlgorithm_t = cudnnSoftmaxAlgorithm_t(0); +} +impl cudnnSoftmaxAlgorithm_t { + pub const CUDNN_SOFTMAX_ACCURATE: cudnnSoftmaxAlgorithm_t = cudnnSoftmaxAlgorithm_t(1); +} +impl cudnnSoftmaxAlgorithm_t { + pub const CUDNN_SOFTMAX_LOG: cudnnSoftmaxAlgorithm_t = cudnnSoftmaxAlgorithm_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSoftmaxAlgorithm_t(pub ::std::os::raw::c_uint); +impl cudnnSoftmaxMode_t { + pub const CUDNN_SOFTMAX_MODE_INSTANCE: cudnnSoftmaxMode_t = cudnnSoftmaxMode_t(0); +} +impl cudnnSoftmaxMode_t { + pub const CUDNN_SOFTMAX_MODE_CHANNEL: cudnnSoftmaxMode_t = cudnnSoftmaxMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSoftmaxMode_t(pub ::std::os::raw::c_uint); +impl cudnnPoolingMode_t { + pub const CUDNN_POOLING_MAX: cudnnPoolingMode_t = cudnnPoolingMode_t(0); +} +impl cudnnPoolingMode_t { + pub const CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING: cudnnPoolingMode_t = + cudnnPoolingMode_t(1); +} +impl cudnnPoolingMode_t { + pub const CUDNN_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING: cudnnPoolingMode_t = + cudnnPoolingMode_t(2); +} +impl cudnnPoolingMode_t { + pub const CUDNN_POOLING_MAX_DETERMINISTIC: cudnnPoolingMode_t = cudnnPoolingMode_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnPoolingMode_t(pub ::std::os::raw::c_uint); +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_SIGMOID: cudnnActivationMode_t = cudnnActivationMode_t(0); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_RELU: cudnnActivationMode_t = cudnnActivationMode_t(1); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_TANH: cudnnActivationMode_t = cudnnActivationMode_t(2); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_CLIPPED_RELU: cudnnActivationMode_t = cudnnActivationMode_t(3); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_ELU: cudnnActivationMode_t = cudnnActivationMode_t(4); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_IDENTITY: cudnnActivationMode_t = cudnnActivationMode_t(5); +} +impl cudnnActivationMode_t { + pub const CUDNN_ACTIVATION_SWISH: cudnnActivationMode_t = cudnnActivationMode_t(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnActivationMode_t(pub ::std::os::raw::c_uint); +impl cudnnLRNMode_t { + pub const CUDNN_LRN_CROSS_CHANNEL_DIM1: cudnnLRNMode_t = cudnnLRNMode_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnLRNMode_t(pub ::std::os::raw::c_uint); +impl cudnnDivNormMode_t { + pub const CUDNN_DIVNORM_PRECOMPUTED_MEANS: cudnnDivNormMode_t = cudnnDivNormMode_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnDivNormMode_t(pub ::std::os::raw::c_uint); +impl cudnnBatchNormMode_t { + pub const CUDNN_BATCHNORM_PER_ACTIVATION: cudnnBatchNormMode_t = cudnnBatchNormMode_t(0); +} +impl cudnnBatchNormMode_t { + pub const CUDNN_BATCHNORM_SPATIAL: cudnnBatchNormMode_t = cudnnBatchNormMode_t(1); +} +impl cudnnBatchNormMode_t { + pub const CUDNN_BATCHNORM_SPATIAL_PERSISTENT: cudnnBatchNormMode_t = cudnnBatchNormMode_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBatchNormMode_t(pub ::std::os::raw::c_uint); +impl cudnnBatchNormOps_t { + pub const CUDNN_BATCHNORM_OPS_BN: cudnnBatchNormOps_t = cudnnBatchNormOps_t(0); +} +impl cudnnBatchNormOps_t { + pub const CUDNN_BATCHNORM_OPS_BN_ACTIVATION: cudnnBatchNormOps_t = cudnnBatchNormOps_t(1); +} +impl cudnnBatchNormOps_t { + pub const CUDNN_BATCHNORM_OPS_BN_ADD_ACTIVATION: cudnnBatchNormOps_t = cudnnBatchNormOps_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBatchNormOps_t(pub ::std::os::raw::c_uint); +impl cudnnNormMode_t { + pub const CUDNN_NORM_PER_ACTIVATION: cudnnNormMode_t = cudnnNormMode_t(0); +} +impl cudnnNormMode_t { + pub const CUDNN_NORM_PER_CHANNEL: cudnnNormMode_t = cudnnNormMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnNormMode_t(pub ::std::os::raw::c_uint); +impl cudnnNormAlgo_t { + pub const CUDNN_NORM_ALGO_STANDARD: cudnnNormAlgo_t = cudnnNormAlgo_t(0); +} +impl cudnnNormAlgo_t { + pub const CUDNN_NORM_ALGO_PERSIST: cudnnNormAlgo_t = cudnnNormAlgo_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnNormAlgo_t(pub ::std::os::raw::c_uint); +impl cudnnNormOps_t { + pub const CUDNN_NORM_OPS_NORM: cudnnNormOps_t = cudnnNormOps_t(0); +} +impl cudnnNormOps_t { + pub const CUDNN_NORM_OPS_NORM_ACTIVATION: cudnnNormOps_t = cudnnNormOps_t(1); +} +impl cudnnNormOps_t { + pub const CUDNN_NORM_OPS_NORM_ADD_ACTIVATION: cudnnNormOps_t = cudnnNormOps_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnNormOps_t(pub ::std::os::raw::c_uint); +impl cudnnSamplerType_t { + pub const CUDNN_SAMPLER_BILINEAR: cudnnSamplerType_t = cudnnSamplerType_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSamplerType_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnDropoutStruct { + _unused: [u8; 0], +} +pub type cudnnDropoutDescriptor_t = *mut cudnnDropoutStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnAlgorithmStruct { + _unused: [u8; 0], +} +pub type cudnnAlgorithmDescriptor_t = *mut cudnnAlgorithmStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnAlgorithmPerformanceStruct { + _unused: [u8; 0], +} +pub type cudnnAlgorithmPerformance_t = *mut cudnnAlgorithmPerformanceStruct; +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(0); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(1); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_GEMM: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(2); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_DIRECT: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(3); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_FFT: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(4); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_FFT_TILING: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(5); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(6); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(7); +} +impl cudnnConvolutionFwdAlgo_t { + pub const CUDNN_CONVOLUTION_FWD_ALGO_COUNT: cudnnConvolutionFwdAlgo_t = + cudnnConvolutionFwdAlgo_t(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionFwdAlgo_t(pub ::std::os::raw::c_uint); +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(0); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_1: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(1); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(2); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_3: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(3); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(4); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD_NONFUSED: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(5); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT_TILING: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(6); +} +impl cudnnConvolutionBwdFilterAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_FILTER_ALGO_COUNT: cudnnConvolutionBwdFilterAlgo_t = + cudnnConvolutionBwdFilterAlgo_t(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionBwdFilterAlgo_t(pub ::std::os::raw::c_uint); +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_0: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(0); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_1: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(1); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(2); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT_TILING: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(3); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(4); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD_NONFUSED: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(5); +} +impl cudnnConvolutionBwdDataAlgo_t { + pub const CUDNN_CONVOLUTION_BWD_DATA_ALGO_COUNT: cudnnConvolutionBwdDataAlgo_t = + cudnnConvolutionBwdDataAlgo_t(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionBwdDataAlgo_t(pub ::std::os::raw::c_uint); +impl cudnnRNNAlgo_t { + pub const CUDNN_RNN_ALGO_STANDARD: cudnnRNNAlgo_t = cudnnRNNAlgo_t(0); +} +impl cudnnRNNAlgo_t { + pub const CUDNN_RNN_ALGO_PERSIST_STATIC: cudnnRNNAlgo_t = cudnnRNNAlgo_t(1); +} +impl cudnnRNNAlgo_t { + pub const CUDNN_RNN_ALGO_PERSIST_DYNAMIC: cudnnRNNAlgo_t = cudnnRNNAlgo_t(2); +} +impl cudnnRNNAlgo_t { + pub const CUDNN_RNN_ALGO_PERSIST_STATIC_SMALL_H: cudnnRNNAlgo_t = cudnnRNNAlgo_t(3); +} +impl cudnnRNNAlgo_t { + pub const CUDNN_RNN_ALGO_COUNT: cudnnRNNAlgo_t = cudnnRNNAlgo_t(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNAlgo_t(pub ::std::os::raw::c_uint); +impl cudnnCTCLossAlgo_t { + pub const CUDNN_CTC_LOSS_ALGO_DETERMINISTIC: cudnnCTCLossAlgo_t = cudnnCTCLossAlgo_t(0); +} +impl cudnnCTCLossAlgo_t { + pub const CUDNN_CTC_LOSS_ALGO_NON_DETERMINISTIC: cudnnCTCLossAlgo_t = cudnnCTCLossAlgo_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnCTCLossAlgo_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnAlgorithmUnionStruct { + pub algo: cudnnAlgorithmUnionStruct_Algorithm, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union cudnnAlgorithmUnionStruct_Algorithm { + pub convFwdAlgo: cudnnConvolutionFwdAlgo_t, + pub convBwdFilterAlgo: cudnnConvolutionBwdFilterAlgo_t, + pub convBwdDataAlgo: cudnnConvolutionBwdDataAlgo_t, + pub RNNAlgo: cudnnRNNAlgo_t, + pub CTCLossAlgo: cudnnCTCLossAlgo_t, +} +pub type cudnnAlgorithm_t = cudnnAlgorithmUnionStruct; +impl cudnnSeverity_t { + pub const CUDNN_SEV_FATAL: cudnnSeverity_t = cudnnSeverity_t(0); +} +impl cudnnSeverity_t { + pub const CUDNN_SEV_ERROR: cudnnSeverity_t = cudnnSeverity_t(1); +} +impl cudnnSeverity_t { + pub const CUDNN_SEV_WARNING: cudnnSeverity_t = cudnnSeverity_t(2); +} +impl cudnnSeverity_t { + pub const CUDNN_SEV_INFO: cudnnSeverity_t = cudnnSeverity_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSeverity_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnDebugStruct { + pub cudnn_version: ::std::os::raw::c_uint, + pub cudnnStatus: cudnnStatus_t, + pub time_sec: ::std::os::raw::c_uint, + pub time_usec: ::std::os::raw::c_uint, + pub time_delta: ::std::os::raw::c_uint, + pub handle: cudnnHandle_t, + pub stream: cudaStream_t, + pub pid: ::std::os::raw::c_ulonglong, + pub tid: ::std::os::raw::c_ulonglong, + pub cudaDeviceId: ::std::os::raw::c_int, + pub reserved: [::std::os::raw::c_int; 15usize], +} +pub type cudnnDebug_t = cudnnDebugStruct; +pub type cudnnCallback_t = ::std::option::Option< + unsafe extern "C" fn( + sev: cudnnSeverity_t, + udata: *mut ::std::os::raw::c_void, + dbg: *const cudnnDebug_t, + msg: *const ::std::os::raw::c_char, + ), +>; +impl cudnnForwardMode_t { + pub const CUDNN_FWD_MODE_INFERENCE: cudnnForwardMode_t = cudnnForwardMode_t(0); +} +impl cudnnForwardMode_t { + pub const CUDNN_FWD_MODE_TRAINING: cudnnForwardMode_t = cudnnForwardMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnForwardMode_t(pub ::std::os::raw::c_uint); +impl cudnnRNNMode_t { + pub const CUDNN_RNN_RELU: cudnnRNNMode_t = cudnnRNNMode_t(0); +} +impl cudnnRNNMode_t { + pub const CUDNN_RNN_TANH: cudnnRNNMode_t = cudnnRNNMode_t(1); +} +impl cudnnRNNMode_t { + pub const CUDNN_LSTM: cudnnRNNMode_t = cudnnRNNMode_t(2); +} +impl cudnnRNNMode_t { + pub const CUDNN_GRU: cudnnRNNMode_t = cudnnRNNMode_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNMode_t(pub ::std::os::raw::c_uint); +impl cudnnRNNBiasMode_t { + pub const CUDNN_RNN_NO_BIAS: cudnnRNNBiasMode_t = cudnnRNNBiasMode_t(0); +} +impl cudnnRNNBiasMode_t { + pub const CUDNN_RNN_SINGLE_INP_BIAS: cudnnRNNBiasMode_t = cudnnRNNBiasMode_t(1); +} +impl cudnnRNNBiasMode_t { + pub const CUDNN_RNN_DOUBLE_BIAS: cudnnRNNBiasMode_t = cudnnRNNBiasMode_t(2); +} +impl cudnnRNNBiasMode_t { + pub const CUDNN_RNN_SINGLE_REC_BIAS: cudnnRNNBiasMode_t = cudnnRNNBiasMode_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNBiasMode_t(pub ::std::os::raw::c_uint); +impl cudnnDirectionMode_t { + pub const CUDNN_UNIDIRECTIONAL: cudnnDirectionMode_t = cudnnDirectionMode_t(0); +} +impl cudnnDirectionMode_t { + pub const CUDNN_BIDIRECTIONAL: cudnnDirectionMode_t = cudnnDirectionMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnDirectionMode_t(pub ::std::os::raw::c_uint); +impl cudnnRNNInputMode_t { + pub const CUDNN_LINEAR_INPUT: cudnnRNNInputMode_t = cudnnRNNInputMode_t(0); +} +impl cudnnRNNInputMode_t { + pub const CUDNN_SKIP_INPUT: cudnnRNNInputMode_t = cudnnRNNInputMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNInputMode_t(pub ::std::os::raw::c_uint); +impl cudnnRNNClipMode_t { + pub const CUDNN_RNN_CLIP_NONE: cudnnRNNClipMode_t = cudnnRNNClipMode_t(0); +} +impl cudnnRNNClipMode_t { + pub const CUDNN_RNN_CLIP_MINMAX: cudnnRNNClipMode_t = cudnnRNNClipMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNClipMode_t(pub ::std::os::raw::c_uint); +impl cudnnRNNDataLayout_t { + pub const CUDNN_RNN_DATA_LAYOUT_SEQ_MAJOR_UNPACKED: cudnnRNNDataLayout_t = + cudnnRNNDataLayout_t(0); +} +impl cudnnRNNDataLayout_t { + pub const CUDNN_RNN_DATA_LAYOUT_SEQ_MAJOR_PACKED: cudnnRNNDataLayout_t = + cudnnRNNDataLayout_t(1); +} +impl cudnnRNNDataLayout_t { + pub const CUDNN_RNN_DATA_LAYOUT_BATCH_MAJOR_UNPACKED: cudnnRNNDataLayout_t = + cudnnRNNDataLayout_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRNNDataLayout_t(pub ::std::os::raw::c_uint); +pub type cudnnRNNPaddingMode_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnRNNStruct { + _unused: [u8; 0], +} +pub type cudnnRNNDescriptor_t = *mut cudnnRNNStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnPersistentRNNPlan { + _unused: [u8; 0], +} +pub type cudnnPersistentRNNPlan_t = *mut cudnnPersistentRNNPlan; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnRNNDataStruct { + _unused: [u8; 0], +} +pub type cudnnRNNDataDescriptor_t = *mut cudnnRNNDataStruct; +impl cudnnSeqDataAxis_t { + pub const CUDNN_SEQDATA_TIME_DIM: cudnnSeqDataAxis_t = cudnnSeqDataAxis_t(0); +} +impl cudnnSeqDataAxis_t { + pub const CUDNN_SEQDATA_BATCH_DIM: cudnnSeqDataAxis_t = cudnnSeqDataAxis_t(1); +} +impl cudnnSeqDataAxis_t { + pub const CUDNN_SEQDATA_BEAM_DIM: cudnnSeqDataAxis_t = cudnnSeqDataAxis_t(2); +} +impl cudnnSeqDataAxis_t { + pub const CUDNN_SEQDATA_VECT_DIM: cudnnSeqDataAxis_t = cudnnSeqDataAxis_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSeqDataAxis_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnSeqDataStruct { + _unused: [u8; 0], +} +pub type cudnnSeqDataDescriptor_t = *mut cudnnSeqDataStruct; +pub type cudnnAttnQueryMap_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnAttnStruct { + _unused: [u8; 0], +} +pub type cudnnAttnDescriptor_t = *mut cudnnAttnStruct; +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_Q_WEIGHTS: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(0); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_K_WEIGHTS: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(1); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_V_WEIGHTS: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(2); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_O_WEIGHTS: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(3); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_Q_BIASES: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(4); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_K_BIASES: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(5); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_V_BIASES: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(6); +} +impl cudnnMultiHeadAttnWeightKind_t { + pub const CUDNN_MH_ATTN_O_BIASES: cudnnMultiHeadAttnWeightKind_t = + cudnnMultiHeadAttnWeightKind_t(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnMultiHeadAttnWeightKind_t(pub ::std::os::raw::c_uint); +impl cudnnWgradMode_t { + pub const CUDNN_WGRAD_MODE_ADD: cudnnWgradMode_t = cudnnWgradMode_t(0); +} +impl cudnnWgradMode_t { + pub const CUDNN_WGRAD_MODE_SET: cudnnWgradMode_t = cudnnWgradMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnWgradMode_t(pub ::std::os::raw::c_uint); +impl cudnnLossNormalizationMode_t { + pub const CUDNN_LOSS_NORMALIZATION_NONE: cudnnLossNormalizationMode_t = + cudnnLossNormalizationMode_t(0); +} +impl cudnnLossNormalizationMode_t { + pub const CUDNN_LOSS_NORMALIZATION_SOFTMAX: cudnnLossNormalizationMode_t = + cudnnLossNormalizationMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnLossNormalizationMode_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnConvolutionStruct { + _unused: [u8; 0], +} +pub type cudnnConvolutionDescriptor_t = *mut cudnnConvolutionStruct; +impl cudnnConvolutionMode_t { + pub const CUDNN_CONVOLUTION: cudnnConvolutionMode_t = cudnnConvolutionMode_t(0); +} +impl cudnnConvolutionMode_t { + pub const CUDNN_CROSS_CORRELATION: cudnnConvolutionMode_t = cudnnConvolutionMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnConvolutionMode_t(pub ::std::os::raw::c_uint); +impl cudnnReorderType_t { + pub const CUDNN_DEFAULT_REORDER: cudnnReorderType_t = cudnnReorderType_t(0); +} +impl cudnnReorderType_t { + pub const CUDNN_NO_REORDER: cudnnReorderType_t = cudnnReorderType_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnReorderType_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnConvolutionFwdAlgoPerfStruct { + pub algo: cudnnConvolutionFwdAlgo_t, + pub status: cudnnStatus_t, + pub time: f32, + pub memory: usize, + pub determinism: cudnnDeterminism_t, + pub mathType: cudnnMathType_t, + pub reserved: [::std::os::raw::c_int; 3usize], +} +pub type cudnnConvolutionFwdAlgoPerf_t = cudnnConvolutionFwdAlgoPerfStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnConvolutionBwdDataAlgoPerfStruct { + pub algo: cudnnConvolutionBwdDataAlgo_t, + pub status: cudnnStatus_t, + pub time: f32, + pub memory: usize, + pub determinism: cudnnDeterminism_t, + pub mathType: cudnnMathType_t, + pub reserved: [::std::os::raw::c_int; 3usize], +} +pub type cudnnConvolutionBwdDataAlgoPerf_t = cudnnConvolutionBwdDataAlgoPerfStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnFusedOpsConstParamStruct { + _unused: [u8; 0], +} +pub type cudnnFusedOpsConstParamPack_t = *mut cudnnFusedOpsConstParamStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnFusedOpsVariantParamStruct { + _unused: [u8; 0], +} +pub type cudnnFusedOpsVariantParamPack_t = *mut cudnnFusedOpsVariantParamStruct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnFusedOpsPlanStruct { + _unused: [u8; 0], +} +pub type cudnnFusedOpsPlan_t = *mut cudnnFusedOpsPlanStruct; +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_SCALE_BIAS_ACTIVATION_CONV_BNSTATS: cudnnFusedOps_t = cudnnFusedOps_t(0); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_SCALE_BIAS_ACTIVATION_WGRAD: cudnnFusedOps_t = cudnnFusedOps_t(1); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_BN_FINALIZE_STATISTICS_TRAINING: cudnnFusedOps_t = cudnnFusedOps_t(2); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_BN_FINALIZE_STATISTICS_INFERENCE: cudnnFusedOps_t = cudnnFusedOps_t(3); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_CONV_SCALE_BIAS_ADD_ACTIVATION: cudnnFusedOps_t = cudnnFusedOps_t(4); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_SCALE_BIAS_ADD_ACTIVATION_GEN_BITMASK: cudnnFusedOps_t = + cudnnFusedOps_t(5); +} +impl cudnnFusedOps_t { + pub const CUDNN_FUSED_DACTIVATION_FORK_DBATCHNORM: cudnnFusedOps_t = cudnnFusedOps_t(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnFusedOps_t(pub ::std::os::raw::c_uint); +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_XDESC: cudnnFusedOpsConstParamLabel_t = cudnnFusedOpsConstParamLabel_t(0); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_XDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(1); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_MODE: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(2); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_EQSCALEBIAS_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(3); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_EQSCALE_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(4); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_EQBIAS_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(5); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_ACTIVATION_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(6); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_CONV_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(7); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_WDESC: cudnnFusedOpsConstParamLabel_t = cudnnFusedOpsConstParamLabel_t(8); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_WDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(9); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DWDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(10); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DWDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(11); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_YDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(12); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_YDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(13); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DYDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(14); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DYDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(15); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_YSTATS_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(16); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_YSUM_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(17); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_YSQSUM_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(18); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_SCALEBIAS_MEANVAR_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(19); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_SCALE_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(20); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_BIAS_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(21); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_SAVED_MEAN_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(22); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_SAVED_INVSTD_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(23); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_RUNNING_MEAN_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(24); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_RUNNING_VAR_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(25); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_ZDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(26); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_ZDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(27); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_Z_EQSCALEBIAS_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(28); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_Z_EQSCALE_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(29); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_Z_EQBIAS_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(30); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_ACTIVATION_BITMASK_DESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(31); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_ACTIVATION_BITMASK_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(32); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DXDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(33); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DXDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(34); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DZDESC: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(35); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_DZDATA_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(36); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_DSCALE_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(37); +} +impl cudnnFusedOpsConstParamLabel_t { + pub const CUDNN_PARAM_BN_DBIAS_PLACEHOLDER: cudnnFusedOpsConstParamLabel_t = + cudnnFusedOpsConstParamLabel_t(38); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnFusedOpsConstParamLabel_t(pub ::std::os::raw::c_uint); +impl cudnnFusedOpsPointerPlaceHolder_t { + pub const CUDNN_PTR_NULL: cudnnFusedOpsPointerPlaceHolder_t = + cudnnFusedOpsPointerPlaceHolder_t(0); +} +impl cudnnFusedOpsPointerPlaceHolder_t { + pub const CUDNN_PTR_ELEM_ALIGNED: cudnnFusedOpsPointerPlaceHolder_t = + cudnnFusedOpsPointerPlaceHolder_t(1); +} +impl cudnnFusedOpsPointerPlaceHolder_t { + pub const CUDNN_PTR_16B_ALIGNED: cudnnFusedOpsPointerPlaceHolder_t = + cudnnFusedOpsPointerPlaceHolder_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnFusedOpsPointerPlaceHolder_t(pub ::std::os::raw::c_uint); +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_XDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(0); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_EQSCALE: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(1); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_EQBIAS: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(2); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_WDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(3); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_DWDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(4); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_YDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(5); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_DYDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(6); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_YSUM: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(7); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_YSQSUM: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(8); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_WORKSPACE: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(9); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_SCALE: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(10); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_BIAS: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(11); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_SAVED_MEAN: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(12); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_SAVED_INVSTD: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(13); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_RUNNING_MEAN: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(14); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_RUNNING_VAR: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(15); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_ZDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(16); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_Z_EQSCALE: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(17); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_Z_EQBIAS: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(18); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_ACTIVATION_BITMASK: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(19); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_DXDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(20); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_DZDATA: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(21); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_DSCALE: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(22); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_PTR_BN_DBIAS: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(23); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_SCALAR_SIZE_T_WORKSPACE_SIZE_IN_BYTES: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(100); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_SCALAR_INT64_T_BN_ACCUMULATION_COUNT: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(101); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_SCALAR_DOUBLE_BN_EXP_AVG_FACTOR: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(102); +} +impl cudnnFusedOpsVariantParamLabel_t { + pub const CUDNN_SCALAR_DOUBLE_BN_EPSILON: cudnnFusedOpsVariantParamLabel_t = + cudnnFusedOpsVariantParamLabel_t(103); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnFusedOpsVariantParamLabel_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnConvolutionBwdFilterAlgoPerfStruct { + pub algo: cudnnConvolutionBwdFilterAlgo_t, + pub status: cudnnStatus_t, + pub time: f32, + pub memory: usize, + pub determinism: cudnnDeterminism_t, + pub mathType: cudnnMathType_t, + pub reserved: [::std::os::raw::c_int; 3usize], +} +pub type cudnnConvolutionBwdFilterAlgoPerf_t = cudnnConvolutionBwdFilterAlgoPerfStruct; +pub type cudnnBackendDescriptor_t = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudnnFractionStruct { + pub numerator: i64, + pub denominator: i64, +} +pub type cudnnFraction_t = cudnnFractionStruct; +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ADD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(0); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ADD_SQUARE: cudnnPointwiseMode_t = cudnnPointwiseMode_t(5); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_DIV: cudnnPointwiseMode_t = cudnnPointwiseMode_t(6); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_MAX: cudnnPointwiseMode_t = cudnnPointwiseMode_t(3); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_MIN: cudnnPointwiseMode_t = cudnnPointwiseMode_t(2); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_MOD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(7); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_MUL: cudnnPointwiseMode_t = cudnnPointwiseMode_t(1); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_POW: cudnnPointwiseMode_t = cudnnPointwiseMode_t(8); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SUB: cudnnPointwiseMode_t = cudnnPointwiseMode_t(9); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ABS: cudnnPointwiseMode_t = cudnnPointwiseMode_t(10); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CEIL: cudnnPointwiseMode_t = cudnnPointwiseMode_t(11); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_COS: cudnnPointwiseMode_t = cudnnPointwiseMode_t(12); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_EXP: cudnnPointwiseMode_t = cudnnPointwiseMode_t(13); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_FLOOR: cudnnPointwiseMode_t = cudnnPointwiseMode_t(14); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_LOG: cudnnPointwiseMode_t = cudnnPointwiseMode_t(15); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_NEG: cudnnPointwiseMode_t = cudnnPointwiseMode_t(16); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_RSQRT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(17); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SIN: cudnnPointwiseMode_t = cudnnPointwiseMode_t(18); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SQRT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(4); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_TAN: cudnnPointwiseMode_t = cudnnPointwiseMode_t(19); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ERF: cudnnPointwiseMode_t = cudnnPointwiseMode_t(20); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_IDENTITY: cudnnPointwiseMode_t = cudnnPointwiseMode_t(21); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_RECIPROCAL: cudnnPointwiseMode_t = cudnnPointwiseMode_t(22); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_RELU_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(100); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_TANH_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(101); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SIGMOID_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(102); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ELU_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(103); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_GELU_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(104); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SOFTPLUS_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(105); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SWISH_FWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(106); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_GELU_APPROX_TANH_FWD: cudnnPointwiseMode_t = + cudnnPointwiseMode_t(107); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_RELU_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(200); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_TANH_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(201); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SIGMOID_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(202); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_ELU_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(203); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_GELU_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(204); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SOFTPLUS_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(205); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_SWISH_BWD: cudnnPointwiseMode_t = cudnnPointwiseMode_t(206); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_GELU_APPROX_TANH_BWD: cudnnPointwiseMode_t = + cudnnPointwiseMode_t(207); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_EQ: cudnnPointwiseMode_t = cudnnPointwiseMode_t(300); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_NEQ: cudnnPointwiseMode_t = cudnnPointwiseMode_t(301); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_GT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(302); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_GE: cudnnPointwiseMode_t = cudnnPointwiseMode_t(303); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_LT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(304); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_CMP_LE: cudnnPointwiseMode_t = cudnnPointwiseMode_t(305); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_LOGICAL_AND: cudnnPointwiseMode_t = cudnnPointwiseMode_t(400); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_LOGICAL_OR: cudnnPointwiseMode_t = cudnnPointwiseMode_t(401); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_LOGICAL_NOT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(402); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_GEN_INDEX: cudnnPointwiseMode_t = cudnnPointwiseMode_t(501); +} +impl cudnnPointwiseMode_t { + pub const CUDNN_POINTWISE_BINARY_SELECT: cudnnPointwiseMode_t = cudnnPointwiseMode_t(601); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnPointwiseMode_t(pub ::std::os::raw::c_uint); +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_NEAREST: cudnnResampleMode_t = cudnnResampleMode_t(0); +} +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_BILINEAR: cudnnResampleMode_t = cudnnResampleMode_t(1); +} +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_AVGPOOL: cudnnResampleMode_t = cudnnResampleMode_t(2); +} +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_AVGPOOL_INCLUDE_PADDING: cudnnResampleMode_t = cudnnResampleMode_t(2); +} +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_AVGPOOL_EXCLUDE_PADDING: cudnnResampleMode_t = cudnnResampleMode_t(4); +} +impl cudnnResampleMode_t { + pub const CUDNN_RESAMPLE_MAXPOOL: cudnnResampleMode_t = cudnnResampleMode_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnResampleMode_t(pub ::std::os::raw::c_uint); +impl cudnnSignalMode_t { + pub const CUDNN_SIGNAL_SET: cudnnSignalMode_t = cudnnSignalMode_t(0); +} +impl cudnnSignalMode_t { + pub const CUDNN_SIGNAL_WAIT: cudnnSignalMode_t = cudnnSignalMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnSignalMode_t(pub ::std::os::raw::c_uint); +impl cudnnGenStatsMode_t { + pub const CUDNN_GENSTATS_SUM_SQSUM: cudnnGenStatsMode_t = cudnnGenStatsMode_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnGenStatsMode_t(pub ::std::os::raw::c_uint); +impl cudnnBnFinalizeStatsMode_t { + pub const CUDNN_BN_FINALIZE_STATISTICS_TRAINING: cudnnBnFinalizeStatsMode_t = + cudnnBnFinalizeStatsMode_t(0); +} +impl cudnnBnFinalizeStatsMode_t { + pub const CUDNN_BN_FINALIZE_STATISTICS_INFERENCE: cudnnBnFinalizeStatsMode_t = + cudnnBnFinalizeStatsMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBnFinalizeStatsMode_t(pub ::std::os::raw::c_uint); +impl cudnnRngDistribution_t { + pub const CUDNN_RNG_DISTRIBUTION_BERNOULLI: cudnnRngDistribution_t = cudnnRngDistribution_t(0); +} +impl cudnnRngDistribution_t { + pub const CUDNN_RNG_DISTRIBUTION_UNIFORM: cudnnRngDistribution_t = cudnnRngDistribution_t(1); +} +impl cudnnRngDistribution_t { + pub const CUDNN_RNG_DISTRIBUTION_NORMAL: cudnnRngDistribution_t = cudnnRngDistribution_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnRngDistribution_t(pub ::std::os::raw::c_uint); +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(0); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_MATH_PREC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_NAN_PROPAGATION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(3); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(4); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(5); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_ELU_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(6); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_SOFTPLUS_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(7); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_SWISH_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(8); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_POINTWISE_AXIS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(9); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_COMP_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(100); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_CONV_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(101); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_DILATIONS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(102); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(103); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_POST_PADDINGS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(104); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_PRE_PADDINGS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(105); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(106); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINEHEUR_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(200); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINEHEUR_OPERATION_GRAPH: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(201); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINEHEUR_RESULTS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(202); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINECFG_ENGINE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(300); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINECFG_INTERMEDIATE_INFO: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(301); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINECFG_KNOB_CHOICES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(302); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_HANDLE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(400); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_ENGINE_CONFIG: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(401); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_WORKSPACE_SIZE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(402); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_COMPUTED_INTERMEDIATE_UIDS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(403); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(404); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_EXECUTION_PLAN_JSON_REPRESENTATION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(405); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(500); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_INTERMEDIATE_INFO_SIZE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(501); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_INTERMEDIATE_INFO_DEPENDENT_DATA_UIDS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(502); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_INTERMEDIATE_INFO_DEPENDENT_ATTRIBUTES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(503); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_CHOICE_KNOB_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(600); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_CHOICE_KNOB_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(601); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(700); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(701); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_CONV_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(702); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_W: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(703); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_X: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(704); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_FORWARD_Y: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(705); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(706); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(707); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_CONV_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(708); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_W: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(709); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DX: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(710); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_DATA_DY: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(711); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(712); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(713); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_CONV_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(714); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DW: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(715); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_X: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(716); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONVOLUTION_BWD_FILTER_DY: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(717); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(750); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(751); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_BDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(752); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(753); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_ALPHA1: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(754); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_ALPHA2: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(755); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_DXDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(756); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_DYDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(757); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_POINTWISE_TDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(758); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_GENSTATS_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(770); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_GENSTATS_MATH_PREC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(771); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_GENSTATS_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(772); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_GENSTATS_SUMDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(773); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_GENSTATS_SQSUMDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(774); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_STATS_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(780); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_MATH_PREC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(781); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_Y_SUM_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(782); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_Y_SQ_SUM_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(783); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(784); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_BIAS_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(785); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_PREV_RUNNING_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(786); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_PREV_RUNNING_VAR_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(787); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_UPDATED_RUNNING_MEAN_DESC: + cudnnBackendAttributeName_t = cudnnBackendAttributeName_t(788); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_UPDATED_RUNNING_VAR_DESC: + cudnnBackendAttributeName_t = cudnnBackendAttributeName_t(789); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_SAVED_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(790); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_SAVED_INV_STD_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(791); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_EQ_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(792); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_EQ_BIAS_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(793); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_ACCUM_COUNT_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(794); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_EPSILON_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(795); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_FINALIZE_EXP_AVERATE_FACTOR_DESC: + cudnnBackendAttributeName_t = cudnnBackendAttributeName_t(796); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATIONGRAPH_HANDLE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(800); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATIONGRAPH_OPS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(801); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATIONGRAPH_ENGINE_GLOBAL_COUNT: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(802); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_BYTE_ALIGNMENT: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(900); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_DATA_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(901); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_DIMENSIONS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(902); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_STRIDES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(903); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_VECTOR_COUNT: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(904); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_VECTORIZED_DIMENSION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(905); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_UNIQUE_ID: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(906); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_IS_VIRTUAL: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(907); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_IS_BY_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(908); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_REORDERING_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(909); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_TENSOR_RAGGED_OFFSET_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(913); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_VARIANT_PACK_UNIQUE_IDS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1000); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_VARIANT_PACK_DATA_POINTERS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1001); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_VARIANT_PACK_INTERMEDIATES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1002); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_VARIANT_PACK_WORKSPACE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1003); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_LAYOUT_INFO_TENSOR_UID: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1100); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_LAYOUT_INFO_TYPES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1101); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_INFO_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1200); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_INFO_MAXIMUM_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1201); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_INFO_MINIMUM_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1202); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_KNOB_INFO_STRIDE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1203); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_OPERATION_GRAPH: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1300); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_GLOBAL_INDEX: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1301); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_KNOB_INFO: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1302); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_NUMERICAL_NOTE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1303); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_LAYOUT_INFO: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1304); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_ENGINE_BEHAVIOR_NOTE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1305); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_MATMUL_COMP_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1500); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_MATMUL_PADDING_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1503); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_ADESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1520); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_BDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1521); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_CDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1522); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1523); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_IRREGULARLY_STRIDED_BATCH_COUNT: + cudnnBackendAttributeName_t = cudnnBackendAttributeName_t(1524); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1525); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1526); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1527); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_REDUCTION_OPERATOR: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1600); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_REDUCTION_COMP_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1601); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_REDUCTION_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1610); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_REDUCTION_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1611); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_REDUCTION_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1612); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_MATH_PREC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1620); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1621); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_INVSTD_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1622); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_BN_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1623); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_X_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1624); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DY_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1625); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DBN_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1626); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_DBN_BIAS_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1627); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_DY_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1628); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_X_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1629); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_BN_BWD_WEIGHTS_EQ_BIAS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1630); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1700); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_COMP_TYPE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1701); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_SPATIAL_DIMS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1702); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_POST_PADDINGS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1703); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_PRE_PADDINGS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1704); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_STRIDES: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1705); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_WINDOW_DIMS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1706); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_NAN_PROPAGATION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1707); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RESAMPLE_PADDING_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1708); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1710); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1711); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_IDXDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1712); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1713); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1714); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_FWD_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1716); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_DXDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1720); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_DYDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1721); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_IDXDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1722); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_ALPHA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1723); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_BETA: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1724); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1725); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1726); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESAMPLE_BWD_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1727); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONCAT_AXIS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1800); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONCAT_INPUT_DESCS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1801); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONCAT_INPLACE_INDEX: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1802); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_CONCAT_OUTPUT_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1803); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_SIGNAL_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1900); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_SIGNAL_FLAGDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1901); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_SIGNAL_VALUE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1902); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_SIGNAL_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1903); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_SIGNAL_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(1904); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2000); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_PHASE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2001); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2002); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2003); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_INV_VARIANCE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2004); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2005); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_BIAS_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2006); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_EPSILON_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2007); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_EXP_AVG_FACTOR_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2008); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_INPUT_RUNNING_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2009); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_INPUT_RUNNING_VAR_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2010); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_OUTPUT_RUNNING_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2011); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_OUTPUT_RUNNING_VAR_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2012); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2013); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_FWD_PEER_STAT_DESCS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2014); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_MODE: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2100); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2101); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_MEAN_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2102); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_INV_VARIANCE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2103); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_DYDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2104); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_SCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2105); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_EPSILON_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2106); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_DSCALE_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2107); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_DBIAS_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2108); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_DXDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2109); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_NORM_BWD_PEER_STAT_DESCS: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2110); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESHAPE_XDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2200); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RESHAPE_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2201); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_DISTRIBUTION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2300); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_NORMAL_DIST_MEAN: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2301); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_NORMAL_DIST_STANDARD_DEVIATION: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2302); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_UNIFORM_DIST_MAXIMUM: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2303); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_UNIFORM_DIST_MINIMUM: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2304); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_RNG_BERNOULLI_DIST_PROBABILITY: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2305); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RNG_YDESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2310); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RNG_SEED: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2311); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RNG_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2312); +} +impl cudnnBackendAttributeName_t { + pub const CUDNN_ATTR_OPERATION_RNG_OFFSET_DESC: cudnnBackendAttributeName_t = + cudnnBackendAttributeName_t(2313); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendAttributeName_t(pub ::std::os::raw::c_uint); +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_HANDLE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(0); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_DATA_TYPE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(1); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_BOOLEAN: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(2); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_INT64: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(3); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_FLOAT: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(4); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_DOUBLE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(5); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_VOID_PTR: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(6); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_CONVOLUTION_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(7); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_HEUR_MODE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(8); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_KNOB_TYPE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(9); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_NAN_PROPOGATION: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(10); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_NUMERICAL_NOTE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(11); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_LAYOUT_TYPE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(12); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_ATTRIB_NAME: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(13); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_POINTWISE_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(14); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_BACKEND_DESCRIPTOR: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(15); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_GENSTATS_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(16); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_BN_FINALIZE_STATS_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(17); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_REDUCTION_OPERATOR_TYPE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(18); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_BEHAVIOR_NOTE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(19); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_TENSOR_REORDERING_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(20); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_RESAMPLE_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(21); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_PADDING_MODE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(22); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_INT32: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(23); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_CHAR: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(24); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_SIGNAL_MODE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(25); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_FRACTION: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(26); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_NORM_MODE: cudnnBackendAttributeType_t = cudnnBackendAttributeType_t(27); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_NORM_FWD_PHASE: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(28); +} +impl cudnnBackendAttributeType_t { + pub const CUDNN_TYPE_RNG_DISTRIBUTION: cudnnBackendAttributeType_t = + cudnnBackendAttributeType_t(29); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendAttributeType_t(pub ::std::os::raw::c_uint); +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_POINTWISE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(0); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(1); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_ENGINE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(2); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(3); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_ENGINEHEUR_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(4); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_EXECUTION_PLAN_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(5); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_INTERMEDIATE_INFO_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(6); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(7); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_KNOB_INFO_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(8); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_LAYOUT_INFO_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(9); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(10); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR: + cudnnBackendDescriptorType_t = cudnnBackendDescriptorType_t(11); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: + cudnnBackendDescriptorType_t = cudnnBackendDescriptorType_t(12); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(13); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_GEN_STATS_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(14); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATIONGRAPH_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(15); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_VARIANT_PACK_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(16); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_TENSOR_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(17); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_MATMUL_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(18); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(19); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_BN_FINALIZE_STATISTICS_DESCRIPTOR: + cudnnBackendDescriptorType_t = cudnnBackendDescriptorType_t(20); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_REDUCTION_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(21); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(22); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_BN_BWD_WEIGHTS_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(23); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_RESAMPLE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(24); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_RESAMPLE_FWD_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(25); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_RESAMPLE_BWD_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(26); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_CONCAT_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(27); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_SIGNAL_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(28); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_NORM_FORWARD_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(29); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_NORM_BACKWARD_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(30); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_RESHAPE_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(31); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_RNG_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(32); +} +impl cudnnBackendDescriptorType_t { + pub const CUDNN_BACKEND_OPERATION_RNG_DESCRIPTOR: cudnnBackendDescriptorType_t = + cudnnBackendDescriptorType_t(33); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendDescriptorType_t(pub ::std::os::raw::c_uint); +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_TENSOR_CORE: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(0); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_DOWN_CONVERT_INPUTS: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(1); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_REDUCED_PRECISION_REDUCTION: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(2); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_FFT: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(3); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_NONDETERMINISTIC: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(4); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_WINOGRAD: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(5); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_WINOGRAD_TILE_4x4: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(6); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_WINOGRAD_TILE_6x6: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(7); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_WINOGRAD_TILE_13x13: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(8); +} +impl cudnnBackendNumericalNote_t { + pub const CUDNN_NUMERICAL_NOTE_TYPE_COUNT: cudnnBackendNumericalNote_t = + cudnnBackendNumericalNote_t(9); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendNumericalNote_t(pub ::std::os::raw::c_uint); +impl cudnnBackendBehaviorNote_t { + pub const CUDNN_BEHAVIOR_NOTE_RUNTIME_COMPILATION: cudnnBackendBehaviorNote_t = + cudnnBackendBehaviorNote_t(0); +} +impl cudnnBackendBehaviorNote_t { + pub const CUDNN_BEHAVIOR_NOTE_REQUIRES_FILTER_INT8x32_REORDER: cudnnBackendBehaviorNote_t = + cudnnBackendBehaviorNote_t(1); +} +impl cudnnBackendBehaviorNote_t { + pub const CUDNN_BEHAVIOR_NOTE_REQUIRES_BIAS_INT8x32_REORDER: cudnnBackendBehaviorNote_t = + cudnnBackendBehaviorNote_t(2); +} +impl cudnnBackendBehaviorNote_t { + pub const CUDNN_BEHAVIOR_NOTE_TYPE_COUNT: cudnnBackendBehaviorNote_t = + cudnnBackendBehaviorNote_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendBehaviorNote_t(pub ::std::os::raw::c_uint); +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPLIT_K: cudnnBackendKnobType_t = cudnnBackendKnobType_t(0); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SWIZZLE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(1); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_TILE_SIZE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(2); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_USE_TEX: cudnnBackendKnobType_t = cudnnBackendKnobType_t(3); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_EDGE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(4); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_KBLOCK: cudnnBackendKnobType_t = cudnnBackendKnobType_t(5); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_LDGA: cudnnBackendKnobType_t = cudnnBackendKnobType_t(6); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_LDGB: cudnnBackendKnobType_t = cudnnBackendKnobType_t(7); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_CHUNK_K: cudnnBackendKnobType_t = cudnnBackendKnobType_t(8); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPLIT_H: cudnnBackendKnobType_t = cudnnBackendKnobType_t(9); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_WINO_TILE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(10); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_MULTIPLY: cudnnBackendKnobType_t = cudnnBackendKnobType_t(11); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPLIT_K_BUF: cudnnBackendKnobType_t = cudnnBackendKnobType_t(12); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_TILEK: cudnnBackendKnobType_t = cudnnBackendKnobType_t(13); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_STAGES: cudnnBackendKnobType_t = cudnnBackendKnobType_t(14); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_REDUCTION_MODE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(15); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_CTA_SPLIT_K_MODE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(16); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPLIT_K_SLC: cudnnBackendKnobType_t = cudnnBackendKnobType_t(17); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_IDX_MODE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(18); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SLICED: cudnnBackendKnobType_t = cudnnBackendKnobType_t(19); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPLIT_RS: cudnnBackendKnobType_t = cudnnBackendKnobType_t(20); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SINGLEBUFFER: cudnnBackendKnobType_t = cudnnBackendKnobType_t(21); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_LDGC: cudnnBackendKnobType_t = cudnnBackendKnobType_t(22); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_SPECFILT: cudnnBackendKnobType_t = cudnnBackendKnobType_t(23); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_KERNEL_CFG: cudnnBackendKnobType_t = cudnnBackendKnobType_t(24); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_WORKSPACE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(25); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_TILE_CGA: cudnnBackendKnobType_t = cudnnBackendKnobType_t(26); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_TILE_CGA_M: cudnnBackendKnobType_t = cudnnBackendKnobType_t(27); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_TILE_CGA_N: cudnnBackendKnobType_t = cudnnBackendKnobType_t(28); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_BLOCK_SIZE: cudnnBackendKnobType_t = cudnnBackendKnobType_t(29); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_OCCUPANCY: cudnnBackendKnobType_t = cudnnBackendKnobType_t(30); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_ARRAY_SIZE_PER_THREAD: cudnnBackendKnobType_t = + cudnnBackendKnobType_t(31); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_NUM_C_PER_BLOCK: cudnnBackendKnobType_t = cudnnBackendKnobType_t(32); +} +impl cudnnBackendKnobType_t { + pub const CUDNN_KNOB_TYPE_COUNTS: cudnnBackendKnobType_t = cudnnBackendKnobType_t(33); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendKnobType_t(pub ::std::os::raw::c_uint); +impl cudnnBackendLayoutType_t { + pub const CUDNN_LAYOUT_TYPE_PREFERRED_NCHW: cudnnBackendLayoutType_t = + cudnnBackendLayoutType_t(0); +} +impl cudnnBackendLayoutType_t { + pub const CUDNN_LAYOUT_TYPE_PREFERRED_NHWC: cudnnBackendLayoutType_t = + cudnnBackendLayoutType_t(1); +} +impl cudnnBackendLayoutType_t { + pub const CUDNN_LAYOUT_TYPE_PREFERRED_PAD4CK: cudnnBackendLayoutType_t = + cudnnBackendLayoutType_t(2); +} +impl cudnnBackendLayoutType_t { + pub const CUDNN_LAYOUT_TYPE_PREFERRED_PAD8CK: cudnnBackendLayoutType_t = + cudnnBackendLayoutType_t(3); +} +impl cudnnBackendLayoutType_t { + pub const CUDNN_LAYOUT_TYPE_COUNT: cudnnBackendLayoutType_t = cudnnBackendLayoutType_t(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendLayoutType_t(pub ::std::os::raw::c_uint); +impl cudnnBackendHeurMode_t { + pub const CUDNN_HEUR_MODE_INSTANT: cudnnBackendHeurMode_t = cudnnBackendHeurMode_t(0); +} +impl cudnnBackendHeurMode_t { + pub const CUDNN_HEUR_MODE_B: cudnnBackendHeurMode_t = cudnnBackendHeurMode_t(1); +} +impl cudnnBackendHeurMode_t { + pub const CUDNN_HEUR_MODE_FALLBACK: cudnnBackendHeurMode_t = cudnnBackendHeurMode_t(2); +} +impl cudnnBackendHeurMode_t { + pub const CUDNN_HEUR_MODE_A: cudnnBackendHeurMode_t = cudnnBackendHeurMode_t(3); +} +impl cudnnBackendHeurMode_t { + pub const CUDNN_HEUR_MODES_COUNT: cudnnBackendHeurMode_t = cudnnBackendHeurMode_t(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendHeurMode_t(pub ::std::os::raw::c_uint); +impl cudnnBackendTensorReordering_t { + pub const CUDNN_TENSOR_REORDERING_NONE: cudnnBackendTensorReordering_t = + cudnnBackendTensorReordering_t(0); +} +impl cudnnBackendTensorReordering_t { + pub const CUDNN_TENSOR_REORDERING_INT8x32: cudnnBackendTensorReordering_t = + cudnnBackendTensorReordering_t(1); +} +impl cudnnBackendTensorReordering_t { + pub const CUDNN_TENSOR_REORDERING_F16x16: cudnnBackendTensorReordering_t = + cudnnBackendTensorReordering_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendTensorReordering_t(pub ::std::os::raw::c_uint); +impl cudnnPaddingMode_t { + pub const CUDNN_ZERO_PAD: cudnnPaddingMode_t = cudnnPaddingMode_t(0); +} +impl cudnnPaddingMode_t { + pub const CUDNN_NEG_INF_PAD: cudnnPaddingMode_t = cudnnPaddingMode_t(1); +} +impl cudnnPaddingMode_t { + pub const CUDNN_EDGE_VAL_PAD: cudnnPaddingMode_t = cudnnPaddingMode_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnPaddingMode_t(pub ::std::os::raw::c_uint); +impl cudnnBackendNormMode_t { + pub const CUDNN_LAYER_NORM: cudnnBackendNormMode_t = cudnnBackendNormMode_t(0); +} +impl cudnnBackendNormMode_t { + pub const CUDNN_INSTANCE_NORM: cudnnBackendNormMode_t = cudnnBackendNormMode_t(1); +} +impl cudnnBackendNormMode_t { + pub const CUDNN_BATCH_NORM: cudnnBackendNormMode_t = cudnnBackendNormMode_t(2); +} +impl cudnnBackendNormMode_t { + pub const CUDNN_GROUP_NORM: cudnnBackendNormMode_t = cudnnBackendNormMode_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendNormMode_t(pub ::std::os::raw::c_uint); +impl cudnnBackendNormFwdPhase_t { + pub const CUDNN_NORM_FWD_INFERENCE: cudnnBackendNormFwdPhase_t = cudnnBackendNormFwdPhase_t(0); +} +impl cudnnBackendNormFwdPhase_t { + pub const CUDNN_NORM_FWD_TRAINING: cudnnBackendNormFwdPhase_t = cudnnBackendNormFwdPhase_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudnnBackendNormFwdPhase_t(pub ::std::os::raw::c_uint); diff --git a/zluda_dnn/src/cudnn_v7.rs b/zluda_dnn/src/cudnn_v7.rs new file mode 100644 index 0000000..4cd07d6 --- /dev/null +++ b/zluda_dnn/src/cudnn_v7.rs @@ -0,0 +1,91 @@ +use crate::types::*; + +/* automatically generated by rust-bindgen 0.66.1 */ + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionForwardAlgorithm( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + wDesc: cudnnFilterDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + preference: cudnnConvolutionFwdPreference_t, + memoryLimitInBytes: usize, + algo: *mut cudnnConvolutionFwdAlgo_t, +) -> cudnnStatus_t { + crate::get_convolution_forward_algorithm( + handle, + xDesc, + wDesc, + convDesc, + yDesc, + memoryLimitInBytes, + algo, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardFilterAlgorithm( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + dwDesc: cudnnFilterDescriptor_t, + preference: cudnnConvolutionBwdFilterPreference_t, + memoryLimitInBytes: usize, + algo: *mut cudnnConvolutionBwdFilterAlgo_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardDataAlgorithm( + handle: cudnnHandle_t, + wDesc: cudnnFilterDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + preference: cudnnConvolutionBwdDataPreference_t, + memoryLimitInBytes: usize, + algo: *mut cudnnConvolutionBwdDataAlgo_t, +) -> cudnnStatus_t { + crate::get_convolution_backward_data_algorithm( + handle, + wDesc, + dyDesc, + convDesc, + dxDesc, + memoryLimitInBytes, + algo, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNDescriptor( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + hiddenSize: ::std::os::raw::c_int, + numLayers: ::std::os::raw::c_int, + dropoutDesc: cudnnDropoutDescriptor_t, + inputMode: cudnnRNNInputMode_t, + direction: cudnnDirectionMode_t, + mode: cudnnRNNMode_t, + algo: cudnnRNNAlgo_t, + mathPrec: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNDescriptor_v5( + rnnDesc: cudnnRNNDescriptor_t, + hiddenSize: ::std::os::raw::c_int, + numLayers: ::std::os::raw::c_int, + dropoutDesc: cudnnDropoutDescriptor_t, + inputMode: cudnnRNNInputMode_t, + direction: cudnnDirectionMode_t, + mode: cudnnRNNMode_t, + mathPrec: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} diff --git a/zluda_dnn/src/cudnn_v8.rs b/zluda_dnn/src/cudnn_v8.rs new file mode 100644 index 0000000..8acde31 --- /dev/null +++ b/zluda_dnn/src/cudnn_v8.rs @@ -0,0 +1,3468 @@ +use crate::types::*; + +/* automatically generated by rust-bindgen 0.66.1 */ + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetVersion() -> usize { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetMaxDeviceVersion() -> usize { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCudartVersion() -> usize { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetErrorString( + status: cudnnStatus_t, +) -> *const ::std::os::raw::c_char { + unimplemented!() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnQueryRuntimeError( + handle: cudnnHandle_t, + rstatus: *mut cudnnStatus_t, + mode: cudnnErrQueryMode_t, + tag: *mut cudnnRuntimeTag_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetProperty( + type_: libraryPropertyType, + value: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreate(handle: *mut cudnnHandle_t) -> cudnnStatus_t { + crate::create(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroy(handle: cudnnHandle_t) -> cudnnStatus_t { + crate::destroy(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetStream( + handle: cudnnHandle_t, + streamId: cudaStream_t, +) -> cudnnStatus_t { + crate::set_stream(streamId) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetStream( + handle: cudnnHandle_t, + streamId: *mut cudaStream_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateTensorDescriptor( + tensorDesc: *mut cudnnTensorDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_tensor_descriptor(tensorDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensor4dDescriptor( + tensorDesc: cudnnTensorDescriptor_t, + format: cudnnTensorFormat_t, + dataType: cudnnDataType_t, + n: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + h: ::std::os::raw::c_int, + w: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensor4dDescriptorEx( + tensorDesc: cudnnTensorDescriptor_t, + dataType: cudnnDataType_t, + n: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + h: ::std::os::raw::c_int, + w: ::std::os::raw::c_int, + nStride: ::std::os::raw::c_int, + cStride: ::std::os::raw::c_int, + hStride: ::std::os::raw::c_int, + wStride: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::set_tensor_4d_descriptor_ex( + tensorDesc, dataType, n, c, h, w, nStride, cStride, hStride, wStride, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetTensor4dDescriptor( + tensorDesc: cudnnTensorDescriptor_t, + dataType: *mut cudnnDataType_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, + nStride: *mut ::std::os::raw::c_int, + cStride: *mut ::std::os::raw::c_int, + hStride: *mut ::std::os::raw::c_int, + wStride: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensorNdDescriptor( + tensorDesc: cudnnTensorDescriptor_t, + dataType: cudnnDataType_t, + nbDims: ::std::os::raw::c_int, + dimA: *const ::std::os::raw::c_int, + strideA: *const ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::set_tensor_nd_decriptor(tensorDesc, dataType, nbDims, dimA, strideA) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensorNdDescriptorEx( + tensorDesc: cudnnTensorDescriptor_t, + format: cudnnTensorFormat_t, + dataType: cudnnDataType_t, + nbDims: ::std::os::raw::c_int, + dimA: *const ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetTensorNdDescriptor( + tensorDesc: cudnnTensorDescriptor_t, + nbDimsRequested: ::std::os::raw::c_int, + dataType: *mut cudnnDataType_t, + nbDims: *mut ::std::os::raw::c_int, + dimA: *mut ::std::os::raw::c_int, + strideA: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetTensorSizeInBytes( + tensorDesc: cudnnTensorDescriptor_t, + size: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyTensorDescriptor( + tensorDesc: cudnnTensorDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_tensor_descriptor(tensorDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnInitTransformDest( + transformDesc: cudnnTensorTransformDescriptor_t, + srcDesc: cudnnTensorDescriptor_t, + destDesc: cudnnTensorDescriptor_t, + destSizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateTensorTransformDescriptor( + transformDesc: *mut cudnnTensorTransformDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensorTransformDescriptor( + transformDesc: cudnnTensorTransformDescriptor_t, + nbDims: u32, + destFormat: cudnnTensorFormat_t, + padBeforeA: *const i32, + padAfterA: *const i32, + foldA: *const u32, + direction: cudnnFoldingDirection_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetTensorTransformDescriptor( + transformDesc: cudnnTensorTransformDescriptor_t, + nbDimsRequested: u32, + destFormat: *mut cudnnTensorFormat_t, + padBeforeA: *mut i32, + padAfterA: *mut i32, + foldA: *mut u32, + direction: *mut cudnnFoldingDirection_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyTensorTransformDescriptor( + transformDesc: cudnnTensorTransformDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnTransformTensor( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::transform_tensor(handle, alpha, xDesc, x, beta, yDesc, y) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnTransformTensorEx( + handle: cudnnHandle_t, + transDesc: cudnnTensorTransformDescriptor_t, + alpha: *const ::std::os::raw::c_void, + srcDesc: cudnnTensorDescriptor_t, + srcData: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + destDesc: cudnnTensorDescriptor_t, + destData: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnAddTensor( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + aDesc: cudnnTensorDescriptor_t, + A: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + cDesc: cudnnTensorDescriptor_t, + C: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::add_tensor(handle, alpha, aDesc, A, beta, cDesc, C) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateOpTensorDescriptor( + opTensorDesc: *mut cudnnOpTensorDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetOpTensorDescriptor( + opTensorDesc: cudnnOpTensorDescriptor_t, + opTensorOp: cudnnOpTensorOp_t, + opTensorCompType: cudnnDataType_t, + opTensorNanOpt: cudnnNanPropagation_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetOpTensorDescriptor( + opTensorDesc: cudnnOpTensorDescriptor_t, + opTensorOp: *mut cudnnOpTensorOp_t, + opTensorCompType: *mut cudnnDataType_t, + opTensorNanOpt: *mut cudnnNanPropagation_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyOpTensorDescriptor( + opTensorDesc: cudnnOpTensorDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnOpTensor( + handle: cudnnHandle_t, + opTensorDesc: cudnnOpTensorDescriptor_t, + alpha1: *const ::std::os::raw::c_void, + aDesc: cudnnTensorDescriptor_t, + A: *const ::std::os::raw::c_void, + alpha2: *const ::std::os::raw::c_void, + bDesc: cudnnTensorDescriptor_t, + B: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + cDesc: cudnnTensorDescriptor_t, + C: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateReduceTensorDescriptor( + reduceTensorDesc: *mut cudnnReduceTensorDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetReduceTensorDescriptor( + reduceTensorDesc: cudnnReduceTensorDescriptor_t, + reduceTensorOp: cudnnReduceTensorOp_t, + reduceTensorCompType: cudnnDataType_t, + reduceTensorNanOpt: cudnnNanPropagation_t, + reduceTensorIndices: cudnnReduceTensorIndices_t, + reduceTensorIndicesType: cudnnIndicesType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetReduceTensorDescriptor( + reduceTensorDesc: cudnnReduceTensorDescriptor_t, + reduceTensorOp: *mut cudnnReduceTensorOp_t, + reduceTensorCompType: *mut cudnnDataType_t, + reduceTensorNanOpt: *mut cudnnNanPropagation_t, + reduceTensorIndices: *mut cudnnReduceTensorIndices_t, + reduceTensorIndicesType: *mut cudnnIndicesType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyReduceTensorDescriptor( + reduceTensorDesc: cudnnReduceTensorDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetReductionIndicesSize( + handle: cudnnHandle_t, + reduceTensorDesc: cudnnReduceTensorDescriptor_t, + aDesc: cudnnTensorDescriptor_t, + cDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetReductionWorkspaceSize( + handle: cudnnHandle_t, + reduceTensorDesc: cudnnReduceTensorDescriptor_t, + aDesc: cudnnTensorDescriptor_t, + cDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnReduceTensor( + handle: cudnnHandle_t, + reduceTensorDesc: cudnnReduceTensorDescriptor_t, + indices: *mut ::std::os::raw::c_void, + indicesSizeInBytes: usize, + workspace: *mut ::std::os::raw::c_void, + workspaceSizeInBytes: usize, + alpha: *const ::std::os::raw::c_void, + aDesc: cudnnTensorDescriptor_t, + A: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + cDesc: cudnnTensorDescriptor_t, + C: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetTensor( + handle: cudnnHandle_t, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + valuePtr: *const ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnScaleTensor( + handle: cudnnHandle_t, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + alpha: *const ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateFilterDescriptor( + filterDesc: *mut cudnnFilterDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_filter_descriptor(filterDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetFilter4dDescriptor( + filterDesc: cudnnFilterDescriptor_t, + dataType: cudnnDataType_t, + format: cudnnTensorFormat_t, + k: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + h: ::std::os::raw::c_int, + w: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFilter4dDescriptor( + filterDesc: cudnnFilterDescriptor_t, + dataType: *mut cudnnDataType_t, + format: *mut cudnnTensorFormat_t, + k: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetFilterNdDescriptor( + filterDesc: cudnnFilterDescriptor_t, + dataType: cudnnDataType_t, + format: cudnnTensorFormat_t, + nbDims: ::std::os::raw::c_int, + filterDimA: *const ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::set_filter_nd_descriptor(filterDesc, dataType, format, nbDims, filterDimA) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFilterNdDescriptor( + filterDesc: cudnnFilterDescriptor_t, + nbDimsRequested: ::std::os::raw::c_int, + dataType: *mut cudnnDataType_t, + format: *mut cudnnTensorFormat_t, + nbDims: *mut ::std::os::raw::c_int, + filterDimA: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFilterSizeInBytes( + filterDesc: cudnnFilterDescriptor_t, + size: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnTransformFilter( + handle: cudnnHandle_t, + transDesc: cudnnTensorTransformDescriptor_t, + alpha: *const ::std::os::raw::c_void, + srcDesc: cudnnFilterDescriptor_t, + srcData: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + destDesc: cudnnFilterDescriptor_t, + destData: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyFilterDescriptor( + filterDesc: cudnnFilterDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_filter_descriptor(filterDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSoftmaxForward( + handle: cudnnHandle_t, + algo: cudnnSoftmaxAlgorithm_t, + mode: cudnnSoftmaxMode_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::softmax_forward(handle, algo, mode, alpha, xDesc, x, beta, yDesc, y) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreatePoolingDescriptor( + poolingDesc: *mut cudnnPoolingDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_pooling_descriptor(poolingDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetPooling2dDescriptor( + poolingDesc: cudnnPoolingDescriptor_t, + mode: cudnnPoolingMode_t, + maxpoolingNanOpt: cudnnNanPropagation_t, + windowHeight: ::std::os::raw::c_int, + windowWidth: ::std::os::raw::c_int, + verticalPadding: ::std::os::raw::c_int, + horizontalPadding: ::std::os::raw::c_int, + verticalStride: ::std::os::raw::c_int, + horizontalStride: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetPooling2dDescriptor( + poolingDesc: cudnnPoolingDescriptor_t, + mode: *mut cudnnPoolingMode_t, + maxpoolingNanOpt: *mut cudnnNanPropagation_t, + windowHeight: *mut ::std::os::raw::c_int, + windowWidth: *mut ::std::os::raw::c_int, + verticalPadding: *mut ::std::os::raw::c_int, + horizontalPadding: *mut ::std::os::raw::c_int, + verticalStride: *mut ::std::os::raw::c_int, + horizontalStride: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetPoolingNdDescriptor( + poolingDesc: cudnnPoolingDescriptor_t, + mode: cudnnPoolingMode_t, + maxpoolingNanOpt: cudnnNanPropagation_t, + nbDims: ::std::os::raw::c_int, + windowDimA: *const ::std::os::raw::c_int, + paddingA: *const ::std::os::raw::c_int, + strideA: *const ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::set_pooling_nd_descriptor( + poolingDesc, + mode, + maxpoolingNanOpt, + nbDims, + windowDimA, + paddingA, + strideA, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetPoolingNdDescriptor( + poolingDesc: cudnnPoolingDescriptor_t, + nbDimsRequested: ::std::os::raw::c_int, + mode: *mut cudnnPoolingMode_t, + maxpoolingNanOpt: *mut cudnnNanPropagation_t, + nbDims: *mut ::std::os::raw::c_int, + windowDimA: *mut ::std::os::raw::c_int, + paddingA: *mut ::std::os::raw::c_int, + strideA: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetPoolingNdForwardOutputDim( + poolingDesc: cudnnPoolingDescriptor_t, + inputTensorDesc: cudnnTensorDescriptor_t, + nbDims: ::std::os::raw::c_int, + outputTensorDimA: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::get_pooling_nd_forward_output_dim(poolingDesc, inputTensorDesc, nbDims, outputTensorDimA) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetPooling2dForwardOutputDim( + poolingDesc: cudnnPoolingDescriptor_t, + inputTensorDesc: cudnnTensorDescriptor_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyPoolingDescriptor( + poolingDesc: cudnnPoolingDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_pooling_descriptor(poolingDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnPoolingForward( + handle: cudnnHandle_t, + poolingDesc: cudnnPoolingDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::pooling_forward(handle, poolingDesc, alpha, xDesc, x, beta, yDesc, y) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateActivationDescriptor( + activationDesc: *mut cudnnActivationDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_activation_descriptor(activationDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetActivationDescriptor( + activationDesc: cudnnActivationDescriptor_t, + mode: cudnnActivationMode_t, + reluNanOpt: cudnnNanPropagation_t, + coef: f64, +) -> cudnnStatus_t { + crate::set_activation_descriptor(activationDesc, mode, reluNanOpt, coef) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetActivationDescriptor( + activationDesc: cudnnActivationDescriptor_t, + mode: *mut cudnnActivationMode_t, + reluNanOpt: *mut cudnnNanPropagation_t, + coef: *mut f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetActivationDescriptorSwishBeta( + activationDesc: cudnnActivationDescriptor_t, + swish_beta: f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetActivationDescriptorSwishBeta( + activationDesc: cudnnActivationDescriptor_t, + swish_beta: *mut f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyActivationDescriptor( + activationDesc: cudnnActivationDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_activation_descriptor(activationDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnActivationForward( + handle: cudnnHandle_t, + activationDesc: cudnnActivationDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::activation_forward(handle, activationDesc, alpha, xDesc, x, beta, yDesc, y) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateLRNDescriptor( + normDesc: *mut cudnnLRNDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_lrn_descriptor(normDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetLRNDescriptor( + normDesc: cudnnLRNDescriptor_t, + lrnN: ::std::os::raw::c_uint, + lrnAlpha: f64, + lrnBeta: f64, + lrnK: f64, +) -> cudnnStatus_t { + crate::set_lrn_descriptor(normDesc, lrnN, lrnAlpha, lrnBeta, lrnK) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetLRNDescriptor( + normDesc: cudnnLRNDescriptor_t, + lrnN: *mut ::std::os::raw::c_uint, + lrnAlpha: *mut f64, + lrnBeta: *mut f64, + lrnK: *mut f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyLRNDescriptor( + lrnDesc: cudnnLRNDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_lrn_descriptor(lrnDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnLRNCrossChannelForward( + handle: cudnnHandle_t, + normDesc: cudnnLRNDescriptor_t, + lrnMode: cudnnLRNMode_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::lrn_cross_channel_forward(handle, normDesc, lrnMode, alpha, xDesc, x, beta, yDesc, y) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDivisiveNormalizationForward( + handle: cudnnHandle_t, + normDesc: cudnnLRNDescriptor_t, + mode: cudnnDivNormMode_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + means: *const ::std::os::raw::c_void, + temp: *mut ::std::os::raw::c_void, + temp2: *mut ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDeriveBNTensorDescriptor( + derivedBnDesc: cudnnTensorDescriptor_t, + xDesc: cudnnTensorDescriptor_t, + mode: cudnnBatchNormMode_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBatchNormalizationForwardInference( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + bnScaleBiasMeanVarDesc: cudnnTensorDescriptor_t, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + estimatedMean: *const ::std::os::raw::c_void, + estimatedVariance: *const ::std::os::raw::c_void, + epsilon: f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDeriveNormTensorDescriptor( + derivedNormScaleBiasDesc: cudnnTensorDescriptor_t, + derivedNormMeanVarDesc: cudnnTensorDescriptor_t, + xDesc: cudnnTensorDescriptor_t, + mode: cudnnNormMode_t, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnNormalizationForwardInference( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + normScaleBiasDesc: cudnnTensorDescriptor_t, + normScale: *const ::std::os::raw::c_void, + normBias: *const ::std::os::raw::c_void, + normMeanVarDesc: cudnnTensorDescriptor_t, + estimatedMean: *const ::std::os::raw::c_void, + estimatedVariance: *const ::std::os::raw::c_void, + zDesc: cudnnTensorDescriptor_t, + z: *const ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + epsilon: f64, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateSpatialTransformerDescriptor( + stDesc: *mut cudnnSpatialTransformerDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetSpatialTransformerNdDescriptor( + stDesc: cudnnSpatialTransformerDescriptor_t, + samplerType: cudnnSamplerType_t, + dataType: cudnnDataType_t, + nbDims: ::std::os::raw::c_int, + dimA: *const ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroySpatialTransformerDescriptor( + stDesc: cudnnSpatialTransformerDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSpatialTfGridGeneratorForward( + handle: cudnnHandle_t, + stDesc: cudnnSpatialTransformerDescriptor_t, + theta: *const ::std::os::raw::c_void, + grid: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSpatialTfSamplerForward( + handle: cudnnHandle_t, + stDesc: cudnnSpatialTransformerDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + grid: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateDropoutDescriptor( + dropoutDesc: *mut cudnnDropoutDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyDropoutDescriptor( + dropoutDesc: cudnnDropoutDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDropoutGetStatesSize( + handle: cudnnHandle_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDropoutGetReserveSpaceSize( + xdesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetDropoutDescriptor( + dropoutDesc: cudnnDropoutDescriptor_t, + handle: cudnnHandle_t, + dropout: f32, + states: *mut ::std::os::raw::c_void, + stateSizeInBytes: usize, + seed: ::std::os::raw::c_ulonglong, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRestoreDropoutDescriptor( + dropoutDesc: cudnnDropoutDescriptor_t, + handle: cudnnHandle_t, + dropout: f32, + states: *mut ::std::os::raw::c_void, + stateSizeInBytes: usize, + seed: ::std::os::raw::c_ulonglong, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetDropoutDescriptor( + dropoutDesc: cudnnDropoutDescriptor_t, + handle: cudnnHandle_t, + dropout: *mut f32, + states: *mut *mut ::std::os::raw::c_void, + seed: *mut ::std::os::raw::c_ulonglong, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDropoutForward( + handle: cudnnHandle_t, + dropoutDesc: cudnnDropoutDescriptor_t, + xdesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + ydesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateAlgorithmDescriptor( + algoDesc: *mut cudnnAlgorithmDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetAlgorithmDescriptor( + algoDesc: cudnnAlgorithmDescriptor_t, + algorithm: cudnnAlgorithm_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetAlgorithmDescriptor( + algoDesc: cudnnAlgorithmDescriptor_t, + algorithm: *mut cudnnAlgorithm_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCopyAlgorithmDescriptor( + src: cudnnAlgorithmDescriptor_t, + dest: cudnnAlgorithmDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyAlgorithmDescriptor( + algoDesc: cudnnAlgorithmDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateAlgorithmPerformance( + algoPerf: *mut cudnnAlgorithmPerformance_t, + numberToCreate: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetAlgorithmPerformance( + algoPerf: cudnnAlgorithmPerformance_t, + algoDesc: cudnnAlgorithmDescriptor_t, + status: cudnnStatus_t, + time: f32, + memory: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetAlgorithmPerformance( + algoPerf: cudnnAlgorithmPerformance_t, + algoDesc: *mut cudnnAlgorithmDescriptor_t, + status: *mut cudnnStatus_t, + time: *mut f32, + memory: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyAlgorithmPerformance( + algoPerf: *mut cudnnAlgorithmPerformance_t, + numberToDestroy: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetAlgorithmSpaceSize( + handle: cudnnHandle_t, + algoDesc: cudnnAlgorithmDescriptor_t, + algoSpaceSizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSaveAlgorithm( + handle: cudnnHandle_t, + algoDesc: cudnnAlgorithmDescriptor_t, + algoSpace: *mut ::std::os::raw::c_void, + algoSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRestoreAlgorithm( + handle: cudnnHandle_t, + algoSpace: *mut ::std::os::raw::c_void, + algoSpaceSizeInBytes: usize, + algoDesc: cudnnAlgorithmDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetCallback( + mask: ::std::os::raw::c_uint, + udata: *mut ::std::os::raw::c_void, + fptr: cudnnCallback_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCallback( + mask: *mut ::std::os::raw::c_uint, + udata: *mut *mut ::std::os::raw::c_void, + fptr: *mut cudnnCallback_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnOpsInferVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSoftmaxBackward( + handle: cudnnHandle_t, + algo: cudnnSoftmaxAlgorithm_t, + mode: cudnnSoftmaxMode_t, + alpha: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnPoolingBackward( + handle: cudnnHandle_t, + poolingDesc: cudnnPoolingDescriptor_t, + alpha: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnActivationBackward( + handle: cudnnHandle_t, + activationDesc: cudnnActivationDescriptor_t, + alpha: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnLRNCrossChannelBackward( + handle: cudnnHandle_t, + normDesc: cudnnLRNDescriptor_t, + lrnMode: cudnnLRNMode_t, + alpha: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDivisiveNormalizationBackward( + handle: cudnnHandle_t, + normDesc: cudnnLRNDescriptor_t, + mode: cudnnDivNormMode_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + means: *const ::std::os::raw::c_void, + dy: *const ::std::os::raw::c_void, + temp: *mut ::std::os::raw::c_void, + temp2: *mut ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dXdMeansDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dMeans: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetBatchNormalizationForwardTrainingExWorkspaceSize( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + bnOps: cudnnBatchNormOps_t, + xDesc: cudnnTensorDescriptor_t, + zDesc: cudnnTensorDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + bnScaleBiasMeanVarDesc: cudnnTensorDescriptor_t, + activationDesc: cudnnActivationDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetBatchNormalizationBackwardExWorkspaceSize( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + bnOps: cudnnBatchNormOps_t, + xDesc: cudnnTensorDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + dzDesc: cudnnTensorDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + dBnScaleBiasDesc: cudnnTensorDescriptor_t, + activationDesc: cudnnActivationDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetBatchNormalizationTrainingExReserveSpaceSize( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + bnOps: cudnnBatchNormOps_t, + activationDesc: cudnnActivationDescriptor_t, + xDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBatchNormalizationForwardTraining( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + bnScaleBiasMeanVarDesc: cudnnTensorDescriptor_t, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + exponentialAverageFactor: f64, + resultRunningMean: *mut ::std::os::raw::c_void, + resultRunningVariance: *mut ::std::os::raw::c_void, + epsilon: f64, + resultSaveMean: *mut ::std::os::raw::c_void, + resultSaveInvVariance: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBatchNormalizationForwardTrainingEx( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + bnOps: cudnnBatchNormOps_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + xData: *const ::std::os::raw::c_void, + zDesc: cudnnTensorDescriptor_t, + zData: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + yData: *mut ::std::os::raw::c_void, + bnScaleBiasMeanVarDesc: cudnnTensorDescriptor_t, + bnScale: *const ::std::os::raw::c_void, + bnBias: *const ::std::os::raw::c_void, + exponentialAverageFactor: f64, + resultRunningMean: *mut ::std::os::raw::c_void, + resultRunningVariance: *mut ::std::os::raw::c_void, + epsilon: f64, + resultSaveMean: *mut ::std::os::raw::c_void, + resultSaveInvVariance: *mut ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBatchNormalizationBackward( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + alphaDataDiff: *const ::std::os::raw::c_void, + betaDataDiff: *const ::std::os::raw::c_void, + alphaParamDiff: *const ::std::os::raw::c_void, + betaParamDiff: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dBnScaleBiasDesc: cudnnTensorDescriptor_t, + bnScale: *const ::std::os::raw::c_void, + dBnScaleResult: *mut ::std::os::raw::c_void, + dBnBiasResult: *mut ::std::os::raw::c_void, + epsilon: f64, + savedMean: *const ::std::os::raw::c_void, + savedInvVariance: *const ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBatchNormalizationBackwardEx( + handle: cudnnHandle_t, + mode: cudnnBatchNormMode_t, + bnOps: cudnnBatchNormOps_t, + alphaDataDiff: *const ::std::os::raw::c_void, + betaDataDiff: *const ::std::os::raw::c_void, + alphaParamDiff: *const ::std::os::raw::c_void, + betaParamDiff: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + xData: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + yData: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dyData: *const ::std::os::raw::c_void, + dzDesc: cudnnTensorDescriptor_t, + dzData: *mut ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dxData: *mut ::std::os::raw::c_void, + dBnScaleBiasDesc: cudnnTensorDescriptor_t, + bnScaleData: *const ::std::os::raw::c_void, + bnBiasData: *const ::std::os::raw::c_void, + dBnScaleData: *mut ::std::os::raw::c_void, + dBnBiasData: *mut ::std::os::raw::c_void, + epsilon: f64, + savedMean: *const ::std::os::raw::c_void, + savedInvVariance: *const ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetNormalizationForwardTrainingWorkspaceSize( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + xDesc: cudnnTensorDescriptor_t, + zDesc: cudnnTensorDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + normScaleBiasDesc: cudnnTensorDescriptor_t, + activationDesc: cudnnActivationDescriptor_t, + normMeanVarDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetNormalizationBackwardWorkspaceSize( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + xDesc: cudnnTensorDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + dzDesc: cudnnTensorDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + dNormScaleBiasDesc: cudnnTensorDescriptor_t, + activationDesc: cudnnActivationDescriptor_t, + normMeanVarDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetNormalizationTrainingReserveSpaceSize( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + activationDesc: cudnnActivationDescriptor_t, + xDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnNormalizationForwardTraining( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + alpha: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + xData: *const ::std::os::raw::c_void, + normScaleBiasDesc: cudnnTensorDescriptor_t, + normScale: *const ::std::os::raw::c_void, + normBias: *const ::std::os::raw::c_void, + exponentialAverageFactor: f64, + normMeanVarDesc: cudnnTensorDescriptor_t, + resultRunningMean: *mut ::std::os::raw::c_void, + resultRunningVariance: *mut ::std::os::raw::c_void, + epsilon: f64, + resultSaveMean: *mut ::std::os::raw::c_void, + resultSaveInvVariance: *mut ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + zDesc: cudnnTensorDescriptor_t, + zData: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + yData: *mut ::std::os::raw::c_void, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnNormalizationBackward( + handle: cudnnHandle_t, + mode: cudnnNormMode_t, + normOps: cudnnNormOps_t, + algo: cudnnNormAlgo_t, + alphaDataDiff: *const ::std::os::raw::c_void, + betaDataDiff: *const ::std::os::raw::c_void, + alphaParamDiff: *const ::std::os::raw::c_void, + betaParamDiff: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + xData: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + yData: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dyData: *const ::std::os::raw::c_void, + dzDesc: cudnnTensorDescriptor_t, + dzData: *mut ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dxData: *mut ::std::os::raw::c_void, + dNormScaleBiasDesc: cudnnTensorDescriptor_t, + normScaleData: *const ::std::os::raw::c_void, + normBiasData: *const ::std::os::raw::c_void, + dNormScaleData: *mut ::std::os::raw::c_void, + dNormBiasData: *mut ::std::os::raw::c_void, + epsilon: f64, + normMeanVarDesc: cudnnTensorDescriptor_t, + savedMean: *const ::std::os::raw::c_void, + savedInvVariance: *const ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + groupCnt: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSpatialTfGridGeneratorBackward( + handle: cudnnHandle_t, + stDesc: cudnnSpatialTransformerDescriptor_t, + dgrid: *const ::std::os::raw::c_void, + dtheta: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSpatialTfSamplerBackward( + handle: cudnnHandle_t, + stDesc: cudnnSpatialTransformerDescriptor_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + alphaDgrid: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + grid: *const ::std::os::raw::c_void, + betaDgrid: *const ::std::os::raw::c_void, + dgrid: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDropoutBackward( + handle: cudnnHandle_t, + dropoutDesc: cudnnDropoutDescriptor_t, + dydesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dxdesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnOpsTrainVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateRNNDescriptor( + rnnDesc: *mut cudnnRNNDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyRNNDescriptor( + rnnDesc: cudnnRNNDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNDescriptor_v8( + rnnDesc: cudnnRNNDescriptor_t, + algo: cudnnRNNAlgo_t, + cellMode: cudnnRNNMode_t, + biasMode: cudnnRNNBiasMode_t, + dirMode: cudnnDirectionMode_t, + inputMode: cudnnRNNInputMode_t, + dataType: cudnnDataType_t, + mathPrec: cudnnDataType_t, + mathType: cudnnMathType_t, + inputSize: i32, + hiddenSize: i32, + projSize: i32, + numLayers: i32, + dropoutDesc: cudnnDropoutDescriptor_t, + auxFlags: u32, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNDescriptor_v8( + rnnDesc: cudnnRNNDescriptor_t, + algo: *mut cudnnRNNAlgo_t, + cellMode: *mut cudnnRNNMode_t, + biasMode: *mut cudnnRNNBiasMode_t, + dirMode: *mut cudnnDirectionMode_t, + inputMode: *mut cudnnRNNInputMode_t, + dataType: *mut cudnnDataType_t, + mathPrec: *mut cudnnDataType_t, + mathType: *mut cudnnMathType_t, + inputSize: *mut i32, + hiddenSize: *mut i32, + projSize: *mut i32, + numLayers: *mut i32, + dropoutDesc: *mut cudnnDropoutDescriptor_t, + auxFlags: *mut u32, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNDescriptor_v6( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + hiddenSize: ::std::os::raw::c_int, + numLayers: ::std::os::raw::c_int, + dropoutDesc: cudnnDropoutDescriptor_t, + inputMode: cudnnRNNInputMode_t, + direction: cudnnDirectionMode_t, + cellMode: cudnnRNNMode_t, + algo: cudnnRNNAlgo_t, + mathPrec: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNDescriptor_v6( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + hiddenSize: *mut ::std::os::raw::c_int, + numLayers: *mut ::std::os::raw::c_int, + dropoutDesc: *mut cudnnDropoutDescriptor_t, + inputMode: *mut cudnnRNNInputMode_t, + direction: *mut cudnnDirectionMode_t, + cellMode: *mut cudnnRNNMode_t, + algo: *mut cudnnRNNAlgo_t, + mathPrec: *mut cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNMatrixMathType( + rnnDesc: cudnnRNNDescriptor_t, + mType: cudnnMathType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNMatrixMathType( + rnnDesc: cudnnRNNDescriptor_t, + mType: *mut cudnnMathType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNBiasMode( + rnnDesc: cudnnRNNDescriptor_t, + biasMode: cudnnRNNBiasMode_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNBiasMode( + rnnDesc: cudnnRNNDescriptor_t, + biasMode: *mut cudnnRNNBiasMode_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNSetClip_v8( + rnnDesc: cudnnRNNDescriptor_t, + clipMode: cudnnRNNClipMode_t, + clipNanOpt: cudnnNanPropagation_t, + lclip: f64, + rclip: f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNGetClip_v8( + rnnDesc: cudnnRNNDescriptor_t, + clipMode: *mut cudnnRNNClipMode_t, + clipNanOpt: *mut cudnnNanPropagation_t, + lclip: *mut f64, + rclip: *mut f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNSetClip( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + clipMode: cudnnRNNClipMode_t, + clipNanOpt: cudnnNanPropagation_t, + lclip: f64, + rclip: f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNGetClip( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + clipMode: *mut cudnnRNNClipMode_t, + clipNanOpt: *mut cudnnNanPropagation_t, + lclip: *mut f64, + rclip: *mut f64, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNProjectionLayers( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + recProjSize: ::std::os::raw::c_int, + outProjSize: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNProjectionLayers( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + recProjSize: *mut ::std::os::raw::c_int, + outProjSize: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreatePersistentRNNPlan( + rnnDesc: cudnnRNNDescriptor_t, + minibatch: ::std::os::raw::c_int, + dataType: cudnnDataType_t, + plan: *mut cudnnPersistentRNNPlan_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyPersistentRNNPlan( + plan: cudnnPersistentRNNPlan_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetPersistentRNNPlan( + rnnDesc: cudnnRNNDescriptor_t, + plan: cudnnPersistentRNNPlan_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBuildRNNDynamic( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + miniBatch: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNWorkspaceSize( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNTrainingReserveSize( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNTempSpaceSizes( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + fwdMode: cudnnForwardMode_t, + xDesc: cudnnRNNDataDescriptor_t, + workSpaceSize: *mut usize, + reserveSpaceSize: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNParamsSize( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + xDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, + dataType: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNWeightSpaceSize( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + weightSpaceSize: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNLinLayerMatrixParams( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + pseudoLayer: ::std::os::raw::c_int, + xDesc: cudnnTensorDescriptor_t, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + linLayerID: ::std::os::raw::c_int, + linLayerMatDesc: cudnnFilterDescriptor_t, + linLayerMat: *mut *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNLinLayerBiasParams( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + pseudoLayer: ::std::os::raw::c_int, + xDesc: cudnnTensorDescriptor_t, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + linLayerID: ::std::os::raw::c_int, + linLayerBiasDesc: cudnnFilterDescriptor_t, + linLayerBias: *mut *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNWeightParams( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + pseudoLayer: i32, + weightSpaceSize: usize, + weightSpace: *const ::std::os::raw::c_void, + linLayerID: i32, + mDesc: cudnnTensorDescriptor_t, + mAddr: *mut *mut ::std::os::raw::c_void, + bDesc: cudnnTensorDescriptor_t, + bAddr: *mut *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNForwardInference( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNPaddingMode( + rnnDesc: cudnnRNNDescriptor_t, + paddingMode: ::std::os::raw::c_uint, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNPaddingMode( + rnnDesc: cudnnRNNDescriptor_t, + paddingMode: *mut ::std::os::raw::c_uint, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateRNNDataDescriptor( + rnnDataDesc: *mut cudnnRNNDataDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyRNNDataDescriptor( + rnnDataDesc: cudnnRNNDataDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNDataDescriptor( + rnnDataDesc: cudnnRNNDataDescriptor_t, + dataType: cudnnDataType_t, + layout: cudnnRNNDataLayout_t, + maxSeqLength: ::std::os::raw::c_int, + batchSize: ::std::os::raw::c_int, + vectorSize: ::std::os::raw::c_int, + seqLengthArray: *const ::std::os::raw::c_int, + paddingFill: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNDataDescriptor( + rnnDataDesc: cudnnRNNDataDescriptor_t, + dataType: *mut cudnnDataType_t, + layout: *mut cudnnRNNDataLayout_t, + maxSeqLength: *mut ::std::os::raw::c_int, + batchSize: *mut ::std::os::raw::c_int, + vectorSize: *mut ::std::os::raw::c_int, + arrayLengthRequested: ::std::os::raw::c_int, + seqLengthArray: *mut ::std::os::raw::c_int, + paddingFill: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNForwardInferenceEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + xDesc: cudnnRNNDataDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: cudnnRNNDataDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + kDesc: cudnnRNNDataDescriptor_t, + keys: *const ::std::os::raw::c_void, + cDesc: cudnnRNNDataDescriptor_t, + cAttn: *mut ::std::os::raw::c_void, + iDesc: cudnnRNNDataDescriptor_t, + iAttn: *mut ::std::os::raw::c_void, + qDesc: cudnnRNNDataDescriptor_t, + queries: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNForward( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + fwdMode: cudnnForwardMode_t, + devSeqLengths: *const i32, + xDesc: cudnnRNNDataDescriptor_t, + x: *const ::std::os::raw::c_void, + yDesc: cudnnRNNDataDescriptor_t, + y: *mut ::std::os::raw::c_void, + hDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + hy: *mut ::std::os::raw::c_void, + cDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + cy: *mut ::std::os::raw::c_void, + weightSpaceSize: usize, + weightSpace: *const ::std::os::raw::c_void, + workSpaceSize: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSize: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetRNNAlgorithmDescriptor( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + algoDesc: cudnnAlgorithmDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNForwardInferenceAlgorithmMaxCount( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindRNNForwardInferenceAlgorithmEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + findIntensity: f32, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnAlgorithmPerformance_t, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateSeqDataDescriptor( + seqDataDesc: *mut cudnnSeqDataDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroySeqDataDescriptor( + seqDataDesc: cudnnSeqDataDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetSeqDataDescriptor( + seqDataDesc: cudnnSeqDataDescriptor_t, + dataType: cudnnDataType_t, + nbDims: ::std::os::raw::c_int, + dimA: *const ::std::os::raw::c_int, + axes: *const cudnnSeqDataAxis_t, + seqLengthArraySize: usize, + seqLengthArray: *const ::std::os::raw::c_int, + paddingFill: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetSeqDataDescriptor( + seqDataDesc: cudnnSeqDataDescriptor_t, + dataType: *mut cudnnDataType_t, + nbDims: *mut ::std::os::raw::c_int, + nbDimsRequested: ::std::os::raw::c_int, + dimA: *mut ::std::os::raw::c_int, + axes: *mut cudnnSeqDataAxis_t, + seqLengthArraySize: *mut usize, + seqLengthSizeRequested: usize, + seqLengthArray: *mut ::std::os::raw::c_int, + paddingFill: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateAttnDescriptor( + attnDesc: *mut cudnnAttnDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyAttnDescriptor( + attnDesc: cudnnAttnDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetAttnDescriptor( + attnDesc: cudnnAttnDescriptor_t, + attnMode: ::std::os::raw::c_uint, + nHeads: ::std::os::raw::c_int, + smScaler: f64, + dataType: cudnnDataType_t, + computePrec: cudnnDataType_t, + mathType: cudnnMathType_t, + attnDropoutDesc: cudnnDropoutDescriptor_t, + postDropoutDesc: cudnnDropoutDescriptor_t, + qSize: ::std::os::raw::c_int, + kSize: ::std::os::raw::c_int, + vSize: ::std::os::raw::c_int, + qProjSize: ::std::os::raw::c_int, + kProjSize: ::std::os::raw::c_int, + vProjSize: ::std::os::raw::c_int, + oProjSize: ::std::os::raw::c_int, + qoMaxSeqLength: ::std::os::raw::c_int, + kvMaxSeqLength: ::std::os::raw::c_int, + maxBatchSize: ::std::os::raw::c_int, + maxBeamSize: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetAttnDescriptor( + attnDesc: cudnnAttnDescriptor_t, + attnMode: *mut ::std::os::raw::c_uint, + nHeads: *mut ::std::os::raw::c_int, + smScaler: *mut f64, + dataType: *mut cudnnDataType_t, + computePrec: *mut cudnnDataType_t, + mathType: *mut cudnnMathType_t, + attnDropoutDesc: *mut cudnnDropoutDescriptor_t, + postDropoutDesc: *mut cudnnDropoutDescriptor_t, + qSize: *mut ::std::os::raw::c_int, + kSize: *mut ::std::os::raw::c_int, + vSize: *mut ::std::os::raw::c_int, + qProjSize: *mut ::std::os::raw::c_int, + kProjSize: *mut ::std::os::raw::c_int, + vProjSize: *mut ::std::os::raw::c_int, + oProjSize: *mut ::std::os::raw::c_int, + qoMaxSeqLength: *mut ::std::os::raw::c_int, + kvMaxSeqLength: *mut ::std::os::raw::c_int, + maxBatchSize: *mut ::std::os::raw::c_int, + maxBeamSize: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetMultiHeadAttnBuffers( + handle: cudnnHandle_t, + attnDesc: cudnnAttnDescriptor_t, + weightSizeInBytes: *mut usize, + workSpaceSizeInBytes: *mut usize, + reserveSpaceSizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetMultiHeadAttnWeights( + handle: cudnnHandle_t, + attnDesc: cudnnAttnDescriptor_t, + wKind: cudnnMultiHeadAttnWeightKind_t, + weightSizeInBytes: usize, + weights: *const ::std::os::raw::c_void, + wDesc: cudnnTensorDescriptor_t, + wAddr: *mut *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnMultiHeadAttnForward( + handle: cudnnHandle_t, + attnDesc: cudnnAttnDescriptor_t, + currIdx: ::std::os::raw::c_int, + loWinIdx: *const ::std::os::raw::c_int, + hiWinIdx: *const ::std::os::raw::c_int, + devSeqLengthsQO: *const ::std::os::raw::c_int, + devSeqLengthsKV: *const ::std::os::raw::c_int, + qDesc: cudnnSeqDataDescriptor_t, + queries: *const ::std::os::raw::c_void, + residuals: *const ::std::os::raw::c_void, + kDesc: cudnnSeqDataDescriptor_t, + keys: *const ::std::os::raw::c_void, + vDesc: cudnnSeqDataDescriptor_t, + values: *const ::std::os::raw::c_void, + oDesc: cudnnSeqDataDescriptor_t, + out: *mut ::std::os::raw::c_void, + weightSizeInBytes: usize, + weights: *const ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnAdvInferVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNForwardTraining( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardData( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + yDesc: *const cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: *const cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dhyDesc: cudnnTensorDescriptor_t, + dhy: *const ::std::os::raw::c_void, + dcyDesc: cudnnTensorDescriptor_t, + dcy: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + dxDesc: *const cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dhxDesc: cudnnTensorDescriptor_t, + dhx: *mut ::std::os::raw::c_void, + dcxDesc: cudnnTensorDescriptor_t, + dcx: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardData_v8( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + devSeqLengths: *const i32, + yDesc: cudnnRNNDataDescriptor_t, + y: *const ::std::os::raw::c_void, + dy: *const ::std::os::raw::c_void, + xDesc: cudnnRNNDataDescriptor_t, + dx: *mut ::std::os::raw::c_void, + hDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + dhy: *const ::std::os::raw::c_void, + dhx: *mut ::std::os::raw::c_void, + cDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + dcy: *const ::std::os::raw::c_void, + dcx: *mut ::std::os::raw::c_void, + weightSpaceSize: usize, + weightSpace: *const ::std::os::raw::c_void, + workSpaceSize: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSize: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardWeights( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + workSpace: *const ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + dwDesc: cudnnFilterDescriptor_t, + dw: *mut ::std::os::raw::c_void, + reserveSpace: *const ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardWeights_v8( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + addGrad: cudnnWgradMode_t, + devSeqLengths: *const i32, + xDesc: cudnnRNNDataDescriptor_t, + x: *const ::std::os::raw::c_void, + hDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + yDesc: cudnnRNNDataDescriptor_t, + y: *const ::std::os::raw::c_void, + weightSpaceSize: usize, + dweightSpace: *mut ::std::os::raw::c_void, + workSpaceSize: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSize: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNForwardTrainingEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + xDesc: cudnnRNNDataDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: cudnnRNNDataDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + kDesc: cudnnRNNDataDescriptor_t, + keys: *const ::std::os::raw::c_void, + cDesc: cudnnRNNDataDescriptor_t, + cAttn: *mut ::std::os::raw::c_void, + iDesc: cudnnRNNDataDescriptor_t, + iAttn: *mut ::std::os::raw::c_void, + qDesc: cudnnRNNDataDescriptor_t, + queries: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardDataEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + yDesc: cudnnRNNDataDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: cudnnRNNDataDescriptor_t, + dy: *const ::std::os::raw::c_void, + dcDesc: cudnnRNNDataDescriptor_t, + dcAttn: *const ::std::os::raw::c_void, + dhyDesc: cudnnTensorDescriptor_t, + dhy: *const ::std::os::raw::c_void, + dcyDesc: cudnnTensorDescriptor_t, + dcy: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + dxDesc: cudnnRNNDataDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dhxDesc: cudnnTensorDescriptor_t, + dhx: *mut ::std::os::raw::c_void, + dcxDesc: cudnnTensorDescriptor_t, + dcx: *mut ::std::os::raw::c_void, + dkDesc: cudnnRNNDataDescriptor_t, + dkeys: *mut ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnRNNBackwardWeightsEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + xDesc: cudnnRNNDataDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + yDesc: cudnnRNNDataDescriptor_t, + y: *const ::std::os::raw::c_void, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + dwDesc: cudnnFilterDescriptor_t, + dw: *mut ::std::os::raw::c_void, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNForwardTrainingAlgorithmMaxCount( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindRNNForwardTrainingAlgorithmEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + hyDesc: cudnnTensorDescriptor_t, + hy: *mut ::std::os::raw::c_void, + cyDesc: cudnnTensorDescriptor_t, + cy: *mut ::std::os::raw::c_void, + findIntensity: f32, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnAlgorithmPerformance_t, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNBackwardDataAlgorithmMaxCount( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindRNNBackwardDataAlgorithmEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + yDesc: *const cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + dyDesc: *const cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + dhyDesc: cudnnTensorDescriptor_t, + dhy: *const ::std::os::raw::c_void, + dcyDesc: cudnnTensorDescriptor_t, + dcy: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + cxDesc: cudnnTensorDescriptor_t, + cx: *const ::std::os::raw::c_void, + dxDesc: *const cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + dhxDesc: cudnnTensorDescriptor_t, + dhx: *mut ::std::os::raw::c_void, + dcxDesc: cudnnTensorDescriptor_t, + dcx: *mut ::std::os::raw::c_void, + findIntensity: f32, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnAlgorithmPerformance_t, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetRNNBackwardWeightsAlgorithmMaxCount( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindRNNBackwardWeightsAlgorithmEx( + handle: cudnnHandle_t, + rnnDesc: cudnnRNNDescriptor_t, + seqLength: ::std::os::raw::c_int, + xDesc: *const cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + hxDesc: cudnnTensorDescriptor_t, + hx: *const ::std::os::raw::c_void, + yDesc: *const cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + findIntensity: f32, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnAlgorithmPerformance_t, + workspace: *const ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + dwDesc: cudnnFilterDescriptor_t, + dw: *mut ::std::os::raw::c_void, + reserveSpace: *const ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnMultiHeadAttnBackwardData( + handle: cudnnHandle_t, + attnDesc: cudnnAttnDescriptor_t, + loWinIdx: *const ::std::os::raw::c_int, + hiWinIdx: *const ::std::os::raw::c_int, + devSeqLengthsDQDO: *const ::std::os::raw::c_int, + devSeqLengthsDKDV: *const ::std::os::raw::c_int, + doDesc: cudnnSeqDataDescriptor_t, + dout: *const ::std::os::raw::c_void, + dqDesc: cudnnSeqDataDescriptor_t, + dqueries: *mut ::std::os::raw::c_void, + queries: *const ::std::os::raw::c_void, + dkDesc: cudnnSeqDataDescriptor_t, + dkeys: *mut ::std::os::raw::c_void, + keys: *const ::std::os::raw::c_void, + dvDesc: cudnnSeqDataDescriptor_t, + dvalues: *mut ::std::os::raw::c_void, + values: *const ::std::os::raw::c_void, + weightSizeInBytes: usize, + weights: *const ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnMultiHeadAttnBackwardWeights( + handle: cudnnHandle_t, + attnDesc: cudnnAttnDescriptor_t, + addGrad: cudnnWgradMode_t, + qDesc: cudnnSeqDataDescriptor_t, + queries: *const ::std::os::raw::c_void, + kDesc: cudnnSeqDataDescriptor_t, + keys: *const ::std::os::raw::c_void, + vDesc: cudnnSeqDataDescriptor_t, + values: *const ::std::os::raw::c_void, + doDesc: cudnnSeqDataDescriptor_t, + dout: *const ::std::os::raw::c_void, + weightSizeInBytes: usize, + weights: *const ::std::os::raw::c_void, + dweights: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + workSpace: *mut ::std::os::raw::c_void, + reserveSpaceSizeInBytes: usize, + reserveSpace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateCTCLossDescriptor( + ctcLossDesc: *mut cudnnCTCLossDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetCTCLossDescriptor( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetCTCLossDescriptorEx( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: cudnnDataType_t, + normMode: cudnnLossNormalizationMode_t, + gradMode: cudnnNanPropagation_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetCTCLossDescriptor_v8( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: cudnnDataType_t, + normMode: cudnnLossNormalizationMode_t, + gradMode: cudnnNanPropagation_t, + maxLabelLength: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCTCLossDescriptor( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: *mut cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCTCLossDescriptorEx( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: *mut cudnnDataType_t, + normMode: *mut cudnnLossNormalizationMode_t, + gradMode: *mut cudnnNanPropagation_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCTCLossDescriptor_v8( + ctcLossDesc: cudnnCTCLossDescriptor_t, + compType: *mut cudnnDataType_t, + normMode: *mut cudnnLossNormalizationMode_t, + gradMode: *mut cudnnNanPropagation_t, + maxLabelLength: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyCTCLossDescriptor( + ctcLossDesc: cudnnCTCLossDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCTCLoss( + handle: cudnnHandle_t, + probsDesc: cudnnTensorDescriptor_t, + probs: *const ::std::os::raw::c_void, + hostLabels: *const ::std::os::raw::c_int, + hostLabelLengths: *const ::std::os::raw::c_int, + hostInputLengths: *const ::std::os::raw::c_int, + costs: *mut ::std::os::raw::c_void, + gradientsDesc: cudnnTensorDescriptor_t, + gradients: *mut ::std::os::raw::c_void, + algo: cudnnCTCLossAlgo_t, + ctcLossDesc: cudnnCTCLossDescriptor_t, + workspace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCTCLoss_v8( + handle: cudnnHandle_t, + algo: cudnnCTCLossAlgo_t, + ctcLossDesc: cudnnCTCLossDescriptor_t, + probsDesc: cudnnTensorDescriptor_t, + probs: *const ::std::os::raw::c_void, + labels: *const ::std::os::raw::c_int, + labelLengths: *const ::std::os::raw::c_int, + inputLengths: *const ::std::os::raw::c_int, + costs: *mut ::std::os::raw::c_void, + gradientsDesc: cudnnTensorDescriptor_t, + gradients: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + workspace: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCTCLossWorkspaceSize( + handle: cudnnHandle_t, + probsDesc: cudnnTensorDescriptor_t, + gradientsDesc: cudnnTensorDescriptor_t, + labels: *const ::std::os::raw::c_int, + labelLengths: *const ::std::os::raw::c_int, + inputLengths: *const ::std::os::raw::c_int, + algo: cudnnCTCLossAlgo_t, + ctcLossDesc: cudnnCTCLossDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetCTCLossWorkspaceSize_v8( + handle: cudnnHandle_t, + algo: cudnnCTCLossAlgo_t, + ctcLossDesc: cudnnCTCLossDescriptor_t, + probsDesc: cudnnTensorDescriptor_t, + gradientsDesc: cudnnTensorDescriptor_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnAdvTrainVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateConvolutionDescriptor( + convDesc: *mut cudnnConvolutionDescriptor_t, +) -> cudnnStatus_t { + crate::cudnn_create_convolution_descriptor(convDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyConvolutionDescriptor( + convDesc: cudnnConvolutionDescriptor_t, +) -> cudnnStatus_t { + crate::destroy_convolution_descriptor(convDesc) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetConvolutionMathType( + convDesc: cudnnConvolutionDescriptor_t, + mathType: cudnnMathType_t, +) -> cudnnStatus_t { + crate::set_convolution_math_type(convDesc, mathType) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionMathType( + convDesc: cudnnConvolutionDescriptor_t, + mathType: *mut cudnnMathType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetConvolutionGroupCount( + convDesc: cudnnConvolutionDescriptor_t, + groupCount: ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::set_convolution_group_count(convDesc, groupCount) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionGroupCount( + convDesc: cudnnConvolutionDescriptor_t, + groupCount: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetConvolutionReorderType( + convDesc: cudnnConvolutionDescriptor_t, + reorderType: cudnnReorderType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionReorderType( + convDesc: cudnnConvolutionDescriptor_t, + reorderType: *mut cudnnReorderType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetConvolution2dDescriptor( + convDesc: cudnnConvolutionDescriptor_t, + pad_h: ::std::os::raw::c_int, + pad_w: ::std::os::raw::c_int, + u: ::std::os::raw::c_int, + v: ::std::os::raw::c_int, + dilation_h: ::std::os::raw::c_int, + dilation_w: ::std::os::raw::c_int, + mode: cudnnConvolutionMode_t, + computeType: cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolution2dDescriptor( + convDesc: cudnnConvolutionDescriptor_t, + pad_h: *mut ::std::os::raw::c_int, + pad_w: *mut ::std::os::raw::c_int, + u: *mut ::std::os::raw::c_int, + v: *mut ::std::os::raw::c_int, + dilation_h: *mut ::std::os::raw::c_int, + dilation_w: *mut ::std::os::raw::c_int, + mode: *mut cudnnConvolutionMode_t, + computeType: *mut cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetConvolutionNdDescriptor( + convDesc: cudnnConvolutionDescriptor_t, + arrayLength: ::std::os::raw::c_int, + padA: *const ::std::os::raw::c_int, + filterStrideA: *const ::std::os::raw::c_int, + dilationA: *const ::std::os::raw::c_int, + mode: cudnnConvolutionMode_t, + computeType: cudnnDataType_t, +) -> cudnnStatus_t { + crate::set_convolution_nd_descriptor( + convDesc, + arrayLength, + padA, + filterStrideA, + dilationA, + mode, + computeType, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionNdDescriptor( + convDesc: cudnnConvolutionDescriptor_t, + arrayLengthRequested: ::std::os::raw::c_int, + arrayLength: *mut ::std::os::raw::c_int, + padA: *mut ::std::os::raw::c_int, + strideA: *mut ::std::os::raw::c_int, + dilationA: *mut ::std::os::raw::c_int, + mode: *mut cudnnConvolutionMode_t, + computeType: *mut cudnnDataType_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolution2dForwardOutputDim( + convDesc: cudnnConvolutionDescriptor_t, + inputTensorDesc: cudnnTensorDescriptor_t, + filterDesc: cudnnFilterDescriptor_t, + n: *mut ::std::os::raw::c_int, + c: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + w: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionNdForwardOutputDim( + convDesc: cudnnConvolutionDescriptor_t, + inputTensorDesc: cudnnTensorDescriptor_t, + filterDesc: cudnnFilterDescriptor_t, + nbDims: ::std::os::raw::c_int, + tensorOuputDimA: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::get_convolution_nd_forward_output_dim( + convDesc, + inputTensorDesc, + filterDesc, + nbDims, + tensorOuputDimA, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionForwardAlgorithmMaxCount( + handle: cudnnHandle_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionForwardAlgorithm_v7( + handle: cudnnHandle_t, + srcDesc: cudnnTensorDescriptor_t, + filterDesc: cudnnFilterDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + destDesc: cudnnTensorDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionFwdAlgoPerf_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionForwardAlgorithm( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + wDesc: cudnnFilterDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionFwdAlgoPerf_t, +) -> cudnnStatus_t { + crate::find_convolution_forward_algorithm( + handle, + xDesc, + wDesc, + convDesc, + yDesc, + requestedAlgoCount, + returnedAlgoCount, + perfResults, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionForwardAlgorithmEx( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionFwdAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::find_convolution_forward_algorithm_ex( + handle, + xDesc, + x, + wDesc, + w, + convDesc, + yDesc, + y, + requestedAlgoCount, + returnedAlgoCount, + perfResults, + workSpace, + workSpaceSizeInBytes + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnIm2Col( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + colBuffer: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnReorderFilterAndBias( + handle: cudnnHandle_t, + filterDesc: cudnnFilterDescriptor_t, + reorderType: cudnnReorderType_t, + filterData: *const ::std::os::raw::c_void, + reorderedFilterData: *mut ::std::os::raw::c_void, + reorderBias: ::std::os::raw::c_int, + biasData: *const ::std::os::raw::c_void, + reorderedBiasData: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionForwardWorkspaceSize( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + wDesc: cudnnFilterDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + algo: cudnnConvolutionFwdAlgo_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::get_convolution_forward_workspace_size( + handle, + xDesc, + wDesc, + convDesc, + yDesc, + algo, + sizeInBytes, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnConvolutionForward( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + algo: cudnnConvolutionFwdAlgo_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + beta: *const ::std::os::raw::c_void, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::convolution_forward( + handle, + alpha, + xDesc, + x, + wDesc, + w, + convDesc, + algo, + workSpace, + workSpaceSizeInBytes, + beta, + yDesc, + y, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnConvolutionBiasActivationForward( + handle: cudnnHandle_t, + alpha1: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + algo: cudnnConvolutionFwdAlgo_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + alpha2: *const ::std::os::raw::c_void, + zDesc: cudnnTensorDescriptor_t, + z: *const ::std::os::raw::c_void, + biasDesc: cudnnTensorDescriptor_t, + bias: *const ::std::os::raw::c_void, + activationDesc: cudnnActivationDescriptor_t, + yDesc: cudnnTensorDescriptor_t, + y: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardDataAlgorithmMaxCount( + handle: cudnnHandle_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::get_convolution_backward_data_algorithm_max_count(handle, count) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionBackwardDataAlgorithm( + handle: cudnnHandle_t, + wDesc: cudnnFilterDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdDataAlgoPerf_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionBackwardDataAlgorithmEx( + handle: cudnnHandle_t, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdDataAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardDataAlgorithm_v7( + handle: cudnnHandle_t, + filterDesc: cudnnFilterDescriptor_t, + diffDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + gradDesc: cudnnTensorDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdDataAlgoPerf_t, +) -> cudnnStatus_t { + crate::get_convolution_backward_data_algorithm_v7( + handle, + filterDesc, + diffDesc, + convDesc, + gradDesc, + requestedAlgoCount, + returnedAlgoCount, + perfResults, + usize::MAX, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardDataWorkspaceSize( + handle: cudnnHandle_t, + wDesc: cudnnFilterDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + dxDesc: cudnnTensorDescriptor_t, + algo: cudnnConvolutionBwdDataAlgo_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::get_convolution_backward_data_workspace_size( + handle, + wDesc, + dyDesc, + convDesc, + dxDesc, + algo, + sizeInBytes, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnConvolutionBackwardData( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + wDesc: cudnnFilterDescriptor_t, + w: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + algo: cudnnConvolutionBwdDataAlgo_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + beta: *const ::std::os::raw::c_void, + dxDesc: cudnnTensorDescriptor_t, + dx: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::convolution_backward_data( + handle, + alpha, + wDesc, + w, + dyDesc, + dy, + convDesc, + algo, + workSpace, + workSpaceSizeInBytes, + beta, + dxDesc, + dx, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFoldedConvBackwardDataDescriptors( + handle: cudnnHandle_t, + filterDesc: cudnnFilterDescriptor_t, + diffDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + gradDesc: cudnnTensorDescriptor_t, + transformFormat: cudnnTensorFormat_t, + foldedFilterDesc: cudnnFilterDescriptor_t, + paddedDiffDesc: cudnnTensorDescriptor_t, + foldedConvDesc: cudnnConvolutionDescriptor_t, + foldedGradDesc: cudnnTensorDescriptor_t, + filterFoldTransDesc: cudnnTensorTransformDescriptor_t, + diffPadTransDesc: cudnnTensorTransformDescriptor_t, + gradFoldTransDesc: cudnnTensorTransformDescriptor_t, + gradUnfoldTransDesc: cudnnTensorTransformDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCnnInferVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardFilterAlgorithmMaxCount( + handle: cudnnHandle_t, + count: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionBackwardFilterAlgorithm( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + dwDesc: cudnnFilterDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdFilterAlgoPerf_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFindConvolutionBackwardFilterAlgorithmEx( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + y: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + dwDesc: cudnnFilterDescriptor_t, + dw: *mut ::std::os::raw::c_void, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdFilterAlgoPerf_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardFilterAlgorithm_v7( + handle: cudnnHandle_t, + srcDesc: cudnnTensorDescriptor_t, + diffDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + gradDesc: cudnnFilterDescriptor_t, + requestedAlgoCount: ::std::os::raw::c_int, + returnedAlgoCount: *mut ::std::os::raw::c_int, + perfResults: *mut cudnnConvolutionBwdFilterAlgoPerf_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetConvolutionBackwardFilterWorkspaceSize( + handle: cudnnHandle_t, + xDesc: cudnnTensorDescriptor_t, + dyDesc: cudnnTensorDescriptor_t, + convDesc: cudnnConvolutionDescriptor_t, + gradDesc: cudnnFilterDescriptor_t, + algo: cudnnConvolutionBwdFilterAlgo_t, + sizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnConvolutionBackwardFilter( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + xDesc: cudnnTensorDescriptor_t, + x: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + convDesc: cudnnConvolutionDescriptor_t, + algo: cudnnConvolutionBwdFilterAlgo_t, + workSpace: *mut ::std::os::raw::c_void, + workSpaceSizeInBytes: usize, + beta: *const ::std::os::raw::c_void, + dwDesc: cudnnFilterDescriptor_t, + dw: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnConvolutionBackwardBias( + handle: cudnnHandle_t, + alpha: *const ::std::os::raw::c_void, + dyDesc: cudnnTensorDescriptor_t, + dy: *const ::std::os::raw::c_void, + beta: *const ::std::os::raw::c_void, + dbDesc: cudnnTensorDescriptor_t, + db: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateFusedOpsConstParamPack( + constPack: *mut cudnnFusedOpsConstParamPack_t, + ops: cudnnFusedOps_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyFusedOpsConstParamPack( + constPack: cudnnFusedOpsConstParamPack_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetFusedOpsConstParamPackAttribute( + constPack: cudnnFusedOpsConstParamPack_t, + paramLabel: cudnnFusedOpsConstParamLabel_t, + param: *const ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFusedOpsConstParamPackAttribute( + constPack: cudnnFusedOpsConstParamPack_t, + paramLabel: cudnnFusedOpsConstParamLabel_t, + param: *mut ::std::os::raw::c_void, + isNULL: *mut ::std::os::raw::c_int, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateFusedOpsVariantParamPack( + varPack: *mut cudnnFusedOpsVariantParamPack_t, + ops: cudnnFusedOps_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyFusedOpsVariantParamPack( + varPack: cudnnFusedOpsVariantParamPack_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnSetFusedOpsVariantParamPackAttribute( + varPack: cudnnFusedOpsVariantParamPack_t, + paramLabel: cudnnFusedOpsVariantParamLabel_t, + ptr: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnGetFusedOpsVariantParamPackAttribute( + varPack: cudnnFusedOpsVariantParamPack_t, + paramLabel: cudnnFusedOpsVariantParamLabel_t, + ptr: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCreateFusedOpsPlan( + plan: *mut cudnnFusedOpsPlan_t, + ops: cudnnFusedOps_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnDestroyFusedOpsPlan(plan: cudnnFusedOpsPlan_t) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnMakeFusedOpsPlan( + handle: cudnnHandle_t, + plan: cudnnFusedOpsPlan_t, + constPack: cudnnFusedOpsConstParamPack_t, + workspaceSizeInBytes: *mut usize, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnFusedOpsExecute( + handle: cudnnHandle_t, + plan: cudnnFusedOpsPlan_t, + varPack: cudnnFusedOpsVariantParamPack_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnCnnTrainVersionCheck() -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendCreateDescriptor( + descriptorType: cudnnBackendDescriptorType_t, + descriptor: *mut cudnnBackendDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendDestroyDescriptor( + descriptor: cudnnBackendDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendInitialize( + descriptor: cudnnBackendDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendFinalize( + descriptor: cudnnBackendDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendSetAttribute( + descriptor: cudnnBackendDescriptor_t, + attributeName: cudnnBackendAttributeName_t, + attributeType: cudnnBackendAttributeType_t, + elementCount: i64, + arrayOfElements: *const ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendGetAttribute( + descriptor: cudnnBackendDescriptor_t, + attributeName: cudnnBackendAttributeName_t, + attributeType: cudnnBackendAttributeType_t, + requestedElementCount: i64, + elementCount: *mut i64, + arrayOfElements: *mut ::std::os::raw::c_void, +) -> cudnnStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cudnnBackendExecute( + handle: cudnnHandle_t, + executionPlan: cudnnBackendDescriptor_t, + variantPack: cudnnBackendDescriptor_t, +) -> cudnnStatus_t { + crate::unsupported() +} diff --git a/zluda_dnn/src/lib.rs b/zluda_dnn/src/lib.rs new file mode 100644 index 0000000..3f1d19f --- /dev/null +++ b/zluda_dnn/src/lib.rs @@ -0,0 +1,1101 @@ +#[allow(warnings)] +mod cudnn_types_v7; +#[allow(warnings)] +mod cudnn_types_v8; + +pub mod types { + pub use super::cudnn_types_v7::*; + pub use super::cudnn_types_v8::*; +} + +#[allow(warnings)] +mod cudnn_v7; +pub use cudnn_v7::*; + +#[allow(warnings)] +mod cudnn_v8; +pub use cudnn_v8::*; + +use types::*; + +use hip_runtime_sys::*; +use miopen_sys::*; +use std::{mem, ptr}; + +macro_rules! call { + ($expr:expr) => {{ + let result = $expr; + if result != miopen_sys::miopenStatus_t::miopenStatusSuccess { + return to_cudnn(result); + } + }}; +} + +#[cfg(debug_assertions)] +fn unsupported() -> cudnnStatus_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +fn unsupported() -> cudnnStatus_t { + cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED +} + +fn to_cudnn(status: miopen_sys::miopenStatus_t) -> cudnnStatus_t { + match status { + miopen_sys::miopenStatus_t::miopenStatusSuccess => cudnnStatus_t::CUDNN_STATUS_SUCCESS, + err => panic!("{}", err.0), //cudnnStatus_t::CUDNN_STATUS_INTERNAL_ERROR, + } +} + +unsafe fn create(handle: *mut cudnnHandle_t) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreate(handle as _)) +} + +unsafe fn cudnn_create_tensor_descriptor( + tensor_desc: *mut cudnnTensorDescriptor_t, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreateTensorDescriptor(tensor_desc as _)) +} + +unsafe fn cudnn_create_activation_descriptor( + activation_desc: *mut cudnnActivationDescriptor_t, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreateActivationDescriptor( + activation_desc as _, + )) +} + +unsafe fn cudnn_create_convolution_descriptor( + conv_desc: *mut cudnnConvolutionDescriptor_t, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreateConvolutionDescriptor( + conv_desc as _, + )) +} + +unsafe fn cudnn_create_filter_descriptor( + filter_desc: *mut cudnnFilterDescriptor_t, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreateTensorDescriptor(filter_desc as _)) +} + +unsafe fn cudnn_create_lrn_descriptor(norm_desc: *mut cudnnLRNDescriptor_t) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreateLRNDescriptor(norm_desc as _)) +} + +unsafe fn cudnn_create_pooling_descriptor( + pooling_desc: *mut cudnnPoolingDescriptor_t, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenCreatePoolingDescriptor(pooling_desc as _)) +} + +unsafe fn set_tensor_nd_decriptor( + tensor_desc: *mut cudnnTensorStruct, + data_type: cudnnDataType_t, + nb_dims: i32, + dim_a: *const i32, + stride_a: *const i32, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenSetTensorDescriptor( + tensor_desc as _, + from_data_type(data_type), + nb_dims, + dim_a as _, + stride_a as _, + )) +} + +fn from_data_type(type_: cudnnDataType_t) -> miopenDataType_t { + match type_ { + cudnnDataType_t::CUDNN_DATA_FLOAT => miopenDataType_t::miopenFloat, + cudnnDataType_t::CUDNN_DATA_DOUBLE => miopenDataType_t::miopenDouble, + cudnnDataType_t::CUDNN_DATA_HALF => miopenDataType_t::miopenHalf, + _ => todo!(), + } +} + +unsafe fn set_filter_nd_descriptor( + filter_desc: cudnnFilterDescriptor_t, + data_type: cudnnDataType_t, + _format: cudnnTensorFormat_t, + nb_dims: i32, + filter_dim_a: *const i32, +) -> cudnnStatus_t { + let data_type = from_data_type(data_type); + to_cudnn(miopenSetTensorDescriptor( + filter_desc as _, + data_type, + nb_dims, + filter_dim_a as _, + ptr::null_mut(), + )) +} + +unsafe fn set_convolution_nd_descriptor( + conv_desc: cudnnConvolutionDescriptor_t, + array_length: i32, + pad_a: *const i32, + filter_stride_a: *const i32, + dilation_a: *const i32, + mode: cudnnConvolutionMode_t, + _compute_type: cudnnDataType_t, +) -> cudnnStatus_t { + if array_length != 2 { + todo!() + } + let pad_h = *pad_a.add(0); + let pad_w = *pad_a.add(1); + let u = *filter_stride_a.add(0); + let v = *filter_stride_a.add(1); + let d_h = *dilation_a.add(0); + let d_w = *dilation_a.add(1); + let mode = conv_mode_to_cudnn(mode); + to_cudnn(miopen_sys::miopenInitConvolutionDescriptor( + conv_desc as _, + mode, + pad_h, + pad_w, + u, + v, + d_h, + d_w, + )) +} + +fn conv_mode_to_cudnn(mode: cudnnConvolutionMode_t) -> miopenConvolutionMode_t { + match mode { + cudnnConvolutionMode_t::CUDNN_CONVOLUTION => miopenConvolutionMode_t::miopenTranspose, + cudnnConvolutionMode_t::CUDNN_CROSS_CORRELATION => { + miopenConvolutionMode_t::miopenConvolution + } + _ => panic!(), + } +} + +unsafe fn get_convolution_nd_forward_output_dim( + conv_desc: cudnnConvolutionDescriptor_t, + input_tensor_desc: cudnnTensorDescriptor_t, + filter_desc: cudnnFilterDescriptor_t, + mut nb_dims: i32, + tensor_ouput_dim_a: *mut i32, +) -> cudnnStatus_t { + to_cudnn(miopen_sys::miopenGetConvolutionNdForwardOutputDim( + conv_desc as _, + input_tensor_desc as _, + filter_desc as _, + &mut nb_dims as *mut _, + tensor_ouput_dim_a, + )) +} + +unsafe fn find_convolution_forward_algorithm( + handle: cudnnHandle_t, + x_desc: cudnnTensorDescriptor_t, + w_desc: cudnnFilterDescriptor_t, + conv_desc: cudnnConvolutionDescriptor_t, + y_desc: cudnnTensorDescriptor_t, + requested_algo_count: i32, + returned_algo_count: *mut i32, + perf_results: *mut cudnnConvolutionFwdAlgoPerf_t, +) -> cudnnStatus_t { + let mut result = vec![mem::zeroed(); requested_algo_count as usize]; + let mut x_size = 0; + call! { miopenGetTensorNumBytes(x_desc as _, &mut x_size) }; + let mut x = mem::zeroed(); + let error = hipMalloc(&mut x, x_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut w_size = 0; + call! { miopenGetTensorNumBytes(w_desc as _, &mut w_size) }; + let mut w = mem::zeroed(); + let error = hipMalloc(&mut w, w_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut y_size = 0; + call! { miopenGetTensorNumBytes(y_desc as _, &mut y_size) }; + let mut y = mem::zeroed(); + let error = hipMalloc(&mut y, y_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut workspace_size = 0; + call! { miopenConvolutionForwardGetWorkSpaceSize(handle as _, w_desc as _, x_desc as _, conv_desc as _, y_desc as _, &mut workspace_size) }; + let mut workspace = mem::zeroed(); + let error = hipMalloc(&mut workspace, workspace_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let error = to_cudnn(miopenFindConvolutionForwardAlgorithm( + handle as _, + x_desc as _, + x, + w_desc as _, + w, + conv_desc as _, + y_desc as _, + y, + requested_algo_count, + returned_algo_count, + result.as_mut_ptr(), + workspace, + workspace_size, + true, + )); + // TODO: propagaate error codes + drop(hipFree(x)); + drop(hipFree(w)); + drop(hipFree(y)); + drop(hipFree(workspace)); + for i in 0..result.len() { + let result = result[i]; + *perf_results.add(i) = algoperf_to_cudnn(result); + } + error +} + +unsafe fn find_convolution_forward_algorithm_ex( + handle: *mut cudnnContext, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + w_desc: *mut cudnnFilterStruct, + w: *const std::ffi::c_void, + conv_desc: *mut cudnnConvolutionStruct, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, + requested_algo_count: i32, + returned_algo_count: *mut i32, + perf_results: *mut cudnnConvolutionFwdAlgoPerfStruct, + work_space: *mut std::ffi::c_void, + work_space_size_in_bytes: usize, +) -> cudnnStatus_t { + let mut result = vec![mem::zeroed(); requested_algo_count as usize]; + let error = to_cudnn(miopenFindConvolutionForwardAlgorithm( + handle as _, + x_desc as _, + x, + w_desc as _, + w, + conv_desc as _, + y_desc as _, + y, + requested_algo_count, + returned_algo_count, + result.as_mut_ptr(), + work_space, + work_space_size_in_bytes, + true, + )); + for i in 0..result.len() { + let result = result[i]; + *perf_results.add(i) = algoperf_to_cudnn(result); + } + error +} + +unsafe fn algoperf_to_cudnn(result: miopenConvAlgoPerf_t) -> cudnnConvolutionFwdAlgoPerf_t { + let algo = algo_to_cudnn(result); + cudnnConvolutionFwdAlgoPerf_t { + algo, + status: cudnnStatus_t::CUDNN_STATUS_SUCCESS, + time: result.time, + memory: result.memory, + determinism: cudnnDeterminism_t::CUDNN_NON_DETERMINISTIC, + mathType: cudnnMathType_t::CUDNN_DEFAULT_MATH, + reserved: mem::zeroed(), + } +} + +unsafe fn algo_to_cudnn(result: miopenConvAlgoPerf_t) -> cudnnConvolutionFwdAlgo_t { + match result.__bindgen_anon_1.fwd_algo { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoGEMM => { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_GEMM + } + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoDirect => { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_DIRECT + } + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoFFT => { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_FFT + } + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoWinograd => { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD + } + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoImplicitGEMM => { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM + } + _ => cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_GEMM, + } +} + +unsafe fn get_convolution_forward_algorithm( + handle: cudnnHandle_t, + x_desc: cudnnTensorDescriptor_t, + w_desc: cudnnFilterDescriptor_t, + conv_desc: cudnnConvolutionDescriptor_t, + y_desc: cudnnTensorDescriptor_t, + _memory_limit_in_bytes: usize, + algo: *mut cudnnConvolutionFwdAlgo_t, +) -> cudnnStatus_t { + let mut algo_count = 0; + let mut result = mem::zeroed(); + let mut x_size = 0; + call! { miopenGetTensorNumBytes(x_desc as _, &mut x_size) }; + let mut x = mem::zeroed(); + let error = hipMalloc(&mut x, x_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut w_size = 0; + call! { miopenGetTensorNumBytes(w_desc as _, &mut w_size) }; + let mut w = mem::zeroed(); + let error = hipMalloc(&mut w, w_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut y_size = 0; + call! { miopenGetTensorNumBytes(y_desc as _, &mut y_size) }; + let mut y = mem::zeroed(); + let error = hipMalloc(&mut y, y_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut workspace_size = 0; + call! { miopenConvolutionForwardGetWorkSpaceSize(handle as _, w_desc as _, x_desc as _, conv_desc as _, y_desc as _, &mut workspace_size) }; + let mut workspace = mem::zeroed(); + let error = hipMalloc(&mut workspace, workspace_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let error = to_cudnn(miopenFindConvolutionForwardAlgorithm( + handle as _, + x_desc as _, + x, + w_desc as _, + w, + conv_desc as _, + y_desc as _, + y, + 1, + &mut algo_count, + &mut result, + workspace, + workspace_size, + true, + )); + // TODO: propagate error codes + drop(hipFree(x)); + drop(hipFree(w)); + drop(hipFree(y)); + drop(hipFree(workspace)); + if algo_count > 0 { + *algo = algo_to_cudnn(result); + } + error +} + +pub unsafe fn get_convolution_forward_workspace_size( + handle: *mut cudnnContext, + x_desc: *mut cudnnTensorStruct, + w_desc: *mut cudnnFilterStruct, + conv_desc: *mut cudnnConvolutionStruct, + y_desc: *mut cudnnTensorStruct, + _algo: cudnnConvolutionFwdAlgo_t, + size_in_bytes: *mut usize, +) -> cudnnStatus_t { + to_cudnn(miopenConvolutionForwardGetWorkSpaceSize( + handle as _, + w_desc as _, + x_desc as _, + conv_desc as _, + y_desc as _, + size_in_bytes, + )) +} + +unsafe fn convolution_forward( + handle: *mut cudnnContext, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + w_desc: *mut cudnnFilterStruct, + w: *const std::ffi::c_void, + conv_desc: *mut cudnnConvolutionStruct, + algo: cudnnConvolutionFwdAlgo_t, + work_space: *mut std::ffi::c_void, + work_space_size_in_bytes: usize, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + let mut algo = algo_from_cudnn(algo); + // In cuDNN it is possible to find algorithm for sizes X and then pass the algo + // for sizes Y. On miOpen this fails + let mut perf_results = vec![mem::zeroed(); 32]; + let mut algo_count = 0; + call!(miopenFindConvolutionForwardAlgorithm( + handle as _, + x_desc as _, + x, + w_desc as _, + w, + conv_desc as _, + y_desc as _, + y, + 32, + &mut algo_count, + perf_results.as_mut_ptr(), + work_space, + work_space_size_in_bytes, + true, + )); + if algo_count == 0 { + panic!() + } + if let None = perf_results[..algo_count as usize] + .iter() + .find(|result| result.__bindgen_anon_1.fwd_algo == algo) + { + algo = perf_results[0].__bindgen_anon_1.fwd_algo; + } + to_cudnn(miopenConvolutionForward( + handle as _, + alpha, + x_desc as _, + x, + w_desc as _, + w, + conv_desc as _, + algo, + beta, + y_desc as _, + y, + work_space, + work_space_size_in_bytes, + )) +} + +fn algo_from_cudnn(algo: cudnnConvolutionFwdAlgo_t) -> miopenConvFwdAlgorithm_t { + match algo { + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoImplicitGEMM + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoGEMM + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_GEMM => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoGEMM + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_DIRECT => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoDirect + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_FFT => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoFFT + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_FFT_TILING => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoFFT + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoWinograd + } + cudnnConvolutionFwdAlgo_t::CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED => { + miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoWinograd + } + _ => miopenConvFwdAlgorithm_t::miopenConvolutionFwdAlgoGEMM, + } +} + +unsafe fn add_tensor( + handle: *mut cudnnContext, + alpha: *const std::ffi::c_void, + a_desc: *mut cudnnTensorStruct, + a: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + c_desc: *mut cudnnTensorStruct, + c: *mut std::ffi::c_void, +) -> cudnnStatus_t { + // CUDA tensor A might be 1 in some dimensions + // MIOpen tensors A and C must be the same + let zero = 0f64; + to_cudnn(miopenOpTensor( + handle as _, + miopenTensorOp_t::miopenTensorOpAdd, + alpha, + c_desc as _, + c, + beta, + a_desc as _, + a, + &zero as *const _ as _, + c_desc as _, + c, + )) +} + +unsafe fn set_pooling_nd_descriptor( + pooling_desc: *mut cudnnPoolingStruct, + mode: cudnnPoolingMode_t, + _maxpooling_nan_opt: cudnnNanPropagation_t, + nb_dims: i32, + window_dim_a: *const i32, + padding_a: *const i32, + stride_a: *const i32, +) -> cudnnStatus_t { + let mode = pooling_from_cudnn(mode); + to_cudnn(miopenSetNdPoolingDescriptor( + pooling_desc as _, + mode, + nb_dims, + window_dim_a as _, + padding_a as _, + stride_a as _, + )) +} + +fn pooling_from_cudnn(mode: cudnnPoolingMode_t) -> miopenPoolingMode_t { + match mode { + cudnnPoolingMode_t::CUDNN_POOLING_MAX => miopenPoolingMode_t::miopenPoolingMax, + cudnnPoolingMode_t::CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING => { + miopenPoolingMode_t::miopenPoolingAverageInclusive + } + cudnnPoolingMode_t::CUDNN_POOLING_AVERAGE_COUNT_EXCLUDE_PADDING => { + miopenPoolingMode_t::miopenPoolingAverage + } + _ => todo!(), + } +} + +unsafe fn get_pooling_nd_forward_output_dim( + pooling_desc: *mut cudnnPoolingStruct, + input_tensor_desc: *mut cudnnTensorStruct, + nb_dims: i32, + output_tensor_dim_a: *mut i32, +) -> cudnnStatus_t { + if nb_dims != 4 { + todo!() + } + to_cudnn(miopenGetPoolingForwardOutputDim( + pooling_desc as _, + input_tensor_desc as _, + output_tensor_dim_a.add(0), + output_tensor_dim_a.add(1), + output_tensor_dim_a.add(2), + output_tensor_dim_a.add(3), + )) +} + +unsafe fn pooling_forward( + handle: *mut cudnnContext, + pooling_desc: *mut cudnnPoolingStruct, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + let mut workspace_size = 0; + call! { miopenPoolingGetWorkSpaceSize(y_desc as _, &mut workspace_size) }; + let mut workspace = mem::zeroed(); + let error = hipMalloc(&mut workspace, workspace_size); + if error != hipError_t::hipSuccess { + return cudnnStatus_t::CUDNN_STATUS_INTERNAL_ERROR; + } + // TODO: Only alpha=1 and beta=0 is supported + let error = to_cudnn(miopenPoolingForward( + handle as _, + pooling_desc as _, + alpha, + x_desc as _, + x, + beta, + y_desc as _, + y, + false, + workspace, + workspace_size, + )); + // TODO: propagate error codes + drop(hipFree(workspace)); + error +} + +unsafe fn set_activation_descriptor( + activation_desc: *mut cudnnActivationStruct, + mode: cudnnActivationMode_t, + _relu_nan_opt: cudnnNanPropagation_t, + coef: f64, +) -> cudnnStatus_t { + let mode = activation_mode(mode); + to_cudnn(miopenSetActivationDescriptor( + activation_desc as _, + mode, + coef, + 0.0, + 0.0, + )) +} + +fn activation_mode(mode: cudnnActivationMode_t) -> miopenActivationMode_t { + match mode { + cudnnActivationMode_t::CUDNN_ACTIVATION_SIGMOID => { + miopenActivationMode_t::miopenActivationLOGISTIC + } + cudnnActivationMode_t::CUDNN_ACTIVATION_RELU => { + miopenActivationMode_t::miopenActivationRELU + } + cudnnActivationMode_t::CUDNN_ACTIVATION_TANH => { + miopenActivationMode_t::miopenActivationTANH + } + cudnnActivationMode_t::CUDNN_ACTIVATION_CLIPPED_RELU => { + miopenActivationMode_t::miopenActivationCLIPPEDRELU + } + cudnnActivationMode_t::CUDNN_ACTIVATION_ELU => miopenActivationMode_t::miopenActivationELU, + cudnnActivationMode_t::CUDNN_ACTIVATION_IDENTITY => { + miopenActivationMode_t::miopenActivationPASTHRU + } + _ => panic!(), + } +} + +unsafe fn activation_forward( + handle: *mut cudnnContext, + activation_desc: *mut cudnnActivationStruct, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + to_cudnn(miopenActivationForward( + handle as _, + activation_desc as _, + alpha, + x_desc as _, + x, + beta, + y_desc as _, + y, + )) +} + +unsafe fn set_lrn_descriptor( + norm_desc: *mut cudnnLRNStruct, + lrn_n: u32, + lrn_alpha: f64, + lrn_beta: f64, + lrn_k: f64, +) -> cudnnStatus_t { + to_cudnn(miopenSetLRNDescriptor( + norm_desc as _, + miopenLRNMode_t::miopenLRNCrossChannel, // ??? + lrn_n, + lrn_alpha, + lrn_beta, + lrn_k, + )) +} + +unsafe fn lrn_cross_channel_forward( + handle: *mut cudnnContext, + norm_desc: *mut cudnnLRNStruct, + _lrn_mode: cudnnLRNMode_t, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + to_cudnn(miopenLRNForward( + handle as _, + norm_desc as _, + alpha, + x_desc as _, + x, + beta, + y_desc as _, + y, + false, + ptr::null_mut(), + )) +} + +unsafe fn softmax_forward( + handle: *mut cudnnContext, + algo: cudnnSoftmaxAlgorithm_t, + mode: cudnnSoftmaxMode_t, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + let algo = softmax_algo(algo); + let mode = softmax_mode(mode); + to_cudnn(miopenSoftmaxForward_V2( + handle as _, + alpha, + x_desc as _, + x, + beta, + y_desc as _, + y, + algo, + mode, + )) +} + +fn softmax_algo(algo: cudnnSoftmaxAlgorithm_t) -> miopenSoftmaxAlgorithm_t { + match algo { + cudnnSoftmaxAlgorithm_t::CUDNN_SOFTMAX_ACCURATE => { + miopenSoftmaxAlgorithm_t::MIOPEN_SOFTMAX_ACCURATE + } + cudnnSoftmaxAlgorithm_t::CUDNN_SOFTMAX_FAST => { + miopenSoftmaxAlgorithm_t::MIOPEN_SOFTMAX_FAST + } + cudnnSoftmaxAlgorithm_t::CUDNN_SOFTMAX_LOG => miopenSoftmaxAlgorithm_t::MIOPEN_SOFTMAX_LOG, + _ => panic!(), + } +} + +fn softmax_mode(mode: cudnnSoftmaxMode_t) -> miopenSoftmaxMode_t { + match mode { + cudnnSoftmaxMode_t::CUDNN_SOFTMAX_MODE_CHANNEL => { + miopenSoftmaxMode_t::MIOPEN_SOFTMAX_MODE_CHANNEL + } + cudnnSoftmaxMode_t::CUDNN_SOFTMAX_MODE_INSTANCE => { + miopenSoftmaxMode_t::MIOPEN_SOFTMAX_MODE_INSTANCE + } + _ => panic!(), + } +} + +unsafe fn destroy(handle: *mut cudnnContext) -> cudnnStatus_t { + to_cudnn(miopenDestroy(handle as _)) +} + +unsafe fn destroy_activation_descriptor( + activation_desc: *mut cudnnActivationStruct, +) -> cudnnStatus_t { + to_cudnn(miopenDestroyActivationDescriptor(activation_desc as _)) +} + +unsafe fn destroy_convolution_descriptor(conv_desc: *mut cudnnConvolutionStruct) -> cudnnStatus_t { + to_cudnn(miopenDestroyConvolutionDescriptor(conv_desc as _)) +} + +unsafe fn destroy_filter_descriptor(filter_desc: *mut cudnnFilterStruct) -> cudnnStatus_t { + to_cudnn(miopenDestroyTensorDescriptor(filter_desc as _)) +} + +unsafe fn destroy_lrn_descriptor(lrn_desc: *mut cudnnLRNStruct) -> cudnnStatus_t { + to_cudnn(miopenDestroyLRNDescriptor(lrn_desc as _)) +} + +unsafe fn destroy_pooling_descriptor(pooling_desc: *mut cudnnPoolingStruct) -> cudnnStatus_t { + to_cudnn(miopenDestroyPoolingDescriptor(pooling_desc as _)) +} + +unsafe fn destroy_tensor_descriptor(tensor_desc: *mut cudnnTensorStruct) -> cudnnStatus_t { + to_cudnn(miopenDestroyTensorDescriptor(tensor_desc as _)) +} + +unsafe fn set_tensor_4d_descriptor_ex( + tensor_desc: *mut cudnnTensorStruct, + data_type: cudnnDataType_t, + n: i32, + c: i32, + h: i32, + w: i32, + n_stride: i32, + c_stride: i32, + h_stride: i32, + w_stride: i32, +) -> cudnnStatus_t { + let data_type = from_data_type(data_type); + to_cudnn(miopenSet4dTensorDescriptorEx( + tensor_desc as _, + data_type, + n, + c, + h, + w, + n_stride, + c_stride, + h_stride, + w_stride, + )) +} + +unsafe fn transform_tensor( + handle: *mut cudnnContext, + alpha: *const std::ffi::c_void, + x_desc: *mut cudnnTensorStruct, + x: *const std::ffi::c_void, + beta: *const std::ffi::c_void, + y_desc: *mut cudnnTensorStruct, + y: *mut std::ffi::c_void, +) -> cudnnStatus_t { + to_cudnn(miopenTransformTensor( + handle as _, + alpha, + x_desc as _, + x, + beta, + y_desc as _, + y, + )) +} + +unsafe fn set_stream(stream_id: *mut CUstream_st) -> cudnnStatus_t { + if stream_id != ptr::null_mut() { + todo!() + } + cudnnStatus_t::CUDNN_STATUS_SUCCESS +} + +fn set_convolution_math_type( + _conv_desc: cudnnConvolutionDescriptor_t, + _math_type: cudnnMathType_t, +) -> cudnnStatus_t { + //TODO: implement + cudnnStatus_t::CUDNN_STATUS_SUCCESS +} + +unsafe fn set_convolution_group_count( + conv_desc: *mut cudnnConvolutionStruct, + group_count: i32, +) -> cudnnStatus_t { + //TODO: implement + to_cudnn(miopenSetConvolutionGroupCount(conv_desc as _, group_count)) +} + +unsafe fn get_convolution_backward_data_algorithm_max_count( + _handle: *mut cudnnContext, + count: *mut i32, +) -> cudnnStatus_t { + *count = 1; + cudnnStatus_t::CUDNN_STATUS_SUCCESS +} + +unsafe fn get_convolution_backward_data_algorithm_v7( + handle: *mut cudnnContext, + w_desc: *mut cudnnFilterStruct, + dy_desc: *mut cudnnTensorStruct, + conv_desc: *mut cudnnConvolutionStruct, + dx_desc: *mut cudnnTensorStruct, + requested_algo_count: i32, + returned_algo_count: *mut i32, + perf_results: *mut cudnnConvolutionBwdDataAlgoPerf_t, + memory_limit_in_bytes: usize, +) -> cudnnStatus_t { + let mut work_space_size = 0; + let mut dy_size = 0; + call! { miopenGetTensorNumBytes(dy_desc as _, &mut dy_size) }; + let mut dy = mem::zeroed(); + let error = hipMalloc(&mut dy, dy_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut w_size = 0; + call! { miopenGetTensorNumBytes(w_desc as _, &mut w_size) }; + let mut w = mem::zeroed(); + let error = hipMalloc(&mut w, w_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let mut dx_size = 0; + call! { miopenGetTensorNumBytes(dx_desc as _, &mut dx_size) }; + let mut dx = mem::zeroed(); + let error = hipMalloc(&mut dx, dx_size); + if error != hipError_t::hipSuccess { + panic!("{:?}", error); + } + let error = to_cudnn(miopenConvolutionBackwardDataGetWorkSpaceSize( + handle as _, + dy_desc as _, + w_desc as _, + conv_desc as _, + dx_desc as _, + &mut work_space_size, + )); + work_space_size = work_space_size.min(memory_limit_in_bytes); + if error != cudnnStatus_t::CUDNN_STATUS_SUCCESS { + panic!("") + } + let mut work_space = mem::zeroed(); + if hipMalloc(&mut work_space, work_space_size) != hipError_t::hipSuccess { + panic!("") + } + let mut miopen_perf_results = vec![mem::zeroed(); requested_algo_count as usize]; + let result = to_cudnn(miopenFindConvolutionBackwardDataAlgorithm( + handle as _, + dy_desc as _, + dy, + w_desc as _, + w, + conv_desc as _, + dx_desc as _, + dx, + requested_algo_count, + returned_algo_count, + miopen_perf_results.as_mut_ptr(), + work_space, + work_space_size, + true, + )); + drop(hipFree(dy)); + drop(hipFree(w)); + drop(hipFree(dx)); + drop(hipFree(work_space)); + for i in 0..*returned_algo_count { + *perf_results.add(i as usize) = convert_bwd_algo(miopen_perf_results[i as usize]); + } + result +} + +unsafe fn convert_bwd_algo(result: miopenConvAlgoPerf_t) -> cudnnConvolutionBwdDataAlgoPerf_t { + let algo = bwd_data_algo_to_cudnn(result.__bindgen_anon_1.bwd_data_algo); + cudnnConvolutionBwdDataAlgoPerf_t { + algo, + status: cudnnStatus_t::CUDNN_STATUS_SUCCESS, + time: result.time, + memory: result.memory, + determinism: cudnnDeterminism_t::CUDNN_NON_DETERMINISTIC, + mathType: cudnnMathType_t::CUDNN_DEFAULT_MATH, + reserved: mem::zeroed(), + } +} + +fn bwd_data_algo_to_cudnn(algo: miopenConvBwdDataAlgorithm_t) -> cudnnConvolutionBwdDataAlgo_t { + match algo { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoGEMM => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_0 + } + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoDirect => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_1 + } + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoWinograd => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD + } + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoFFT => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT + } + miopenConvBwdDataAlgorithm_t::miopenTransposeBwdDataAlgoGEMM => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_0 + } + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoImplicitGEMM => { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_0 + } + _ => panic!(), + } +} + +fn bwd_data_algo_from_cudnn(algo: cudnnConvolutionBwdDataAlgo_t) -> miopenConvBwdDataAlgorithm_t { + match algo { + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_0 => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoGEMM + } + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_1 => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoDirect + } + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoFFT + } + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT_TILING => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoFFT + } + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoWinograd + } + cudnnConvolutionBwdDataAlgo_t::CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD_NONFUSED => { + miopenConvBwdDataAlgorithm_t::miopenConvolutionBwdDataAlgoWinograd + } + _ => panic!(), + } +} + +unsafe fn get_convolution_backward_data_algorithm( + handle: *mut cudnnContext, + w_desc: *mut cudnnFilterStruct, + dy_desc: *mut cudnnTensorStruct, + conv_desc: *mut cudnnConvolutionStruct, + dx_desc: *mut cudnnTensorStruct, + memory_limit_in_bytes: usize, + algo: *mut cudnnConvolutionBwdDataAlgo_t, +) -> cudnnStatus_t { + let mut algo_count = 0; + let mut perf_result = mem::zeroed::(); + let error = get_convolution_backward_data_algorithm_v7( + handle, + w_desc, + dy_desc, + conv_desc, + dx_desc, + 1, + &mut algo_count, + &mut perf_result as *mut _, + memory_limit_in_bytes, + ); + if error != cudnnStatus_t::CUDNN_STATUS_SUCCESS || algo_count == 0 { + panic!("") + } + *algo = perf_result.algo; + cudnnStatus_t::CUDNN_STATUS_SUCCESS +} + +unsafe fn get_convolution_backward_data_workspace_size( + handle: *mut cudnnContext, + w_desc: *mut cudnnFilterStruct, + dy_desc: *mut cudnnTensorStruct, + conv_desc: *mut cudnnConvolutionStruct, + dx_desc: *mut cudnnTensorStruct, + _algo: cudnnConvolutionBwdDataAlgo_t, + size_in_bytes: *mut usize, +) -> cudnnStatus_t { + to_cudnn(miopenConvolutionBackwardDataGetWorkSpaceSize( + handle as _, + dy_desc as _, + w_desc as _, + conv_desc as _, + dx_desc as _, + size_in_bytes, + )) +} + +unsafe fn convolution_backward_data( + handle: *mut cudnnContext, + alpha: *const std::ffi::c_void, + w_desc: *mut cudnnFilterStruct, + w: *const std::ffi::c_void, + dy_desc: *mut cudnnTensorStruct, + dy: *const std::ffi::c_void, + conv_desc: *mut cudnnConvolutionStruct, + algo: cudnnConvolutionBwdDataAlgo_t, + work_space: *mut std::ffi::c_void, + work_space_size_in_bytes: usize, + beta: *const std::ffi::c_void, + dx_desc: *mut cudnnTensorStruct, + dx: *mut std::ffi::c_void, +) -> cudnnStatus_t { + let algo = bwd_data_algo_from_cudnn(algo); + to_cudnn(miopenConvolutionBackwardData( + handle as _, + alpha, + dy_desc as _, + dy, + w_desc as _, + w, + conv_desc as _, + algo, + beta, + dx_desc as _, + dx, + work_space, + work_space_size_in_bytes, + )) +} diff --git a/zluda_dump/Cargo.toml b/zluda_dump/Cargo.toml index 80c7ddc..2ee1592 100644 --- a/zluda_dump/Cargo.toml +++ b/zluda_dump/Cargo.toml @@ -9,9 +9,25 @@ name = "zluda_dump" crate-type = ["cdylib"] [dependencies] +hip_common = { path = "../hip_common" } ptx = { path = "../ptx" } +cuda_base = { path = "../cuda_base" } +cuda_types = { path = "../cuda_types" } +zluda_dark_api = { path = "../zluda_dark_api" } +crossbeam-channel = "0.5.4" lz4-sys = "1.9" -regex = "1.4" +regex = "1.5" +dynasm = "1.2" +dynasmrt = "1.2" +lazy_static = "1.4" +# we don't need elf32, but goblin has a bug where elf64 does not build without elf32 +goblin = { version = "0.5.1", default-features = false, features = ["elf64", "elf32", "archive"] } +paste = "1.0" +serde = { version = "1.0.137", features = ["derive"] } +serde_derive = "1.0.137" +serde_json = "1.0.81" +rustc-hash = "1.1" +thread-id = "4.0.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["libloaderapi", "debugapi", "std"] } @@ -20,3 +36,11 @@ detours-sys = { path = "../detours-sys" } [target.'cfg(not(windows))'.dependencies] libc = "0.2" + +[dev-dependencies] +rand_chacha = "0.3.1" +rand = "0.8.5" + +# Nominally debug_only, but useful for power users +[package.metadata.zluda] +dump_names = ["libcuda.so", "libcuda.so.1"] diff --git a/zluda_dump/README.md b/zluda_dump/README.md new file mode 100644 index 0000000..544262a --- /dev/null +++ b/zluda_dump/README.md @@ -0,0 +1,3 @@ +grep -E '^cu.*' log.txt | sed 's/([^)]*)//g' | sort | uniq > uniq_host.txt +cat *.log | grep "^Unrecognized s" | grep -Eo '`([^`]*)`' | sed -E 's/^`((@\w+ )?[^[:space:]]*).*`/\1/' | sort | uniq > uniq_statements.txt +cat *.log | grep "^Unrecognized d" | grep -Eo '`([^`]*)`' | sed -E 's/^`([^`]*)`/\1/' | sort | uniq > uniq_directives.txt \ No newline at end of file diff --git a/zluda_dump/src/dark_api.rs b/zluda_dump/src/dark_api.rs new file mode 100644 index 0000000..a619bca --- /dev/null +++ b/zluda_dump/src/dark_api.rs @@ -0,0 +1,934 @@ +use crate::format; +extern crate zluda_dark_api; +use crate::log::LogEntry; +use crate::{log, os}; +use cuda_types::*; +use std::hash::Hash; +use std::{ + collections::{hash_map, HashMap}, + ffi::c_void, + mem, + os::raw::c_uint, + slice, +}; +use std::{iter, ptr}; +use zluda_dark_api::CUmoduleContent; +use zluda_dark_api::{AntiZludaHashInput, CudaDarkApiDump, CudaDarkApiKnownExports}; + +const MINIMUM_FUNCTION_ADDRESS: usize = 0x1000; + +pub(crate) struct DarkApiState { + // Key is Box, because thunk fn neeads a stable memory location for + // the guid + overrides: HashMap, (Vec<*const c_void>, *const *const c_void)>, + known_exports: CudaDarkApiKnownExports, +} + +#[derive(Eq, PartialEq)] +pub(crate) struct CUuuidWrapper(pub CUuuid); + +impl Hash for CUuuidWrapper { + fn hash(&self, state: &mut H) { + self.0.bytes.hash(state); + } +} + +impl DarkApiState { + pub(crate) fn new() -> Self { + DarkApiState { + overrides: HashMap::new(), + known_exports: CudaDarkApiKnownExports::new(), + } + } +} +pub(crate) fn override_export_table( + fn_logger: &mut log::FunctionLogger, + pp_export_table: *mut *const c_void, + p_export_table_id: *const CUuuid, + state: &mut crate::trace::StateTracker, +) { + let state = &mut state.dark_api; + let guid = Box::new(unsafe { *p_export_table_id }.bytes); + let export_table_mut = unsafe { &mut *pp_export_table }; + *export_table_mut = match state.overrides.entry(guid) { + hash_map::Entry::Occupied(entry) => entry.get().0.as_ptr() as *const _, + hash_map::Entry::Vacant(entry) => { + let known_fns_bitmap = state.known_exports.known(entry.key()); + let byte_length = unsafe { *{ (*export_table_mut) as *const usize } }; + let length; + if byte_length >= MINIMUM_FUNCTION_ADDRESS { + // not length prefixed + if known_fns_bitmap.len() > 0 { + // take "our" length + length = known_fns_bitmap.len(); + } else { + // guess + length = (0..usize::max_value()) + .position(|offset| unsafe { + *((*export_table_mut) as *mut usize).add(offset) + < MINIMUM_FUNCTION_ADDRESS + }) + .unwrap() + + 1; // include terminator just in case + fn_logger.log(LogEntry::ExportTableLengthGuess(length)); + } + } else { + length = byte_length / mem::size_of::<*mut c_void>(); + if known_fns_bitmap.len() > 0 && known_fns_bitmap.len() != length { + fn_logger.log(LogEntry::ExportTableLengthMismatch { + expected: known_fns_bitmap.len(), + observed: length, + }); + } + } + let overriden_table = unsafe { + get_overriden_export_table( + entry.key(), + // padding with false in case the export table got longer in a newer version + known_fns_bitmap.chain(iter::repeat(false)), + slice::from_raw_parts(*pp_export_table as _, length) + .iter() + .copied(), + ) + }; + entry + .insert((overriden_table, unsafe { *pp_export_table } as _)) + .0 + .as_ptr() as _ + } + } +} + +unsafe fn get_overriden_export_table( + guid: &Box<[u8; 16]>, + known_exports: impl Iterator, + original_exports: impl Iterator, +) -> Vec<*const c_void> { + let mut export_table = Vec::new(); + for (idx, (original_fn, is_known)) in original_exports.zip(known_exports).enumerate() { + let override_fn = if !is_known { + os::get_thunk(original_fn, report_unknown_export_table_call, &**guid, idx) + } else { + match zluda_dark_api::get_dark_api_fn::(&guid, idx) { + Some(fn_ptr) => fn_ptr, + None => { + if (original_fn as usize) < MINIMUM_FUNCTION_ADDRESS { + original_fn + } else { + os::get_thunk(original_fn, report_known_export_table_call, &**guid, idx) + } + } + } + }; + export_table.push(override_fn); + } + export_table +} + +unsafe extern "system" fn report_unknown_export_table_call( + export_table: *const [u8; 16], + idx: usize, +) { + if let Ok(mut global_state) = crate::GLOBAL_STATE.lock() { + let mut logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: *export_table, + }, + idx, + None, + ); + logger.log(log::LogEntry::UnknownExportTableFn) + } +} + +unsafe extern "system" fn report_known_export_table_call( + export_table: *const [u8; 16], + idx: usize, +) { + if let Ok(mut global_state) = crate::GLOBAL_STATE.lock() { + let _logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: *export_table, + }, + idx, + None, + ); + } +} + +struct CudaDarkApiDumpFns; + +impl CudaDarkApiDump for CudaDarkApiDumpFns { + unsafe fn get_module_from_cubin_impl( + guid: &[u8; 16], + idx: usize, + module: *mut CUmodule, + fatbinc_wrapper: *const zluda_dark_api::FatbincWrapper, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(result).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&module, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(fatbinc_wrapper).as_bytes())?; + write!(writer, ": {:p})", fatbinc_wrapper) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + *mut CUmodule, + *const zluda_dark_api::FatbincWrapper, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(module, fatbinc_wrapper); + fn_logger.result = Some(original_result); + if !matches!( + original_result, + CUresult::CUDA_SUCCESS + | CUresult::CUDA_ERROR_INVALID_PTX + | CUresult::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE + | CUresult::CUDA_ERROR_NOT_SUPPORTED, + ) { + return original_result; + } + let maybe_fatbin = fn_logger.log_unwrap( + zluda_dark_api::CudaFatbin::from_wrapper(fatbinc_wrapper).map_err(Into::into), + ); + if let Some(fatbin) = maybe_fatbin { + cuda_state.record_module( + &mut fn_logger, + Some(*module), + CUmoduleContent::Fatbin(fatbin), + ); + } + original_result + } + + unsafe fn get_module_from_cubin_ex1_impl( + guid: &[u8; 16], + idx: usize, + module: *mut CUmodule, + fatbinc_wrapper: *const zluda_dark_api::FatbincWrapper, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: usize, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(module).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&module, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(fatbinc_wrapper).as_bytes())?; + write!(writer, ": {:p}, ", fatbinc_wrapper)?; + writer.write_all(stringify!(arg3).as_bytes())?; + write!(writer, ": {:p}, ", arg3)?; + writer.write_all(stringify!(arg4).as_bytes())?; + write!(writer, ": {:p}, ", arg4)?; + writer.write_all(stringify!(arg5).as_bytes())?; + write!(writer, ": {})", arg5) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + *mut CUmodule, + *const zluda_dark_api::FatbincWrapper, + *mut c_void, + *mut c_void, + usize, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(module, fatbinc_wrapper, arg3, arg4, arg5); + fn_logger.result = Some(original_result); + if !matches!( + original_result, + CUresult::CUDA_SUCCESS + | CUresult::CUDA_ERROR_INVALID_PTX + | CUresult::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE + | CUresult::CUDA_ERROR_NOT_SUPPORTED, + ) { + return original_result; + } + let maybe_fatbin = fn_logger.log_unwrap( + zluda_dark_api::CudaFatbin::from_wrapper(fatbinc_wrapper).map_err(Into::into), + ); + if let Some(fatbin) = maybe_fatbin { + cuda_state.record_module( + &mut fn_logger, + Some(*module), + CUmoduleContent::Fatbin(fatbin), + ); + } + original_result + } + + unsafe fn get_module_from_cubin_ex2_impl( + guid: &[u8; 16], + idx: usize, + fatbin_header: *const zluda_dark_api::FatbinHeader, + module: *mut CUmodule, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: c_uint, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(fatbin_header).as_bytes())?; + write!(writer, ": {:p}, ", fatbin_header)?; + writer.write_all(stringify!(module).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&module, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(arg3).as_bytes())?; + write!(writer, ": {:p}, ", arg3)?; + writer.write_all(stringify!(arg4).as_bytes())?; + write!(writer, ": {:p}, ", arg4)?; + writer.write_all(stringify!(arg5).as_bytes())?; + write!(writer, ": {})", arg5) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + *const zluda_dark_api::FatbinHeader, + *mut CUmodule, + *mut c_void, + *mut c_void, + c_uint, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(fatbin_header, module, arg3, arg4, arg5); + fn_logger.result = Some(original_result); + if !matches!( + original_result, + CUresult::CUDA_SUCCESS + | CUresult::CUDA_ERROR_INVALID_PTX + | CUresult::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE + | CUresult::CUDA_ERROR_NOT_SUPPORTED, + ) { + return original_result; + } + cuda_state.record_module( + &mut fn_logger, + Some(*module), + CUmoduleContent::Fatbin(zluda_dark_api::CudaFatbin::from_header(fatbin_header)), + ); + original_result + } + + #[allow(non_snake_case)] + unsafe fn launch_kernel_impl( + guid: &[u8; 16], + idx: usize, + 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, + extra: *mut *mut ::std::os::raw::c_void, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(f).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&f, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(gridDimX).as_bytes())?; + write!(writer, ": {}, ", gridDimX)?; + writer.write_all(stringify!(gridDimY).as_bytes())?; + write!(writer, ": {}, ", gridDimY)?; + writer.write_all(stringify!(gridDimZ).as_bytes())?; + write!(writer, ": {}, ", gridDimZ)?; + writer.write_all(stringify!(blockDimX).as_bytes())?; + write!(writer, ": {}, ", blockDimX)?; + writer.write_all(stringify!(blockDimY).as_bytes())?; + write!(writer, ": {}, ", blockDimY)?; + writer.write_all(stringify!(blockDimZ).as_bytes())?; + write!(writer, ": {}, ", blockDimZ)?; + writer.write_all(stringify!(sharedMemBytes).as_bytes())?; + write!(writer, ": {}, ", sharedMemBytes)?; + writer.write_all(stringify!(hStream).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&hStream, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(extra).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&extra, "cuLaunchKernel", 9, writer)?; + writer.write_all(b")") + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + CUfunction, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + ::std::os::raw::c_uint, + CUstream, + *mut *mut ::std::os::raw::c_void, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn( + f, + gridDimX, + gridDimY, + gridDimZ, + blockDimX, + blockDimY, + blockDimZ, + sharedMemBytes, + hStream, + extra, + ); + fn_logger.result = Some(original_result); + original_result + } + + unsafe fn ctx_create_v2_bypass_impl( + _guid: &[u8; 16], + _idx: usize, + _pctx: *mut cuda_types::CUcontext, + _flags: c_uint, + _dev: cuda_types::CUdevice, + ) -> CUresult { + todo!() + } + + unsafe fn dlss_feature_evaluate_init_impl( + guid: &[u8; 16], + idx: usize, + retval1: *mut *mut c_void, + handle: *mut c_void, + retval2: *mut *mut c_void, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(retval1).as_bytes())?; + write!(writer, ": {:p}, ", deref_not_null(retval1))?; + writer.write_all(stringify!(handle).as_bytes())?; + write!(writer, ": {:p}, ", handle)?; + writer.write_all(stringify!(retval2).as_bytes())?; + write!(writer, ": {:p})", deref_not_null(retval2)) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(*mut *mut c_void, *mut c_void, *mut *mut c_void) -> CUresult, + >(*original_ptr); + let original_result = original_fn(retval1, handle, retval2); + fn_logger.result = Some(original_result); + original_result + } + + unsafe fn dlss_cuInit_impl(guid: &[u8; 16], idx: usize) -> CUresult { + let arguments_writer = + Box::new(move |writer: &mut dyn std::io::Write| writer.write_all(b"()")); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = + mem::transmute::<_, unsafe extern "system" fn() -> CUresult>(*original_ptr); + let original_result = original_fn(); + fn_logger.result = Some(original_result); + original_result + } + + unsafe fn dlss_start1_impl( + guid: &[u8; 16], + idx: usize, + retval1: *mut *mut c_void, + arg2: *mut c_void, + arg3: *mut c_void, + arg4: *mut c_void, + arg5: *mut c_void, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(retval1).as_bytes())?; + write!(writer, ": {:p}, ", deref_not_null(retval1))?; + writer.write_all(stringify!(arg2).as_bytes())?; + write!(writer, ": {:p}, ", arg2)?; + writer.write_all(stringify!(arg3).as_bytes())?; + write!(writer, ": {:p}, ", arg3)?; + writer.write_all(stringify!(arg4).as_bytes())?; + write!(writer, ": {:p}, ", arg4)?; + writer.write_all(stringify!(arg5).as_bytes())?; + write!(writer, ": {:p})", arg5) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + *mut *mut c_void, + *mut c_void, + *mut c_void, + *mut c_void, + *mut c_void, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(retval1, arg2, arg3, arg4, arg5); + fn_logger.result = Some(original_result); + original_result + } + + #[allow(non_snake_case)] + unsafe fn dlss_start2_impl( + guid: &[u8; 16], + idx: usize, + handle: *mut c_void, + retval: *mut u32, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(handle).as_bytes())?; + write!(writer, ": {:p}, ", handle)?; + writer.write_all(stringify!(retval).as_bytes())?; + if retval == ptr::null_mut() { + write!(writer, ": {:p})", retval) + } else { + write!(writer, ": {})", *retval) + } + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(*mut c_void, *mut u32) -> CUresult, + >(*original_ptr); + let original_result = original_fn(handle, retval); + fn_logger.result = Some(original_result); + original_result + } + + #[allow(non_snake_case)] + unsafe fn dlss_feature_evaluate1_impl( + guid: &[u8; 16], + idx: usize, + retval1: *mut u32, + retval2: *mut u32, + retval3: *mut u32, + handle: *mut c_void, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(retval1).as_bytes())?; + writer.write_all(b": ")?; + write_deref(writer, retval1)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(retval2).as_bytes())?; + writer.write_all(b": ")?; + write_deref(writer, retval2)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(retval3).as_bytes())?; + writer.write_all(b": ")?; + write_deref(writer, retval3)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(handle).as_bytes())?; + write!(writer, ": {:p})", handle) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(*mut u32, *mut u32, *mut u32, *mut c_void) -> CUresult, + >(*original_ptr); + let original_result = original_fn(retval1, retval2, retval3, handle); + fn_logger.result = Some(original_result); + original_result + } + + #[allow(non_snake_case)] + unsafe fn dlss_feature_evaluate2_impl( + guid: &[u8; 16], + idx: usize, + handle1: *mut c_void, + handle2: *mut c_void, + handle3: *mut c_void, + arg4: u8, + handle5: *mut c_void, + arg6: u32, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(handle1).as_bytes())?; + write!(writer, ": {:p}, ", handle1)?; + writer.write_all(stringify!(handle2).as_bytes())?; + write!(writer, ": {:p}, ", handle2)?; + writer.write_all(stringify!(handle3).as_bytes())?; + write!(writer, ": {:p}, ", handle3)?; + writer.write_all(stringify!(arg4).as_bytes())?; + write!(writer, ": {}, ", arg4)?; + writer.write_all(stringify!(handle5).as_bytes())?; + write!(writer, ": {:p}, ", handle5)?; + writer.write_all(stringify!(arg6).as_bytes())?; + write!(writer, ": {})", arg6) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + *mut c_void, + *mut c_void, + *mut c_void, + u8, + *mut c_void, + u32, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(handle1, handle2, handle3, arg4, handle5, arg6); + fn_logger.result = Some(original_result); + original_result + } + + unsafe fn dlss_module_load_impl( + guid: &[u8; 16], + idx: usize, + context: CUcontext, + result: *mut CUmodule, + fatbin: *mut c_void, + arg4: u32, + arg5: *mut c_void, + arg6: *mut c_void, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(context).as_bytes())?; + write!(writer, ": {:p}, ", context)?; + writer.write_all(stringify!(result).as_bytes())?; + write!(writer, ": {:p}, ", deref_not_null(result))?; + writer.write_all(stringify!(fatbin).as_bytes())?; + write!(writer, ": {:p}, ", fatbin)?; + writer.write_all(stringify!(arg4).as_bytes())?; + write!(writer, ": {}, ", arg4)?; + writer.write_all(stringify!(arg5).as_bytes())?; + write!(writer, ": {:p}, ", arg5)?; + writer.write_all(stringify!(arg6).as_bytes())?; + write!(writer, ": {:p})", arg6) + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn( + CUcontext, + *mut CUmodule, + *mut c_void, + u32, + *mut c_void, + *mut c_void, + ) -> CUresult, + >(*original_ptr); + let original_result = original_fn(context, result, fatbin, arg4, arg5, arg6); + fn_logger.result = Some(original_result); + if !matches!( + original_result, + CUresult::CUDA_SUCCESS + | CUresult::CUDA_ERROR_INVALID_PTX + | CUresult::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE + | CUresult::CUDA_ERROR_NOT_SUPPORTED, + ) { + return original_result; + } + cuda_state.record_module( + &mut fn_logger, + Some(*result), + CUmoduleContent::Fatbin(zluda_dark_api::CudaFatbin::from_header(fatbin.cast())), + ); + original_result + } + + unsafe fn dlss_module_get_function_impl( + guid: &[u8; 16], + idx: usize, + result: *mut CUfunction, + module: CUmodule, + name: *const i8, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(result).as_bytes())?; + write!(writer, ": {:p}, ", deref_not_null(result))?; + writer.write_all(stringify!(module).as_bytes())?; + write!(writer, ": {:p}, ", module)?; + writer.write_all(stringify!(name).as_bytes())?; + write!(writer, ": ")?; + format::CudaDisplay::write(&name, "", 0, writer)?; + write!(writer, ")") + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(*mut CUfunction, CUmodule, *const i8) -> CUresult, + >(*original_ptr); + let original_result = original_fn(result, module, name); + fn_logger.result = Some(original_result); + original_result + } + + #[allow(non_snake_case)] + unsafe fn zluda_check_impl( + guid: &[u8; 16], + idx: usize, + rt_version: u32, + timestamp: u64, + result: *mut u128, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(")?; + writer.write_all(stringify!(rt_version).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(&rt_version, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(timestamp).as_bytes())?; + writer.write_all(b": ")?; + format::CudaDisplay::write(×tamp, "", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(stringify!(result).as_bytes())?; + writer.write_all(b": ")?; + write_deref(writer, result)?; + write!(writer, ")") + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let delayed_state = global_state.delayed_state.unwrap_mut(); + let libcuda = &mut delayed_state.libcuda; + let cuda_state = &mut delayed_state.cuda_state; + let (overriding_table, original_table) = &cuda_state.dark_api.overrides[guid]; + let original_ptr = original_table.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(u32, u64, *mut u128) -> CUresult, + >(*original_ptr); + let original_result = original_fn(rt_version, timestamp, result); + let mut device_count = 0i32; + libcuda.cuDeviceGetCount(&mut device_count as _); + let device_attributes = (0..device_count) + .map(|dev| { + let dev = CUdevice_v1(dev); + let mut device_attributes = + mem::zeroed::(); + libcuda.cuDeviceGetUuid(&mut device_attributes.guid, dev); + libcuda.cuDeviceGetAttribute( + &mut device_attributes.pci_bus as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, + dev, + ); + libcuda.cuDeviceGetAttribute( + &mut device_attributes.pci_domain as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, + dev, + ); + libcuda.cuDeviceGetAttribute( + &mut device_attributes.pci_device as *mut u32 as _, + CUdevice_attribute::CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, + dev, + ); + device_attributes + }) + .collect::>(); + let mut driver_version = 0u32; + libcuda.cuDriverGetVersion(&mut driver_version as *mut _ as _); + let zludart_guid = [ + 0x6bu8, 0xd5, 0xfb, 0x6c, 0x5b, 0xf4, 0xe7, 0x4a, 0x89, 0x87, 0xd9, 0x39, 0x12, 0xfd, + 0x9d, 0xf9, + ]; + let cudart_export_table = &cuda_state.dark_api.overrides[&zludart_guid].0; + let hash_input = AntiZludaHashInput { + cudart_export_table: cudart_export_table.as_ptr() as _, + anti_zluda_export_table: overriding_table.as_ptr() as _, + fn_ptr: overriding_table[idx] as _, + device_count: device_count as u32, + driver_version, + rt_version, + timestamp, + }; + let dev_getter = |dev| device_attributes[dev as usize].clone(); + let hash = zluda_dark_api::anti_zluda_hash(false, hash_input, dev_getter); + if hash != *result { + fn_logger.log(LogEntry::IntegrityHashOverride { + before: *result, + after: hash, + }); + *result = hash; + } + fn_logger.result = Some(original_result); + original_result + } + + unsafe fn unwrap_context_impl( + guid: &[u8; 16], + idx: usize, + ctx: CUcontext, + is_wrapped: *mut u32, + unwrapped_ctx: *mut CUcontext, + ) -> CUresult { + let arguments_writer = Box::new(move |writer: &mut dyn std::io::Write| { + writer.write_all(b"(ctx: ")?; + format::CudaDisplay::write(&ctx, "", 0, writer)?; + writer.write_all(b", is_wrapped: ")?; + format::CudaDisplay::write(&is_wrapped, "", 0, writer)?; + writer.write_all(b", unwrapped_ctx: ")?; + format::CudaDisplay::write(&unwrapped_ctx, "", 0, writer)?; + write!(writer, ")") + }); + let global_state = &mut *super::GLOBAL_STATE.lock().unwrap(); + let mut fn_logger = global_state.log_factory.get_logger_dark_api( + CUuuid { + bytes: guid.clone(), + }, + idx, + Some(arguments_writer), + ); + let cuda_state = &mut global_state.delayed_state.unwrap_mut().cuda_state; + let original_ptr = cuda_state.dark_api.overrides[guid].1.add(idx); + let original_fn = mem::transmute::< + _, + unsafe extern "system" fn(CUcontext, *mut u32, *mut CUcontext) -> CUresult, + >(*original_ptr); + let original_result = original_fn(ctx, is_wrapped, unwrapped_ctx); + if *is_wrapped != 0 { + fn_logger.log(LogEntry::WrappedContext); + } + fn_logger.result = Some(original_result); + original_result + } +} + +unsafe fn deref_not_null(ptr: *mut *mut T) -> *mut T { + if ptr == ptr::null_mut() { + ptr::null_mut() + } else { + *ptr + } +} + +unsafe fn write_deref( + writer: &mut dyn std::io::Write, + t: *mut T, +) -> Result<(), std::io::Error> { + if t == ptr::null_mut() { + write!(writer, "{:p}", t) + } else { + write!(writer, "{}", *t) + } +} diff --git a/zluda_dump/src/debug.ptx b/zluda_dump/src/debug.ptx new file mode 100644 index 0000000..29104f8 --- /dev/null +++ b/zluda_dump/src/debug.ptx @@ -0,0 +1,55 @@ +/* + This collection of functions is here to assist with debugging + You use it by manually pasting into a module.ptx that was generated by zluda_dump + and inspecting content of additional debug buffer in replay.py +*/ + +.func debug_dump_from_thread_16(.reg.b64 debug_addr, .reg.u32 global_id_0, .reg.b16 value) +{ + .reg.u32 local_id; + mov.u32 local_id, %tid.x; + .reg.u32 local_size; + mov.u32 local_size, %ntid.x; + .reg.u32 group_id; + mov.u32 group_id, %ctaid.x; + .reg.b32 global_id; + mad.lo.u32 global_id, group_id, local_size, local_id; + .reg.pred should_exit; + setp.ne.u32 should_exit, global_id, global_id_0; + @should_exit bra END; + .reg.b32 index; + ld.global.u32 index, [debug_addr]; + st.global.u32 [debug_addr], index+1; + .reg.u64 st_offset; + cvt.u64.u32 st_offset, index; + mad.lo.u64 st_offset, st_offset, 2, 4; // sizeof(b16), sizeof(32) + add.u64 debug_addr, debug_addr, st_offset; + st.global.u16 [debug_addr], value; +END: + ret; +} + +.func debug_dump_from_thread_32(.reg.b64 debug_addr, .reg.u32 global_id_0, .reg.b32 value) +{ + .reg.u32 local_id; + mov.u32 local_id, %tid.x; + .reg.u32 local_size; + mov.u32 local_size, %ntid.x; + .reg.u32 group_id; + mov.u32 group_id, %ctaid.x; + .reg.b32 global_id; + mad.lo.u32 global_id, group_id, local_size, local_id; + .reg.pred should_exit; + setp.ne.u32 should_exit, global_id, global_id_0; + @should_exit bra END; + .reg.b32 index; + ld.global.u32 index, [debug_addr]; + st.global.u32 [debug_addr], index+1; + .reg.u64 st_offset; + cvt.u64.u32 st_offset, index; + mad.lo.u64 st_offset, st_offset, 4, 4; // sizeof(b32), sizeof(32) + add.u64 debug_addr, debug_addr, st_offset; + st.global.u32 [debug_addr], value; +END: + ret; +} diff --git a/zluda_dump/src/events_to_csv.py b/zluda_dump/src/events_to_csv.py new file mode 100644 index 0000000..3c07bf3 --- /dev/null +++ b/zluda_dump/src/events_to_csv.py @@ -0,0 +1,24 @@ +# Convert event trace json to csv +import json +import csv +import sys + +def main(p): + with open(p, 'rb') as f: + event_text = f.read() + try: + event_trace = json.loads(event_text) + except json.JSONDecodeError: + event_text = bytearray(event_text) + event_text.append(ord(']')) + event_trace = json.loads(event_text) + with open(f'{p}.csv', 'w', newline='') as csvfile: + writer = csv.writer(csvfile, dialect='excel') + writer.writerow(['name', 'cat', 'ts', 'dur', 'pid', 'tid']) + for e in event_trace: + if e['ph'] != 'X': + continue + writer.writerow([e['name'], e['cat'], e['ts'], e['dur'], e['pid'], e['tid']]) + +if __name__ == "__main__": + main(sys.argv[1]) diff --git a/zluda_dump/src/format.rs b/zluda_dump/src/format.rs new file mode 100644 index 0000000..849d5e9 --- /dev/null +++ b/zluda_dump/src/format.rs @@ -0,0 +1,961 @@ +use cuda_types::*; +use std::{ + ffi::{c_void, CStr}, + fmt::LowerHex, + mem, ptr, slice, +}; + +use cuda_base::cuda_derive_display_trait; + +pub(crate) trait CudaDisplay { + fn write( + &self, + fn_name: &'static str, + index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()>; +} + +impl CudaDisplay for cuda_types::CUuuid { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + let guid = self.bytes; + write!(writer, "{{{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}}}", guid[3], guid[2], guid[1], guid[0], guid[5], guid[4], guid[7], guid[6], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]) + } +} + +impl CudaDisplay for cuda_types::CUdevice { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", self.0) + } +} + +impl CudaDisplay for cuda_types::CUdeviceptr { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{:p}", self.0) + } +} + +impl CudaDisplay for cuda_types::CUdeviceptr_v1 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{:p}", self.0 as usize as *const ()) + } +} + +impl CudaDisplay for u8 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for u16 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for i32 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for u32 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for u64 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for usize { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +impl CudaDisplay for f32 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{}", *self) + } +} + +pub fn write_handle( + this: &[T; 64], + writer: &mut (impl std::io::Write + ?Sized), +) -> std::io::Result<()> { + writer.write_all(b"0x")?; + for i in (0..64).rev() { + write!(writer, "{:02x}", this[i])?; + } + Ok(()) +} + +impl CudaDisplay for cuda_types::CUipcMemHandle { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write_handle(&self.reserved, writer) + } +} + +impl CudaDisplay for cuda_types::CUipcEventHandle { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write_handle(&self.reserved, writer) + } +} + +impl CudaDisplay for cuda_types::CUmemPoolPtrExportData_v1 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write_handle(&self.reserved, writer) + } +} + +impl CudaDisplay for *mut c_void { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{:p}", *self) + } +} + +impl CudaDisplay for *const c_void { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + write!(writer, "{:p}", *self) + } +} + +impl CudaDisplay for *const i8 { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + if *self == ptr::null_mut() { + writer.write_all(b"NULL") + } else { + write!( + writer, + "\"{}\"", + unsafe { CStr::from_ptr(*self as _) }.to_string_lossy() + ) + } + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct Luid { + low_part: u32, + high_part: u32, +} + +impl CudaDisplay for *mut i8 { + fn write( + &self, + fn_name: &'static str, + index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + if fn_name == "cuDeviceGetLuid" && index == 0 { + let luid_ptr = *self as *mut Luid; + let luid = unsafe { *luid_ptr }; + write!(writer, "{{{:08X}-{:08X}}}", luid.low_part, luid.high_part) + } else { + write!( + writer, + "\"{}\"", + unsafe { CStr::from_ptr(*self as _) }.to_string_lossy() + ) + } + } +} + +impl CudaDisplay for cuda_types::CUstreamBatchMemOpParams { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + unsafe { + match self.operation { + // The below is not a typo, `WAIT_VALUE` and `WRITE_VALUE` are + // distinct operations with nominally distinct union variants, but + // in reality they are structurally different, so we take a little + // shortcut here + cuda_types::CUstreamBatchMemOpType::CU_STREAM_MEM_OP_WAIT_VALUE_32 + | cuda_types::CUstreamBatchMemOpType::CU_STREAM_MEM_OP_WRITE_VALUE_32 => { + write_wait_value(&self.waitValue, writer, false) + } + cuda_types::CUstreamBatchMemOpType::CU_STREAM_MEM_OP_WAIT_VALUE_64 + | cuda_types::CUstreamBatchMemOpType::CU_STREAM_MEM_OP_WRITE_VALUE_64 => { + write_wait_value(&self.waitValue, writer, true) + } + cuda_types::CUstreamBatchMemOpType::CU_STREAM_MEM_OP_FLUSH_REMOTE_WRITES => { + CudaDisplay::write(&self.flushRemoteWrites, "", 0, writer) + } + _ => { + writer.write_all(b"{ operation: ")?; + CudaDisplay::write(&self.operation, "", 0, writer)?; + writer.write_all(b", ... }") + } + } + } + } +} + +pub fn write_wait_value( + this: &cuda_types::CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st, + writer: &mut (impl std::io::Write + ?Sized), + is_64_bit: bool, +) -> std::io::Result<()> { + writer.write_all(b"{ operation: ")?; + CudaDisplay::write(&this.operation, "", 0, writer)?; + writer.write_all(b", address: ")?; + CudaDisplay::write(&this.address, "", 0, writer)?; + write_wait_value_32_or_64(&this.__bindgen_anon_1, writer, is_64_bit)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&this.flags, "", 0, writer)?; + writer.write_all(b", alias: ")?; + CudaDisplay::write(&this.alias, "", 0, writer)?; + writer.write_all(b" }") +} + +pub fn write_wait_value_32_or_64( + this: &cuda_types::CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st__bindgen_ty_1, + writer: &mut (impl std::io::Write + ?Sized), + is_64_bit: bool, +) -> std::io::Result<()> { + if is_64_bit { + writer.write_all(b", value64: ")?; + CudaDisplay::write(unsafe { &this.value64 }, "", 0, writer) + } else { + writer.write_all(b", value: ")?; + CudaDisplay::write(unsafe { &this.value }, "", 0, writer) + } +} + +impl CudaDisplay for cuda_types::CUDA_RESOURCE_DESC_st { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"{ resType: ")?; + CudaDisplay::write(&self.resType, "", 0, writer)?; + match self.resType { + cuda_types::CUresourcetype::CU_RESOURCE_TYPE_ARRAY => { + writer.write_all(b", res: ")?; + CudaDisplay::write(unsafe { &self.res.array }, "", 0, writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } + cuda_types::CUresourcetype::CU_RESOURCE_TYPE_MIPMAPPED_ARRAY => { + writer.write_all(b", res: ")?; + CudaDisplay::write(unsafe { &self.res.mipmap }, "", 0, writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } + cuda_types::CUresourcetype::CU_RESOURCE_TYPE_LINEAR => { + writer.write_all(b", res: ")?; + CudaDisplay::write(unsafe { &self.res.linear }, "", 0, writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } + cuda_types::CUresourcetype::CU_RESOURCE_TYPE_PITCH2D => { + writer.write_all(b", res: ")?; + CudaDisplay::write(unsafe { &self.res.pitch2D }, "", 0, writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } + _ => { + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b", ... }") + } + } + } +} + +impl CudaDisplay for cuda_types::CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"{ type: ")?; + CudaDisplay::write(&self.type_, "", 0, writer)?; + match self.type_ { + cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.fd }, "", 0,writer)?; + } + cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32 + | cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP + | cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE + |cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE => { + write_win32_handle(unsafe { self.handle.win32 }, writer)?; + } + cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT + | cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.win32.handle }, "", 0,writer)?; + } + cuda_types::CUexternalMemoryHandleType::CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.nvSciBufObject }, "", 0,writer)?; + } + _ => { + writer.write_all(b", size: ")?; + CudaDisplay::write(&self.size, "", 0,writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0,writer)?; + return writer.write_all(b", ... }") + } + } + writer.write_all(b", size: ")?; + CudaDisplay::write(&self.size, "", 0, writer)?; + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } +} + +pub fn write_win32_handle( + win32: cuda_types::CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st__bindgen_ty_1__bindgen_ty_1, + writer: &mut (impl std::io::Write + ?Sized), +) -> std::io::Result<()> { + if win32.handle != ptr::null_mut() { + writer.write_all(b", handle: ")?; + CudaDisplay::write(&win32.handle, "", 0, writer)?; + } + if win32.name != ptr::null_mut() { + let name_ptr = win32.name as *const u16; + let mut strlen = 0usize; + while unsafe { *name_ptr.add(strlen) } != 0 { + strlen += 1; + } + let text = String::from_utf16_lossy(unsafe { slice::from_raw_parts(name_ptr, strlen) }); + write!(writer, ", name: \"{}\"", text)?; + } + Ok(()) +} + +impl CudaDisplay for cuda_types::CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"{ type: ")?; + CudaDisplay::write(&self.type_, "", 0, writer)?; + match self.type_ { + cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.fd }, "", 0,writer)?; + } + cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32 + | cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE + | cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE + | cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX + | cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT => { + write_win32_handle(unsafe { mem::transmute(self.handle.win32) }, writer)?; + } + cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.win32.handle }, "", 0,writer)?; + } + cuda_types::CUexternalSemaphoreHandleType::CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC => { + writer.write_all(b", handle: ")?; + CudaDisplay::write(unsafe { &self.handle.nvSciSyncObj }, "", 0,writer)?; + } + _ => { + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0,writer)?; + return writer.write_all(b", ... }") + } + } + writer.write_all(b", flags: ")?; + CudaDisplay::write(&self.flags, "", 0, writer)?; + writer.write_all(b" }") + } +} + +impl CudaDisplay + for cuda_types::CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_2 +{ + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"{ fence: ")?; + CudaDisplay::write(&unsafe { self.fence }, "", 0, writer)?; + writer.write_all(b" }") + } +} + +impl CudaDisplay + for cuda_types::CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_2 +{ + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"{ fence: ")?; + CudaDisplay::write(&unsafe { self.fence }, "", 0, writer)?; + writer.write_all(b" }") + } +} + +impl CudaDisplay for *mut T { + fn write( + &self, + fn_name: &'static str, + index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + if *self == ptr::null_mut() { + writer.write_all(b"NULL") + } else { + if fn_name == "cuLaunchKernel" && index == 9 { + unsafe { write_launch_kernel_extra(*self as *mut *mut c_void, writer) } + } else { + let this: &T = unsafe { &**self }; + this.write(fn_name, index, writer) + } + } + } +} + +unsafe fn write_launch_kernel_extra( + mut extra: *mut *mut c_void, + writer: &mut (impl std::io::Write + ?Sized), +) -> std::io::Result<()> { + writer.write_all(b"[")?; + let mut format_as_size = false; + loop { + let ptr = *extra; + match ptr as usize { + 0 => { + writer.write_all(b"CU_LAUNCH_PARAM_END")?; + break; + } + 1 => { + writer.write_all(b"CU_LAUNCH_PARAM_BUFFER_POINTER")?; + } + 2 => { + writer.write_all(b"CU_LAUNCH_PARAM_BUFFER_SIZE")?; + format_as_size = true; + } + _ => { + if format_as_size { + let size = *(ptr as *mut usize); + write!(writer, "{}", size)?; + format_as_size = false; + } else { + write!(writer, "{:p}", ptr)?; + } + } + } + writer.write_all(b", ")?; + extra = extra.offset(1); + } + writer.write_all(b"]")?; + Ok(()) +} + +impl CudaDisplay for *const T { + fn write( + &self, + fn_name: &'static str, + index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + if *self == ptr::null() { + writer.write_all(b"NULL") + } else { + let this: &T = unsafe { &**self }; + this.write(fn_name, index, writer) + } + } +} + +impl CudaDisplay for [T; N] { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"[")?; + for i in 0..N { + CudaDisplay::write(&self[i], "", 0, writer)?; + if i != N - 1 { + writer.write_all(b", ")?; + } + } + writer.write_all(b"]") + } +} + +impl CudaDisplay for [i8; N] { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + writer.write_all(b"[")?; + for i in 0..N { + write!(writer, "{}", self[i])?; + if i != N - 1 { + writer.write_all(b", ")?; + } + } + writer.write_all(b"]") + } +} + +impl CudaDisplay for cuda_types::CUgraphNodeParams { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + _writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + todo!() + } +} + +impl CudaDisplay for cuda_types::CUlaunchAttribute_st { + fn write( + &self, + _fn_name: &'static str, + _index: usize, + _writer: &mut (impl std::io::Write + ?Sized), + ) -> std::io::Result<()> { + todo!() + } +} + +#[allow(non_snake_case)] +pub fn write_cuStreamBatchMemOp( + writer: &mut (impl std::io::Write + ?Sized), + stream: cuda_types::CUstream, + count: ::std::os::raw::c_uint, + paramArray: *mut cuda_types::CUstreamBatchMemOpParams, + flags: ::std::os::raw::c_uint, +) -> std::io::Result<()> { + writer.write_all(b"(stream: ")?; + CudaDisplay::write(&stream, "cuStreamBatchMemOp", 0, writer)?; + writer.write_all(b", ")?; + writer.write_all(b"count: ")?; + CudaDisplay::write(&count, "cuStreamBatchMemOp", 1, writer)?; + writer.write_all(b", paramArray: [")?; + for i in 0..count { + if i != 0 { + writer.write_all(b", ")?; + } + CudaDisplay::write( + &unsafe { paramArray.add(i as usize) }, + "cuStreamBatchMemOp", + 2, + writer, + )?; + } + writer.write_all(b"], flags: ")?; + CudaDisplay::write(&flags, "cuStreamBatchMemOp", 3, writer)?; + writer.write_all(b")") +} + +#[allow(non_snake_case)] +pub fn write_cuGraphKernelNodeGetAttribute( + writer: &mut (impl std::io::Write + ?Sized), + hNode: cuda_types::CUgraphNode, + attr: cuda_types::CUlaunchAttributeID, + value_out: *mut cuda_types::CUkernelNodeAttrValue, +) -> std::io::Result<()> { + writer.write_all(b"(hNode: ")?; + CudaDisplay::write(&hNode, "cuGraphKernelNodeGetAttribute", 0, writer)?; + writer.write_all(b", attr: ")?; + CudaDisplay::write(&attr, "cuGraphKernelNodeGetAttribute", 1, writer)?; + match attr { + cuda_types::CUlaunchAttributeID::CU_LAUNCH_ATTRIBUTE_ACCESS_POLICY_WINDOW => { + writer.write_all(b", value_out: ")?; + CudaDisplay::write( + unsafe { &(*value_out).accessPolicyWindow }, + "cuGraphKernelNodeGetAttribute", + 2, + writer, + )?; + } + cuda_types::CUlaunchAttributeID::CU_LAUNCH_ATTRIBUTE_COOPERATIVE => { + writer.write_all(b", value_out: ")?; + CudaDisplay::write( + unsafe { &(*value_out).cooperative }, + "cuGraphKernelNodeGetAttribute", + 2, + writer, + )?; + } + _ => return writer.write_all(b", ...) "), + } + writer.write_all(b")") +} + +#[allow(non_snake_case)] +pub fn write_cuGraphKernelNodeSetAttribute( + writer: &mut (impl std::io::Write + ?Sized), + hNode: cuda_types::CUgraphNode, + attr: cuda_types::CUlaunchAttributeID, + value_out: *const cuda_types::CUkernelNodeAttrValue, +) -> std::io::Result<()> { + write_cuGraphKernelNodeGetAttribute(writer, hNode, attr, value_out as *mut _) +} + +#[allow(non_snake_case)] +pub fn write_cuStreamGetAttribute( + writer: &mut (impl std::io::Write + ?Sized), + hStream: cuda_types::CUstream, + attr: cuda_types::CUstreamAttrID, + value_out: *mut cuda_types::CUstreamAttrValue, +) -> std::io::Result<()> { + writer.write_all(b"(hStream: ")?; + CudaDisplay::write(&hStream, "cuStreamGetAttribute", 0, writer)?; + writer.write_all(b", attr: ")?; + CudaDisplay::write(&attr, "cuStreamGetAttribute", 1, writer)?; + match attr { + cuda_types::CUstreamAttrID::CU_LAUNCH_ATTRIBUTE_ACCESS_POLICY_WINDOW => { + writer.write_all(b", value_out: ")?; + CudaDisplay::write( + unsafe { &(*value_out).accessPolicyWindow }, + "cuStreamGetAttribute", + 2, + writer, + )?; + } + cuda_types::CUstreamAttrID::CU_LAUNCH_ATTRIBUTE_SYNCHRONIZATION_POLICY => { + writer.write_all(b", value_out: ")?; + CudaDisplay::write( + unsafe { &(*value_out).syncPolicy }, + "cuStreamGetAttribute", + 2, + writer, + )?; + } + _ => return writer.write_all(b", ...) "), + } + writer.write_all(b")") +} + +#[allow(non_snake_case)] +pub fn write_cuStreamGetAttribute_ptsz( + writer: &mut (impl std::io::Write + ?Sized), + hStream: cuda_types::CUstream, + attr: cuda_types::CUstreamAttrID, + value_out: *mut cuda_types::CUstreamAttrValue, +) -> std::io::Result<()> { + write_cuStreamGetAttribute(writer, hStream, attr, value_out) +} + +#[allow(non_snake_case)] +pub fn write_cuStreamSetAttribute( + writer: &mut (impl std::io::Write + ?Sized), + hStream: cuda_types::CUstream, + attr: cuda_types::CUstreamAttrID, + value_out: *const cuda_types::CUstreamAttrValue, +) -> std::io::Result<()> { + write_cuStreamGetAttribute(writer, hStream, attr, value_out as *mut _) +} + +#[allow(non_snake_case)] +pub fn write_cuStreamSetAttribute_ptsz( + writer: &mut (impl std::io::Write + ?Sized), + hStream: cuda_types::CUstream, + attr: cuda_types::CUstreamAttrID, + value_out: *const cuda_types::CUstreamAttrValue, +) -> std::io::Result<()> { + write_cuStreamSetAttribute(writer, hStream, attr, value_out) +} + +#[allow(non_snake_case)] +pub fn write_cuCtxCreate_v3( + _writer: &mut (impl std::io::Write + ?Sized), + _pctx: *mut cuda_types::CUcontext, + _paramsArray: *mut cuda_types::CUexecAffinityParam, + _numParams: ::std::os::raw::c_int, + _flags: ::std::os::raw::c_uint, + _dev: cuda_types::CUdevice, +) -> std::io::Result<()> { + todo!() +} + +#[allow(non_snake_case)] +pub fn write_cuCtxGetExecAffinity( + _writer: &mut (impl std::io::Write + ?Sized), + _pExecAffinity: *mut cuda_types::CUexecAffinityParam, + _type_: cuda_types::CUexecAffinityType, +) -> std::io::Result<()> { + todo!() +} + +#[allow(non_snake_case)] +pub fn write_cuMemMapArrayAsync( + _writer: &mut (impl std::io::Write + ?Sized), + _mapInfoList: *mut cuda_types::CUarrayMapInfo, + _count: ::std::os::raw::c_uint, + _hStream: cuda_types::CUstream, +) -> std::io::Result<()> { + todo!() +} + +#[allow(non_snake_case)] +pub fn write_cuMemMapArrayAsync_ptsz( + writer: &mut (impl std::io::Write + ?Sized), + mapInfoList: *mut cuda_types::CUarrayMapInfo, + count: ::std::os::raw::c_uint, + hStream: cuda_types::CUstream, +) -> std::io::Result<()> { + write_cuMemMapArrayAsync(writer, mapInfoList, count, hStream) +} + +#[allow(non_snake_case)] +pub fn write_cuLinkCreate_v2( + writer: &mut (impl std::io::Write + ?Sized), + numOptions: ::std::os::raw::c_uint, + options: *mut CUjit_option, + optionValues: *mut *mut ::std::os::raw::c_void, + stateOut: *mut CUlinkState, +) -> std::io::Result<()> { + writer.write_all(b"(numOptions: ")?; + CudaDisplay::write(&numOptions, "cuLinkCreate_v2", 0, writer)?; + writer.write_all(b", options: ")?; + write_array("cuLinkCreate_v2", 1, writer, numOptions, options)?; + writer.write_all(b", optionValues: ")?; + write_array("cuLinkCreate_v2", 2, writer, numOptions, optionValues)?; + writer.write_all(b", stateOut: ")?; + CudaDisplay::write(&stateOut, "cuLinkCreate_v2", 3, writer)?; + writer.write_all(b")") +} + +#[allow(non_snake_case)] +pub fn write_cuLinkAddData_v2( + writer: &mut (impl std::io::Write + ?Sized), + 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, +) -> std::io::Result<()> { + writer.write_all(b"(state: ")?; + CudaDisplay::write(&state, "cuLinkAddData_v2", 0, writer)?; + writer.write_all(b", type: ")?; + CudaDisplay::write(&type_, "cuLinkAddData_v2", 1, writer)?; + writer.write_all(b", data: ")?; + CudaDisplay::write(&data, "cuLinkAddData_v2", 2, writer)?; + writer.write_all(b", size: ")?; + CudaDisplay::write(&size, "cuLinkAddData_v2", 3, writer)?; + writer.write_all(b", name: ")?; + CudaDisplay::write(&name, "cuLinkAddData_v2", 4, writer)?; + writer.write_all(b", numOptions: ")?; + CudaDisplay::write(&numOptions, "cuLinkAddData_v2", 5, writer)?; + writer.write_all(b", options: ")?; + write_array("cuLinkAddData_v2", 6, writer, numOptions, options)?; + writer.write_all(b", optionValues: ")?; + write_array("cuLinkAddData_v2", 7, writer, numOptions, optionValues)?; + writer.write_all(b")") +} + +#[allow(non_snake_case)] +pub fn write_cuModuleLoadDataEx( + writer: &mut (impl std::io::Write + ?Sized), + 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, +) -> std::io::Result<()> { + writer.write_all(b"(module: ")?; + CudaDisplay::write(&module, "cuModuleLoadDataEx", 0, writer)?; + writer.write_all(b", image: ")?; + CudaDisplay::write(&image, "cuModuleLoadDataEx", 1, writer)?; + writer.write_all(b", numOptions: ")?; + CudaDisplay::write(&numOptions, "cuModuleLoadDataEx", 2, writer)?; + writer.write_all(b", options: ")?; + write_array("cuModuleLoadDataEx", 3, writer, numOptions, options)?; + writer.write_all(b", optionValues: ")?; + write_array("cuModuleLoadDataEx", 4, writer, numOptions, optionValues)?; + writer.write_all(b")") +} + +fn write_array( + fn_name: &'static str, + index: usize, + writer: &mut (impl std::io::Write + ?Sized), + length: u32, + values: *mut T, +) -> std::io::Result<()> { + let length = length as usize; + if length < 2 { + CudaDisplay::write(&values, fn_name, index, writer) + } else { + writer.write_all(b"[")?; + for i in 0..length { + CudaDisplay::write(&unsafe { values.add(i) }, fn_name, index, writer)?; + if i != length - 1 { + writer.write_all(b", ")?; + } + } + writer.write_all(b"]") + } +} + +cuda_derive_display_trait!( + cuda_types, + CudaDisplay, + [ + CUarrayMapInfo_st, + CUDA_RESOURCE_DESC_st, + CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st, + CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st, + CUexecAffinityParam_st, + CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st, + CUstreamBatchMemOpParams_union_CUstreamMemOpWriteValueParams_st, + CUuuid_st, + HGPUNV, + CUgraphNodeParams_st, + CUlaunchAttribute_st + ], + [ + cuCtxCreate_v3, + cuCtxGetExecAffinity, + cuGraphKernelNodeGetAttribute, + cuGraphKernelNodeSetAttribute, + cuMemMapArrayAsync, + cuMemMapArrayAsync_ptsz, + cuStreamBatchMemOp, + cuStreamGetAttribute, + cuStreamGetAttribute_ptsz, + cuStreamSetAttribute, + cuStreamSetAttribute_ptsz, + cuLinkCreate_v2, + cuLinkAddData_v2, + cuModuleLoadDataEx, + ] +); + +#[cfg(test)] + +mod tests { + use cuda_types::CUuuid; + + use super::CudaDisplay; + + #[test] + fn guid_formats_correctly() { + let cuid = CUuuid { + bytes: [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, + ], + }; + let mut writer = String::new(); + CudaDisplay::write(&cuid, "", 0, unsafe { writer.as_mut_vec() }).unwrap(); + assert_eq!(writer, "{04030201-0605-0807-090a-0b0c0d0e0f10}"); + } +} diff --git a/zluda_dump/src/lib.rs b/zluda_dump/src/lib.rs index 409606e..704749f 100644 --- a/zluda_dump/src/lib.rs +++ b/zluda_dump/src/lib.rs @@ -1,276 +1,648 @@ -use std::{ - collections::HashMap, - env, - error::Error, - ffi::{c_void, CStr}, - fs, - io::prelude::*, - mem, - os::raw::{c_int, c_uint, c_ulong, c_ushort}, - path::PathBuf, - rc::Rc, - slice, -}; -use std::{fs::File, ptr}; +use cuda_types::*; +use log::LogEntry; +use paste::paste; +use std::ffi::{c_void, CStr}; +use std::fmt::Display; +use std::marker::PhantomData; +use std::ptr::NonNull; +use std::str::FromStr; +use std::{env, error::Error, fs, path::PathBuf, sync::Mutex}; +use std::{io, mem, ptr}; +use trace::TexrefAddress; +use zluda_dark_api::CUmoduleContent; -use cuda::{CUdeviceptr, CUfunction, CUjit_option, CUmodule, CUresult, CUstream, CUuuid}; -use ptx::ast; -use regex::Regex; +#[macro_use] +extern crate lazy_static; +extern crate cuda_types; +macro_rules! extern_redirect { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + $( + #[no_mangle] + pub extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + let original_fn = |dynamic_fns: &mut crate::CudaDynamicFns| { + dynamic_fns.$fn_name($( $arg_id ),*) + }; + let get_formatted_args = Box::new(move |writer: &mut dyn std::io::Write| { + (paste! { format :: [] }) ( + writer + $(,$arg_id)* + ) + }); + crate::handle_cuda_function_call(stringify!($fn_name), original_fn, get_formatted_args) + } + )* + }; +} + +macro_rules! extern_redirect_with_post { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + $( + #[no_mangle] + pub extern "system" fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + let original_fn = |dynamic_fns: &mut crate::CudaDynamicFns| { + dynamic_fns.$fn_name($( $arg_id ),*) + }; + let get_formatted_args = Box::new(move |writer: &mut dyn std::io::Write| { + (paste! { format :: [] }) ( + writer + $(,$arg_id)* + ) + }); + crate::handle_cuda_function_call_with_probes( + stringify!($fn_name), + move |logger, state| paste! { [<$fn_name _Pre>] } ( $( $arg_id ),* , logger, state ), + original_fn, + get_formatted_args, + move |logger, state, pre_result, cuda_result| paste! { [<$fn_name _Post>] } ( $( $arg_id ),* , logger, state, pre_result, cuda_result ) + ) + } + )* + }; +} + +use cuda_base::cuda_function_declarations; +cuda_function_declarations!( + cuda_types, + extern_redirect, + extern_redirect_with_post, + [ + cuModuleGetTexRef, + cuModuleLoad, + cuModuleLoadData, + cuModuleLoadDataEx, + cuGetExportTable, + cuModuleGetFunction, + cuDeviceGetAttribute, + cuDeviceComputeCapability, + cuModuleLoadFatBinary, + cuLaunchKernel, + cuTexRefSetAddress_v2, + cuTexRefSetAddress2D_v2, + cuTexRefSetAddress2D_v3, + cuTexRefSetArray, + cuModuleGetGlobal_v2, + cuGetProcAddress, + cuGetProcAddress_v2, + cuLinkAddData_v2, + cuLibraryLoadData, + cuLibraryGetModule + ] +); + +mod dark_api; +mod format; +mod log; #[cfg_attr(windows, path = "os_win.rs")] #[cfg_attr(not(windows), path = "os_unix.rs")] mod os; +mod profiler; +mod side_by_side; +mod trace; -macro_rules! extern_redirect { - (pub fn $fn_name:ident ( $($arg_id:ident: $arg_type:ty),* $(,)? ) -> $ret_type:ty ;) => { - #[no_mangle] - pub fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { - unsafe { $crate::init_libcuda_handle() }; - let name = std::ffi::CString::new(stringify!($fn_name)).unwrap(); - let fn_ptr = unsafe { crate::os::get_proc_address($crate::LIBCUDA_HANDLE, &name) }; - if fn_ptr == std::ptr::null_mut() { - return CUresult::CUDA_ERROR_UNKNOWN; - } - let typed_fn = unsafe { std::mem::transmute::<_, fn( $( $arg_id : $arg_type),* ) -> $ret_type>(fn_ptr) }; - typed_fn($( $arg_id ),*) - } - }; +lazy_static! { + static ref GLOBAL_STATE: Mutex = Mutex::new(GlobalState::new()); } -macro_rules! extern_redirect_with { - ( - pub fn $fn_name:ident ( $($arg_id:ident: $arg_type:ty),* $(,)? ) -> $ret_type:ty ; - $receiver:path ; - ) => { - #[no_mangle] - pub fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { - unsafe { $crate::init_libcuda_handle() }; - let continuation = |$( $arg_id : $arg_type),* | { - let name = std::ffi::CString::new(stringify!($fn_name)).unwrap(); - let fn_ptr = unsafe { crate::os::get_proc_address($crate::LIBCUDA_HANDLE, &name) }; - if fn_ptr == std::ptr::null_mut() { - return CUresult::CUDA_ERROR_UNKNOWN; +struct GlobalState { + log_factory: log::Factory, + // We split off fields that require a mutable reference to log factory to be + // created, additionally creation of some fields in this struct can fail + // initalization (e.g. we passed path a non-existant path to libcuda) + delayed_state: LateInit, +} + +unsafe impl Send for GlobalState {} + +impl GlobalState { + fn new() -> Self { + GlobalState { + log_factory: log::Factory::new(), + delayed_state: LateInit::Unitialized, + } + } +} + +enum LateInit { + Success(T), + Unitialized, + Error, +} + +impl LateInit { + fn as_mut(&mut self) -> Option<&mut T> { + match self { + Self::Success(t) => Some(t), + Self::Unitialized => None, + Self::Error => None, + } + } + + pub(crate) fn unwrap_mut(&mut self) -> &mut T { + match self { + Self::Success(t) => t, + Self::Unitialized | Self::Error => panic!(), + } + } +} + +struct GlobalDelayedState { + _settings: Settings, + libcuda: CudaDynamicFns, + cuda_state: trace::StateTracker, + pub(crate) side_by_side: Option, + pub(crate) profiler: Option, +} + +impl GlobalDelayedState { + fn new<'a>( + func: &'static str, + arguments_writer: Box std::io::Result<()>>, + factory: &'a mut log::Factory, + ) -> (LateInit, log::FunctionLogger<'a>) { + let (mut fn_logger, settings) = + factory.get_first_logger_and_init_settings(func, arguments_writer); + let mut libcuda = match unsafe { CudaDynamicFns::load_library(&settings.libcuda_path) } { + Some(libcuda) => libcuda, + None => { + fn_logger.log(log::LogEntry::ErrorBox( + format!("Invalid CUDA library at path {}", &settings.libcuda_path).into(), + )); + return (LateInit::Error, fn_logger); + } + }; + let side_by_side_lib = settings + .side_by_side_path + .as_ref() + .and_then(|side_by_side_path| { + match unsafe { CudaDynamicFns::load_library(&*side_by_side_path) } { + Some(fns) => Some(fns), + None => { + fn_logger.log(log::LogEntry::ErrorBox( + format!( + "Invalid side-by-side CUDA library at path {}", + &side_by_side_path + ) + .into(), + )); + None + } } - let typed_fn = unsafe { std::mem::transmute::<_, fn( $( $arg_id : $arg_type),* ) -> $ret_type>(fn_ptr) }; - typed_fn($( $arg_id ),*) - }; - unsafe { $receiver($( $arg_id ),* , continuation) } - } - }; -} - -#[allow(warnings)] -mod cuda; - -pub static mut LIBCUDA_HANDLE: *mut c_void = ptr::null_mut(); -pub static mut MODULES: Option> = None; -pub static mut KERNELS: Option> = None; -pub static mut BUFFERS: Vec<(usize, usize)> = Vec::new(); -pub static mut LAUNCH_COUNTER: usize = 0; -pub static mut KERNEL_PATTERN: Option = None; - -pub struct ModuleDump { - content: Rc, - kernels_args: HashMap>, -} - -pub struct KernelDump { - module_content: Rc, - name: String, - arguments: Vec, -} - -// We are doing dlopen here instead of just using LD_PRELOAD, -// it's because CUDA Runtime API does dlopen to open libcuda.so, which ignores LD_PRELOAD -pub unsafe fn init_libcuda_handle() { - if LIBCUDA_HANDLE == ptr::null_mut() { - let libcuda_handle = os::load_cuda_library(); - assert_ne!(libcuda_handle, ptr::null_mut()); - LIBCUDA_HANDLE = libcuda_handle; - match env::var("ZLUDA_DUMP_KERNEL") { - Ok(kernel_filter) => match Regex::new(&kernel_filter) { - Ok(r) => KERNEL_PATTERN = Some(r), - Err(err) => { - eprintln!( - "[ZLUDA_DUMP] Env variable ZLUDA_DUMP_KERNEL is not a regex: {}", - err - ); - } - }, - Err(_) => (), - } - eprintln!("[ZLUDA_DUMP] Initialized"); + }); + let cuda_state = trace::StateTracker::new(&settings); + let side_by_side = side_by_side_lib + .map(|lib| { + side_by_side::SideBySide::new( + lib, + &mut fn_logger, + settings.side_by_side_skip_kernel.as_ref(), + settings.side_by_side_dump_threshold, + ) + }) + .flatten(); + let profiler = profiler::Profiler::new(&settings, &mut libcuda, &mut fn_logger); + let delayed_state = GlobalDelayedState { + _settings: settings, + libcuda, + cuda_state, + side_by_side, + profiler, + }; + (LateInit::Success(delayed_state), fn_logger) } } -#[allow(non_snake_case)] -pub unsafe fn cuModuleLoadData( - module: *mut CUmodule, - raw_image: *const ::std::os::raw::c_void, - cont: impl FnOnce(*mut CUmodule, *const c_void) -> CUresult, -) -> CUresult { - let result = cont(module, raw_image); - if result == CUresult::CUDA_SUCCESS { - record_module_image_raw(*module, raw_image); - } - result +struct Settings { + dump_dir: Option, + libcuda_path: String, + log_enabled: bool, + override_cc_major: Option, + side_by_side_path: Option, + side_by_side_skip_kernel: Option, + side_by_side_dump_threshold: Option, + profiler_output: Option, } -unsafe fn record_module_image_raw(module: CUmodule, raw_image: *const ::std::os::raw::c_void) { - let image = to_str(raw_image); - match image { - None => eprintln!("[ZLUDA_DUMP] Malformed module image: {:?}", raw_image), - Some(image) => record_module_image(module, image), - }; -} - -unsafe fn record_module_image(module: CUmodule, image: &str) { - if !image.contains(&".address_size") { - eprintln!("[ZLUDA_DUMP] Malformed module image: {:?}", module) - } else { - let mut errors = Vec::new(); - let ast = ptx::ModuleParser::new().parse(&mut errors, image); - match (&*errors, ast) { - (&[], Ok(ast)) => { - let kernels_args = ast - .directives - .iter() - .filter_map(directive_to_kernel) - .collect::>(); - let modules = MODULES.get_or_insert_with(|| HashMap::new()); - modules.insert( - module, - ModuleDump { - content: Rc::new(image.to_string()), - kernels_args, - }, - ); +impl Settings { + fn read_and_init(log_enabled: bool, logger: &mut log::FunctionLogger) -> Self { + let maybe_dump_dir = Self::read_and_init_dump_dir(); + let dump_dir = match maybe_dump_dir { + Ok(Some(dir)) => { + logger.log(log::LogEntry::CreatedDumpDirectory(dir.clone())); + Some(dir) } - (errs, ast) => { - let err_string = errs - .iter() - .map(|e| format!("{:?}", e)) - .chain(ast.err().iter().map(|e| format!("{:?}", e))) - .collect::>() - .join("\n"); - eprintln!( - "[ZLUDA_DUMP] Errors when parsing module:\n---ERRORS---\n{}\n---MODULE---\n{}", - err_string, image - ); + Ok(None) => None, + Err(err) => { + logger.log(log::LogEntry::ErrorBox(err)); + None } + }; + let mut report_err = |e| logger.log(e); + let libcuda_path: String = parse_env_var("ZLUDA_CUDA_LIB", &mut report_err) + .unwrap_or_else(|| os::LIBCUDA_DEFAULT_PATH.to_owned()); + let override_cc_major = + parse_env_var::("ZLUDA_OVERRIDE_COMPUTE_CAPABILITY_MAJOR", &mut report_err); + let side_by_side_path = + parse_env_var::("ZLUDA_SIDE_BY_SIDE_LIB", &mut report_err); + let side_by_side_skip_kernel = + parse_env_var::("ZLUDA_SIDE_BY_SIDE_SKIP_KERNEL", &mut report_err); + let side_by_side_dump_threshold = + parse_env_var::("ZLUDA_SIDE_BY_DUMP_THRESHOLD", &mut report_err); + let profiler_output = parse_env_var::("ZLUDA_PROFILER_OUTPUT", &mut report_err); + Settings { + dump_dir, + log_enabled, + libcuda_path, + override_cc_major, + side_by_side_path, + side_by_side_skip_kernel, + side_by_side_dump_threshold, + profiler_output, } } + + fn read_and_init_dump_dir() -> Result, Box> { + let dir = match env::var("ZLUDA_DUMP_DIR") { + Ok(dir) => dir, + Err(env::VarError::NotPresent) => return Ok(None), + Err(err) => return Err(Box::new(err) as Box<_>), + }; + Ok(Some(Self::create_dump_directory(dir)?)) + } + + fn create_dump_directory(dir: String) -> io::Result { + let mut main_dir = PathBuf::from(dir); + let current_exe = env::current_exe()?; + let file_name_base = current_exe.file_name().unwrap().to_string_lossy(); + main_dir.push(&*file_name_base); + let mut suffix = 1; + // This can get into infinite loop. Unfortunately try_exists is unstable: + // https://doc.rust-lang.org/std/path/struct.Path.html#method.try_exists + while main_dir.exists() { + main_dir.set_file_name(format!("{}_{}", file_name_base, suffix)); + suffix += 1; + } + fs::create_dir_all(&*main_dir)?; + Ok(main_dir) + } } -unsafe fn to_str(image: *const T) -> Option<&'static str> { - let ptr = image as *const u8; - let mut offset = 0; - loop { - let c = *ptr.add(offset); - if !c.is_ascii() { +fn parse_env_var(key: &'static str, report_err: &mut FnErr) -> Option +where + T::Err: Display + 'static, + FnErr: FnMut(log::LogEntry), +{ + let value = match env::var(key) { + Ok(env_var) => env_var, + Err(env::VarError::NotPresent) => return None, + Err(err) => { + report_err(LogEntry::EnvVarError(err)); return None; } - if c == 0 { - return Some(std::str::from_utf8_unchecked(slice::from_raw_parts( - ptr, offset, - ))); + }; + match value.parse::() { + Ok(value) => Some(value), + Err(err) => { + let err = Box::new(err); + report_err(LogEntry::MalformedEnvVar { key, value, err }); + return None; } - offset += 1; } } -fn directive_to_kernel(dir: &ast::Directive) -> Option<(String, Vec)> { - match dir { - ast::Directive::Method(ast::Function { - func_directive: ast::MethodDecl::Kernel { name, in_args }, - .. - }) => { - let arg_sizes = in_args - .iter() - .map(|arg| ast::Type::from(arg.v_type.clone()).size_of()) - .collect(); - Some((name.to_string(), arg_sizes)) - } - _ => None, - } -} - -#[allow(non_snake_case)] -pub unsafe fn cuModuleLoadDataEx( - module: *mut CUmodule, - image: *const c_void, - numOptions: c_uint, - options: *mut CUjit_option, - optionValues: *mut *mut c_void, - cont: impl FnOnce( - *mut CUmodule, - *const c_void, - c_uint, - *mut CUjit_option, - *mut *mut c_void, - ) -> CUresult, +fn handle_cuda_function_call( + func: &'static str, + original_cuda_fn: impl FnOnce(&mut CudaDynamicFns) -> Option, + arguments_writer: Box std::io::Result<()>>, ) -> CUresult { - let result = cont(module, image, numOptions, options, optionValues); - if result == CUresult::CUDA_SUCCESS { - record_module_image_raw(*module, image); - } - result + handle_cuda_function_call_with_probes( + func, + |_, _| (), + original_cuda_fn, + arguments_writer, + |_, _, _, _| (), + ) +} + +fn handle_cuda_function_call_with_probes( + func: &'static str, + pre_probe: PreFn, + original_cuda_fn: impl FnOnce(&mut CudaDynamicFns) -> Option, + arguments_writer: Box std::io::Result<()>>, + post_probe: PostFn, +) -> CUresult +where + for<'a> PreFn: FnOnce(&'a mut log::FunctionLogger, &'a mut GlobalDelayedState) -> T, + for<'a> PostFn: FnOnce(&'a mut log::FunctionLogger, &'a mut GlobalDelayedState, T, CUresult), +{ + let global_state_mutex = &*GLOBAL_STATE; + // We unwrap because there's really no sensible thing we could do, + // alternatively we could return a CUDA error, but I think it's fine to + // crash. This is a diagnostic utility, if the lock was poisoned we can't + // extract any useful trace or logging anyway + let global_state = &mut *global_state_mutex.lock().unwrap(); + let (mut logger, delayed_state) = match global_state.delayed_state { + LateInit::Success(ref mut delayed_state) => ( + global_state.log_factory.get_logger(func, arguments_writer), + delayed_state, + ), + // There's no libcuda to load, so we might as well panic + LateInit::Error => panic!(), + LateInit::Unitialized => { + let (new_delayed_state, logger) = + GlobalDelayedState::new(func, arguments_writer, &mut global_state.log_factory); + global_state.delayed_state = new_delayed_state; + (logger, global_state.delayed_state.as_mut().unwrap()) + } + }; + let pre_result = pre_probe(&mut logger, delayed_state); + let maybe_cu_result = { + let task = delayed_state.profiler.as_ref().map(|p| p.record_task(func)); + if task.is_some() && func == "cuDevicePrimaryCtxReset" { + Some(CUresult::CUDA_SUCCESS) + } else { + original_cuda_fn(&mut delayed_state.libcuda) + } + }; + let cu_result = match maybe_cu_result { + Some(result) => result, + None => { + logger.log(log::LogEntry::ErrorBox( + format!("No function {} in the underlying CUDA library", func).into(), + )); + CUresult::CUDA_ERROR_UNKNOWN + } + }; + logger.result = maybe_cu_result; + post_probe(&mut logger, delayed_state, pre_result, cu_result); + cu_result } #[allow(non_snake_case)] -unsafe fn cuModuleGetFunction( +pub(crate) fn cuModuleLoad_Pre( + _module: *mut CUmodule, + _fname: *const ::std::os::raw::c_char, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoad_Post( + module: *mut CUmodule, + fname: *const ::std::os::raw::c_char, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + state.cuda_state.record_module( + fn_logger, + Some(unsafe { *module }), + CUmoduleContent::File(fname), + ); +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadData_Pre( + _module: *mut CUmodule, + _raw_image: *const ::std::os::raw::c_void, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadData_Post( + module: *mut CUmodule, + raw_image: *const ::std::os::raw::c_void, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + if let Some(module_content) = + fn_logger.log_unwrap(unsafe { CUmoduleContent::from_ptr(raw_image.cast()) }.map_err(LogEntry::from)) + { + state + .cuda_state + .record_module(fn_logger, Some(unsafe { *module }), module_content); + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadDataEx_Pre( + _module: *mut CUmodule, + _raw_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, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadDataEx_Post( + module: *mut CUmodule, + raw_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, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + pre_result: (), + result: CUresult, +) { + cuModuleLoadData_Post(module, raw_image, fn_logger, state, pre_result, result) +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetExportTable_Pre( + _ppExportTable: *mut *const ::std::os::raw::c_void, + _pExportTableId: *const CUuuid, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetExportTable_Post( + ppExportTable: *mut *const ::std::os::raw::c_void, + pExportTableId: *const CUuuid, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + dark_api::override_export_table( + fn_logger, + ppExportTable, + pExportTableId, + &mut state.cuda_state, + ) +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetFunction_Pre( + _hfunc: *mut CUfunction, + _hmod: CUmodule, + _name: *const ::std::os::raw::c_char, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetFunction_Post( hfunc: *mut CUfunction, hmod: CUmodule, name: *const ::std::os::raw::c_char, - cont: impl FnOnce(*mut CUfunction, CUmodule, *const ::std::os::raw::c_char) -> CUresult, -) -> CUresult { - let result = cont(hfunc, hmod, name); + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { if result != CUresult::CUDA_SUCCESS { - return result; + return; } - if let Some(modules) = &MODULES { - if let Some(module_dump) = modules.get(&hmod) { - if let Some(kernel) = to_str(name) { - if let Some(args) = module_dump.kernels_args.get(kernel) { - let kernel_args = KERNELS.get_or_insert_with(|| HashMap::new()); - kernel_args.insert( - *hfunc, - KernelDump { - module_content: module_dump.content.clone(), - name: kernel.to_string(), - arguments: args.clone(), - }, - ); - } else { - eprintln!("[ZLUDA_DUMP] Unknown kernel: {}", kernel); - } - } else { - eprintln!("[ZLUDA_DUMP] Unknown kernel name at: {:?}", hfunc); - } - } else { - eprintln!("[ZLUDA_DUMP] Unknown module: {:?}", hmod); + unsafe { + state + .cuda_state + .record_function(*hfunc, hmod, name, fn_logger) + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuDeviceGetAttribute_Pre( + _pi: *mut ::std::os::raw::c_int, + _attrib: CUdevice_attribute, + _dev: CUdevice, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuDeviceGetAttribute_Post( + pi: *mut ::std::os::raw::c_int, + attrib: CUdevice_attribute, + _dev: CUdevice, + _fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + _result: CUresult, +) { + if attrib == CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR { + if let Some(major_ver_override) = state.cuda_state.override_cc_major { + unsafe { *pi = major_ver_override as i32 }; } - } else { - eprintln!("[ZLUDA_DUMP] Unknown module: {:?}", hmod); } - CUresult::CUDA_SUCCESS } #[allow(non_snake_case)] -pub unsafe fn cuMemAlloc_v2( - dptr: *mut CUdeviceptr, - bytesize: usize, - cont: impl FnOnce(*mut CUdeviceptr, usize) -> CUresult, -) -> CUresult { - let result = cont(dptr, bytesize); - assert_eq!(result, CUresult::CUDA_SUCCESS); - let start = (*dptr).0 as usize; - BUFFERS.push((start, bytesize)); - CUresult::CUDA_SUCCESS +pub(crate) fn cuDeviceComputeCapability_Pre( + _major: *mut ::std::os::raw::c_int, + _minor: *mut ::std::os::raw::c_int, + _dev: CUdevice, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { } #[allow(non_snake_case)] -pub unsafe fn cuLaunchKernel( +pub(crate) fn cuDeviceComputeCapability_Post( + major: *mut ::std::os::raw::c_int, + _minor: *mut ::std::os::raw::c_int, + _dev: CUdevice, + _fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + _result: CUresult, +) { + if let Some(major_ver_override) = state.cuda_state.override_cc_major { + unsafe { *major = major_ver_override as i32 }; + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadFatBinary_Pre( + _module: *mut CUmodule, + _fatCubin: *const ::std::os::raw::c_void, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleLoadFatBinary_Post( + _module: *mut CUmodule, + _fatCubin: *const ::std::os::raw::c_void, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result == CUresult::CUDA_SUCCESS { + panic!() + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuLaunchKernel_Pre( + 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, + stream: CUstream, + kernelParams: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, +) -> (Option, Option) { + let side_by_side_args = unsafe { + side_by_side::pre_kernel_launch( + &mut state.libcuda, + &mut state.cuda_state, + &mut state.side_by_side, + fn_logger, + f, + stream, + kernelParams, + extra, + ) + }; + let start_event = if state.profiler.is_some() { + fn_logger.log_unwrap(record_event(stream, &mut state.libcuda)) + } else { + None + }; + (side_by_side_args, start_event) +} + +// TODO: stop leaking CUevent on failure +fn record_event(stream: CUstream, libcuda: &mut CudaDynamicFns) -> Result { + let mut event = ptr::null_mut(); + cuda_call!(libcuda.cuEventCreate(&mut event, 0)); + cuda_call!(libcuda.cuEventRecord(event, stream)); + Ok(event) +} + +#[allow(non_snake_case)] +pub(crate) fn cuLaunchKernel_Post( f: CUfunction, gridDimX: ::std::os::raw::c_uint, gridDimY: ::std::os::raw::c_uint, @@ -279,33 +651,40 @@ pub unsafe fn cuLaunchKernel( blockDimY: ::std::os::raw::c_uint, blockDimZ: ::std::os::raw::c_uint, sharedMemBytes: ::std::os::raw::c_uint, - hStream: CUstream, + stream: CUstream, kernelParams: *mut *mut ::std::os::raw::c_void, extra: *mut *mut ::std::os::raw::c_void, - cont: impl FnOnce( - CUfunction, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - ::std::os::raw::c_uint, - CUstream, - *mut *mut ::std::os::raw::c_void, - *mut *mut ::std::os::raw::c_void, - ) -> CUresult, -) -> CUresult { - let mut error; - let dump_env = match create_dump_dir(f, LAUNCH_COUNTER) { - Ok(dump_env) => dump_env, - Err(err) => { - eprintln!("[ZLUDA_DUMP] {:#?}", err); - None + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + pre_result: (Option, Option), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + let (side_by_side_args, start_event) = pre_result; + if let Some(start_event) = start_event { + if let Some(end_event) = fn_logger.log_unwrap(record_event(stream, &mut state.libcuda)) { + let func_name = match state.cuda_state.functions.get(&f) { + Some(recorded_func) => profiler::FunctionName::Resolved(recorded_func.name.clone()), + None => profiler::FunctionName::Unresolved(f), + }; + state.profiler.as_ref().unwrap().record_kernel( + stream, + func_name, + start_event, + end_event, + ); } - }; - if let Some(dump_env) = &dump_env { - dump_pre_data( + } + unsafe { + side_by_side::post_kernel_launch( + &mut state.libcuda, + &mut state.cuda_state, + &mut state.side_by_side, + fn_logger, + side_by_side_args, + f, gridDimX, gridDimY, gridDimZ, @@ -313,358 +692,507 @@ pub unsafe fn cuLaunchKernel( blockDimY, blockDimZ, sharedMemBytes, + stream, kernelParams, - dump_env, + extra, ) - .unwrap_or_else(|err| eprintln!("[ZLUDA_DUMP] {:#?}", err)); - }; - error = cont( - f, - gridDimX, - gridDimY, - gridDimZ, - blockDimX, - blockDimY, - blockDimZ, - sharedMemBytes, - hStream, - kernelParams, - extra, - ); - assert_eq!(error, CUresult::CUDA_SUCCESS); - error = cuda::cuStreamSynchronize(hStream); - assert_eq!(error, CUresult::CUDA_SUCCESS); - if let Some((_, kernel_dump)) = &dump_env { - dump_arguments( - kernelParams, - "post", - &kernel_dump.name, - LAUNCH_COUNTER, - &kernel_dump.arguments, - ) - .unwrap_or_else(|err| eprintln!("[ZLUDA_DUMP] {:#?}", err)); } - LAUNCH_COUNTER += 1; - CUresult::CUDA_SUCCESS + .unwrap_or_default() } #[allow(non_snake_case)] -fn dump_launch_arguments( - gridDimX: u32, - gridDimY: u32, - gridDimZ: u32, - blockDimX: u32, - blockDimY: u32, - blockDimZ: u32, - sharedMemBytes: u32, - dump_dir: &PathBuf, -) -> Result<(), Box> { - let mut module_file_path = dump_dir.clone(); - module_file_path.push("launch.txt"); - let mut module_file = File::create(module_file_path)?; - write!(&mut module_file, "{}\n", gridDimX)?; - write!(&mut module_file, "{}\n", gridDimY)?; - write!(&mut module_file, "{}\n", gridDimZ)?; - write!(&mut module_file, "{}\n", blockDimX)?; - write!(&mut module_file, "{}\n", blockDimY)?; - write!(&mut module_file, "{}\n", blockDimZ)?; - write!(&mut module_file, "{}\n", sharedMemBytes)?; - Ok(()) -} - -unsafe fn should_dump_kernel(name: &str) -> bool { - match &KERNEL_PATTERN { - Some(pattern) => pattern.is_match(name), - None => true, - } -} - -unsafe fn create_dump_dir( - f: CUfunction, - counter: usize, -) -> Result, Box> { - match KERNELS.as_ref().and_then(|kernels| kernels.get(&f)) { - Some(kernel_dump) => { - if !should_dump_kernel(&kernel_dump.name) { - return Ok(None); - } - let mut dump_dir = get_dump_dir()?; - dump_dir.push(format!("{:04}_{}", counter, kernel_dump.name)); - fs::create_dir_all(&dump_dir)?; - Ok(Some((dump_dir, kernel_dump))) - } - None => Err("Unknown kernel: {:?}")?, - } +pub(crate) fn cuTexRefSetAddress_v2_Pre( + _ByteOffset: *mut usize, + _hTexRef: CUtexref, + _dptr: CUdeviceptr, + _bytes: usize, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) -> () { } #[allow(non_snake_case)] -unsafe fn dump_pre_data( - 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, - kernelParams: *mut *mut ::std::os::raw::c_void, - (dump_dir, kernel_dump): &(PathBuf, &'static KernelDump), -) -> Result<(), Box> { - dump_launch_arguments( - gridDimX, - gridDimY, - gridDimZ, - blockDimX, - blockDimY, - blockDimZ, - sharedMemBytes, - dump_dir, - )?; - let mut module_file_path = dump_dir.clone(); - module_file_path.push("module.ptx"); - let mut module_file = File::create(module_file_path)?; - module_file.write_all(kernel_dump.module_content.as_bytes())?; - dump_arguments( - kernelParams, - "pre", - &kernel_dump.name, - LAUNCH_COUNTER, - &kernel_dump.arguments, - )?; - Ok(()) -} - -unsafe fn dump_arguments( - kernel_params: *mut *mut ::std::os::raw::c_void, - prefix: &str, - kernel_name: &str, - counter: usize, - args: &[usize], -) -> Result<(), Box> { - let mut dump_dir = get_dump_dir()?; - dump_dir.push(format!("{:04}_{}", counter, kernel_name)); - dump_dir.push(prefix); - if dump_dir.exists() { - fs::remove_dir_all(&dump_dir)?; - } - fs::create_dir_all(&dump_dir)?; - for (i, arg_len) in args.iter().enumerate() { - let dev_ptr = *(*kernel_params.add(i) as *mut usize); - match BUFFERS.iter().find(|(start, _)| *start == dev_ptr as usize) { - Some((start, len)) => { - let mut output = vec![0u8; *len]; - let error = - cuda::cuMemcpyDtoH_v2(output.as_mut_ptr() as *mut _, CUdeviceptr(*start), *len); - assert_eq!(error, CUresult::CUDA_SUCCESS); - let mut path = dump_dir.clone(); - path.push(format!("arg_{:03}.buffer", i)); - let mut file = File::create(path)?; - file.write_all(&mut output)?; - } - None => { - let mut path = dump_dir.clone(); - path.push(format!("arg_{:03}", i)); - let mut file = File::create(path)?; - file.write_all(slice::from_raw_parts( - *kernel_params.add(i) as *mut u8, - *arg_len, - ))?; - } - } - } - Ok(()) -} - -fn get_dump_dir() -> Result> { - let dir = env::var("ZLUDA_DUMP_DIR")?; - let mut main_dir = PathBuf::from(dir); - let current_exe = env::current_exe()?; - main_dir.push(current_exe.file_name().unwrap()); - fs::create_dir_all(&main_dir)?; - Ok(main_dir) -} - -// TODO make this more common with ZLUDA implementation -const CUDART_INTERFACE_GUID: CUuuid = CUuuid { - bytes: [ - 0x6b, 0xd5, 0xfb, 0x6c, 0x5b, 0xf4, 0xe7, 0x4a, 0x89, 0x87, 0xd9, 0x39, 0x12, 0xfd, 0x9d, - 0xf9, - ], -}; - -const GET_MODULE_OFFSET: usize = 6; -static mut CUDART_INTERFACE_VTABLE: Vec<*const c_void> = Vec::new(); -static mut ORIGINAL_GET_MODULE_FROM_CUBIN: Option< - unsafe extern "C" fn( - result: *mut CUmodule, - fatbinc_wrapper: *const FatbincWrapper, - ptr1: *mut c_void, - ptr2: *mut c_void, - ) -> CUresult, -> = None; - -#[allow(non_snake_case)] -pub unsafe fn cuGetExportTable( - ppExportTable: *mut *const ::std::os::raw::c_void, - pExportTableId: *const CUuuid, - cont: impl FnOnce(*mut *const ::std::os::raw::c_void, *const CUuuid) -> CUresult, -) -> CUresult { - if *pExportTableId == CUDART_INTERFACE_GUID { - if CUDART_INTERFACE_VTABLE.len() == 0 { - let mut base_table = ptr::null(); - let base_result = cont(&mut base_table, pExportTableId); - if base_result != CUresult::CUDA_SUCCESS { - return base_result; - } - let len = *(base_table as *const usize); - CUDART_INTERFACE_VTABLE = vec![ptr::null(); len]; - ptr::copy_nonoverlapping( - base_table as *const _, - CUDART_INTERFACE_VTABLE.as_mut_ptr(), - len, - ); - if GET_MODULE_OFFSET >= len { - return CUresult::CUDA_ERROR_UNKNOWN; - } - ORIGINAL_GET_MODULE_FROM_CUBIN = - mem::transmute(CUDART_INTERFACE_VTABLE[GET_MODULE_OFFSET]); - CUDART_INTERFACE_VTABLE[GET_MODULE_OFFSET] = get_module_from_cubin as *const _; - } - *ppExportTable = CUDART_INTERFACE_VTABLE.as_ptr() as *const _; - return CUresult::CUDA_SUCCESS; - } else { - cont(ppExportTable, pExportTableId) - } -} - -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)] -#[derive(Debug)] -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( - module: *mut CUmodule, - fatbinc_wrapper: *const FatbincWrapper, - ptr1: *mut c_void, - ptr2: *mut c_void, -) -> CUresult { - if module == ptr::null_mut() - || (*fatbinc_wrapper).magic != FATBINC_MAGIC - || (*fatbinc_wrapper).version != FATBINC_VERSION - { - return CUresult::CUDA_ERROR_INVALID_VALUE; - } - 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); - let mut maybe_kernel_text = None; - for file in ptx_files { - match decompress_kernel_module(file) { - None => continue, - Some(vec) => { - maybe_kernel_text = Some(vec); - break; - } - }; - } - let result = ORIGINAL_GET_MODULE_FROM_CUBIN.unwrap()(module, fatbinc_wrapper, ptr1, ptr2); +pub(crate) fn cuTexRefSetAddress_v2_Post( + _ByteOffset: *mut usize, + hTexRef: CUtexref, + pointer: CUdeviceptr, + bytes: usize, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) -> () { if result != CUresult::CUDA_SUCCESS { - return result; + return; } - if let Some(text) = maybe_kernel_text { - match CStr::from_bytes_with_nul(&text) { - Ok(cstr) => match cstr.to_str() { - Ok(utf8_str) => record_module_image(*module, utf8_str), - Err(_) => {} - }, - Err(_) => {} - } + if pointer.0 == ptr::null_mut() { + state.cuda_state.remove_texref_address(fn_logger, hTexRef); + } else { + state.cuda_state.record_texref_address( + fn_logger, + hTexRef, + Some(TexrefAddress::OneD { pointer, bytes }), + ) } - result } -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 +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetAddress2D_v2_Pre( + _hTexRef: CUtexref, + _desc: *const CUDA_ARRAY_DESCRIPTOR, + _dptr: CUdeviceptr, + _Pitch: usize, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) -> () { } -const MAX_PTX_MODULE_DECOMPRESSION_BOUND: usize = 16 * 1024 * 1024; +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetAddress2D_v3_Pre( + _hTexRef: CUtexref, + _desc: *const CUDA_ARRAY_DESCRIPTOR, + _dptr: CUdeviceptr, + _Pitch: usize, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} -unsafe fn decompress_kernel_module(file: *const FatbinFileHeader) -> Option> { - let decompressed_size = usize::max(1024, (*file).uncompressed_payload as usize); - let mut decompressed_vec = vec![0u8; decompressed_size]; - loop { - match lz4_sys::LZ4_decompress_safe( - (file as *const u8).add((*file).header_size as usize) as *const _, - decompressed_vec.as_mut_ptr() as *mut _, - (*file).payload_size as c_int, - decompressed_vec.len() as c_int, - ) { - error if error < 0 => { - let new_size = decompressed_vec.len() * 2; - if new_size > MAX_PTX_MODULE_DECOMPRESSION_BOUND { +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetAddress2D_v2_Post( + hTexRef: CUtexref, + desc: *const CUDA_ARRAY_DESCRIPTOR, + dptr: CUdeviceptr, + pitch: usize, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) -> () { + if result != CUresult::CUDA_SUCCESS { + return; + } + let desc = unsafe { *desc }; + state.cuda_state.record_texref_address( + fn_logger, + hTexRef, + Some(TexrefAddress::new_2d(desc, dptr, pitch)), + ) +} + +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetAddress2D_v3_Post( + hTexRef: CUtexref, + desc: *const CUDA_ARRAY_DESCRIPTOR, + dptr: CUdeviceptr, + Pitch: usize, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + pre_result: (), + result: CUresult, +) { + cuTexRefSetAddress2D_v2_Post( + hTexRef, desc, dptr, Pitch, fn_logger, state, pre_result, result, + ) +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetTexRef_Pre( + _pTexRef: *mut CUtexref, + _hmod: CUmodule, + _name: *const ::std::os::raw::c_char, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetTexRef_Post( + pTexRef: *mut CUtexref, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + state + .cuda_state + .record_texref(fn_logger, name, unsafe { *pTexRef }, hmod) +} + +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetArray_Pre( + _hTexRef: CUtexref, + _hArray: CUarray, + _Flags: ::std::os::raw::c_uint, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuTexRefSetArray_Post( + texref: CUtexref, + array: CUarray, + flags: ::std::os::raw::c_uint, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + state.cuda_state.record_texref_address( + fn_logger, + texref, + Some(TexrefAddress::Array { array, flags }), + ) +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetGlobal_v2_Pre( + _dptr: *mut CUdeviceptr, + _bytes: *mut usize, + _hmod: CUmodule, + _name: *const ::std::os::raw::c_char, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuModuleGetGlobal_v2_Post( + dptr: *mut CUdeviceptr, + _bytes: *mut usize, + hmod: CUmodule, + name: *const ::std::os::raw::c_char, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + if dptr == ptr::null_mut() { + return; + } + // We don't collect byte size, because some applications call this function + // exclusively with `bytes` == NULL + state + .cuda_state + .record_global(fn_logger, hmod, name, unsafe { *dptr }) +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetProcAddress_Pre( + _symbol: *const ::std::os::raw::c_char, + _pfn: *mut *mut ::std::os::raw::c_void, + _cudaVersion: ::std::os::raw::c_int, + _flags: cuuint64_t, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetProcAddress_Post( + symbol: *const ::std::os::raw::c_char, + result_value: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, + _pre_result: (), + result_code: CUresult, +) { + if result_code != CUresult::CUDA_SUCCESS { + return; + } + let symbol = unsafe { CStr::from_ptr(symbol) }; + let name = symbol.to_bytes(); + let version = cudaVersion as u32; + let fn_ptr = get_proc_address(name, flags, version); + if fn_ptr == ptr::null_mut() || fn_ptr == usize::MAX as _ { + fn_logger.log(LogEntry::NoCudaFunction( + symbol.to_string_lossy().to_owned(), + )); + } else { + unsafe { *result_value = fn_ptr }; + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetProcAddress_v2_Pre( + _symbol: *const ::std::os::raw::c_char, + _pfn: *mut *mut ::std::os::raw::c_void, + _cudaVersion: ::std::os::raw::c_int, + _flags: cuuint64_t, + _symbolStatus: *mut CUdriverProcAddressQueryResult, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuGetProcAddress_v2_Post( + symbol: *const ::std::os::raw::c_char, + result_value: *mut *mut ::std::os::raw::c_void, + cudaVersion: ::std::os::raw::c_int, + flags: cuuint64_t, + _symbolStatus: *mut CUdriverProcAddressQueryResult, + fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, + _pre_result: (), + result_code: CUresult, +) { + if result_code != CUresult::CUDA_SUCCESS { + return; + } + let symbol = unsafe { CStr::from_ptr(symbol) }; + let name = symbol.to_bytes(); + let version = cudaVersion as u32; + let fn_ptr = get_proc_address(name, flags, version); + if fn_ptr == ptr::null_mut() || fn_ptr == usize::MAX as _ { + fn_logger.log(LogEntry::NoCudaFunction( + symbol.to_string_lossy().to_owned(), + )); + } else { + unsafe { *result_value = fn_ptr }; + } +} + +#[allow(non_snake_case)] +pub(crate) fn cuLinkAddData_v2_Pre( + _link_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, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuLinkAddData_v2_Post( + _link_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, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if result != CUresult::CUDA_SUCCESS { + return; + } + let module = match type_ { + CUjitInputType::CU_JIT_INPUT_CUBIN => CUmoduleContent::Elf(data.cast()), + CUjitInputType::CU_JIT_INPUT_PTX => CUmoduleContent::RawText(data.cast()), + CUjitInputType::CU_JIT_INPUT_LIBRARY => { + let data_slice = unsafe { std::slice::from_raw_parts(data.cast::(), size) }; + CUmoduleContent::Archive(data_slice) + } + _ => return, + }; + state.cuda_state.record_module(fn_logger, None, module); +} + +#[allow(non_snake_case)] +pub(crate) fn cuLibraryGetModule_Pre( + _pMod: *mut CUmodule, + _library: CUlibrary, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuLibraryGetModule_Post( + _pMod: *mut CUmodule, + _library: CUlibrary, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, + _pre_result: (), + _result: CUresult, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuLibraryLoadData_Pre( + _library: *mut CUlibrary, + _code: *const ::std::os::raw::c_void, + _jitOptions: *mut CUjit_option, + _jitOptionsValues: *mut *mut ::std::os::raw::c_void, + _numJitOptions: ::std::os::raw::c_uint, + _libraryOptions: *mut CUlibraryOption, + _libraryOptionValues: *mut *mut ::std::os::raw::c_void, + _numLibraryOptions: ::std::os::raw::c_uint, + _fn_logger: &mut log::FunctionLogger, + _state: &mut GlobalDelayedState, +) { +} + +#[allow(non_snake_case)] +pub(crate) fn cuLibraryLoadData_Post( + _library: *mut CUlibrary, + code: *const ::std::os::raw::c_void, + _jitOptions: *mut CUjit_option, + _jitOptionsValues: *mut *mut ::std::os::raw::c_void, + _numJitOptions: ::std::os::raw::c_uint, + _libraryOptions: *mut CUlibraryOption, + _libraryOptionValues: *mut *mut ::std::os::raw::c_void, + _numLibraryOptions: ::std::os::raw::c_uint, + fn_logger: &mut log::FunctionLogger, + state: &mut GlobalDelayedState, + _pre_result: (), + result: CUresult, +) { + if !matches!( + result, + CUresult::CUDA_SUCCESS + | CUresult::CUDA_ERROR_INVALID_PTX + | CUresult::CUDA_ERROR_NOT_SUPPORTED + ) { + return; + } + if let Some(module_content) = + fn_logger.log_unwrap(unsafe { CUmoduleContent::from_ptr(code.cast()) }.map_err(LogEntry::from)) + { + state + .cuda_state + .record_module(fn_logger, None, module_content); + } +} + +fn get_proc_address(name: &[u8], flag: u64, version: u32) -> *mut ::std::os::raw::c_void { + include!("../../process_address_table/table.rs") +} + +pub(crate) struct DynamicFn { + pointer: usize, + _marker: PhantomData, +} + +impl Default for DynamicFn { + fn default() -> Self { + DynamicFn { + pointer: 0, + _marker: PhantomData, + } + } +} + +impl DynamicFn { + pub(crate) unsafe fn get(&mut self, lib: *mut c_void, name: &[u8]) -> Option { + match self.pointer { + 0 => { + let addr = os::get_proc_address(lib, CStr::from_bytes_with_nul_unchecked(name)); + if addr == ptr::null_mut() { + self.pointer = 1; return None; + } else { + self.pointer = addr as _; } - decompressed_vec.resize(decompressed_vec.len() * 2, 0); - } - real_decompressed_size => { - decompressed_vec.truncate(real_decompressed_size as usize); - return Some(decompressed_vec); } + 1 => return None, + _ => {} } + Some(mem::transmute_copy(&self.pointer)) } } + +pub(crate) struct CudaDynamicFns { + pub(crate) lib_handle: NonNull<::std::ffi::c_void>, + pub(crate) fn_table: CudaFnTable, +} + +#[macro_export] +macro_rules! try_get_cuda_function { + ($libcuda:expr, $name:ident) => { + unsafe { + let libcuda: &mut _ = $libcuda; + libcuda + .fn_table + .$name + .get( + libcuda.lib_handle.as_ptr(), + concat!(stringify!($name), "\0").as_bytes(), + ) + .ok_or(LogEntry::NoCudaFunction(std::borrow::Cow::Borrowed( + stringify!($name), + ))) + } + }; +} + +impl CudaDynamicFns { + pub(crate) unsafe fn load_library(path: &str) -> Option { + let lib_handle = NonNull::new(os::load_library(path)); + lib_handle.map(|lib_handle| CudaDynamicFns { + lib_handle, + fn_table: CudaFnTable::default(), + }) + } +} + +macro_rules! emit_cuda_fn_table { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* ) -> $ret_type:path);*) => { + #[derive(Default)] + pub(crate) struct CudaFnTable { + pub(crate) $($fn_name: DynamicFn $ret_type>),* + } + + impl CudaDynamicFns { + $( + #[allow(dead_code)] + pub(crate) fn $fn_name(&mut self, $($arg_id : $arg_type),*) -> Option<$ret_type> { + let func = unsafe { self.fn_table.$fn_name.get(self.lib_handle.as_ptr(), concat!(stringify!($fn_name), "\0").as_bytes()) }; + func.map(|f| f($($arg_id),*) ) + } + )* + } + }; +} + +cuda_function_declarations!(cuda_types, emit_cuda_fn_table, emit_cuda_fn_table, []); + +#[macro_export] +macro_rules! cuda_call { + ($fn_table:ident . $fn_:ident ( $($arg:expr),* ) ) => { + { + { + match $fn_table . $fn_ ( $($arg),* ) { + None => return Err(LogEntry::NoCudaFunction(std::borrow::Cow::Borrowed(stringify!($fn_)))), + Some(cuda_types::CUresult::CUDA_SUCCESS) => (), + Some(err) => return Err(LogEntry::CudaError(err)) + } + } + } + }; + + ($fn_:ident ( $($arg:expr),* ) ) => { + { + { + match $fn_ ( $($arg),* ) { + cuda_types::CUresult::CUDA_SUCCESS => (), + err => return Err(LogEntry::CudaError(err)) + } + } + } + }; +} diff --git a/zluda_dump/src/log.rs b/zluda_dump/src/log.rs new file mode 100644 index 0000000..2cfbda6 --- /dev/null +++ b/zluda_dump/src/log.rs @@ -0,0 +1,793 @@ +use super::CUresult; +use super::Settings; +use crate::format; +use crate::format::CudaDisplay; +use crate::parse_env_var; +use cuda_types::*; +use std::borrow::Cow; +use std::env; +use std::error::Error; +use std::ffi::c_void; +use std::ffi::CString; +use std::fmt; +use std::fmt::Display; +use std::fs::File; +use std::io; +use std::io::Stderr; +use std::io::Write; +use std::path::PathBuf; +use std::str::Utf8Error; +use zluda_dark_api::AnyUInt; +use zluda_dark_api::FatbinFileKind; +use zluda_dark_api::Lz4DecompressionFailure; +use zluda_dark_api::UnexpectedFieldError; + +const LOG_PREFIX: &[u8] = b"[ZLUDA_DUMP] "; + +// This type holds all the relevant settings for logging like output path and +// creates objects which match those settings +pub(crate) struct Factory { + // Fallible emitter is optional emitter to file system, we might lack + // file permissions or be out of disk space + fallible_emitter: Option>, + // This is emitter that "always works" (and if it does not, then we don't + // care). In addition of normal logs it emits errors from fallible emitter + infallible_emitter: Box, + write_buffer: WriteBuffer, + // another shared buffer, so we dont't reallocate on every function call + log_queue: Vec, + log_enable: bool, +} + +// When writing out to the emitter (file, WinAPI, whatever else) instead of +// writing piece-by-piece it's better to first concatenate everything in memory +// then write out from memory to the slow emitter only once. +// Additionally we might have an unprefixed and prefixed buffer, this struct +// handles this detail +struct WriteBuffer { + prefixed_buffer: Option>, + unprefixed_buffer: Option>, +} + +impl WriteBuffer { + fn new() -> Self { + WriteBuffer { + prefixed_buffer: None, + unprefixed_buffer: None, + } + } + + fn init( + &mut self, + fallible_emitter: &Option>, + infallible_emitter: &Box, + ) { + if infallible_emitter.should_prefix() { + self.prefixed_buffer = Some(Vec::new()); + } else { + self.unprefixed_buffer = Some(Vec::new()); + } + if let Some(emitter) = fallible_emitter { + if emitter.should_prefix() { + self.prefixed_buffer = Some(Vec::new()); + } else { + self.unprefixed_buffer = Some(Vec::new()); + } + } + } + + fn all_buffers(&mut self) -> impl Iterator> { + self.prefixed_buffer + .as_mut() + .into_iter() + .chain(self.unprefixed_buffer.as_mut().into_iter()) + } + + fn start_line(&mut self) { + if let Some(buffer) = &mut self.prefixed_buffer { + buffer.extend_from_slice(LOG_PREFIX); + } + } + + fn end_line(&mut self) { + for buffer in self.all_buffers() { + buffer.push(b'\n'); + } + } + + fn write(&mut self, s: &str) { + for buffer in self.all_buffers() { + buffer.extend_from_slice(s.as_bytes()); + } + } + + fn finish(&mut self) { + for buffer in self.all_buffers() { + buffer.push(b'\0'); + } + } + + fn undo_finish(&mut self) { + for buffer in self.all_buffers() { + buffer.truncate(buffer.len() - 1); + } + } + + fn send_to(&self, log_emitter: &mut Box) -> Result<(), io::Error> { + if log_emitter.should_prefix() { + log_emitter.write_zero_aware( + &*self + .prefixed_buffer + .as_ref() + .unwrap_or_else(|| unreachable!()), + ) + } else { + log_emitter.write_zero_aware( + &*self + .unprefixed_buffer + .as_ref() + .unwrap_or_else(|| unreachable!()), + ) + } + } + + fn reset(&mut self) { + for buffer in self.all_buffers() { + unsafe { buffer.set_len(0) }; + } + } +} + +impl Write for WriteBuffer { + fn write(&mut self, buf: &[u8]) -> io::Result { + if let Some(buffer) = &mut self.prefixed_buffer { + buffer.extend_from_slice(buf); + } + if let Some(buffer) = &mut self.unprefixed_buffer { + buffer.extend_from_slice(buf); + } + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Factory { + pub(crate) fn new() -> Self { + let log_enable = parse_env_var::("ZLUDA_LOG_ENABLE", &mut |_| {}).unwrap_or(true); + let infallible_emitter = if !log_enable { + Box::new(NullLog) + } else { + os::new_debug_logger() + }; + Factory { + infallible_emitter, + fallible_emitter: None, + write_buffer: WriteBuffer::new(), + log_queue: Vec::new(), + log_enable, + } + } + + fn initalize_fallible_emitter( + settings: &Settings, + ) -> std::io::Result>> { + if !settings.log_enabled { + return Ok(None); + } + settings + .dump_dir + .as_ref() + .map(|path| { + Ok::<_, std::io::Error>(Box::new(File::create(path.to_path_buf().join("log.txt"))?) + as Box) + }) + .transpose() + } + + // We load settings during first function call, since during that time we + // also create one of the loggers, what do we do about errors encountered + // at that time? We log them to the newly created logger, but to make it + // "nice" we do both of those in a single function + // An alternative would be to have something like this: + // let mut factory = Factory::new(); + // let mut cuInitLog = factory.get_logger("cuInit"); + // cuInitLog.load_settings(&settings); + // which is a bit nonsensical + pub(crate) fn get_first_logger_and_init_settings( + &mut self, + func: &'static str, + arguments_writer: Box std::io::Result<()>>, + ) -> (FunctionLogger, Settings) { + let log_enabled = self.log_enable; + let mut first_logger = self.get_logger(func, arguments_writer); + let settings = Settings::read_and_init(log_enabled, &mut first_logger); + match Self::initalize_fallible_emitter(&settings) { + Ok(fallible_emitter) => { + *first_logger.fallible_emitter = fallible_emitter; + } + Err(err) => first_logger.log(LogEntry::IoError(err)), + } + first_logger.write_buffer.init( + first_logger.fallible_emitter, + first_logger.infallible_emitter, + ); + (first_logger, settings) + } + + pub(crate) fn get_logger( + &mut self, + func: &'static str, + arguments_writer: Box std::io::Result<()>>, + ) -> FunctionLogger { + FunctionLogger { + result: None, + name: CudaFunctionName::Normal(func), + fallible_emitter: &mut self.fallible_emitter, + infallible_emitter: &mut self.infallible_emitter, + write_buffer: &mut self.write_buffer, + log_queue: &mut self.log_queue, + arguments_writer: Some(arguments_writer), + } + } + + pub(crate) fn get_logger_dark_api( + &mut self, + guid: CUuuid, + index: usize, + arguments_writer: Option std::io::Result<()>>>, + ) -> FunctionLogger { + FunctionLogger { + result: None, + name: CudaFunctionName::Dark { guid, index }, + fallible_emitter: &mut self.fallible_emitter, + infallible_emitter: &mut self.infallible_emitter, + write_buffer: &mut self.write_buffer, + log_queue: &mut self.log_queue, + arguments_writer, + } + } +} + +enum CudaFunctionName { + Normal(&'static str), + Dark { guid: CUuuid, index: usize }, +} + +// This encapsulates log output for a single function call. +// It's a separate struct and not just a plain function for two reasons: +// * While we want to always display return code before logging errors, +// logging errors might come before return code is returned +// * We want to handle panics gracefully with Drop +pub(crate) struct FunctionLogger<'a> { + pub(crate) result: Option, + name: CudaFunctionName, + infallible_emitter: &'a mut Box, + fallible_emitter: &'a mut Option>, + arguments_writer: Option std::io::Result<()>>>, + write_buffer: &'a mut WriteBuffer, + log_queue: &'a mut Vec, +} + +impl<'a> FunctionLogger<'a> { + pub(crate) fn log(&mut self, l: LogEntry) { + self.log_queue.push(l); + } + + pub(crate) fn log_io_error(&mut self, error: io::Result<()>) { + if let Err(e) = error { + self.log_queue.push(LogEntry::IoError(e)); + } + } + + pub(crate) fn log_unwrap(&mut self, err: Result) -> Option { + match err { + Ok(t) => Some(t), + Err(e) => { + self.log(e); + None + } + } + } + + pub(crate) fn log_fn(&mut self, f: impl FnOnce(&mut Self) -> Result<(), LogEntry>) { + let result = f(self); + if let Err(e) = result { + self.log(e) + } + } + + fn flush_log_queue_to_write_buffer(&mut self) { + self.write_buffer.start_line(); + match self.name { + CudaFunctionName::Normal(fn_name) => self.write_buffer.write(fn_name), + CudaFunctionName::Dark { guid, index } => { + format::CudaDisplay::write(&guid, "", 0, &mut self.write_buffer).ok(); + write!(&mut self.write_buffer, "::{}", index).ok(); + } + } + match &mut self.arguments_writer { + Some(arg_writer) => { + arg_writer(&mut self.write_buffer).ok(); + } + None => { + self.write_buffer.write_all(b"(...)").ok(); + } + } + self.write_buffer.write_all(b" -> ").ok(); + if let Some(result) = self.result { + format::CudaDisplay::write(&result, "", 0, self.write_buffer).ok(); + } else { + self.write_buffer.write_all(b"UNKNOWN").ok(); + }; + self.write_buffer.end_line(); + for entry in self.log_queue.iter() { + write!(self.write_buffer, " {}", entry).ok(); + self.write_buffer.end_line(); + } + self.write_buffer.finish(); + } + + // This is a dirty hack: we call it at the point where our write buffer is + // already finalized and squeeze the error produced by the previous emitter + fn hack_squeeze_in_additional_error(&mut self, entry: LogEntry) { + self.write_buffer.undo_finish(); + write!(self.write_buffer, " {}", entry).unwrap_or_else(|_| unreachable!()); + self.write_buffer.end_line(); + self.write_buffer.finish(); + } +} + +impl<'a> Drop for FunctionLogger<'a> { + fn drop(&mut self) { + self.flush_log_queue_to_write_buffer(); + let error_from_writing_to_fallible_emitter = match self.fallible_emitter { + Some(emitter) => self.write_buffer.send_to(emitter), + None => Ok(()), + }; + if let Err(e) = error_from_writing_to_fallible_emitter { + self.hack_squeeze_in_additional_error(LogEntry::IoError(e)) + } + self.write_buffer.send_to(self.infallible_emitter).ok(); + self.write_buffer.reset(); + self.log_queue.truncate(0); + } +} + +// Structured log type. We don't want frontend to care about log formatting +pub(crate) enum LogEntry { + IoError(io::Error), + CreatedDumpDirectory(PathBuf), + SideBySideStart(CString), + ErrorBox(Box), + UnsupportedModule { + module: Option, + raw_image: *const c_void, + kind: FatbinFileKind, + }, + MalformedModulePath(Utf8Error), + NonUtf8ModuleText(Utf8Error), + ModuleParsingError(String), + Lz4DecompressionFailure, + UnknownExportTableFn, + UnexpectedBinaryField { + field_name: &'static str, + expected: Vec, + observed: AnyUInt, + }, + UnknownModule(CUmodule), + UnknownFunction(CUfunction, CUmodule, String), + UnknownFunctionUse(CUfunction), + NoCudaFunction(Cow<'static, str>), + CudaError(cuda_types::CUresult), + ArgumentMismatch { + devptr: *mut c_void, + diff_count: usize, + total_count: usize, + }, + UnknownTexref(CUtexref), + EnvVarError(env::VarError), + MalformedEnvVar { + key: &'static str, + value: String, + err: Box, + }, + ExportTableLengthGuess(usize), + ExportTableLengthMismatch { + expected: usize, + observed: usize, + }, + IntegrityHashOverride { + before: u128, + after: u128, + }, + WrappedContext, +} + +impl Display for LogEntry { + fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result { + match self { + LogEntry::IoError(e) => e.fmt(f), + LogEntry::CreatedDumpDirectory(dir) => { + write!( + f, + "Created dump directory {}", + dir.as_os_str().to_string_lossy() + ) + } + LogEntry::SideBySideStart(device) => { + write!( + f, + "Side-by-side secondary device: {}", + device.to_string_lossy() + ) + } + LogEntry::ErrorBox(e) => e.fmt(f), + LogEntry::UnsupportedModule { + module, + raw_image, + kind, + } => { + write!( + f, + "Unsupported {} module {:?} loaded from module image {:?}", + human_readable(*kind), + module, + raw_image + ) + } + LogEntry::MalformedModulePath(e) => e.fmt(f), + LogEntry::NonUtf8ModuleText(e) => e.fmt(f), + LogEntry::ModuleParsingError(file_name) => { + write!( + f, + "Error parsing module, log has been written to {}", + file_name + ) + } + LogEntry::Lz4DecompressionFailure => write!(f, "LZ4 decompression failure"), + LogEntry::UnknownExportTableFn => write!(f, "Unknown export table function"), + LogEntry::UnexpectedBinaryField { + field_name, + expected, + observed, + } => write!( + f, + "Unexpected field {}. Expected one of: {{{}}}, observed: {}", + field_name, + expected + .iter() + .map(|x| x.to_string()) + .collect::>() + .join(", "), + observed + ), + LogEntry::UnknownModule(module) => as_io_write(f, |f| { + f.write_all(b"Unknown module ")?; + CudaDisplay::write(module, "", 0, f) + }), + LogEntry::UnknownFunction(func, module, name) => as_io_write(f, |f| { + f.write_all(b"Unknown function ")?; + CudaDisplay::write(func, "", 0, f)?; + write!(f, " ({}) in module ", name)?; + CudaDisplay::write(module, "", 0, f) + }), + LogEntry::UnknownFunctionUse(func) => as_io_write(f, |f| { + f.write_all(b"Unknown function ")?; + CudaDisplay::write(func, "", 0, f) + }), + LogEntry::NoCudaFunction(fn_name) => { + write!(f, "Could not resolve CUDA function {}", fn_name) + } + LogEntry::CudaError(error) => as_io_write(f, |f| { + f.write_all(b"CUDA error ")?; + CudaDisplay::write(error, "", 0, f) + }), + LogEntry::ArgumentMismatch { + devptr, + diff_count, + total_count, + } => { + let total_percentage = (*diff_count as f64 / *total_count as f64) * 100f64; + write!( + f, + "Mismatched elements for argument {:p}. Mismatched elements: {} / {} ({}%)", + *devptr, diff_count, total_count, total_percentage + ) + } + LogEntry::UnknownTexref(texref) => as_io_write(f, |f| { + f.write_all(b"Unknown texture references ")?; + CudaDisplay::write(texref, "", 0, f) + }), + LogEntry::EnvVarError(err) => { + write!(f, "Error reading environment variable: {}", err) + } + LogEntry::MalformedEnvVar { key, value, err } => { + write!( + f, + "Error parsing environment variable with key {} and value {}: {}", + key, value, err + ) + } + LogEntry::ExportTableLengthGuess(length) => { + write!( + f, + "Unknown export table length, guessed length: {}", + *length + ) + } + LogEntry::ExportTableLengthMismatch { expected, observed } => { + write!( + f, + "Export table length mismatch. Expected: {}, observed: {}", + *expected, *observed + ) + } + LogEntry::IntegrityHashOverride { before, after } => { + write!( + f, + "Overriding integrity hash. Before: {before:032x}, after: {after:032x}" + ) + } + LogEntry::WrappedContext => write!(f, "Observed wrapped context"), + } + } +} + +fn as_io_write<'a, 'b: 'a>( + formatter: &'a mut fmt::Formatter<'b>, + func: impl FnOnce(&mut IoFormatter<'a, 'b>) -> io::Result<()>, +) -> fmt::Result { + let mut formatter = IoFormatter { formatter }; + func(&mut formatter).map_err(|_| fmt::Error) +} + +struct IoFormatter<'a, 'b: 'a> { + formatter: &'a mut fmt::Formatter<'b>, +} + +impl<'a, 'b> fmt::Write for IoFormatter<'a, 'b> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.formatter.write_str(s) + } + + fn write_char(&mut self, c: char) -> fmt::Result { + self.formatter.write_char(c) + } + + fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { + self.formatter.write_fmt(args) + } +} + +impl<'a, 'b> io::Write for IoFormatter<'a, 'b> { + fn write(&mut self, buf: &[u8]) -> io::Result { + let str = + std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + self.formatter + .write_str(str) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +fn human_readable(kind: FatbinFileKind) -> &'static str { + match kind { + FatbinFileKind::Ptx => "PTX", + FatbinFileKind::Elf => "ELF", + FatbinFileKind::Archive => "Archive", + } +} + +impl From for LogEntry { + fn from(e: io::Error) -> Self { + LogEntry::IoError(e) + } +} + +impl From for LogEntry { + fn from(_err: Lz4DecompressionFailure) -> Self { + LogEntry::Lz4DecompressionFailure + } +} + +impl From for LogEntry { + fn from(err: UnexpectedFieldError) -> Self { + LogEntry::UnexpectedBinaryField { + field_name: err.name, + expected: err.expected, + observed: err.observed, + } + } +} + +// Some of our writers want to have trailing zero (WinAPI debug logger) and some +// don't (everything else), this trait encapsulates that logic +pub(crate) trait WriteTrailingZeroAware { + fn write_zero_aware(&mut self, buf: &[u8]) -> std::io::Result<()>; + fn flush(&mut self) -> std::io::Result<()>; + fn should_prefix(&self) -> bool; +} + +impl WriteTrailingZeroAware for File { + fn write_zero_aware(&mut self, buf: &[u8]) -> std::io::Result<()> { + ::write_all(self, buf.split_last().unwrap().1) + } + + fn flush(&mut self) -> std::io::Result<()> { + ::flush(self) + } + + fn should_prefix(&self) -> bool { + false + } +} + +impl WriteTrailingZeroAware for Stderr { + fn write_zero_aware(&mut self, buf: &[u8]) -> std::io::Result<()> { + ::write_all(self, buf.split_last().unwrap().1) + } + + fn flush(&mut self) -> std::io::Result<()> { + ::flush(self) + } + + fn should_prefix(&self) -> bool { + true + } +} + +struct NullLog; + +impl WriteTrailingZeroAware for NullLog { + fn write_zero_aware(&mut self, _buf: &[u8]) -> std::io::Result<()> { + Ok(()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + + fn should_prefix(&self) -> bool { + false + } +} + +#[cfg(windows)] +mod os { + use super::WriteTrailingZeroAware; + use std::{os::windows::prelude::AsRawHandle, ptr}; + use winapi::um::debugapi::OutputDebugStringA; + + struct OutputDebugString {} + + impl WriteTrailingZeroAware for OutputDebugString { + fn write_zero_aware(&mut self, buf: &[u8]) -> std::io::Result<()> { + unsafe { OutputDebugStringA(buf.as_ptr() as *const _) }; + Ok(()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + + fn should_prefix(&self) -> bool { + true + } + } + + pub(crate) fn new_debug_logger() -> Box { + let stderr = std::io::stderr(); + let log_to_stderr = stderr.as_raw_handle() != ptr::null_mut(); + if log_to_stderr { + Box::new(stderr) + } else { + Box::new(OutputDebugString {}) + } + } +} + +#[cfg(not(windows))] +mod os { + use super::WriteTrailingZeroAware; + + pub(crate) fn new_debug_logger() -> Box { + Box::new(std::io::stderr()) + } +} + +#[cfg(test)] +mod tests { + use std::{cell::RefCell, io, rc::Rc, str}; + + use super::{FunctionLogger, LogEntry, WriteTrailingZeroAware}; + use crate::{log::CudaFunctionName, log::WriteBuffer, CUresult}; + + struct FailOnNthWrite { + fail_on: usize, + counter: usize, + } + + impl WriteTrailingZeroAware for FailOnNthWrite { + fn write_zero_aware(&mut self, _: &[u8]) -> std::io::Result<()> { + self.counter += 1; + if self.counter >= self.fail_on { + Err(io::Error::from_raw_os_error(4)) + } else { + Ok(()) + } + } + + fn flush(&mut self) -> std::io::Result<()> { + panic!() + } + + fn should_prefix(&self) -> bool { + false + } + } + + // Custom type to not trigger trait coherence rules + #[derive(Clone)] + struct RcVec(Rc>>); + + impl WriteTrailingZeroAware for RcVec { + fn write_zero_aware(&mut self, buf: &[u8]) -> std::io::Result<()> { + let mut vec = self.0.borrow_mut(); + vec.extend_from_slice(buf.split_last().unwrap().1); + Ok(()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + + fn should_prefix(&self) -> bool { + false + } + } + + #[test] + fn error_in_fallible_emitter_is_handled_gracefully() { + let result = RcVec(Rc::new(RefCell::new(Vec::::new()))); + let mut infallible_emitter = Box::new(result.clone()) as Box; + let mut fallible_emitter = Some(Box::new(FailOnNthWrite { + fail_on: 1, + counter: 0, + }) as Box); + let mut write_buffer = WriteBuffer::new(); + write_buffer.unprefixed_buffer = Some(Vec::new()); + let mut log_queue = Vec::new(); + let mut func_logger = FunctionLogger { + result: Some(CUresult::CUDA_SUCCESS), + name: CudaFunctionName::Normal("cuInit"), + infallible_emitter: &mut infallible_emitter, + fallible_emitter: &mut fallible_emitter, + arguments_writer: None, + write_buffer: &mut write_buffer, + log_queue: &mut log_queue, + }; + + func_logger.log(LogEntry::IoError(io::Error::from_raw_os_error(1))); + func_logger.log(LogEntry::IoError(io::Error::from_raw_os_error(2))); + func_logger.log(LogEntry::IoError(io::Error::from_raw_os_error(3))); + drop(func_logger); + drop(infallible_emitter); + + let result = result.0.borrow_mut(); + let result_str = str::from_utf8(&*result).unwrap(); + let result_lines = result_str.lines().collect::>(); + assert_eq!(result_lines.len(), 5); + assert_eq!(result_lines[0], "cuInit(...) -> CUDA_SUCCESS"); + assert!(result_lines[1].starts_with(" ")); + assert!(result_lines[2].starts_with(" ")); + assert!(result_lines[3].starts_with(" ")); + assert!(result_lines[4].starts_with(" ")); + } +} diff --git a/zluda_dump/src/os_unix.rs b/zluda_dump/src/os_unix.rs index b3d9343..31dcd3b 100644 --- a/zluda_dump/src/os_unix.rs +++ b/zluda_dump/src/os_unix.rs @@ -1,14 +1,76 @@ -use std::ffi::{c_void, CStr}; +use std::ffi::{c_void, CStr, CString}; +use std::mem; -const NVCUDA_DEFAULT_PATH: &'static [u8] = b"/usr/lib/x86_64-linux-gnu/libcuda.so.1\0"; +pub(crate) const LIBCUDA_DEFAULT_PATH: &'static str = "/usr/lib/x86_64-linux-gnu/libcuda.so.1"; -pub unsafe fn load_cuda_library() -> *mut c_void { - libc::dlopen( - NVCUDA_DEFAULT_PATH.as_ptr() as *const _, - libc::RTLD_LOCAL | libc::RTLD_NOW, - ) +pub unsafe fn load_library(libcuda_path: &str) -> *mut c_void { + let libcuda_path = CString::new(libcuda_path).unwrap(); + // I would like to use dlmopen but NVIDIA's CUDA does not survive it + let result = libc::dlopen( + libcuda_path.as_ptr() as *const _, + libc::RTLD_LOCAL | libc::RTLD_LAZY, + ); + if result == std::ptr::null_mut() { + panic!("{}", CStr::from_ptr(libc::dlerror()).to_string_lossy()); + } + result } pub unsafe fn get_proc_address(handle: *mut c_void, func: &CStr) -> *mut c_void { libc::dlsym(handle, func.as_ptr() as *const _) } + +#[macro_export] +macro_rules! os_log { + ($format:tt) => { + { + eprintln!("[ZLUDA_DUMP] {}", format!($format)); + } + }; + ($format:tt, $($obj: expr),+) => { + { + eprintln!("[ZLUDA_DUMP] {}", format!($format, $($obj,)+)); + } + }; +} + +//RDI, RSI, RDX, RCX, R8, R9 +#[cfg(target_arch = "x86_64")] +pub fn get_thunk( + original_fn: *const c_void, + report_fn: unsafe extern "system" fn(*const [u8; 16], usize), + guid: *const [u8; 16], + idx: usize, +) -> *const c_void { + use dynasmrt::{dynasm, DynasmApi}; + let mut ops = dynasmrt::x86::Assembler::new().unwrap(); + let start = ops.offset(); + dynasm!(ops + ; .arch x64 + ; sub rsp, 8 // push stack for alignment + ; push rdi + ; push rsi + ; push rdx + ; push rcx + ; push r8 + ; push r9 + ; mov rdi, QWORD guid as i64 + ; mov rsi, QWORD idx as i64 + ; mov rax, QWORD report_fn as i64 + ; call rax + ; pop r9 + ; pop r8 + ; pop rcx + ; pop rdx + ; pop rsi + ; pop rdi + ; add rsp, 8 // pop stack + ; mov rax, QWORD original_fn as i64 + ; jmp rax + ; int 3 + ); + let exe_buf = ops.finalize().unwrap(); + let result_fn = exe_buf.ptr(start); + mem::forget(exe_buf); + result_fn as *const _ +} diff --git a/zluda_dump/src/os_win.rs b/zluda_dump/src/os_win.rs index 7f985c5..ad856e9 100644 --- a/zluda_dump/src/os_win.rs +++ b/zluda_dump/src/os_win.rs @@ -1,68 +1,191 @@ use std::{ ffi::{c_void, CStr}, - mem, - os::raw::c_ushort, - ptr, + mem, ptr, }; -use wchar::wch_c; +use std::os::windows::io::AsRawHandle; use winapi::{ - shared::minwindef::HMODULE, + shared::minwindef::{FARPROC, HMODULE}, + um::debugapi::OutputDebugStringA, um::libloaderapi::{GetProcAddress, LoadLibraryW}, }; -const NVCUDA_DEFAULT_PATH: &[u16] = wch_c!(r"C:\Windows\System32\nvcuda.dll"); +pub(crate) const LIBCUDA_DEFAULT_PATH: &'static str = "C:\\Windows\\System32\\nvcuda.dll"; const LOAD_LIBRARY_NO_REDIRECT: &'static [u8] = b"ZludaLoadLibraryW_NoRedirect\0"; - -include!("../../zluda_redirect/src/payload_guid.rs"); - -pub unsafe fn load_cuda_library() -> *mut c_void { - let load_lib = if is_detoured() { - match get_non_detoured_load_library() { - Some(load_lib) => load_lib, - None => return ptr::null_mut(), - } - } else { - LoadLibraryW - }; - load_lib(NVCUDA_DEFAULT_PATH.as_ptr()) as *mut _ +const GET_PROC_ADDRESS_NO_REDIRECT: &'static [u8] = b"ZludaGetProcAddress_NoRedirect\0"; +lazy_static! { + static ref PLATFORM_LIBRARY: PlatformLibrary = unsafe { PlatformLibrary::new() }; } -unsafe fn is_detoured() -> bool { - let mut module = ptr::null_mut(); - loop { - module = detours_sys::DetourEnumerateModules(module); - if module == ptr::null_mut() { - break; - } - let mut size = 0; - let payload = detours_sys::DetourFindPayload(module, &PAYLOAD_GUID, &mut size); - if payload != ptr::null_mut() { - return true; - } - } - false +#[allow(non_snake_case)] +struct PlatformLibrary { + LoadLibraryW: unsafe extern "system" fn(*const u16) -> HMODULE, + GetProcAddress: unsafe extern "system" fn(hModule: HMODULE, lpProcName: *const u8) -> FARPROC, } -unsafe fn get_non_detoured_load_library( -) -> Option HMODULE> { - let mut module = ptr::null_mut(); - loop { - module = detours_sys::DetourEnumerateModules(module); - if module == ptr::null_mut() { - break; - } - let result = GetProcAddress( - module as *mut _, - LOAD_LIBRARY_NO_REDIRECT.as_ptr() as *mut _, - ); - if result != ptr::null_mut() { - return Some(mem::transmute(result)); +impl PlatformLibrary { + #[allow(non_snake_case)] + unsafe fn new() -> Self { + let (LoadLibraryW, GetProcAddress) = match Self::get_detourer_module() { + None => ( + LoadLibraryW as unsafe extern "system" fn(*const u16) -> HMODULE, + mem::transmute( + GetProcAddress + as unsafe extern "system" fn( + hModule: HMODULE, + lpProcName: *const i8, + ) -> FARPROC, + ), + ), + Some(zluda_with) => ( + mem::transmute(GetProcAddress( + zluda_with, + LOAD_LIBRARY_NO_REDIRECT.as_ptr() as _, + )), + mem::transmute(GetProcAddress( + zluda_with, + GET_PROC_ADDRESS_NO_REDIRECT.as_ptr() as _, + )), + ), + }; + PlatformLibrary { + LoadLibraryW, + GetProcAddress, } } - None + + unsafe fn get_detourer_module() -> Option { + let mut module = ptr::null_mut(); + loop { + module = detours_sys::DetourEnumerateModules(module); + if module == ptr::null_mut() { + break; + } + let payload = GetProcAddress(module as _, b"ZLUDA_REDIRECT\0".as_ptr() as _); + if payload != ptr::null_mut() { + return Some(module as _); + } + } + None + } +} + +pub unsafe fn load_library(libcuda_path: &str) -> *mut c_void { + let libcuda_path_uf16 = libcuda_path + .encode_utf16() + .chain(std::iter::once(0)) + .collect::>(); + (PLATFORM_LIBRARY.LoadLibraryW)(libcuda_path_uf16.as_ptr()) as _ } pub unsafe fn get_proc_address(handle: *mut c_void, func: &CStr) -> *mut c_void { - GetProcAddress(handle as *mut _, func.as_ptr()) as *mut _ + (PLATFORM_LIBRARY.GetProcAddress)(handle as _, func.as_ptr() as _) as _ +} + +#[macro_export] +macro_rules! os_log { + ($format:tt) => { + { + use crate::os::__log_impl; + __log_impl(format!($format)); + } + }; + ($format:tt, $($obj: expr),+) => { + { + use crate::os::__log_impl; + __log_impl(format!($format, $($obj,)+)); + } + }; +} + +pub fn __log_impl(s: String) { + let log_to_stderr = std::io::stderr().as_raw_handle() != ptr::null_mut(); + if log_to_stderr { + eprintln!("[ZLUDA_DUMP] {}", s); + } else { + let mut win_str = String::with_capacity("[ZLUDA_DUMP] ".len() + s.len() + 2); + win_str.push_str("[ZLUDA_DUMP] "); + win_str.push_str(&s); + win_str.push_str("\n\0"); + unsafe { OutputDebugStringA(win_str.as_ptr() as *const _) }; + } +} + +#[cfg(target_arch = "x86")] +pub fn get_thunk( + original_fn: *const c_void, + report_fn: unsafe extern "system" fn(*const [u8; 16], usize), + guid: *const [u8; 16], + idx: usize, +) -> *const c_void { + use dynasmrt::{dynasm, DynasmApi}; + let mut ops = dynasmrt::x86::Assembler::new().unwrap(); + let start = ops.offset(); + dynasm!(ops + ; .arch x86 + ; push idx as i32 + ; push guid as i32 + ; mov eax, report_fn as i32 + ; call eax + ; mov eax, original_fn as i32 + ; jmp eax + ; int 3 + ); + let exe_buf = ops.finalize().unwrap(); + let result_fn = exe_buf.ptr(start); + mem::forget(exe_buf); + result_fn as *const _ +} + +//RCX, RDX, R8, R9 +#[cfg(target_arch = "x86_64")] +pub fn get_thunk( + original_fn: *const c_void, + report_fn: unsafe extern "system" fn(*const [u8; 16], usize), + guid: *const [u8; 16], + idx: usize, +) -> *const c_void { + use dynasmrt::{dynasm, DynasmApi}; + let mut ops = dynasmrt::x86::Assembler::new().unwrap(); + let start = ops.offset(); + dynasm!(ops + ; .arch x64 + ; mov [rsp+0x20], r9 + ; mov [rsp+0x18], r8 + ; mov [rsp+0x10], rdx + ; mov [rsp+0x08], rcx + // 0x20 for shadow space, 0x38 for 7 stack args, aligns to 16 bytes + ; sub rsp, 0x58 + ; mov rcx, QWORD guid as i64 + ; mov rdx, QWORD idx as i64 + ; mov rax, QWORD report_fn as i64 + ; call rax + ; mov rax, [rsp+0x58+0x58] + ; mov [rsp+0x50], rax + ; mov rax, [rsp+0x50+0x58] + ; mov [rsp+0x48], rax + ; mov rax, [rsp+0x48+0x58] + ; mov [rsp+0x40], rax + ; mov rax, [rsp+0x40+0x58] + ; mov [rsp+0x38], rax + ; mov rax, [rsp+0x38+0x58] + ; mov [rsp+0x30], rax + ; mov rax, [rsp+0x30+0x58] + ; mov [rsp+0x28], rax + ; mov rax, [rsp+0x28+0x58] + ; mov [rsp+0x20], rax + ; mov r9, [rsp+0x20+0x58] + ; mov r8, [rsp+0x18+0x58] + ; mov rdx, [rsp+0x10+0x58] + ; mov rcx, [rsp+0x08+0x58] + ; mov rax, QWORD original_fn as i64 + ; call rax + ; add rsp, 0x58 + ; ret + ; int 3 + ); + let exe_buf = ops.finalize().unwrap(); + let result_fn = exe_buf.ptr(start); + mem::forget(exe_buf); + result_fn as *const _ } diff --git a/zluda_dump/src/profiler.rs b/zluda_dump/src/profiler.rs new file mode 100644 index 0000000..81955ab --- /dev/null +++ b/zluda_dump/src/profiler.rs @@ -0,0 +1,447 @@ +use crate::cuda_call; +use crate::try_get_cuda_function; +use crate::CudaDynamicFns; +use crate::{ + log::{FunctionLogger, LogEntry}, + Settings, +}; +use crossbeam_channel::{Receiver, Sender}; +use cuda_types::*; +use rustc_hash::FxHashSet; +use serde::Serialize; +use std::borrow::Cow; +use std::env; +use std::ffi::CStr; +use std::fmt::Display; +use std::io::BufWriter; +use std::io::Write; +use std::process; +use std::sync::Arc; +use std::time::Instant; +use std::{ + collections::VecDeque, + fs::File, + path::PathBuf, + ptr, + thread::{self, JoinHandle}, + time::Duration, +}; + +pub(crate) struct Profiler { + cu_event_destroy_v2: extern "system" fn(CUevent) -> CUresult, + sender: Sender, + _thread: JoinHandle<()>, +} + +impl Profiler { + pub(crate) fn new( + settings: &Settings, + fn_table: &mut CudaDynamicFns, + logger: &mut FunctionLogger, + ) -> Option { + logger + .log_unwrap(Self::new_impl(settings, fn_table)) + .flatten() + } + + pub(crate) fn record_kernel( + &self, + stream: CUstream, + function: FunctionName, + start: CUevent, + end: CUevent, + ) { + self.sender + .send(ProfilerPacket::RecordKernel(KernelEnqueue { + stream, + function, + start, + end, + cu_event_destroy_v2: self.cu_event_destroy_v2, + })) + .ok(); + } + + pub(crate) fn record_task(&self, function: &'static str) -> TimedTask { + let thread_id = thread_id::get(); + TimedTask { + profiler: self, + name: function, + start: Instant::now(), + thread_id, + } + } + + fn new_impl( + settings: &Settings, + fn_table: &mut CudaDynamicFns, + ) -> Result, LogEntry> { + let path = match &settings.profiler_output { + Some(path) => { + let path = PathBuf::from(path); + if path.is_absolute() { + path + } else { + let mut base_dir = match &settings.dump_dir { + Some(dump_dir) => dump_dir.clone(), + None => std::env::current_dir()?, + }; + base_dir.push(path); + base_dir + } + } + None => return Ok(None), + }; + let file = File::create(path)?; + let cu_event_create = try_get_cuda_function!(fn_table, cuEventCreate)?; + let cu_event_destroy_v2 = try_get_cuda_function!(fn_table, cuEventDestroy_v2)?; + let cu_event_query = try_get_cuda_function!(fn_table, cuEventQuery)?; + let cu_event_elapsed_time = try_get_cuda_function!(fn_table, cuEventElapsedTime)?; + let mut profiling_start = ptr::null_mut(); + cuda_call!(fn_table.cuInit(0)); + let device_name = Self::get_device_name(fn_table)?; + let mut ctx = ptr::null_mut(); + cuda_call!(fn_table.cuDevicePrimaryCtxRetain(&mut ctx, CUdevice_v1(0))); + cuda_call!(fn_table.cuCtxPushCurrent_v2(ctx)); + cuda_call!(cu_event_create(&mut profiling_start, 0)); + cuda_call!(fn_table.cuEventRecord(profiling_start, ptr::null_mut())); + let host_start = Instant::now(); + cuda_call!(fn_table.cuEventSynchronize(profiling_start)); + cuda_call!(fn_table.cuCtxPopCurrent_v2(&mut ctx)); + // Don't release the primary context, otherwise the event will get wiped out + let (sender, receiver) = crossbeam_channel::bounded(1); + let kernel_start = ForceSend(profiling_start); + let thread = thread::spawn(move || { + Self::run( + file, + device_name, + cu_event_query, + cu_event_elapsed_time, + host_start, + kernel_start, + receiver, + ) + }); + Ok(Some(Self { + cu_event_destroy_v2, + sender, + _thread: thread, + })) + } + + fn get_device_name(fn_table: &mut CudaDynamicFns) -> Result { + let mut name = vec![0i8; 256]; + cuda_call!(fn_table.cuDeviceGetName(name.as_mut_ptr(), name.len() as i32, CUdevice_v1(0))); + Ok(unsafe { CStr::from_ptr(name.as_ptr()) } + .to_str() + .unwrap() + .to_string()) + } + + fn run( + file: File, + device_name: String, + cu_event_query: extern "system" fn(CUevent) -> CUresult, + cu_event_elapsed_time: extern "system" fn(*mut f32, CUevent, CUevent) -> CUresult, + host_start: Instant, + kernel_start: ForceSend, + receiver: Receiver, + ) { + let mut writer = ProfilingWriter::new(Self::current_exe(), file, device_name); + let profiling_start = kernel_start.0; + let mut queue = VecDeque::new(); + let mut timeout = 1; + 'thread_loop: loop { + match receiver.recv_timeout(Duration::from_millis(timeout)) { + Ok(ProfilerPacket::Finish) => return, + Ok(ProfilerPacket::RecordKernel(packet)) => { + timeout = 1; + queue.push_back(packet); + loop { + match receiver.try_recv() { + Ok(ProfilerPacket::Finish) => return, + Ok(ProfilerPacket::RecordTask(task)) => { + Self::process_task(&mut writer, host_start, task) + } + Ok(ProfilerPacket::RecordKernel(packet)) => queue.push_back(packet), + Err(_) => continue 'thread_loop, + } + } + } + Ok(ProfilerPacket::RecordTask(task)) => { + timeout = 1; + Self::process_task(&mut writer, host_start, task) + } + Err(_) => { + timeout = u64::max(100, timeout * 2); + Self::process_queue( + &mut writer, + profiling_start, + cu_event_query, + cu_event_elapsed_time, + &mut queue, + ); + } + } + } + } + + fn current_exe() -> Option { + env::current_exe() + .map(|path| { + path.file_name() + .map(|exe| exe.to_string_lossy().to_string()) + }) + .unwrap_or(None) + } + + fn process_task(writer: &mut ProfilingWriter, host_start: Instant, task: TaskMeasurement) { + let time_from_start = task.start.saturating_duration_since(host_start); + let duration = task.end.saturating_duration_since(task.start); + writer.write_host(task.thread_id, task.function, time_from_start, duration) + } + + fn process_queue( + writer: &mut ProfilingWriter, + first_event: CUevent, + cu_event_query: extern "system" fn(CUevent) -> CUresult, + cu_event_elapsed_time: extern "system" fn(*mut f32, CUevent, CUevent) -> CUresult, + queue: &mut VecDeque, + ) { + loop { + let should_dequeue = match queue.front() { + Some(packet) => cu_event_query(packet.end) == CUresult::CUDA_SUCCESS, + None => false, + }; + if !should_dequeue { + return; + } + let kernel = queue.pop_front().unwrap(); + let mut time_from_start = 0f32; + let cu_result = cu_event_elapsed_time(&mut time_from_start, first_event, kernel.start); + if cu_result != CUresult::CUDA_SUCCESS { + panic!("{}", cu_result.0); + } + let mut time_of_execution = 0f32; + let cu_result = cu_event_elapsed_time(&mut time_of_execution, kernel.start, kernel.end); + if cu_result != CUresult::CUDA_SUCCESS { + panic!("{}", cu_result.0); + } + writer.write_kernel( + kernel.stream, + &kernel.function, + time_from_start, + time_of_execution, + ); + } + } +} + +impl Drop for Profiler { + fn drop(&mut self) { + self.sender.send(ProfilerPacket::Finish).ok(); + } +} + +pub(crate) struct TimedTask<'a> { + profiler: &'a Profiler, + name: &'static str, + start: Instant, + thread_id: usize, +} + +impl<'a> Drop for TimedTask<'a> { + fn drop(&mut self) { + let end = Instant::now(); + self.profiler + .sender + .send(ProfilerPacket::RecordTask(TaskMeasurement { + function: self.name, + start: self.start, + end, + thread_id: self.thread_id, + })) + .ok(); + } +} + +enum ProfilerPacket { + RecordKernel(KernelEnqueue), + RecordTask(TaskMeasurement), + Finish, +} + +struct KernelEnqueue { + stream: CUstream, + function: FunctionName, + start: CUevent, + end: CUevent, + cu_event_destroy_v2: extern "system" fn(CUevent) -> CUresult, +} + +#[allow(unused_must_use)] +impl Drop for KernelEnqueue { + fn drop(&mut self) { + (self.cu_event_destroy_v2)(self.start); + (self.cu_event_destroy_v2)(self.end); + } +} + +struct TaskMeasurement { + function: &'static str, + start: Instant, + end: Instant, + thread_id: usize, +} + +unsafe impl Send for KernelEnqueue {} + +struct ForceSend(T); + +unsafe impl Send for ForceSend {} + +pub(crate) enum FunctionName { + Resolved(Arc), + Unresolved(CUfunction), +} + +impl Display for FunctionName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FunctionName::Resolved(name) => Display::fmt(name, f), + FunctionName::Unresolved(cu_func) => write!(f, "{:p}", cu_func), + } + } +} + +struct ProfilingWriter { + file: BufWriter, + known_streams: FxHashSet, + pid: u32, +} + +impl ProfilingWriter { + fn new(process: Option, mut file: File, device_name: String) -> Self { + let pid = process::id(); + file.write_all(b"[\n").unwrap(); + let mut serializer = serde_json::Serializer::new(&mut file); + let entry = ProfilingEvent::Metadata { + name: "process_name", + ph: "M", + pid: 0, + tid: 0, + args: NameArg { name: device_name }, + }; + entry.serialize(&mut serializer).unwrap(); + drop(serializer); + if let Some(exe) = process { + file.write_all(b",\n").unwrap(); + let mut serializer = serde_json::Serializer::new(&mut file); + let entry = ProfilingEvent::Metadata { + name: "process_name", + ph: "M", + pid, + tid: 0, + args: NameArg { name: exe }, + }; + entry.serialize(&mut serializer).unwrap(); + } + let file = BufWriter::new(file); + Self { + file, + known_streams: FxHashSet::default(), + pid, + } + } + + fn write_host( + &mut self, + tid: usize, + func: &'static str, + time_from_start: Duration, + duration: Duration, + ) { + self.file.write_all(b",\n").unwrap(); + let mut serializer = serde_json::Serializer::new(&mut self.file); + let entry = ProfilingEvent::Complete { + name: Cow::Borrowed(func), + cat: "host", + ph: "X", + ts: time_from_start.as_micros() as f32, + dur: duration.as_micros() as f32, + pid: self.pid, + tid, + }; + entry.serialize(&mut serializer).unwrap(); + } + + fn write_kernel( + &mut self, + stream: CUstream, + function: &FunctionName, + millis_from_start: f32, + millis_duration: f32, + ) { + if self.known_streams.insert(stream) { + self.file.write_all(b",\n").unwrap(); + let mut serializer = serde_json::Serializer::new(&mut self.file); + let entry = ProfilingEvent::Metadata { + name: "thread_name", + ph: "M", + pid: 0, + tid: stream as usize, + args: NameArg { + name: format!("Stream {:p}", stream), + }, + }; + entry.serialize(&mut serializer).unwrap(); + } + self.file.write_all(b",\n").unwrap(); + let mut serializer = serde_json::Serializer::new(&mut self.file); + let ts = millis_from_start * 1000f32; + let dur = millis_duration * 1000f32; + let entry = ProfilingEvent::Complete { + name: Cow::Owned(format!("{}", function)), + cat: "kernel", + ph: "X", + ts: ts, + dur: dur, + pid: 0, + tid: stream as usize, + }; + entry.serialize(&mut serializer).unwrap(); + } +} + +impl Drop for ProfilingWriter { + fn drop(&mut self) { + self.file.write_all(b"\n]").ok(); + } +} + +// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview +#[derive(Serialize)] +#[serde(untagged)] +enum ProfilingEvent { + Complete { + name: Cow<'static, str>, + cat: &'static str, + ph: &'static str, + ts: f32, + dur: f32, + pid: u32, + tid: usize, + }, + Metadata { + name: &'static str, + ph: &'static str, + pid: u32, + tid: usize, + args: NameArg, + }, +} + +#[derive(Serialize)] +struct NameArg { + name: String, +} diff --git a/zluda_dump/src/replay.py b/zluda_dump/src/replay.py index 9c78754..d7c81b5 100644 --- a/zluda_dump/src/replay.py +++ b/zluda_dump/src/replay.py @@ -1,4 +1,4 @@ -import pycuda.autoinit +import pycuda.autoinit as cu_autoinit import pycuda.driver as drv import pycuda.tools as py_tools from pathlib import PurePath @@ -7,94 +7,164 @@ from os import path import os import itertools import sys +import json -# It's impossible to discern what is the type of a buffer, here you can override equality checks -def assert_array_equal_override(kernel_name, idx, arr1, arr2): - if kernel_name == 'knn_match' and idx == 6: - arr1_view = np.frombuffer(arr1, dtype=np.dtype([('f1', np.uint32), ('f2', np.uint32), ('f3', np.uint32)])) - np.ndarray.sort(arr1_view) - arr2_view = np.frombuffer(arr2, dtype=np.dtype([('f1', np.uint32), ('f2', np.uint32), ('f3', np.uint32)])) - np.ndarray.sort(arr2_view) - if kernel_name == 'nonmax_suppression' and idx == 7: - arr1_view = np.frombuffer(arr1, dtype=np.dtype(np.uint32)) - np.ndarray.sort(arr1_view) - arr2_view = np.frombuffer(arr2, dtype=np.dtype(np.uint32)) - np.ndarray.sort(arr2_view) - np.testing.assert_array_equal(arr1, arr2) +def format_size(array_format): + if array_format == drv.array_format.UNSIGNED_INT8 or array_format == drv.array_format.SIGNED_INT8: + return 1 + if array_format == drv.array_format.UNSIGNED_INT16 or array_format == drv.array_format.SIGNED_INT16 or array_format == drv.array_format.HALF: + return 2 + if array_format == drv.array_format.UNSIGNED_INT32 or array_format == drv.array_format.SIGNED_INT32 or array_format == drv.array_format.FLOAT: + return 4 + raise NotImplementedError -def load_arguments(arg_path): - is_buffer = arg_path.endswith(".buffer") - with open(arg_path, "rb") as f: - arg_bytes = f.read() - if not is_buffer: - if len(arg_bytes) == 1: - return np.frombuffer(arg_bytes, dtype=np.uint8)[0], None - elif len(arg_bytes) == 2: - return np.frombuffer(arg_bytes, dtype=np.uint16)[0], None - elif len(arg_bytes) == 4: - return np.frombuffer(arg_bytes, dtype=np.uint32)[0], None - elif len(arg_bytes) == 8: - return np.frombuffer(arg_bytes, dtype=np.uint64)[0], None - else: - raise Exception('Incorrect size of {}: {}'.format(arg_path, len(arg_bytes))) +def array_bytes_width(cu_descriptor): + return cu_descriptor.width * cu_descriptor.num_channels * format_size(cu_descriptor.format) + + +def texref_set_data(kernel_launch, buffers, texref, texref_details): + allocation = texref_details['allocation'] + if 'Array' in texref_details['address']: + set_array = texref_details['address']['Array'] + array_details = kernel_launch['allocations'][str(allocation['buffer_key'])] + cu_descriptor = drv.ArrayDescriptor3D() + cu_descriptor.width = array_details['Width'] + cu_descriptor.height = array_details['Height'] + cu_descriptor.depth = array_details['Depth'] + cu_descriptor.format = drv.array_format(array_details['Format']) + cu_descriptor.num_channels = array_details['NumChannels'] + cu_descriptor.flags = array_details['Flags'] + array = drv.Array(cu_descriptor) + if allocation['offset_into_buffer'] != 0: + raise NotImplementedError + copy_desc = drv.Memcpy3D() + copy_desc.set_dst_array(array) + copy_desc.set_src_device(buffers[str(allocation['buffer_key'])][0]) + copy_desc.width_in_bytes = array_bytes_width(cu_descriptor) + copy_desc.depth = max(cu_descriptor.depth, 1) + copy_desc.height = max(cu_descriptor.height, 1) + copy_desc() + texref_format, texref_num_channels = texref.get_format() + if set_array["flags"] != 0 or texref_format != array_details['Format'] or texref_num_channels != \ + array_details['NumChannels']: + raise NotImplementedError + texref.set_array(array) + elif 'OneD' in texref_details['address']: + if allocation['offset_into_buffer'] != 0: + raise NotImplementedError + buffer = buffers[str(allocation['buffer_key'])][0] + texref.set_address(buffer, texref_details['address']['OneD']['bytes']) + pass + elif 'TwoD' in texref_details['address']: + buffer = int(buffers[str(allocation['buffer_key'])][0]) + allocation['offset_into_buffer'] + twod_set = texref_details['address']['TwoD'] + desc = drv.ArrayDescriptor() + desc.width = twod_set['width'] + desc.height = twod_set['height'] + desc.format = drv.array_format(twod_set['format']) + desc.num_channels = twod_set['channels'] + texref.set_address_2d(buffer, desc, texref_details['address']['TwoD']['pitch']) + pass else: - buff = np.frombuffer(bytearray(arg_bytes), dtype=np.uint8) - buff.setflags(write=1, align=1) - return drv.InOut(buff), buff + raise NotImplementedError -def parse_arguments(dump_path, prefix): - dir = path.join(dump_path, prefix) - arg_files = os.listdir(dir) - return [load_arguments(path.join(dir, f)) for f in sorted(arg_files)] +def load_buffers(input_path, subpath, mapper): + buffer_dir = path.join(input_path, subpath) + result = {} + for buffer in os.scandir(buffer_dir): + with open(buffer.path, "rb") as buffer_file: + arg_bytes = buffer_file.read() + result[buffer.name] = (mapper(arg_bytes), len(arg_bytes)) + return result -def append_debug_buffer(args): - args = list(args) - debug_buff = np.zeros(1024 * 1024, np.single) - args.append((drv.InOut(debug_buff), debug_buff)) - return args +def global_copy_data(module, buffers, global_name, global_details): + devptr, global_size = module.get_global(global_name) + buffer, buffer_size = buffers[str(global_details['buffer_key'])] + drv.memcpy_dtod(devptr, int(buffer) + global_details['offset_into_buffer'], global_size) + #drv.memcpy_dtod(devptr, buffer, global_size) -def verify_single_dump(input_path, max_block_threads): +def round_to_nearest(n, m): + return (n + m - 1) // m * m + + +# pycuda does not respect alignment when packing arguments, we have to do it ourselves +def insert_padding(value, start, align): + offset = round_to_nearest(start, align) - start + value[0:0] = bytearray(offset) + return offset + + +def verify_single_dump(input_path): print(input_path) - kernel_name = path.basename(input_path).split("_", 1)[1] - with open(path.join(input_path, "launch.txt"), "r") as launch_f: - launch_lines = list(map(int, launch_f.readlines())) - block = tuple(launch_lines[3:6]) - launch_block_size = block[0] * block[1] * block[2] - if launch_block_size > max_block_threads: - print( - f" Skipping, launch block size ({launch_block_size}) bigger than maximum block size ({max_block_threads})") - return + with open(path.join(input_path, "kernel_launch.json"), "r") as launch_f: + kernel_launch = json.load(launch_f) module = drv.module_from_file(path.join(input_path, "module.ptx")) - kernel = module.get_function(kernel_name) - pre_args = append_debug_buffer(parse_arguments(input_path, "pre")) - kernel_pre_args, host_pre_args = zip(*pre_args) - kernel(*list(kernel_pre_args), grid=tuple(launch_lines[:3]), block=block, shared=launch_lines[6]) - post_args = parse_arguments(input_path, "post") - _, host_post_args_args = zip(*post_args) - for idx, (pre_arg, post_arg) in enumerate(zip(host_pre_args, host_post_args_args)): - if pre_arg is None: - continue + pre = load_buffers(input_path, "pre", drv.to_device) + post = load_buffers(input_path, "post", lambda x: x) + kernel = module.get_function(kernel_launch['name']) + grid = (kernel_launch['parameters']['gridDimX'], kernel_launch['parameters']['gridDimY'], + kernel_launch['parameters']['gridDimZ']) + block = (kernel_launch['parameters']['blockDimX'], kernel_launch['parameters']['blockDimY'], + kernel_launch['parameters']['blockDimZ']) + shared = kernel_launch['parameters']['sharedMemBytes'] + for (texref_name, texref_details) in kernel_launch['texrefs'].items(): + texref = module.get_texref(texref_name) + texref.set_format(drv.array_format(texref_details['format']), texref_details['num_channels']) + texref.set_address_mode(0, drv.address_mode(texref_details['address_mode'][0])) + texref.set_address_mode(1, drv.address_mode(texref_details['address_mode'][1])) + texref.set_flags(texref_details['flags']) + # other setters are not implemented by pycuda + texref_set_data(kernel_launch, pre, texref, texref_details) + for (global_name, global_details) in kernel_launch['globals'].items(): + global_copy_data(module, pre, global_name, global_details) + explicit_args = [] + start = 0 + for explicit_arg in kernel_launch['explicit_arguments']: + value = bytearray(explicit_arg['data']['ptr']) + size = explicit_arg['data']['layout']['size'] + align = explicit_arg['data']['layout']['align'] + for buffer_use in explicit_arg['buffers']: + arg_offset = buffer_use['offset_into_argument'] + buff_offset = buffer_use['buffer']['offset_into_buffer'] + if buff_offset != 0: + raise NotImplementedError + buff_key = buffer_use['buffer']['buffer_key'] + new_devptr = int(pre[str(buff_key)][0]).to_bytes(8, sys.byteorder) + value[arg_offset:arg_offset + len(new_devptr)] = new_devptr + pass + start += insert_padding(value, start, align) + start += size + explicit_args.append(np.frombuffer(value, dtype=np.uint8)) + kernel(*explicit_args, grid=grid, block=block, shared=shared) + cu_autoinit.context.synchronize() + for (buffer_name, (expected_buffer, _)) in post.items(): + device_buffer = pre[buffer_name] + host_buffer = drv.from_device(device_buffer[0], (device_buffer[1],), np.uint8) + expected_buffer_np = np.frombuffer(expected_buffer, dtype=np.uint8) + #host_buffer = np.frombuffer(host_buffer, dtype=np.single) + #expected_buffer_np = np.frombuffer(expected_buffer_np, dtype=np.single) try: - assert_array_equal_override(kernel_name, idx, pre_arg, post_arg) + np.testing.assert_array_equal(expected_buffer_np, host_buffer) except Exception as e: - print(f"{idx}: {e}") + print(f"{buffer_name}: {e}") + #np.save("f:\\temp\\buffer", host_buffer) def main(argv): device = drv.Device(0) - max_threads = device.get_attribute(drv.device_attribute.MAX_THREADS_PER_BLOCK) print(device.name()) input_path = argv[1] - if os.path.exists(path.join(input_path, "launch.txt")): - verify_single_dump(input_path, max_threads) + if os.path.exists(path.join(input_path, "kernel_launch.json")): + verify_single_dump(input_path) else: for input_subdir in sorted([path.join(input_path, dir_name) for dir_name in os.listdir(input_path)]): - verify_single_dump(input_subdir, max_threads) + if os.path.isdir(input_subdir): + verify_single_dump(input_subdir) if __name__ == "__main__": diff --git a/zluda_dump/src/side_by_side.rs b/zluda_dump/src/side_by_side.rs new file mode 100644 index 0000000..6ff29f1 --- /dev/null +++ b/zluda_dump/src/side_by_side.rs @@ -0,0 +1,1297 @@ +// Side-by-side really does three complex operations: +// * Copy unstructured CUDA arguments to structured host representation. In +// practice, it means inspecting arguments to cuKernelLaunch(...) - firstly +// copying all explicit arguments to the kernel, secondly copying all texrefs +// * Copy structured host representation to structured device representation. +// This device representation is in the "space" of a different CUDA driver +// * Copy explicit device representation to structured host representation. +// It suffices to only copy explicit arguments, texrefs are read-only + +use crate::cuda_call; +use crate::log::LogEntry; +use crate::trace::serialize_array_format; +use crate::trace::DumpWriter; +use crate::trace::KernelLaunchParams; +use crate::trace::RecordedFunction; +use crate::trace::TexrefAddress; +use crate::try_get_cuda_function; +use crate::CudaDynamicFns; +use crate::{log, trace}; +use cuda_types::*; +use regex::bytes::Regex; +use serde::ser::SerializeMap; +use serde::ser::SerializeSeq; +use serde::ser::SerializeStruct; +use serde::Serialize; +use serde::Serializer; +use std::alloc::Layout; +use std::borrow::Cow; +use std::cmp; +use std::collections::hash_map; +use std::collections::HashMap; +use std::ffi::CStr; +use std::ffi::CString; +use std::mem; +use std::ops::Deref; +use std::os::raw::c_void; +use std::ptr; +use std::ptr::NonNull; + +// This struct encapsulates all mutable state of side-by-side CUDA driver +pub(crate) struct SideBySide { + skip_kernel: Option, + dump_threshold: Option, + // Side-by-side function table + fn_table: CudaDynamicFns, + // maps underlying CUDA modules to side-by-side CUDA modules + modules: HashMap, + // maps underlying CUDA functions to side-by-side CUDA functions + functions: HashMap, + context: CUcontext, +} + +impl SideBySide { + pub(crate) fn new( + fn_table: CudaDynamicFns, + fn_logger: &mut log::FunctionLogger, + skip_kernel: Option<&String>, + side_by_side_dump_threshold: Option, + ) -> Option { + let maybe_error = Self::new_impl( + fn_table, + fn_logger, + skip_kernel, + side_by_side_dump_threshold, + ); + fn_logger.log_unwrap(maybe_error) + } + + fn new_impl( + mut fn_table: CudaDynamicFns, + fn_logger: &mut log::FunctionLogger, + skip_kernel: Option<&String>, + side_by_side_dump_threshold: Option, + ) -> Result { + cuda_call!(fn_table.cuInit(0)); + let mut context = ptr::null_mut(); + cuda_call!(fn_table.cuCtxCreate_v2(&mut context, 0, CUdevice_v1(0))); + cuda_call!(fn_table.cuCtxPopCurrent_v2(&mut context)); + let mut name = vec![0i8; 256]; + cuda_call!(fn_table.cuDeviceGetName(name.as_mut_ptr(), name.len() as i32, CUdevice_v1(0))); + fn_logger.log(LogEntry::SideBySideStart( + unsafe { CStr::from_ptr(name.as_ptr()) }.to_owned(), + )); + let skip_kernel = skip_kernel.map(|text| Regex::new(&text).unwrap()); + Ok(Self { + skip_kernel, + dump_threshold: side_by_side_dump_threshold, + fn_table, + context, + modules: HashMap::new(), + functions: HashMap::new(), + }) + } + + pub(crate) fn get_module_and_function( + &mut self, + original_module: CUmodule, + original_func: CUfunction, + original_func_name: &str, + original_func_text: &str, + ) -> Result<(CUmodule, CUfunction), LogEntry> { + let mapped_module = match self.modules.entry(original_module) { + hash_map::Entry::Occupied(entry) => *entry.get(), + hash_map::Entry::Vacant(entry) => { + let mut cu_module = ptr::null_mut(); + let libcuda = &mut self.fn_table; + cuda_call!( + libcuda.cuModuleLoadData(&mut cu_module, original_func_text.as_ptr() as _) + ); + *entry.insert(cu_module) + } + }; + Ok(match self.functions.entry(original_func) { + hash_map::Entry::Occupied(entry) => (mapped_module, *entry.get()), + hash_map::Entry::Vacant(entry) => { + let mut cu_func = ptr::null_mut(); + let mut name = original_func_name.to_string(); + name.push('\0'); + let libcuda = &mut self.fn_table; + cuda_call!(libcuda.cuModuleGetFunction( + &mut cu_func, + mapped_module, + name.as_ptr() as _ + )); + (mapped_module, *entry.insert(cu_func)) + } + }) + } + + fn activate_context(&mut self) -> Result { + SideBySideContext::new(self) + } +} + +#[allow(non_snake_case)] +struct SideBySideContext { + cuCtxPopCurrent_v2: extern "system" fn(*mut CUcontext) -> CUresult, +} + +impl SideBySideContext { + #[allow(non_snake_case)] + fn new(sbs: &mut SideBySide) -> Result { + let context = sbs.context; + let fn_table = &mut sbs.fn_table; + cuda_call!(fn_table.cuCtxPushCurrent(context)); + let cuCtxPopCurrent_v2 = try_get_cuda_function!(fn_table, cuCtxPopCurrent_v2)?; + Ok(Self { cuCtxPopCurrent_v2 }) + } +} + +#[allow(unused_must_use)] +impl Drop for SideBySideContext { + fn drop(&mut self) { + let mut _unused = ptr::null_mut(); + (self.cuCtxPopCurrent_v2)(&mut _unused); + } +} + +pub(crate) unsafe fn pre_kernel_launch( + libcuda: &mut CudaDynamicFns, + state: &mut trace::StateTracker, + side_by_side: &mut Option, + fn_logger: &mut log::FunctionLogger, + f: CUfunction, + stream: CUstream, + kernel_params: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, +) -> Option { + let side_by_side = side_by_side.as_ref()?; + let recorded_fn = if let Some(parsed_fn) = state.functions.get(&f) { + parsed_fn + } else { + fn_logger.log(LogEntry::UnknownFunctionUse(f)); + return None; + }; + if let Some(ref skip_filter) = side_by_side.skip_kernel { + if skip_filter.is_match(recorded_fn.name.as_bytes()) { + return None; + } + } + let parsed_fn = recorded_fn.parsed.as_ref()?; + let texrefs = fn_logger.log_unwrap(state.get_texrefs(recorded_fn.module))?; + let globals = fn_logger.log_unwrap(state.get_globals(recorded_fn.module))?; + fn_logger.log_unwrap(synchronize(libcuda))?; + save_kernel_arguments( + libcuda, + fn_logger, + stream, + recorded_fn.module, + texrefs, + globals, + &parsed_fn.explicit_arguments, + kernel_params, + extra, + ) +} + +unsafe fn save_kernel_arguments<'a>( + libcuda: &mut CudaDynamicFns, + fn_logger: &mut log::FunctionLogger, + stream: CUstream, + module: CUmodule, + get_texrefs: impl Iterator, + get_globals: impl Iterator, + args_layout: &[Layout], + kernel_params: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, +) -> Option { + let mut memory_allocations = HostMemoryAllocations::new(); + if extra == ptr::null_mut() { + let explicit_arguments = if kernel_params == ptr::null_mut() { + Vec::new() + } else { + fn_logger.log_unwrap( + args_layout + .iter() + .enumerate() + .map(|(index, arg_layout)| { + let raw_argument = *kernel_params.add(index); + ExplicitArgument::new( + libcuda, + stream, + &mut memory_allocations, + *arg_layout, + raw_argument, + ) + }) + .collect::, _>>(), + )? + }; + let images = fn_logger.log_unwrap( + get_texrefs + .map(|(texref_name, texref, address)| { + TexrefDetails::new( + libcuda, + stream, + texref_name, + texref, + address, + &mut memory_allocations, + ) + }) + .collect::, _>>(), + )?; + let globals = fn_logger.log_unwrap( + get_globals + .map(|(name, devptr)| { + Ok(( + name.to_owned(), + memory_allocations.alloc_global(libcuda, stream, module, name, devptr)?, + )) + }) + .collect::, _>>(), + )?; + Some(HostArguments { + explicit_arguments, + texrefs: images, + globals, + memory_allocations, + }) + } else { + unimplemented!() + } +} + +fn synchronize(libcuda: &mut CudaDynamicFns) -> Result<(), LogEntry> { + cuda_call!(libcuda.cuStreamSynchronize(ptr::null_mut())); + Ok(()) +} + +pub(crate) struct HostMemoryAllocations(pub(crate) HashMap<*mut c_void, HostBuffer>); + +pub(crate) enum HostBuffer { + Linear { + data: Vec, + }, + Array { + data: Vec, + descriptor: CUDA_ARRAY3D_DESCRIPTOR, + }, +} + +impl HostBuffer { + pub(crate) fn data(&self) -> &[u8] { + match self { + HostBuffer::Linear { data } => data, + HostBuffer::Array { data, .. } => data, + } + } + pub(crate) fn array_descriptor(&self) -> Option<&CUDA_ARRAY3D_DESCRIPTOR> { + match self { + HostBuffer::Linear { .. } => None, + HostBuffer::Array { descriptor, .. } => Some(descriptor), + } + } +} + +impl HostMemoryAllocations { + fn new() -> Self { + Self(HashMap::new()) + } + + fn try_alloc( + &mut self, + libcuda: &mut CudaDynamicFns, + stream: CUstream, + devptr: CUdeviceptr, + ) -> Result, LogEntry> { + Ok(get_address_range(libcuda, devptr)? + .map(|(start, size)| { + match self.0.entry(start.0) { + hash_map::Entry::Occupied(_) => {} + hash_map::Entry::Vacant(entry) => { + let fake_buffer = DeviceBuffer::Linear { + data: start, + size, + cuMemFree_v2: dont_drop_device_memory, + }; + let buffer = BufferRef::copy(libcuda, stream, &fake_buffer)?; + entry.insert(HostBuffer::Linear { data: buffer }); + } + }; + let offset = unsafe { devptr.0.offset_from(start.0) as usize }; + Ok::<_, LogEntry>(BufferRef { + offset_into_buffer: offset, + buffer_key: start.0, + }) + }) + .transpose()?) + } + + fn alloc_texref( + &mut self, + libcuda: &mut CudaDynamicFns, + stream: CUstream, + address: &TexrefAddress, + ) -> Result { + match address { + TexrefAddress::OneD { pointer, .. } | TexrefAddress::TwoD { pointer, .. } => self + .try_alloc(libcuda, stream, *pointer) + .transpose() + .unwrap(), + TexrefAddress::Array { array, .. } => { + let array: CUarray = *array; + match self.0.entry(array as _) { + hash_map::Entry::Occupied(_) => {} + hash_map::Entry::Vacant(entry) => { + let mut descriptor = unsafe { mem::zeroed::() }; + cuda_call!(libcuda.cuArray3DGetDescriptor_v2(&mut descriptor, array)); + let fake_array = DeviceBuffer::Array { + array, + cuArrayDestroy: dont_drop_array, + descriptor, + }; + let buffer = BufferRef::copy(libcuda, stream, &fake_array)?; + entry.insert(HostBuffer::Array { + data: buffer, + descriptor: descriptor, + }); + } + } + Ok(BufferRef { + buffer_key: array as _, + offset_into_buffer: 0, + }) + } + } + } + + fn alloc_global( + &mut self, + libcuda: &mut CudaDynamicFns, + stream: CUstream, + module: CUmodule, + name: &CStr, + devptr: CUdeviceptr_v2, + ) -> Result { + let mut ptr = unsafe { mem::zeroed() }; + let mut size = unsafe { mem::zeroed() }; + cuda_call!(libcuda.cuModuleGetGlobal_v2(&mut ptr, &mut size, module, name.as_ptr())); + if devptr != ptr { + unreachable!() + } + let fake_buffer = DeviceBuffer::Linear { + data: ptr, + size, + cuMemFree_v2: dont_drop_device_memory, + }; + let buffer = BufferRef::copy(libcuda, stream, &fake_buffer)?; + self.0.insert(ptr.0, HostBuffer::Linear { data: buffer }); + Ok(BufferRef { + buffer_key: ptr.0, + offset_into_buffer: 0, + }) + } +} + +extern "system" fn dont_drop_device_memory(_ptr: CUdeviceptr_v2) -> CUresult { + CUresult::CUDA_SUCCESS +} + +extern "system" fn dont_drop_array(_array: CUarray) -> CUresult { + CUresult::CUDA_SUCCESS +} + +#[derive(Serialize)] +pub(crate) struct HostArguments { + explicit_arguments: Vec, + #[serde(serialize_with = "serialize_hashmap_cstring")] + texrefs: HashMap, + #[serde(serialize_with = "serialize_hashmap_cstring")] + globals: HashMap, + #[serde(skip)] + pub(crate) memory_allocations: HostMemoryAllocations, +} + +fn serialize_hashmap_cstring( + m: &HashMap, + serializer: S, +) -> Result +where + S: Serializer, + V: Serialize, +{ + let mut map = serializer.serialize_map(Some(m.len()))?; + for (k, v) in m { + map.serialize_entry(&k.to_string_lossy(), v)?; + } + map.end() +} + +// This struct represents a host-side dump of a single kernel argument +// Every argument is a byte array with certain layout requirements. +// The byte array can contain pointers to buffers, which we try to identify and +// extract +#[derive(Clone, Serialize)] +pub(crate) struct ExplicitArgument { + buffers: Vec, + data: AlignedBuffer, +} + +impl ExplicitArgument { + unsafe fn new( + libcuda: &mut CudaDynamicFns, + stream: CUstream, + unique_buffers: &mut HostMemoryAllocations, + layout: Layout, + raw_data: *mut c_void, + ) -> Result { + let data = AlignedBuffer::new(layout, raw_data); + let buffers = std::iter::successors(Some(0), |x| Some(x + mem::size_of::())) + .take_while(|offset| offset + mem::size_of::() <= layout.size()) + .filter_map(|potential_pointer_offset| { + ExplicitArgumentBuffer::try_new( + libcuda, + stream, + unique_buffers, + raw_data, + potential_pointer_offset, + ) + .transpose() + }) + .collect::, _>>()?; + Ok(Self { data, buffers }) + } + + fn as_ptr(&self) -> *mut c_void { + self.data.ptr.as_ptr() as _ + } +} + +#[derive(Clone, Serialize)] +struct ExplicitArgumentBuffer { + offset_into_argument: usize, + buffer: BufferRef, +} + +impl ExplicitArgumentBuffer { + unsafe fn try_new( + libcuda: &mut CudaDynamicFns, + stream: CUstream, + unique_buffers: &mut HostMemoryAllocations, + data: *mut c_void, + offset: usize, + ) -> Result, LogEntry> { + let devptr = *(data.add(offset) as *mut CUdeviceptr_v2); + Ok(unique_buffers + .try_alloc(libcuda, stream, devptr)? + .map(|buffer| Self { + buffer, + offset_into_argument: offset, + })) + } +} + +#[derive(Clone, Serialize)] +struct BufferRef { + offset_into_buffer: usize, + #[serde(serialize_with = "serialize_mut_ptr")] + buffer_key: *mut c_void, +} + +fn serialize_mut_ptr(x: &*mut T, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_u64(*x as usize as u64) +} + +impl BufferRef { + fn copy( + libcuda: &mut CudaDynamicFns, + stream: CUstream, + buffer: &DeviceBuffer, + ) -> Result, LogEntry> { + match buffer { + DeviceBuffer::Linear { data, size, .. } => { + let mut buffer = vec![0u8; *size]; + cuda_call!(libcuda.cuMemcpyDtoHAsync_v2( + buffer.as_mut_ptr() as _, + *data, + *size, + stream + )); + Ok(buffer) + } + DeviceBuffer::Array { + array, descriptor, .. + } => { + let mut buffer = vec![0u8; array_buffer_size(descriptor)]; + if descriptor.Height == 0 && descriptor.Depth == 0 { + cuda_call!(libcuda.cuMemcpyAtoH_v2( + buffer.as_mut_ptr() as _, + *array, + 0, + buffer.len() + )); + } else { + let mut memcpy_descriptor = unsafe { mem::zeroed::() }; + set_memcpy(&mut memcpy_descriptor, descriptor); + memcpy_descriptor.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_descriptor.srcArray = *array; + memcpy_descriptor.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_descriptor.dstHost = buffer.as_mut_ptr() as _; + memcpy_descriptor.dstPitch = memcpy_descriptor.WidthInBytes; + memcpy_descriptor.dstHeight = memcpy_descriptor.Height; + cuda_call!(libcuda.cuMemcpy3D_v2(&memcpy_descriptor)); + } + Ok(buffer) + } + } + } +} + +fn set_memcpy(memcpy_descriptor: &mut CUDA_MEMCPY3D, descriptor: &CUDA_ARRAY3D_DESCRIPTOR) { + memcpy_descriptor.WidthInBytes = + channel_size(descriptor.Format) * descriptor.NumChannels as usize * descriptor.Width; + memcpy_descriptor.Height = cmp::max(descriptor.Height, 1); + memcpy_descriptor.Depth = cmp::max(descriptor.Depth, 1); +} + +fn array_buffer_size(descriptor: &CUDA_ARRAY3D_DESCRIPTOR) -> usize { + descriptor.Width + * cmp::max(descriptor.Height, 1) + * cmp::max(descriptor.Depth, 1) + * descriptor.NumChannels as usize + * channel_size(descriptor.Format) +} + +fn channel_size(format: CUarray_format) -> usize { + match format { + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT8 | CUarray_format::CU_AD_FORMAT_SIGNED_INT8 => 1, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT16 + | CUarray_format::CU_AD_FORMAT_HALF => 2, + CUarray_format::CU_AD_FORMAT_UNSIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_SIGNED_INT32 + | CUarray_format::CU_AD_FORMAT_FLOAT => 4, + _ => unimplemented!(), + } +} + +fn get_address_range( + libcuda: &mut CudaDynamicFns, + devptr: CUdeviceptr, +) -> Result, LogEntry> { + let mut start = CUdeviceptr_v2(ptr::null_mut()); + let mut size = 0usize; + match libcuda.cuMemGetAddressRange_v2(&mut start, &mut size, devptr) { + Some(cuda_types::CUresult::CUDA_SUCCESS) => Ok(Some((start, size))), + Some(_) => return Ok(None), + None => { + return Err(LogEntry::NoCudaFunction(Cow::Borrowed( + "cuMemGetAddressRange_v2", + ))) + } + } +} + +#[derive(Serialize, Clone)] +struct TexrefDetails { + address: TexrefAddress, + allocation: BufferRef, + #[serde(serialize_with = "serialize_address_mode")] + address_mode: [CUaddress_mode; 3usize], + #[serde(serialize_with = "serialize_filter_mode")] + filter_mode: CUfilter_mode, + flags: ::std::os::raw::c_uint, + #[serde(serialize_with = "serialize_filter_mode")] + mipmap_filter_mode: CUfilter_mode, + mipmap_level_bias: f32, + min_mipmap_level_clamp: f32, + max_mipmap_level_clamp: f32, + max_anisotropy: i32, + #[serde(serialize_with = "serialize_array_format")] + format: CUarray_format, + num_channels: i32, +} + +fn serialize_address_mode( + address_mode: &[CUaddress_mode; 3usize], + serializer: S, +) -> Result +where + S: Serializer, +{ + let mut slice = serializer.serialize_seq(Some(3))?; + slice.serialize_element(&address_mode[0].0)?; + slice.serialize_element(&address_mode[1].0)?; + slice.serialize_element(&address_mode[2].0)?; + slice.end() +} + +fn serialize_filter_mode(filter_mode: &CUfilter_mode, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_i32(filter_mode.0) +} + +impl TexrefDetails { + unsafe fn new( + libcuda: &mut CudaDynamicFns, + stream: CUstream, + name: &CStr, + texref: CUtexref, + address: TexrefAddress, + unique_buffers: &mut HostMemoryAllocations, + ) -> Result<(CString, Self), LogEntry> { + let allocation = unique_buffers.alloc_texref(libcuda, stream, &address)?; + let mut address_mode = [CUaddress_mode(0); 3]; + cuda_call!(libcuda.cuTexRefGetAddressMode(&mut address_mode[0], texref, 0)); + cuda_call!(libcuda.cuTexRefGetAddressMode(&mut address_mode[1], texref, 1)); + let mut filter_mode = mem::zeroed(); + cuda_call!(libcuda.cuTexRefGetFilterMode(&mut filter_mode, texref)); + let mut flags = 0u32; + cuda_call!(libcuda.cuTexRefGetFlags(&mut flags, texref)); + let mut mipmap_filter_mode = mem::zeroed(); + cuda_call!(libcuda.cuTexRefGetMipmapFilterMode(&mut mipmap_filter_mode, texref)); + let mut mipmap_level_bias = 0.0; + cuda_call!(libcuda.cuTexRefGetMipmapLevelBias(&mut mipmap_level_bias, texref)); + let mut min_mipmap_level_clamp = 0.0; + let mut max_mipmap_level_clamp = 0.0; + cuda_call!(libcuda.cuTexRefGetMipmapLevelClamp( + &mut min_mipmap_level_clamp, + &mut max_mipmap_level_clamp, + texref + )); + let mut format = mem::zeroed(); + let mut num_channels = 0; + cuda_call!(libcuda.cuTexRefGetFormat(&mut format, &mut num_channels, texref)); + let mut max_anisotropy = 0; + cuda_call!(libcuda.cuTexRefGetMaxAnisotropy(&mut max_anisotropy, texref)); + Ok(( + name.to_owned(), + TexrefDetails { + address, + allocation, + address_mode, + filter_mode, + flags, + mipmap_filter_mode, + mipmap_level_bias, + min_mipmap_level_clamp, + max_mipmap_level_clamp, + max_anisotropy, + format, + num_channels, + }, + )) + } +} + +struct AlignedBuffer { + layout: Layout, + ptr: NonNull, +} + +impl AlignedBuffer { + fn new(layout: Layout, data: *mut c_void) -> Self { + let ptr = unsafe { std::alloc::alloc(layout) }; + unsafe { std::ptr::copy_nonoverlapping::(data as _, ptr, layout.size()) }; + let ptr = NonNull::new(ptr).unwrap(); + Self { layout, ptr } + } +} + +impl Clone for AlignedBuffer { + fn clone(&self) -> Self { + Self::new(self.layout, self.ptr.as_ptr() as _) + } +} + +impl Deref for AlignedBuffer { + type Target = [u8]; + + fn deref<'a>(&'a self) -> &'a Self::Target { + unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.layout.size()) } + } +} + +impl Drop for AlignedBuffer { + fn drop(&mut self) { + unsafe { std::alloc::dealloc(self.ptr.as_ptr(), self.layout) } + } +} + +impl Serialize for AlignedBuffer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut struct_ = serializer.serialize_struct("AlignedBuffer", 2)?; + struct_.serialize_field( + "layout", + &LayoutSerialized { + size: self.layout.size(), + align: self.layout.align(), + }, + )?; + struct_.serialize_field("ptr", self.deref())?; + struct_.end() + } +} + +#[derive(Serialize)] +#[serde(rename = "Layout")] +struct LayoutSerialized { + size: usize, + align: usize, +} + +pub(crate) unsafe fn post_kernel_launch( + libcuda: &mut CudaDynamicFns, + state: &mut trace::StateTracker, + side_by_side: &mut Option, + fn_logger: &mut log::FunctionLogger, + pre_kernel_args: Option, + f: CUfunction, + grid_dim_x: ::std::os::raw::c_uint, + grid_dim_y: ::std::os::raw::c_uint, + grid_dim_z: ::std::os::raw::c_uint, + block_dim_x: ::std::os::raw::c_uint, + block_dim_y: ::std::os::raw::c_uint, + block_dim_z: ::std::os::raw::c_uint, + shared_mem_bytes: ::std::os::raw::c_uint, + stream: CUstream, + kernel_params: *mut *mut ::std::os::raw::c_void, + extra: *mut *mut ::std::os::raw::c_void, +) -> Option<()> { + let pre_args = &pre_kernel_args?; + let side_by_side = side_by_side.as_mut()?; + let recorded_fn = if let Some(parsed_fn) = state.functions.get(&f) { + parsed_fn + } else { + fn_logger.log(LogEntry::UnknownFunctionUse(f)); + return None; + }; + let parsed_fn = recorded_fn.parsed.as_ref()?; + let texrefs = fn_logger.log_unwrap(state.get_texrefs(recorded_fn.module))?; + let globals = fn_logger.log_unwrap(state.get_globals(recorded_fn.module))?; + fn_logger.log_unwrap(synchronize(libcuda))?; + let post_kernel_args_original = save_kernel_arguments( + libcuda, + fn_logger, + stream, + recorded_fn.module, + texrefs, + globals, + &parsed_fn.explicit_arguments, + kernel_params, + extra, + )?; + let _ctx = fn_logger.log_unwrap(side_by_side.activate_context())?; + let post_kernel_args_side_by_side = launch_kernel_and_get_results( + side_by_side, + recorded_fn, + fn_logger, + pre_args, + f, + grid_dim_x, + grid_dim_y, + grid_dim_z, + block_dim_x, + block_dim_y, + block_dim_z, + shared_mem_bytes, + )?; + let launch_params = KernelLaunchParams { + gridDimX: grid_dim_x, + gridDimY: grid_dim_y, + gridDimZ: grid_dim_z, + blockDimX: block_dim_x, + blockDimY: block_dim_y, + blockDimZ: block_dim_z, + sharedMemBytes: shared_mem_bytes, + }; + if parsed_fn.text.len() != 1 { + todo!("Linking not implemented"); + } + compare_and_notify_if_mismatch( + fn_logger, + &recorded_fn.name, + &state.writer, + &post_kernel_args_original, + &post_kernel_args_side_by_side, + side_by_side.dump_threshold, + &parsed_fn.text[0], + pre_args, + launch_params, + ); + Some(()) +} + +fn launch_kernel_and_get_results( + side_by_side: &mut SideBySide, + recorded_fn: &RecordedFunction, + fn_logger: &mut log::FunctionLogger, + host_args: &HostArguments, + original_func: CUfunction, + grid_dim_x: ::std::os::raw::c_uint, + grid_dim_y: ::std::os::raw::c_uint, + grid_dim_z: ::std::os::raw::c_uint, + block_dim_x: ::std::os::raw::c_uint, + block_dim_y: ::std::os::raw::c_uint, + block_dim_z: ::std::os::raw::c_uint, + shared_mem_bytes: ::std::os::raw::c_uint, +) -> Option>> { + let parsed_fn = recorded_fn.parsed.as_ref()?; + if parsed_fn.text.len() != 1 { + todo!("Linking not implemented"); + } + let (side_by_side_module, side_by_side_func) = + fn_logger.log_unwrap(side_by_side.get_module_and_function( + recorded_fn.module, + original_func, + &recorded_fn.name, + &parsed_fn.text[0], + ))?; + let side_by_side_fn_table = &mut side_by_side.fn_table; + let device_arguments = + fn_logger.log_unwrap(DeviceArguments::new(side_by_side_fn_table, &host_args))?; + fn_logger + .log_unwrap(device_arguments.bind_globals(side_by_side_fn_table, side_by_side_module))?; + let mut kernel_params = fn_logger.log_unwrap( + device_arguments.bind_texrefs_get_arguments(side_by_side_fn_table, side_by_side_module), + )?; + fn_logger.log_unwrap(launch_kernel( + side_by_side_fn_table, + side_by_side_func, + grid_dim_x, + grid_dim_y, + grid_dim_z, + block_dim_x, + block_dim_y, + block_dim_z, + shared_mem_bytes, + &mut kernel_params, + ))?; + fn_logger.log_unwrap( + device_arguments.copy_allocations_to_host(side_by_side_fn_table, ptr::null_mut()), + ) +} + +struct DeviceArguments { + explicit_arguments: Vec, + texrefs: HashMap, + globals: HashMap, + memory_allocations: HashMap<*mut c_void, DeviceBuffer>, +} + +impl DeviceArguments { + fn new(libcuda: &mut CudaDynamicFns, host: &HostArguments) -> Result { + let memory_allocations = host + .memory_allocations + .0 + .iter() + .map(|(key, buff)| Ok((key.clone(), DeviceBuffer::new(libcuda, buff)?))) + .collect::>()?; + let mut explicit_arguments = host.explicit_arguments.clone(); + Self::adjust_device_pointers(&mut explicit_arguments, &memory_allocations); + let texrefs = host.texrefs.clone(); + let globals = host.globals.clone(); + Ok(DeviceArguments { + explicit_arguments, + texrefs, + globals, + memory_allocations, + }) + } + + fn adjust_device_pointers( + explicit_arguments: &mut Vec, + memory_allocations: &HashMap<*mut c_void, DeviceBuffer>, + ) { + for arg in explicit_arguments.iter_mut() { + for buffer in &arg.buffers { + match &memory_allocations[&buffer.buffer.buffer_key] { + DeviceBuffer::Linear { data, .. } => { + let start = *data; + let actual_ptr = CUdeviceptr_v2(unsafe { + start.0.add(buffer.buffer.offset_into_buffer) + }); + unsafe { + std::ptr::write::( + arg.data.ptr.as_ptr().add(buffer.offset_into_argument) as _, + actual_ptr, + ) + }; + } + DeviceBuffer::Array { .. } => unimplemented!(), + } + } + } + } + + fn bind_texrefs_get_arguments( + &self, + libcuda: &mut CudaDynamicFns, + module: CUmodule, + ) -> Result, LogEntry> { + for (name, texref_details) in self.texrefs.iter() { + unsafe { + Self::bind_texref( + libcuda, + module, + name, + texref_details, + &self.memory_allocations, + )? + }; + } + Ok(self + .explicit_arguments + .iter() + .map(|arg| arg.as_ptr()) + .collect::>()) + } + + fn bind_globals(&self, libcuda: &mut CudaDynamicFns, module: CUmodule) -> Result<(), LogEntry> { + for (name, buffer_ref) in self.globals.iter() { + let mut device_ptr = unsafe { mem::zeroed() }; + let mut size = 0; + cuda_call!(libcuda.cuModuleGetGlobal_v2( + &mut device_ptr, + &mut size, + module, + name.as_ptr() + )); + let buffer = self.memory_allocations.get(&buffer_ref.buffer_key).unwrap(); + if let DeviceBuffer::Linear { data, .. } = buffer { + let src = CUdeviceptr_v2(unsafe { data.0.add(buffer_ref.offset_into_buffer) }); + cuda_call!(libcuda.cuMemcpyDtoD_v2(device_ptr, src, size)); + } else { + unreachable!() + } + } + Ok(()) + } + + unsafe fn bind_texref( + libcuda: &mut CudaDynamicFns, + module: CUmodule, + name: &CStr, + texref_details: &TexrefDetails, + device_allocations: &HashMap<*mut c_void, DeviceBuffer>, + ) -> Result<(), LogEntry> { + let mut texref = ptr::null_mut(); + cuda_call!(libcuda.cuModuleGetTexRef(&mut texref, module, name.as_ptr())); + let dev_buffer = device_allocations + .get(&texref_details.allocation.buffer_key) + .unwrap(); + cuda_call!(libcuda.cuTexRefSetFormat( + texref, + texref_details.format, + texref_details.num_channels as i32 + )); + cuda_call!(libcuda.cuTexRefSetAddressMode(texref, 0, texref_details.address_mode[0])); + cuda_call!(libcuda.cuTexRefSetAddressMode(texref, 1, texref_details.address_mode[1])); + cuda_call!(libcuda.cuTexRefSetFilterMode(texref, texref_details.filter_mode)); + cuda_call!(libcuda.cuTexRefSetFlags(texref, texref_details.flags)); + cuda_call!(libcuda.cuTexRefSetMipmapFilterMode(texref, texref_details.mipmap_filter_mode)); + cuda_call!(libcuda.cuTexRefSetMipmapLevelBias(texref, texref_details.mipmap_level_bias)); + cuda_call!(libcuda.cuTexRefSetMipmapLevelClamp( + texref, + texref_details.min_mipmap_level_clamp, + texref_details.max_mipmap_level_clamp + )); + cuda_call!(libcuda.cuTexRefSetMaxAnisotropy(texref, texref_details.max_anisotropy as u32)); + match (dev_buffer, texref_details.address) { + (DeviceBuffer::Linear { data, .. }, TexrefAddress::OneD { bytes, .. }) => { + let devptr = + CUdeviceptr_v2(data.0.add(texref_details.allocation.offset_into_buffer)); + cuda_call!(libcuda.cuTexRefSetAddress_v2(ptr::null_mut(), texref, devptr, bytes)); + } + ( + DeviceBuffer::Linear { data, .. }, + TexrefAddress::TwoD { + width, + height, + format, + channels, + pitch, + .. + }, + ) => { + let devptr = + CUdeviceptr_v2(data.0.add(texref_details.allocation.offset_into_buffer)); + cuda_call!(libcuda.cuTexRefSetAddress2D_v3( + texref, + &CUDA_ARRAY_DESCRIPTOR { + Width: width, + Height: height, + Format: format, + NumChannels: channels, + }, + devptr, + pitch + )); + } + (DeviceBuffer::Array { array, .. }, TexrefAddress::Array { flags, .. }) => { + cuda_call!(libcuda.cuTexRefSetArray(texref, *array, flags)); + } + _ => unreachable!(), + } + Ok(()) + } + + fn copy_allocations_to_host( + &self, + libcuda: &mut CudaDynamicFns, + stream: CUstream, + ) -> Result>, LogEntry> { + self.memory_allocations + .iter() + .map(|(key, buffer)| Ok((*key, BufferRef::copy(libcuda, stream, buffer)?))) + .collect::, LogEntry>>() + } +} + +#[allow(non_snake_case)] +pub(crate) enum DeviceBuffer { + Linear { + data: CUdeviceptr_v2, + size: usize, + cuMemFree_v2: extern "system" fn(CUdeviceptr_v2) -> CUresult, + }, + Array { + array: CUarray, + descriptor: CUDA_ARRAY3D_DESCRIPTOR, + cuArrayDestroy: extern "system" fn(CUarray) -> CUresult, + }, +} + +impl DeviceBuffer { + #[allow(non_snake_case)] + fn new(libcuda: &mut CudaDynamicFns, host: &HostBuffer) -> Result { + match host { + HostBuffer::Linear { data: host_data } => { + let cuMemFree_v2 = try_get_cuda_function!(libcuda, cuMemFree_v2)?; + let mut data = CUdeviceptr_v2(ptr::null_mut()); + cuda_call!(libcuda.cuMemAlloc_v2(&mut data, host_data.len())); + let result = DeviceBuffer::Linear { + data, + size: host_data.len(), + cuMemFree_v2, + }; + cuda_call!(libcuda.cuMemcpyHtoD_v2(data, host_data.as_ptr() as _, host_data.len())); + Ok(result) + } + HostBuffer::Array { data, descriptor } => { + let cuArrayDestroy = try_get_cuda_function!(libcuda, cuArrayDestroy)?; + let mut array = unsafe { mem::zeroed::() }; + cuda_call!(libcuda.cuArray3DCreate_v2(&mut array, descriptor)); + let result = DeviceBuffer::Array { + array: array, + descriptor: *descriptor, + cuArrayDestroy, + }; + if descriptor.Height == 0 && descriptor.Depth == 0 { + cuda_call!(libcuda.cuMemcpyHtoA_v2(array, 0, data.as_ptr() as _, data.len())); + } else { + let mut memcpy_descriptor = unsafe { mem::zeroed::() }; + set_memcpy(&mut memcpy_descriptor, descriptor); + memcpy_descriptor.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_HOST; + memcpy_descriptor.srcHost = data.as_ptr() as _; + memcpy_descriptor.srcPitch = memcpy_descriptor.WidthInBytes; + memcpy_descriptor.srcHeight = memcpy_descriptor.Height; + memcpy_descriptor.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY; + memcpy_descriptor.dstArray = array; + cuda_call!(libcuda.cuMemcpy3D_v2(&memcpy_descriptor)); + } + Ok(result) + } + } + } +} + +impl Drop for DeviceBuffer { + #[allow(unused_must_use)] + fn drop(&mut self) { + match self { + DeviceBuffer::Linear { + data, cuMemFree_v2, .. + } => { + (cuMemFree_v2)(*data); + } + DeviceBuffer::Array { + array, + cuArrayDestroy, + .. + } => { + (cuArrayDestroy)(*array); + } + } + } +} + +fn launch_kernel( + fn_table: &mut CudaDynamicFns, + side_by_side_func: CUfunction, + grid_dim_x: u32, + grid_dim_y: u32, + grid_dim_z: u32, + block_dim_x: u32, + block_dim_y: u32, + block_dim_z: u32, + shared_mem_bytes: u32, + kernel_params: &mut [*mut c_void], +) -> Result<(), LogEntry> { + cuda_call!(fn_table.cuLaunchKernel( + side_by_side_func, + grid_dim_x, + grid_dim_y, + grid_dim_z, + block_dim_x, + block_dim_y, + block_dim_z, + shared_mem_bytes, + ptr::null_mut(), + kernel_params.as_mut_ptr(), + ptr::null_mut() + )); + cuda_call!(fn_table.cuStreamSynchronize(ptr::null_mut())); + Ok(()) +} + +fn compare_and_notify_if_mismatch( + fn_logger: &mut log::FunctionLogger, + name: &str, + dump_writer: &DumpWriter, + output_original: &HostArguments, + output_side_by_side: &HashMap<*mut c_void, Vec>, + side_by_side_dump_threshold: Option, + module: &str, + input: &HostArguments, + parameters: KernelLaunchParams, +) { + let mut original = output_original + .memory_allocations + .0 + .iter() + .collect::>(); + original.sort_by_key(|(k, _)| **k); + let mut side_by_side = output_side_by_side.iter().collect::>(); + side_by_side.sort_by_key(|(k, _)| **k); + let mut should_dump = false; + for ((devptr1, original_buf), (devptr2, side_by_side_buff)) in + original.iter().zip(side_by_side.iter()) + { + if **devptr1 != **devptr2 { + unreachable!() + } + let diff_count = unsafe { diff_count(original_buf.data(), side_by_side_buff) }; + let total_count = original_buf.data().len(); + if diff_count > 0 { + fn_logger.log(LogEntry::ArgumentMismatch { + devptr: **devptr1, + diff_count: diff_count as usize, + total_count, + }) + } + if let Some(dump_threshold) = side_by_side_dump_threshold { + let diff_percentage = (diff_count as f64 / total_count as f64) * 100f64; + if diff_percentage >= dump_threshold as f64 { + should_dump = true; + } + } + } + if should_dump { + dump_writer.save_kernel_launch(fn_logger, name, module, parameters, input, output_original) + } +} + +unsafe fn diff_count(mut b1: &[u8], mut b2: &[u8]) -> u64 { + use std::arch::x86_64::*; + let mut counter = _mm256_setzero_si256(); + let increment = _mm256_set1_epi8(1); + while b1.len() >= 32 { + let values1 = _mm256_loadu_si256(b1.as_ptr() as _); + let values2 = _mm256_loadu_si256(b2.as_ptr() as _); + let diff = _mm256_cmpeq_epi8(values1, values2); + let masked = _mm256_add_epi8(diff, increment); // overflow + let mut shifted = masked; + // iteration 1 + //shifted = _mm256_srli_si256::<0>(shifted); + let low_half = _mm256_castsi256_si128(shifted); + let high_half = _mm256_extractf128_si256::<1>(shifted); + let extended_low = _mm256_cvtepu8_epi64(low_half); + let extended_high = _mm256_cvtepu8_epi64(high_half); + counter = _mm256_add_epi64(counter, _mm256_add_epi64(extended_low, extended_high)); + // iteration 2 + shifted = _mm256_srli_si256::<4>(shifted); + let low_half = _mm256_castsi256_si128(shifted); + let high_half = _mm256_extractf128_si256::<1>(shifted); + let extended_low = _mm256_cvtepu8_epi64(low_half); + let extended_high = _mm256_cvtepu8_epi64(high_half); + counter = _mm256_add_epi64(counter, _mm256_add_epi64(extended_low, extended_high)); + // iteration 3 + shifted = _mm256_srli_si256::<4>(shifted); + let low_half = _mm256_castsi256_si128(shifted); + let high_half = _mm256_extractf128_si256::<1>(shifted); + let extended_low = _mm256_cvtepu8_epi64(low_half); + let extended_high = _mm256_cvtepu8_epi64(high_half); + counter = _mm256_add_epi64(counter, _mm256_add_epi64(extended_low, extended_high)); + // iteration 4 + shifted = _mm256_srli_si256::<4>(shifted); + let low_half = _mm256_castsi256_si128(shifted); + let high_half = _mm256_extractf128_si256::<1>(shifted); + let extended_low = _mm256_cvtepu8_epi64(low_half); + let extended_high = _mm256_cvtepu8_epi64(high_half); + counter = _mm256_add_epi64(counter, _mm256_add_epi64(extended_low, extended_high)); + b1 = &b1[32..]; + b2 = &b2[32..]; + } + // No horizontal add for 64 bit elements + let counter_low_half = _mm256_castsi256_si128(counter); + let counter_high_half = _mm256_extractf128_si256::<1>(counter); + let counter_128 = _mm_add_epi64(counter_low_half, counter_high_half); + let elm_0 = _mm_extract_epi64::<0>(counter_128) as u64; + let elm_1 = _mm_extract_epi64::<1>(counter_128) as u64; + diff_count_scalar(b1, b2) + elm_0 + elm_1 +} + +fn diff_count_scalar(b1: &[u8], b2: &[u8]) -> u64 { + b1.iter() + .copied() + .zip(b2.iter().copied()) + .filter(|(x, y)| x != y) + .count() as u64 +} + +#[cfg(test)] +mod tests { + use rand::{Rng, SeedableRng}; + use rand_chacha::ChaCha8Rng; + + use super::{diff_count, diff_count_scalar}; + + #[test] + fn diff_count_is_correct() { + let count = 506; + let mut rng = ChaCha8Rng::seed_from_u64(0x82edbf28bf683468); + let mut vec1 = Vec::new(); + let mut vec2 = Vec::new(); + for _ in 0..count { + let value = rng.gen::(); + vec1.push(value); + if rng.gen::() { + vec2.push(value); + } else { + vec2.push(rng.gen()) + } + } + unsafe { assert_eq!(diff_count(&vec1, &vec2), diff_count_scalar(&vec1, &vec2)) } + } +} diff --git a/zluda_dump/src/trace.rs b/zluda_dump/src/trace.rs new file mode 100644 index 0000000..b650f32 --- /dev/null +++ b/zluda_dump/src/trace.rs @@ -0,0 +1,740 @@ +use crate::log::{FunctionLogger, LogEntry}; +use crate::{dark_api, log, side_by_side, Settings}; +use cuda_types::*; +use ptx::{ast, DisplayParseError, ModuleParserExt}; +use ptx::{ast::PtxError, Token}; +use serde::{Serialize, Serializer}; +use std::alloc::Layout; +use std::ffi::CString; +use std::sync::Arc; +use std::{ + collections::HashMap, + ffi::CStr, + fs::{self, File}, + io::{self, Write}, + path::PathBuf, + rc::Rc, +}; +use zluda_dark_api::{CUmoduleContent, FatbinFileKind}; + +// This struct is the heart of CUDA state tracking, it: +// * receives calls from the probes about changes to CUDA state +// * records updates to the state change +// * writes out relevant state change and details to disk and log +pub(crate) struct StateTracker { + pub(crate) writer: DumpWriter, + module_counter: usize, + pub(crate) modules: HashMap, + pub(crate) functions: HashMap, + pub(crate) texrefs: HashMap, + pub(crate) dark_api: dark_api::DarkApiState, + pub(crate) override_cc_major: Option, +} + +fn visit_cumodule_content( + this: CUmoduleContent, + cu_module: Option, + fn_logger: &mut log::FunctionLogger, + mut on_file: impl FnMut(&mut log::FunctionLogger, FatbinFileKind, CUmoduleFileIndex, &[u8]), +) { + match this { + CUmoduleContent::Elf(buffer) => { + let buffer = unsafe { hip_common::elf::as_slice(buffer) }; + on_file( + fn_logger, + FatbinFileKind::Elf, + CUmoduleFileIndex::Single, + buffer, + ); + } + CUmoduleContent::Archive(buffer) => { + on_file( + fn_logger, + FatbinFileKind::Archive, + CUmoduleFileIndex::Single, + buffer, + ); + } + CUmoduleContent::File(file_name) => { + fn_logger.log_fn(|fn_logger| { + let file_name = unsafe { CStr::from_ptr(file_name) }; + let file_name = file_name.to_str().map_err(LogEntry::MalformedModulePath)?; + let buffer = std::fs::read(file_name)?; + let (kind, _) = unsafe { try_get_kind_slice(cu_module, buffer.as_ptr())? }; + on_file(fn_logger, kind, CUmoduleFileIndex::Single, &buffer); + Ok(()) + }); + } + CUmoduleContent::RawText(buffer) => { + let kind_slice = unsafe { try_get_kind_slice(cu_module, buffer) }; + if let Some((kind, buffer)) = fn_logger.log_unwrap(kind_slice) { + on_file(fn_logger, kind, CUmoduleFileIndex::Single, buffer); + } + } + CUmoduleContent::Fatbin(zluda_dark_api::CudaFatbin::Version1(module)) => { + visit_module(fn_logger, &module, &mut on_file, true, None); + } + CUmoduleContent::Fatbin(zluda_dark_api::CudaFatbin::Version2 { + post_link, + pre_link, + }) => { + visit_module(fn_logger, &post_link, &mut on_file, false, None); + for (sub_index, sub_module) in pre_link.iter().enumerate() { + visit_module(fn_logger, sub_module, &mut on_file, false, Some(sub_index)); + } + } + } +} + +unsafe fn try_get_kind_slice( + module: Option, + raw_image: *const u8, +) -> Result<(FatbinFileKind, &'static [u8]), LogEntry> { + Ok( + if *(raw_image as *const [u8; 4]) == *goblin::elf64::header::ELFMAG { + let slice = hip_common::elf::as_slice(raw_image); + (FatbinFileKind::Elf, slice) + } else if *(raw_image as *const [u8; 8]) == *goblin::archive::MAGIC { + return Err(LogEntry::UnsupportedModule { + module, + raw_image: raw_image.cast(), + kind: FatbinFileKind::Archive, + }); + } else { + let mut current = raw_image; + loop { + if *current == 0 { + break; + } + current = current.add(1); + } + ( + FatbinFileKind::Ptx, + std::slice::from_raw_parts(raw_image, current.offset_from(raw_image) as usize), + ) + }, + ) +} + +fn visit_module( + fn_logger: &mut FunctionLogger, + module: &zluda_dark_api::FatbinModuleHandle, + on_file: &mut impl FnMut(&mut FunctionLogger, FatbinFileKind, CUmoduleFileIndex, &[u8]), + version1: bool, + sub_index: Option, +) { + fn_logger.log_fn(|fn_logger| { + let module = unsafe { module.get()? }; + match module { + zluda_dark_api::FatbinModule::Elf(ptr) => { + let buffer = unsafe { hip_common::elf::as_slice(ptr) }; + on_file( + fn_logger, + FatbinFileKind::Elf, + if version1 { + CUmoduleFileIndex::Single + } else { + if let Some(module) = sub_index { + CUmoduleFileIndex::FatbinSub { module, file: 0 } + } else { + CUmoduleFileIndex::FatbinMain { file: 0 } + } + }, + buffer, + ); + } + zluda_dark_api::FatbinModule::Files(files) => { + for (index, maybe_file) in files.enumerate() { + if let Some(file) = fn_logger.log_unwrap(maybe_file.map_err(Into::into)) { + if let Some(buffer) = fn_logger + .log_unwrap(unsafe { file.get_or_decompress() }.map_err(Into::into)) + { + on_file( + fn_logger, + file.kind, + if version1 { + CUmoduleFileIndex::Fatbin { file: index } + } else { + if let Some(module) = sub_index { + CUmoduleFileIndex::FatbinSub { + module, + file: index, + } + } else { + CUmoduleFileIndex::FatbinMain { file: index } + } + }, + &buffer, + ); + } + } + } + } + } + Ok(()) + }); +} + +#[derive(Clone, Copy)] +enum CUmoduleFileIndex { + Single, + Fatbin { file: usize }, + FatbinMain { file: usize }, + FatbinSub { module: usize, file: usize }, +} + +impl StateTracker { + pub(crate) fn new(settings: &Settings) -> Self { + StateTracker { + writer: DumpWriter::new(settings.dump_dir.clone()), + modules: HashMap::new(), + functions: HashMap::new(), + texrefs: HashMap::new(), + module_counter: 0, + dark_api: dark_api::DarkApiState::new(), + override_cc_major: settings.override_cc_major, + } + } + + pub(crate) fn record_module( + &mut self, + fn_logger: &mut log::FunctionLogger, + cu_module: Option, + module: CUmoduleContent, + ) { + self.module_counter += 1; + let mut parsed_sources = (Vec::new(), HashMap::new()); + let mut ptx_parsing = PtxParseControl::Replace; + visit_cumodule_content( + module, + cu_module, + fn_logger, + |fn_logger, kind, index, buffer| { + fn_logger.log_io_error(self.writer.save_module2( + self.module_counter, + kind, + index, + buffer, + )); + if ptx_parsing != PtxParseControl::Skip && kind == FatbinFileKind::Ptx { + ptx_parsing = match index { + CUmoduleFileIndex::Single + | CUmoduleFileIndex::Fatbin { .. } + | CUmoduleFileIndex::FatbinMain { .. } => PtxParseControl::Replace, + CUmoduleFileIndex::FatbinSub { module: 0, .. } => { + if !parsed_sources.0.is_empty() { + PtxParseControl::Skip + } else { + PtxParseControl::Append + } + } + CUmoduleFileIndex::FatbinSub { .. } => PtxParseControl::Append, + }; + let parsing_result = match ptx_parsing { + PtxParseControl::Append => { + std::mem::replace(&mut parsed_sources, (Vec::new(), HashMap::new())) + } + PtxParseControl::Replace => (Vec::new(), HashMap::new()), + PtxParseControl::Skip => { + return; + } + }; + parsed_sources = self.try_parse_ptx(fn_logger, index, parsing_result, &buffer); + } + }, + ); + if let Some(cu_module) = cu_module { + self.modules + .insert(cu_module, ParsedModule::new(parsed_sources)); + } + } + + fn try_parse_ptx( + &mut self, + fn_logger: &mut log::FunctionLogger, + file_index: CUmoduleFileIndex, + (mut kernel_text, mut kernels): (Vec, HashMap>), + buffer: &[u8], + ) -> (Vec, HashMap>) { + let module_text = match std::str::from_utf8(buffer).map_err(LogEntry::NonUtf8ModuleText) { + Ok(m) => m, + Err(err) => { + fn_logger.log(err); + return (kernel_text, kernels); + } + }; + let (ast, errors) = ptx::ModuleParser::parse_unchecked(module_text); + if !errors.is_empty() { + fn_logger.log(log::LogEntry::ModuleParsingError( + DumpWriter::get_file_name2(self.module_counter, file_index, "log"), + )); + fn_logger.log_io_error(self.writer.save_module_error_log( + module_text, + self.module_counter, + file_index, + &*errors, + )); + } else { + for directive in ast.directives { + match directive { + ast::Directive::Method( + _, + ast::Function { + func_directive: + ast::MethodDeclaration { + name: ast::MethodName::Kernel(kernel_name), + input_arguments, + .. + }, + .. + }, + ) => { + kernels.insert( + kernel_name.to_string(), + input_arguments.iter().map(|arg| arg.layout()).collect(), + ); + } + _ => {} + } + } + let mut zero_terminated_kernel_text = module_text.to_string(); + zero_terminated_kernel_text.push('\0'); + kernel_text.push(zero_terminated_kernel_text); + } + (kernel_text, kernels) + } + + pub(crate) unsafe fn record_function( + &mut self, + func: CUfunction, + module: CUmodule, + raw_name: *const ::std::os::raw::c_char, + fn_logger: &mut log::FunctionLogger, + ) { + let name = CStr::from_ptr(raw_name).to_string_lossy().to_string(); + let maybe_parsed_func = if let Some(parsed_mod) = self.modules.get(&module) { + if let Some(args) = parsed_mod.kernels_args.get(&name) { + Some(RecordedFunction { + name: Arc::new(name.clone()), + module, + parsed: Some(ParsedFunction { + text: parsed_mod.sources.clone(), + explicit_arguments: args.clone(), + }), + }) + } else { + // We don't know about this function + fn_logger.log(LogEntry::UnknownFunction(func, module, name.clone())); + None + } + } else { + // We don't know about this module + fn_logger.log(LogEntry::UnknownModule(module)); + None + }; + let parsed_func = maybe_parsed_func.unwrap_or_else(move || RecordedFunction { + name: Arc::new(name), + module, + parsed: None, + }); + self.functions.insert(func, parsed_func); + } + + pub(crate) fn record_texref( + &mut self, + fn_logger: &mut log::FunctionLogger, + name: *const ::std::os::raw::c_char, + texref: CUtexref, + hmod: CUmodule, + ) { + let parsed_module = match self.modules.get_mut(&hmod) { + Some(m) => m, + _ => { + fn_logger.log(LogEntry::UnknownModule(hmod)); + return; + } + }; + parsed_module + .texrefs + .insert(unsafe { CStr::from_ptr(name) }.to_owned(), texref); + self.texrefs + .insert(texref, RecordedTexref { address: None }); + } + + pub(crate) fn get_texrefs( + &self, + module: CUmodule, + ) -> Result + '_, LogEntry> { + let module = match self.modules.get(&module) { + Some(m) => m, + _ => return Err(LogEntry::UnknownModule(module)), + }; + let all_texrefs = &self.texrefs; + Ok(module + .texrefs + .iter() + .map(move |(name, cu_texref)| { + let cu_texref = *cu_texref; + all_texrefs + .get(&cu_texref) + .copied() + .map(move |recorded| { + recorded + .address + .map(|address| (name.as_c_str(), cu_texref, address)) + }) + .into_iter() + }) + .flatten() + .flatten()) + } + + pub(crate) fn get_globals( + &self, + module: CUmodule, + ) -> Result + '_, LogEntry> { + let module = match self.modules.get(&module) { + Some(m) => m, + _ => return Err(LogEntry::UnknownModule(module)), + }; + Ok(module + .globals + .iter() + .map(|(name, ptr)| (name.as_c_str(), *ptr))) + } + + pub(crate) fn record_texref_address( + &mut self, + fn_logger: &mut log::FunctionLogger, + tex_ref: CUtexref, + pitch: Option, + ) { + fn_logger.log_fn(|_| { + let recorded_texref = self + .texrefs + .get_mut(&tex_ref) + .ok_or(LogEntry::UnknownTexref(tex_ref))?; + recorded_texref.address = pitch; + Ok(()) + }); + } + + pub(crate) fn remove_texref_address( + &mut self, + fn_logger: &mut log::FunctionLogger, + tex_ref: CUtexref, + ) { + self.record_texref_address(fn_logger, tex_ref, None) + } + + pub(crate) fn record_global( + &mut self, + fn_logger: &mut FunctionLogger, + hmod: CUmodule, + name: *const i8, + dptr: CUdeviceptr, + ) { + fn_logger.log_fn(|_| { + let recorded_module = self + .modules + .get_mut(&hmod) + .ok_or(LogEntry::UnknownModule(hmod))?; + let name = unsafe { CStr::from_ptr(name) }.to_owned(); + recorded_module.globals.insert(name, dptr); + Ok(()) + }); + } +} + +#[derive(PartialEq, Eq)] +enum PtxParseControl { + Skip, + Append, + Replace, +} + +pub(crate) struct ParsedModule { + // Note that text includes NULL terminator + sources: Rc>, + kernels_args: HashMap>, + texrefs: HashMap, + globals: HashMap, +} + +impl ParsedModule { + pub(crate) fn new((kernel_text, kernels): (Vec, HashMap>)) -> Self { + ParsedModule { + sources: Rc::new(kernel_text), + kernels_args: kernels, + texrefs: HashMap::new(), + globals: HashMap::new(), + } + } +} + +#[derive(Clone, Copy)] +pub(crate) struct RecordedTexref { + pub(crate) address: Option, +} + +pub(crate) struct RecordedFunction { + pub(crate) name: Arc, + pub(crate) module: CUmodule, + pub(crate) parsed: Option, +} + +pub(crate) struct ParsedFunction { + pub(crate) text: Rc>, + pub(crate) explicit_arguments: Vec, +} + +#[derive(Serialize, Clone, Copy)] +pub(crate) enum TexrefAddress { + OneD { + #[serde(skip)] + pointer: CUdeviceptr, + bytes: usize, + }, + TwoD { + #[serde(skip)] + pointer: CUdeviceptr, + width: usize, + height: usize, + #[serde(serialize_with = "serialize_array_format")] + format: CUarray_format, + channels: u32, + pitch: usize, + }, + Array { + #[serde(skip)] + array: CUarray, + flags: u32, + }, +} + +pub(crate) fn serialize_array_format( + array_format: &CUarray_format, + serializer: S, +) -> Result +where + S: Serializer, +{ + serializer.serialize_i32(array_format.0) +} + +impl TexrefAddress { + pub(crate) fn new_2d(desc: CUDA_ARRAY_DESCRIPTOR, pointer: CUdeviceptr, pitch: usize) -> Self { + Self::TwoD { + pointer, + pitch, + width: desc.Width, + height: desc.Height, + format: desc.Format, + channels: desc.NumChannels, + } + } +} + +// This structs writes out information about CUDA execution to the dump dir +pub(crate) struct DumpWriter { + dump_dir: Option, +} + +impl DumpWriter { + fn new(dump_dir: Option) -> Self { + Self { dump_dir } + } + + fn save_module2( + &self, + cu_module_index: usize, + kind: FatbinFileKind, + index: CUmoduleFileIndex, + buffer: &[u8], + ) -> io::Result<()> { + let mut dump_file = match &self.dump_dir { + None => return Ok(()), + Some(d) => d.clone(), + }; + dump_file.push(Self::get_file_name2( + cu_module_index, + index, + kind.file_extension(), + )); + let mut file = File::create(dump_file)?; + file.write_all(buffer)?; + Ok(()) + } + + fn get_file_name2( + cu_module_index: usize, + module_file: CUmoduleFileIndex, + kind: &str, + ) -> String { + match module_file { + CUmoduleFileIndex::Single => { + format!("module_{:04}.{}", cu_module_index, kind) + } + CUmoduleFileIndex::Fatbin { file } => { + format!("module_{:04}_{:02}.{}", cu_module_index, file + 1, kind) + } + CUmoduleFileIndex::FatbinMain { file } => { + format!( + "module_{:04}_main_{:02}.{}", + cu_module_index, + file + 1, + kind + ) + } + CUmoduleFileIndex::FatbinSub { module, file } => { + format!( + "module_{:04}_sub_{:03}_{:02}.{}", + cu_module_index, + module + 1, + file + 1, + kind + ) + } + } + } + + pub(crate) fn save_kernel_launch( + &self, + logger: &mut FunctionLogger, + name: &str, + module: &str, + parameters: KernelLaunchParams, + input: &side_by_side::HostArguments, + output: &side_by_side::HostArguments, + ) { + logger.log_io_error(Self::save_kernel_launch_impl( + self, name, module, parameters, input, output, + )) + } + + fn save_module_error_log<'input>( + &self, + module_text: &str, + cu_module_index: usize, + module_file: CUmoduleFileIndex, + errors: &[ptx::ParseError, PtxError>], + ) -> io::Result<()> { + let mut log_file = match &self.dump_dir { + None => return Ok(()), + Some(d) => d.clone(), + }; + log_file.push(Self::get_file_name2(cu_module_index, module_file, "log")); + let mut file = File::create(log_file)?; + for error in errors { + let pretty_print_error = unsafe { DisplayParseError::new(error, module_text) }; + writeln!(file, "{}", pretty_print_error)?; + } + Ok(()) + } + + fn save_kernel_launch_impl( + &self, + name: &str, + module: &str, + parameters: KernelLaunchParams, + input: &side_by_side::HostArguments, + output: &side_by_side::HostArguments, + ) -> io::Result<()> { + let mut dump_dir = if let Some(ref dump_dir) = self.dump_dir { + dump_dir.clone() + } else { + return Ok(()); + }; + dump_dir.push(name); + let mut suffix = 1; + while dump_dir.exists() { + dump_dir.set_file_name(format!("{}_{}", name, suffix)); + suffix += 1; + } + fs::create_dir(&dump_dir)?; + dump_dir.push("kernel_launch.json"); + let allocations = input + .memory_allocations + .0 + .iter() + .filter_map(|(k, v)| { + v.array_descriptor() + .map(|desc| (*k as usize, Array3dDescriptor::new(desc))) + }) + .collect::>(); + let kernel_launch = KernelLaunch { + name, + parameters, + arguments: input, + allocations, + }; + let file = File::create(&dump_dir)?; + serde_json::to_writer_pretty(file, &kernel_launch)?; + dump_dir.set_file_name("module.ptx"); + fs::write(&dump_dir, module)?; + dump_dir.set_file_name("pre"); + fs::create_dir(&dump_dir)?; + Self::write_buffers(input, &dump_dir)?; + dump_dir.set_file_name("post"); + fs::create_dir(&dump_dir)?; + Self::write_buffers(output, &dump_dir)?; + Ok(()) + } + + fn write_buffers( + buffers: &side_by_side::HostArguments, + dump_dir: &PathBuf, + ) -> Result<(), io::Error> { + Ok(for (key, buffer) in buffers.memory_allocations.0.iter() { + let mut file_path = dump_dir.clone(); + file_path.push((*key as usize).to_string()); + fs::write(file_path, buffer.data())?; + }) + } +} + +#[derive(Serialize)] +#[allow(non_snake_case)] +pub(crate) struct KernelLaunchParams { + pub(crate) gridDimX: u32, + pub(crate) gridDimY: u32, + pub(crate) gridDimZ: u32, + pub(crate) blockDimX: u32, + pub(crate) blockDimY: u32, + pub(crate) blockDimZ: u32, + pub(crate) sharedMemBytes: u32, +} + +#[derive(Serialize)] +struct KernelLaunch<'a> { + name: &'a str, + parameters: KernelLaunchParams, + #[serde(flatten)] + arguments: &'a side_by_side::HostArguments, + allocations: HashMap, +} + +#[derive(Serialize)] +#[allow(non_snake_case)] +struct Array3dDescriptor { + pub Width: usize, + pub Height: usize, + pub Depth: usize, + #[serde(serialize_with = "serialize_array_format")] + pub Format: CUarray_format, + pub NumChannels: u32, + pub Flags: u32, +} + +impl Array3dDescriptor { + fn new(original: &CUDA_ARRAY3D_DESCRIPTOR) -> Self { + Self { + Width: original.Width, + Height: original.Height, + Depth: original.Depth, + Format: original.Format, + NumChannels: original.NumChannels, + Flags: original.Flags, + } + } +} diff --git a/zluda_fft/Cargo.toml b/zluda_fft/Cargo.toml new file mode 100644 index 0000000..d8d8efb --- /dev/null +++ b/zluda_fft/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "zluda_fft" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "cufft" +crate-type = ["cdylib"] + +[dependencies] +hipfft-sys = { path = "../hipfft-sys" } +hip_common = { path = "../hip_common" } +cuda_types = { path = "../cuda_types" } +zluda_dark_api = { path = "../zluda_dark_api" } +slab = "0.4" +lazy_static = "1.4.0" + +[package.metadata.zluda] +linux_only = true +linux_names = ["libcufft.so.10"] +dump_names = ["libcufft.so"] diff --git a/zluda_fft/README b/zluda_fft/README new file mode 100644 index 0000000..536a28d --- /dev/null +++ b/zluda_fft/README @@ -0,0 +1,4 @@ +bindgen /usr/local/cuda/targets/x86_64-linux/include/cufft.h -o src/cufft.rs --allowlist-function="^cufft.*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda/targets/x86_64-linux/include +bindgen /usr/local/cuda/targets/x86_64-linux/include/cufftXt.h --allowlist-function="^cufftXt.*" --blocklist-type="^cufft[^XB].*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -o src/cufftxt.rs -- -I/usr/local/cuda/targets/x86_64-linux/include +sed -i -e 's/extern "C" {//g' -e 's/-> cufftResult;/-> cufftResult { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' src/cufft.rs +sed -i -e 's/extern "C" {//g' -e 's/-> cufftResult;/-> cufftResult { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' src/cufftxt.rs \ No newline at end of file diff --git a/zluda_fft/src/cufft.rs b/zluda_fft/src/cufft.rs new file mode 100644 index 0000000..9fb5dd9 --- /dev/null +++ b/zluda_fft/src/cufft.rs @@ -0,0 +1,474 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[repr(align(8))] +#[derive(Copy, Clone)] +pub struct float2 { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub struct double2 { + pub x: f64, + pub y: f64, +} +pub type cuFloatComplex = float2; +pub type cuDoubleComplex = double2; +pub type cuComplex = cuFloatComplex; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CUstream_st { + _unused: [u8; 0], +} +#[doc = " CUDA stream"] +pub type cudaStream_t = *mut CUstream_st; +impl libraryPropertyType_t { + pub const MAJOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(0); +} +impl libraryPropertyType_t { + pub const MINOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(1); +} +impl libraryPropertyType_t { + pub const PATCH_LEVEL: libraryPropertyType_t = libraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::libraryPropertyType_t as libraryPropertyType; +impl cufftResult_t { + pub const CUFFT_SUCCESS: cufftResult_t = cufftResult_t(0); +} +impl cufftResult_t { + pub const CUFFT_INVALID_PLAN: cufftResult_t = cufftResult_t(1); +} +impl cufftResult_t { + pub const CUFFT_ALLOC_FAILED: cufftResult_t = cufftResult_t(2); +} +impl cufftResult_t { + pub const CUFFT_INVALID_TYPE: cufftResult_t = cufftResult_t(3); +} +impl cufftResult_t { + pub const CUFFT_INVALID_VALUE: cufftResult_t = cufftResult_t(4); +} +impl cufftResult_t { + pub const CUFFT_INTERNAL_ERROR: cufftResult_t = cufftResult_t(5); +} +impl cufftResult_t { + pub const CUFFT_EXEC_FAILED: cufftResult_t = cufftResult_t(6); +} +impl cufftResult_t { + pub const CUFFT_SETUP_FAILED: cufftResult_t = cufftResult_t(7); +} +impl cufftResult_t { + pub const CUFFT_INVALID_SIZE: cufftResult_t = cufftResult_t(8); +} +impl cufftResult_t { + pub const CUFFT_UNALIGNED_DATA: cufftResult_t = cufftResult_t(9); +} +impl cufftResult_t { + pub const CUFFT_INCOMPLETE_PARAMETER_LIST: cufftResult_t = cufftResult_t(10); +} +impl cufftResult_t { + pub const CUFFT_INVALID_DEVICE: cufftResult_t = cufftResult_t(11); +} +impl cufftResult_t { + pub const CUFFT_PARSE_ERROR: cufftResult_t = cufftResult_t(12); +} +impl cufftResult_t { + pub const CUFFT_NO_WORKSPACE: cufftResult_t = cufftResult_t(13); +} +impl cufftResult_t { + pub const CUFFT_NOT_IMPLEMENTED: cufftResult_t = cufftResult_t(14); +} +impl cufftResult_t { + pub const CUFFT_LICENSE_ERROR: cufftResult_t = cufftResult_t(15); +} +impl cufftResult_t { + pub const CUFFT_NOT_SUPPORTED: cufftResult_t = cufftResult_t(16); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftResult_t(pub ::std::os::raw::c_uint); +pub use self::cufftResult_t as cufftResult; +pub type cufftReal = f32; +pub type cufftDoubleReal = f64; +pub type cufftComplex = cuComplex; +pub type cufftDoubleComplex = cuDoubleComplex; +impl cufftType_t { + pub const CUFFT_R2C: cufftType_t = cufftType_t(42); +} +impl cufftType_t { + pub const CUFFT_C2R: cufftType_t = cufftType_t(44); +} +impl cufftType_t { + pub const CUFFT_C2C: cufftType_t = cufftType_t(41); +} +impl cufftType_t { + pub const CUFFT_D2Z: cufftType_t = cufftType_t(106); +} +impl cufftType_t { + pub const CUFFT_Z2D: cufftType_t = cufftType_t(108); +} +impl cufftType_t { + pub const CUFFT_Z2Z: cufftType_t = cufftType_t(105); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftType_t(pub ::std::os::raw::c_uint); +pub use self::cufftType_t as cufftType; +pub type cufftHandle = ::std::os::raw::c_int; + +#[no_mangle] +pub unsafe extern "system" fn cufftPlan1d( + plan: *mut cufftHandle, + nx: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftPlan2d( + plan: *mut cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: cufftType, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftPlan3d( + plan: *mut cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: cufftType, +) -> cufftResult { + crate::plan_3d(plan, nx, ny, nz, type_) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftPlanMany( + plan: *mut cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, +) -> cufftResult { + crate::plan_many( + plan, rank, n, inembed, istride, idist, onembed, ostride, odist, type_, batch, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftMakePlan1d( + plan: cufftHandle, + nx: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftMakePlan2d( + plan: cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftMakePlan3d( + plan: cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftMakePlanMany( + plan: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, +) -> cufftResult { + crate::make_plan_many( + plan, rank, n, inembed, istride, idist, onembed, ostride, odist, type_, batch, workSize, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftMakePlanMany64( + plan: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + type_: cufftType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, +) -> cufftResult { + crate::make_plan_many_64( + plan, rank, n, inembed, istride, idist, onembed, ostride, odist, type_, batch, workSize, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSizeMany64( + plan: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + type_: cufftType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftEstimate1d( + nx: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftEstimate2d( + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftEstimate3d( + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftEstimateMany( + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftCreate(handle: *mut cufftHandle) -> cufftResult { + crate::create(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSize1d( + handle: cufftHandle, + nx: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSize2d( + handle: cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSize3d( + handle: cufftHandle, + nx: ::std::os::raw::c_int, + ny: ::std::os::raw::c_int, + nz: ::std::os::raw::c_int, + type_: cufftType, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSizeMany( + handle: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_int, + inembed: *mut ::std::os::raw::c_int, + istride: ::std::os::raw::c_int, + idist: ::std::os::raw::c_int, + onembed: *mut ::std::os::raw::c_int, + ostride: ::std::os::raw::c_int, + odist: ::std::os::raw::c_int, + type_: cufftType, + batch: ::std::os::raw::c_int, + workArea: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetSize( + handle: cufftHandle, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftSetWorkArea( + plan: cufftHandle, + workArea: *mut ::std::os::raw::c_void, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftSetAutoAllocation( + plan: cufftHandle, + autoAllocate: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecC2C( + plan: cufftHandle, + idata: *mut cufftComplex, + odata: *mut cufftComplex, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::exec_c2c(plan, idata, odata, direction) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecR2C( + plan: cufftHandle, + idata: *mut cufftReal, + odata: *mut cufftComplex, +) -> cufftResult { + crate::exec_r2c(plan, idata, odata) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecC2R( + plan: cufftHandle, + idata: *mut cufftComplex, + odata: *mut cufftReal, +) -> cufftResult { + crate::exec_c2r(plan, idata, odata) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecZ2Z( + plan: cufftHandle, + idata: *mut cufftDoubleComplex, + odata: *mut cufftDoubleComplex, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::exec_z2z(plan, idata, odata, direction) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecD2Z( + plan: cufftHandle, + idata: *mut cufftDoubleReal, + odata: *mut cufftDoubleComplex, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftExecZ2D( + plan: cufftHandle, + idata: *mut cufftDoubleComplex, + odata: *mut cufftDoubleReal, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftSetStream( + plan: cufftHandle, + stream: cudaStream_t, +) -> cufftResult { + crate::set_stream(plan, stream) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftDestroy(plan: cufftHandle) -> cufftResult { + crate::destroy(plan) +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetVersion(version: *mut ::std::os::raw::c_int) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftGetProperty( + type_: libraryPropertyType, + value: *mut ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} diff --git a/zluda_fft/src/cufftxt.rs b/zluda_fft/src/cufftxt.rs new file mode 100644 index 0000000..6aa2191 --- /dev/null +++ b/zluda_fft/src/cufftxt.rs @@ -0,0 +1,446 @@ +use crate::cufft::*; + +/* automatically generated by rust-bindgen 0.66.1 */ + +impl cudaDataType_t { + pub const CUDA_R_16F: cudaDataType_t = cudaDataType_t(2); +} +impl cudaDataType_t { + pub const CUDA_C_16F: cudaDataType_t = cudaDataType_t(6); +} +impl cudaDataType_t { + pub const CUDA_R_16BF: cudaDataType_t = cudaDataType_t(14); +} +impl cudaDataType_t { + pub const CUDA_C_16BF: cudaDataType_t = cudaDataType_t(15); +} +impl cudaDataType_t { + pub const CUDA_R_32F: cudaDataType_t = cudaDataType_t(0); +} +impl cudaDataType_t { + pub const CUDA_C_32F: cudaDataType_t = cudaDataType_t(4); +} +impl cudaDataType_t { + pub const CUDA_R_64F: cudaDataType_t = cudaDataType_t(1); +} +impl cudaDataType_t { + pub const CUDA_C_64F: cudaDataType_t = cudaDataType_t(5); +} +impl cudaDataType_t { + pub const CUDA_R_4I: cudaDataType_t = cudaDataType_t(16); +} +impl cudaDataType_t { + pub const CUDA_C_4I: cudaDataType_t = cudaDataType_t(17); +} +impl cudaDataType_t { + pub const CUDA_R_4U: cudaDataType_t = cudaDataType_t(18); +} +impl cudaDataType_t { + pub const CUDA_C_4U: cudaDataType_t = cudaDataType_t(19); +} +impl cudaDataType_t { + pub const CUDA_R_8I: cudaDataType_t = cudaDataType_t(3); +} +impl cudaDataType_t { + pub const CUDA_C_8I: cudaDataType_t = cudaDataType_t(7); +} +impl cudaDataType_t { + pub const CUDA_R_8U: cudaDataType_t = cudaDataType_t(8); +} +impl cudaDataType_t { + pub const CUDA_C_8U: cudaDataType_t = cudaDataType_t(9); +} +impl cudaDataType_t { + pub const CUDA_R_16I: cudaDataType_t = cudaDataType_t(20); +} +impl cudaDataType_t { + pub const CUDA_C_16I: cudaDataType_t = cudaDataType_t(21); +} +impl cudaDataType_t { + pub const CUDA_R_16U: cudaDataType_t = cudaDataType_t(22); +} +impl cudaDataType_t { + pub const CUDA_C_16U: cudaDataType_t = cudaDataType_t(23); +} +impl cudaDataType_t { + pub const CUDA_R_32I: cudaDataType_t = cudaDataType_t(10); +} +impl cudaDataType_t { + pub const CUDA_C_32I: cudaDataType_t = cudaDataType_t(11); +} +impl cudaDataType_t { + pub const CUDA_R_32U: cudaDataType_t = cudaDataType_t(12); +} +impl cudaDataType_t { + pub const CUDA_C_32U: cudaDataType_t = cudaDataType_t(13); +} +impl cudaDataType_t { + pub const CUDA_R_64I: cudaDataType_t = cudaDataType_t(24); +} +impl cudaDataType_t { + pub const CUDA_C_64I: cudaDataType_t = cudaDataType_t(25); +} +impl cudaDataType_t { + pub const CUDA_R_64U: cudaDataType_t = cudaDataType_t(26); +} +impl cudaDataType_t { + pub const CUDA_C_64U: cudaDataType_t = cudaDataType_t(27); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E4M3: cudaDataType_t = cudaDataType_t(28); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E5M2: cudaDataType_t = cudaDataType_t(29); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDataType_t(pub ::std::os::raw::c_uint); +pub use self::cudaDataType_t as cudaDataType; +impl libFormat_t { + pub const LIB_FORMAT_CUFFT: libFormat_t = libFormat_t(0); +} +impl libFormat_t { + pub const LIB_FORMAT_UNDEFINED: libFormat_t = libFormat_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libFormat_t(pub ::std::os::raw::c_uint); +pub use self::libFormat_t as libFormat; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaXtDesc_t { + pub version: ::std::os::raw::c_int, + pub nGPUs: ::std::os::raw::c_int, + pub GPUs: [::std::os::raw::c_int; 64usize], + pub data: [*mut ::std::os::raw::c_void; 64usize], + pub size: [usize; 64usize], + pub cudaXtState: *mut ::std::os::raw::c_void, +} +pub type cudaXtDesc = cudaXtDesc_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cudaLibXtDesc_t { + pub version: ::std::os::raw::c_int, + pub descriptor: *mut cudaXtDesc, + pub library: libFormat, + pub subFormat: ::std::os::raw::c_int, + pub libDescriptor: *mut ::std::os::raw::c_void, +} +pub type cudaLibXtDesc = cudaLibXtDesc_t; +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_INPUT: cufftXtSubFormat_t = cufftXtSubFormat_t(0); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_OUTPUT: cufftXtSubFormat_t = cufftXtSubFormat_t(1); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_INPLACE: cufftXtSubFormat_t = cufftXtSubFormat_t(2); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_INPLACE_SHUFFLED: cufftXtSubFormat_t = cufftXtSubFormat_t(3); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_1D_INPUT_SHUFFLED: cufftXtSubFormat_t = cufftXtSubFormat_t(4); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_DISTRIBUTED_INPUT: cufftXtSubFormat_t = cufftXtSubFormat_t(5); +} +impl cufftXtSubFormat_t { + pub const CUFFT_XT_FORMAT_DISTRIBUTED_OUTPUT: cufftXtSubFormat_t = cufftXtSubFormat_t(6); +} +impl cufftXtSubFormat_t { + pub const CUFFT_FORMAT_UNDEFINED: cufftXtSubFormat_t = cufftXtSubFormat_t(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftXtSubFormat_t(pub ::std::os::raw::c_uint); +pub use self::cufftXtSubFormat_t as cufftXtSubFormat; +impl cufftXtCopyType_t { + pub const CUFFT_COPY_HOST_TO_DEVICE: cufftXtCopyType_t = cufftXtCopyType_t(0); +} +impl cufftXtCopyType_t { + pub const CUFFT_COPY_DEVICE_TO_HOST: cufftXtCopyType_t = cufftXtCopyType_t(1); +} +impl cufftXtCopyType_t { + pub const CUFFT_COPY_DEVICE_TO_DEVICE: cufftXtCopyType_t = cufftXtCopyType_t(2); +} +impl cufftXtCopyType_t { + pub const CUFFT_COPY_UNDEFINED: cufftXtCopyType_t = cufftXtCopyType_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftXtCopyType_t(pub ::std::os::raw::c_uint); +pub use self::cufftXtCopyType_t as cufftXtCopyType; +impl cufftXtQueryType_t { + pub const CUFFT_QUERY_1D_FACTORS: cufftXtQueryType_t = cufftXtQueryType_t(0); +} +impl cufftXtQueryType_t { + pub const CUFFT_QUERY_UNDEFINED: cufftXtQueryType_t = cufftXtQueryType_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftXtQueryType_t(pub ::std::os::raw::c_uint); +pub use self::cufftXtQueryType_t as cufftXtQueryType; +impl cufftXtWorkAreaPolicy_t { + pub const CUFFT_WORKAREA_MINIMAL: cufftXtWorkAreaPolicy_t = cufftXtWorkAreaPolicy_t(0); +} +impl cufftXtWorkAreaPolicy_t { + pub const CUFFT_WORKAREA_USER: cufftXtWorkAreaPolicy_t = cufftXtWorkAreaPolicy_t(1); +} +impl cufftXtWorkAreaPolicy_t { + pub const CUFFT_WORKAREA_PERFORMANCE: cufftXtWorkAreaPolicy_t = cufftXtWorkAreaPolicy_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftXtWorkAreaPolicy_t(pub ::std::os::raw::c_uint); +pub use self::cufftXtWorkAreaPolicy_t as cufftXtWorkAreaPolicy; + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetGPUs( + handle: cufftHandle, + nGPUs: ::std::os::raw::c_int, + whichGPUs: *mut ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtMalloc( + plan: cufftHandle, + descriptor: *mut *mut cudaLibXtDesc, + format: cufftXtSubFormat, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtMemcpy( + plan: cufftHandle, + dstPointer: *mut ::std::os::raw::c_void, + srcPointer: *mut ::std::os::raw::c_void, + type_: cufftXtCopyType, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtFree(descriptor: *mut cudaLibXtDesc) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetWorkArea( + plan: cufftHandle, + workArea: *mut *mut ::std::os::raw::c_void, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorC2C( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorR2C( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorC2R( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorZ2Z( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorD2Z( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptorZ2D( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtQueryPlan( + plan: cufftHandle, + queryStruct: *mut ::std::os::raw::c_void, + queryType: cufftXtQueryType, +) -> cufftResult { + crate::unsupported() +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_LD_COMPLEX: cufftXtCallbackType_t = cufftXtCallbackType_t(0); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_LD_COMPLEX_DOUBLE: cufftXtCallbackType_t = cufftXtCallbackType_t(1); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_LD_REAL: cufftXtCallbackType_t = cufftXtCallbackType_t(2); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_LD_REAL_DOUBLE: cufftXtCallbackType_t = cufftXtCallbackType_t(3); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_ST_COMPLEX: cufftXtCallbackType_t = cufftXtCallbackType_t(4); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_ST_COMPLEX_DOUBLE: cufftXtCallbackType_t = cufftXtCallbackType_t(5); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_ST_REAL: cufftXtCallbackType_t = cufftXtCallbackType_t(6); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_ST_REAL_DOUBLE: cufftXtCallbackType_t = cufftXtCallbackType_t(7); +} +impl cufftXtCallbackType_t { + pub const CUFFT_CB_UNDEFINED: cufftXtCallbackType_t = cufftXtCallbackType_t(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cufftXtCallbackType_t(pub ::std::os::raw::c_uint); +pub use self::cufftXtCallbackType_t as cufftXtCallbackType; + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetCallback( + plan: cufftHandle, + callback_routine: *mut *mut ::std::os::raw::c_void, + cbType: cufftXtCallbackType, + caller_info: *mut *mut ::std::os::raw::c_void, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtClearCallback( + plan: cufftHandle, + cbType: cufftXtCallbackType, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetCallbackSharedSize( + plan: cufftHandle, + cbType: cufftXtCallbackType, + sharedSize: usize, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtMakePlanMany( + plan: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + inputtype: cudaDataType, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + outputtype: cudaDataType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, + executiontype: cudaDataType, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtGetSizeMany( + plan: cufftHandle, + rank: ::std::os::raw::c_int, + n: *mut ::std::os::raw::c_longlong, + inembed: *mut ::std::os::raw::c_longlong, + istride: ::std::os::raw::c_longlong, + idist: ::std::os::raw::c_longlong, + inputtype: cudaDataType, + onembed: *mut ::std::os::raw::c_longlong, + ostride: ::std::os::raw::c_longlong, + odist: ::std::os::raw::c_longlong, + outputtype: cudaDataType, + batch: ::std::os::raw::c_longlong, + workSize: *mut usize, + executiontype: cudaDataType, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExec( + plan: cufftHandle, + input: *mut ::std::os::raw::c_void, + output: *mut ::std::os::raw::c_void, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtExecDescriptor( + plan: cufftHandle, + input: *mut cudaLibXtDesc, + output: *mut cudaLibXtDesc, + direction: ::std::os::raw::c_int, +) -> cufftResult { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetWorkAreaPolicy( + plan: cufftHandle, + policy: cufftXtWorkAreaPolicy, + workSize: *mut usize, +) -> cufftResult { + crate::unsupported() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cufftBox3d_t { + pub lower: [usize; 3usize], + pub upper: [usize; 3usize], + pub strides: [usize; 3usize], +} +pub type cufftBox3d = cufftBox3d_t; + +#[no_mangle] +pub unsafe extern "system" fn cufftXtSetDistribution( + plan: cufftHandle, + box_in: *const cufftBox3d, + box_out: *const cufftBox3d, +) -> cufftResult { + crate::unsupported() +} diff --git a/zluda_fft/src/lib.rs b/zluda_fft/src/lib.rs new file mode 100644 index 0000000..20962c1 --- /dev/null +++ b/zluda_fft/src/lib.rs @@ -0,0 +1,253 @@ +#[allow(warnings)] +mod cufft; +pub use cufft::*; + +#[allow(warnings)] +mod cufftxt; +pub use cufftxt::*; + +use cuda_types::*; +use hipfft_sys::*; +use lazy_static::lazy_static; +use slab::Slab; +use std::{mem, ptr, sync::Mutex}; + +#[cfg(debug_assertions)] +pub(crate) fn unsupported() -> cufftResult { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unsupported() -> cufftResult { + cufftResult::CUFFT_NOT_SUPPORTED +} + +lazy_static! { + static ref PLANS: Mutex> = Mutex::new(Slab::new()); +} + +struct Plan(hipfftHandle); +unsafe impl Send for Plan {} + +unsafe fn create(handle: *mut cufftHandle) -> cufftResult { + let mut hip_handle = unsafe { mem::zeroed() }; + let error = hipfftCreate(&mut hip_handle); + if error != hipfftResult::HIPFFT_SUCCESS { + return cufftResult::CUFFT_INTERNAL_ERROR; + } + let plan_key = { + let mut plans = PLANS.lock().unwrap(); + plans.insert(Plan(hip_handle)) + }; + *handle = plan_key as i32; + cufftResult::CUFFT_SUCCESS +} + +fn destroy(plan: i32) -> cufftResult_t { + let mut plans = PLANS.lock().unwrap(); + plans.remove(plan as usize); + cufftResult::CUFFT_SUCCESS +} + +unsafe fn make_plan_many_64( + plan: i32, + rank: i32, + n: *mut i64, + inembed: *mut i64, + istride: i64, + idist: i64, + onembed: *mut i64, + ostride: i64, + odist: i64, + type_: cufftType, + batch: i64, + work_size: *mut usize, +) -> cufftResult_t { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + let type_ = cuda_type(type_); + to_cuda(hipfftMakePlanMany64( + hip_plan, rank, n, inembed, istride, idist, onembed, ostride, odist, type_, batch, + work_size, + )) +} + +fn cuda_type(type_: cufftType) -> hipfftType_t { + match type_ { + cufftType::CUFFT_R2C => hipfftType_t::HIPFFT_R2C, + cufftType::CUFFT_C2R => hipfftType_t::HIPFFT_C2R, + cufftType::CUFFT_C2C => hipfftType_t::HIPFFT_C2C, + cufftType::CUFFT_D2Z => hipfftType_t::HIPFFT_D2Z, + cufftType::CUFFT_Z2D => hipfftType_t::HIPFFT_Z2D, + cufftType::CUFFT_Z2Z => hipfftType_t::HIPFFT_Z2Z, + _ => panic!(), + } +} + +fn get_hip_plan(plan: cufftHandle) -> Result { + let plans = PLANS.lock().unwrap(); + plans + .get(plan as usize) + .map(|p| p.0) + .ok_or(cufftResult_t::CUFFT_INVALID_PLAN) +} + +fn to_cuda(result: hipfftResult) -> cufftResult_t { + match result { + hipfftResult::HIPFFT_SUCCESS => cufftResult_t::CUFFT_SUCCESS, + _ => cufftResult_t::CUFFT_INTERNAL_ERROR, + } +} + +unsafe fn make_plan_many( + plan: i32, + rank: i32, + n: *mut i32, + inembed: *mut i32, + istride: i32, + idist: i32, + onembed: *mut i32, + ostride: i32, + odist: i32, + type_: cufftType, + batch: i32, + work_size: *mut usize, +) -> cufftResult_t { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + let type_ = cuda_type(type_); + to_cuda(hipfftMakePlanMany( + hip_plan, rank, n, inembed, istride, idist, onembed, ostride, odist, type_, batch, + work_size, + )) +} + +unsafe fn plan_many( + plan: *mut i32, + rank: i32, + n: *mut i32, + inembed: *mut i32, + istride: i32, + idist: i32, + onembed: *mut i32, + ostride: i32, + odist: i32, + type_: cufftType, + batch: i32, +) -> cufftResult_t { + let type_ = cuda_type(type_); + let mut hip_plan = mem::zeroed(); + let result = to_cuda(hipfftPlanMany( + &mut hip_plan, + rank, + n, + inembed, + istride, + idist, + onembed, + ostride, + odist, + type_, + batch, + )); + if result != cufftResult_t::CUFFT_SUCCESS { + return result; + } + let plan_key = { + let mut plans = PLANS.lock().unwrap(); + plans.insert(Plan(hip_plan)) + }; + *plan = plan_key as i32; + result +} + +unsafe fn set_stream(plan: i32, stream: *mut cufft::CUstream_st) -> cufftResult_t { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + let lib = hip_common::zluda_ext::get_cuda_library().unwrap(); + let cu_get_export_table = lib + .get:: CUresult>(b"cuGetExportTable\0") + .unwrap(); + let mut export_table = ptr::null(); + let error = (cu_get_export_table)(&mut export_table, &zluda_dark_api::ZludaExt::GUID); + assert_eq!(error, CUresult::CUDA_SUCCESS); + let zluda_ext = zluda_dark_api::ZludaExt::new(export_table); + let stream: Result<_, _> = zluda_ext.get_hip_stream(stream as _).into(); + to_cuda(hipfftSetStream(hip_plan, stream.unwrap() as _)) +} + +unsafe fn exec_c2c( + plan: i32, + idata: *mut cufft::float2, + odata: *mut cufft::float2, + direction: i32, +) -> cufftResult_t { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + to_cuda(hipfftExecC2C( + hip_plan, + idata.cast(), + odata.cast(), + direction, + )) +} + +unsafe fn exec_z2z( + plan: i32, + idata: *mut cufft::double2, + odata: *mut cufft::double2, + direction: i32, +) -> cufftResult { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + to_cuda(hipfftExecZ2Z( + hip_plan, + idata.cast(), + odata.cast(), + direction, + )) +} + +unsafe fn exec_r2c(plan: i32, idata: *mut f32, odata: *mut cufft::float2) -> cufftResult { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + to_cuda(hipfftExecR2C(hip_plan, idata, odata.cast())) +} + +unsafe fn exec_c2r(plan: i32, idata: *mut cufft::float2, odata: *mut f32) -> cufftResult { + let hip_plan = match get_hip_plan(plan) { + Ok(p) => p, + Err(e) => return e, + }; + to_cuda(hipfftExecC2R(hip_plan, idata.cast(), odata)) +} + +unsafe fn plan_3d(plan: *mut i32, nx: i32, ny: i32, nz: i32, type_: cufftType) -> cufftResult { + let type_ = cuda_type(type_); + let mut hip_plan = mem::zeroed(); + let result = to_cuda(hipfftPlan3d(&mut hip_plan, nx, ny, nz, type_)); + if result != cufftResult_t::CUFFT_SUCCESS { + return result; + } + let plan_key = { + let mut plans = PLANS.lock().unwrap(); + plans.insert(Plan(hip_plan)) + }; + *plan = plan_key as i32; + result +} diff --git a/zluda_inject/Cargo.toml b/zluda_inject/Cargo.toml index 1181a21..c1a7066 100644 --- a/zluda_inject/Cargo.toml +++ b/zluda_inject/Cargo.toml @@ -5,9 +5,23 @@ authors = ["Andrzej Janik "] edition = "2018" [[bin]] -name = "zluda_with" +name = "zluda" path = "src/main.rs" [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["jobapi2", "processthreadsapi", "synchapi", "winbase", "std"] } +winapi = { version = "0.3.9", features = ["jobapi", "jobapi2", "processenv", "processthreadsapi", "synchapi", "winbase", "std"] } +tempfile = "3" +argh = "0.1" detours-sys = { path = "../detours-sys" } + +[dev-dependencies] +# all of those are used in integration tests +zluda_redirect = { path = "../zluda_redirect" } +zluda_dump = { path = "../zluda_dump" } +zluda_ml = { path = "../zluda_ml" } + +[build-dependencies] +embed-manifest = "1.3.1" + +[package.metadata.zluda] +windows_only = true diff --git a/zluda_inject/build.rs b/zluda_inject/build.rs new file mode 100644 index 0000000..591815a --- /dev/null +++ b/zluda_inject/build.rs @@ -0,0 +1,96 @@ +use embed_manifest::{embed_manifest, new_manifest}; +use std::{ + env::{self, VarError}, + fs::{self, DirEntry}, + io, + path::{self, PathBuf}, + process::Command, +}; + +fn main() -> Result<(), VarError> { + if std::env::var_os("CARGO_CFG_WINDOWS").is_some() { + embed_manifest(new_manifest("zluda_with")).expect("unable to embed manifest file"); + } + println!("cargo:rerun-if-changed=build.rs"); + if env::var("PROFILE")? != "debug" { + return Ok(()); + } + if env::var("CARGO_CFG_TARGET_OS")? != "windows" { + return Ok(()); + } + let rustc_exe = env::var("RUSTC")?; + let out_dir = env::var("OUT_DIR")?; + let target = env::var("TARGET")?; + let is_msvc = env::var("CARGO_CFG_TARGET_ENV")? == "msvc"; + let opt_level = env::var("OPT_LEVEL")?; + let debug = str::parse::(env::var("DEBUG")?.as_str()).unwrap(); + let mut helpers_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); + helpers_dir.push("tests"); + helpers_dir.push("helpers"); + let helpers_dir_as_string = helpers_dir.to_string_lossy(); + println!("cargo:rerun-if-changed={}", helpers_dir_as_string); + for rust_file in fs::read_dir(&helpers_dir).unwrap().filter_map(rust_file) { + let full_file_path = format!( + "{}{}{}", + helpers_dir_as_string, + path::MAIN_SEPARATOR, + rust_file + ); + let mut rustc_cmd = Command::new(&*rustc_exe); + if debug { + rustc_cmd.arg("-g"); + } + rustc_cmd.arg(format!("-Lnative={}", helpers_dir_as_string)); + if !is_msvc { + // HACK ALERT + // I have no idea why the extra library below has to be linked + rustc_cmd.arg(r"-lucrt"); + } else { + // For some reason rustc emits foobar.dll.lib and then expects foobar.lib + let mut implib_path = PathBuf::from(&out_dir); + let implib = PathBuf::from(rust_file); + implib_path.push(format!( + "{}.lib", + implib.file_stem().unwrap().to_string_lossy() + )); + let link_args = format!("link-args=/IMPLIB:{}", implib_path.as_path().display()); + rustc_cmd.args(["-C", link_args.as_str()]); + } + rustc_cmd + .arg("-ldylib=nvcuda") + .arg("-C") + .arg(format!("opt-level={}", opt_level)) + .arg("-L") + .arg(format!("{}", out_dir)) + .arg("--out-dir") + .arg(format!("{}", out_dir)) + .arg("--target") + .arg(format!("{}", target)) + .arg(full_file_path); + assert!(rustc_cmd.status().unwrap().success()); + } + std::fs::copy( + format!( + "{}{}do_cuinit_late_clr.exe", + helpers_dir_as_string, + path::MAIN_SEPARATOR + ), + format!("{}{}do_cuinit_late_clr.exe", out_dir, path::MAIN_SEPARATOR), + ) + .unwrap(); + println!("cargo:rustc-env=HELPERS_OUT_DIR={}", &out_dir); + Ok(()) +} + +fn rust_file(entry: io::Result) -> Option { + entry.ok().and_then(|e| { + let os_file_name = e.file_name(); + let file_name = os_file_name.to_string_lossy(); + let is_file = e.file_type().ok().map(|t| t.is_file()).unwrap_or(false); + if is_file && file_name.ends_with(".rs") { + Some(file_name.to_string()) + } else { + None + } + }) +} diff --git a/zluda_inject/src/bin.rs b/zluda_inject/src/bin.rs index ce83fe9..df664cf 100644 --- a/zluda_inject/src/bin.rs +++ b/zluda_inject/src/bin.rs @@ -1,10 +1,14 @@ -use std::mem; -use std::path::Path; -use std::ptr; -use std::{env, ops::Deref}; +use std::env; +use std::os::windows; +use std::os::windows::ffi::OsStrExt; use std::{error::Error, process}; +use std::{fs, io, ptr}; +use std::{mem, path::PathBuf}; +use argh::FromArgs; use mem::size_of_val; +use tempfile::TempDir; +use winapi::um::processenv::SearchPathW; use winapi::um::{ jobapi2::{AssignProcessToJobObject, SetInformationJobObject}, processthreadsapi::{GetExitCodeProcess, ResumeThread}, @@ -19,26 +23,62 @@ use winapi::um::{ use winapi::um::winbase::{INFINITE, WAIT_FAILED}; static REDIRECT_DLL: &'static str = "zluda_redirect.dll"; -static ZLUDA_DLL: &'static str = "nvcuda.dll"; +static NVCUDA_DLL: &'static str = "nvcuda.dll"; +static NVML_DLL: &'static str = "nvml.dll"; +static NVAPI_DLL: &'static str = "nvapi64.dll"; +static NVOPTIX_DLL: &'static str = "optix.6.6.0.dll"; include!("../../zluda_redirect/src/payload_guid.rs"); +#[derive(FromArgs)] +/// Launch application with custom CUDA libraries +struct ProgramArguments { + /// DLL to be injected instead of system nvcuda.dll. If not provided {0}, will use nvcuda.dll from its own directory + #[argh(option)] + nvcuda: Option, + + /// DLL to be injected instead of system nvml.dll. If not provided {0}, will use nvml.dll from its own directory + #[argh(option)] + nvml: Option, + + /// DLL to be injected instead of system nvapi64.dll. If not provided, no injection will take place + #[argh(option)] + nvapi: Option, + + /// DLL to be injected instead of system nvoptix.dll. If not provided, no injection will take place + #[argh(option)] + nvoptix: Option, + + /// executable to be injected with custom CUDA libraries + #[argh(positional)] + exe: String, + + /// arguments to the executable + #[argh(positional)] + args: Vec, +} + pub fn main_impl() -> Result<(), Box> { - let args = env::args().collect::>(); - if args.len() <= 1 { - print_help_and_exit(); - } - let injector_path = env::current_exe()?; - let injector_dir = injector_path.parent().unwrap(); - let redirect_path = create_redirect_path(injector_dir); - let (mut inject_path, cmd) = create_inject_path(&args[1..], injector_dir); - let mut cmd_line = construct_command_line(cmd); + let raw_args = argh::from_env::(); + let normalized_args = NormalizedArguments::new(raw_args)?; + let mut environment = Environment::setup(normalized_args)?; let mut startup_info = unsafe { mem::zeroed::() }; let mut proc_info = unsafe { mem::zeroed::() }; + let mut dlls_to_inject = vec![ + environment.nvcuda_path_zero_terminated.as_ptr() as _, + environment.nvml_path_zero_terminated.as_ptr() as *const i8, + environment.redirect_path_zero_terminated.as_ptr() as _, + ]; + if let Some(ref nvapi) = environment.nvapi_path_zero_terminated { + dlls_to_inject.push(nvapi.as_ptr() as _); + } + if let Some(ref nvoptix) = environment.nvoptix_path_zero_terminated { + dlls_to_inject.push(nvoptix.as_ptr() as _); + } os_call!( - detours_sys::DetourCreateProcessWithDllExW( + detours_sys::DetourCreateProcessWithDllsW( ptr::null(), - cmd_line.as_mut_ptr(), + environment.winapi_command_line_zero_terminated.as_mut_ptr(), ptr::null_mut(), ptr::null_mut(), 0, @@ -47,7 +87,8 @@ pub fn main_impl() -> Result<(), Box> { ptr::null(), &mut startup_info as *mut _, &mut proc_info as *mut _, - redirect_path.as_ptr() as *const i8, + dlls_to_inject.len() as u32, + dlls_to_inject.as_mut_ptr(), Option::None ), |x| x != 0 @@ -56,12 +97,43 @@ pub fn main_impl() -> Result<(), Box> { os_call!( detours_sys::DetourCopyPayloadToProcess( proc_info.hProcess, - &PAYLOAD_GUID, - inject_path.as_mut_ptr() as *mut _, - (inject_path.len() * mem::size_of::()) as u32 + &PAYLOAD_NVCUDA_GUID, + environment.nvcuda_path_zero_terminated.as_ptr() as *mut _, + environment.nvcuda_path_zero_terminated.len() as u32 ), |x| x != 0 ); + os_call!( + detours_sys::DetourCopyPayloadToProcess( + proc_info.hProcess, + &PAYLOAD_NVML_GUID, + environment.nvml_path_zero_terminated.as_ptr() as *mut _, + environment.nvml_path_zero_terminated.len() as u32 + ), + |x| x != 0 + ); + if let Some(nvapi) = environment.nvapi_path_zero_terminated { + os_call!( + detours_sys::DetourCopyPayloadToProcess( + proc_info.hProcess, + &PAYLOAD_NVAPI_GUID, + nvapi.as_ptr() as *mut _, + nvapi.len() as u32 + ), + |x| x != 0 + ); + } + if let Some(nvoptix) = environment.nvoptix_path_zero_terminated { + os_call!( + detours_sys::DetourCopyPayloadToProcess( + proc_info.hProcess, + &PAYLOAD_NVOPTIX_GUID, + nvoptix.as_ptr() as *mut _, + nvoptix.len() 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); @@ -73,6 +145,168 @@ pub fn main_impl() -> Result<(), Box> { process::exit(child_exit_code as i32) } +struct NormalizedArguments { + nvcuda_path: PathBuf, + nvml_path: PathBuf, + nvapi_path: Option, + nvoptix_path: Option, + redirect_path: PathBuf, + winapi_command_line_zero_terminated: Vec, +} + +impl NormalizedArguments { + fn new(prog_args: ProgramArguments) -> Result> { + let current_exe = env::current_exe()?; + let nvcuda_path = + Self::get_absolute_path_or_default(¤t_exe, prog_args.nvcuda, NVCUDA_DLL)?; + let nvml_path = Self::get_absolute_path_or_default(¤t_exe, prog_args.nvml, NVML_DLL)?; + let nvapi_path = prog_args.nvapi.map(Self::get_absolute_path).transpose()?; + let nvoptix_path = prog_args.nvoptix.map(Self::get_absolute_path).transpose()?; + let winapi_command_line_zero_terminated = + construct_command_line(std::iter::once(prog_args.exe).chain(prog_args.args)); + let mut redirect_path = current_exe.parent().unwrap().to_path_buf(); + redirect_path.push(REDIRECT_DLL); + Ok(Self { + nvcuda_path, + nvml_path, + nvapi_path, + nvoptix_path, + redirect_path, + winapi_command_line_zero_terminated, + }) + } + + const WIN_MAX_PATH: usize = 260; + + fn get_absolute_path_or_default( + current_exe: &PathBuf, + dll: Option, + default: &str, + ) -> Result> { + if let Some(dll) = dll { + Self::get_absolute_path(dll) + } else { + let mut dll_path = current_exe.parent().unwrap().to_path_buf(); + dll_path.push(default); + Ok(dll_path) + } + } + + fn get_absolute_path(dll: PathBuf) -> Result> { + Ok(if dll.is_absolute() { + dll + } else { + let mut full_dll_path = vec![0; Self::WIN_MAX_PATH]; + let mut dll_utf16 = dll.as_os_str().encode_wide().collect::>(); + dll_utf16.push(0); + loop { + let copied_len = os_call!( + SearchPathW( + ptr::null_mut(), + dll_utf16.as_ptr(), + ptr::null(), + full_dll_path.len() as u32, + full_dll_path.as_mut_ptr(), + ptr::null_mut() + ), + |x| x != 0 + ) as usize; + if copied_len > full_dll_path.len() { + full_dll_path.resize(copied_len + 1, 0); + } else { + full_dll_path.truncate(copied_len); + break; + } + } + PathBuf::from(String::from_utf16_lossy(&full_dll_path)) + }) + } +} + +struct Environment { + nvcuda_path_zero_terminated: String, + nvml_path_zero_terminated: String, + nvapi_path_zero_terminated: Option, + nvoptix_path_zero_terminated: Option, + redirect_path_zero_terminated: String, + winapi_command_line_zero_terminated: Vec, + _temp_dir: TempDir, +} + +// This structs represents "environment". By environment we mean all paths +// (nvcuda.dll, nvml.dll, etc.) and all related resources like the temporary +// directory which contains nvcuda.dll +impl Environment { + fn setup(args: NormalizedArguments) -> io::Result { + let _temp_dir = TempDir::new()?; + let nvcuda_path_zero_terminated = Self::zero_terminate(Self::copy_to_correct_name( + args.nvcuda_path, + &_temp_dir, + NVCUDA_DLL, + )?); + let nvml_path_zero_terminated = Self::zero_terminate(Self::copy_to_correct_name( + args.nvml_path, + &_temp_dir, + NVML_DLL, + )?); + let nvapi_path_zero_terminated = args + .nvapi_path + .map(|nvapi| { + Ok::<_, io::Error>(Self::zero_terminate(Self::copy_to_correct_name( + nvapi, &_temp_dir, NVAPI_DLL, + )?)) + }) + .transpose()?; + let nvoptix_path_zero_terminated = args + .nvoptix_path + .map(|nvoptix| { + Ok::<_, io::Error>(Self::zero_terminate(Self::copy_to_correct_name( + nvoptix, + &_temp_dir, + NVOPTIX_DLL, + )?)) + }) + .transpose()?; + let redirect_path_zero_terminated = Self::zero_terminate(args.redirect_path); + Ok(Self { + nvcuda_path_zero_terminated, + nvml_path_zero_terminated, + nvapi_path_zero_terminated, + nvoptix_path_zero_terminated, + redirect_path_zero_terminated, + winapi_command_line_zero_terminated: args.winapi_command_line_zero_terminated, + _temp_dir, + }) + } + + fn copy_to_correct_name( + path_buf: PathBuf, + temp_dir: &TempDir, + correct_name: &str, + ) -> io::Result { + let file_name = path_buf.file_name().unwrap(); + if file_name == correct_name { + Ok(path_buf) + } else { + let mut temp_file_path = temp_dir.path().to_path_buf(); + temp_file_path.push(correct_name); + match windows::fs::symlink_file(&path_buf, &temp_file_path) { + Ok(()) => {} + Err(_) => { + fs::copy(&path_buf, &temp_file_path)?; + } + } + Ok(temp_file_path) + } + } + + fn zero_terminate(p: PathBuf) -> String { + let mut s = p.to_string_lossy().to_string(); + s.push('\0'); + s + } +} + fn kill_child_on_process_exit(child: HANDLE) -> Result<(), Box> { let job_handle = os_call!(CreateJobObjectA(ptr::null_mut(), ptr::null()), |x| x != ptr::null_mut()); @@ -91,29 +325,11 @@ fn kill_child_on_process_exit(child: HANDLE) -> Result<(), Box> { Ok(()) } -fn print_help_and_exit() -> ! { - let current_exe = env::current_exe().unwrap(); - let exe_name = current_exe.file_name().unwrap().to_string_lossy(); - println!( - "USAGE: - {0} -- [ARGS]... - {0} -- [ARGS]... -ARGS: - DLL to ne injected instead of system nvcuda.dll, if not provided - will use nvcuda.dll from the directory where {0} is located - Path to the executable to be injected with - ... Arguments that will be passed to -", - exe_name - ); - process::exit(1) -} - // Adapted from https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way -fn construct_command_line(args: &[String]) -> Vec { +fn construct_command_line(args: impl Iterator) -> Vec { let mut cmd_line = Vec::new(); - let args_len = args.len(); - for (idx, arg) in args.iter().enumerate() { + let args_len = args.size_hint().0; + for (idx, arg) in args.enumerate() { if !arg.contains(&[' ', '\t', '\n', '\u{2B7F}', '\"'][..]) { cmd_line.extend(arg.encode_utf16()); } else { @@ -164,31 +380,3 @@ fn construct_command_line(args: &[String]) -> Vec { cmd_line.push(0); cmd_line } - -fn create_redirect_path(injector_dir: &Path) -> Vec { - let mut injector_dir = injector_dir.to_path_buf(); - injector_dir.push(REDIRECT_DLL); - let mut result = injector_dir.to_string_lossy().into_owned().into_bytes(); - result.push(0); - result -} - -fn create_inject_path<'a>(args: &'a [String], injector_dir: &Path) -> (Vec, &'a [String]) { - if args.get(0).map(Deref::deref) == Some("--") { - let mut injector_dir = injector_dir.to_path_buf(); - injector_dir.push(ZLUDA_DLL); - let mut result = injector_dir - .to_string_lossy() - .as_ref() - .encode_utf16() - .collect::>(); - result.push(0); - (result, &args[1..]) - } else if args.get(1).map(Deref::deref) == Some("--") { - let mut dll_path = args[0].encode_utf16().collect::>(); - dll_path.push(0); - (dll_path, &args[2..]) - } else { - print_help_and_exit() - } -} diff --git a/zluda_inject/tests/helpers/direct_cuinit.rs b/zluda_inject/tests/helpers/direct_cuinit.rs new file mode 100644 index 0000000..8341a60 --- /dev/null +++ b/zluda_inject/tests/helpers/direct_cuinit.rs @@ -0,0 +1,9 @@ +#![crate_type = "bin"] + +extern "system" { + fn cuInit(flags: u32) -> u32; +} + +fn main() { + unsafe { cuInit(0) }; +} diff --git a/zluda_inject/tests/helpers/do_cuinit.rs b/zluda_inject/tests/helpers/do_cuinit.rs new file mode 100644 index 0000000..468d56c --- /dev/null +++ b/zluda_inject/tests/helpers/do_cuinit.rs @@ -0,0 +1,10 @@ +#![crate_type = "cdylib"] + +extern "system" { + fn cuInit(flags: u32) -> u32; +} + +#[no_mangle] +unsafe extern "system" fn do_cuinit(flags: u32) -> u32 { + cuInit(flags) +} diff --git a/zluda_inject/tests/helpers/do_cuinit_early.rs b/zluda_inject/tests/helpers/do_cuinit_early.rs new file mode 100644 index 0000000..9743f4a --- /dev/null +++ b/zluda_inject/tests/helpers/do_cuinit_early.rs @@ -0,0 +1,10 @@ +#![crate_type = "bin"] + +#[link(name = "do_cuinit")] +extern "system" { + fn do_cuinit(flags: u32) -> u32; +} + +fn main() { + unsafe { do_cuinit(0) }; +} diff --git a/zluda_inject/tests/helpers/do_cuinit_late.rs b/zluda_inject/tests/helpers/do_cuinit_late.rs new file mode 100644 index 0000000..ab3516d --- /dev/null +++ b/zluda_inject/tests/helpers/do_cuinit_late.rs @@ -0,0 +1,23 @@ +#![crate_type = "bin"] + +use std::ffi::c_void; +use std::mem; +use std::env; +use std::path::PathBuf; +use std::ffi::CString; + +extern "system" { + fn LoadLibraryA(lpFileName: *const i8) -> *mut c_void; + fn GetProcAddress(hModule: *mut c_void, lpProcName: *const u8) -> *mut c_void; +} + +fn main() { + let current_exe = env::current_exe().unwrap(); + let mut dll = PathBuf::from(current_exe.parent().unwrap()); + dll.push("do_cuinit.dll"); + let dll_cstring = CString::new(dll.to_str().unwrap()).unwrap(); + let nvcuda = unsafe { LoadLibraryA(dll_cstring.as_ptr()) }; + let cu_init = unsafe { GetProcAddress(nvcuda, b"do_cuinit\0".as_ptr()) }; + let cu_init = unsafe { mem::transmute::<_, unsafe extern "system" fn(u32) -> u32>(cu_init) }; + unsafe { cu_init(0) }; +} diff --git a/zluda_inject/tests/helpers/do_cuinit_late_clr.cs b/zluda_inject/tests/helpers/do_cuinit_late_clr.cs new file mode 100644 index 0000000..666c237 --- /dev/null +++ b/zluda_inject/tests/helpers/do_cuinit_late_clr.cs @@ -0,0 +1,34 @@ +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace Zluda +{ + class Program + { + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate int CuInit(int flags); + + static int Main(string[] args) + { + DirectoryInfo exeDirectory = Directory.GetParent(Assembly.GetEntryAssembly().Location); + string dllPath = Path.Combine(exeDirectory.ToString(), "do_cuinit.dll"); + IntPtr nvcuda = NativeMethods.LoadLibrary(dllPath); + if (nvcuda == IntPtr.Zero) + return 1; + IntPtr doCuinitPtr = NativeMethods.GetProcAddress(nvcuda, "do_cuinit"); + CuInit cuinit = (CuInit)Marshal.GetDelegateForFunctionPointer(doCuinitPtr, typeof(CuInit)); + return cuinit(0); + } + } + + static class NativeMethods + { + [DllImport("kernel32.dll")] + public static extern IntPtr LoadLibrary(string dllToLoad); + + [DllImport("kernel32.dll")] + public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); + } +} \ No newline at end of file diff --git a/zluda_inject/tests/helpers/do_cuinit_late_clr.exe b/zluda_inject/tests/helpers/do_cuinit_late_clr.exe new file mode 100644 index 0000000000000000000000000000000000000000..b8e497548df827757fa72eff3987701293f7b812 GIT binary patch literal 4608 zcmeHKO>7&-6@I&-D2k30{WuQY*v*DY5amad6bZ0vNHS^tI5Z@SkYqJ*1Ix?hh}?R) zOV92yVvzSDH*daqGxLUCy7&rp5K#=@?b}4}p=HV{{-4=4%)Jj@>!o+PZ$9*% zws`ZQwTkTFpF2sb2!pIh3-hkm9G%Kn(BPyK7RO*L|%*ARD^ zANXQbY{2C@`s#P5M$G+lRh$t-p3pobbLJ9|3rgh zI$gyGjP0l4PGI#ABRPy^CX;awyP1@*)rPwv9qJm!*^A$kcmXR)4j%#=?CkG+vh)7I z_!FZEd7K@wDe<1}57FquSY2|s2P|N9FxDSC!r|j^r~dfkX??gCMtU3zT|IY3Q>%z_ zQlHF>WhTZZ#=phO=_Cidgd7dMfE=Lxl;zbx+HTorj~jqKiFWA1Dt!)_Q#o|@LVgZy z3{&1<{fy%k(K2DUcJ@B~a5n_{mo`C1q8tuF1y;4aSRVnO(wq5J+tiY|CAwdW+Bp4% zX7o6Hq4*p0rFJh}Li9NORIh1q`n8sX{7daY_`FNZUnTB;OxfCJx?hA zf2#hMl;=6cS5<^xK<3$_xueYWQAImU_n}XtZLN>`^+@ZW4!HdcSRR3;lL`ipe3hQl zo`HT-X+KGQhM74Td?kNwe4t<2rETe!syci}+0#Z8rVjd}HcKAyrHHf{3YsN=ZIkqU z;w)<9BeX_CN_N3@sw??r^y@UDY~3 z8f|OI+pt30wS$eSX}cSiBQs(P2)*bkQ^5=>l=B;|HETLf(X_6R)e@FW=~qmLt_bN0 zXX2?05=e#U@oHw7mJpT7BG_2;EQPF<{uQz52(=>O$S51Lo?914t>@C5En)LyBkyi{ zbWuo;bKFYQf+zQ7gAOi(G8};NZcqqhYtlK}EW4hMy!&(>aOz@7?X=%=XeKLzVVJbG zDrDWZ!~t`Zb0K%^(bi!R*mt;ZIwq>1DZzjnDY0^;k`%sA%f;_vW#mQ8Y?w#tDWBs6 zuLvJUg5bstk259m!P2}N$VSfhMYZTOh>z%^U6iJ5v@=CsZDamwX!7=|ga1GYbzp-m z3UL!%d;xA%33VHld+?x*$E;t^zw!6NwfwciAKm)RpXhap8Jd>pFi7i!(BH54@k3o* z14nyPsewK{fg3k44u{@O($LvSdT(#99#28gQ>i#QbN%yOqz^2m26BmazxV9=(aBF< zgmdC}Z;Z4Qk4S+Vx^^su*%FC_(J}B?VqoMLCQCrln$_!@TtwIOBj1*0?Y!sCZ&{+o zXJxG-z2|%leqE>lcqiDeN$)q`W>!CD*fYDO%!NI?*dxqGM=VbWG=0cb!(T z_vFwC_2&w@S4!Sy*u-{Zkcpl|E!TGZ=PzslR#tv# zYk1EXL76HTNo3%Qa4t9d`Sx+FR>oLs$DC9+3-I-DJ437|z`pH8+s4V5iB769IjqNr zXBF9TfWr8%<9>UF=x@kvi*8;2{nY8Ls${x}E1{N6r!TB6jGRmx zet>t*bUar~ryIggpPuPS_9UmwW$9ARz*}zf23+#((}E|V8rsOr%b<^ zsgI`(yk+*L@PqZ;^C6gF>;%h~_zegedobarCvdrVL#NYAja;qf;N|4opD}B-^k@_z zkf9&&gK?L5o=U56nA;atC^2VKM~@U&L*Nvpg0$;4-e=+8Wz>mQR0GtGgMwm(jCfJh zg=09(r_-h%{icv *mut c_void; + fn GetProcAddress(hModule: *mut c_void, lpProcName: *const u8) -> *mut c_void; +} + +fn main() { + let nvcuda = unsafe { LoadLibraryA(b"C:\\Windows\\System32\\nvcuda.dll\0".as_ptr()) }; + let cu_init = unsafe { GetProcAddress(nvcuda, b"cuInit\0".as_ptr()) }; + let cu_init = unsafe { mem::transmute::<_, unsafe extern "system" fn(u32) -> u32>(cu_init) }; + unsafe { cu_init(0) }; +} diff --git a/zluda_inject/tests/helpers/nvcuda.lib b/zluda_inject/tests/helpers/nvcuda.lib new file mode 100644 index 0000000000000000000000000000000000000000..b793c56e227f0c0374d75e2d6f88c58f5e86a9fd GIT binary patch literal 71050 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 jg{UL@#5yE~J1kGE)Emw_B io::Result<()> { + let status = Command::new("query.exe").arg("session").status()?; + // App returns 1 on my machine + assert_eq!(status.code(), Some(1)); + Ok(()) +} diff --git a/zluda_inject/tests/helpers/subprocess.rs b/zluda_inject/tests/helpers/subprocess.rs new file mode 100644 index 0000000..3d1588c --- /dev/null +++ b/zluda_inject/tests/helpers/subprocess.rs @@ -0,0 +1,10 @@ +#![crate_type = "bin"] + +use std::io; +use std::process::Command; + +fn main() -> io::Result<()> { + let status = Command::new("direct_cuinit.exe").status()?; + assert!(status.success()); + Ok(()) +} diff --git a/zluda_inject/tests/inject.rs b/zluda_inject/tests/inject.rs new file mode 100644 index 0000000..78f26f1 --- /dev/null +++ b/zluda_inject/tests/inject.rs @@ -0,0 +1,67 @@ +use std::{ + env, io, + path::PathBuf, + process::{Command, Output}, +}; + +#[test] +fn direct_cuinit() -> io::Result<()> { + run_process_and_check_for_zluda_dump("direct_cuinit") +} + +#[test] +fn do_cuinit_early() -> io::Result<()> { + run_process_and_check_for_zluda_dump("do_cuinit_early") +} + +#[test] +fn do_cuinit_late() -> io::Result<()> { + run_process_and_check_for_zluda_dump("do_cuinit_late") +} + +#[test] +fn do_cuinit_late_clr() -> io::Result<()> { + run_process_and_check_for_zluda_dump("do_cuinit_late_clr") +} + +#[test] +fn indirect_cuinit() -> io::Result<()> { + run_process_and_check_for_zluda_dump("indirect_cuinit") +} + +#[test] +fn subprocess() -> io::Result<()> { + run_process_and_check_for_zluda_dump("subprocess") +} + +#[test] +fn query_exe() -> io::Result<()> { + let process_output = run_process("query_exe")?; + let stdout_text = String::from_utf8(process_output.stdout).unwrap(); + assert!(stdout_text.contains("SESSIONNAME")); + Ok(()) +} + +fn run_process_and_check_for_zluda_dump(name: &'static str) -> io::Result<()> { + let process_output = run_process(name)?; + let stderr_text = String::from_utf8(process_output.stderr).unwrap(); + assert!(stderr_text.contains("ZLUDA_DUMP")); + Ok(()) +} + +fn run_process(name: &'static str) -> io::Result { + let zluda_with_exe = PathBuf::from(env!("CARGO_BIN_EXE_zluda_with")); + let mut zluda_dump_dll = zluda_with_exe.parent().unwrap().to_path_buf(); + zluda_dump_dll.push("zluda_dump.dll"); + let helpers_dir = env!("HELPERS_OUT_DIR"); + let exe_under_test = format!("{}{}{}.exe", helpers_dir, std::path::MAIN_SEPARATOR, name); + let mut test_cmd = Command::new(&zluda_with_exe); + let test_cmd = test_cmd + .arg("--nvcuda") + .arg(&zluda_dump_dll) + .arg("--") + .arg(&exe_under_test); + let test_output = test_cmd.output()?; + assert!(test_output.status.success()); + Ok(test_output) +} diff --git a/zluda_lib/Cargo.toml b/zluda_lib/Cargo.toml index 54a2d53..af94623 100644 --- a/zluda_lib/Cargo.toml +++ b/zluda_lib/Cargo.toml @@ -10,3 +10,7 @@ crate-type = ["cdylib"] [dependencies] zluda = { path = "../zluda" } + +[package.metadata.zluda] +linux_names = ["libcuda.so", "libcuda.so.1"] +skip_dump_link = true diff --git a/zluda_lib/src/lib.rs b/zluda_lib/src/lib.rs index a489d98..c8b3014 100644 --- a/zluda_lib/src/lib.rs +++ b/zluda_lib/src/lib.rs @@ -7,5 +7,5 @@ pub use zluda::cuda::*; // the function below stops it from doing so #[no_mangle] fn _zluda_very_bad_linker_hack() { - cuInit(0); + let _ = unsafe { cuInit(0) }; } diff --git a/zluda_llvm/Cargo.toml b/zluda_llvm/Cargo.toml new file mode 100644 index 0000000..5c6d4a3 --- /dev/null +++ b/zluda_llvm/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "zluda_llvm" +version = "0.0.0" +edition = "2018" + +[dependencies] +bitflags = "2.4" +llvm-sys = { path = "../ext/llvm-sys.rs" } + +[build-dependencies] +cc = "1.0.69" diff --git a/zluda_llvm/README.md b/zluda_llvm/README.md new file mode 100644 index 0000000..db44643 --- /dev/null +++ b/zluda_llvm/README.md @@ -0,0 +1,8 @@ +LLVM-C interfaces has a decent coverage, but it does not expose everything, +hence this project to fill in the gaps. +Compilation order: +* CMake generate llvm-project +* Compile llvm-config and build subset of LLVM components +* Link llvm-sys rust wrapper with LLVM componets +* Compile C++ code in zluda_llvm +* Link zluda_llvm Rust + zluda_llvm C++ + llvm-sys diff --git a/zluda_llvm/build.rs b/zluda_llvm/build.rs new file mode 100644 index 0000000..09d7196 --- /dev/null +++ b/zluda_llvm/build.rs @@ -0,0 +1,15 @@ +use std::env; + +fn main() { + println!("cargo:rerun-if-changed=src/lib.cpp"); + println!("cargo:rerun-if-changed=src/lib.rs"); + let llvm_cxxflags = env::var("DEP_LLVM_15_CXXFLAGS").unwrap(); + let mut cc = cc::Build::new(); + for flag in llvm_cxxflags.split_ascii_whitespace() { + cc.flag(flag); + } + cc.shared_flag(true) + .file("src/lib.cpp") + .compile("llvm_zluda_cpp"); + // rustc-link-lib and rustc-link-search are already set by cc +} diff --git a/zluda_llvm/src/lib.cpp b/zluda_llvm/src/lib.cpp new file mode 100644 index 0000000..a4f0eaf --- /dev/null +++ b/zluda_llvm/src/lib.cpp @@ -0,0 +1,161 @@ +// Some LLVM headers produce this warning, we'd like to pass them +// with -isystem, but it's currently impossible to do so +#if defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" +#endif +#include "llvm-c/Core.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/Support/Alignment.h" +#if defined(__GNUC__) + #pragma GCC diagnostic pop +#endif + +using namespace llvm; + +// Taken from Core.cpp +static AtomicRMWInst::BinOp mapFromLLVMRMWBinOp(LLVMAtomicRMWBinOp BinOp) +{ + switch (BinOp) + { + case LLVMAtomicRMWBinOpXchg: + return AtomicRMWInst::Xchg; + case LLVMAtomicRMWBinOpAdd: + return AtomicRMWInst::Add; + case LLVMAtomicRMWBinOpSub: + return AtomicRMWInst::Sub; + case LLVMAtomicRMWBinOpAnd: + return AtomicRMWInst::And; + case LLVMAtomicRMWBinOpNand: + return AtomicRMWInst::Nand; + case LLVMAtomicRMWBinOpOr: + return AtomicRMWInst::Or; + case LLVMAtomicRMWBinOpXor: + return AtomicRMWInst::Xor; + case LLVMAtomicRMWBinOpMax: + return AtomicRMWInst::Max; + case LLVMAtomicRMWBinOpMin: + return AtomicRMWInst::Min; + case LLVMAtomicRMWBinOpUMax: + return AtomicRMWInst::UMax; + case LLVMAtomicRMWBinOpUMin: + return AtomicRMWInst::UMin; + case LLVMAtomicRMWBinOpFAdd: + return AtomicRMWInst::FAdd; + case LLVMAtomicRMWBinOpFSub: + return AtomicRMWInst::FSub; + case LLVMAtomicRMWBinOpFMax: + return AtomicRMWInst::FMax; + case LLVMAtomicRMWBinOpFMin: + return AtomicRMWInst::FMin; + } + + llvm_unreachable("Invalid LLVMAtomicRMWBinOp value!"); +} + +// Taken from Core.cpp +static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) +{ + switch (Ordering) + { + case LLVMAtomicOrderingNotAtomic: + return AtomicOrdering::NotAtomic; + case LLVMAtomicOrderingUnordered: + return AtomicOrdering::Unordered; + case LLVMAtomicOrderingMonotonic: + return AtomicOrdering::Monotonic; + case LLVMAtomicOrderingAcquire: + return AtomicOrdering::Acquire; + case LLVMAtomicOrderingRelease: + return AtomicOrdering::Release; + case LLVMAtomicOrderingAcquireRelease: + return AtomicOrdering::AcquireRelease; + case LLVMAtomicOrderingSequentiallyConsistent: + return AtomicOrdering::SequentiallyConsistent; + } + + llvm_unreachable("Invalid LLVMAtomicOrdering value!"); +} + +LLVM_C_EXTERN_C_BEGIN + +LLVMValueRef LLVMZludaBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op, + LLVMValueRef PTR, LLVMValueRef Val, + char *scope, + LLVMAtomicOrdering ordering, + unsigned Align) +{ + AtomicRMWInst::BinOp intop = mapFromLLVMRMWBinOp(op); + IRBuilder<> *builder = unwrap(B); + LLVMContext &context = builder->getContext(); + SyncScope::ID syncScope = context.getOrInsertSyncScopeID(scope); + MaybeAlign maybeAlign = MaybeAlign(Align); + auto inst = builder->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), + maybeAlign, + mapFromLLVMOrdering(ordering), syncScope); + return wrap(inst); +} + +LLVMValueRef LLVMZludaBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, + LLVMValueRef Cmp, LLVMValueRef New, + char *scope, + LLVMAtomicOrdering SuccessOrdering, + LLVMAtomicOrdering FailureOrdering, + unsigned Align) +{ + IRBuilder<> *builder = unwrap(B); + LLVMContext &context = builder->getContext(); + SyncScope::ID syncScope = context.getOrInsertSyncScopeID(scope); + Value *newUnwrapped = unwrap(New); + MaybeAlign maybeAlign = MaybeAlign(Align); + auto inst = unwrap(B)->CreateAtomicCmpXchg( + unwrap(Ptr), unwrap(Cmp), newUnwrapped, maybeAlign, mapFromLLVMOrdering(SuccessOrdering), + mapFromLLVMOrdering(FailureOrdering), + syncScope); + return wrap(inst); +} + +void LLVMZludaSetFastMathFlags(LLVMValueRef Val, unsigned Flags) +{ + Instruction *I = dyn_cast(unwrap(Val)); + FastMathFlags flags = FastMathFlags(); + flags.setAllowReassoc((Flags & FastMathFlags::AllowReassoc) != 0); + flags.setNoNaNs((Flags & FastMathFlags::NoNaNs) != 0); + flags.setNoInfs((Flags & FastMathFlags::NoInfs) != 0); + flags.setNoSignedZeros((Flags & FastMathFlags::NoSignedZeros) != 0); + flags.setAllowReciprocal((Flags & FastMathFlags::AllowReciprocal) != 0); + flags.setAllowContract((Flags & FastMathFlags::AllowContract) != 0); + flags.setApproxFunc((Flags & FastMathFlags::ApproxFunc) != 0); + I->setFastMathFlags(flags); +} + +LLVMValueRef LLVMZludaBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering, + char *scope, const char *Name) +{ + IRBuilder<> *builder = unwrap(B); + SyncScope::ID syncScope = builder->getContext().getOrInsertSyncScopeID(scope); + return wrap( + builder->CreateFence(mapFromLLVMOrdering(Ordering), + syncScope, + Name)); +} + +LLVMValueRef LLVMZludaBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + unsigned AddrSpace, const char *Name) +{ + IRBuilder<> *builder = unwrap(B); + return wrap(builder->CreateAlloca(unwrap(Ty), AddrSpace, nullptr, Name)); +} + +void LLVMZludaSetAtomic(LLVMContextRef C, LLVMValueRef Val, LLVMAtomicOrdering Ordering, char *scope) +{ + LLVMContext *Ctx = unwrap(C); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + SyncScope::ID syncScope = Ctx->getOrInsertSyncScopeID(scope); + if (LoadInst *LI = dyn_cast(unwrap(Val))) + return LI->setAtomic(O, syncScope); + return cast(unwrap(Val))->setAtomic(O, syncScope); +} + +LLVM_C_EXTERN_C_END \ No newline at end of file diff --git a/zluda_llvm/src/lib.rs b/zluda_llvm/src/lib.rs new file mode 100644 index 0000000..96cbfe6 --- /dev/null +++ b/zluda_llvm/src/lib.rs @@ -0,0 +1,67 @@ +pub use llvm_sys::*; + +#[allow(non_upper_case_globals)] +pub mod zluda { + use bitflags::bitflags; + use llvm_sys::prelude::*; + use llvm_sys::*; + + bitflags! { + #[repr(transparent)] + pub struct FastMathFlags: u32 { + const AllowReassoc = 0b00000001; + const NoNaNs = 0b00000010; + const NoInfs = 0b00000100; + const NoSignedZeros = 0b00001000; + const AllowReciprocal = 0b00010000; + const AllowContract = 0b00100000; + const ApproxFunc = 0b01000000; + } + } + + extern "C" { + pub fn LLVMZludaBuildAtomicRMW( + B: LLVMBuilderRef, + op: LLVMAtomicRMWBinOp, + PTR: LLVMValueRef, + Val: LLVMValueRef, + scope: *const i8, + ordering: LLVMAtomicOrdering, + Align: u32, + ) -> LLVMValueRef; + + pub fn LLVMZludaBuildAtomicCmpXchg( + B: LLVMBuilderRef, + PTR: LLVMValueRef, + Cmp: LLVMValueRef, + New: LLVMValueRef, + scope: *const i8, + SuccessOrdering: LLVMAtomicOrdering, + FailureOrdering: LLVMAtomicOrdering, + Align: u32, + ) -> LLVMValueRef; + + pub fn LLVMZludaSetFastMathFlags(Val: LLVMValueRef, Flags: FastMathFlags); + + pub fn LLVMZludaBuildFence( + B: LLVMBuilderRef, + ordering: LLVMAtomicOrdering, + scope: *const i8, + Name: *const i8, + ) -> LLVMValueRef; + + pub fn LLVMZludaBuildAlloca( + B: LLVMBuilderRef, + Ty: LLVMTypeRef, + AddrSpace: u32, + Name: *const i8, + ) -> LLVMValueRef; + + pub fn LLVMZludaSetAtomic( + C: LLVMContextRef, + Val: LLVMValueRef, + Ordering: LLVMAtomicOrdering, + scope: *const i8, + ); + } +} diff --git a/zluda_ml/Cargo.toml b/zluda_ml/Cargo.toml new file mode 100644 index 0000000..25d88a9 --- /dev/null +++ b/zluda_ml/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "zluda_ml" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "nvml" +crate-type = ["cdylib"] + +[target.'cfg(windows)'.dependencies] +atiadlxx-sys = { path = "../atiadlxx-sys" } + +[target.'cfg(unix)'.dependencies] +rocm_smi-sys = { path = "../rocm_smi-sys" } + +[package.metadata.zluda] +top_level = true +linux_names = ["libnvidia-ml.so", "libnvidia-ml.so.1"] diff --git a/zluda_ml/README b/zluda_ml/README new file mode 100644 index 0000000..2fd0277 --- /dev/null +++ b/zluda_ml/README @@ -0,0 +1,3 @@ +bindgen /usr/local/cuda-12/include/nvml.h --no-derive-debug --allowlist-var="^NVML.*" --allowlist-function="^nvml.*" --default-enum-style=newtype --no-layout-tests --no-doc-comments -o src/nvml.rs -- -DNVML_NO_UNVERSIONED_FUNC_DEFS +sed -i -e 's/extern "C" {//g' -e 's/-> nvmlReturn_t;/-> nvmlReturn_t { crate::r#impl::unimplemented()/g' -e 's/pub fn /#[no_mangle] pub extern "C" fn /g' src/nvml.rs +rustfmt src/nvml.rs \ No newline at end of file diff --git a/zluda_ml/src/common.rs b/zluda_ml/src/common.rs new file mode 100644 index 0000000..fdab22f --- /dev/null +++ b/zluda_ml/src/common.rs @@ -0,0 +1,160 @@ +use std::{ + ffi::{c_char, c_uint, CStr}, + ptr, +}; + +use crate::nvml::*; + +#[cfg(debug_assertions)] +pub(crate) fn unimplemented() -> nvmlReturn_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unimplemented() -> nvmlReturn_t { + nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED +} + +macro_rules! stringify_nmvlreturn_t { + ($x:ident => [ $($variant:ident),+ ]) => { + match $x { + $( + nvmlReturn_t::$variant => Some(concat!(stringify!($variant), "\0")), + )+ + _ => None + } + } +} + +pub(crate) fn error_string(result: nvmlReturn_t) -> *const ::std::os::raw::c_char { + let text = stringify_nmvlreturn_t!( + result => [ + NVML_SUCCESS, + NVML_ERROR_UNINITIALIZED, + NVML_ERROR_INVALID_ARGUMENT, + NVML_ERROR_NOT_SUPPORTED, + NVML_ERROR_NO_PERMISSION, + NVML_ERROR_ALREADY_INITIALIZED, + NVML_ERROR_NOT_FOUND, + NVML_ERROR_INSUFFICIENT_SIZE, + NVML_ERROR_INSUFFICIENT_POWER, + NVML_ERROR_DRIVER_NOT_LOADED, + NVML_ERROR_TIMEOUT, + NVML_ERROR_IRQ_ISSUE, + NVML_ERROR_LIBRARY_NOT_FOUND, + NVML_ERROR_FUNCTION_NOT_FOUND, + NVML_ERROR_CORRUPTED_INFOROM, + NVML_ERROR_GPU_IS_LOST, + NVML_ERROR_RESET_REQUIRED, + NVML_ERROR_OPERATING_SYSTEM, + NVML_ERROR_LIB_RM_VERSION_MISMATCH, + NVML_ERROR_IN_USE, + NVML_ERROR_MEMORY, + NVML_ERROR_NO_DATA, + NVML_ERROR_VGPU_ECC_NOT_SUPPORTED, + NVML_ERROR_INSUFFICIENT_RESOURCES, + NVML_ERROR_UNKNOWN + ] + ); + match text { + Some(text) => text.as_ptr() as *const _, + None => ptr::null(), + } +} + +// For version we report NVIDIA's minimum required driver version for CUDA +// version we want to support incremented by 00.00.01: +// https://docs.nvidia.com/deploy/cuda-compatibility/index.html#minor-version-compatibility +const VERSION: &'static [u8] = b"511.09.01"; // minimum required by Arnold +const NVML_VERSION: &'static [u8] = b"11.511.09.01"; // // minimum required by Arnold + +impl From> for nvmlReturn_t { + fn from(result: Result<(), nvmlReturn_t>) -> Self { + match result { + Ok(()) => nvmlReturn_t::NVML_SUCCESS, + Err(e) => e, + } + } +} + +impl From for Result<(), nvmlReturn_t> { + fn from(result: nvmlReturn_t) -> Self { + match result { + nvmlReturn_t::NVML_SUCCESS => Ok(()), + e => Err(e), + } + } +} + +pub(crate) unsafe fn system_get_cuda_driver_version( + cuda_driver_version: *mut ::std::os::raw::c_int, +) -> Result<(), nvmlReturn_t> { + *cuda_driver_version = 11000; + Ok(()) +} + +pub(crate) unsafe fn system_get_driver_version( + version_ptr: *mut c_char, + length: c_uint, +) -> Result<(), nvmlReturn_t> { + if version_ptr == ptr::null_mut() || length == 0 { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let strlen = usize::min(VERSION.len(), (length as usize) - 1); + std::ptr::copy_nonoverlapping(VERSION.as_ptr(), version_ptr as _, strlen); + *version_ptr.add(strlen) = 0; + Ok(()) +} + +pub(crate) unsafe fn system_get_nvml_version( + version_ptr: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> Result<(), nvmlReturn_t> { + if version_ptr == ptr::null_mut() || length == 0 { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let strlen = usize::min(NVML_VERSION.len(), (length as usize) - 1); + std::ptr::copy_nonoverlapping(NVML_VERSION.as_ptr(), version_ptr as _, strlen); + *version_ptr.add(strlen) = 0; + Ok(()) +} + +pub(crate) fn device_get_temperature_threshold( + _device: *mut crate::nvml::nvmlDevice_st, + _threshold_type: crate::nvml::nvmlTemperatureThresholds_t, + _temp: *mut u32, +) -> nvmlReturn_t { + nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED +} + +pub(crate) unsafe fn device_get_nvlink_state( + _device: *mut crate::nvml::nvmlDevice_st, + _link: u32, + _is_active: *mut crate::nvml::nvmlEnableState_enum, +) -> nvmlReturn_t { + return nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED; +} + +pub(crate) unsafe fn parse_pci_address(address: *const i8) -> Result<(i32, i32, i32), nvmlReturn_t> { + let address = CStr::from_ptr(address); + let address = address + .to_str() + .map_err(|_| nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let mut split_addr = address.split(':').rev(); + let device_function = split_addr + .next() + .ok_or(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let (device, function) = device_function + .split_once('.') + .ok_or(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let bus = split_addr + .next() + .ok_or(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let device = + i32::from_str_radix(device, 16).map_err(|_| nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let function = + i32::from_str_radix(function, 16).map_err(|_| nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + let bus = + i32::from_str_radix(bus, 16).map_err(|_| nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT)?; + Ok((bus, device, function)) +} diff --git a/zluda_ml/src/lib.rs b/zluda_ml/src/lib.rs new file mode 100644 index 0000000..cb54bf2 --- /dev/null +++ b/zluda_ml/src/lib.rs @@ -0,0 +1,6 @@ +mod common; +#[cfg_attr(unix, path = "unix.rs")] +#[cfg_attr(windows, path = "windows.rs")] +pub mod r#impl; +#[allow(warnings)] +mod nvml; diff --git a/zluda_ml/src/nvml.rs b/zluda_ml/src/nvml.rs new file mode 100644 index 0000000..f08574e --- /dev/null +++ b/zluda_ml/src/nvml.rs @@ -0,0 +1,4966 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +pub const NVML_API_VERSION: u32 = 12; +pub const NVML_API_VERSION_STR: &[u8; 3] = b"12\0"; +pub const NVML_VALUE_NOT_AVAILABLE: i32 = -1; +pub const NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE: u32 = 32; +pub const NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE: u32 = 16; +pub const NVML_DEVICE_PCI_BUS_ID_LEGACY_FMT: &[u8; 17] = b"%04X:%02X:%02X.0\0"; +pub const NVML_DEVICE_PCI_BUS_ID_FMT: &[u8; 17] = b"%08X:%02X:%02X.0\0"; +pub const NVML_NVLINK_MAX_LINKS: u32 = 18; +pub const NVML_MAX_PHYSICAL_BRIDGE: u32 = 128; +pub const NVML_MAX_THERMAL_SENSORS_PER_GPU: u32 = 3; +pub const NVML_MAX_GPU_PERF_PSTATES: u32 = 16; +pub const NVML_GRID_LICENSE_EXPIRY_NOT_AVAILABLE: u32 = 0; +pub const NVML_GRID_LICENSE_EXPIRY_INVALID: u32 = 1; +pub const NVML_GRID_LICENSE_EXPIRY_VALID: u32 = 2; +pub const NVML_GRID_LICENSE_EXPIRY_NOT_APPLICABLE: u32 = 3; +pub const NVML_GRID_LICENSE_EXPIRY_PERMANENT: u32 = 4; +pub const NVML_GRID_LICENSE_BUFFER_SIZE: u32 = 128; +pub const NVML_VGPU_NAME_BUFFER_SIZE: u32 = 64; +pub const NVML_GRID_LICENSE_FEATURE_MAX_COUNT: u32 = 3; +pub const NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_NO: u32 = 0; +pub const NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_YES: u32 = 1; +pub const NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_NO: u32 = 0; +pub const NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_YES: u32 = 1; +pub const NVML_VGPU_SCHEDULER_POLICY_UNKNOWN: u32 = 0; +pub const NVML_VGPU_SCHEDULER_POLICY_BEST_EFFORT: u32 = 1; +pub const NVML_VGPU_SCHEDULER_POLICY_EQUAL_SHARE: u32 = 2; +pub const NVML_VGPU_SCHEDULER_POLICY_FIXED_SHARE: u32 = 3; +pub const NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT: u32 = 3; +pub const NVML_SCHEDULER_SW_MAX_LOG_ENTRIES: u32 = 200; +pub const NVML_GRID_LICENSE_STATE_UNKNOWN: u32 = 0; +pub const NVML_GRID_LICENSE_STATE_UNINITIALIZED: u32 = 1; +pub const NVML_GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED: u32 = 2; +pub const NVML_GRID_LICENSE_STATE_UNLICENSED_RESTRICTED: u32 = 3; +pub const NVML_GRID_LICENSE_STATE_UNLICENSED: u32 = 4; +pub const NVML_GRID_LICENSE_STATE_LICENSED: u32 = 5; +pub const NVML_GSP_FIRMWARE_VERSION_BUF_SIZE: u32 = 64; +pub const NVML_DEVICE_ARCH_KEPLER: u32 = 2; +pub const NVML_DEVICE_ARCH_MAXWELL: u32 = 3; +pub const NVML_DEVICE_ARCH_PASCAL: u32 = 4; +pub const NVML_DEVICE_ARCH_VOLTA: u32 = 5; +pub const NVML_DEVICE_ARCH_TURING: u32 = 6; +pub const NVML_DEVICE_ARCH_AMPERE: u32 = 7; +pub const NVML_DEVICE_ARCH_ADA: u32 = 8; +pub const NVML_DEVICE_ARCH_HOPPER: u32 = 9; +pub const NVML_DEVICE_ARCH_UNKNOWN: u32 = 4294967295; +pub const NVML_BUS_TYPE_UNKNOWN: u32 = 0; +pub const NVML_BUS_TYPE_PCI: u32 = 1; +pub const NVML_BUS_TYPE_PCIE: u32 = 2; +pub const NVML_BUS_TYPE_FPCI: u32 = 3; +pub const NVML_BUS_TYPE_AGP: u32 = 4; +pub const NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW: u32 = 0; +pub const NVML_FAN_POLICY_MANUAL: u32 = 1; +pub const NVML_POWER_SOURCE_AC: u32 = 0; +pub const NVML_POWER_SOURCE_BATTERY: u32 = 1; +pub const NVML_POWER_SOURCE_UNDERSIZED: u32 = 2; +pub const NVML_PCIE_LINK_MAX_SPEED_INVALID: u32 = 0; +pub const NVML_PCIE_LINK_MAX_SPEED_2500MBPS: u32 = 1; +pub const NVML_PCIE_LINK_MAX_SPEED_5000MBPS: u32 = 2; +pub const NVML_PCIE_LINK_MAX_SPEED_8000MBPS: u32 = 3; +pub const NVML_PCIE_LINK_MAX_SPEED_16000MBPS: u32 = 4; +pub const NVML_PCIE_LINK_MAX_SPEED_32000MBPS: u32 = 5; +pub const NVML_PCIE_LINK_MAX_SPEED_64000MBPS: u32 = 6; +pub const NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED: u32 = 0; +pub const NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED: u32 = 1; +pub const NVML_MAX_GPU_UTILIZATIONS: u32 = 8; +pub const NVML_FI_DEV_ECC_CURRENT: u32 = 1; +pub const NVML_FI_DEV_ECC_PENDING: u32 = 2; +pub const NVML_FI_DEV_ECC_SBE_VOL_TOTAL: u32 = 3; +pub const NVML_FI_DEV_ECC_DBE_VOL_TOTAL: u32 = 4; +pub const NVML_FI_DEV_ECC_SBE_AGG_TOTAL: u32 = 5; +pub const NVML_FI_DEV_ECC_DBE_AGG_TOTAL: u32 = 6; +pub const NVML_FI_DEV_ECC_SBE_VOL_L1: u32 = 7; +pub const NVML_FI_DEV_ECC_DBE_VOL_L1: u32 = 8; +pub const NVML_FI_DEV_ECC_SBE_VOL_L2: u32 = 9; +pub const NVML_FI_DEV_ECC_DBE_VOL_L2: u32 = 10; +pub const NVML_FI_DEV_ECC_SBE_VOL_DEV: u32 = 11; +pub const NVML_FI_DEV_ECC_DBE_VOL_DEV: u32 = 12; +pub const NVML_FI_DEV_ECC_SBE_VOL_REG: u32 = 13; +pub const NVML_FI_DEV_ECC_DBE_VOL_REG: u32 = 14; +pub const NVML_FI_DEV_ECC_SBE_VOL_TEX: u32 = 15; +pub const NVML_FI_DEV_ECC_DBE_VOL_TEX: u32 = 16; +pub const NVML_FI_DEV_ECC_DBE_VOL_CBU: u32 = 17; +pub const NVML_FI_DEV_ECC_SBE_AGG_L1: u32 = 18; +pub const NVML_FI_DEV_ECC_DBE_AGG_L1: u32 = 19; +pub const NVML_FI_DEV_ECC_SBE_AGG_L2: u32 = 20; +pub const NVML_FI_DEV_ECC_DBE_AGG_L2: u32 = 21; +pub const NVML_FI_DEV_ECC_SBE_AGG_DEV: u32 = 22; +pub const NVML_FI_DEV_ECC_DBE_AGG_DEV: u32 = 23; +pub const NVML_FI_DEV_ECC_SBE_AGG_REG: u32 = 24; +pub const NVML_FI_DEV_ECC_DBE_AGG_REG: u32 = 25; +pub const NVML_FI_DEV_ECC_SBE_AGG_TEX: u32 = 26; +pub const NVML_FI_DEV_ECC_DBE_AGG_TEX: u32 = 27; +pub const NVML_FI_DEV_ECC_DBE_AGG_CBU: u32 = 28; +pub const NVML_FI_DEV_RETIRED_SBE: u32 = 29; +pub const NVML_FI_DEV_RETIRED_DBE: u32 = 30; +pub const NVML_FI_DEV_RETIRED_PENDING: u32 = 31; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L0: u32 = 32; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L1: u32 = 33; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L2: u32 = 34; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L3: u32 = 35; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L4: u32 = 36; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L5: u32 = 37; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL: u32 = 38; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L0: u32 = 39; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L1: u32 = 40; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L2: u32 = 41; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L3: u32 = 42; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L4: u32 = 43; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L5: u32 = 44; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_TOTAL: u32 = 45; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L0: u32 = 46; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L1: u32 = 47; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L2: u32 = 48; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L3: u32 = 49; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L4: u32 = 50; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L5: u32 = 51; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL: u32 = 52; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L0: u32 = 53; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L1: u32 = 54; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L2: u32 = 55; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L3: u32 = 56; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L4: u32 = 57; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L5: u32 = 58; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_TOTAL: u32 = 59; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L0: u32 = 60; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L1: u32 = 61; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L2: u32 = 62; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L3: u32 = 63; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L4: u32 = 64; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L5: u32 = 65; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_TOTAL: u32 = 66; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L0: u32 = 67; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L1: u32 = 68; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L2: u32 = 69; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L3: u32 = 70; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L4: u32 = 71; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L5: u32 = 72; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_TOTAL: u32 = 73; +pub const NVML_FI_DEV_PERF_POLICY_POWER: u32 = 74; +pub const NVML_FI_DEV_PERF_POLICY_THERMAL: u32 = 75; +pub const NVML_FI_DEV_PERF_POLICY_SYNC_BOOST: u32 = 76; +pub const NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT: u32 = 77; +pub const NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION: u32 = 78; +pub const NVML_FI_DEV_PERF_POLICY_RELIABILITY: u32 = 79; +pub const NVML_FI_DEV_PERF_POLICY_TOTAL_APP_CLOCKS: u32 = 80; +pub const NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS: u32 = 81; +pub const NVML_FI_DEV_MEMORY_TEMP: u32 = 82; +pub const NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION: u32 = 83; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L0: u32 = 84; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L1: u32 = 85; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L2: u32 = 86; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L3: u32 = 87; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L4: u32 = 88; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L5: u32 = 89; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_COMMON: u32 = 90; +pub const NVML_FI_DEV_NVLINK_LINK_COUNT: u32 = 91; +pub const NVML_FI_DEV_RETIRED_PENDING_SBE: u32 = 92; +pub const NVML_FI_DEV_RETIRED_PENDING_DBE: u32 = 93; +pub const NVML_FI_DEV_PCIE_REPLAY_COUNTER: u32 = 94; +pub const NVML_FI_DEV_PCIE_REPLAY_ROLLOVER_COUNTER: u32 = 95; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L6: u32 = 96; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L7: u32 = 97; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L8: u32 = 98; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L9: u32 = 99; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L10: u32 = 100; +pub const NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L11: u32 = 101; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L6: u32 = 102; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L7: u32 = 103; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L8: u32 = 104; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L9: u32 = 105; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L10: u32 = 106; +pub const NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L11: u32 = 107; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L6: u32 = 108; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L7: u32 = 109; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L8: u32 = 110; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L9: u32 = 111; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L10: u32 = 112; +pub const NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L11: u32 = 113; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L6: u32 = 114; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L7: u32 = 115; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L8: u32 = 116; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L9: u32 = 117; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L10: u32 = 118; +pub const NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L11: u32 = 119; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L6: u32 = 120; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L7: u32 = 121; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L8: u32 = 122; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L9: u32 = 123; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L10: u32 = 124; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L11: u32 = 125; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L6: u32 = 126; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L7: u32 = 127; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L8: u32 = 128; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L9: u32 = 129; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L10: u32 = 130; +pub const NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L11: u32 = 131; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L6: u32 = 132; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L7: u32 = 133; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L8: u32 = 134; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L9: u32 = 135; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L10: u32 = 136; +pub const NVML_FI_DEV_NVLINK_SPEED_MBPS_L11: u32 = 137; +pub const NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX: u32 = 138; +pub const NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX: u32 = 139; +pub const NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX: u32 = 140; +pub const NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX: u32 = 141; +pub const NVML_FI_DEV_REMAPPED_COR: u32 = 142; +pub const NVML_FI_DEV_REMAPPED_UNC: u32 = 143; +pub const NVML_FI_DEV_REMAPPED_PENDING: u32 = 144; +pub const NVML_FI_DEV_REMAPPED_FAILURE: u32 = 145; +pub const NVML_FI_DEV_NVLINK_REMOTE_NVLINK_ID: u32 = 146; +pub const NVML_FI_DEV_NVSWITCH_CONNECTED_LINK_COUNT: u32 = 147; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L0: u32 = 148; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L1: u32 = 149; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L2: u32 = 150; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L3: u32 = 151; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L4: u32 = 152; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L5: u32 = 153; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L6: u32 = 154; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L7: u32 = 155; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L8: u32 = 156; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L9: u32 = 157; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L10: u32 = 158; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L11: u32 = 159; +pub const NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_TOTAL: u32 = 160; +pub const NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY: u32 = 161; +pub const NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY: u32 = 162; +pub const NVML_FI_DEV_NVLINK_ERROR_DL_CRC: u32 = 163; +pub const NVML_FI_DEV_NVLINK_GET_SPEED: u32 = 164; +pub const NVML_FI_DEV_NVLINK_GET_STATE: u32 = 165; +pub const NVML_FI_DEV_NVLINK_GET_VERSION: u32 = 166; +pub const NVML_FI_DEV_NVLINK_GET_POWER_STATE: u32 = 167; +pub const NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD: u32 = 168; +pub const NVML_FI_DEV_PCIE_L0_TO_RECOVERY_COUNTER: u32 = 169; +pub const NVML_FI_DEV_C2C_LINK_COUNT: u32 = 170; +pub const NVML_FI_DEV_C2C_LINK_GET_STATUS: u32 = 171; +pub const NVML_FI_DEV_C2C_LINK_GET_MAX_BW: u32 = 172; +pub const NVML_FI_DEV_PCIE_COUNT_CORRECTABLE_ERRORS: u32 = 173; +pub const NVML_FI_DEV_PCIE_COUNT_NAKS_RECEIVED: u32 = 174; +pub const NVML_FI_DEV_PCIE_COUNT_RECEIVER_ERROR: u32 = 175; +pub const NVML_FI_DEV_PCIE_COUNT_BAD_TLP: u32 = 176; +pub const NVML_FI_DEV_PCIE_COUNT_NAKS_SENT: u32 = 177; +pub const NVML_FI_DEV_PCIE_COUNT_BAD_DLLP: u32 = 178; +pub const NVML_FI_DEV_PCIE_COUNT_NON_FATAL_ERROR: u32 = 179; +pub const NVML_FI_DEV_PCIE_COUNT_FATAL_ERROR: u32 = 180; +pub const NVML_FI_DEV_PCIE_COUNT_UNSUPPORTED_REQ: u32 = 181; +pub const NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR: u32 = 182; +pub const NVML_FI_DEV_PCIE_COUNT_LANE_ERROR: u32 = 183; +pub const NVML_FI_DEV_IS_RESETLESS_MIG_SUPPORTED: u32 = 184; +pub const NVML_FI_DEV_POWER_AVERAGE: u32 = 185; +pub const NVML_FI_DEV_POWER_INSTANT: u32 = 186; +pub const NVML_FI_DEV_POWER_MIN_LIMIT: u32 = 187; +pub const NVML_FI_DEV_POWER_MAX_LIMIT: u32 = 188; +pub const NVML_FI_DEV_POWER_DEFAULT_LIMIT: u32 = 189; +pub const NVML_FI_DEV_POWER_CURRENT_LIMIT: u32 = 190; +pub const NVML_FI_DEV_ENERGY: u32 = 191; +pub const NVML_FI_DEV_POWER_REQUESTED_LIMIT: u32 = 192; +pub const NVML_FI_DEV_TEMPERATURE_SHUTDOWN_TLIMIT: u32 = 193; +pub const NVML_FI_DEV_TEMPERATURE_SLOWDOWN_TLIMIT: u32 = 194; +pub const NVML_FI_DEV_TEMPERATURE_MEM_MAX_TLIMIT: u32 = 195; +pub const NVML_FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT: u32 = 196; +pub const NVML_FI_MAX: u32 = 197; +pub const NVML_NVFBC_SESSION_FLAG_DIFFMAP_ENABLED: u32 = 1; +pub const NVML_NVFBC_SESSION_FLAG_CLASSIFICATIONMAP_ENABLED: u32 = 2; +pub const NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_NO_WAIT: u32 = 4; +pub const NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_INFINITE: u32 = 8; +pub const NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_TIMEOUT: u32 = 16; +pub const NVML_CC_SYSTEM_CPU_CAPS_NONE: u32 = 0; +pub const NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV: u32 = 1; +pub const NVML_CC_SYSTEM_GPUS_CC_NOT_CAPABLE: u32 = 0; +pub const NVML_CC_SYSTEM_GPUS_CC_CAPABLE: u32 = 1; +pub const NVML_CC_SYSTEM_DEVTOOLS_MODE_OFF: u32 = 0; +pub const NVML_CC_SYSTEM_DEVTOOLS_MODE_ON: u32 = 1; +pub const NVML_CC_SYSTEM_ENVIRONMENT_UNAVAILABLE: u32 = 0; +pub const NVML_CC_SYSTEM_ENVIRONMENT_SIM: u32 = 1; +pub const NVML_CC_SYSTEM_ENVIRONMENT_PROD: u32 = 2; +pub const NVML_CC_SYSTEM_FEATURE_DISABLED: u32 = 0; +pub const NVML_CC_SYSTEM_FEATURE_ENABLED: u32 = 1; +pub const NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE: u32 = 0; +pub const NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE: u32 = 1; +pub const NVML_GPU_CERT_CHAIN_SIZE: u32 = 4096; +pub const NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE: u32 = 5120; +pub const NVML_CC_GPU_CEC_NONCE_SIZE: u32 = 32; +pub const NVML_CC_GPU_ATTESTATION_REPORT_SIZE: u32 = 8192; +pub const NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE: u32 = 4096; +pub const NVML_CC_CEC_ATTESTATION_REPORT_NOT_PRESENT: u32 = 0; +pub const NVML_CC_CEC_ATTESTATION_REPORT_PRESENT: u32 = 1; +pub const NVML_GPU_FABRIC_UUID_LEN: u32 = 16; +pub const NVML_GPU_FABRIC_STATE_NOT_SUPPORTED: u32 = 0; +pub const NVML_GPU_FABRIC_STATE_NOT_STARTED: u32 = 1; +pub const NVML_GPU_FABRIC_STATE_IN_PROGRESS: u32 = 2; +pub const NVML_GPU_FABRIC_STATE_COMPLETED: u32 = 3; +pub const NVML_POWER_SCOPE_GPU: u32 = 0; +pub const NVML_POWER_SCOPE_MODULE: u32 = 1; +pub const NVML_INIT_FLAG_NO_GPUS: u32 = 1; +pub const NVML_INIT_FLAG_NO_ATTACH: u32 = 2; +pub const NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE: u32 = 16; +pub const NVML_DEVICE_UUID_BUFFER_SIZE: u32 = 80; +pub const NVML_DEVICE_UUID_V2_BUFFER_SIZE: u32 = 96; +pub const NVML_DEVICE_PART_NUMBER_BUFFER_SIZE: u32 = 80; +pub const NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE: u32 = 80; +pub const NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE: u32 = 80; +pub const NVML_DEVICE_NAME_BUFFER_SIZE: u32 = 64; +pub const NVML_DEVICE_NAME_V2_BUFFER_SIZE: u32 = 96; +pub const NVML_DEVICE_SERIAL_BUFFER_SIZE: u32 = 30; +pub const NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE: u32 = 32; +pub const NVML_AFFINITY_SCOPE_NODE: u32 = 0; +pub const NVML_AFFINITY_SCOPE_SOCKET: u32 = 1; +pub const NVML_DEVICE_MIG_DISABLE: u32 = 0; +pub const NVML_DEVICE_MIG_ENABLE: u32 = 1; +pub const NVML_GPU_INSTANCE_PROFILE_1_SLICE: u32 = 0; +pub const NVML_GPU_INSTANCE_PROFILE_2_SLICE: u32 = 1; +pub const NVML_GPU_INSTANCE_PROFILE_3_SLICE: u32 = 2; +pub const NVML_GPU_INSTANCE_PROFILE_4_SLICE: u32 = 3; +pub const NVML_GPU_INSTANCE_PROFILE_7_SLICE: u32 = 4; +pub const NVML_GPU_INSTANCE_PROFILE_8_SLICE: u32 = 5; +pub const NVML_GPU_INSTANCE_PROFILE_6_SLICE: u32 = 6; +pub const NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1: u32 = 7; +pub const NVML_GPU_INSTANCE_PROFILE_2_SLICE_REV1: u32 = 8; +pub const NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV2: u32 = 9; +pub const NVML_GPU_INSTANCE_PROFILE_COUNT: u32 = 10; +pub const NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE: u32 = 0; +pub const NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE: u32 = 1; +pub const NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE: u32 = 2; +pub const NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE: u32 = 3; +pub const NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE: u32 = 4; +pub const NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE: u32 = 5; +pub const NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE: u32 = 6; +pub const NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE_REV1: u32 = 7; +pub const NVML_COMPUTE_INSTANCE_PROFILE_COUNT: u32 = 8; +pub const NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED: u32 = 0; +pub const NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT: u32 = 1; +pub const NVML_GPM_METRICS_GET_VERSION: u32 = 1; +pub const NVML_GPM_SUPPORT_VERSION: u32 = 1; +pub const NVML_NVLINK_POWER_STATE_HIGH_SPEED: u32 = 0; +pub const NVML_NVLINK_POWER_STATE_LOW: u32 = 1; +pub const NVML_NVLINK_LOW_POWER_THRESHOLD_MIN: u32 = 1; +pub const NVML_NVLINK_LOW_POWER_THRESHOLD_MAX: u32 = 8191; +pub const NVML_NVLINK_LOW_POWER_THRESHOLD_RESET: u32 = 4294967295; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlDevice_st { + _unused: [u8; 0], +} +pub type nvmlDevice_t = *mut nvmlDevice_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlPciInfo_st { + pub busIdLegacy: [::std::os::raw::c_char; 16usize], + pub domain: ::std::os::raw::c_uint, + pub bus: ::std::os::raw::c_uint, + pub device: ::std::os::raw::c_uint, + pub pciDeviceId: ::std::os::raw::c_uint, + pub pciSubSystemId: ::std::os::raw::c_uint, + pub busId: [::std::os::raw::c_char; 32usize], +} +pub type nvmlPciInfo_t = nvmlPciInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlEccErrorCounts_st { + pub l1Cache: ::std::os::raw::c_ulonglong, + pub l2Cache: ::std::os::raw::c_ulonglong, + pub deviceMemory: ::std::os::raw::c_ulonglong, + pub registerFile: ::std::os::raw::c_ulonglong, +} +pub type nvmlEccErrorCounts_t = nvmlEccErrorCounts_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlUtilization_st { + pub gpu: ::std::os::raw::c_uint, + pub memory: ::std::os::raw::c_uint, +} +pub type nvmlUtilization_t = nvmlUtilization_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlMemory_st { + pub total: ::std::os::raw::c_ulonglong, + pub free: ::std::os::raw::c_ulonglong, + pub used: ::std::os::raw::c_ulonglong, +} +pub type nvmlMemory_t = nvmlMemory_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlMemory_v2_st { + pub version: ::std::os::raw::c_uint, + pub total: ::std::os::raw::c_ulonglong, + pub reserved: ::std::os::raw::c_ulonglong, + pub free: ::std::os::raw::c_ulonglong, + pub used: ::std::os::raw::c_ulonglong, +} +pub type nvmlMemory_v2_t = nvmlMemory_v2_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlBAR1Memory_st { + pub bar1Total: ::std::os::raw::c_ulonglong, + pub bar1Free: ::std::os::raw::c_ulonglong, + pub bar1Used: ::std::os::raw::c_ulonglong, +} +pub type nvmlBAR1Memory_t = nvmlBAR1Memory_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlProcessInfo_v1_st { + pub pid: ::std::os::raw::c_uint, + pub usedGpuMemory: ::std::os::raw::c_ulonglong, +} +pub type nvmlProcessInfo_v1_t = nvmlProcessInfo_v1_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlProcessInfo_v2_st { + pub pid: ::std::os::raw::c_uint, + pub usedGpuMemory: ::std::os::raw::c_ulonglong, + pub gpuInstanceId: ::std::os::raw::c_uint, + pub computeInstanceId: ::std::os::raw::c_uint, +} +pub type nvmlProcessInfo_v2_t = nvmlProcessInfo_v2_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlProcessInfo_st { + pub pid: ::std::os::raw::c_uint, + pub usedGpuMemory: ::std::os::raw::c_ulonglong, + pub gpuInstanceId: ::std::os::raw::c_uint, + pub computeInstanceId: ::std::os::raw::c_uint, + pub usedGpuCcProtectedMemory: ::std::os::raw::c_ulonglong, +} +pub type nvmlProcessInfo_t = nvmlProcessInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlDeviceAttributes_st { + pub multiprocessorCount: ::std::os::raw::c_uint, + pub sharedCopyEngineCount: ::std::os::raw::c_uint, + pub sharedDecoderCount: ::std::os::raw::c_uint, + pub sharedEncoderCount: ::std::os::raw::c_uint, + pub sharedJpegCount: ::std::os::raw::c_uint, + pub sharedOfaCount: ::std::os::raw::c_uint, + pub gpuInstanceSliceCount: ::std::os::raw::c_uint, + pub computeInstanceSliceCount: ::std::os::raw::c_uint, + pub memorySizeMB: ::std::os::raw::c_ulonglong, +} +pub type nvmlDeviceAttributes_t = nvmlDeviceAttributes_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlRowRemapperHistogramValues_st { + pub max: ::std::os::raw::c_uint, + pub high: ::std::os::raw::c_uint, + pub partial: ::std::os::raw::c_uint, + pub low: ::std::os::raw::c_uint, + pub none: ::std::os::raw::c_uint, +} +pub type nvmlRowRemapperHistogramValues_t = nvmlRowRemapperHistogramValues_st; +impl nvmlBridgeChipType_enum { + pub const NVML_BRIDGE_CHIP_PLX: nvmlBridgeChipType_enum = nvmlBridgeChipType_enum(0); +} +impl nvmlBridgeChipType_enum { + pub const NVML_BRIDGE_CHIP_BRO4: nvmlBridgeChipType_enum = nvmlBridgeChipType_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlBridgeChipType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlBridgeChipType_enum as nvmlBridgeChipType_t; +impl nvmlNvLinkUtilizationCountUnits_enum { + pub const NVML_NVLINK_COUNTER_UNIT_CYCLES: nvmlNvLinkUtilizationCountUnits_enum = + nvmlNvLinkUtilizationCountUnits_enum(0); +} +impl nvmlNvLinkUtilizationCountUnits_enum { + pub const NVML_NVLINK_COUNTER_UNIT_PACKETS: nvmlNvLinkUtilizationCountUnits_enum = + nvmlNvLinkUtilizationCountUnits_enum(1); +} +impl nvmlNvLinkUtilizationCountUnits_enum { + pub const NVML_NVLINK_COUNTER_UNIT_BYTES: nvmlNvLinkUtilizationCountUnits_enum = + nvmlNvLinkUtilizationCountUnits_enum(2); +} +impl nvmlNvLinkUtilizationCountUnits_enum { + pub const NVML_NVLINK_COUNTER_UNIT_RESERVED: nvmlNvLinkUtilizationCountUnits_enum = + nvmlNvLinkUtilizationCountUnits_enum(3); +} +impl nvmlNvLinkUtilizationCountUnits_enum { + pub const NVML_NVLINK_COUNTER_UNIT_COUNT: nvmlNvLinkUtilizationCountUnits_enum = + nvmlNvLinkUtilizationCountUnits_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlNvLinkUtilizationCountUnits_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlNvLinkUtilizationCountUnits_enum as nvmlNvLinkUtilizationCountUnits_t; +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_NOP: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(1); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_READ: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(2); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_WRITE: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(4); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_RATOM: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(8); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_NRATOM: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(16); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_FLUSH: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(32); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_RESPDATA: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(64); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_RESPNODATA: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(128); +} +impl nvmlNvLinkUtilizationCountPktTypes_enum { + pub const NVML_NVLINK_COUNTER_PKTFILTER_ALL: nvmlNvLinkUtilizationCountPktTypes_enum = + nvmlNvLinkUtilizationCountPktTypes_enum(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlNvLinkUtilizationCountPktTypes_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlNvLinkUtilizationCountPktTypes_enum as nvmlNvLinkUtilizationCountPktTypes_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlNvLinkUtilizationControl_st { + pub units: nvmlNvLinkUtilizationCountUnits_t, + pub pktfilter: nvmlNvLinkUtilizationCountPktTypes_t, +} +pub type nvmlNvLinkUtilizationControl_t = nvmlNvLinkUtilizationControl_st; +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_P2P_SUPPORTED: nvmlNvLinkCapability_enum = + nvmlNvLinkCapability_enum(0); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_SYSMEM_ACCESS: nvmlNvLinkCapability_enum = + nvmlNvLinkCapability_enum(1); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_P2P_ATOMICS: nvmlNvLinkCapability_enum = nvmlNvLinkCapability_enum(2); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_SYSMEM_ATOMICS: nvmlNvLinkCapability_enum = + nvmlNvLinkCapability_enum(3); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_SLI_BRIDGE: nvmlNvLinkCapability_enum = nvmlNvLinkCapability_enum(4); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_VALID: nvmlNvLinkCapability_enum = nvmlNvLinkCapability_enum(5); +} +impl nvmlNvLinkCapability_enum { + pub const NVML_NVLINK_CAP_COUNT: nvmlNvLinkCapability_enum = nvmlNvLinkCapability_enum(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlNvLinkCapability_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlNvLinkCapability_enum as nvmlNvLinkCapability_t; +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_DL_REPLAY: nvmlNvLinkErrorCounter_enum = + nvmlNvLinkErrorCounter_enum(0); +} +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_DL_RECOVERY: nvmlNvLinkErrorCounter_enum = + nvmlNvLinkErrorCounter_enum(1); +} +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_DL_CRC_FLIT: nvmlNvLinkErrorCounter_enum = + nvmlNvLinkErrorCounter_enum(2); +} +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_DL_CRC_DATA: nvmlNvLinkErrorCounter_enum = + nvmlNvLinkErrorCounter_enum(3); +} +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_DL_ECC_DATA: nvmlNvLinkErrorCounter_enum = + nvmlNvLinkErrorCounter_enum(4); +} +impl nvmlNvLinkErrorCounter_enum { + pub const NVML_NVLINK_ERROR_COUNT: nvmlNvLinkErrorCounter_enum = nvmlNvLinkErrorCounter_enum(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlNvLinkErrorCounter_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlNvLinkErrorCounter_enum as nvmlNvLinkErrorCounter_t; +impl nvmlIntNvLinkDeviceType_enum { + pub const NVML_NVLINK_DEVICE_TYPE_GPU: nvmlIntNvLinkDeviceType_enum = + nvmlIntNvLinkDeviceType_enum(0); +} +impl nvmlIntNvLinkDeviceType_enum { + pub const NVML_NVLINK_DEVICE_TYPE_IBMNPU: nvmlIntNvLinkDeviceType_enum = + nvmlIntNvLinkDeviceType_enum(1); +} +impl nvmlIntNvLinkDeviceType_enum { + pub const NVML_NVLINK_DEVICE_TYPE_SWITCH: nvmlIntNvLinkDeviceType_enum = + nvmlIntNvLinkDeviceType_enum(2); +} +impl nvmlIntNvLinkDeviceType_enum { + pub const NVML_NVLINK_DEVICE_TYPE_UNKNOWN: nvmlIntNvLinkDeviceType_enum = + nvmlIntNvLinkDeviceType_enum(255); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlIntNvLinkDeviceType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlIntNvLinkDeviceType_enum as nvmlIntNvLinkDeviceType_t; +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_INTERNAL: nvmlGpuLevel_enum = nvmlGpuLevel_enum(0); +} +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_SINGLE: nvmlGpuLevel_enum = nvmlGpuLevel_enum(10); +} +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_MULTIPLE: nvmlGpuLevel_enum = nvmlGpuLevel_enum(20); +} +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_HOSTBRIDGE: nvmlGpuLevel_enum = nvmlGpuLevel_enum(30); +} +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_NODE: nvmlGpuLevel_enum = nvmlGpuLevel_enum(40); +} +impl nvmlGpuLevel_enum { + pub const NVML_TOPOLOGY_SYSTEM: nvmlGpuLevel_enum = nvmlGpuLevel_enum(50); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGpuLevel_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlGpuLevel_enum as nvmlGpuTopologyLevel_t; +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_OK: nvmlGpuP2PStatus_enum = nvmlGpuP2PStatus_enum(0); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED: nvmlGpuP2PStatus_enum = + nvmlGpuP2PStatus_enum(1); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_CHIPSET_NOT_SUPPORTED: nvmlGpuP2PStatus_enum = + nvmlGpuP2PStatus_enum(1); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_GPU_NOT_SUPPORTED: nvmlGpuP2PStatus_enum = nvmlGpuP2PStatus_enum(2); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_IOH_TOPOLOGY_NOT_SUPPORTED: nvmlGpuP2PStatus_enum = + nvmlGpuP2PStatus_enum(3); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_DISABLED_BY_REGKEY: nvmlGpuP2PStatus_enum = nvmlGpuP2PStatus_enum(4); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_NOT_SUPPORTED: nvmlGpuP2PStatus_enum = nvmlGpuP2PStatus_enum(5); +} +impl nvmlGpuP2PStatus_enum { + pub const NVML_P2P_STATUS_UNKNOWN: nvmlGpuP2PStatus_enum = nvmlGpuP2PStatus_enum(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGpuP2PStatus_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlGpuP2PStatus_enum as nvmlGpuP2PStatus_t; +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_READ: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(0); +} +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_WRITE: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(1); +} +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_NVLINK: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(2); +} +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_ATOMICS: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(3); +} +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_PROP: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(4); +} +impl nvmlGpuP2PCapsIndex_enum { + pub const NVML_P2P_CAPS_INDEX_UNKNOWN: nvmlGpuP2PCapsIndex_enum = nvmlGpuP2PCapsIndex_enum(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGpuP2PCapsIndex_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlGpuP2PCapsIndex_enum as nvmlGpuP2PCapsIndex_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlBridgeChipInfo_st { + pub type_: nvmlBridgeChipType_t, + pub fwVersion: ::std::os::raw::c_uint, +} +pub type nvmlBridgeChipInfo_t = nvmlBridgeChipInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlBridgeChipHierarchy_st { + pub bridgeCount: ::std::os::raw::c_uchar, + pub bridgeChipInfo: [nvmlBridgeChipInfo_t; 128usize], +} +pub type nvmlBridgeChipHierarchy_t = nvmlBridgeChipHierarchy_st; +impl nvmlSamplingType_enum { + pub const NVML_TOTAL_POWER_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(0); +} +impl nvmlSamplingType_enum { + pub const NVML_GPU_UTILIZATION_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(1); +} +impl nvmlSamplingType_enum { + pub const NVML_MEMORY_UTILIZATION_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(2); +} +impl nvmlSamplingType_enum { + pub const NVML_ENC_UTILIZATION_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(3); +} +impl nvmlSamplingType_enum { + pub const NVML_DEC_UTILIZATION_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(4); +} +impl nvmlSamplingType_enum { + pub const NVML_PROCESSOR_CLK_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(5); +} +impl nvmlSamplingType_enum { + pub const NVML_MEMORY_CLK_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(6); +} +impl nvmlSamplingType_enum { + pub const NVML_MODULE_POWER_SAMPLES: nvmlSamplingType_enum = nvmlSamplingType_enum(7); +} +impl nvmlSamplingType_enum { + pub const NVML_SAMPLINGTYPE_COUNT: nvmlSamplingType_enum = nvmlSamplingType_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlSamplingType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlSamplingType_enum as nvmlSamplingType_t; +impl nvmlPcieUtilCounter_enum { + pub const NVML_PCIE_UTIL_TX_BYTES: nvmlPcieUtilCounter_enum = nvmlPcieUtilCounter_enum(0); +} +impl nvmlPcieUtilCounter_enum { + pub const NVML_PCIE_UTIL_RX_BYTES: nvmlPcieUtilCounter_enum = nvmlPcieUtilCounter_enum(1); +} +impl nvmlPcieUtilCounter_enum { + pub const NVML_PCIE_UTIL_COUNT: nvmlPcieUtilCounter_enum = nvmlPcieUtilCounter_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlPcieUtilCounter_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlPcieUtilCounter_enum as nvmlPcieUtilCounter_t; +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_DOUBLE: nvmlValueType_enum = nvmlValueType_enum(0); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_UNSIGNED_INT: nvmlValueType_enum = nvmlValueType_enum(1); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_UNSIGNED_LONG: nvmlValueType_enum = nvmlValueType_enum(2); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_UNSIGNED_LONG_LONG: nvmlValueType_enum = nvmlValueType_enum(3); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_SIGNED_LONG_LONG: nvmlValueType_enum = nvmlValueType_enum(4); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_SIGNED_INT: nvmlValueType_enum = nvmlValueType_enum(5); +} +impl nvmlValueType_enum { + pub const NVML_VALUE_TYPE_COUNT: nvmlValueType_enum = nvmlValueType_enum(6); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlValueType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlValueType_enum as nvmlValueType_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub union nvmlValue_st { + pub dVal: f64, + pub siVal: ::std::os::raw::c_int, + pub uiVal: ::std::os::raw::c_uint, + pub ulVal: ::std::os::raw::c_ulong, + pub ullVal: ::std::os::raw::c_ulonglong, + pub sllVal: ::std::os::raw::c_longlong, +} +pub type nvmlValue_t = nvmlValue_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlSample_st { + pub timeStamp: ::std::os::raw::c_ulonglong, + pub sampleValue: nvmlValue_t, +} +pub type nvmlSample_t = nvmlSample_st; +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_POWER: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(0); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_THERMAL: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(1); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_SYNC_BOOST: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(2); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_BOARD_LIMIT: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(3); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_LOW_UTILIZATION: nvmlPerfPolicyType_enum = + nvmlPerfPolicyType_enum(4); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_RELIABILITY: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(5); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_TOTAL_APP_CLOCKS: nvmlPerfPolicyType_enum = + nvmlPerfPolicyType_enum(10); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_TOTAL_BASE_CLOCKS: nvmlPerfPolicyType_enum = + nvmlPerfPolicyType_enum(11); +} +impl nvmlPerfPolicyType_enum { + pub const NVML_PERF_POLICY_COUNT: nvmlPerfPolicyType_enum = nvmlPerfPolicyType_enum(12); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlPerfPolicyType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlPerfPolicyType_enum as nvmlPerfPolicyType_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlViolationTime_st { + pub referenceTime: ::std::os::raw::c_ulonglong, + pub violationTime: ::std::os::raw::c_ulonglong, +} +pub type nvmlViolationTime_t = nvmlViolationTime_st; +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_NONE: nvmlThermalTarget_t = nvmlThermalTarget_t(0); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_GPU: nvmlThermalTarget_t = nvmlThermalTarget_t(1); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_MEMORY: nvmlThermalTarget_t = nvmlThermalTarget_t(2); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_POWER_SUPPLY: nvmlThermalTarget_t = nvmlThermalTarget_t(4); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_BOARD: nvmlThermalTarget_t = nvmlThermalTarget_t(8); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_VCD_BOARD: nvmlThermalTarget_t = nvmlThermalTarget_t(9); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_VCD_INLET: nvmlThermalTarget_t = nvmlThermalTarget_t(10); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_VCD_OUTLET: nvmlThermalTarget_t = nvmlThermalTarget_t(11); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_ALL: nvmlThermalTarget_t = nvmlThermalTarget_t(15); +} +impl nvmlThermalTarget_t { + pub const NVML_THERMAL_TARGET_UNKNOWN: nvmlThermalTarget_t = nvmlThermalTarget_t(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlThermalTarget_t(pub ::std::os::raw::c_int); +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_NONE: nvmlThermalController_t = nvmlThermalController_t(0); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_GPU_INTERNAL: nvmlThermalController_t = + nvmlThermalController_t(1); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_ADM1032: nvmlThermalController_t = nvmlThermalController_t(2); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_ADT7461: nvmlThermalController_t = nvmlThermalController_t(3); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_MAX6649: nvmlThermalController_t = nvmlThermalController_t(4); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_MAX1617: nvmlThermalController_t = nvmlThermalController_t(5); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_LM99: nvmlThermalController_t = nvmlThermalController_t(6); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_LM89: nvmlThermalController_t = nvmlThermalController_t(7); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_LM64: nvmlThermalController_t = nvmlThermalController_t(8); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_G781: nvmlThermalController_t = nvmlThermalController_t(9); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_ADT7473: nvmlThermalController_t = + nvmlThermalController_t(10); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_SBMAX6649: nvmlThermalController_t = + nvmlThermalController_t(11); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_VBIOSEVT: nvmlThermalController_t = + nvmlThermalController_t(12); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_OS: nvmlThermalController_t = nvmlThermalController_t(13); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_NVSYSCON_CANOAS: nvmlThermalController_t = + nvmlThermalController_t(14); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_NVSYSCON_E551: nvmlThermalController_t = + nvmlThermalController_t(15); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_MAX6649R: nvmlThermalController_t = + nvmlThermalController_t(16); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_ADT7473S: nvmlThermalController_t = + nvmlThermalController_t(17); +} +impl nvmlThermalController_t { + pub const NVML_THERMAL_CONTROLLER_UNKNOWN: nvmlThermalController_t = + nvmlThermalController_t(-1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlThermalController_t(pub ::std::os::raw::c_int); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuThermalSettings_t { + pub count: ::std::os::raw::c_uint, + pub sensor: [nvmlGpuThermalSettings_t__bindgen_ty_1; 3usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuThermalSettings_t__bindgen_ty_1 { + pub controller: nvmlThermalController_t, + pub defaultMinTemp: ::std::os::raw::c_int, + pub defaultMaxTemp: ::std::os::raw::c_int, + pub currentTemp: ::std::os::raw::c_int, + pub target: nvmlThermalTarget_t, +} +impl nvmlEnableState_enum { + pub const NVML_FEATURE_DISABLED: nvmlEnableState_enum = nvmlEnableState_enum(0); +} +impl nvmlEnableState_enum { + pub const NVML_FEATURE_ENABLED: nvmlEnableState_enum = nvmlEnableState_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlEnableState_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlEnableState_enum as nvmlEnableState_t; +impl nvmlBrandType_enum { + pub const NVML_BRAND_UNKNOWN: nvmlBrandType_enum = nvmlBrandType_enum(0); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_QUADRO: nvmlBrandType_enum = nvmlBrandType_enum(1); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_TESLA: nvmlBrandType_enum = nvmlBrandType_enum(2); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVS: nvmlBrandType_enum = nvmlBrandType_enum(3); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_GRID: nvmlBrandType_enum = nvmlBrandType_enum(4); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_GEFORCE: nvmlBrandType_enum = nvmlBrandType_enum(5); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_TITAN: nvmlBrandType_enum = nvmlBrandType_enum(6); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_VAPPS: nvmlBrandType_enum = nvmlBrandType_enum(7); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_VPC: nvmlBrandType_enum = nvmlBrandType_enum(8); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_VCS: nvmlBrandType_enum = nvmlBrandType_enum(9); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_VWS: nvmlBrandType_enum = nvmlBrandType_enum(10); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_CLOUD_GAMING: nvmlBrandType_enum = nvmlBrandType_enum(11); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_VGAMING: nvmlBrandType_enum = nvmlBrandType_enum(11); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_QUADRO_RTX: nvmlBrandType_enum = nvmlBrandType_enum(12); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA_RTX: nvmlBrandType_enum = nvmlBrandType_enum(13); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_NVIDIA: nvmlBrandType_enum = nvmlBrandType_enum(14); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_GEFORCE_RTX: nvmlBrandType_enum = nvmlBrandType_enum(15); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_TITAN_RTX: nvmlBrandType_enum = nvmlBrandType_enum(16); +} +impl nvmlBrandType_enum { + pub const NVML_BRAND_COUNT: nvmlBrandType_enum = nvmlBrandType_enum(17); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlBrandType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlBrandType_enum as nvmlBrandType_t; +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_SHUTDOWN: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(0); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_SLOWDOWN: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(1); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_MEM_MAX: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(2); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_GPU_MAX: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(3); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MIN: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(4); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_CURR: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(5); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MAX: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(6); +} +impl nvmlTemperatureThresholds_enum { + pub const NVML_TEMPERATURE_THRESHOLD_COUNT: nvmlTemperatureThresholds_enum = + nvmlTemperatureThresholds_enum(7); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlTemperatureThresholds_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlTemperatureThresholds_enum as nvmlTemperatureThresholds_t; +impl nvmlTemperatureSensors_enum { + pub const NVML_TEMPERATURE_GPU: nvmlTemperatureSensors_enum = nvmlTemperatureSensors_enum(0); +} +impl nvmlTemperatureSensors_enum { + pub const NVML_TEMPERATURE_COUNT: nvmlTemperatureSensors_enum = nvmlTemperatureSensors_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlTemperatureSensors_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlTemperatureSensors_enum as nvmlTemperatureSensors_t; +impl nvmlComputeMode_enum { + pub const NVML_COMPUTEMODE_DEFAULT: nvmlComputeMode_enum = nvmlComputeMode_enum(0); +} +impl nvmlComputeMode_enum { + pub const NVML_COMPUTEMODE_EXCLUSIVE_THREAD: nvmlComputeMode_enum = nvmlComputeMode_enum(1); +} +impl nvmlComputeMode_enum { + pub const NVML_COMPUTEMODE_PROHIBITED: nvmlComputeMode_enum = nvmlComputeMode_enum(2); +} +impl nvmlComputeMode_enum { + pub const NVML_COMPUTEMODE_EXCLUSIVE_PROCESS: nvmlComputeMode_enum = nvmlComputeMode_enum(3); +} +impl nvmlComputeMode_enum { + pub const NVML_COMPUTEMODE_COUNT: nvmlComputeMode_enum = nvmlComputeMode_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlComputeMode_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlComputeMode_enum as nvmlComputeMode_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlClkMonFaultInfo_struct { + pub clkApiDomain: ::std::os::raw::c_uint, + pub clkDomainFaultMask: ::std::os::raw::c_uint, +} +pub type nvmlClkMonFaultInfo_t = nvmlClkMonFaultInfo_struct; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlClkMonStatus_status { + pub bGlobalStatus: ::std::os::raw::c_uint, + pub clkMonListSize: ::std::os::raw::c_uint, + pub clkMonList: [nvmlClkMonFaultInfo_t; 32usize], +} +pub type nvmlClkMonStatus_t = nvmlClkMonStatus_status; +impl nvmlMemoryErrorType_enum { + pub const NVML_MEMORY_ERROR_TYPE_CORRECTED: nvmlMemoryErrorType_enum = + nvmlMemoryErrorType_enum(0); +} +impl nvmlMemoryErrorType_enum { + pub const NVML_MEMORY_ERROR_TYPE_UNCORRECTED: nvmlMemoryErrorType_enum = + nvmlMemoryErrorType_enum(1); +} +impl nvmlMemoryErrorType_enum { + pub const NVML_MEMORY_ERROR_TYPE_COUNT: nvmlMemoryErrorType_enum = nvmlMemoryErrorType_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlMemoryErrorType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlMemoryErrorType_enum as nvmlMemoryErrorType_t; +impl nvmlEccCounterType_enum { + pub const NVML_VOLATILE_ECC: nvmlEccCounterType_enum = nvmlEccCounterType_enum(0); +} +impl nvmlEccCounterType_enum { + pub const NVML_AGGREGATE_ECC: nvmlEccCounterType_enum = nvmlEccCounterType_enum(1); +} +impl nvmlEccCounterType_enum { + pub const NVML_ECC_COUNTER_TYPE_COUNT: nvmlEccCounterType_enum = nvmlEccCounterType_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlEccCounterType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlEccCounterType_enum as nvmlEccCounterType_t; +impl nvmlClockType_enum { + pub const NVML_CLOCK_GRAPHICS: nvmlClockType_enum = nvmlClockType_enum(0); +} +impl nvmlClockType_enum { + pub const NVML_CLOCK_SM: nvmlClockType_enum = nvmlClockType_enum(1); +} +impl nvmlClockType_enum { + pub const NVML_CLOCK_MEM: nvmlClockType_enum = nvmlClockType_enum(2); +} +impl nvmlClockType_enum { + pub const NVML_CLOCK_VIDEO: nvmlClockType_enum = nvmlClockType_enum(3); +} +impl nvmlClockType_enum { + pub const NVML_CLOCK_COUNT: nvmlClockType_enum = nvmlClockType_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlClockType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlClockType_enum as nvmlClockType_t; +impl nvmlClockId_enum { + pub const NVML_CLOCK_ID_CURRENT: nvmlClockId_enum = nvmlClockId_enum(0); +} +impl nvmlClockId_enum { + pub const NVML_CLOCK_ID_APP_CLOCK_TARGET: nvmlClockId_enum = nvmlClockId_enum(1); +} +impl nvmlClockId_enum { + pub const NVML_CLOCK_ID_APP_CLOCK_DEFAULT: nvmlClockId_enum = nvmlClockId_enum(2); +} +impl nvmlClockId_enum { + pub const NVML_CLOCK_ID_CUSTOMER_BOOST_MAX: nvmlClockId_enum = nvmlClockId_enum(3); +} +impl nvmlClockId_enum { + pub const NVML_CLOCK_ID_COUNT: nvmlClockId_enum = nvmlClockId_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlClockId_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlClockId_enum as nvmlClockId_t; +impl nvmlDriverModel_enum { + pub const NVML_DRIVER_WDDM: nvmlDriverModel_enum = nvmlDriverModel_enum(0); +} +impl nvmlDriverModel_enum { + pub const NVML_DRIVER_WDM: nvmlDriverModel_enum = nvmlDriverModel_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlDriverModel_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlDriverModel_enum as nvmlDriverModel_t; +impl nvmlPStates_enum { + pub const NVML_PSTATE_0: nvmlPStates_enum = nvmlPStates_enum(0); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_1: nvmlPStates_enum = nvmlPStates_enum(1); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_2: nvmlPStates_enum = nvmlPStates_enum(2); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_3: nvmlPStates_enum = nvmlPStates_enum(3); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_4: nvmlPStates_enum = nvmlPStates_enum(4); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_5: nvmlPStates_enum = nvmlPStates_enum(5); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_6: nvmlPStates_enum = nvmlPStates_enum(6); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_7: nvmlPStates_enum = nvmlPStates_enum(7); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_8: nvmlPStates_enum = nvmlPStates_enum(8); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_9: nvmlPStates_enum = nvmlPStates_enum(9); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_10: nvmlPStates_enum = nvmlPStates_enum(10); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_11: nvmlPStates_enum = nvmlPStates_enum(11); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_12: nvmlPStates_enum = nvmlPStates_enum(12); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_13: nvmlPStates_enum = nvmlPStates_enum(13); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_14: nvmlPStates_enum = nvmlPStates_enum(14); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_15: nvmlPStates_enum = nvmlPStates_enum(15); +} +impl nvmlPStates_enum { + pub const NVML_PSTATE_UNKNOWN: nvmlPStates_enum = nvmlPStates_enum(32); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlPStates_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlPStates_enum as nvmlPstates_t; +impl nvmlGom_enum { + pub const NVML_GOM_ALL_ON: nvmlGom_enum = nvmlGom_enum(0); +} +impl nvmlGom_enum { + pub const NVML_GOM_COMPUTE: nvmlGom_enum = nvmlGom_enum(1); +} +impl nvmlGom_enum { + pub const NVML_GOM_LOW_DP: nvmlGom_enum = nvmlGom_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGom_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlGom_enum as nvmlGpuOperationMode_t; +impl nvmlInforomObject_enum { + pub const NVML_INFOROM_OEM: nvmlInforomObject_enum = nvmlInforomObject_enum(0); +} +impl nvmlInforomObject_enum { + pub const NVML_INFOROM_ECC: nvmlInforomObject_enum = nvmlInforomObject_enum(1); +} +impl nvmlInforomObject_enum { + pub const NVML_INFOROM_POWER: nvmlInforomObject_enum = nvmlInforomObject_enum(2); +} +impl nvmlInforomObject_enum { + pub const NVML_INFOROM_COUNT: nvmlInforomObject_enum = nvmlInforomObject_enum(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlInforomObject_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlInforomObject_enum as nvmlInforomObject_t; +impl nvmlReturn_enum { + pub const NVML_SUCCESS: nvmlReturn_enum = nvmlReturn_enum(0); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_UNINITIALIZED: nvmlReturn_enum = nvmlReturn_enum(1); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_INVALID_ARGUMENT: nvmlReturn_enum = nvmlReturn_enum(2); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_NOT_SUPPORTED: nvmlReturn_enum = nvmlReturn_enum(3); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_NO_PERMISSION: nvmlReturn_enum = nvmlReturn_enum(4); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_ALREADY_INITIALIZED: nvmlReturn_enum = nvmlReturn_enum(5); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_NOT_FOUND: nvmlReturn_enum = nvmlReturn_enum(6); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_INSUFFICIENT_SIZE: nvmlReturn_enum = nvmlReturn_enum(7); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_INSUFFICIENT_POWER: nvmlReturn_enum = nvmlReturn_enum(8); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_DRIVER_NOT_LOADED: nvmlReturn_enum = nvmlReturn_enum(9); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_TIMEOUT: nvmlReturn_enum = nvmlReturn_enum(10); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_IRQ_ISSUE: nvmlReturn_enum = nvmlReturn_enum(11); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_LIBRARY_NOT_FOUND: nvmlReturn_enum = nvmlReturn_enum(12); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_FUNCTION_NOT_FOUND: nvmlReturn_enum = nvmlReturn_enum(13); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_CORRUPTED_INFOROM: nvmlReturn_enum = nvmlReturn_enum(14); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_GPU_IS_LOST: nvmlReturn_enum = nvmlReturn_enum(15); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_RESET_REQUIRED: nvmlReturn_enum = nvmlReturn_enum(16); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_OPERATING_SYSTEM: nvmlReturn_enum = nvmlReturn_enum(17); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_LIB_RM_VERSION_MISMATCH: nvmlReturn_enum = nvmlReturn_enum(18); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_IN_USE: nvmlReturn_enum = nvmlReturn_enum(19); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_MEMORY: nvmlReturn_enum = nvmlReturn_enum(20); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_NO_DATA: nvmlReturn_enum = nvmlReturn_enum(21); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_VGPU_ECC_NOT_SUPPORTED: nvmlReturn_enum = nvmlReturn_enum(22); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_INSUFFICIENT_RESOURCES: nvmlReturn_enum = nvmlReturn_enum(23); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_FREQ_NOT_SUPPORTED: nvmlReturn_enum = nvmlReturn_enum(24); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_ARGUMENT_VERSION_MISMATCH: nvmlReturn_enum = nvmlReturn_enum(25); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_DEPRECATED: nvmlReturn_enum = nvmlReturn_enum(26); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_NOT_READY: nvmlReturn_enum = nvmlReturn_enum(27); +} +impl nvmlReturn_enum { + pub const NVML_ERROR_UNKNOWN: nvmlReturn_enum = nvmlReturn_enum(999); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlReturn_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlReturn_enum as nvmlReturn_t; +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_L1_CACHE: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(0); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_L2_CACHE: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(1); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_DRAM: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(2); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_DEVICE_MEMORY: nvmlMemoryLocation_enum = + nvmlMemoryLocation_enum(2); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_REGISTER_FILE: nvmlMemoryLocation_enum = + nvmlMemoryLocation_enum(3); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_TEXTURE_MEMORY: nvmlMemoryLocation_enum = + nvmlMemoryLocation_enum(4); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_TEXTURE_SHM: nvmlMemoryLocation_enum = + nvmlMemoryLocation_enum(5); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_CBU: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(6); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_SRAM: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(7); +} +impl nvmlMemoryLocation_enum { + pub const NVML_MEMORY_LOCATION_COUNT: nvmlMemoryLocation_enum = nvmlMemoryLocation_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlMemoryLocation_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlMemoryLocation_enum as nvmlMemoryLocation_t; +impl nvmlPageRetirementCause_enum { + pub const NVML_PAGE_RETIREMENT_CAUSE_MULTIPLE_SINGLE_BIT_ECC_ERRORS: + nvmlPageRetirementCause_enum = nvmlPageRetirementCause_enum(0); +} +impl nvmlPageRetirementCause_enum { + pub const NVML_PAGE_RETIREMENT_CAUSE_DOUBLE_BIT_ECC_ERROR: nvmlPageRetirementCause_enum = + nvmlPageRetirementCause_enum(1); +} +impl nvmlPageRetirementCause_enum { + pub const NVML_PAGE_RETIREMENT_CAUSE_COUNT: nvmlPageRetirementCause_enum = + nvmlPageRetirementCause_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlPageRetirementCause_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlPageRetirementCause_enum as nvmlPageRetirementCause_t; +impl nvmlRestrictedAPI_enum { + pub const NVML_RESTRICTED_API_SET_APPLICATION_CLOCKS: nvmlRestrictedAPI_enum = + nvmlRestrictedAPI_enum(0); +} +impl nvmlRestrictedAPI_enum { + pub const NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS: nvmlRestrictedAPI_enum = + nvmlRestrictedAPI_enum(1); +} +impl nvmlRestrictedAPI_enum { + pub const NVML_RESTRICTED_API_COUNT: nvmlRestrictedAPI_enum = nvmlRestrictedAPI_enum(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlRestrictedAPI_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlRestrictedAPI_enum as nvmlRestrictedAPI_t; +impl nvmlGpuVirtualizationMode { + pub const NVML_GPU_VIRTUALIZATION_MODE_NONE: nvmlGpuVirtualizationMode = + nvmlGpuVirtualizationMode(0); +} +impl nvmlGpuVirtualizationMode { + pub const NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH: nvmlGpuVirtualizationMode = + nvmlGpuVirtualizationMode(1); +} +impl nvmlGpuVirtualizationMode { + pub const NVML_GPU_VIRTUALIZATION_MODE_VGPU: nvmlGpuVirtualizationMode = + nvmlGpuVirtualizationMode(2); +} +impl nvmlGpuVirtualizationMode { + pub const NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU: nvmlGpuVirtualizationMode = + nvmlGpuVirtualizationMode(3); +} +impl nvmlGpuVirtualizationMode { + pub const NVML_GPU_VIRTUALIZATION_MODE_HOST_VSGA: nvmlGpuVirtualizationMode = + nvmlGpuVirtualizationMode(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGpuVirtualizationMode(pub ::std::os::raw::c_uint); +pub use self::nvmlGpuVirtualizationMode as nvmlGpuVirtualizationMode_t; +impl nvmlHostVgpuMode_enum { + pub const NVML_HOST_VGPU_MODE_NON_SRIOV: nvmlHostVgpuMode_enum = nvmlHostVgpuMode_enum(0); +} +impl nvmlHostVgpuMode_enum { + pub const NVML_HOST_VGPU_MODE_SRIOV: nvmlHostVgpuMode_enum = nvmlHostVgpuMode_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlHostVgpuMode_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlHostVgpuMode_enum as nvmlHostVgpuMode_t; +impl nvmlVgpuVmIdType { + pub const NVML_VGPU_VM_ID_DOMAIN_ID: nvmlVgpuVmIdType = nvmlVgpuVmIdType(0); +} +impl nvmlVgpuVmIdType { + pub const NVML_VGPU_VM_ID_UUID: nvmlVgpuVmIdType = nvmlVgpuVmIdType(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuVmIdType(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuVmIdType as nvmlVgpuVmIdType_t; +impl nvmlVgpuGuestInfoState_enum { + pub const NVML_VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED: nvmlVgpuGuestInfoState_enum = + nvmlVgpuGuestInfoState_enum(0); +} +impl nvmlVgpuGuestInfoState_enum { + pub const NVML_VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED: nvmlVgpuGuestInfoState_enum = + nvmlVgpuGuestInfoState_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuGuestInfoState_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuGuestInfoState_enum as nvmlVgpuGuestInfoState_t; +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_UNKNOWN: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(0); +} +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_VGPU: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(1); +} +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(2); +} +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_VWORKSTATION: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(2); +} +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_GAMING: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(3); +} +impl nvmlGridLicenseFeatureCode_t { + pub const NVML_GRID_LICENSE_FEATURE_CODE_COMPUTE: nvmlGridLicenseFeatureCode_t = + nvmlGridLicenseFeatureCode_t(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlGridLicenseFeatureCode_t(pub ::std::os::raw::c_uint); +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_NVLINK_P2P: nvmlVgpuCapability_enum = nvmlVgpuCapability_enum(0); +} +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_GPUDIRECT: nvmlVgpuCapability_enum = nvmlVgpuCapability_enum(1); +} +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_MULTI_VGPU_EXCLUSIVE: nvmlVgpuCapability_enum = + nvmlVgpuCapability_enum(2); +} +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_EXCLUSIVE_TYPE: nvmlVgpuCapability_enum = nvmlVgpuCapability_enum(3); +} +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_EXCLUSIVE_SIZE: nvmlVgpuCapability_enum = nvmlVgpuCapability_enum(4); +} +impl nvmlVgpuCapability_enum { + pub const NVML_VGPU_CAP_COUNT: nvmlVgpuCapability_enum = nvmlVgpuCapability_enum(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuCapability_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuCapability_enum as nvmlVgpuCapability_t; +impl nvmlVgpuDriverCapability_enum { + pub const NVML_VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU: nvmlVgpuDriverCapability_enum = + nvmlVgpuDriverCapability_enum(0); +} +impl nvmlVgpuDriverCapability_enum { + pub const NVML_VGPU_DRIVER_CAP_COUNT: nvmlVgpuDriverCapability_enum = + nvmlVgpuDriverCapability_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuDriverCapability_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuDriverCapability_enum as nvmlVgpuDriverCapability_t; +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(0); +} +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(1); +} +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(2); +} +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(3); +} +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(4); +} +impl nvmlDeviceVgpuCapability_enum { + pub const NVML_DEVICE_VGPU_CAP_COUNT: nvmlDeviceVgpuCapability_enum = + nvmlDeviceVgpuCapability_enum(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlDeviceVgpuCapability_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlDeviceVgpuCapability_enum as nvmlDeviceVgpuCapability_t; +pub type nvmlVgpuTypeId_t = ::std::os::raw::c_uint; +pub type nvmlVgpuInstance_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuInstanceUtilizationSample_st { + pub vgpuInstance: nvmlVgpuInstance_t, + pub timeStamp: ::std::os::raw::c_ulonglong, + pub smUtil: nvmlValue_t, + pub memUtil: nvmlValue_t, + pub encUtil: nvmlValue_t, + pub decUtil: nvmlValue_t, +} +pub type nvmlVgpuInstanceUtilizationSample_t = nvmlVgpuInstanceUtilizationSample_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuProcessUtilizationSample_st { + pub vgpuInstance: nvmlVgpuInstance_t, + pub pid: ::std::os::raw::c_uint, + pub processName: [::std::os::raw::c_char; 64usize], + pub timeStamp: ::std::os::raw::c_ulonglong, + pub smUtil: ::std::os::raw::c_uint, + pub memUtil: ::std::os::raw::c_uint, + pub encUtil: ::std::os::raw::c_uint, + pub decUtil: ::std::os::raw::c_uint, +} +pub type nvmlVgpuProcessUtilizationSample_t = nvmlVgpuProcessUtilizationSample_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub union nvmlVgpuSchedulerParams_t { + pub vgpuSchedDataWithARR: nvmlVgpuSchedulerParams_t__bindgen_ty_1, + pub vgpuSchedData: nvmlVgpuSchedulerParams_t__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerParams_t__bindgen_ty_1 { + pub avgFactor: ::std::os::raw::c_uint, + pub timeslice: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerParams_t__bindgen_ty_2 { + pub timeslice: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerLogEntries_st { + pub timestamp: ::std::os::raw::c_ulonglong, + pub timeRunTotal: ::std::os::raw::c_ulonglong, + pub timeRun: ::std::os::raw::c_ulonglong, + pub swRunlistId: ::std::os::raw::c_uint, + pub targetTimeSlice: ::std::os::raw::c_ulonglong, + pub cumulativePreemptionTime: ::std::os::raw::c_ulonglong, +} +pub type nvmlVgpuSchedulerLogEntry_t = nvmlVgpuSchedulerLogEntries_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerLog_st { + pub engineId: ::std::os::raw::c_uint, + pub schedulerPolicy: ::std::os::raw::c_uint, + pub isEnabledARR: ::std::os::raw::c_uint, + pub schedulerParams: nvmlVgpuSchedulerParams_t, + pub entriesCount: ::std::os::raw::c_uint, + pub logEntries: [nvmlVgpuSchedulerLogEntry_t; 200usize], +} +pub type nvmlVgpuSchedulerLog_t = nvmlVgpuSchedulerLog_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerGetState_st { + pub schedulerPolicy: ::std::os::raw::c_uint, + pub isEnabledARR: ::std::os::raw::c_uint, + pub schedulerParams: nvmlVgpuSchedulerParams_t, +} +pub type nvmlVgpuSchedulerGetState_t = nvmlVgpuSchedulerGetState_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub union nvmlVgpuSchedulerSetParams_t { + pub vgpuSchedDataWithARR: nvmlVgpuSchedulerSetParams_t__bindgen_ty_1, + pub vgpuSchedData: nvmlVgpuSchedulerSetParams_t__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerSetParams_t__bindgen_ty_1 { + pub avgFactor: ::std::os::raw::c_uint, + pub frequency: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerSetParams_t__bindgen_ty_2 { + pub timeslice: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerSetState_st { + pub schedulerPolicy: ::std::os::raw::c_uint, + pub enableARRMode: ::std::os::raw::c_uint, + pub schedulerParams: nvmlVgpuSchedulerSetParams_t, +} +pub type nvmlVgpuSchedulerSetState_t = nvmlVgpuSchedulerSetState_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuSchedulerCapabilities_st { + pub supportedSchedulers: [::std::os::raw::c_uint; 3usize], + pub maxTimeslice: ::std::os::raw::c_uint, + pub minTimeslice: ::std::os::raw::c_uint, + pub isArrModeSupported: ::std::os::raw::c_uint, + pub maxFrequencyForARR: ::std::os::raw::c_uint, + pub minFrequencyForARR: ::std::os::raw::c_uint, + pub maxAvgFactorForARR: ::std::os::raw::c_uint, + pub minAvgFactorForARR: ::std::os::raw::c_uint, +} +pub type nvmlVgpuSchedulerCapabilities_t = nvmlVgpuSchedulerCapabilities_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuLicenseExpiry_st { + pub year: ::std::os::raw::c_uint, + pub month: ::std::os::raw::c_ushort, + pub day: ::std::os::raw::c_ushort, + pub hour: ::std::os::raw::c_ushort, + pub min: ::std::os::raw::c_ushort, + pub sec: ::std::os::raw::c_ushort, + pub status: ::std::os::raw::c_uchar, +} +pub type nvmlVgpuLicenseExpiry_t = nvmlVgpuLicenseExpiry_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuLicenseInfo_st { + pub isLicensed: ::std::os::raw::c_uchar, + pub licenseExpiry: nvmlVgpuLicenseExpiry_t, + pub currentState: ::std::os::raw::c_uint, +} +pub type nvmlVgpuLicenseInfo_t = nvmlVgpuLicenseInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlProcessUtilizationSample_st { + pub pid: ::std::os::raw::c_uint, + pub timeStamp: ::std::os::raw::c_ulonglong, + pub smUtil: ::std::os::raw::c_uint, + pub memUtil: ::std::os::raw::c_uint, + pub encUtil: ::std::os::raw::c_uint, + pub decUtil: ::std::os::raw::c_uint, +} +pub type nvmlProcessUtilizationSample_t = nvmlProcessUtilizationSample_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGridLicenseExpiry_st { + pub year: ::std::os::raw::c_uint, + pub month: ::std::os::raw::c_ushort, + pub day: ::std::os::raw::c_ushort, + pub hour: ::std::os::raw::c_ushort, + pub min: ::std::os::raw::c_ushort, + pub sec: ::std::os::raw::c_ushort, + pub status: ::std::os::raw::c_uchar, +} +pub type nvmlGridLicenseExpiry_t = nvmlGridLicenseExpiry_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGridLicensableFeature_st { + pub featureCode: nvmlGridLicenseFeatureCode_t, + pub featureState: ::std::os::raw::c_uint, + pub licenseInfo: [::std::os::raw::c_char; 128usize], + pub productName: [::std::os::raw::c_char; 128usize], + pub featureEnabled: ::std::os::raw::c_uint, + pub licenseExpiry: nvmlGridLicenseExpiry_t, +} +pub type nvmlGridLicensableFeature_t = nvmlGridLicensableFeature_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGridLicensableFeatures_st { + pub isGridLicenseSupported: ::std::os::raw::c_int, + pub licensableFeaturesCount: ::std::os::raw::c_uint, + pub gridLicensableFeatures: [nvmlGridLicensableFeature_t; 3usize], +} +pub type nvmlGridLicensableFeatures_t = nvmlGridLicensableFeatures_st; +pub type nvmlDeviceArchitecture_t = ::std::os::raw::c_uint; +pub type nvmlBusType_t = ::std::os::raw::c_uint; +pub type nvmlFanControlPolicy_t = ::std::os::raw::c_uint; +pub type nvmlPowerSource_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuDynamicPstatesInfo_st { + pub flags: ::std::os::raw::c_uint, + pub utilization: [nvmlGpuDynamicPstatesInfo_st__bindgen_ty_1; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuDynamicPstatesInfo_st__bindgen_ty_1 { + pub bIsPresent: ::std::os::raw::c_uint, + pub percentage: ::std::os::raw::c_uint, + pub incThreshold: ::std::os::raw::c_uint, + pub decThreshold: ::std::os::raw::c_uint, +} +pub type nvmlGpuDynamicPstatesInfo_t = nvmlGpuDynamicPstatesInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlFieldValue_st { + pub fieldId: ::std::os::raw::c_uint, + pub scopeId: ::std::os::raw::c_uint, + pub timestamp: ::std::os::raw::c_longlong, + pub latencyUsec: ::std::os::raw::c_longlong, + pub valueType: nvmlValueType_t, + pub nvmlReturn: nvmlReturn_t, + pub value: nvmlValue_t, +} +pub type nvmlFieldValue_t = nvmlFieldValue_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlUnit_st { + _unused: [u8; 0], +} +pub type nvmlUnit_t = *mut nvmlUnit_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlHwbcEntry_st { + pub hwbcId: ::std::os::raw::c_uint, + pub firmwareVersion: [::std::os::raw::c_char; 32usize], +} +pub type nvmlHwbcEntry_t = nvmlHwbcEntry_st; +impl nvmlFanState_enum { + pub const NVML_FAN_NORMAL: nvmlFanState_enum = nvmlFanState_enum(0); +} +impl nvmlFanState_enum { + pub const NVML_FAN_FAILED: nvmlFanState_enum = nvmlFanState_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlFanState_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlFanState_enum as nvmlFanState_t; +impl nvmlLedColor_enum { + pub const NVML_LED_COLOR_GREEN: nvmlLedColor_enum = nvmlLedColor_enum(0); +} +impl nvmlLedColor_enum { + pub const NVML_LED_COLOR_AMBER: nvmlLedColor_enum = nvmlLedColor_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlLedColor_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlLedColor_enum as nvmlLedColor_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlLedState_st { + pub cause: [::std::os::raw::c_char; 256usize], + pub color: nvmlLedColor_t, +} +pub type nvmlLedState_t = nvmlLedState_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlUnitInfo_st { + pub name: [::std::os::raw::c_char; 96usize], + pub id: [::std::os::raw::c_char; 96usize], + pub serial: [::std::os::raw::c_char; 96usize], + pub firmwareVersion: [::std::os::raw::c_char; 96usize], +} +pub type nvmlUnitInfo_t = nvmlUnitInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlPSUInfo_st { + pub state: [::std::os::raw::c_char; 256usize], + pub current: ::std::os::raw::c_uint, + pub voltage: ::std::os::raw::c_uint, + pub power: ::std::os::raw::c_uint, +} +pub type nvmlPSUInfo_t = nvmlPSUInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlUnitFanInfo_st { + pub speed: ::std::os::raw::c_uint, + pub state: nvmlFanState_t, +} +pub type nvmlUnitFanInfo_t = nvmlUnitFanInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlUnitFanSpeeds_st { + pub fans: [nvmlUnitFanInfo_t; 24usize], + pub count: ::std::os::raw::c_uint, +} +pub type nvmlUnitFanSpeeds_t = nvmlUnitFanSpeeds_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlEventSet_st { + _unused: [u8; 0], +} +pub type nvmlEventSet_t = *mut nvmlEventSet_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlEventData_st { + pub device: nvmlDevice_t, + pub eventType: ::std::os::raw::c_ulonglong, + pub eventData: ::std::os::raw::c_ulonglong, + pub gpuInstanceId: ::std::os::raw::c_uint, + pub computeInstanceId: ::std::os::raw::c_uint, +} +pub type nvmlEventData_t = nvmlEventData_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlAccountingStats_st { + pub gpuUtilization: ::std::os::raw::c_uint, + pub memoryUtilization: ::std::os::raw::c_uint, + pub maxMemoryUsage: ::std::os::raw::c_ulonglong, + pub time: ::std::os::raw::c_ulonglong, + pub startTime: ::std::os::raw::c_ulonglong, + pub isRunning: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 5usize], +} +pub type nvmlAccountingStats_t = nvmlAccountingStats_st; +impl nvmlEncoderQueryType_enum { + pub const NVML_ENCODER_QUERY_H264: nvmlEncoderQueryType_enum = nvmlEncoderQueryType_enum(0); +} +impl nvmlEncoderQueryType_enum { + pub const NVML_ENCODER_QUERY_HEVC: nvmlEncoderQueryType_enum = nvmlEncoderQueryType_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlEncoderQueryType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlEncoderQueryType_enum as nvmlEncoderType_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlEncoderSessionInfo_st { + pub sessionId: ::std::os::raw::c_uint, + pub pid: ::std::os::raw::c_uint, + pub vgpuInstance: nvmlVgpuInstance_t, + pub codecType: nvmlEncoderType_t, + pub hResolution: ::std::os::raw::c_uint, + pub vResolution: ::std::os::raw::c_uint, + pub averageFps: ::std::os::raw::c_uint, + pub averageLatency: ::std::os::raw::c_uint, +} +pub type nvmlEncoderSessionInfo_t = nvmlEncoderSessionInfo_st; +impl nvmlFBCSessionType_enum { + pub const NVML_FBC_SESSION_TYPE_UNKNOWN: nvmlFBCSessionType_enum = nvmlFBCSessionType_enum(0); +} +impl nvmlFBCSessionType_enum { + pub const NVML_FBC_SESSION_TYPE_TOSYS: nvmlFBCSessionType_enum = nvmlFBCSessionType_enum(1); +} +impl nvmlFBCSessionType_enum { + pub const NVML_FBC_SESSION_TYPE_CUDA: nvmlFBCSessionType_enum = nvmlFBCSessionType_enum(2); +} +impl nvmlFBCSessionType_enum { + pub const NVML_FBC_SESSION_TYPE_VID: nvmlFBCSessionType_enum = nvmlFBCSessionType_enum(3); +} +impl nvmlFBCSessionType_enum { + pub const NVML_FBC_SESSION_TYPE_HWENC: nvmlFBCSessionType_enum = nvmlFBCSessionType_enum(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlFBCSessionType_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlFBCSessionType_enum as nvmlFBCSessionType_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlFBCStats_st { + pub sessionsCount: ::std::os::raw::c_uint, + pub averageFPS: ::std::os::raw::c_uint, + pub averageLatency: ::std::os::raw::c_uint, +} +pub type nvmlFBCStats_t = nvmlFBCStats_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlFBCSessionInfo_st { + pub sessionId: ::std::os::raw::c_uint, + pub pid: ::std::os::raw::c_uint, + pub vgpuInstance: nvmlVgpuInstance_t, + pub displayOrdinal: ::std::os::raw::c_uint, + pub sessionType: nvmlFBCSessionType_t, + pub sessionFlags: ::std::os::raw::c_uint, + pub hMaxResolution: ::std::os::raw::c_uint, + pub vMaxResolution: ::std::os::raw::c_uint, + pub hResolution: ::std::os::raw::c_uint, + pub vResolution: ::std::os::raw::c_uint, + pub averageFPS: ::std::os::raw::c_uint, + pub averageLatency: ::std::os::raw::c_uint, +} +pub type nvmlFBCSessionInfo_t = nvmlFBCSessionInfo_st; +impl nvmlDetachGpuState_enum { + pub const NVML_DETACH_GPU_KEEP: nvmlDetachGpuState_enum = nvmlDetachGpuState_enum(0); +} +impl nvmlDetachGpuState_enum { + pub const NVML_DETACH_GPU_REMOVE: nvmlDetachGpuState_enum = nvmlDetachGpuState_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlDetachGpuState_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlDetachGpuState_enum as nvmlDetachGpuState_t; +impl nvmlPcieLinkState_enum { + pub const NVML_PCIE_LINK_KEEP: nvmlPcieLinkState_enum = nvmlPcieLinkState_enum(0); +} +impl nvmlPcieLinkState_enum { + pub const NVML_PCIE_LINK_SHUT_DOWN: nvmlPcieLinkState_enum = nvmlPcieLinkState_enum(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlPcieLinkState_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlPcieLinkState_enum as nvmlPcieLinkState_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlConfComputeSystemCaps_st { + pub cpuCaps: ::std::os::raw::c_uint, + pub gpusCaps: ::std::os::raw::c_uint, +} +pub type nvmlConfComputeSystemCaps_t = nvmlConfComputeSystemCaps_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlConfComputeSystemState_st { + pub environment: ::std::os::raw::c_uint, + pub ccFeature: ::std::os::raw::c_uint, + pub devToolsMode: ::std::os::raw::c_uint, +} +pub type nvmlConfComputeSystemState_t = nvmlConfComputeSystemState_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlConfComputeMemSizeInfo_st { + pub protectedMemSizeKib: ::std::os::raw::c_ulonglong, + pub unprotectedMemSizeKib: ::std::os::raw::c_ulonglong, +} +pub type nvmlConfComputeMemSizeInfo_t = nvmlConfComputeMemSizeInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlConfComputeGpuCertificate_st { + pub certChainSize: ::std::os::raw::c_uint, + pub attestationCertChainSize: ::std::os::raw::c_uint, + pub certChain: [::std::os::raw::c_uchar; 4096usize], + pub attestationCertChain: [::std::os::raw::c_uchar; 5120usize], +} +pub type nvmlConfComputeGpuCertificate_t = nvmlConfComputeGpuCertificate_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlConfComputeGpuAttestationReport_st { + pub isCecAttestationReportPresent: ::std::os::raw::c_uint, + pub attestationReportSize: ::std::os::raw::c_uint, + pub cecAttestationReportSize: ::std::os::raw::c_uint, + pub nonce: [::std::os::raw::c_uchar; 32usize], + pub attestationReport: [::std::os::raw::c_uchar; 8192usize], + pub cecAttestationReport: [::std::os::raw::c_uchar; 4096usize], +} +pub type nvmlConfComputeGpuAttestationReport_t = nvmlConfComputeGpuAttestationReport_st; +pub type nvmlGpuFabricState_t = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuFabricInfo_t { + pub clusterUuid: [::std::os::raw::c_char; 16usize], + pub status: nvmlReturn_t, + pub partitionId: ::std::os::raw::c_uint, + pub state: nvmlGpuFabricState_t, +} +pub type nvmlPowerScopeType_t = ::std::os::raw::c_uchar; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlPowerValue_v2_t { + pub version: ::std::os::raw::c_uint, + pub powerScope: nvmlPowerScopeType_t, + pub powerValueMw: ::std::os::raw::c_uint, +} + +#[no_mangle] +pub extern "C" fn nvmlInit_v2() -> nvmlReturn_t { + unsafe { crate::r#impl::init().into() } +} + +#[no_mangle] +pub extern "C" fn nvmlInitWithFlags(flags: ::std::os::raw::c_uint) -> nvmlReturn_t { + unsafe { crate::r#impl::init_with_flags(flags).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlShutdown() -> nvmlReturn_t { + unsafe { crate::r#impl::shutdown() } +} + +#[no_mangle] +pub extern "C" fn nvmlErrorString(result: nvmlReturn_t) -> *const ::std::os::raw::c_char { + crate::common::error_string(result) +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetDriverVersion( + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::common::system_get_driver_version(version, length).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetNVMLVersion( + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::common::system_get_nvml_version(version, length).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetCudaDriverVersion( + cudaDriverVersion: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + unsafe { crate::common::system_get_cuda_driver_version(cudaDriverVersion).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetCudaDriverVersion_v2( + cudaDriverVersion: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + unsafe { crate::common::system_get_cuda_driver_version(cudaDriverVersion).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetProcessName( + pid: ::std::os::raw::c_uint, + name: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetCount(unitCount: *mut ::std::os::raw::c_uint) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetHandleByIndex( + index: ::std::os::raw::c_uint, + unit: *mut nvmlUnit_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetUnitInfo(unit: nvmlUnit_t, info: *mut nvmlUnitInfo_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetLedState( + unit: nvmlUnit_t, + state: *mut nvmlLedState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetPsuInfo(unit: nvmlUnit_t, psu: *mut nvmlPSUInfo_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetTemperature( + unit: nvmlUnit_t, + type_: ::std::os::raw::c_uint, + temp: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetFanSpeedInfo( + unit: nvmlUnit_t, + fanSpeeds: *mut nvmlUnitFanSpeeds_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitGetDevices( + unit: nvmlUnit_t, + deviceCount: *mut ::std::os::raw::c_uint, + devices: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetHicVersion( + hwbcCount: *mut ::std::os::raw::c_uint, + hwbcEntries: *mut nvmlHwbcEntry_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCount_v2(deviceCount: *mut ::std::os::raw::c_uint) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_count(deviceCount) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAttributes_v2( + device: nvmlDevice_t, + attributes: *mut nvmlDeviceAttributes_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleByIndex_v2( + index: ::std::os::raw::c_uint, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_handle_by_index(index, device) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleBySerial( + serial: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleByUUID( + uuid: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleByPciBusId_v2( + pciBusId: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_handle_by_pci_bus_id(pciBusId, device) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetName( + device: nvmlDevice_t, + name: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBrand( + device: nvmlDevice_t, + type_: *mut nvmlBrandType_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetIndex( + device: nvmlDevice_t, + index: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSerial( + device: nvmlDevice_t, + serial: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetModuleId( + device: nvmlDevice_t, + moduleId: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +pub type nvmlAffinityScope_t = ::std::os::raw::c_uint; + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemoryAffinity( + device: nvmlDevice_t, + nodeSetSize: ::std::os::raw::c_uint, + nodeSet: *mut ::std::os::raw::c_ulong, + scope: nvmlAffinityScope_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCpuAffinityWithinScope( + device: nvmlDevice_t, + cpuSetSize: ::std::os::raw::c_uint, + cpuSet: *mut ::std::os::raw::c_ulong, + scope: nvmlAffinityScope_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCpuAffinity( + device: nvmlDevice_t, + cpuSetSize: ::std::os::raw::c_uint, + cpuSet: *mut ::std::os::raw::c_ulong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetCpuAffinity(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceClearCpuAffinity(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTopologyCommonAncestor( + device1: nvmlDevice_t, + device2: nvmlDevice_t, + pathInfo: *mut nvmlGpuTopologyLevel_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTopologyNearestGpus( + device: nvmlDevice_t, + level: nvmlGpuTopologyLevel_t, + count: *mut ::std::os::raw::c_uint, + deviceArray: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetTopologyGpuSet( + cpuNumber: ::std::os::raw::c_uint, + count: *mut ::std::os::raw::c_uint, + deviceArray: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetP2PStatus( + device1: nvmlDevice_t, + device2: nvmlDevice_t, + p2pIndex: nvmlGpuP2PCapsIndex_t, + p2pStatus: *mut nvmlGpuP2PStatus_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetUUID( + device: nvmlDevice_t, + uuid: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetMdevUUID( + vgpuInstance: nvmlVgpuInstance_t, + mdevUuid: *mut ::std::os::raw::c_char, + size: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMinorNumber( + device: nvmlDevice_t, + minorNumber: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBoardPartNumber( + device: nvmlDevice_t, + partNumber: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetInforomVersion( + device: nvmlDevice_t, + object: nvmlInforomObject_t, + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetInforomImageVersion( + device: nvmlDevice_t, + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetInforomConfigurationChecksum( + device: nvmlDevice_t, + checksum: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceValidateInforom(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDisplayMode( + device: nvmlDevice_t, + display: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDisplayActive( + device: nvmlDevice_t, + isActive: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPersistenceMode( + device: nvmlDevice_t, + mode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPciInfo_v3( + device: nvmlDevice_t, + pci: *mut nvmlPciInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMaxPcieLinkGeneration( + device: nvmlDevice_t, + maxLinkGen: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuMaxPcieLinkGeneration( + device: nvmlDevice_t, + maxLinkGenDevice: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMaxPcieLinkWidth( + device: nvmlDevice_t, + maxLinkWidth: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCurrPcieLinkGeneration( + device: nvmlDevice_t, + currLinkGen: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCurrPcieLinkWidth( + device: nvmlDevice_t, + currLinkWidth: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPcieThroughput( + device: nvmlDevice_t, + counter: nvmlPcieUtilCounter_t, + value: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_pcie_throughput(device, counter, value) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPcieReplayCounter( + device: nvmlDevice_t, + value: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetClockInfo( + device: nvmlDevice_t, + type_: nvmlClockType_t, + clock: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMaxClockInfo( + device: nvmlDevice_t, + type_: nvmlClockType_t, + clock: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpcClkVfOffset( + device: nvmlDevice_t, + offset: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetApplicationsClock( + device: nvmlDevice_t, + clockType: nvmlClockType_t, + clockMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDefaultApplicationsClock( + device: nvmlDevice_t, + clockType: nvmlClockType_t, + clockMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceResetApplicationsClocks(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetClock( + device: nvmlDevice_t, + clockType: nvmlClockType_t, + clockId: nvmlClockId_t, + clockMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMaxCustomerBoostClock( + device: nvmlDevice_t, + clockType: nvmlClockType_t, + clockMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedMemoryClocks( + device: nvmlDevice_t, + count: *mut ::std::os::raw::c_uint, + clocksMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedGraphicsClocks( + device: nvmlDevice_t, + memoryClockMHz: ::std::os::raw::c_uint, + count: *mut ::std::os::raw::c_uint, + clocksMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAutoBoostedClocksEnabled( + device: nvmlDevice_t, + isEnabled: *mut nvmlEnableState_t, + defaultIsEnabled: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetAutoBoostedClocksEnabled( + device: nvmlDevice_t, + enabled: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetDefaultAutoBoostedClocksEnabled( + device: nvmlDevice_t, + enabled: nvmlEnableState_t, + flags: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetFanSpeed( + device: nvmlDevice_t, + speed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_fan_speed(device, speed).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetFanSpeed_v2( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, + speed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTargetFanSpeed( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, + targetSpeed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetDefaultFanSpeed_v2( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMinMaxFanSpeed( + device: nvmlDevice_t, + minSpeed: *mut ::std::os::raw::c_uint, + maxSpeed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetFanControlPolicy_v2( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, + policy: *mut nvmlFanControlPolicy_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetFanControlPolicy( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, + policy: nvmlFanControlPolicy_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNumFans( + device: nvmlDevice_t, + numFans: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTemperature( + device: nvmlDevice_t, + sensorType: nvmlTemperatureSensors_t, + temp: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_temperature(device, sensorType, temp) } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTemperatureThreshold( + device: nvmlDevice_t, + thresholdType: nvmlTemperatureThresholds_t, + temp: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::common::device_get_temperature_threshold(device, thresholdType, temp) } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetTemperatureThreshold( + device: nvmlDevice_t, + thresholdType: nvmlTemperatureThresholds_t, + temp: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetThermalSettings( + device: nvmlDevice_t, + sensorIndex: ::std::os::raw::c_uint, + pThermalSettings: *mut nvmlGpuThermalSettings_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPerformanceState( + device: nvmlDevice_t, + pState: *mut nvmlPstates_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCurrentClocksEventReasons( + device: nvmlDevice_t, + clocksEventReasons: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCurrentClocksThrottleReasons( + device: nvmlDevice_t, + clocksThrottleReasons: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedClocksEventReasons( + device: nvmlDevice_t, + supportedClocksEventReasons: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedClocksThrottleReasons( + device: nvmlDevice_t, + supportedClocksThrottleReasons: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerState( + device: nvmlDevice_t, + pState: *mut nvmlPstates_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDynamicPstatesInfo( + device: nvmlDevice_t, + pDynamicPstatesInfo: *mut nvmlGpuDynamicPstatesInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemClkVfOffset( + device: nvmlDevice_t, + offset: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMinMaxClockOfPState( + device: nvmlDevice_t, + type_: nvmlClockType_t, + pstate: nvmlPstates_t, + minClockMHz: *mut ::std::os::raw::c_uint, + maxClockMHz: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedPerformanceStates( + device: nvmlDevice_t, + pstates: *mut nvmlPstates_t, + size: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpcClkMinMaxVfOffset( + device: nvmlDevice_t, + minOffset: *mut ::std::os::raw::c_int, + maxOffset: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemClkMinMaxVfOffset( + device: nvmlDevice_t, + minOffset: *mut ::std::os::raw::c_int, + maxOffset: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerManagementMode( + device: nvmlDevice_t, + mode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerManagementLimit( + device: nvmlDevice_t, + limit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_power_management_limit(device, limit) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerManagementLimitConstraints( + device: nvmlDevice_t, + minLimit: *mut ::std::os::raw::c_uint, + maxLimit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_power_management_limit_constraints(device, minLimit, maxLimit) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerManagementDefaultLimit( + device: nvmlDevice_t, + defaultLimit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_power_management_limit(device, defaultLimit) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerUsage( + device: nvmlDevice_t, + power: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_power_usage(device, power) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTotalEnergyConsumption( + device: nvmlDevice_t, + energy: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEnforcedPowerLimit( + device: nvmlDevice_t, + limit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuOperationMode( + device: nvmlDevice_t, + current: *mut nvmlGpuOperationMode_t, + pending: *mut nvmlGpuOperationMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemoryInfo( + device: nvmlDevice_t, + memory: *mut nvmlMemory_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_memory_info(device, memory).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemoryInfo_v2( + device: nvmlDevice_t, + memory: *mut nvmlMemory_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetComputeMode( + device: nvmlDevice_t, + mode: *mut nvmlComputeMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCudaComputeCapability( + device: nvmlDevice_t, + major: *mut ::std::os::raw::c_int, + minor: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEccMode( + device: nvmlDevice_t, + current: *mut nvmlEnableState_t, + pending: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDefaultEccMode( + device: nvmlDevice_t, + defaultMode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBoardId( + device: nvmlDevice_t, + boardId: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMultiGpuBoard( + device: nvmlDevice_t, + multiGpuBool: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetTotalEccErrors( + device: nvmlDevice_t, + errorType: nvmlMemoryErrorType_t, + counterType: nvmlEccCounterType_t, + eccCounts: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDetailedEccErrors( + device: nvmlDevice_t, + errorType: nvmlMemoryErrorType_t, + counterType: nvmlEccCounterType_t, + eccCounts: *mut nvmlEccErrorCounts_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemoryErrorCounter( + device: nvmlDevice_t, + errorType: nvmlMemoryErrorType_t, + counterType: nvmlEccCounterType_t, + locationType: nvmlMemoryLocation_t, + count: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetUtilizationRates( + device: nvmlDevice_t, + utilization: *mut nvmlUtilization_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_utilization_rates(device, utilization).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEncoderUtilization( + device: nvmlDevice_t, + utilization: *mut ::std::os::raw::c_uint, + samplingPeriodUs: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEncoderCapacity( + device: nvmlDevice_t, + encoderQueryType: nvmlEncoderType_t, + encoderCapacity: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEncoderStats( + device: nvmlDevice_t, + sessionCount: *mut ::std::os::raw::c_uint, + averageFps: *mut ::std::os::raw::c_uint, + averageLatency: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetEncoderSessions( + device: nvmlDevice_t, + sessionCount: *mut ::std::os::raw::c_uint, + sessionInfos: *mut nvmlEncoderSessionInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDecoderUtilization( + device: nvmlDevice_t, + utilization: *mut ::std::os::raw::c_uint, + samplingPeriodUs: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetJpgUtilization( + device: nvmlDevice_t, + utilization: *mut ::std::os::raw::c_uint, + samplingPeriodUs: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetOfaUtilization( + device: nvmlDevice_t, + utilization: *mut ::std::os::raw::c_uint, + samplingPeriodUs: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetFBCStats( + device: nvmlDevice_t, + fbcStats: *mut nvmlFBCStats_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetFBCSessions( + device: nvmlDevice_t, + sessionCount: *mut ::std::os::raw::c_uint, + sessionInfo: *mut nvmlFBCSessionInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDriverModel( + device: nvmlDevice_t, + current: *mut nvmlDriverModel_t, + pending: *mut nvmlDriverModel_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVbiosVersion( + device: nvmlDevice_t, + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBridgeChipInfo( + device: nvmlDevice_t, + bridgeHierarchy: *mut nvmlBridgeChipHierarchy_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetComputeRunningProcesses_v3( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGraphicsRunningProcesses_v3( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMPSComputeRunningProcesses_v3( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceOnSameBoard( + device1: nvmlDevice_t, + device2: nvmlDevice_t, + onSameBoard: *mut ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAPIRestriction( + device: nvmlDevice_t, + apiType: nvmlRestrictedAPI_t, + isRestricted: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSamples( + device: nvmlDevice_t, + type_: nvmlSamplingType_t, + lastSeenTimeStamp: ::std::os::raw::c_ulonglong, + sampleValType: *mut nvmlValueType_t, + sampleCount: *mut ::std::os::raw::c_uint, + samples: *mut nvmlSample_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBAR1MemoryInfo( + device: nvmlDevice_t, + bar1Memory: *mut nvmlBAR1Memory_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetViolationStatus( + device: nvmlDevice_t, + perfPolicyType: nvmlPerfPolicyType_t, + violTime: *mut nvmlViolationTime_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetIrqNum( + device: nvmlDevice_t, + irqNum: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNumGpuCores( + device: nvmlDevice_t, + numCores: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPowerSource( + device: nvmlDevice_t, + powerSource: *mut nvmlPowerSource_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMemoryBusWidth( + device: nvmlDevice_t, + busWidth: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPcieLinkMaxSpeed( + device: nvmlDevice_t, + maxSpeed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPcieSpeed( + device: nvmlDevice_t, + pcieSpeed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAdaptiveClockInfoStatus( + device: nvmlDevice_t, + adaptiveClockStatus: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetBusType( + device: nvmlDevice_t, + type_: *mut nvmlBusType_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuFabricInfo( + device: nvmlDevice_t, + gpuFabricInfo: *mut nvmlGpuFabricInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetConfComputeCapabilities( + capabilities: *mut nvmlConfComputeSystemCaps_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetConfComputeState( + state: *mut nvmlConfComputeSystemState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetConfComputeMemSizeInfo( + device: nvmlDevice_t, + memInfo: *mut nvmlConfComputeMemSizeInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetConfComputeGpusReadyState( + isAcceptingWork: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetConfComputeProtectedMemoryUsage( + device: nvmlDevice_t, + memory: *mut nvmlMemory_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetConfComputeGpuCertificate( + device: nvmlDevice_t, + gpuCert: *mut nvmlConfComputeGpuCertificate_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetConfComputeGpuAttestationReport( + device: nvmlDevice_t, + gpuAtstReport: *mut nvmlConfComputeGpuAttestationReport_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAccountingMode( + device: nvmlDevice_t, + mode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAccountingStats( + device: nvmlDevice_t, + pid: ::std::os::raw::c_uint, + stats: *mut nvmlAccountingStats_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAccountingPids( + device: nvmlDevice_t, + count: *mut ::std::os::raw::c_uint, + pids: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAccountingBufferSize( + device: nvmlDevice_t, + bufferSize: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetRetiredPages( + device: nvmlDevice_t, + cause: nvmlPageRetirementCause_t, + pageCount: *mut ::std::os::raw::c_uint, + addresses: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetRetiredPages_v2( + device: nvmlDevice_t, + cause: nvmlPageRetirementCause_t, + pageCount: *mut ::std::os::raw::c_uint, + addresses: *mut ::std::os::raw::c_ulonglong, + timestamps: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetRetiredPagesPendingStatus( + device: nvmlDevice_t, + isPending: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetRemappedRows( + device: nvmlDevice_t, + corrRows: *mut ::std::os::raw::c_uint, + uncRows: *mut ::std::os::raw::c_uint, + isPending: *mut ::std::os::raw::c_uint, + failureOccurred: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetRowRemapperHistogram( + device: nvmlDevice_t, + values: *mut nvmlRowRemapperHistogramValues_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetArchitecture( + device: nvmlDevice_t, + arch: *mut nvmlDeviceArchitecture_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlUnitSetLedState(unit: nvmlUnit_t, color: nvmlLedColor_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetPersistenceMode( + device: nvmlDevice_t, + mode: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetComputeMode( + device: nvmlDevice_t, + mode: nvmlComputeMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetEccMode( + device: nvmlDevice_t, + ecc: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceClearEccErrorCounts( + device: nvmlDevice_t, + counterType: nvmlEccCounterType_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetDriverModel( + device: nvmlDevice_t, + driverModel: nvmlDriverModel_t, + flags: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetGpuLockedClocks( + device: nvmlDevice_t, + minGpuClockMHz: ::std::os::raw::c_uint, + maxGpuClockMHz: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceResetGpuLockedClocks(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetMemoryLockedClocks( + device: nvmlDevice_t, + minMemClockMHz: ::std::os::raw::c_uint, + maxMemClockMHz: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceResetMemoryLockedClocks(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetApplicationsClocks( + device: nvmlDevice_t, + memClockMHz: ::std::os::raw::c_uint, + graphicsClockMHz: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetClkMonStatus( + device: nvmlDevice_t, + status: *mut nvmlClkMonStatus_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetPowerManagementLimit( + device: nvmlDevice_t, + limit: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetGpuOperationMode( + device: nvmlDevice_t, + mode: nvmlGpuOperationMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetAPIRestriction( + device: nvmlDevice_t, + apiType: nvmlRestrictedAPI_t, + isRestricted: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetFanSpeed_v2( + device: nvmlDevice_t, + fan: ::std::os::raw::c_uint, + speed: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetGpcClkVfOffset( + device: nvmlDevice_t, + offset: ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetMemClkVfOffset( + device: nvmlDevice_t, + offset: ::std::os::raw::c_int, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetConfComputeUnprotectedMemSize( + device: nvmlDevice_t, + sizeKiB: ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemSetConfComputeGpusReadyState( + isAcceptingWork: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetAccountingMode( + device: nvmlDevice_t, + mode: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceClearAccountingPids(device: nvmlDevice_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkState( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + isActive: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + unsafe { crate::common::device_get_nvlink_state(device, link, isActive) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkVersion( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + version: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkCapability( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + capability: nvmlNvLinkCapability_t, + capResult: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkRemotePciInfo_v2( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + pci: *mut nvmlPciInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkErrorCounter( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: nvmlNvLinkErrorCounter_t, + counterValue: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceResetNvLinkErrorCounters( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetNvLinkUtilizationControl( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: ::std::os::raw::c_uint, + control: *mut nvmlNvLinkUtilizationControl_t, + reset: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkUtilizationControl( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: ::std::os::raw::c_uint, + control: *mut nvmlNvLinkUtilizationControl_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkUtilizationCounter( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: ::std::os::raw::c_uint, + rxcounter: *mut ::std::os::raw::c_ulonglong, + txcounter: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceFreezeNvLinkUtilizationCounter( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: ::std::os::raw::c_uint, + freeze: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceResetNvLinkUtilizationCounter( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + counter: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkRemoteDeviceType( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + pNvLinkDeviceType: *mut nvmlIntNvLinkDeviceType_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlEventSetCreate(set: *mut nvmlEventSet_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceRegisterEvents( + device: nvmlDevice_t, + eventTypes: ::std::os::raw::c_ulonglong, + set: nvmlEventSet_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedEventTypes( + device: nvmlDevice_t, + eventTypes: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlEventSetWait_v2( + set: nvmlEventSet_t, + data: *mut nvmlEventData_t, + timeoutms: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlEventSetFree(set: nvmlEventSet_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceModifyDrainState( + pciInfo: *mut nvmlPciInfo_t, + newState: nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceQueryDrainState( + pciInfo: *mut nvmlPciInfo_t, + currentState: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceRemoveGpu_v2( + pciInfo: *mut nvmlPciInfo_t, + gpuState: nvmlDetachGpuState_t, + linkState: nvmlPcieLinkState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceDiscoverGpus(pciInfo: *mut nvmlPciInfo_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub unsafe extern "C" fn nvmlDeviceGetFieldValues( + device: nvmlDevice_t, + valuesCount: ::std::os::raw::c_int, + values: *mut nvmlFieldValue_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_field_values(device, valuesCount, values) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceClearFieldValues( + device: nvmlDevice_t, + valuesCount: ::std::os::raw::c_int, + values: *mut nvmlFieldValue_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVirtualizationMode( + device: nvmlDevice_t, + pVirtualMode: *mut nvmlGpuVirtualizationMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHostVgpuMode( + device: nvmlDevice_t, + pHostVgpuMode: *mut nvmlHostVgpuMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetVirtualizationMode( + device: nvmlDevice_t, + virtualMode: nvmlGpuVirtualizationMode_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGridLicensableFeatures_v4( + device: nvmlDevice_t, + pGridLicensableFeatures: *mut nvmlGridLicensableFeatures_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetProcessUtilization( + device: nvmlDevice_t, + utilization: *mut nvmlProcessUtilizationSample_t, + processSamplesCount: *mut ::std::os::raw::c_uint, + lastSeenTimeStamp: ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGspFirmwareVersion( + device: nvmlDevice_t, + version: *mut ::std::os::raw::c_char, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGspFirmwareMode( + device: nvmlDevice_t, + isEnabled: *mut ::std::os::raw::c_uint, + defaultMode: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGetVgpuDriverCapabilities( + capability: nvmlVgpuDriverCapability_t, + capResult: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuCapabilities( + device: nvmlDevice_t, + capability: nvmlDeviceVgpuCapability_t, + capResult: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetSupportedVgpus( + device: nvmlDevice_t, + vgpuCount: *mut ::std::os::raw::c_uint, + vgpuTypeIds: *mut nvmlVgpuTypeId_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCreatableVgpus( + device: nvmlDevice_t, + vgpuCount: *mut ::std::os::raw::c_uint, + vgpuTypeIds: *mut nvmlVgpuTypeId_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetClass( + vgpuTypeId: nvmlVgpuTypeId_t, + vgpuTypeClass: *mut ::std::os::raw::c_char, + size: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetName( + vgpuTypeId: nvmlVgpuTypeId_t, + vgpuTypeName: *mut ::std::os::raw::c_char, + size: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetGpuInstanceProfileId( + vgpuTypeId: nvmlVgpuTypeId_t, + gpuInstanceProfileId: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetDeviceID( + vgpuTypeId: nvmlVgpuTypeId_t, + deviceID: *mut ::std::os::raw::c_ulonglong, + subsystemID: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetFramebufferSize( + vgpuTypeId: nvmlVgpuTypeId_t, + fbSize: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetNumDisplayHeads( + vgpuTypeId: nvmlVgpuTypeId_t, + numDisplayHeads: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetResolution( + vgpuTypeId: nvmlVgpuTypeId_t, + displayIndex: ::std::os::raw::c_uint, + xdim: *mut ::std::os::raw::c_uint, + ydim: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetLicense( + vgpuTypeId: nvmlVgpuTypeId_t, + vgpuTypeLicenseString: *mut ::std::os::raw::c_char, + size: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetFrameRateLimit( + vgpuTypeId: nvmlVgpuTypeId_t, + frameRateLimit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetMaxInstances( + device: nvmlDevice_t, + vgpuTypeId: nvmlVgpuTypeId_t, + vgpuInstanceCount: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetMaxInstancesPerVm( + vgpuTypeId: nvmlVgpuTypeId_t, + vgpuInstanceCountPerVm: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetActiveVgpus( + device: nvmlDevice_t, + vgpuCount: *mut ::std::os::raw::c_uint, + vgpuInstances: *mut nvmlVgpuInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetVmID( + vgpuInstance: nvmlVgpuInstance_t, + vmId: *mut ::std::os::raw::c_char, + size: ::std::os::raw::c_uint, + vmIdType: *mut nvmlVgpuVmIdType_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetUUID( + vgpuInstance: nvmlVgpuInstance_t, + uuid: *mut ::std::os::raw::c_char, + size: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetVmDriverVersion( + vgpuInstance: nvmlVgpuInstance_t, + version: *mut ::std::os::raw::c_char, + length: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetFbUsage( + vgpuInstance: nvmlVgpuInstance_t, + fbUsage: *mut ::std::os::raw::c_ulonglong, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetLicenseStatus( + vgpuInstance: nvmlVgpuInstance_t, + licensed: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetType( + vgpuInstance: nvmlVgpuInstance_t, + vgpuTypeId: *mut nvmlVgpuTypeId_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetFrameRateLimit( + vgpuInstance: nvmlVgpuInstance_t, + frameRateLimit: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetEccMode( + vgpuInstance: nvmlVgpuInstance_t, + eccMode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetEncoderCapacity( + vgpuInstance: nvmlVgpuInstance_t, + encoderCapacity: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceSetEncoderCapacity( + vgpuInstance: nvmlVgpuInstance_t, + encoderCapacity: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetEncoderStats( + vgpuInstance: nvmlVgpuInstance_t, + sessionCount: *mut ::std::os::raw::c_uint, + averageFps: *mut ::std::os::raw::c_uint, + averageLatency: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetEncoderSessions( + vgpuInstance: nvmlVgpuInstance_t, + sessionCount: *mut ::std::os::raw::c_uint, + sessionInfo: *mut nvmlEncoderSessionInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetFBCStats( + vgpuInstance: nvmlVgpuInstance_t, + fbcStats: *mut nvmlFBCStats_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetFBCSessions( + vgpuInstance: nvmlVgpuInstance_t, + sessionCount: *mut ::std::os::raw::c_uint, + sessionInfo: *mut nvmlFBCSessionInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetGpuInstanceId( + vgpuInstance: nvmlVgpuInstance_t, + gpuInstanceId: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetGpuPciId( + vgpuInstance: nvmlVgpuInstance_t, + vgpuPciId: *mut ::std::os::raw::c_char, + length: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuTypeGetCapabilities( + vgpuTypeId: nvmlVgpuTypeId_t, + capability: nvmlVgpuCapability_t, + capResult: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuVersion_st { + pub minVersion: ::std::os::raw::c_uint, + pub maxVersion: ::std::os::raw::c_uint, +} +pub type nvmlVgpuVersion_t = nvmlVgpuVersion_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuMetadata_st { + pub version: ::std::os::raw::c_uint, + pub revision: ::std::os::raw::c_uint, + pub guestInfoState: nvmlVgpuGuestInfoState_t, + pub guestDriverVersion: [::std::os::raw::c_char; 80usize], + pub hostDriverVersion: [::std::os::raw::c_char; 80usize], + pub reserved: [::std::os::raw::c_uint; 6usize], + pub vgpuVirtualizationCaps: ::std::os::raw::c_uint, + pub guestVgpuVersion: ::std::os::raw::c_uint, + pub opaqueDataSize: ::std::os::raw::c_uint, + pub opaqueData: [::std::os::raw::c_char; 4usize], +} +pub type nvmlVgpuMetadata_t = nvmlVgpuMetadata_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuPgpuMetadata_st { + pub version: ::std::os::raw::c_uint, + pub revision: ::std::os::raw::c_uint, + pub hostDriverVersion: [::std::os::raw::c_char; 80usize], + pub pgpuVirtualizationCaps: ::std::os::raw::c_uint, + pub reserved: [::std::os::raw::c_uint; 5usize], + pub hostSupportedVgpuRange: nvmlVgpuVersion_t, + pub opaqueDataSize: ::std::os::raw::c_uint, + pub opaqueData: [::std::os::raw::c_char; 4usize], +} +pub type nvmlVgpuPgpuMetadata_t = nvmlVgpuPgpuMetadata_st; +impl nvmlVgpuVmCompatibility_enum { + pub const NVML_VGPU_VM_COMPATIBILITY_NONE: nvmlVgpuVmCompatibility_enum = + nvmlVgpuVmCompatibility_enum(0); +} +impl nvmlVgpuVmCompatibility_enum { + pub const NVML_VGPU_VM_COMPATIBILITY_COLD: nvmlVgpuVmCompatibility_enum = + nvmlVgpuVmCompatibility_enum(1); +} +impl nvmlVgpuVmCompatibility_enum { + pub const NVML_VGPU_VM_COMPATIBILITY_HIBERNATE: nvmlVgpuVmCompatibility_enum = + nvmlVgpuVmCompatibility_enum(2); +} +impl nvmlVgpuVmCompatibility_enum { + pub const NVML_VGPU_VM_COMPATIBILITY_SLEEP: nvmlVgpuVmCompatibility_enum = + nvmlVgpuVmCompatibility_enum(4); +} +impl nvmlVgpuVmCompatibility_enum { + pub const NVML_VGPU_VM_COMPATIBILITY_LIVE: nvmlVgpuVmCompatibility_enum = + nvmlVgpuVmCompatibility_enum(8); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuVmCompatibility_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuVmCompatibility_enum as nvmlVgpuVmCompatibility_t; +impl nvmlVgpuPgpuCompatibilityLimitCode_enum { + pub const NVML_VGPU_COMPATIBILITY_LIMIT_NONE: nvmlVgpuPgpuCompatibilityLimitCode_enum = + nvmlVgpuPgpuCompatibilityLimitCode_enum(0); +} +impl nvmlVgpuPgpuCompatibilityLimitCode_enum { + pub const NVML_VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER: nvmlVgpuPgpuCompatibilityLimitCode_enum = + nvmlVgpuPgpuCompatibilityLimitCode_enum(1); +} +impl nvmlVgpuPgpuCompatibilityLimitCode_enum { + pub const NVML_VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER: nvmlVgpuPgpuCompatibilityLimitCode_enum = + nvmlVgpuPgpuCompatibilityLimitCode_enum(2); +} +impl nvmlVgpuPgpuCompatibilityLimitCode_enum { + pub const NVML_VGPU_COMPATIBILITY_LIMIT_GPU: nvmlVgpuPgpuCompatibilityLimitCode_enum = + nvmlVgpuPgpuCompatibilityLimitCode_enum(4); +} +impl nvmlVgpuPgpuCompatibilityLimitCode_enum { + pub const NVML_VGPU_COMPATIBILITY_LIMIT_OTHER: nvmlVgpuPgpuCompatibilityLimitCode_enum = + nvmlVgpuPgpuCompatibilityLimitCode_enum(2147483648); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct nvmlVgpuPgpuCompatibilityLimitCode_enum(pub ::std::os::raw::c_uint); +pub use self::nvmlVgpuPgpuCompatibilityLimitCode_enum as nvmlVgpuPgpuCompatibilityLimitCode_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlVgpuPgpuCompatibility_st { + pub vgpuVmCompatibility: nvmlVgpuVmCompatibility_t, + pub compatibilityLimitCode: nvmlVgpuPgpuCompatibilityLimitCode_t, +} +pub type nvmlVgpuPgpuCompatibility_t = nvmlVgpuPgpuCompatibility_st; + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetMetadata( + vgpuInstance: nvmlVgpuInstance_t, + vgpuMetadata: *mut nvmlVgpuMetadata_t, + bufferSize: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuMetadata( + device: nvmlDevice_t, + pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t, + bufferSize: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGetVgpuCompatibility( + vgpuMetadata: *mut nvmlVgpuMetadata_t, + pgpuMetadata: *mut nvmlVgpuPgpuMetadata_t, + compatibilityInfo: *mut nvmlVgpuPgpuCompatibility_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPgpuMetadataString( + device: nvmlDevice_t, + pgpuMetadata: *mut ::std::os::raw::c_char, + bufferSize: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuSchedulerLog( + device: nvmlDevice_t, + pSchedulerLog: *mut nvmlVgpuSchedulerLog_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuSchedulerState( + device: nvmlDevice_t, + pSchedulerState: *mut nvmlVgpuSchedulerGetState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuSchedulerCapabilities( + device: nvmlDevice_t, + pCapabilities: *mut nvmlVgpuSchedulerCapabilities_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetVgpuSchedulerState( + device: nvmlDevice_t, + pSchedulerState: *mut nvmlVgpuSchedulerSetState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGetVgpuVersion( + supported: *mut nvmlVgpuVersion_t, + current: *mut nvmlVgpuVersion_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSetVgpuVersion(vgpuVersion: *mut nvmlVgpuVersion_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuUtilization( + device: nvmlDevice_t, + lastSeenTimeStamp: ::std::os::raw::c_ulonglong, + sampleValType: *mut nvmlValueType_t, + vgpuInstanceSamplesCount: *mut ::std::os::raw::c_uint, + utilizationSamples: *mut nvmlVgpuInstanceUtilizationSample_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetVgpuProcessUtilization( + device: nvmlDevice_t, + lastSeenTimeStamp: ::std::os::raw::c_ulonglong, + vgpuProcessSamplesCount: *mut ::std::os::raw::c_uint, + utilizationSamples: *mut nvmlVgpuProcessUtilizationSample_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetAccountingMode( + vgpuInstance: nvmlVgpuInstance_t, + mode: *mut nvmlEnableState_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetAccountingPids( + vgpuInstance: nvmlVgpuInstance_t, + count: *mut ::std::os::raw::c_uint, + pids: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetAccountingStats( + vgpuInstance: nvmlVgpuInstance_t, + pid: ::std::os::raw::c_uint, + stats: *mut nvmlAccountingStats_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceClearAccountingPids( + vgpuInstance: nvmlVgpuInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetLicenseInfo_v2( + vgpuInstance: nvmlVgpuInstance_t, + licenseInfo: *mut nvmlVgpuLicenseInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlExcludedDeviceInfo_st { + pub pciInfo: nvmlPciInfo_t, + pub uuid: [::std::os::raw::c_char; 80usize], +} +pub type nvmlExcludedDeviceInfo_t = nvmlExcludedDeviceInfo_st; + +#[no_mangle] +pub extern "C" fn nvmlGetExcludedDeviceCount( + deviceCount: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGetExcludedDeviceInfoByIndex( + index: ::std::os::raw::c_uint, + info: *mut nvmlExcludedDeviceInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuInstancePlacement_st { + pub start: ::std::os::raw::c_uint, + pub size: ::std::os::raw::c_uint, +} +pub type nvmlGpuInstancePlacement_t = nvmlGpuInstancePlacement_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuInstanceProfileInfo_st { + pub id: ::std::os::raw::c_uint, + pub isP2pSupported: ::std::os::raw::c_uint, + pub sliceCount: ::std::os::raw::c_uint, + pub instanceCount: ::std::os::raw::c_uint, + pub multiprocessorCount: ::std::os::raw::c_uint, + pub copyEngineCount: ::std::os::raw::c_uint, + pub decoderCount: ::std::os::raw::c_uint, + pub encoderCount: ::std::os::raw::c_uint, + pub jpegCount: ::std::os::raw::c_uint, + pub ofaCount: ::std::os::raw::c_uint, + pub memorySizeMB: ::std::os::raw::c_ulonglong, +} +pub type nvmlGpuInstanceProfileInfo_t = nvmlGpuInstanceProfileInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuInstanceProfileInfo_v2_st { + pub version: ::std::os::raw::c_uint, + pub id: ::std::os::raw::c_uint, + pub isP2pSupported: ::std::os::raw::c_uint, + pub sliceCount: ::std::os::raw::c_uint, + pub instanceCount: ::std::os::raw::c_uint, + pub multiprocessorCount: ::std::os::raw::c_uint, + pub copyEngineCount: ::std::os::raw::c_uint, + pub decoderCount: ::std::os::raw::c_uint, + pub encoderCount: ::std::os::raw::c_uint, + pub jpegCount: ::std::os::raw::c_uint, + pub ofaCount: ::std::os::raw::c_uint, + pub memorySizeMB: ::std::os::raw::c_ulonglong, + pub name: [::std::os::raw::c_char; 96usize], +} +pub type nvmlGpuInstanceProfileInfo_v2_t = nvmlGpuInstanceProfileInfo_v2_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuInstanceInfo_st { + pub device: nvmlDevice_t, + pub id: ::std::os::raw::c_uint, + pub profileId: ::std::os::raw::c_uint, + pub placement: nvmlGpuInstancePlacement_t, +} +pub type nvmlGpuInstanceInfo_t = nvmlGpuInstanceInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpuInstance_st { + _unused: [u8; 0], +} +pub type nvmlGpuInstance_t = *mut nvmlGpuInstance_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlComputeInstancePlacement_st { + pub start: ::std::os::raw::c_uint, + pub size: ::std::os::raw::c_uint, +} +pub type nvmlComputeInstancePlacement_t = nvmlComputeInstancePlacement_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlComputeInstanceProfileInfo_st { + pub id: ::std::os::raw::c_uint, + pub sliceCount: ::std::os::raw::c_uint, + pub instanceCount: ::std::os::raw::c_uint, + pub multiprocessorCount: ::std::os::raw::c_uint, + pub sharedCopyEngineCount: ::std::os::raw::c_uint, + pub sharedDecoderCount: ::std::os::raw::c_uint, + pub sharedEncoderCount: ::std::os::raw::c_uint, + pub sharedJpegCount: ::std::os::raw::c_uint, + pub sharedOfaCount: ::std::os::raw::c_uint, +} +pub type nvmlComputeInstanceProfileInfo_t = nvmlComputeInstanceProfileInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlComputeInstanceProfileInfo_v2_st { + pub version: ::std::os::raw::c_uint, + pub id: ::std::os::raw::c_uint, + pub sliceCount: ::std::os::raw::c_uint, + pub instanceCount: ::std::os::raw::c_uint, + pub multiprocessorCount: ::std::os::raw::c_uint, + pub sharedCopyEngineCount: ::std::os::raw::c_uint, + pub sharedDecoderCount: ::std::os::raw::c_uint, + pub sharedEncoderCount: ::std::os::raw::c_uint, + pub sharedJpegCount: ::std::os::raw::c_uint, + pub sharedOfaCount: ::std::os::raw::c_uint, + pub name: [::std::os::raw::c_char; 96usize], +} +pub type nvmlComputeInstanceProfileInfo_v2_t = nvmlComputeInstanceProfileInfo_v2_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlComputeInstanceInfo_st { + pub device: nvmlDevice_t, + pub gpuInstance: nvmlGpuInstance_t, + pub id: ::std::os::raw::c_uint, + pub profileId: ::std::os::raw::c_uint, + pub placement: nvmlComputeInstancePlacement_t, +} +pub type nvmlComputeInstanceInfo_t = nvmlComputeInstanceInfo_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlComputeInstance_st { + _unused: [u8; 0], +} +pub type nvmlComputeInstance_t = *mut nvmlComputeInstance_st; + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetMigMode( + device: nvmlDevice_t, + mode: ::std::os::raw::c_uint, + activationStatus: *mut nvmlReturn_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMigMode( + device: nvmlDevice_t, + currentMode: *mut ::std::os::raw::c_uint, + pendingMode: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstanceProfileInfo( + device: nvmlDevice_t, + profile: ::std::os::raw::c_uint, + info: *mut nvmlGpuInstanceProfileInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstanceProfileInfoV( + device: nvmlDevice_t, + profile: ::std::os::raw::c_uint, + info: *mut nvmlGpuInstanceProfileInfo_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstancePossiblePlacements_v2( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + placements: *mut nvmlGpuInstancePlacement_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstanceRemainingCapacity( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceCreateGpuInstance( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + gpuInstance: *mut nvmlGpuInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceCreateGpuInstanceWithPlacement( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + placement: *const nvmlGpuInstancePlacement_t, + gpuInstance: *mut nvmlGpuInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceDestroy(gpuInstance: nvmlGpuInstance_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstances( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + gpuInstances: *mut nvmlGpuInstance_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstanceById( + device: nvmlDevice_t, + id: ::std::os::raw::c_uint, + gpuInstance: *mut nvmlGpuInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetInfo( + gpuInstance: nvmlGpuInstance_t, + info: *mut nvmlGpuInstanceInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstanceProfileInfo( + gpuInstance: nvmlGpuInstance_t, + profile: ::std::os::raw::c_uint, + engProfile: ::std::os::raw::c_uint, + info: *mut nvmlComputeInstanceProfileInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstanceProfileInfoV( + gpuInstance: nvmlGpuInstance_t, + profile: ::std::os::raw::c_uint, + engProfile: ::std::os::raw::c_uint, + info: *mut nvmlComputeInstanceProfileInfo_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstanceRemainingCapacity( + gpuInstance: nvmlGpuInstance_t, + profileId: ::std::os::raw::c_uint, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstancePossiblePlacements( + gpuInstance: nvmlGpuInstance_t, + profileId: ::std::os::raw::c_uint, + placements: *mut nvmlComputeInstancePlacement_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceCreateComputeInstance( + gpuInstance: nvmlGpuInstance_t, + profileId: ::std::os::raw::c_uint, + computeInstance: *mut nvmlComputeInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceCreateComputeInstanceWithPlacement( + gpuInstance: nvmlGpuInstance_t, + profileId: ::std::os::raw::c_uint, + placement: *const nvmlComputeInstancePlacement_t, + computeInstance: *mut nvmlComputeInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlComputeInstanceDestroy( + computeInstance: nvmlComputeInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstances( + gpuInstance: nvmlGpuInstance_t, + profileId: ::std::os::raw::c_uint, + computeInstances: *mut nvmlComputeInstance_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpuInstanceGetComputeInstanceById( + gpuInstance: nvmlGpuInstance_t, + id: ::std::os::raw::c_uint, + computeInstance: *mut nvmlComputeInstance_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlComputeInstanceGetInfo_v2( + computeInstance: nvmlComputeInstance_t, + info: *mut nvmlComputeInstanceInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceIsMigDeviceHandle( + device: nvmlDevice_t, + isMigDevice: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstanceId( + device: nvmlDevice_t, + id: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetComputeInstanceId( + device: nvmlDevice_t, + id: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMaxMigDeviceCount( + device: nvmlDevice_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMigDeviceHandleByIndex( + device: nvmlDevice_t, + index: ::std::os::raw::c_uint, + migDevice: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetDeviceHandleFromMigDeviceHandle( + migDevice: nvmlDevice_t, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpmSample_st { + _unused: [u8; 0], +} +pub type nvmlGpmSample_t = *mut nvmlGpmSample_st; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpmMetric_t { + pub metricId: ::std::os::raw::c_uint, + pub nvmlReturn: nvmlReturn_t, + pub value: f64, + pub metricInfo: nvmlGpmMetric_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpmMetric_t__bindgen_ty_1 { + pub shortName: *mut ::std::os::raw::c_char, + pub longName: *mut ::std::os::raw::c_char, + pub unit: *mut ::std::os::raw::c_char, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpmMetricsGet_t { + pub version: ::std::os::raw::c_uint, + pub numMetrics: ::std::os::raw::c_uint, + pub sample1: nvmlGpmSample_t, + pub sample2: nvmlGpmSample_t, + pub metrics: [nvmlGpmMetric_t; 98usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlGpmSupport_t { + pub version: ::std::os::raw::c_uint, + pub isSupportedDevice: ::std::os::raw::c_uint, +} + +#[no_mangle] +pub extern "C" fn nvmlGpmMetricsGet(metricsGet: *mut nvmlGpmMetricsGet_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmSampleFree(gpmSample: nvmlGpmSample_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmSampleAlloc(gpmSample: *mut nvmlGpmSample_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmSampleGet( + device: nvmlDevice_t, + gpmSample: nvmlGpmSample_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmMigSampleGet( + device: nvmlDevice_t, + gpuInstanceId: ::std::os::raw::c_uint, + gpmSample: nvmlGpmSample_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmQueryDeviceSupport( + device: nvmlDevice_t, + gpmSupport: *mut nvmlGpmSupport_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmQueryIfStreamingEnabled( + device: nvmlDevice_t, + state: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlGpmSetStreamingEnabled( + device: nvmlDevice_t, + state: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct nvmlNvLinkPowerThres_st { + pub lowPwrThreshold: ::std::os::raw::c_uint, +} +pub type nvmlNvLinkPowerThres_t = nvmlNvLinkPowerThres_st; + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetNvLinkDeviceLowPowerThreshold( + device: nvmlDevice_t, + info: *mut nvmlNvLinkPowerThres_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemSetNvlinkBwMode(nvlinkBwMode: ::std::os::raw::c_uint) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlSystemGetNvlinkBwMode( + nvlinkBwMode: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceSetPowerManagementLimit_v2( + device: nvmlDevice_t, + powerValue: *mut nvmlPowerValue_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlInit() -> nvmlReturn_t { + unsafe { crate::r#impl::init().into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetCount(deviceCount: *mut ::std::os::raw::c_uint) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_count(deviceCount) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleByIndex( + index: ::std::os::raw::c_uint, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_handle_by_index(index, device) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetHandleByPciBusId( + pciBusId: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_handle_by_pci_bus_id(pciBusId, device) }.into() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPciInfo( + device: nvmlDevice_t, + pci: *mut nvmlPciInfo_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_pci_info(device, pci).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetPciInfo_v2( + device: nvmlDevice_t, + pci: *mut nvmlPciInfo_t, +) -> nvmlReturn_t { + unsafe { crate::r#impl::device_get_pci_info(device, pci).into() } +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetNvLinkRemotePciInfo( + device: nvmlDevice_t, + link: ::std::os::raw::c_uint, + pci: *mut nvmlPciInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGridLicensableFeatures( + device: nvmlDevice_t, + pGridLicensableFeatures: *mut nvmlGridLicensableFeatures_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGridLicensableFeatures_v2( + device: nvmlDevice_t, + pGridLicensableFeatures: *mut nvmlGridLicensableFeatures_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGridLicensableFeatures_v3( + device: nvmlDevice_t, + pGridLicensableFeatures: *mut nvmlGridLicensableFeatures_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceRemoveGpu(pciInfo: *mut nvmlPciInfo_t) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlEventSetWait( + set: nvmlEventSet_t, + data: *mut nvmlEventData_t, + timeoutms: ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetAttributes( + device: nvmlDevice_t, + attributes: *mut nvmlDeviceAttributes_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlComputeInstanceGetInfo( + computeInstance: nvmlComputeInstance_t, + info: *mut nvmlComputeInstanceInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetComputeRunningProcesses( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v1_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetComputeRunningProcesses_v2( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGraphicsRunningProcesses( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v1_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGraphicsRunningProcesses_v2( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMPSComputeRunningProcesses( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v1_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetMPSComputeRunningProcesses_v2( + device: nvmlDevice_t, + infoCount: *mut ::std::os::raw::c_uint, + infos: *mut nvmlProcessInfo_v2_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlDeviceGetGpuInstancePossiblePlacements( + device: nvmlDevice_t, + profileId: ::std::os::raw::c_uint, + placements: *mut nvmlGpuInstancePlacement_t, + count: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +#[no_mangle] +pub extern "C" fn nvmlVgpuInstanceGetLicenseInfo( + vgpuInstance: nvmlVgpuInstance_t, + licenseInfo: *mut nvmlVgpuLicenseInfo_t, +) -> nvmlReturn_t { + crate::common::unimplemented() +} diff --git a/zluda_ml/src/unix.rs b/zluda_ml/src/unix.rs new file mode 100644 index 0000000..908394e --- /dev/null +++ b/zluda_ml/src/unix.rs @@ -0,0 +1,246 @@ +use crate::{common, nvml::*}; +use rocm_smi_sys::*; +use std::{ + ptr, + time::{Instant, SystemTime, UNIX_EPOCH}, +}; + +macro_rules! smi_call { + ($x:expr) => {{ + let result = $x; + if result != rsmi_status_t::RSMI_STATUS_SUCCESS { + return Err(result.into()); + } + }}; +} + +impl From for nvmlReturn_t { + fn from(error: rsmi_status_t) -> Self { + match error { + rsmi_status_t::RSMI_STATUS_SUCCESS => nvmlReturn_t::NVML_SUCCESS, + rsmi_status_t::RSMI_STATUS_INVALID_ARGS => nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT, + rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED => nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED, + rsmi_status_t::RSMI_STATUS_FILE_ERROR => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_PERMISSION => nvmlReturn_t::NVML_ERROR_NO_PERMISSION, + rsmi_status_t::RSMI_STATUS_OUT_OF_RESOURCES => { + nvmlReturn_t::NVML_ERROR_INSUFFICIENT_RESOURCES + } + rsmi_status_t::RSMI_STATUS_INTERNAL_EXCEPTION => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_INPUT_OUT_OF_BOUNDS => { + nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT + } + rsmi_status_t::RSMI_STATUS_INIT_ERROR => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_NOT_YET_IMPLEMENTED => { + nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED + } + rsmi_status_t::RSMI_STATUS_NOT_FOUND => nvmlReturn_t::NVML_ERROR_NOT_FOUND, + rsmi_status_t::RSMI_STATUS_INSUFFICIENT_SIZE => { + nvmlReturn_t::NVML_ERROR_INSUFFICIENT_SIZE + } + rsmi_status_t::RSMI_STATUS_INTERRUPT => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_UNEXPECTED_SIZE => nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT, + rsmi_status_t::RSMI_STATUS_NO_DATA => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_UNEXPECTED_DATA => nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT, + rsmi_status_t::RSMI_STATUS_BUSY => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_REFCOUNT_OVERFLOW => nvmlReturn_t::NVML_ERROR_UNKNOWN, + rsmi_status_t::RSMI_STATUS_UNKNOWN_ERROR => nvmlReturn_t::NVML_ERROR_UNKNOWN, + _ => nvmlReturn_t::NVML_ERROR_UNKNOWN, + } + } +} + +pub(crate) unsafe fn init() -> rsmi_status_t { + rsmi_init(0) +} + +pub(crate) unsafe fn init_with_flags(_flags: ::std::os::raw::c_uint) -> rsmi_status_t { + init() +} + +pub(crate) unsafe fn shutdown() -> nvmlReturn_t { + rsmi_shut_down().into() +} + +pub(crate) unsafe fn device_get_handle_by_index( + index: ::std::os::raw::c_uint, + device: *mut nvmlDevice_t, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let mut num_devices = 0; + smi_call! {rsmi_num_monitor_devices(&mut num_devices)}; + if index >= num_devices { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + *device = (index + 1) as nvmlDevice_t; + Ok(()) +} + +pub(crate) unsafe fn device_get_handle_by_pci_bus_id( + pci_bus_id: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> Result<(), nvmlReturn_t> { + if pci_bus_id == ptr::null_mut() || device == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let device = device as *mut u32; + let mut devices = 0; + smi_call! {rsmi_num_monitor_devices(&mut devices)}; + let (pci_bus, pci_device, pci_function) = common::parse_pci_address(pci_bus_id)?; + for dev in 0..devices { + let mut packed_bdfid = 0; + smi_call! { rsmi_dev_pci_id_get(dev, &mut packed_bdfid) }; + let dev_function = (packed_bdfid & 0x7) as i32; + let dev_device = ((packed_bdfid >> 3) & 0x1f) as i32; + let dev_bus = ((packed_bdfid >> 8) & 0xff) as i32; + if dev_function == pci_function && dev_device == pci_device && dev_bus == pci_bus { + *device = dev + 1; + return Ok(()); + } + } + Err(nvmlReturn_t::NVML_ERROR_NOT_FOUND) +} + +pub(crate) unsafe fn device_get_fan_speed( + _device: nvmlDevice_t, + _speed: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(crate::common::unimplemented()) +} + +pub(crate) unsafe fn device_get_memory_info( + device: nvmlDevice_t, + memory: *mut nvmlMemory_t, +) -> Result<(), nvmlReturn_t> { + if memory == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let device = device as u32 - 1; + let mut total = 0; + smi_call! { rsmi_dev_memory_total_get(device, rsmi_memory_type_t::RSMI_MEM_TYPE_VRAM, &mut total) }; + let mut used = 0; + smi_call! { rsmi_dev_memory_usage_get(device, rsmi_memory_type_t::RSMI_MEM_TYPE_VRAM, &mut used) }; + *memory = nvmlMemory_t { + total, + used, + free: total - used, + }; + Ok(()) +} + +pub(crate) unsafe fn device_get_pci_info( + _device: nvmlDevice_t, + _pci: *mut nvmlPciInfo_t, +) -> Result<(), nvmlReturn_t> { + Err(crate::common::unimplemented()) +} + +pub(crate) unsafe fn device_get_temperature( + _device: nvmlDevice_t, + _sensor_type: nvmlTemperatureSensors_t, + _temp: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +pub(crate) unsafe fn device_get_utilization_rates( + _device: nvmlDevice_t, + _utilization: *mut nvmlUtilization_t, +) -> Result<(), nvmlReturn_t> { + Err(crate::common::unimplemented()) +} + +pub(crate) unsafe fn device_get_field_values( + device: *mut nvmlDevice_st, + values_count: i32, + values: *mut nvmlFieldValue_st, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || values == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let device = ((device as usize) - 1) as u32; + for value in 0..values_count as usize { + get_field_value(device, values.add(value))?; + } + Ok(()) +} + +unsafe fn get_field_value(device: u32, values: *mut nvmlFieldValue_st) -> Result<(), nvmlReturn_t> { + let values = &mut *values; + if values.fieldId != NVML_FI_DEV_NVLINK_LINK_COUNT { + return Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED); + } + let start = Instant::now(); + let xgmi_links = total_xgmi_links(device)?; + let end = Instant::now(); + let latency = end.duration_since(start).as_micros(); + let timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_micros(); + values.latencyUsec = latency as i64; + // TODO: what is expected here? + values.scopeId = 0; + values.value.uiVal = xgmi_links; + values.timestamp = timestamp as i64; + values.valueType = nvmlValueType_t::NVML_VALUE_TYPE_UNSIGNED_INT; + values.nvmlReturn = nvmlReturn_t::NVML_SUCCESS; + Ok(()) +} + +unsafe fn total_xgmi_links(device: u32) -> Result { + let mut xgmi_links = 0; + let mut total_devices = 0; + smi_call! {rsmi_num_monitor_devices(&mut total_devices)}; + for target_dev in 0..total_devices { + if target_dev == device { + continue; + } + let mut hops = 0; + let mut link_type = RSMI_IO_LINK_TYPE::RSMI_IOLINK_TYPE_UNDEFINED; + smi_call! {rsmi_topo_get_link_type(device, target_dev, &mut hops, &mut link_type)}; + if link_type == RSMI_IO_LINK_TYPE::RSMI_IOLINK_TYPE_XGMI { + xgmi_links += 1; + } + } + Ok(xgmi_links) +} + +pub(crate) unsafe fn device_get_count(device_count: *mut u32) -> Result<(), nvmlReturn_t> { + if device_count == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + smi_call! {rsmi_num_monitor_devices(device_count)}; + Ok(()) +} + +pub(crate) unsafe fn device_get_power_management_limit( + _device: nvmlDevice_t, + _limit: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED) +} + +pub(crate) unsafe fn device_get_power_management_limit_constraints( + _device: *mut nvmlDevice_st, + _min_limit: *mut u32, + _max_limit: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED) +} + +pub(crate) unsafe fn device_get_power_usage( + _device: *mut nvmlDevice_st, + _power: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED) +} + +pub(crate) unsafe fn device_get_pcie_throughput( + _device: *mut nvmlDevice_st, + _counter: nvmlPcieUtilCounter_enum, + _value: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED) +} diff --git a/zluda_ml/src/windows.rs b/zluda_ml/src/windows.rs new file mode 100644 index 0000000..e6886bc --- /dev/null +++ b/zluda_ml/src/windows.rs @@ -0,0 +1,446 @@ +use crate::{common, nvml::*}; +use atiadlxx_sys::*; +use std::borrow::Cow; +use std::ffi::CStr; +use std::io::Write; +use std::{ + alloc::Layout, + collections::{btree_map, BTreeMap}, + ffi::c_void, + mem, ptr, + sync::atomic::{self, AtomicPtr, Ordering}, +}; + +const MIB: u64 = 1_048_576; +const AMD_PCI_ID_DECIMAL: i32 = 1002i32; +const AMD_PCI_ID_HEX: u32 = 0x1002u32; +/* + Undocumented, but internet suggests that ADLODNTemperatureType is defined as + enum class ADLODNTemperatureType + { + Core = 1, + Memory = 2, + VrmCore = 3, + VrmMemory = 4, + Liquid = 5, + Plx = 6, + Hotspot = 7, + }; +*/ +const ADLODNTEMPERATURE_TYPE_CORE: i32 = 1; + +static mut ADL_CONTEXT: AtomicPtr = AtomicPtr::new(ptr::null_mut()); +static mut DEVICES: Vec = Vec::new(); + +struct Device { + adapter_info: atiadlxx_sys::AdapterInfoX2, +} + +macro_rules! adl_call { + ($x:expr) => {{ + let result = $x; + if result as u32 != atiadlxx_sys::ADL_OK { + return Err(result.into()); + } + }}; +} + +impl From for nvmlReturn_t { + fn from(error: i32) -> Self { + if error as u32 == atiadlxx_sys::ADL_OK { + return nvmlReturn_t::NVML_SUCCESS; + } + match error { + atiadlxx_sys::ADL_ERR_NOT_INIT => nvmlReturn_t::NVML_ERROR_UNINITIALIZED, + atiadlxx_sys::ADL_ERR_NOT_SUPPORTED => nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED, + _ => nvmlReturn_t::NVML_ERROR_UNKNOWN, + } + } +} + +pub(crate) unsafe fn shutdown() -> nvmlReturn_t { + let context = ADL_CONTEXT.load(Ordering::Relaxed); + if context == ptr::null_mut() { + return nvmlReturn_t::NVML_ERROR_UNINITIALIZED; + } + match ADL_CONTEXT.compare_exchange( + context, + ptr::null_mut(), + std::sync::atomic::Ordering::SeqCst, + std::sync::atomic::Ordering::SeqCst, + ) { + // TODO: should we call free after destroy? + Ok(_) => nvmlReturn_t::from(atiadlxx_sys::ADL2_Main_Control_Destroy(context)), + Err(ptr) if ptr == ptr::null_mut() => nvmlReturn_t::NVML_SUCCESS, + Err(_) => nvmlReturn_t::NVML_ERROR_UNKNOWN, + } +} + +pub(crate) unsafe fn init() -> Result<(), nvmlReturn_t> { + let mut context = ptr::null_mut(); + adl_call!(atiadlxx_sys::ADL2_Main_ControlX2_Create( + Some(alloc), + 1, + &mut context, + atiadlxx_sys::ADLThreadingModel::ADL_THREADING_LOCKED, + )); + match ADL_CONTEXT.compare_exchange(ptr::null_mut(), context, Ordering::SeqCst, Ordering::SeqCst) + { + Ok(_) => { + let mut num_adapters = 0; + let mut adapter_info = ptr::null_mut(); + adl_call!(atiadlxx_sys::ADL2_Adapter_AdapterInfoX4_Get( + context, + -1, + &mut num_adapters, + &mut adapter_info + )); + let devices = (0..num_adapters as usize) + .filter_map(|idx| { + let adapter_info = *adapter_info.add(idx); + // Having this id in decimal is a nonsense, but that's just + // how ADL works + if adapter_info.iVendorID == AMD_PCI_ID_DECIMAL + && adapter_info.iExist == 1 + && adapter_info.iPresent == 1 + { + Some(Device { adapter_info }) + } else { + None + } + }) + // For some reason ADL returns a huge number of adapters + // I'm not sure why, probably to account for multiple displays, + // physical and virtual + .fold(BTreeMap::new(), |mut map, dev| { + if let btree_map::Entry::Vacant(entry) = map.entry(( + dev.adapter_info.iBusNumber, + dev.adapter_info.iDeviceNumber, + dev.adapter_info.iFunctionNumber, + )) { + entry.insert(dev); + } + map + }) + .into_iter() + .map(|(_, device)| device) + .collect::>(); + DEVICES = devices; + atomic::fence(Ordering::SeqCst); + Ok(()) + } + Err(_) => Ok(()), + } +} + +pub(crate) unsafe fn init_with_flags(_flags: ::std::os::raw::c_uint) -> Result<(), nvmlReturn_t> { + init() +} + +struct CountingWriter { + pub base: T, + pub len: usize, +} + +impl std::io::Write for CountingWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.len += buf.len(); + self.base.write(buf) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.base.flush() + } +} + +pub(crate) unsafe fn device_get_handle_by_index( + index: ::std::os::raw::c_uint, + device: *mut nvmlDevice_t, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device_ptr = mem::transmute(DEVICES.get(index as usize)); + *device = device_ptr; + if device_ptr != ptr::null_mut() { + Ok(()) + } else { + Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT) + } +} + +pub(crate) unsafe fn device_get_handle_by_pci_bus_id( + pci_bus_id: *const ::std::os::raw::c_char, + device: *mut nvmlDevice_t, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || pci_bus_id == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let (bus, pci_device, function) = common::parse_pci_address(pci_bus_id)?; + let device_ptr = mem::transmute(DEVICES.iter().find(|dev| { + dev.adapter_info.iBusNumber == bus + && dev.adapter_info.iDeviceNumber == pci_device + && dev.adapter_info.iFunctionNumber == function + })); + *device = device_ptr; + if device_ptr != ptr::null_mut() { + Ok(()) + } else { + Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT) + } +} + +pub(crate) unsafe fn device_get_fan_speed( + device: nvmlDevice_t, + speed: *mut u32, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || speed == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut fan_speed_info = mem::zeroed(); + adl_call!(atiadlxx_sys::ADL2_Overdrive6_FanSpeed_Get( + context, + device.adapter_info.iAdapterIndex, + &mut fan_speed_info + )); + *speed = fan_speed_info.iFanSpeedPercent as u32; + Ok(()) +} + +pub(crate) unsafe fn device_get_memory_info( + device: nvmlDevice_t, + memory: *mut nvmlMemory_t, +) -> Result<(), nvmlReturn_t> { + if memory == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut memory_info = mem::zeroed(); + adl_call!(atiadlxx_sys::ADL2_Adapter_MemoryInfo2_Get( + context, + device.adapter_info.iAdapterIndex, + &mut memory_info, + )); + let mut memory_use_in_mb = 0; + adl_call!(atiadlxx_sys::ADL2_Adapter_VRAMUsage_Get( + context, + device.adapter_info.iAdapterIndex, + &mut memory_use_in_mb, + )); + // visible/invisible memory in memory_info is some nonsense, + // on my machine: iMemorySize is 15.98GiB, iInvisibleMemorySize is 15.73GiB, + // iVisibleMemorySize is 0.25GiB + let total = memory_info.iMemorySize.max(0) as u64; + let used = memory_use_in_mb.max(0) as u64 * MIB; + let free = total.saturating_sub(used); + let nvml_memory = nvmlMemory_t { total, used, free }; + *memory = nvml_memory; + Ok(()) +} + +pub(crate) unsafe fn device_get_pci_info( + device: nvmlDevice_t, + pci: *mut nvmlPciInfo_t, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || pci == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut bus_id_legacy = [0u8; 16]; + write!( + &mut bus_id_legacy[..], + "0:{:x}:{:x}.{:x}\0", + device.adapter_info.iBusNumber, // 2 digits + device.adapter_info.iDeviceNumber, // 2 digits + device.adapter_info.iFunctionNumber // 1 digit + ) + .map_err(|_| nvmlReturn_t::NVML_ERROR_UNKNOWN)?; + let mut bus_id = [0u8; 32]; + bus_id[..16].copy_from_slice(&bus_id_legacy); + let pnp_string = CStr::from_ptr(device.adapter_info.strPNPString.as_ptr()).to_string_lossy(); + let subsys_id = extract_prefixed_hex_number(&pnp_string, "SUBSYS_", 8); + let device_id = extract_prefixed_hex_number(&pnp_string, "DEV_", 4); + let pci_location = nvmlPciInfo_t { + busIdLegacy: mem::transmute(bus_id_legacy), + bus: device.adapter_info.iBusNumber as u32, + domain: 0, + device: device.adapter_info.iDeviceNumber as u32, + pciDeviceId: (device_id << 16) | AMD_PCI_ID_HEX, + pciSubSystemId: subsys_id, + busId: mem::transmute(bus_id), + }; + *pci = pci_location; + Ok(()) +} + +unsafe fn extract_prefixed_hex_number(pnp_string: &Cow, prefix: &str, digits: usize) -> u32 { + let prefix_start = pnp_string.find(prefix).unwrap(); + let value_start = prefix_start + prefix.len(); + let value_str = &pnp_string.as_bytes()[value_start..value_start + digits]; + u32::from_str_radix(std::str::from_utf8_unchecked(value_str), 16).unwrap() +} + +pub(crate) unsafe fn device_get_temperature( + device: nvmlDevice_t, + sensor_type: nvmlTemperatureSensors_t, + temp: *mut ::std::os::raw::c_uint, +) -> nvmlReturn_t { + if device == ptr::null_mut() + || temp == ptr::null_mut() + || sensor_type != nvmlTemperatureSensors_t::NVML_TEMPERATURE_GPU + { + return nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT; + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return nvmlReturn_t::NVML_ERROR_UNINITIALIZED; + } + let device: &Device = mem::transmute(device); + atiadlxx_sys::ADL2_OverdriveN_Temperature_Get( + context, + device.adapter_info.iAdapterIndex, + ADLODNTEMPERATURE_TYPE_CORE, + temp as _, + ) + .into() +} + +pub(crate) unsafe fn device_get_utilization_rates( + device: nvmlDevice_t, + utilization: *mut nvmlUtilization_t, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || utilization == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut activity = mem::zeroed(); + adl_call!(atiadlxx_sys::ADL2_Overdrive5_CurrentActivity_Get( + context, + device.adapter_info.iAdapterIndex, + &mut activity + )); + *utilization = nvmlUtilization_t { + gpu: activity.iActivityPercent as u32, + memory: activity.iActivityPercent as u32, + }; + Ok(()) +} + +unsafe extern "C" fn alloc(size: i32) -> *mut c_void { + if size < 0 { + return ptr::null_mut(); + } + std::alloc::alloc(Layout::from_size_align_unchecked( + size as usize, + mem::size_of::(), + )) as *mut c_void +} + +pub(crate) unsafe fn device_get_field_values( + _device: *mut nvmlDevice_st, + _values_count: i32, + _values: *mut nvmlFieldValue_st, +) -> nvmlReturn_t { + crate::common::unimplemented() +} + +pub(crate) unsafe fn device_get_count(device_count: *mut u32) -> nvmlReturn_t { + if device_count == ptr::null_mut() { + return nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT; + } + *device_count = DEVICES.len() as u32; + nvmlReturn_t::NVML_SUCCESS +} + +pub(crate) unsafe fn device_get_power_management_limit( + device: nvmlDevice_t, + limit: *mut u32, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || limit == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut power_setting = mem::zeroed(); + adl_call!(ADL2_OverdriveN_PowerLimit_Get( + context, + device.adapter_info.iAdapterIndex, + &mut power_setting + )); + // This function does not actually work, so I'm not sure + // what it returns (watts, milliwats, something else?) + *limit = (power_setting.iTDPLimit * 1000) as u32; + Ok(()) +} + +pub(crate) unsafe fn device_get_power_management_limit_constraints( + device: *mut nvmlDevice_st, + min_limit: *mut u32, + max_limit: *mut u32, +) -> Result<(), nvmlReturn_t> { + // TODO: actually implement constraints + device_get_power_management_limit(device, min_limit)?; + device_get_power_management_limit(device, max_limit) +} + +pub(crate) unsafe fn device_get_power_usage( + device: *mut nvmlDevice_st, + power: *mut u32, +) -> Result<(), nvmlReturn_t> { + if device == ptr::null_mut() || power == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_INVALID_ARGUMENT); + } + let context = ADL_CONTEXT.load(Ordering::SeqCst); + if context == ptr::null_mut() { + return Err(nvmlReturn_t::NVML_ERROR_UNINITIALIZED); + } + let device: &Device = mem::transmute(device); + let mut pmlog = mem::zeroed(); + adl_call!(ADL2_New_QueryPMLogData_Get( + context, + device.adapter_info.iAdapterIndex, + &mut pmlog + )); + let sensor = pmlog.sensors[ADLSensorType::PMLOG_ASIC_POWER.0 as usize]; + if sensor.supported == 0 { + return Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED); + } + *power = (sensor.value * 1000) as u32; + Ok(()) +} + +pub(crate) unsafe fn device_get_pcie_throughput( + _device: *mut nvmlDevice_st, + _counter: nvmlPcieUtilCounter_enum, + _value: *mut u32, +) -> Result<(), nvmlReturn_t> { + Err(nvmlReturn_t::NVML_ERROR_NOT_SUPPORTED) +} diff --git a/zluda_redirect/Cargo.toml b/zluda_redirect/Cargo.toml index 130e244..e96f688 100644 --- a/zluda_redirect/Cargo.toml +++ b/zluda_redirect/Cargo.toml @@ -10,4 +10,8 @@ crate-type = ["cdylib"] [target.'cfg(windows)'.dependencies] detours-sys = { path = "../detours-sys" } wchar = "0.6" -winapi = { version = "0.3", features = ["processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "tlhelp32", "std"] } \ No newline at end of file +winapi = { version = "0.3", features = ["winuser", "sysinfoapi", "memoryapi", "processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "tlhelp32", "handleapi", "std"] } +memchr = "2.5.0" + +[package.metadata.zluda] +windows_only = true diff --git a/zluda_redirect/src/lib.rs b/zluda_redirect/src/lib.rs index 5de7530..ccc905f 100644 --- a/zluda_redirect/src/lib.rs +++ b/zluda_redirect/src/lib.rs @@ -3,34 +3,32 @@ extern crate detours_sys; extern crate winapi; -use std::{ - ffi::c_void, - mem, - os::raw::{c_int, c_uint, c_ulong}, - ptr, slice, usize, -}; +use std::{ffi::c_void, mem, path::PathBuf, ptr, slice, usize}; use detours_sys::{ - DetourAttach, DetourDetach, DetourRestoreAfterWith, DetourTransactionAbort, - DetourTransactionBegin, DetourTransactionCommit, DetourUpdateProcessWithDll, - DetourUpdateThread, + DetourAttach, DetourRestoreAfterWith, DetourTransactionAbort, DetourTransactionBegin, + DetourTransactionCommit, DetourUpdateProcessWithDll, DetourUpdateThread, }; use wchar::wch; use winapi::{ shared::minwindef::{BOOL, LPVOID}, um::{ handleapi::{CloseHandle, INVALID_HANDLE_VALUE}, + libloaderapi::{ + FindResourceW, GetModuleFileNameW, GetModuleHandleA, GetModuleHandleW, LoadResource, + }, minwinbase::LPSECURITY_ATTRIBUTES, processthreadsapi::{ - CreateProcessA, GetCurrentProcessId, GetCurrentThread, GetCurrentThreadId, OpenThread, - ResumeThread, SuspendThread, TerminateProcess, LPPROCESS_INFORMATION, LPSTARTUPINFOA, - LPSTARTUPINFOW, + CreateProcessA, GetCurrentProcessId, GetCurrentThreadId, OpenThread, ResumeThread, + SuspendThread, TerminateProcess, LPPROCESS_INFORMATION, LPSTARTUPINFOA, LPSTARTUPINFOW, }, + sysinfoapi::GetSystemDirectoryA, tlhelp32::{ CreateToolhelp32Snapshot, Thread32First, Thread32Next, TH32CS_SNAPTHREAD, THREADENTRY32, }, winbase::CREATE_SUSPENDED, winnt::{LPSTR, LPWSTR, THREAD_SUSPEND_RESUME}, + winuser::{MAKEINTRESOURCEW, RT_VERSION}, }, }; use winapi::{ @@ -40,7 +38,7 @@ use winapi::{ use winapi::{ shared::minwindef::{FARPROC, HINSTANCE}, um::{ - libloaderapi::{GetModuleFileNameA, GetProcAddress}, + libloaderapi::GetProcAddress, processthreadsapi::{CreateProcessAsUserW, CreateProcessW}, winbase::{CreateProcessWithLogonW, CreateProcessWithTokenW}, winnt::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, HANDLE, LPCWSTR}, @@ -53,16 +51,33 @@ use winapi::{ include!("payload_guid.rs"); -const NVCUDA_UTF8: &'static str = "NVCUDA.DLL"; -const NVCUDA_UTF16: &[u16] = wch!("NVCUDA.DLL"); -static mut ZLUDA_PATH_UTF8: Vec = Vec::new(); -static mut ZLUDA_PATH_UTF16: Option<&'static [u16]> = None; -static mut DETACH_LOAD_LIBRARY: bool = false; -static mut NVCUDA_ORIGINAL_MODULE: HMODULE = ptr::null_mut(); -static mut CUINIT_ORIGINAL_FN: FARPROC = ptr::null_mut(); +const WIN_MAX_PATH: usize = 260; +const NVCUDA1_UTF8: &'static str = "NVCUDA.DLL"; +const NVCUDA1_UTF16: &[u16] = wch!("NVCUDA.DLL"); +const NVCUDA2_UTF8: &'static str = "NVCUDA.DLL"; +const NVCUDA2_UTF16: &[u16] = wch!("NVCUDA.DLL"); +const NVML_UTF8: &'static str = "NVML.DLL"; +const NVML_UTF16: &[u16] = wch!("NVML.DLL"); +const NVAPI_UTF8: &'static str = "NVAPI64.DLL"; +const NVAPI_UTF16: &[u16] = wch!("NVAPI64.DLL"); +const NVOPTIX_UTF8: &'static str = "OPTIX.6.6.0.DLL"; +const NVOPTIX_UTF16: &[u16] = wch!("OPTIX.6.6.0.DLL"); +static mut ZLUDA_PATH_UTF8: Option<&'static [u8]> = None; +static mut ZLUDA_PATH_UTF16: Vec = Vec::new(); +static mut ZLUDA_ML_PATH_UTF8: Option<&'static [u8]> = None; +static mut ZLUDA_ML_PATH_UTF16: Vec = Vec::new(); +static mut ZLUDA_API_PATH_UTF8: Option<&'static [u8]> = None; +static mut ZLUDA_API_PATH_UTF16: Option> = None; +static mut ZLUDA_OPTIX_PATH_UTF8: Option<&'static [u8]> = None; +static mut ZLUDA_OPTIX_PATH_UTF16: Option> = None; +static mut DRIVERSTORE_UTF8: Vec = Vec::new(); +static mut DRIVERSTORE_UTF16: Vec = Vec::new(); static mut CURRENT_MODULE_FILENAME: Vec = Vec::new(); -const CUDA_ERROR_NOT_SUPPORTED: c_uint = 801; -const CUDA_ERROR_UNKNOWN: c_uint = 999; +static mut DETOUR_STATE: Option = None; + +#[no_mangle] +#[used] +pub static ZLUDA_REDIRECT: () = (); static mut LOAD_LIBRARY_A: unsafe extern "system" fn(lpLibFileName: LPCSTR) -> HMODULE = LoadLibraryA; @@ -76,6 +91,12 @@ static mut LOAD_LIBRARY_EX_A: unsafe extern "system" fn( dwFlags: DWORD, ) -> HMODULE = LoadLibraryExA; +static mut LOAD_LIBRARY_EX_W: unsafe extern "system" fn( + lpLibFileName: LPCWSTR, + hFile: HANDLE, + dwFlags: DWORD, +) -> HMODULE = LoadLibraryExW; + static mut CREATE_PROCESS_A: unsafe extern "system" fn( lpApplicationName: LPCSTR, lpCommandLine: LPSTR, @@ -142,11 +163,14 @@ static mut CREATE_PROCESS_WITH_LOGON_W: unsafe extern "system" fn( lpProcessInformation: LPPROCESS_INFORMATION, ) -> BOOL = CreateProcessWithLogonW; -static mut LOAD_LIBRARY_EX_W: unsafe extern "system" fn( - lpLibFileName: LPCWSTR, - hFile: HANDLE, - dwFlags: DWORD, -) -> HMODULE = LoadLibraryExW; +#[no_mangle] +#[allow(non_snake_case)] +unsafe extern "system" fn ZludaGetProcAddress_NoRedirect( + hModule: HMODULE, + lpProcName: LPCSTR, +) -> FARPROC { + GetProcAddress(hModule, lpProcName) +} #[no_mangle] #[allow(non_snake_case)] @@ -156,22 +180,98 @@ unsafe extern "system" fn ZludaLoadLibraryW_NoRedirect(lpLibFileName: LPCWSTR) - #[allow(non_snake_case)] unsafe extern "system" fn ZludaLoadLibraryA(lpLibFileName: LPCSTR) -> HMODULE { - let nvcuda_file_name = if is_nvcuda_dll_utf8(lpLibFileName as *const _) { - ZLUDA_PATH_UTF8.as_ptr() as *const _ + let library_name = get_library_name_utf8(lpLibFileName as _); + (LOAD_LIBRARY_A)(library_name as _) +} + +unsafe fn get_library_name_utf8(raw_library_name: *const u8) -> *const u8 { + let library_name = zero_terminated(raw_library_name); + if is_driverstore_utf8(library_name) { + if let Some(last_separator) = library_name + .iter() + .copied() + .rposition(|c| c as char == '\\' || c as char == '/') + { + let existing_module = + GetModuleHandleA(library_name[last_separator + 1..].as_ptr() as _); + if probably_is_nvidia_dll(existing_module) { + return raw_library_name; + } + } + } + if is_nvcuda_dll_utf8(library_name) { + return ZLUDA_PATH_UTF8.unwrap().as_ptr(); + } else if is_nvml_dll_utf8(library_name) { + return ZLUDA_ML_PATH_UTF8.unwrap().as_ptr(); } else { - lpLibFileName + if let Some(nvapi_path) = ZLUDA_API_PATH_UTF8 { + if is_nvapi_dll_utf8(library_name) { + return nvapi_path.as_ptr(); + } + } + if let Some(optix_path) = ZLUDA_OPTIX_PATH_UTF8 { + if is_nvoptix_dll_utf8(library_name) { + return optix_path.as_ptr(); + } + } }; - (LOAD_LIBRARY_A)(nvcuda_file_name) + raw_library_name } #[allow(non_snake_case)] unsafe extern "system" fn ZludaLoadLibraryW(lpLibFileName: LPCWSTR) -> HMODULE { - let nvcuda_file_name = if is_nvcuda_dll_utf16(lpLibFileName) { - ZLUDA_PATH_UTF16.unwrap().as_ptr() + let library_name = get_library_name_utf16(lpLibFileName); + (LOAD_LIBRARY_W)(library_name) +} + +unsafe fn get_library_name_utf16(raw_library_name: *const u16) -> *const u16 { + let library_name = zero_terminated(raw_library_name); + if is_driverstore_utf16(library_name) { + if let Some(last_separator) = library_name.iter().copied().rposition(|c| { + char::from_u32(c as u32).unwrap_or_default() == '\\' + || char::from_u32(c as u32).unwrap_or_default() == '/' + }) { + let existing_module = GetModuleHandleW(library_name[last_separator + 1..].as_ptr()); + if probably_is_nvidia_dll(existing_module) { + return raw_library_name; + } + } + } + if is_nvcuda_dll_utf16(library_name) { + return ZLUDA_PATH_UTF16.as_ptr(); + } else if is_nvml_dll_utf16(library_name) { + return ZLUDA_ML_PATH_UTF16.as_ptr(); } else { - lpLibFileName + if let Some(nvapi_path) = ZLUDA_API_PATH_UTF16.as_ref() { + if is_nvapi_dll_utf16(library_name) { + return nvapi_path.as_ptr(); + } + } + if let Some(optix_path) = ZLUDA_OPTIX_PATH_UTF16.as_ref() { + if is_nvoptix_dll_utf16(library_name) { + return optix_path.as_ptr(); + } + } }; - (LOAD_LIBRARY_W)(nvcuda_file_name) + raw_library_name +} + +unsafe fn probably_is_nvidia_dll(module: HMODULE) -> bool { + if module == ptr::null_mut() { + return false; + } + let resource_handle = FindResourceW(module, MAKEINTRESOURCEW(1), RT_VERSION); + if resource_handle == ptr::null_mut() { + return false; + } + let resource = LoadResource(module, resource_handle); + if resource == ptr::null_mut() { + return false; + } + let version_len = *(resource as *mut u16); + let resource_slice = slice::from_raw_parts(resource as *const u8, version_len as usize); + let key = wch!("NVIDIA"); + memchr::memmem::find(resource_slice, key.align_to::().1).is_some() } #[allow(non_snake_case)] @@ -180,12 +280,8 @@ unsafe extern "system" fn ZludaLoadLibraryExA( hFile: HANDLE, dwFlags: DWORD, ) -> HMODULE { - let nvcuda_file_name = if is_nvcuda_dll_utf8(lpLibFileName as *const _) { - ZLUDA_PATH_UTF8.as_ptr() as *const _ - } else { - lpLibFileName - }; - (LOAD_LIBRARY_EX_A)(nvcuda_file_name, hFile, dwFlags) + let library_name = get_library_name_utf8(lpLibFileName as _); + (LOAD_LIBRARY_EX_A)(library_name as _, hFile, dwFlags) } #[allow(non_snake_case)] @@ -194,12 +290,112 @@ unsafe extern "system" fn ZludaLoadLibraryExW( hFile: HANDLE, dwFlags: DWORD, ) -> HMODULE { - let nvcuda_file_name = if is_nvcuda_dll_utf16(lpLibFileName) { - ZLUDA_PATH_UTF16.unwrap().as_ptr() + let library_name = get_library_name_utf16(lpLibFileName); + (LOAD_LIBRARY_EX_W)(library_name, hFile, dwFlags) +} + +unsafe fn zero_terminated(t: *const T) -> &'static [T] { + let mut len = 0; + loop { + if *t.add(len) == T::default() { + break; + } + len += 1; + } + std::slice::from_raw_parts(t, len) +} + +unsafe fn is_driverstore_utf8(lib: &[u8]) -> bool { + starts_with_ignore_case(lib, &DRIVERSTORE_UTF8, utf8_to_ascii_uppercase) +} + +unsafe fn is_driverstore_utf16(lib: &[u16]) -> bool { + starts_with_ignore_case(lib, &DRIVERSTORE_UTF16, utf16_to_ascii_uppercase) +} + +fn is_nvcuda_dll_utf8(lib: &[u8]) -> bool { + is_dll_utf8(lib, NVCUDA1_UTF8.as_bytes()) || is_dll_utf8(lib, NVCUDA2_UTF8.as_bytes()) +} + +fn is_nvcuda_dll_utf16(lib: &[u16]) -> bool { + is_dll_utf16(lib, NVCUDA1_UTF16) || is_dll_utf16(lib, NVCUDA2_UTF16) +} + +fn is_nvml_dll_utf8(lib: &[u8]) -> bool { + is_dll_utf8(lib, NVML_UTF8.as_bytes()) +} + +fn is_nvml_dll_utf16(lib: &[u16]) -> bool { + is_dll_utf16(lib, NVML_UTF16) +} + +fn is_nvapi_dll_utf8(lib: &[u8]) -> bool { + is_dll_utf8(lib, NVAPI_UTF8.as_bytes()) +} + +fn is_nvapi_dll_utf16(lib: &[u16]) -> bool { + is_dll_utf16(lib, NVAPI_UTF16) +} + +fn is_nvoptix_dll_utf8(lib: &[u8]) -> bool { + is_dll_utf8(lib, NVOPTIX_UTF8.as_bytes()) +} + +fn is_nvoptix_dll_utf16(lib: &[u16]) -> bool { + is_dll_utf16(lib, NVOPTIX_UTF16) +} + +fn is_dll_utf8(lib: &[u8], name: &[u8]) -> bool { + ends_with_ignore_case(lib, name, utf8_to_ascii_uppercase) +} + +fn is_dll_utf16(lib: &[u16], name: &[u16]) -> bool { + ends_with_ignore_case(lib, name, utf16_to_ascii_uppercase) +} + +fn utf8_to_ascii_uppercase(c: u8) -> u8 { + c.to_ascii_uppercase() +} + +fn utf16_to_ascii_uppercase(c: u16) -> u16 { + if c >= 'a' as u16 && c <= 'z' as u16 { + c - 32 } else { - lpLibFileName - }; - (LOAD_LIBRARY_EX_W)(nvcuda_file_name, hFile, dwFlags) + c + } +} + +fn ends_with_ignore_case( + haystack: &[T], + needle: &[T], + uppercase: impl Fn(T) -> T, +) -> bool { + if haystack.len() < needle.len() { + return false; + } + let offset = haystack.len() - needle.len(); + for i in 0..needle.len() { + if uppercase(haystack[offset + i]) != needle[i] { + return false; + } + } + true +} + +fn starts_with_ignore_case( + haystack: &[T], + needle: &[T], + uppercase: impl Fn(T) -> T, +) -> bool { + if haystack.len() < needle.len() { + return false; + } + for i in 0..needle.len() { + if uppercase(haystack[i]) != needle[i] { + return false; + } + } + true } #[allow(non_snake_case)] @@ -335,7 +531,7 @@ unsafe extern "system" fn ZludaCreateProcessWithTokenW( dwLogonFlags, lpApplicationName, lpCommandLine, - dwCreationFlags, + dwCreationFlags | CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, @@ -344,35 +540,244 @@ unsafe extern "system" fn ZludaCreateProcessWithTokenW( continue_create_process_hook(create_proc_result, dwCreationFlags, lpProcessInformation) } +// This type encapsulates typical calling sequence of detours and cleanup. +// We have two ways we do detours: +// * If we are loaded before nvcuda.dll, we hook LoadLibrary* +// * If we are loaded after nvcuda.dll, we override every cu* function +// Additionally, within both of those we attach to CreateProcess* +struct DetourDetachGuard { + state: DetourUndoState, + suspended_threads: Vec<*mut c_void>, + // First element is the original fn, second is the new fn + overriden_non_cuda_fns: Vec<(*mut *mut c_void, *mut c_void)>, +} + +impl DetourDetachGuard { + // First element in the pair is ptr to original fn, second argument is the + // new function. We accept *mut *mut c_void instead of *mut c_void as the + // first element in the pair, because somehow otherwise original functions + // also get overriden, so for example ZludaLoadLibraryExW ends calling + // itself recursively until stack overflow exception occurs + unsafe fn new<'a>() -> Option { + let mut result = DetourDetachGuard { + state: DetourUndoState::DoNothing, + suspended_threads: Vec::new(), + overriden_non_cuda_fns: Vec::new(), + }; + if DetourTransactionBegin() != NO_ERROR as i32 { + return None; + } + result.state = DetourUndoState::AbortTransactionResumeThreads; + if !Self::suspend_all_threads_except_current(&mut result.suspended_threads) { + return None; + } + for thread_handle in result.suspended_threads.iter().copied() { + if DetourUpdateThread(thread_handle) != NO_ERROR as i32 { + return None; + } + } + result.overriden_non_cuda_fns.extend_from_slice(&[ + ( + &mut LOAD_LIBRARY_A as *mut _ as *mut *mut c_void, + ZludaLoadLibraryA as *mut c_void, + ), + (&mut LOAD_LIBRARY_W as *mut _ as _, ZludaLoadLibraryW as _), + ( + &mut LOAD_LIBRARY_EX_A as *mut _ as _, + ZludaLoadLibraryExA as _, + ), + ( + &mut LOAD_LIBRARY_EX_W as *mut _ as _, + ZludaLoadLibraryExW as _, + ), + ( + &mut CREATE_PROCESS_A as *mut _ as _, + ZludaCreateProcessA as _, + ), + ( + &mut CREATE_PROCESS_W as *mut _ as _, + ZludaCreateProcessW as _, + ), + ( + &mut CREATE_PROCESS_AS_USER_W as *mut _ as _, + ZludaCreateProcessAsUserW as _, + ), + ( + &mut CREATE_PROCESS_WITH_LOGON_W as *mut _ as _, + ZludaCreateProcessWithLogonW as _, + ), + ( + &mut CREATE_PROCESS_WITH_TOKEN_W as *mut _ as _, + ZludaCreateProcessWithTokenW as _, + ), + ]); + for (original_fn, new_fn) in result.overriden_non_cuda_fns.iter().copied() { + if DetourAttach(original_fn, new_fn) != NO_ERROR as i32 { + return None; + } + } + if DetourTransactionCommit() != NO_ERROR as i32 { + return None; + } + result.state = DetourUndoState::DoNothing; + // HACK ALERT + // I really have no idea how this could happen. + // Perhaps a thread was closed? + if !result.resume_threads() { + if cfg!(debug_assertions) { + panic!(); + } + } + result.state = DetourUndoState::DetachDetours; + Some(result) + } + + unsafe fn suspend_all_threads_except_current(threads: &mut Vec<*mut c_void>) -> bool { + let thread_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if thread_snapshot == INVALID_HANDLE_VALUE { + return false; + } + let current_thread = GetCurrentThreadId(); + let current_process = GetCurrentProcessId(); + let mut thread = mem::zeroed::(); + thread.dwSize = mem::size_of::() as u32; + if Thread32First(thread_snapshot, &mut thread) == 0 { + CloseHandle(thread_snapshot); + return false; + } + loop { + if thread.th32OwnerProcessID == current_process && thread.th32ThreadID != current_thread + { + let thread_handle = OpenThread(THREAD_SUSPEND_RESUME, 0, thread.th32ThreadID); + if thread_handle == ptr::null_mut() { + CloseHandle(thread_snapshot); + return false; + } + if SuspendThread(thread_handle) == (-1i32 as u32) { + CloseHandle(thread_handle); + CloseHandle(thread_snapshot); + return false; + } + threads.push(thread_handle); + } + if Thread32Next(thread_snapshot, &mut thread) == 0 { + break; + } + } + CloseHandle(thread_snapshot); + true + } + + // returns true on success + unsafe fn resume_threads(&self) -> bool { + let mut success = true; + for t in self.suspended_threads.iter().copied() { + if ResumeThread(t) == -1i32 as u32 { + success = false; + } + if CloseHandle(t) == 0 { + success = false; + } + } + success + } +} + +impl Drop for DetourDetachGuard { + fn drop(&mut self) { + match self.state { + DetourUndoState::DoNothing => {} + DetourUndoState::AbortTransactionResumeThreads => { + unsafe { DetourTransactionAbort() }; + unsafe { self.resume_threads() }; + } + DetourUndoState::DetachDetours => { + // TODO: implement + } + } + } +} + +// Along with Drop impl this forms a state machine for undoing detours. +// I would like to model this as a an usual full state machine with fields in +// variants, but you can't move fields out of type that implements Drop +enum DetourUndoState { + DoNothing, + AbortTransactionResumeThreads, + DetachDetours, +} + unsafe fn continue_create_process_hook( create_proc_result: BOOL, - creation_flags: DWORD, + original_creation_flags: DWORD, process_information: LPPROCESS_INFORMATION, ) -> BOOL { if create_proc_result == 0 { return 0; } + // Detours injection can fail for various reasons, like child being 32bit. + // If we did not manage to inject then too bad, it's better if the child + // continues uninjected than to break the parent if DetourUpdateProcessWithDll( (*process_information).hProcess, - &mut CURRENT_MODULE_FILENAME.as_ptr() as *mut _ as *mut _, + &mut ZLUDA_ML_PATH_UTF8.unwrap().as_ptr() as *mut _ as *mut _, 1, - ) == 0 + ) != FALSE + && DetourUpdateProcessWithDll( + (*process_information).hProcess, + &mut ZLUDA_PATH_UTF8.unwrap().as_ptr() as *mut _ as *mut _, + 1, + ) != FALSE + && DetourUpdateProcessWithDll( + (*process_information).hProcess, + &mut CURRENT_MODULE_FILENAME.as_ptr() as *mut _ as *mut _, + 1, + ) != FALSE { - TerminateProcess((*process_information).hProcess, 1); - return 0; + detours_sys::DetourCopyPayloadToProcess( + (*process_information).hProcess, + &PAYLOAD_NVML_GUID, + ZLUDA_ML_PATH_UTF8.unwrap().as_ptr() as *mut _, + (ZLUDA_ML_PATH_UTF8.unwrap().len() * mem::size_of::()) as u32, + ); + detours_sys::DetourCopyPayloadToProcess( + (*process_information).hProcess, + &PAYLOAD_NVCUDA_GUID, + ZLUDA_PATH_UTF8.unwrap().as_ptr() as *mut _, + (ZLUDA_PATH_UTF8.unwrap().len() * mem::size_of::()) as u32, + ); } - if detours_sys::DetourCopyPayloadToProcess( - (*process_information).hProcess, - &PAYLOAD_GUID, - ZLUDA_PATH_UTF16.unwrap().as_ptr() as *mut _, - (ZLUDA_PATH_UTF16.unwrap().len() * mem::size_of::()) as u32, - ) == FALSE - { - TerminateProcess((*process_information).hProcess, 1); - return 0; + if let Some(nvapi_path) = ZLUDA_API_PATH_UTF8 { + if DetourUpdateProcessWithDll( + (*process_information).hProcess, + &mut nvapi_path.as_ptr() as *mut _ as *mut _, + 1, + ) != FALSE + { + detours_sys::DetourCopyPayloadToProcess( + (*process_information).hProcess, + &PAYLOAD_NVAPI_GUID, + nvapi_path.as_ptr() as *mut _, + (nvapi_path.len() * mem::size_of::()) as u32, + ); + } } - - if creation_flags & CREATE_SUSPENDED == 0 { + if let Some(optix_path) = ZLUDA_OPTIX_PATH_UTF8 { + if DetourUpdateProcessWithDll( + (*process_information).hProcess, + &mut optix_path.as_ptr() as *mut _ as *mut _, + 1, + ) != FALSE + { + detours_sys::DetourCopyPayloadToProcess( + (*process_information).hProcess, + &PAYLOAD_NVOPTIX_GUID, + optix_path.as_ptr() as *mut _, + (optix_path.len() * mem::size_of::()) as u32, + ); + } + } + if original_creation_flags & CREATE_SUSPENDED == 0 { if ResumeThread((*process_information).hThread) == -1i32 as u32 { TerminateProcess((*process_information).hProcess, 1); return 0; @@ -381,159 +786,6 @@ unsafe fn continue_create_process_hook( create_proc_result } -unsafe extern "C" fn cuinit_detour(flags: c_uint) -> c_uint { - let zluda_module = LoadLibraryW(ZLUDA_PATH_UTF16.unwrap().as_ptr()); - if zluda_module == ptr::null_mut() { - return CUDA_ERROR_UNKNOWN; - } - let suspended_threads = suspend_all_threads_except_current(); - let suspended_threads = match suspended_threads { - Some(t) => t, - None => return CUDA_ERROR_UNKNOWN, - }; - if DetourTransactionBegin() != NO_ERROR as i32 { - resume_threads(&suspended_threads); - return CUDA_ERROR_UNKNOWN; - } - for t in suspended_threads.iter() { - if DetourUpdateThread(*t) != NO_ERROR as i32 { - DetourTransactionAbort(); - resume_threads(&suspended_threads); - return CUDA_ERROR_UNKNOWN; - } - } - if detours_sys::DetourEnumerateExports( - NVCUDA_ORIGINAL_MODULE as *mut _, - &zluda_module as *const _ as *mut _, - Some(override_nvcuda_export), - ) == FALSE - { - DetourTransactionAbort(); - resume_threads(&suspended_threads); - return CUDA_ERROR_UNKNOWN; - } - if DetourTransactionCommit() != NO_ERROR as i32 { - DetourTransactionAbort(); - resume_threads(&suspended_threads); - return CUDA_ERROR_UNKNOWN; - } - resume_threads(&suspended_threads); - let zluda_cuinit = GetProcAddress(zluda_module, b"cuInit\0".as_ptr() as *const _); - (mem::transmute::<_, unsafe extern "C" fn(c_uint) -> c_uint>(zluda_cuinit))(flags) -} - -unsafe fn suspend_all_threads_except_current() -> Option> { - let thread_snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if thread_snap == INVALID_HANDLE_VALUE { - return None; - } - let current_thread = GetCurrentThreadId(); - let current_process = GetCurrentProcessId(); - let mut threads = Vec::new(); - let mut thread = mem::zeroed::(); - thread.dwSize = mem::size_of::() as u32; - if Thread32First(thread_snap, &mut thread) == 0 { - CloseHandle(thread_snap); - return None; - } - loop { - if thread.th32OwnerProcessID == current_process && thread.th32ThreadID != current_thread { - let thread_handle = OpenThread(THREAD_SUSPEND_RESUME, 0, thread.th32ThreadID); - if thread_handle == ptr::null_mut() { - CloseHandle(thread_snap); - resume_threads(&threads); - return None; - } - if SuspendThread(thread_handle) == (-1i32 as u32) { - CloseHandle(thread_snap); - resume_threads(&threads); - return None; - } - threads.push(thread_handle); - } - if Thread32Next(thread_snap, &mut thread) == 0 { - break; - } - } - CloseHandle(thread_snap); - Some(threads) -} - -unsafe fn resume_threads(threads: &[*mut c_void]) { - for t in threads { - ResumeThread(*t); - CloseHandle(*t); - } -} - -unsafe extern "C" fn override_nvcuda_export( - context_ptr: *mut c_void, - _: c_ulong, - name: LPCSTR, - mut address: *mut c_void, -) -> c_int { - let zluda_module: HMODULE = *(context_ptr as *mut HMODULE); - let mut zluda_fn = GetProcAddress(zluda_module, name); - if zluda_fn == ptr::null_mut() { - // We only support 64 bits and in all relevant calling conventions stack - // is caller-cleaned, so probably we will not crash - zluda_fn = unsupported_cuda_fn as *mut _; - } - if DetourAttach((&mut address) as *mut _, zluda_fn as *mut _) != NO_ERROR as i32 { - return FALSE; - } - TRUE -} - -unsafe extern "C" fn unsupported_cuda_fn() -> c_uint { - CUDA_ERROR_NOT_SUPPORTED -} - -fn is_nvcuda_dll_utf8(lib: *const u8) -> bool { - is_nvcuda_dll(lib, 0, NVCUDA_UTF8.as_bytes(), |c| { - if c >= 'a' as u8 && c <= 'z' as u8 { - c - 32 - } else { - c - } - }) -} -fn is_nvcuda_dll_utf16(lib: *const u16) -> bool { - is_nvcuda_dll(lib, 0u16, NVCUDA_UTF16, |c| { - if c >= 'a' as u16 && c <= 'z' as u16 { - c - 32 - } else { - c - } - }) -} - -fn is_nvcuda_dll( - lib: *const T, - zero: T, - dll_name: &[T], - uppercase: impl Fn(T) -> T, -) -> bool { - let mut len = 0; - loop { - if unsafe { *lib.offset(len) } == zero { - break; - } - len += 1; - } - if (len as usize) < dll_name.len() { - return false; - } - let slice = - unsafe { slice::from_raw_parts(lib.offset(len - dll_name.len() as isize), dll_name.len()) }; - for i in 0..dll_name.len() { - if uppercase(slice[i]) != dll_name[i] { - return false; - } - } - true -} - #[allow(non_snake_case)] #[no_mangle] unsafe extern "system" fn DllMain(instDLL: HINSTANCE, dwReason: u32, _: *const u8) -> i32 { @@ -541,302 +793,104 @@ unsafe extern "system" fn DllMain(instDLL: HINSTANCE, dwReason: u32, _: *const u if DetourRestoreAfterWith() == FALSE { return FALSE; } - if !initialize_current_module_name(instDLL) { + if !initialize_globals(instDLL) { return FALSE; } - match get_zluda_dll_path() { - Some(path) => { - ZLUDA_PATH_UTF16 = Some(path); - // from_utf16_lossy(...) handles terminating NULL correctly - ZLUDA_PATH_UTF8 = String::from_utf16_lossy(path).into_bytes(); + match DetourDetachGuard::new() { + Some(g) => { + DETOUR_STATE = Some(g); + TRUE } - None => return FALSE, - } - // If the application (directly or not) links to nvcuda.dll, nvcuda.dll - // will get loaded before we can act. In this case, instead of - // redirecting LoadLibrary* to load ZLUDA, we redirect cuInit to - // a cuInit implementation that will load ZLUDA and set up detouts. - // We can't do it here because LoadLibrary* inside DllMain is illegal. - // We greatly prefer wholesale redirecting inside LoadLibrary*. - // Hooking inside cuInit is brittle in the face of multiple - // threads (DetourUpdateThread) - match get_cuinit() { - Some((nvcuda_mod, cuinit_fn)) => attach_cuinit(nvcuda_mod, cuinit_fn), - None => attach_load_libary(), + None => FALSE, } } else if dwReason == DLL_PROCESS_DETACH { - if DETACH_LOAD_LIBRARY { - detach_load_library() - } else { - detach_cuinit() + match DETOUR_STATE.take() { + Some(_) => TRUE, + None => FALSE, } } else { TRUE } } -#[must_use] -unsafe fn initialize_current_module_name(current_module: HINSTANCE) -> bool { - let mut name = vec![0; 128 as usize]; +unsafe fn initialize_globals(current_module: HINSTANCE) -> bool { + let mut module_name = vec![0; 128 as usize]; loop { - let size = GetModuleFileNameA( + let size = GetModuleFileNameW( current_module, - name.as_mut_ptr() as *mut _, - name.len() as u32, + module_name.as_mut_ptr(), + module_name.len() as u32, ); if size == 0 { return false; } - if size < name.len() as u32 { - name.truncate(size as usize); - CURRENT_MODULE_FILENAME = name; - return true; - } - name.resize(name.len() * 2, 0); - } -} - -unsafe fn get_cuinit() -> Option<(HMODULE, FARPROC)> { - let mut module = ptr::null_mut(); - loop { - module = detours_sys::DetourEnumerateModules(module); - if module == ptr::null_mut() { - return None; - } - let cuinit_addr = GetProcAddress(module as *mut _, b"cuInit\0".as_ptr() as *const _); - if cuinit_addr != ptr::null_mut() { - return Some((module as *mut _, cuinit_addr)); - } - } -} - -#[must_use] -unsafe fn attach_cuinit(nvcuda_mod: HMODULE, mut cuinit: FARPROC) -> i32 { - if DetourTransactionBegin() != NO_ERROR as i32 { - return FALSE; - } - if !attach_create_process() { - return FALSE; - } - NVCUDA_ORIGINAL_MODULE = nvcuda_mod; - CUINIT_ORIGINAL_FN = cuinit; - if DetourAttach(mem::transmute(&mut cuinit), cuinit_detour as *mut _) != NO_ERROR as i32 { - return FALSE; - } - if DetourTransactionCommit() != NO_ERROR as i32 { - return FALSE; - } - TRUE -} - -#[must_use] -unsafe fn detach_cuinit() -> i32 { - if DetourTransactionBegin() != NO_ERROR as i32 { - return FALSE; - } - if !detach_create_process() { - return FALSE; - } - if DetourUpdateThread(GetCurrentThread()) != NO_ERROR as i32 { - return FALSE; - } - if DetourDetach( - mem::transmute(&mut CUINIT_ORIGINAL_FN), - cuinit_detour as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourTransactionCommit() != NO_ERROR as i32 { - return FALSE; - } - TRUE -} - -#[must_use] -unsafe fn attach_load_libary() -> i32 { - if DetourTransactionBegin() != NO_ERROR as i32 { - return FALSE; - } - if !attach_create_process() { - return FALSE; - } - if DetourAttach( - mem::transmute(&mut LOAD_LIBRARY_A), - ZludaLoadLibraryA as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourAttach( - mem::transmute(&mut LOAD_LIBRARY_W), - ZludaLoadLibraryW as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourAttach( - mem::transmute(&mut LOAD_LIBRARY_EX_A), - ZludaLoadLibraryExA as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourAttach( - mem::transmute(&mut LOAD_LIBRARY_EX_W), - ZludaLoadLibraryExW as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourTransactionCommit() != NO_ERROR as i32 { - return FALSE; - } - TRUE -} - -#[must_use] -unsafe fn detach_load_library() -> i32 { - if DetourTransactionBegin() != NO_ERROR as i32 { - return FALSE; - } - if !detach_create_process() { - return FALSE; - } - if DetourUpdateThread(GetCurrentThread()) != NO_ERROR as i32 { - return FALSE; - } - if DetourDetach( - mem::transmute(&mut LOAD_LIBRARY_A), - ZludaLoadLibraryA as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourDetach( - mem::transmute(&mut LOAD_LIBRARY_W), - ZludaLoadLibraryW as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourDetach( - mem::transmute(&mut LOAD_LIBRARY_EX_A), - ZludaLoadLibraryExA as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourDetach( - mem::transmute(&mut LOAD_LIBRARY_EX_W), - ZludaLoadLibraryExW as *mut _, - ) != NO_ERROR as i32 - { - return FALSE; - } - if DetourTransactionCommit() != NO_ERROR as i32 { - return FALSE; - } - TRUE -} - -fn get_zluda_dll_path() -> Option<&'static [u16]> { - let mut module = ptr::null_mut(); - loop { - module = unsafe { detours_sys::DetourEnumerateModules(module) }; - if module == ptr::null_mut() { + if size < module_name.len() as u32 { + module_name.truncate(size as usize); + module_name.push(0); + CURRENT_MODULE_FILENAME = String::from_utf16_lossy(&module_name).into_bytes(); break; } - let mut size = 0; - let payload = unsafe { detours_sys::DetourFindPayload(module, &PAYLOAD_GUID, &mut size) }; - if payload != ptr::null_mut() { - return unsafe { - Some(slice::from_raw_parts( - payload as *const _, - (size as usize) / mem::size_of::(), - )) - }; - } + module_name.resize(module_name.len() * 2, 0); } - None -} - -#[must_use] -unsafe fn attach_create_process() -> bool { - if DetourAttach( - mem::transmute(&mut CREATE_PROCESS_A), - ZludaCreateProcessA as *mut _, - ) != NO_ERROR as i32 - { + let mut system_dir = vec![0; WIN_MAX_PATH]; + let system_dir_len = + GetSystemDirectoryA(system_dir.as_mut_ptr() as *mut i8, system_dir.len() as u32); + if system_dir_len == 0 { return false; } - if DetourAttach( - mem::transmute(&mut CREATE_PROCESS_W), - ZludaCreateProcessW as *mut _, - ) != NO_ERROR as i32 - { + system_dir.truncate(system_dir_len as usize); + let mut driver_store = PathBuf::from(std::str::from_utf8_unchecked(&*system_dir)); + driver_store.push("DriverStore"); + driver_store.push("FileRepository"); + let driver_store_string = driver_store.to_str().unwrap().to_ascii_uppercase(); + DRIVERSTORE_UTF16 = driver_store_string.encode_utf16().collect::>(); + DRIVERSTORE_UTF8 = driver_store_string.into_bytes(); + if !load_global_string(&PAYLOAD_NVCUDA_GUID, &mut ZLUDA_PATH_UTF8, || { + &mut ZLUDA_PATH_UTF16 + }) { return false; } - if DetourAttach( - mem::transmute(&mut CREATE_PROCESS_AS_USER_W), - ZludaCreateProcessAsUserW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - if DetourAttach( - mem::transmute(&mut CREATE_PROCESS_WITH_LOGON_W), - ZludaCreateProcessWithLogonW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - if DetourAttach( - mem::transmute(&mut CREATE_PROCESS_WITH_TOKEN_W), - ZludaCreateProcessWithTokenW as *mut _, - ) != NO_ERROR as i32 - { + if !load_global_string(&PAYLOAD_NVML_GUID, &mut ZLUDA_ML_PATH_UTF8, || { + &mut ZLUDA_ML_PATH_UTF16 + }) { return false; } + load_global_string(&PAYLOAD_NVAPI_GUID, &mut ZLUDA_API_PATH_UTF8, || { + ZLUDA_API_PATH_UTF16.get_or_insert(Vec::new()) + }); + load_global_string(&PAYLOAD_NVOPTIX_GUID, &mut ZLUDA_OPTIX_PATH_UTF8, || { + ZLUDA_OPTIX_PATH_UTF16.get_or_insert(Vec::new()) + }); true } -#[must_use] -unsafe fn detach_create_process() -> bool { - if DetourDetach( - mem::transmute(&mut CREATE_PROCESS_A), - ZludaCreateProcessA as *mut _, - ) != NO_ERROR as i32 - { - return false; +fn load_global_string( + guid: &detours_sys::GUID, + utf8_path: &mut Option<&'static [u8]>, + utf16_path: impl FnOnce() -> &'static mut Vec, +) -> bool { + if let Some(payload) = get_payload(guid) { + *utf8_path = Some(payload); + *utf16_path() = unsafe { std::str::from_utf8_unchecked(payload) } + .encode_utf16() + .collect::>(); + true + } else { + false + } +} + +fn get_payload(guid: &detours_sys::GUID) -> Option<&'static [T]> { + let mut size = 0; + let payload_ptr = unsafe { detours_sys::DetourFindPayloadEx(guid, &mut size) }; + if payload_ptr != ptr::null_mut() { + Some(unsafe { + slice::from_raw_parts( + payload_ptr as *const _, + (size as usize) / mem::size_of::(), + ) + }) + } else { + None } - if DetourDetach( - mem::transmute(&mut CREATE_PROCESS_W), - ZludaCreateProcessW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - if DetourDetach( - mem::transmute(&mut CREATE_PROCESS_AS_USER_W), - ZludaCreateProcessAsUserW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - if DetourDetach( - mem::transmute(&mut CREATE_PROCESS_WITH_LOGON_W), - ZludaCreateProcessWithLogonW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - if DetourDetach( - mem::transmute(&mut CREATE_PROCESS_WITH_TOKEN_W), - ZludaCreateProcessWithTokenW as *mut _, - ) != NO_ERROR as i32 - { - return false; - } - true } diff --git a/zluda_redirect/src/payload_guid.rs b/zluda_redirect/src/payload_guid.rs index eaf021d..8ece43e 100644 --- a/zluda_redirect/src/payload_guid.rs +++ b/zluda_redirect/src/payload_guid.rs @@ -1,6 +1,31 @@ -const PAYLOAD_GUID: detours_sys::GUID = detours_sys::GUID { +#[allow(dead_code)] +const PAYLOAD_NVCUDA_GUID: detours_sys::GUID = detours_sys::GUID { Data1: 0xC225FC0C, Data2: 0x00D7, Data3: 0x40B8, Data4: [0x93, 0x5A, 0x7E, 0x34, 0x2A, 0x93, 0x44, 0xC1], -}; \ No newline at end of file +}; + +#[allow(dead_code)] +const PAYLOAD_NVML_GUID: detours_sys::GUID = detours_sys::GUID { + Data1: 0x75B54759, + Data2: 0xB6F1, + Data3: 0x49C2, + Data4: [0xA2, 0x09, 0x68, 0x54, 0x96, 0xBD, 0x70, 0xC0], +}; + +#[allow(dead_code)] +const PAYLOAD_NVAPI_GUID: detours_sys::GUID = detours_sys::GUID { + Data1: 0xc01fff7f, + Data2: 0x310d, + Data3: 0x4ac4, + Data4: [0xAF, 0x47, 0x11, 0x4d, 0x9a, 0xef, 0x7a, 47], +}; + +#[allow(dead_code)] +const PAYLOAD_NVOPTIX_GUID: detours_sys::GUID = detours_sys::GUID { + Data1: 0x629e45e5, + Data2: 0xf4d1, + Data3: 0x4649, + Data4: [0x9d, 0xb4, 0x7e, 0x17, 0xf6, 0x74, 0xc2, 0xad], +}; diff --git a/zluda_rt/Cargo.toml b/zluda_rt/Cargo.toml new file mode 100644 index 0000000..263b693 --- /dev/null +++ b/zluda_rt/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "zluda_rt" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "nvoptix" +crate-type = ["cdylib"] + +[dependencies] +comgr = { path = "../comgr" } +hip_common = { path = "../hip_common" } +hip_runtime-sys = { path = "../hip_runtime-sys" } +hiprt-sys = { path = "../hiprt-sys" } +optix_base = { path = "../optix_base" } +optix_types = { path = "../optix_types" } +ptx = { path = "../ptx" } +rustc-hash = "1.1" +paste = "1.0" +winapi = { version = "0.3", features = ["libloaderapi", "std"] } +libloading = "0.8" +nougat = "0.2.4" +glam = "0.22" +dirs = "4.0.0" +sha2 = "0.10.2" +generic-array = "0.14.5" +typenum = "1.15.0" +data-encoding = "2.3.3" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_with = "2.1.0" +static_assertions = "1.1.0" +rusqlite = { version = "0.28.0", features = ["bundled", "serde_json"] } + +[dev-dependencies] +float-cmp = "0.9.0" + +[build-dependencies] +vergen = { version = "7.5.1", default-features = false, features = ["git"] } +# We don't use time crate, but this coerces vergen to not use newer version that requires +# higher minimum rust version +time = "=0.3.23" + +[package.metadata.zluda] +broken = true +linux_names = ["liboptix.so.6.5.0", "liboptix.so.6.6.0"] diff --git a/zluda_rt/bin/liboptix.so.6.5.0 b/zluda_rt/bin/liboptix.so.6.5.0 new file mode 100644 index 0000000000000000000000000000000000000000..2d188c014d258d9e2f9dee8d413141af01f9a70a GIT binary patch literal 1004520 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%0D=}^+5aBGhE?M$!ZENw4ddW-ACITvP|qDT^@t!L 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
J6@pD38U9c$I3NwjM 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 %!-34}tY3S;_( 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�O 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 hBCmzd)s;# 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

UZQtN} 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 z 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 literal 0 HcmV?d00001 diff --git a/zluda_rt/bin/optix.6.5.0.dll b/zluda_rt/bin/optix.6.5.0.dll new file mode 100644 index 0000000000000000000000000000000000000000..90cf28e2306e9a99392fbaeb11b1d534ad6c67f9 GIT binary patch literal 203248 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

8!f_s1VK^5c+X?Jvg9N!AQm=761u3 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%0DV$S&;S??nL1PZi*f5(>u=o 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 VWbS{4B}3V3&2u>^Z4ZUv{{a=Trzijb literal 0 HcmV?d00001 diff --git a/zluda_rt/build.rs b/zluda_rt/build.rs new file mode 100644 index 0000000..9d7f95d --- /dev/null +++ b/zluda_rt/build.rs @@ -0,0 +1,5 @@ +use vergen::{Config, vergen}; + +fn main() { + vergen(Config::default()).unwrap() +} \ No newline at end of file diff --git a/zluda_rt/optix.xmi b/zluda_rt/optix.xmi new file mode 100644 index 0000000..5f28feb --- /dev/null +++ b/zluda_rt/optix.xmi @@ -0,0 +1,325 @@ + + + + + umbrello uml modeller http://umbrello.kde.org + 1.6.18 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zluda_rt/src/acceleration.rs b/zluda_rt/src/acceleration.rs new file mode 100644 index 0000000..371b747 --- /dev/null +++ b/zluda_rt/src/acceleration.rs @@ -0,0 +1,139 @@ +use crate::{ + context::{self, Context, ContextData}, + geometry_group::GeometryGroupData, + group::GroupData, + null_check, null_unwrap, MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use hiprt_sys::hiprtBuildFlagBits; +use optix_types::*; +use std::ffi::CStr; +use std::{ + ffi::CString, + rc::{Rc, Weak}, +}; + +pub(crate) type Acceleration = *const OptixCell; + +pub(crate) struct AccelerationData { + pub(crate) context: Weak>, + pub(crate) owner: Option, + builder: CString, +} + +impl AccelerationData { + fn new(weak_context: Weak>, _: &mut ContextData) -> Self { + Self { + context: weak_context, + owner: None, + builder: CString::new("").unwrap(), + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.accelerations.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn to_hiprt(&self) -> Option { + Some(match self.builder.as_bytes() { + b"NoAccel" => hiprtBuildFlagBits::hiprtBuildFlagBitPreferFastBuild, + b"Bvh" => hiprtBuildFlagBits::hiprtBuildFlagBitPreferBalancedBuild, + // As of version 1.2.0 high quality gives crashes + b"Sbvh" | b"Trbvh" => hiprtBuildFlagBits::hiprtBuildFlagBitPreferBalancedBuild, + _ => return None, + }) + } +} + +impl OptixObjectData for AccelerationData { + const TYPE: TypeTag = TypeTag::Acceleration; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.accelerations.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) enum AccelerationOwner { + Group(Weak>), + GeometryGroup(Weak>), +} + +pub(crate) unsafe fn create( + context: Context, + acceleration: *mut Acceleration, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(acceleration)?; + *acceleration = AccelerationData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_builder( + acceleration: *const OptixCell, + builder: *const i8, +) -> Result<(), RTresult> { + null_check(builder)?; + let acceleration = null_unwrap(acceleration)?; + let mut acceleration = acceleration.borrow_mut()?; + acceleration.builder = CStr::from_ptr(builder).to_owned(); + Ok(()) +} + +pub(crate) unsafe fn mark_dirty(acceleration: Acceleration) -> Result<(), RTresult> { + let acceleration = null_unwrap(acceleration)?; + let acceleration = acceleration.borrow()?; + let context = acceleration + .context + .upgrade() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let mut context = context.borrow_mut()?; + context.invalidate(); + Ok(()) +} + +pub(crate) fn destroy(_acceleration: Acceleration) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn get_context( + acceleration: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let acceleration = null_unwrap(acceleration)?; + let acceleration = acceleration.borrow()?; + *context = acceleration.context.as_ptr(); + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::optix_test; + use crate::test_common::OptixFns; + use std::{ffi::CStr, ptr}; + + optix_test!(default_acceleration); + + unsafe fn default_acceleration(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let mut accel = ptr::null_mut(); + o.rtAccelerationCreate(ctx, &mut accel); + let mut builder = ptr::null(); + o.rtAccelerationGetBuilder(accel, &mut builder); + let builder_name = CStr::from_ptr(builder); + assert_eq!(builder_name.to_str().unwrap(), ""); + o.rtContextDestroy(ctx); + } +} diff --git a/zluda_rt/src/buffer.rs b/zluda_rt/src/buffer.rs new file mode 100644 index 0000000..6727fde --- /dev/null +++ b/zluda_rt/src/buffer.rs @@ -0,0 +1,972 @@ +use crate::{ + context::{self, Context, ContextData}, + hip, null_check, null_unwrap, null_unwrap_mut, AlignedBuffer, MaybeWeakRefMut, OptixCell, + OptixObjectData, TypeTag, +}; +use hip_runtime_sys::*; +use optix_types::*; +use std::{ + alloc::Layout, + ffi::c_void, + mem, ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Buffer = *const OptixCell; + +#[repr(C)] +pub(crate) struct DeviceBuffer { + pub(crate) pointer: hipDeviceptr_t, + pub(crate) width: u64, + pub(crate) height: u64, +} + +struct BufferAllocation { + size: u64, + pointer: hipDeviceptr_t, + host_buffer: Option, +} + +impl Drop for BufferAllocation { + #[allow(unused_must_use)] + fn drop(&mut self) { + if self.pointer.0 != ptr::null_mut() { + unsafe { hipFree(self.pointer.0) }; + } + } +} + +impl BufferAllocation { + fn empty() -> Self { + BufferAllocation { + size: 0, + pointer: hipDeviceptr_t(ptr::null_mut()), + host_buffer: None, + } + } + + fn new(this: Option, meta: BufferMetadata) -> Result<(Self, bool), RTresult> { + let size = meta.byte_size(); + if let Some(this) = this { + if size == this.size { + return Ok((this, false)); + } + } + let pointer = Self::hip_allocate(meta.allocation_size())?; + Ok(( + Self { + size, + pointer, + host_buffer: None, + }, + true, + )) + } + + fn hip_allocate(size: u64) -> Result { + Ok(if size > 0 { + let dev_ptr = hip::malloc(size as usize) + .map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED)?; + hip::zero_fill(dev_ptr, size as usize) + .map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED)?; + dev_ptr + } else { + hipDeviceptr_t(ptr::null_mut()) + }) + } + + fn map(&mut self, meta: BufferMetadata) -> Result<*mut c_void, RTresult> { + match self.host_buffer { + Some(_) => return Err(RTresult::RT_ERROR_ALREADY_MAPPED), + None => { + let layout = unsafe { + Layout::from_size_align_unchecked( + self.size as usize, + BufferMetadata::alignment(meta.format)?, + ) + }; + let buffer = if self.pointer.0 != ptr::null_mut() { + AlignedBuffer::from_hip(layout, self.pointer)? + } else { + AlignedBuffer::new(Layout::new::()) + }; + let result = buffer.as_ptr(); + self.host_buffer = Some(buffer); + Ok(result as _) + } + } + } + + fn unmap(&mut self) -> Result<(), RTresult> { + match &self.host_buffer { + None => return Err(RTresult::RT_ERROR_INVALID_VALUE), + Some(buffer) => { + if self.pointer.0 != ptr::null_mut() { + hip! {hipMemcpyHtoD(self.pointer, buffer.as_ptr(), buffer.size), RT_ERROR_MEMORY_ALLOCATION_FAILED}; + } + self.host_buffer = None; + Ok(()) + } + } + } +} + +#[derive(Copy, Clone)] +pub(crate) struct BufferMetadata { + pub(crate) format: RTformatSafe, + pub(crate) element_size: u64, + pub(crate) width: u64, + pub(crate) height: u64, +} + +impl BufferMetadata { + pub(crate) fn byte_size(&self) -> u64 { + self.width * self.height.max(1) * self.element_size + } + + // We allocate one extra element for Arnold + // Arnold 7.1.4.1 has a buggy binary search which + // returns an element one past the end + pub(crate) fn allocation_size(&self) -> u64 { + (self.width + 1) * self.height.max(1) * self.element_size + } + + fn dimensions(&self) -> u32 { + if self.height == 0 { + 1 + } else { + 2 + } + } + + fn size(&self, dim: u32) -> u64 { + match dim { + 0 => self.width, + 1 => self.height, + _ => 0, + } + } + + pub(crate) fn depth(&self) -> usize { + 0 + } + + fn element_size(format: RTformatSafe) -> Result { + Ok(match format { + RTformatSafe::RT_FORMAT_UNKNOWN => 0, + RTformatSafe::RT_FORMAT_USER => 0, + RTformatSafe::RT_FORMAT_FLOAT => mem::size_of::(), + RTformatSafe::RT_FORMAT_FLOAT2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_FLOAT3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_FLOAT4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_BYTE => mem::size_of::(), + RTformatSafe::RT_FORMAT_BYTE2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_BYTE3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_BYTE4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_UNSIGNED_BYTE => mem::size_of::(), + RTformatSafe::RT_FORMAT_UNSIGNED_BYTE2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_UNSIGNED_BYTE3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_UNSIGNED_BYTE4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_SHORT => mem::size_of::(), + RTformatSafe::RT_FORMAT_SHORT2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_SHORT3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_SHORT4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_UNSIGNED_SHORT => mem::size_of::(), + RTformatSafe::RT_FORMAT_UNSIGNED_SHORT2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_UNSIGNED_SHORT3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_UNSIGNED_SHORT4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_INT => mem::size_of::(), + RTformatSafe::RT_FORMAT_INT2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_INT3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_INT4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_UNSIGNED_INT => mem::size_of::(), + RTformatSafe::RT_FORMAT_UNSIGNED_INT2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_UNSIGNED_INT3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_UNSIGNED_INT4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_HALF => 2, + RTformatSafe::RT_FORMAT_HALF2 => 2 * 2, + RTformatSafe::RT_FORMAT_HALF3 => 2 * 3, + RTformatSafe::RT_FORMAT_HALF4 => 2 * 4, + RTformatSafe::RT_FORMAT_LONG_LONG => mem::size_of::(), + RTformatSafe::RT_FORMAT_LONG_LONG2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_LONG_LONG3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_LONG_LONG4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG => mem::size_of::(), + RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG2 => mem::size_of::() * 2, + RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG3 => mem::size_of::() * 3, + RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG4 => mem::size_of::() * 4, + RTformatSafe::RT_FORMAT_BUFFER_ID => 4, + RTformatSafe::RT_FORMAT_PROGRAM_ID => 4, + RTformatSafe::RT_FORMAT_UNSIGNED_BC1 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC2 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC3 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC4 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC4 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC5 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC5 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC6H => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC6H => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC7 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }) + } + + fn alignment(format: RTformatSafe) -> Result { + Ok(match format { + RTformatSafe::RT_FORMAT_UNKNOWN => 1, + RTformatSafe::RT_FORMAT_USER => 1, + RTformatSafe::RT_FORMAT_BYTE + | RTformatSafe::RT_FORMAT_BYTE2 + | RTformatSafe::RT_FORMAT_BYTE3 + | RTformatSafe::RT_FORMAT_BYTE4 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE2 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE3 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE4 => 1, + RTformatSafe::RT_FORMAT_SHORT + | RTformatSafe::RT_FORMAT_SHORT2 + | RTformatSafe::RT_FORMAT_SHORT3 + | RTformatSafe::RT_FORMAT_SHORT4 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT4 + | RTformatSafe::RT_FORMAT_HALF + | RTformatSafe::RT_FORMAT_HALF2 + | RTformatSafe::RT_FORMAT_HALF3 + | RTformatSafe::RT_FORMAT_HALF4 => 2, + RTformatSafe::RT_FORMAT_INT + | RTformatSafe::RT_FORMAT_INT2 + | RTformatSafe::RT_FORMAT_INT3 + | RTformatSafe::RT_FORMAT_INT4 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT + | RTformatSafe::RT_FORMAT_UNSIGNED_INT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT4 + | RTformatSafe::RT_FORMAT_FLOAT + | RTformatSafe::RT_FORMAT_FLOAT2 + | RTformatSafe::RT_FORMAT_FLOAT3 + | RTformatSafe::RT_FORMAT_FLOAT4 => 4, + RTformatSafe::RT_FORMAT_LONG_LONG + | RTformatSafe::RT_FORMAT_LONG_LONG2 + | RTformatSafe::RT_FORMAT_LONG_LONG3 + | RTformatSafe::RT_FORMAT_LONG_LONG4 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG2 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG3 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG4 => 8, + RTformatSafe::RT_FORMAT_BUFFER_ID => 4, + RTformatSafe::RT_FORMAT_PROGRAM_ID => 4, + RTformatSafe::RT_FORMAT_UNSIGNED_BC1 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC2 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC3 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC4 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC4 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC5 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC5 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC6H => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_BC6H => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + RTformatSafe::RT_FORMAT_UNSIGNED_BC7 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }) + } + + pub(crate) fn array_format(&self) -> Result { + Ok(match self.format { + RTformatSafe::RT_FORMAT_FLOAT + | RTformatSafe::RT_FORMAT_FLOAT2 + | RTformatSafe::RT_FORMAT_FLOAT3 + | RTformatSafe::RT_FORMAT_FLOAT4 => hipArray_Format::HIP_AD_FORMAT_FLOAT, + RTformatSafe::RT_FORMAT_BYTE + | RTformatSafe::RT_FORMAT_BYTE2 + | RTformatSafe::RT_FORMAT_BYTE3 + | RTformatSafe::RT_FORMAT_BYTE4 => hipArray_Format::HIP_AD_FORMAT_SIGNED_INT8, + RTformatSafe::RT_FORMAT_UNSIGNED_BYTE + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE2 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE3 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE4 => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT8 + } + RTformatSafe::RT_FORMAT_SHORT + | RTformatSafe::RT_FORMAT_SHORT2 + | RTformatSafe::RT_FORMAT_SHORT3 + | RTformatSafe::RT_FORMAT_SHORT4 => hipArray_Format::HIP_AD_FORMAT_SIGNED_INT16, + RTformatSafe::RT_FORMAT_UNSIGNED_SHORT + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT4 => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT16 + } + RTformatSafe::RT_FORMAT_INT + | RTformatSafe::RT_FORMAT_INT2 + | RTformatSafe::RT_FORMAT_INT3 + | RTformatSafe::RT_FORMAT_INT4 => hipArray_Format::HIP_AD_FORMAT_SIGNED_INT32, + RTformatSafe::RT_FORMAT_UNSIGNED_INT + | RTformatSafe::RT_FORMAT_UNSIGNED_INT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT4 => { + hipArray_Format::HIP_AD_FORMAT_UNSIGNED_INT32 + } + RTformatSafe::RT_FORMAT_HALF + | RTformatSafe::RT_FORMAT_HALF2 + | RTformatSafe::RT_FORMAT_HALF3 + | RTformatSafe::RT_FORMAT_HALF4 => hipArray_Format::HIP_AD_FORMAT_HALF, + RTformatSafe::RT_FORMAT_LONG_LONG + | RTformatSafe::RT_FORMAT_LONG_LONG2 + | RTformatSafe::RT_FORMAT_LONG_LONG3 + | RTformatSafe::RT_FORMAT_LONG_LONG4 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG2 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG3 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG4 => { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED) + } + RTformatSafe::RT_FORMAT_UNKNOWN + | RTformatSafe::RT_FORMAT_USER + | RTformatSafe::RT_FORMAT_BUFFER_ID + | RTformatSafe::RT_FORMAT_PROGRAM_ID => return Err(RTresult::RT_ERROR_INVALID_CONTEXT), + RTformatSafe::RT_FORMAT_UNSIGNED_BC1 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC2 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC3 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC4 + | RTformatSafe::RT_FORMAT_BC4 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC5 + | RTformatSafe::RT_FORMAT_BC5 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC6H + | RTformatSafe::RT_FORMAT_BC6H + | RTformatSafe::RT_FORMAT_UNSIGNED_BC7 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }) + } + + pub(crate) fn channels(&self) -> Result { + Ok(match self.format { + RTformatSafe::RT_FORMAT_UNKNOWN + | RTformatSafe::RT_FORMAT_USER + | RTformatSafe::RT_FORMAT_BUFFER_ID + | RTformatSafe::RT_FORMAT_PROGRAM_ID + | RTformatSafe::RT_FORMAT_FLOAT + | RTformatSafe::RT_FORMAT_BYTE + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE + | RTformatSafe::RT_FORMAT_SHORT + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT + | RTformatSafe::RT_FORMAT_INT + | RTformatSafe::RT_FORMAT_UNSIGNED_INT + | RTformatSafe::RT_FORMAT_HALF + | RTformatSafe::RT_FORMAT_LONG_LONG + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG => 1, + RTformatSafe::RT_FORMAT_FLOAT2 + | RTformatSafe::RT_FORMAT_BYTE2 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE2 + | RTformatSafe::RT_FORMAT_SHORT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT2 + | RTformatSafe::RT_FORMAT_INT2 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT2 + | RTformatSafe::RT_FORMAT_HALF2 + | RTformatSafe::RT_FORMAT_LONG_LONG2 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG2 => 2, + RTformatSafe::RT_FORMAT_FLOAT3 + | RTformatSafe::RT_FORMAT_BYTE3 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE3 + | RTformatSafe::RT_FORMAT_SHORT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT3 + | RTformatSafe::RT_FORMAT_INT3 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT3 + | RTformatSafe::RT_FORMAT_HALF3 + | RTformatSafe::RT_FORMAT_LONG_LONG3 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG3 => 3, + RTformatSafe::RT_FORMAT_FLOAT4 + | RTformatSafe::RT_FORMAT_BYTE4 + | RTformatSafe::RT_FORMAT_UNSIGNED_BYTE4 + | RTformatSafe::RT_FORMAT_SHORT4 + | RTformatSafe::RT_FORMAT_UNSIGNED_SHORT4 + | RTformatSafe::RT_FORMAT_INT4 + | RTformatSafe::RT_FORMAT_UNSIGNED_INT4 + | RTformatSafe::RT_FORMAT_HALF4 + | RTformatSafe::RT_FORMAT_LONG_LONG4 + | RTformatSafe::RT_FORMAT_UNSIGNED_LONG_LONG4 => 4, + RTformatSafe::RT_FORMAT_UNSIGNED_BC1 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC2 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC3 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC4 + | RTformatSafe::RT_FORMAT_BC4 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC5 + | RTformatSafe::RT_FORMAT_BC5 + | RTformatSafe::RT_FORMAT_UNSIGNED_BC6H + | RTformatSafe::RT_FORMAT_BC6H + | RTformatSafe::RT_FORMAT_UNSIGNED_BC7 => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }) + } + + fn next_mip(self) -> Self { + Self { + format: self.format, + element_size: self.element_size, + width: (self.width / 2).max(1), + height: (self.height / 2).max(1), + } + } + + fn generate_mips(self) -> impl Iterator { + std::iter::repeat(()).scan(self, |metadata, _| { + let result = *metadata; + *metadata = metadata.next_mip(); + Some(result) + }) + } +} + +struct OnDemandAllocation { + mip_levels: u32, + alloc: BufferAllocation, + callback_data: *mut ::std::os::raw::c_void, + callback: unsafe extern "C" fn( + callback_data: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> ::std::os::raw::c_int, +} + +enum BufferStorage { + Normal(Vec), + FromCallback(OnDemandAllocation), +} + +pub(crate) struct BufferData { + pub(crate) context: Weak>, + pub(crate) metadata: BufferMetadata, + alloc: BufferStorage, + pub(crate) index: u32, +} + +impl OptixObjectData for BufferData { + const TYPE: TypeTag = TypeTag::Buffer; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.buffers.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +impl BufferData { + fn new(weak_context: Weak>, context: &mut ContextData) -> Self { + context.buffers_counter += 1; + let metadata = BufferMetadata { + format: RTformatSafe::RT_FORMAT_BYTE, + element_size: 1, + width: 0, + height: 0, + }; + Self { + context: weak_context, + index: context.buffers_counter, + metadata, + alloc: BufferStorage::Normal(vec![BufferAllocation::empty()]), + } + } + + fn new_from_callback( + weak_context: Weak>, + context: &mut ContextData, + callback: unsafe extern "C" fn( + callback_data: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> i32, + callback_data: *mut ::std::os::raw::c_void, + ) -> Self { + context.buffers_counter += 1; + let metadata = BufferMetadata { + format: RTformatSafe::RT_FORMAT_BYTE, + element_size: 1, + width: 0, + height: 0, + }; + Self { + context: weak_context, + index: context.buffers_counter, + metadata, + alloc: BufferStorage::FromCallback(OnDemandAllocation { + mip_levels: 1, + alloc: BufferAllocation::empty(), + callback_data, + callback, + }), + } + } + + fn alloc0(&self) -> &BufferAllocation { + match &self.alloc { + BufferStorage::Normal(alloc) => &alloc[0], + BufferStorage::FromCallback(on_demand) => &on_demand.alloc, + } + } + + fn propagate_size_change(&mut self) -> Result<(), RTresult> { + match self.alloc { + BufferStorage::Normal(ref mut alloc) => { + for (alloc, metadata) in alloc.iter_mut().zip(self.metadata.generate_mips()) { + let alloc_copy = mem::replace(alloc, BufferAllocation::empty()); + *alloc = BufferAllocation::new(Some(alloc_copy), metadata)?.0; + } + } + BufferStorage::FromCallback(_) => {} + } + Ok(()) + } + + // We do all this dance because callback function can and does call various buffer functions (eg rtBufferGetSize2D) + pub(crate) fn load_from_callback(this: &Rc>) -> Result<(), RTresult> { + let needs_copy = { + let mut this = this.borrow_mut_no_invalidate()?; + let metadata = this.metadata; + match this.alloc { + BufferStorage::Normal(_) => return Ok(()), + BufferStorage::FromCallback(ref mut alloc) => { + let alloc_copy = mem::replace(&mut alloc.alloc, BufferAllocation::empty()); + let (new_alloc, needs_copy) = + BufferAllocation::new(Some(alloc_copy), metadata)?; + alloc.alloc = new_alloc; + if needs_copy { + Some((alloc.callback, alloc.callback_data, metadata)) + } else { + None + } + } + } + }; + if let Some((callback, callback_data, metadata)) = needs_copy { + let layout = unsafe { + Layout::from_size_align_unchecked( + metadata.byte_size() as usize, + BufferMetadata::alignment(metadata.format)?, + ) + }; + let mut buffer = AlignedBuffer::new(layout); + let mut block = RTmemoryblock { + format: metadata.format.into(), + baseAddress: buffer.as_bytes_mut().as_mut_ptr().cast(), + mipLevel: 0u32, + x: 0, + y: 0, + z: 0, + width: metadata.width as u32, + height: metadata.height.max(1) as u32, + depth: metadata.depth().max(1) as u32, + rowPitch: (metadata.width * metadata.element_size) as u32, + planePitch: 0, + }; + if unsafe { (callback)(callback_data, Rc::as_ptr(this), &mut block) } == 0 { + return Err(RTresult::RT_ERROR_UNKNOWN); + } + let mut this = this.borrow_mut()?; + let alloc = match this.alloc { + BufferStorage::Normal(_) => return Err(RTresult::RT_ERROR_UNKNOWN), + BufferStorage::FromCallback(ref mut alloc) => alloc, + }; + hip! { hipMemcpyHtoD(alloc.alloc.pointer, buffer.as_ptr(), metadata.byte_size() as usize), RT_ERROR_UNKNOWN }; + } + Ok(()) + } + + fn register(this: Rc>, context: &mut ContextData) { + context.buffers.insert(this); + } + + fn map_ex(&mut self, level: u32) -> Result<*mut c_void, RTresult> { + match self.alloc { + BufferStorage::Normal(ref mut alloc) => { + let alloc = alloc + .get_mut(level as usize) + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + alloc.map(self.metadata) + } + BufferStorage::FromCallback(_) => Err(RTresult::RT_ERROR_UNKNOWN), + } + } + + fn unmap_ex(&mut self, level: u32) -> Result<(), RTresult> { + match self.alloc { + BufferStorage::Normal(ref mut alloc) => { + let alloc = alloc + .get_mut(level as usize) + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + alloc.unmap() + } + BufferStorage::FromCallback(_) => Err(RTresult::RT_ERROR_UNKNOWN), + } + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, BufferData::new, BufferData::register) + } + + unsafe fn create_from_callback( + context: Context, + callback: unsafe extern "C" fn( + callback_data: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> i32, + callback_data: *mut ::std::os::raw::c_void, + ) -> Result { + context::create_subobject( + context, + |weak_context, context| { + BufferData::new_from_callback(weak_context, context, callback, callback_data) + }, + BufferData::register, + ) + } + + pub(crate) fn get_device_mip0(&self) -> DeviceBuffer { + let alloc = &self.alloc0(); + DeviceBuffer { + pointer: alloc.pointer, + width: self.metadata.width, + height: self.metadata.height, + } + } + + pub(crate) fn pointer_mip0(&self) -> hipDeviceptr_t { + self.alloc0().pointer + } +} + +pub(crate) unsafe fn create( + context: Context, + _bufferdesc: u32, + buffer: *mut Buffer, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(buffer)?; + *buffer = BufferData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn create_from_callback( + context: Context, + _bufferdesc: ::std::os::raw::c_uint, + callback: Option< + unsafe extern "C" fn( + callbackData: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> ::std::os::raw::c_int, + >, + callback_data: *mut ::std::os::raw::c_void, + buffer: *mut Buffer, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(buffer)?; + let callback = callback.ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + *buffer = BufferData::create_from_callback(context, callback, callback_data)?; + Ok(()) +} + +pub(crate) unsafe fn destroy(buffer: Buffer) -> Result<(), RTresult> { + OptixCell::destroy(buffer) +} + +pub(crate) unsafe fn get_dimensionality( + buffer: Buffer, + dimensionality: *mut u32, +) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer)?; + let dimensionality = null_unwrap_mut(dimensionality)?; + let buffer = buffer.borrow()?; + *dimensionality = buffer.metadata.dimensions(); + Ok(()) +} + +pub(crate) unsafe fn get_format(buffer: Buffer, format: *mut RTformat) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer)?; + let format = null_unwrap_mut(format)?; + let buffer = buffer.borrow()?; + *format = RTformat(buffer.metadata.format as u32); + Ok(()) +} + +pub(crate) unsafe fn get_size1d(buffer: Buffer, width: *mut u64) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer)?; + let width = null_unwrap_mut(width)?; + let buffer = buffer.borrow()?; + *width = buffer.metadata.size(0); + Ok(()) +} + +pub(crate) unsafe fn set_format(buffer_ptr: Buffer, format: RTformat) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer_ptr)?; + let mut buffer = buffer.borrow_mut()?; + buffer.metadata.format = RTformatSafe::new(format).ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + buffer.metadata.element_size = BufferMetadata::element_size(buffer.metadata.format)? as u64; + buffer.propagate_size_change()?; + Ok(()) +} + +pub(crate) unsafe fn set_size1d(buffer_ptr: Buffer, width: u64) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer_ptr)?; + let mut buffer = buffer.borrow_mut()?; + buffer.metadata.width = width; + buffer.metadata.height = 0; + buffer.propagate_size_change()?; + Ok(()) +} + +pub(crate) unsafe fn set_size2d( + buffer_ptr: Buffer, + width: u64, + height: u64, +) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer_ptr)?; + let mut buffer = buffer.borrow_mut()?; + buffer.metadata.width = width; + buffer.metadata.height = height; + buffer.propagate_size_change()?; + Ok(()) +} + +pub(crate) unsafe fn get_context(buffer: Buffer, context: *mut Context) -> Result<(), RTresult> { + null_check(context)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + *context = Weak::as_ptr(&buffer.context); + Ok(()) +} + +pub(crate) unsafe fn get_size2d( + buffer: Buffer, + width: *mut u64, + height: *mut u64, +) -> Result<(), RTresult> { + null_check(width)?; + null_check(height)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + *width = buffer.metadata.width; + *height = buffer.metadata.height; + Ok(()) +} + +pub(crate) unsafe fn map(buffer: Buffer, user_pointer: *mut *mut c_void) -> Result<(), RTresult> { + map_ex( + buffer, + RTbuffermapflag::RT_BUFFER_MAP_READ_WRITE.0, + 0, + ptr::null_mut(), + user_pointer, + ) +} + +pub(crate) unsafe fn unmap(buffer: Buffer) -> Result<(), RTresult> { + unmap_ex(buffer, 0) +} + +pub(crate) unsafe fn get_glboid(_buffer: Buffer, glid: *mut u32) -> Result<(), RTresult> { + null_check(glid)?; + *glid = 0; + Ok(()) +} + +pub(crate) unsafe fn map_ex( + buffer: Buffer, + _map_flags: u32, + level: u32, + user_owned: *mut c_void, + optix_owned: *mut *mut c_void, +) -> Result<(), RTresult> { + if user_owned != ptr::null_mut() { + return Err(RTresult::RT_ERROR_INVALID_VALUE); + } + + null_check(optix_owned)?; + let buffer = null_unwrap(buffer)?; + let mut buffer = buffer.borrow_mut_no_invalidate()?; + *optix_owned = buffer.map_ex(level)?; + Ok(()) +} + +pub(crate) unsafe fn unmap_ex(buffer: Buffer, level: u32) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer)?; + let mut buffer = buffer.borrow_mut_no_invalidate()?; + buffer.unmap_ex(level) +} + +pub(crate) unsafe fn get_element_size( + buffer: Buffer, + element_size: *mut u64, +) -> Result<(), RTresult> { + null_check(element_size)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + *element_size = buffer.metadata.element_size; + Ok(()) +} + +pub(crate) unsafe fn set_element_size( + buffer_ptr: Buffer, + element_size: u64, +) -> Result<(), RTresult> { + if element_size == 0 { + return Err(RTresult::RT_ERROR_INVALID_VALUE); + } + let buffer = null_unwrap(buffer_ptr)?; + let mut buffer = buffer.borrow_mut()?; + if buffer.metadata.format != RTformatSafe::RT_FORMAT_USER { + return Ok(()); + } + buffer.metadata.element_size = element_size; + buffer.propagate_size_change()?; + Ok(()) +} + +pub(crate) unsafe fn get_id(buffer: Buffer, buffer_id: *mut i32) -> Result<(), RTresult> { + null_check(buffer_id)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + *buffer_id = buffer.index as i32; + Ok(()) +} + +pub(crate) unsafe fn get_miplevel_count(buffer: Buffer, level: *mut u32) -> Result<(), RTresult> { + null_check(level)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + let buffer_levels = match &buffer.alloc { + BufferStorage::Normal(alloc) => alloc.len() as u32, + BufferStorage::FromCallback(alloc) => alloc.mip_levels, + }; + *level = buffer_levels; + Ok(()) +} + +pub(crate) unsafe fn get_sizev( + buffer: Buffer, + dimensionality: u32, + dims: *mut u64, +) -> Result<(), RTresult> { + null_check(dims)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + for d in 0..dimensionality { + let size = match d { + 0 => buffer.metadata.width, + 1 => buffer.metadata.height, + _ => 0, + }; + *dims.add(d as usize) = size; + } + Ok(()) +} + +pub(crate) unsafe fn get_device_pointer( + buffer: Buffer, + _optix_device_ordinal: i32, + device_pointer: *mut *mut c_void, +) -> Result<(), RTresult> { + null_check(device_pointer)?; + let buffer = null_unwrap(buffer)?; + let buffer = buffer.borrow()?; + *device_pointer = buffer.alloc0().pointer.0; + Ok(()) +} + +pub(crate) unsafe fn set_mip_level_count(buffer: Buffer, levels: u32) -> Result<(), RTresult> { + let buffer = null_unwrap(buffer)?; + let mut buffer = buffer.borrow_mut()?; + let levels = levels as usize; + let metadata = buffer.metadata; + let alloc = match &mut buffer.alloc { + BufferStorage::Normal(alloc) => alloc, + // TODO: implement MIP levels when mipmapped textures work in HIP + BufferStorage::FromCallback(alloc) => { + alloc.mip_levels = levels as u32; + return Ok(()); + } + }; + if levels <= alloc.len() { + alloc.truncate(levels); + return Ok(()); + } + let mut meta_generator = metadata.generate_mips().skip(alloc.len()); + for _ in alloc.len()..levels { + let metadata = meta_generator.next().unwrap(); + alloc.push(BufferAllocation::new(None, metadata)?.0); + } + Ok(()) +} + +pub(crate) unsafe fn get_miplevel_size2d( + buffer: Buffer, + level: u32, + width: *mut u64, + height: *mut u64, +) -> Result<(), RTresult> { + if level != 0 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + get_size2d(buffer, width, height) +} + +#[cfg(test)] +mod tests { + use crate::optix_test; + use crate::test_common::OptixFns; + use optix_types::*; + use std::{mem, ptr}; + + optix_test!(new_buffer); + + unsafe fn new_buffer(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let mut buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut buffer); + let mut dims = mem::zeroed(); + o.rtBufferGetDimensionality(buffer, &mut dims); + assert_eq!(dims, 1); + let mut format = mem::zeroed(); + o.rtBufferGetFormat(buffer, &mut format); + assert_eq!(format, RTformat::RT_FORMAT_BYTE); + let mut size = mem::zeroed(); + o.rtBufferGetSize1D(buffer, &mut size); + assert_eq!(size, 0); + let mut dim_buffer = [164, 2, 3]; + o.rtBufferGetSizev(buffer, 3, dim_buffer.as_mut_ptr()); + assert_eq!(dim_buffer, [0, 0, 0]); + o.rtBufferDestroy(buffer); + o.rtContextDestroy(ctx); + } + + optix_test!(empty_buffer_can_be_mapped); + + unsafe fn empty_buffer_can_be_mapped(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let mut buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut buffer); + o.rtBufferSetFormat(buffer, RTformat::RT_FORMAT_PROGRAM_ID); + let mut dims = mem::zeroed(); + o.rtBufferGetDimensionality(buffer, &mut dims); + assert_eq!(dims, 1); + let mut size = mem::zeroed(); + o.rtBufferGetSize1D(buffer, &mut size); + assert_eq!(size, 0); + let mut host_ptr = ptr::null_mut(); + o.rtBufferMapEx( + buffer, + RTbuffermapflag::RT_BUFFER_MAP_READ_WRITE.0, + 0, + ptr::null_mut(), + &mut host_ptr, + ); + assert_ne!(host_ptr, ptr::null_mut()); + o.rtBufferUnmapEx(buffer, 0); + o.rtBufferDestroy(buffer); + o.rtContextDestroy(ctx); + } +} diff --git a/zluda_rt/src/cache.rs b/zluda_rt/src/cache.rs new file mode 100644 index 0000000..f9876a9 --- /dev/null +++ b/zluda_rt/src/cache.rs @@ -0,0 +1,281 @@ +use crate::context::ContextData; +use crate::{OptixCell, ProgramData}; +use data_encoding::HEXLOWER; +use hip_common::raytracing::VariablesBlock; +use hip_common::unwrap_or_return; +use rustc_hash::FxHashMap; +use sha2::{Digest, Sha512}; +use std::collections::BTreeMap; +use std::ffi::{CStr, CString}; +use std::path::{Path, PathBuf}; +use std::rc::Weak; +use std::time::{self, SystemTime}; + +pub(crate) struct KernelRepository(hip_common::cache::KernelRepository); + +impl KernelRepository { + pub(crate) fn new(cache_file: PathBuf) -> rusqlite::Result { + Ok(Self(hip_common::cache::KernelRepository::new(Some( + cache_file, + ))?)) + } + + #[cfg(test)] + pub(crate) fn new_in_memory() -> rusqlite::Result { + Ok(Self(hip_common::cache::KernelRepository::new(None)?)) + } + + pub(crate) fn save_program( + &mut self, + now: i64, + program_name: &CStr, + hash: &str, + compiler_version: &str, + git_hash: &str, + device: &CStr, + binary: &[u8], + input_attributes: &str, + hiprt_version: &str, + ) -> rusqlite::Result<()> { + self.0.save_program( + now, + hash, + compiler_version, + git_hash, + device, + binary, + rusqlite::params![ + hip_common::cache::SqlCStrRef(program_name), + input_attributes, + hiprt_version + ], + ) + } + + fn try_load_program( + &mut self, + now: i64, + program_name: &CStr, + hash: &str, + compiler_version: &str, + git_hash: &str, + device: &CStr, + input_attributes: &str, + hiprt_version: &str, + ) -> rusqlite::Result>> { + self.0.try_load_program( + now, + hash, + compiler_version, + git_hash, + device, + rusqlite::params![ + hip_common::cache::SqlCStrRef(program_name), + input_attributes, + hiprt_version + ], + ) + } +} + +pub(crate) struct KernelCache(KernelRepository); + +impl KernelCache { + pub(crate) const OPTIX6_CACHE_FILE: &'static str = "zluda_optix6.db"; + + pub(crate) fn new(cache_dir: &Path) -> Option { + let mut file = cache_dir.to_path_buf(); + file.push(Self::OPTIX6_CACHE_FILE); + Some(Self(KernelRepository::new(file).ok()?)) + } + + pub(crate) fn save_program( + &mut self, + compiler_version: &str, + hiprt_version: &str, + isa: &CStr, + program_name: &CStr, + ptx: &str, + prog: &ProgramData, + input_attributes: &VariablesBlock, + ) { + let now = unwrap_or_return!(SystemTime::now().duration_since(time::UNIX_EPOCH)).as_millis() + as i64; + let mut hasher = Sha512::new(); + hasher.update(ptx); + let hash = hasher.finalize(); + let hash = HEXLOWER.encode(&hash[..]); + let git_hash = env!("VERGEN_GIT_SHA"); + let attributes = unwrap_or_return!(Self::serialize_input_attributes( + &input_attributes.variables + )); + self.0 + .save_program( + now, + program_name, + &hash, + compiler_version, + git_hash, + isa, + &prog.shared.binary, + &attributes, + hiprt_version, + ) + .ok(); + } + + pub(crate) fn try_load_program( + &mut self, + weak_context: Weak>, + compiler_version: &str, + hiprt_version: &str, + isa: &CStr, + program_name: &CStr, + ptx: &str, + input_attributes: &VariablesBlock, + ) -> Option<(ProgramData, VariablesBlock)> { + let now = SystemTime::now() + .duration_since(time::UNIX_EPOCH) + .ok()? + .as_millis() as i64; + let mut hasher = Sha512::new(); + hasher.update(ptx); + let hash = hasher.finalize(); + let hash = HEXLOWER.encode(&hash[..]); + let git_hash = env!("VERGEN_GIT_SHA"); + let attributes = Self::serialize_input_attributes(&input_attributes.variables).ok()?; + let binary = self + .0 + .try_load_program( + now, + program_name, + &hash, + compiler_version, + git_hash, + isa, + &attributes, + hiprt_version, + ) + .ok()??; + ProgramData::try_from_binary(weak_context, binary) + } + + fn serialize_input_attributes( + attributes: &FxHashMap, + ) -> serde_json::Result { + let sorted_attrbutes = attributes.iter().collect::>(); + serde_json::to_string(&serialize::VariablesMapSerialize2 { + variables: sorted_attrbutes, + }) + } +} + +impl Drop for KernelCache { + fn drop(&mut self) { + if let Ok(connection) = self.0 .0.connect() { + connection.execute_batch("VACUUM;").ok(); + } + } +} + +struct RaytracingDataExtension; + +impl hip_common::cache::KernelExtendedData for RaytracingDataExtension { + const INPUT_COLUMNS: &'static [[&'static str; 2]] = &[ + ["name", "TEXT NOT NULL"], + ["input_attributes", "TEXT NOT NULL"], + ["hiprt_version", "TEXT NOT NULL"], + ]; +} + +pub(crate) mod serialize { + use serde::{Deserialize, Serialize}; + use serde_with::{serde_as, SerializeAs}; + use std::collections::BTreeMap; + use std::ffi::CString; + + #[serde_as] + #[derive(serde::Serialize)] + #[serde(transparent)] + pub(crate) struct VariablesMapSerialize2<'a> { + #[serde_as(as = "BTreeMap")] + pub(crate) variables: BTreeMap<&'a CString, &'a hip_common::raytracing::Variable>, + } + + struct AsString; + + impl SerializeAs<&CString> for AsString { + fn serialize_as(value: &&CString, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(value.to_str().unwrap()) + } + } + + #[derive(Serialize, Deserialize)] + #[serde(remote = "hip_common::raytracing::Variable")] + pub(crate) struct Variable { + pub size: u32, + pub offset: u32, + pub default_value: Vec, + } + + impl SerializeAs for Variable { + fn serialize_as( + value: &hip_common::raytracing::Variable, + serializer: S, + ) -> Result + where + S: serde::Serializer, + { + Variable::serialize(value, serializer) + } + } +} + +#[cfg(test)] +mod tests { + use super::KernelRepository; + use std::ffi::CString; + + #[test] + fn kernel_insert_select() { + let mut cache = KernelRepository::new_in_memory().unwrap(); + let input_attributes = "{TEST}"; + cache + .save_program( + 1, + &*CString::new("start").unwrap(), + "FFFF", + "Clang 15", + "EEEE", + &*CString::new("gfx1030").unwrap(), + &vec![0x11, 0x12, 0x13, 0x14], + &input_attributes, + "1.2", + ) + .unwrap(); + assert_eq!(get_time(&mut cache.0.connect().unwrap()), 1); + let binary = cache + .try_load_program( + 2, + CString::new("start").unwrap().as_c_str(), + "FFFF", + "Clang 15", + "EEEE", + &*CString::new("gfx1030").unwrap(), + input_attributes, + "1.2", + ) + .unwrap() + .unwrap(); + assert_eq!(binary, vec![0x11, 0x12, 0x13, 0x14]); + } + + fn get_time(connection: &mut rusqlite::Connection) -> i64 { + connection + .query_row("SELECT last_used FROM kernels", [], |row| row.get(0)) + .unwrap() + } +} diff --git a/zluda_rt/src/context.rs b/zluda_rt/src/context.rs new file mode 100644 index 0000000..6973751 --- /dev/null +++ b/zluda_rt/src/context.rs @@ -0,0 +1,698 @@ +use crate::{ + acceleration::AccelerationData, + buffer::{Buffer, BufferData, DeviceBuffer}, + cache::KernelCache, + definitions, div_positive_round_up, + geometry::GeometryData, + geometry_group::GeometryGroupData, + geometry_instance::GeometryInstanceData, + geometry_triangles::GeometryTrianglesData, + group::GroupData, + hip, hiprt, + material::MaterialData, + null_check, null_unwrap, null_unwrap_mut, + program::{self, Program, ProgramData}, + repr_gpu::{self, Scene, TrivialHIPAllocator}, + texture_sampler::TextureSamplerData, + transform::TransformData, + variable::{Variable, VariableData}, + MaybeWeakRefMut, OptixCell, OptixObjectData, RcHashSet, TypeTag, +}; +use comgr::Comgr; +use hip_common::raytracing::VariablesBlock; +use hip_runtime_sys::*; +use hiprt_sys::*; +use optix_types::*; +use rustc_hash::FxHashMap; +use std::{ + ffi::{CStr, CString}, + fs, + mem::{self, ManuallyDrop}, + path::PathBuf, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Context = *const OptixCell; + +pub(crate) struct ContextData { + pub(crate) hip_context: hipCtx_t, + pub(crate) hiprt: Rc, + pub(crate) ray_type_count: u32, + pub(crate) geometry_group_count: u32, + pub(crate) context: hiprtContext, + pub(crate) comgr: Rc, + pub(crate) isa: CString, + pub(crate) buffers: RcHashSet>, + pub(crate) buffers_counter: u32, + pub(crate) variables: FxHashMap>>, + pub(crate) programs: RcHashSet>, + pub(crate) callable_program_counter: u32, + pub(crate) cumulative_attributes: VariablesBlock, + pub(crate) materials: RcHashSet>, + pub(crate) geometry: RcHashSet>, + pub(crate) geometry_triangles: RcHashSet>, + pub(crate) geometry_instances: RcHashSet>, + pub(crate) geometry_groups: RcHashSet>, + pub(crate) groups: RcHashSet>, + pub(crate) accelerations: RcHashSet>, + pub(crate) texture_samplers: RcHashSet>, + pub(crate) transforms: RcHashSet>, + pub(crate) texture_counter: u32, + pub(crate) entry_points: Vec>>>, + pub(crate) exception_programs: Vec>>>, + pub(crate) miss_programs: Vec>>>, + disk_cache_location: PathBuf, + pub(crate) optix_salt: [u8; 32], + pub(crate) vendor_salt: [u8; 32], + pub(crate) public_vendor_key: Vec, + pub(crate) cache: Option, + pub(crate) compiler_version: String, + pub(crate) hiprt_version: String, + pub(crate) scene_rebuild_pending: bool, + pub(crate) scene: Scene, + pub(crate) global_stack: GlobalStack, +} + +// 16kB is the maximum allowed in rocm 5.4 and seems to be enough for Arnold +const MAX_GPU_STACK: usize = 16 * 1_024; + +impl ContextData { + pub(crate) fn new() -> Result { + hip! { hipInit(0), RT_ERROR_CONTEXT_CREATION_FAILED }; + let comgr = comgr::Comgr::find_and_load() + .map_err(|_| RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + let mut stack_size = 0; + hip! { hipDeviceGetLimit(&mut stack_size, hipLimit_t::hipLimitStackSize), RT_ERROR_CONTEXT_CREATION_FAILED }; + if stack_size < MAX_GPU_STACK { + hip! { hipDeviceSetLimit(hipLimit_t::hipLimitStackSize, MAX_GPU_STACK), RT_ERROR_CONTEXT_CREATION_FAILED }; + } + let mut hip_context = ptr::null_mut(); + hip! { hipCtxCreate(&mut hip_context, 0, 0), RT_ERROR_CONTEXT_CREATION_FAILED }; + let mut context_input = hiprtContextCreationInput { + ctxt: hip_context as _, + device: 0, + deviceType: hiprtDeviceType::hiprtDeviceAMD, + }; + let hiprt = + unsafe { HipRt::load() }.map_err(|_| RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + let mut context = ptr::null_mut(); + hiprt! { + hiprt.hiprtCreateContext(HIPRT_API_VERSION, &mut context_input, &mut context), + RT_ERROR_CONTEXT_CREATION_FAILED + }; + let isa = unsafe { + hip_common::comgr_isa(0).map_err(|_| RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)? + }; + let hiprt_version = hiprt::HIPRT_API_VERSION.to_string(); + let compiler_version = comgr + .version() + .map_err(|_| RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + let mut disk_cache_location = + dirs::cache_dir().ok_or(RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + disk_cache_location.push("ZLUDA"); + disk_cache_location.push("OptixCache"); + fs::create_dir_all(&disk_cache_location) + .map_err(|_| RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + let cache = KernelCache::new(&disk_cache_location) + .ok_or(RTresult::RT_ERROR_CONTEXT_CREATION_FAILED)?; + Ok(ContextData { + hip_context, + hiprt: Rc::new(hiprt), + context, + ray_type_count: 0, + geometry_group_count: 0, + comgr: Rc::new(comgr), + buffers: RcHashSet::new(), + buffers_counter: 0, + variables: FxHashMap::default(), + programs: RcHashSet::new(), + callable_program_counter: 0, + cumulative_attributes: VariablesBlock::empty(), + materials: RcHashSet::new(), + geometry: RcHashSet::new(), + geometry_triangles: RcHashSet::new(), + geometry_instances: RcHashSet::new(), + geometry_groups: RcHashSet::new(), + transforms: RcHashSet::new(), + groups: RcHashSet::new(), + accelerations: RcHashSet::new(), + texture_samplers: RcHashSet::new(), + texture_counter: 0, + entry_points: Vec::new(), + exception_programs: Vec::new(), + miss_programs: Vec::new(), + isa, + disk_cache_location, + optix_salt: [0; 32], + vendor_salt: [0; 32], + public_vendor_key: Vec::new(), + cache: Some(cache), + compiler_version, + hiprt_version, + scene_rebuild_pending: true, + scene: Scene::empty(), + global_stack: GlobalStack::empty(), + }) + } + + pub fn attributes_layout(&self) -> (u16, u16) { + let size = div_positive_round_up( + self.cumulative_attributes.layout.size() as u64, + mem::size_of::() as u64, + ); + let align = div_positive_round_up( + self.cumulative_attributes.layout.align() as u64, + mem::size_of::() as u64, + ); + (size as u16, align as u16) + } + + pub fn allocate_miss_programs( + &self, + allocator: &mut TrivialHIPAllocator, + ) -> Result { + let call_chain_visitor = repr_gpu::MissProgramsVisitCallChain { + context: self, + miss_programs: &self.miss_programs, + }; + let chain_layout = repr_gpu::get_layout(0, &call_chain_visitor)?; + let chain_on_gpu = allocator.allocate(chain_layout.layout.size())?; + repr_gpu::copy_to_gpu(0, &call_chain_visitor, &chain_layout, chain_on_gpu)?; + Ok(chain_on_gpu) + } + + pub fn allocate_callable_programs( + &self, + allocator: &mut TrivialHIPAllocator, + ) -> Result { + let visitor = repr_gpu::CallableProgramsVisitor::new(self)?; + let chain_layout = repr_gpu::get_layout(self.ray_type_count, &visitor)?; + let dev_ptr = allocator.allocate(chain_layout.layout.size())?; + repr_gpu::copy_to_gpu(self.ray_type_count, &visitor, &chain_layout, dev_ptr)?; + Ok(dev_ptr) + } + + pub fn allocate_buffers( + &self, + allocator: &mut TrivialHIPAllocator, + ) -> Result { + let mut buffers = (0..self.buffers_counter + 1) + .into_iter() + .map(|_| unsafe { mem::zeroed::() }) + .collect::>(); + // We allocate this additional buffer for bug compatiblity with OptiX + // Arnold has a bug where it tries to access buffer with id = 0 + // On OptiX this returns NULL pointer. Furthermore, in OptiX, dereferencing + // an invalid pointer returns zeros. We emulate this behavior by returning + // this zero-filled buffer. It actually works well enough to run Arnold + let page_zero = allocator.allocate(1024 * 4)?; + hip! { hipMemset(page_zero.0, 0, 1024 * 4), RT_ERROR_MEMORY_ALLOCATION_FAILED }; + buffers[0] = DeviceBuffer { + pointer: page_zero, + width: 1024, + height: 0, + }; + for buffer in self.buffers.iter() { + let buffer = buffer.borrow()?; + buffers[buffer.index as usize] = buffer.get_device_mip0(); + } + allocator.copy_to_device(&buffers[..]) + } + + pub fn get_uv_offset(&self) -> Result { + let uv_offset = self + .cumulative_attributes + .variables + .get(unsafe { CStr::from_bytes_with_nul_unchecked(b"rtTriangleBarycentrics\0") }) + .map(|var| var.offset) + .unwrap_or(!0u32); + Ok(uv_offset) + } + + pub fn invalidate(&mut self) { + self.scene_rebuild_pending = true; + } + + pub(crate) fn buffers_load_from_callback(&mut self) -> Result<(), RTresult> { + for buffer_rc in self.buffers.iter() { + BufferData::load_from_callback(buffer_rc)?; + } + Ok(()) + } +} + +impl Drop for ContextData { + #[allow(unused_must_use)] + fn drop(&mut self) { + unsafe { + self.hiprt.hiprtDestroyContext(self.context); + hipCtxDestroy(self.hip_context); + } + } +} + +impl OptixObjectData for ContextData { + const TYPE: TypeTag = TypeTag::Context; + + fn deregister(&mut self, _this: &Rc>) -> Result<(), RTresult> { + Err(RTresult::RT_ERROR_UNKNOWN) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Ref(self) + } +} + +pub(crate) struct GlobalStack { + pointer: hipDeviceptr_t, + thread_space: usize, +} + +impl GlobalStack { + pub(crate) const THREAD_STACK_DEPTH: u16 = 512; + + fn empty() -> GlobalStack { + GlobalStack { + pointer: hipDeviceptr_t(ptr::null_mut()), + thread_space: 0, + } + } + + fn reallocate(&mut self, width: u32, height: u32) -> Result<(), RTresult> { + let (grid_dim_x, block_dim_x) = program::get_launch_dimensions_x(width)?; + let thread_space = grid_dim_x as usize * block_dim_x as usize * height as usize; + if thread_space <= self.thread_space { + return Ok(()); + } + hip::free(self.pointer).map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED)?; + self.pointer = + hip::malloc(thread_space * Self::THREAD_STACK_DEPTH as usize * mem::size_of::()) + .map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED)?; + self.thread_space = thread_space; + Ok(()) + } +} + +pub(crate) unsafe fn get_error_string( + _context: Context, + _code: RTresult, + string_return: *mut *const i8, +) { + *string_return = b"\0".as_ptr() as _; +} + +pub(crate) unsafe fn set_entry_point_count(context: Context, count: u32) -> Result<(), RTresult> { + let context = null_unwrap(context)?; + let mut context = (*context).borrow_mut()?; + context.entry_points.resize(count as usize, None); + context.exception_programs.resize(count as usize, None); + Ok(()) +} + +pub(crate) unsafe fn set_ray_type_count( + context: Context, + ray_type_count: u32, +) -> Result<(), RTresult> { + let context = null_unwrap(context)?; + let mut context = context.borrow_mut()?; + context.ray_type_count = ray_type_count; + context.miss_programs.resize(ray_type_count as usize, None); + Ok(()) +} + +pub(crate) unsafe fn create(context: *mut Context) -> Result<(), RTresult> { + null_check(context)?; + *context = Rc::into_raw(Rc::new(OptixCell::new(ContextData::new()?))) as *mut _; + Ok(()) +} + +pub(crate) unsafe fn destroy(context: Context) -> Result<(), RTresult> { + null_check(context)?; + Rc::from_raw(context); + Ok(()) +} + +pub(crate) unsafe fn declare_variable( + context_ptr: Context, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + let v = null_unwrap_mut(v)?; + let context = null_unwrap(context_ptr)?; + let variable = VariableData::new_with_context(context)?; + let mut context = context.borrow_mut()?; + let name = CStr::from_ptr(name as _).to_owned(); + let result = Rc::as_ptr(&variable); + context.variables.insert(name, variable); + *v = result; + Ok(()) +} + +// TODO: implement +pub(crate) fn validate(_context: Context) -> Result<(), RTresult> { + Ok(()) +} + +pub(crate) unsafe fn set_ray_generation_program( + context: Context, + entry_point_index: u32, + program: Program, +) -> Result<(), RTresult> { + set_program(context, entry_point_index, program, |ctx| { + &mut ctx.entry_points + }) +} + +pub(crate) unsafe fn set_exception_program( + context: Context, + entry_point_index: u32, + program: Program, +) -> Result<(), RTresult> { + set_program(context, entry_point_index, program, |ctx| { + &mut ctx.exception_programs + }) +} + +unsafe fn set_program( + context: Context, + entry_point_index: u32, + program: Program, + setter: F, +) -> Result<(), RTresult> +where + F: for<'a> FnOnce(&'a mut ContextData) -> &'a mut Vec>>>, +{ + let context = null_unwrap(context)?; + let mut context = (*context).borrow_mut()?; + match setter(&mut context).get_mut(entry_point_index as usize) { + None => Err(RTresult::RT_ERROR_INVALID_VALUE), + Some(context_entry) => { + let program = ManuallyDrop::new(Rc::from_raw(program)); + *context_entry = Some((&*program).clone()); + Ok(()) + } + } +} + +pub(crate) unsafe fn set_miss_program( + context: Context, + ray_type_index: u32, + program: Program, +) -> Result<(), RTresult> { + set_program(context, ray_type_index, program, |ctx| { + &mut ctx.miss_programs + }) +} + +pub(crate) unsafe fn launch_2d( + context: Context, + entry_point_index: u32, + width: u64, + height: u64, +) -> Result<(), RTresult> { + if width > u32::MAX as u64 || height > u32::MAX as u64 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let context = null_unwrap(context)?; + let mut context = (context).borrow_mut_no_invalidate()?; + context.buffers_load_from_callback()?; + if context.scene_rebuild_pending { + context.scene = Scene::new(&context)?; + context.scene_rebuild_pending = false; + } + if width == 0 || height == 0 { + return Ok(()); + } + context + .global_stack + .reallocate(width as u32, height as u32)?; + let main_program = context + .entry_points + .get(entry_point_index as usize) + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)? + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + let main_program = main_program.borrow()?; + let exception_program = context + .exception_programs + .get(entry_point_index as usize) + .map(Option::as_ref) + .flatten() + .map(Rc::as_ref) + .map(OptixCell::borrow) + .transpose()?; + context.scene.launch_2d( + entry_point_index, + &main_program, + exception_program, + width as u32, + height as u32, + context.global_stack.pointer, + ) +} + +pub(crate) unsafe fn create_subobject( + context: Context, + constructor: impl FnOnce(Weak>, &mut ContextData) -> T, + register: impl FnOnce(Rc>, &mut ContextData), +) -> Result<*const OptixCell, RTresult> { + let context = ManuallyDrop::new(Rc::from_raw(context)); + let weak_context = Rc::downgrade(&context); + let mut context = (**context).borrow_mut()?; + let object = Rc::new(OptixCell::new(constructor(weak_context, &mut context))); + let result = Rc::as_ptr(&object); + register(object, &mut *context); + Ok(result) +} + +pub(crate) fn set_stack_size(_context: Context, _bytes: u64) -> Result<(), RTresult> { + Ok(()) +} + +pub(crate) fn set_max_depth(_context: Context, _max_depth: u32) -> Result<(), RTresult> { + Ok(()) +} + +pub(crate) unsafe fn query_variable( + context: Context, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let context = null_unwrap(context)?; + let context = (context).borrow()?; + *v = context + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) unsafe fn set_attribute( + context: Context, + attrib: RTcontextattribute, + size: u64, + p: *const std::ffi::c_void, +) -> Result<(), RTresult> { + null_check(p)?; + match attrib { + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION => { + let context = null_unwrap(context)?; + let mut context = OptixCell::borrow_mut_no_invalidate(context)?; + let cache_location = CStr::from_ptr(p as _); + let cache_location = cache_location + .to_str() + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let cache_location = PathBuf::from(cache_location); + let cache = KernelCache::new(&cache_location).ok_or(RTresult::RT_ERROR_UNKNOWN)?; + context.disk_cache_location = cache_location; + context.cache = Some(cache); + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_DISK_CACHE_ENABLED => { + if size != mem::size_of::() as u64 { + return Err(RTresult::RT_ERROR_INVALID_VALUE); + } + let value = p as *const u32; + let context = null_unwrap(context)?; + let mut context = OptixCell::borrow_mut_no_invalidate(context)?; + if *value == 0 { + context.cache = None; + } else { + context.cache = Some( + KernelCache::new(&context.disk_cache_location) + .ok_or(RTresult::RT_ERROR_UNKNOWN)?, + ); + } + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_PREFER_FAST_RECOMPILES => {} + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_PREFER_WATERTIGHT_TRAVERSAL => {} + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_PUBLIC_VENDOR_KEY => { + let context = null_unwrap(context)?; + let mut context = OptixCell::borrow_mut_no_invalidate(context)?; + context.public_vendor_key = + std::slice::from_raw_parts(p as *const u8, size as usize).to_vec(); + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_VENDOR_SALT => { + if size != 32 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let context = null_unwrap(context)?; + let mut context = OptixCell::borrow_mut_no_invalidate(context)?; + context.vendor_salt = *(p as *const [u8; 32]); + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_OPTIX_SALT => { + if size != 32 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let context = null_unwrap(context)?; + let mut context = OptixCell::borrow_mut_no_invalidate(context)?; + context.optix_salt = *(p as *const [u8; 32]); + } + // TODO: implement + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_DISK_CACHE_MEMORY_LIMITS => {} + // TODO: reverse + RTcontextattribute(15) + | RTcontextattribute(16) + | RTcontextattribute(17) + | RTcontextattribute(33554454) => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + _ => return Err(definitions::unimplemented()), + } + Ok(()) +} + +pub(crate) fn set_max_callable_program_depth(_context: Context, _max_depth: u32) -> RTresult { + RTresult::RT_SUCCESS +} + +pub(crate) unsafe fn get_attribute( + context: Context, + attrib: RTcontextattribute, + size: u64, + p: *mut std::ffi::c_void, +) -> Result<(), RTresult> { + null_check(p)?; + match attrib { + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_DISK_CACHE_LOCATION => { + let context = null_unwrap(context)?; + let context = OptixCell::borrow(context)?; + let cache = context + .disk_cache_location + .to_str() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + *(p as *mut _) = cache.as_ptr(); + } + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_OPTIX_SALT => { + if size != 32 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let context = null_unwrap(context)?; + let context = OptixCell::borrow(context)?; + *(p as *mut [u8; 32]) = context.optix_salt; + } + _ => return Err(definitions::unimplemented()), + } + Ok(()) +} + +pub(crate) unsafe fn set_devices( + context: Context, + count: u32, + devices: *const i32, +) -> Result<(), RTresult> { + null_check(context)?; + if count != 1 { + return Err(definitions::unimplemented()); + } + if *devices != 0 { + return Err(definitions::unimplemented()); + } + Ok(()) +} + +pub(crate) fn set_exception_enabled( + context: Context, + _exception: RTexception, + _enabled: i32, +) -> Result<(), RTresult> { + null_check(context)?; + Ok(()) +} + +pub(crate) fn set_print_enabled( + context: *const OptixCell, + _enabled: i32, +) -> Result<(), RTresult> { + null_check(context)?; + Ok(()) +} + +pub(crate) fn set_usage_report_callback( + context: *const OptixCell, + _callback: RTusagereportcallback, + _verbosity: i32, + _cbdata: *mut std::ffi::c_void, +) -> Result<(), RTresult> { + null_check(context)?; + Ok(()) +} + +pub(crate) fn set_print_launch_index( + context: *const OptixCell, + _x: i32, + _y: i32, + _z: i32, +) -> Result<(), RTresult> { + null_check(context)?; + Ok(()) +} + +pub(crate) unsafe fn get_device_count(context: Context, count: *mut u32) -> Result<(), RTresult> { + null_check(context)?; + *count = 1; + Ok(()) +} + +pub(crate) unsafe fn get_devices(context: Context, devices: *mut i32) -> Result<(), RTresult> { + null_check(context)?; + *devices = 0; + Ok(()) +} + +// Used only during Arnold deinitialization +pub(crate) unsafe fn get_buffer_from_id( + context: Context, + buffer_id: i32, + buffer_output: *mut Buffer, +) -> Result<(), RTresult> { + null_check(buffer_output)?; + let context = null_unwrap(context)?; + let context = context.borrow()?; + for buffer_rc in context.buffers.iter() { + let buffer = buffer_rc.borrow()?; + if buffer.index == (buffer_id as u32) { + *buffer_output = Rc::as_ptr(buffer_rc); + return Ok(()); + } + } + *buffer_output = ptr::null_mut(); + Err(RTresult::RT_ERROR_INVALID_VALUE) +} + +#[cfg(test)] +mod tests { + use crate::optix_test; + use crate::test_common::OptixFns; + use std::ptr; + + optix_test!(create_destroy_context); + + unsafe fn create_destroy_context(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + o.rtContextDestroy(ctx); + } +} diff --git a/zluda_rt/src/eptx.rs b/zluda_rt/src/eptx.rs new file mode 100644 index 0000000..85d4d55 --- /dev/null +++ b/zluda_rt/src/eptx.rs @@ -0,0 +1,109 @@ +use generic_array::arr; +use generic_array::GenericArray; +use sha2::Digest; +use sha2::Sha256; +use std::convert::TryInto; +use std::io::Write; +use std::mem; +use std::u8; +use typenum::{U16, U2, U32}; + +const OPTIX_KEY: &'static [u8] = + b"-3343556356fgfgfdessss-(--9355-489795-2333354:[]}}{[]523552%GWEf"; + +const REMAINDER_KEY: [u8; 7] = [164, 195, 147, 255, 203, 161, 184]; + +pub(crate) fn decode_ptx<'a>( + content: &'a mut [u8], + optix_salt: &[u8], + vendor_salt: &[u8], + vendor_key: &[u8], +) -> &'a mut [u8] { + let content = normalize(content); + let concatenated_key = [&vendor_key[..], &OPTIX_KEY[..]].concat(); + let hashed_key = sha256(&concatenated_key[..]); + let hexed_key = to_hex_string(hashed_key); + let session_key_input = [&optix_salt[..], &hexed_key[..], &vendor_salt[..]].concat(); + let mut hashed_session_key = sha256(&session_key_input[..]); + let reduced_key = reduce_key(&mut hashed_session_key); + decode(content, &*reduced_key); + decode_remainder(content); + content +} + +fn decode(content: &mut [u8], reduced_key: &GenericArray) { + for i in 0..content.len() / 8 { + let block = &mut content[i * 8..i * 8 + 8]; + unsafe { decrypt_block(block.try_into().unwrap(), reduced_key) }; + } +} + +fn decode_remainder(content: &mut [u8]) { + let remainer_start = (content.len() / 8) * 8; + for i in 0..content.len() % 8 { + content[remainer_start + i] = content[remainer_start + i] ^ REMAINDER_KEY[i]; + } +} + +fn sha256(content: &[u8]) -> GenericArray { + let mut hasher = Sha256::new(); + hasher.update(content); + hasher.finalize() +} + +fn to_hex_string(hash: GenericArray) -> [u8; 64] { + let mut result = [0u8; 64]; + for (idx, c) in hash.into_iter().enumerate() { + write!(&mut result[idx * 2..idx * 2 + 2], "{:02x}", c).unwrap(); + } + result +} + +fn reduce_key<'a>(content: &'a mut GenericArray) -> &'a mut GenericArray { + for i in 0usize..16 { + content[i] = content[i].wrapping_add(content[i + 16]); + } + GenericArray::from_mut_slice(&mut content.as_mut_slice()[..16]) +} + +unsafe fn decrypt_block(block: &mut [u8; 8], key: &GenericArray) { + let delta: u32 = 0x9E3779B9; + let mut sum: u32 = 0xE3779B90; + let v = mem::transmute::<[u8; 8], [u32; 2]>(*block); + let mut v0 = v[0]; + let mut v1 = v[1]; + let key = key.as_ptr() as *const u32; + let k0 = *key.offset(0); + let k1 = *key.offset(1); + let k2 = *key.offset(2); + let k3 = *key.offset(3); + for _ in 0..16 { + v1 = v1.wrapping_sub( + ((v0 << 4).wrapping_add(k2)) ^ (v0.wrapping_add(sum)) ^ ((v0 >> 5).wrapping_add(k3)), + ); + v0 = v0.wrapping_sub( + ((v1 << 4).wrapping_add(k0)) ^ (v1.wrapping_add(sum)) ^ ((v1 >> 5).wrapping_add(k1)), + ); + sum = sum.wrapping_sub(delta) + } + *block = std::mem::transmute::, [u8; 8]>(arr![u32; v0, v1]); +} + +fn normalize<'a>(content: &'a mut [u8]) -> &'a mut [u8] { + let mut to = 0; + let mut from = 8; + loop { + if from >= content.len() { + break; + } + let mut c = content[from]; + if c == 1 { + from += 1; + c = content[from] - 1; + } + content[to] = c; + from += 1; + to += 1; + } + &mut content[0..to] +} diff --git a/zluda_rt/src/geometry.rs b/zluda_rt/src/geometry.rs new file mode 100644 index 0000000..04437fb --- /dev/null +++ b/zluda_rt/src/geometry.rs @@ -0,0 +1,147 @@ +use crate::{ + context::{self, Context, ContextData}, + null_check, null_unwrap, + program::{Program, ProgramData}, + variable::{Variable, VariableData}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use optix_types::*; +use rustc_hash::FxHashMap; +use std::{ + ffi::{CStr, CString}, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Geometry = *const OptixCell; + +pub(crate) struct GeometryData { + pub(crate) context: Weak>, + pub(crate) program_intersection: Option>>, + pub(crate) program_bounding_box: Option>>, + pub(crate) variables: FxHashMap>>, + pub(crate) primitive_count: u32, +} + +impl GeometryData { + fn new(_context: Weak>, _: &mut ContextData) -> Self { + Self { + context: _context, + program_intersection: None, + program_bounding_box: None, + variables: FxHashMap::default(), + primitive_count: 0, + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.geometry.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } +} + +impl OptixObjectData for GeometryData { + const TYPE: TypeTag = TypeTag::Geometry; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.geometry.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) unsafe fn create(context: Context, geometry: *mut Geometry) -> Result<(), RTresult> { + null_check(context)?; + null_check(geometry)?; + *geometry = GeometryData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_primitive_count( + geometry: Geometry, + primitive_count: u32, +) -> Result<(), RTresult> { + let geometry = null_unwrap(geometry)?; + let mut geometry = geometry.borrow_mut()?; + geometry.primitive_count = primitive_count; + Ok(()) +} + +pub(crate) unsafe fn set_bounding_box_program( + geometry: Geometry, + program: Program, +) -> Result<(), RTresult> { + null_check(program)?; + let geometry = null_unwrap(geometry)?; + let mut geometry = geometry.borrow_mut()?; + geometry.program_bounding_box = Some(OptixCell::clone_weak(program)); + Ok(()) +} + +pub(crate) unsafe fn set_intersection_program( + geometry: Geometry, + program: Program, +) -> Result<(), RTresult> { + null_check(program)?; + let geometry = null_unwrap(geometry)?; + let mut geometry = geometry.borrow_mut()?; + geometry.program_intersection = Some(OptixCell::clone_weak(program)); + Ok(()) +} + +pub(crate) unsafe fn declare_variable( + geometry: Geometry, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(v)?; + let instance = null_unwrap(geometry)?; + let mut material = instance.borrow_mut()?; + let variable = VariableData::new(&mut *material)?; + let name = CStr::from_ptr(name).to_owned(); + let result = Rc::as_ptr(&variable); + material.variables.insert(name, variable); + *v = result; + Ok(()) +} + +pub(crate) unsafe fn query_variable( + geometry: Geometry, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let geometry = null_unwrap(geometry)?; + let geometry = (geometry).borrow()?; + *v = geometry + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) fn destroy(_geometry: Geometry) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn get_context( + geometry: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let geometry = null_unwrap(geometry)?; + let geometry = geometry.borrow()?; + *context = geometry.context.as_ptr(); + Ok(()) +} diff --git a/zluda_rt/src/geometry_group.rs b/zluda_rt/src/geometry_group.rs new file mode 100644 index 0000000..2e127ac --- /dev/null +++ b/zluda_rt/src/geometry_group.rs @@ -0,0 +1,316 @@ +use crate::{ + acceleration::{Acceleration, AccelerationData, AccelerationOwner}, + context::{self, Context, ContextData}, + geometry_instance::{DeviceGeometryInstance, GeometryInstance, GeometryInstanceData}, + hip, hiprt, null_check, null_unwrap, + repr_gpu::{self, TrivialHIPAllocator}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use hip_runtime_sys::*; +use hiprt_sys::*; +use optix_types::*; +use std::{ + alloc::Layout, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type GeometryGroup = *const OptixCell; + +pub(crate) struct GeometryGroupData { + pub(crate) context: Weak>, + pub(crate) acceleration: Option>>, + pub(crate) children: Vec>>>, + pub(crate) index: u32, + pub(crate) visibility: u32, +} + +impl GeometryGroupData { + fn new(weak_context: Weak>, context: &mut ContextData) -> Self { + let index = context.geometry_group_count; + context.geometry_group_count += 1; + Self { + context: weak_context, + acceleration: None, + children: Vec::new(), + index, + visibility: !0u32, + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.geometry_groups.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn prepare_globals( + &self, + allocator: &mut TrivialHIPAllocator, + ctx: &ContextData, + global_state: &mut repr_gpu::GlobalState, + ) -> Result { + let ray_type_count = ctx.ray_type_count; + let acceleration = self + .acceleration + .as_ref() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let acceleration = acceleration.borrow()?; + let build_flags = acceleration.to_hiprt().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let mut hiprt_instances_host = Vec::with_capacity(self.children.len()); + let custom_func_table = allocator.new_func_table()?; + let mut custom_func_set_counter = 0u32; + let attribute_visitor = repr_gpu::AttributesVisitCallChain { + context: ctx, + children: &*self.children, + }; + let attribute_chain_layout = repr_gpu::get_layout(ray_type_count, &attribute_visitor)?; + let attribute_call_chain = allocator.allocate(attribute_chain_layout.layout.size())?; + repr_gpu::copy_to_gpu( + ray_type_count, + &attribute_visitor, + &attribute_chain_layout, + attribute_call_chain, + )?; + let hit_chains = (0..ray_type_count).map(|ray| { + let prologue_layout = Layout::new::(); + let any_hit_visitor = repr_gpu::HitProgramsVisitCallChain { + closest_hit: false, + ray, + children: &self.children, + context: ctx, + }; + let closest_hit_visitor = repr_gpu::HitProgramsVisitCallChain { + closest_hit: true, + ray, + children: &self.children, + context: ctx, + }; + let any_hit_chain_layout = repr_gpu::get_layout(ray_type_count, &any_hit_visitor)?; + let closest_hit_chain_layout = repr_gpu::get_layout(ray_type_count, &closest_hit_visitor)?; + let with_any_hit = prologue_layout + .extend(any_hit_chain_layout.layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let with_closest_hit = with_any_hit + .0 + .extend(closest_hit_chain_layout.layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let hit_chain_gpu = allocator.allocate(with_closest_hit.0.size())?; + let prolog = repr_gpu::HitProgramChain { + any_hit_start: with_any_hit.1 as u32, + closest_hit_start: with_closest_hit.1 as u32, + }; + hip! { hipMemcpyHtoD(hit_chain_gpu, &prolog as *const _ as _, prologue_layout.size()), RT_ERROR_UNKNOWN }; + repr_gpu::copy_to_gpu( + ray_type_count, + &any_hit_visitor, + &any_hit_chain_layout, + hipDeviceptr_t(unsafe { hit_chain_gpu.0.cast::().add(with_any_hit.1).cast() }), + )?; + repr_gpu::copy_to_gpu( + ray_type_count, + &closest_hit_visitor, + &closest_hit_chain_layout, + hipDeviceptr_t(unsafe { + hit_chain_gpu.0.cast::().add(with_closest_hit.1).cast() + }), + )?; + Ok(hit_chain_gpu) + }).collect::, _>>()?; + for instance in self.children.iter() { + let instance = instance.as_ref().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let instance = instance.borrow()?; + match instance.prepare_globals( + allocator, + ctx, + build_flags, + ray_type_count, + custom_func_set_counter, + global_state, + hipDeviceptr_t(ptr::null_mut()), + )? { + DeviceGeometryInstance::Geometry { + custom_func_set, + hiprt_geometry, + } => { + hiprt_instances_host.push(hiprt_geometry); + hiprt! { ctx.hiprt.hiprtSetCustomFuncTable(ctx.context, custom_func_table, custom_func_set_counter, custom_func_set), RT_ERROR_UNKNOWN }; + custom_func_set_counter += 1; + } + DeviceGeometryInstance::GeometryTriangles { hiprt_geometry } => { + hiprt_instances_host.push(hiprt_geometry); + } + }; + } + let instance_frames_host = vec![ + hiprtFrame { + translation: hiprtFloat3 { + x: 0f32, + y: 0f32, + z: 0f32, + }, + scale: hiprtFloat3 { + x: 1f32, + y: 1f32, + z: 1f32, + }, + rotation: hiprtFloat4 { + x: 0f32, + y: 0f32, + z: 1.0f32, + w: 0f32, + }, + time: 0f32, + pad: 0, + }; + self.children.len() + ]; + let instance_geometries = allocator.copy_to_device(&hiprt_instances_host[..])?; + let instance_frames = allocator.copy_to_device(&instance_frames_host[..])?; + let instance_mask_host = vec![self.visibility; self.children.len()]; + let instance_masks = allocator.copy_to_device(&instance_mask_host[..])?; + let scene_input = hiprtSceneBuildInput { + instanceCount: self.children.len() as u32, + instanceGeometries: instance_geometries.0, + frameCount: self.children.len() as u32, + instanceFrames: instance_frames.0, + nodes: ptr::null_mut(), + instanceTransformHeaders: ptr::null_mut(), + instanceMasks: instance_masks.0, + }; + let build_options = hiprtBuildOptions { + buildFlags: build_flags.0, + }; + let transform_blocks = vec![hipDeviceptr_t(ptr::null_mut()); self.children.len()]; + let transform_blocks = allocator.copy_to_device(&transform_blocks)?; + let hit_chains = allocator.copy_to_device(&hit_chains)?; + let scene = allocator.new_scene(scene_input, build_options)?; + Ok(BvhDetails { + scene, + attribute_call_chain, + func_set: custom_func_table, + transform_blocks, + hit_chains, + }) + } +} + +impl OptixObjectData for GeometryGroupData { + const TYPE: TypeTag = TypeTag::GeometryGroup; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.geometry_groups.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +#[repr(C)] +pub(crate) struct BvhDetails { + pub(crate) scene: hiprtScene, + pub(crate) func_set: hiprtCustomFuncTable, + pub(crate) attribute_call_chain: hipDeviceptr_t, + pub(crate) transform_blocks: hipDeviceptr_t, + pub(crate) hit_chains: hipDeviceptr_t, +} + +pub(crate) unsafe fn create( + context: Context, + geometry_group: *mut GeometryGroup, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(geometry_group)?; + *geometry_group = GeometryGroupData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_acceleration( + geometry_group: GeometryGroup, + acceleration: Acceleration, +) -> Result<(), RTresult> { + null_check(acceleration)?; + let geometry_group = null_unwrap(geometry_group)?; + let acceleration = null_unwrap(acceleration)?; + { + let mut geometry_group = geometry_group.borrow_mut()?; + geometry_group.acceleration = Some(OptixCell::clone_rc(acceleration)); + } + { + let mut acceleration = acceleration.borrow_mut()?; + acceleration.owner = Some(AccelerationOwner::GeometryGroup(OptixCell::clone_weak( + geometry_group, + ))); + } + Ok(()) +} + +pub(crate) unsafe fn set_child( + geometry_group: GeometryGroup, + index: u32, + geometry_instance: GeometryInstance, +) -> Result<(), RTresult> { + null_check(geometry_instance)?; + let geometry_group = null_unwrap(geometry_group)?; + let mut geometry_group = geometry_group.borrow_mut()?; + match geometry_group.children.get_mut(index as usize) { + Some(instance_slot) => { + *instance_slot = Some(OptixCell::clone_rc(geometry_instance)); + Ok(()) + } + None => Err(RTresult::RT_ERROR_INVALID_VALUE), + } +} + +pub(crate) unsafe fn set_child_count( + geometry_group: GeometryGroup, + count: u32, +) -> Result<(), RTresult> { + let geometry_group = null_unwrap(geometry_group)?; + let mut geometry_group = geometry_group.borrow_mut()?; + geometry_group.children.resize(count as usize, None); + Ok(()) +} + +pub(crate) unsafe fn get_child_count( + geometry_group: GeometryGroup, + count: *mut u32, +) -> Result<(), RTresult> { + null_check(count)?; + let geometry_group = null_unwrap(geometry_group)?; + let geometry_group = geometry_group.borrow()?; + *count = geometry_group.children.len() as u32; + Ok(()) +} + +pub(crate) unsafe fn set_visibility_mask( + geometry_group: *const OptixCell, + mask: u32, +) -> Result<(), RTresult> { + let geometry_group = null_unwrap(geometry_group)?; + let mut geometry_group = geometry_group.borrow_mut()?; + geometry_group.visibility = mask; + Ok(()) +} + +pub(crate) unsafe fn get_context( + geometrygroup: GeometryGroup, + context: *mut Context, +) -> Result<(), RTresult> { + let geometrygroup = null_unwrap(geometrygroup)?; + let geometrygroup = geometrygroup.borrow()?; + *context = geometrygroup.context.as_ptr(); + Ok(()) +} + +pub(crate) fn destroy(_geometrygroup: GeometryGroup) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} diff --git a/zluda_rt/src/geometry_instance.rs b/zluda_rt/src/geometry_instance.rs new file mode 100644 index 0000000..a748c9d --- /dev/null +++ b/zluda_rt/src/geometry_instance.rs @@ -0,0 +1,411 @@ +use crate::{ + context::{self, Context, ContextData}, + geometry::{Geometry, GeometryData}, + geometry_triangles::{GeometryTriangles, GeometryTrianglesData}, + hip, + material::{Material, MaterialData}, + null_check, null_unwrap, + program::ProgramData, + repr_gpu::{self, TrivialHIPAllocator}, + variable::{Variable, VariableData}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use hip_runtime_sys::*; +use hiprt_sys::*; +use optix_types::*; +use rustc_hash::FxHashMap; +use std::{ + alloc::{Layout, LayoutError}, + ffi::{c_void, CStr, CString}, + mem, ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type GeometryInstance = *const OptixCell; + +pub(crate) struct GeometryInstanceData { + pub(crate) context: Weak>, + pub(crate) child: GeometryInstanceChild, + pub(crate) materials: Vec>>>, + pub(crate) variables: FxHashMap>>, +} + +impl GeometryInstanceData { + fn new(weak_context: Weak>, _: &mut ContextData) -> Self { + Self { + context: weak_context, + child: GeometryInstanceChild::None, + materials: Vec::new(), + variables: FxHashMap::default(), + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.geometry_instances.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn prepare_globals( + &self, + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + build_flags: hiprtBuildFlagBits, + ray_type_count: u32, + custom_func_set_counter: u32, + global_state: &mut repr_gpu::GlobalState, + transform_block: hipDeviceptr_t, + ) -> Result { + match self.child { + GeometryInstanceChild::None => return Err(RTresult::RT_ERROR_INVALID_CONTEXT), + GeometryInstanceChild::Geometry(ref geometry) => self.prepare_custom_geometry( + allocator, + context, + build_flags, + ray_type_count, + custom_func_set_counter, + geometry, + transform_block, + global_state + ), + GeometryInstanceChild::GeometryTriangles(ref triangles) => { + self.prepare_triangles(allocator, build_flags, triangles) + } + } + } + + fn prepare_custom_geometry( + &self, + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + build_flags: hiprtBuildFlagBits, + ray_type_count: u32, + custom_func_set_counter: u32, + geometry: &Rc>, + transform_block: hipDeviceptr_t, + global_state: &mut repr_gpu::GlobalState + ) -> Result { + let geometry = geometry.borrow()?; + let program_intersection = geometry + .program_intersection + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let program_intersection = program_intersection + .upgrade() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let program_intersection = program_intersection.borrow()?; + let program_bounding_box = geometry + .program_bounding_box + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let program_bounding_box = program_bounding_box + .upgrade() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let program_bounding_box = program_bounding_box.borrow()?; + let mut bb_variable_block = program_bounding_box + .prepare_variable_block_for_function_non_hit(allocator, self, &geometry, context)?; + let intersection_input = self.prepare_intersection_input( + allocator, + context, + ray_type_count, + &*program_intersection, + &*geometry, + transform_block, + )?; + let intersect_func = program_intersection.get_function()?; + let mut bounding_box_fn = program_bounding_box.get_function()?; + let custom_func_set = hiprtCustomFuncSet { + intersectFunc: unsafe { mem::transmute(intersect_func) }, + intersectFuncData: intersection_input.0, + }; + let mut bounding_box_primitive_count = geometry.primitive_count; + let kernel_bounding_box = program_bounding_box + .shared + .module + .get_function(ProgramData::KERNEL_BOUNDING_BOX_NAME) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let mut bounding_boxes_device = allocator + .allocate(mem::size_of::() * 8 * bounding_box_primitive_count as usize)?; + let mut params = [ + global_state as *mut repr_gpu::GlobalState as *mut c_void, + &mut bounding_box_fn as *mut _ as *mut c_void, + &mut bounding_box_primitive_count as *mut _ as _, + &mut bounding_boxes_device.0 as *mut _ as _, + &mut bb_variable_block as *mut _ as _, + ]; + program_bounding_box + .shared + .module + .launch_kernel_1d( + kernel_bounding_box, + bounding_box_primitive_count, + 0, + ptr::null_mut(), + params.as_mut_ptr(), + ) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let mut aabb_list = hiprtAABBListPrimitive { + aabbs: bounding_boxes_device.0, + aabbCount: bounding_box_primitive_count, + aabbStride: (mem::size_of::() * 8) as u32, + }; + let geometry_input = hiprtGeometryBuildInput { + type_: hiprtPrimitiveType::hiprtPrimitiveTypeAABBList, + __bindgen_anon_1: hiprtGeometryBuildInput__bindgen_ty_1 { + aabbList: hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_2 { + primitive: &mut aabb_list, + customType: custom_func_set_counter, + }, + }, + nodes: ptr::null_mut(), + }; + let build_options = hiprtBuildOptions { + buildFlags: build_flags.0, + }; + let hiprt_geometry = allocator.new_geometry(geometry_input, build_options)?; + Ok(DeviceGeometryInstance::Geometry { + hiprt_geometry: hipDeviceptr_t(hiprt_geometry), + custom_func_set, + }) + } + + fn prepare_intersection_input( + &self, + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + ray_type_count: u32, + program: &ProgramData, + geometry: &GeometryData, + transform_block: hipDeviceptr_t, + ) -> Result { + let visitor = repr_gpu::IntersectVisitCallChain { + context, + geometry_instance: self, + }; + let layout_var_block = program.variables_block.layout; + let call_chain_layout = repr_gpu::get_layout(ray_type_count, &visitor)?; + let (total_layout, offsets) = + Self::layout_of_struct([layout_var_block, call_chain_layout.layout].iter().copied()) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let intersection_input = allocator.allocate(total_layout.size())?; + let prologue = repr_gpu::IntersectionInput { + transform_block, + materials_start: offsets[1] as u32, + }; + let mut staging_var_block = vec![0u8; layout_var_block.size()]; + unsafe { ptr::copy_nonoverlapping(&prologue, staging_var_block.as_mut_ptr() as _, 1) }; + ProgramData::copy_variable_block( + &program.variables_block, + &mut staging_var_block, + |var_name| program.get_variable_for_function_non_hit(self, geometry, context, var_name), + )?; + hip! { hipMemcpyHtoD(intersection_input, staging_var_block.as_mut_ptr() as _, layout_var_block.size()), RT_ERROR_UNKNOWN }; + repr_gpu::copy_to_gpu( + ray_type_count, + &visitor, + &call_chain_layout, + hipDeviceptr_t(unsafe { intersection_input.0.cast::().add(offsets[1]).cast() }), + )?; + Ok(intersection_input) + } + + fn layout_of_struct( + mut fields: impl Iterator, + ) -> Result<(Layout, Vec), LayoutError> { + fields.try_fold( + (Layout::new::<()>(), Vec::new()), + |(total_layout, mut offsets), layout| { + let (new_layout, offset) = total_layout.extend(layout)?; + offsets.push(offset); + Ok((new_layout, offsets)) + }, + ) + } + + fn prepare_triangles( + &self, + allocator: &mut TrivialHIPAllocator, + build_flags: hiprtBuildFlagBits, + triangles: &Rc>, + ) -> Result { + let triangles = triangles.borrow()?; + let mut primitive = triangles.to_hiprt()?; + let geometry_input = hiprtGeometryBuildInput { + type_: hiprtPrimitiveType::hiprtPrimitiveTypeTriangleMesh, + __bindgen_anon_1: hiprtGeometryBuildInput__bindgen_ty_1 { + triangleMesh: hiprtGeometryBuildInput__bindgen_ty_1__bindgen_ty_1 { + primitive: &mut primitive, + }, + }, + nodes: ptr::null_mut(), + }; + let build_options = hiprtBuildOptions { + buildFlags: build_flags.0, + }; + let hiprt_geometry = allocator.new_geometry(geometry_input, build_options)?; + Ok(DeviceGeometryInstance::GeometryTriangles { + hiprt_geometry: hipDeviceptr_t(hiprt_geometry), + }) + } +} + +impl OptixObjectData for GeometryInstanceData { + const TYPE: TypeTag = TypeTag::GeometryInstance; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.geometry_instances.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) enum DeviceGeometryInstance { + Geometry { + hiprt_geometry: hipDeviceptr_t, + custom_func_set: hiprtCustomFuncSet, + }, + GeometryTriangles { + hiprt_geometry: hipDeviceptr_t, + }, +} + +pub(crate) enum GeometryInstanceChild { + None, + Geometry(Rc>), + GeometryTriangles(Rc>), +} + +#[repr(C)] +#[derive(Clone)] +pub(crate) struct DeviceProgram { + pub(crate) function: hipDeviceptr_t, + pub(crate) variable_block: hipDeviceptr_t, +} + +pub(crate) unsafe fn create( + context: Context, + material: *mut GeometryInstance, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(material)?; + *material = GeometryInstanceData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_geometry_triangles( + instance: GeometryInstance, + triangles: GeometryTriangles, +) -> Result<(), RTresult> { + null_check(triangles)?; + let instance = null_unwrap(instance)?; + let mut instance = instance.borrow_mut()?; + let triangles = OptixCell::clone_rc(triangles); + instance.child = GeometryInstanceChild::GeometryTriangles(triangles); + Ok(()) +} + +pub(crate) unsafe fn set_geometry( + instance: GeometryInstance, + geometry: Geometry, +) -> Result<(), RTresult> { + null_check(geometry)?; + let instance = null_unwrap(instance)?; + let mut instance = instance.borrow_mut()?; + let triangles = OptixCell::clone_rc(geometry); + instance.child = GeometryInstanceChild::Geometry(triangles); + Ok(()) +} + +pub(crate) unsafe fn set_material( + instance: GeometryInstance, + index: u32, + material: Material, +) -> Result<(), RTresult> { + null_check(material)?; + let instance = null_unwrap(instance)?; + let mut instance = instance.borrow_mut()?; + match instance.materials.get_mut(index as usize) { + Some(material_slot) => { + *material_slot = Some(OptixCell::clone_rc(material)); + Ok(()) + } + None => Err(RTresult::RT_ERROR_INVALID_VALUE), + } +} + +pub(crate) unsafe fn set_material_count( + instance: GeometryInstance, + count: u32, +) -> Result<(), RTresult> { + let instance = null_unwrap(instance)?; + let mut instance = instance.borrow_mut()?; + instance.materials.resize(count as usize, None); + Ok(()) +} + +pub(crate) unsafe fn declare_variable( + instance_ptr: GeometryInstance, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(v)?; + let instance = null_unwrap(instance_ptr)?; + let mut instance = instance.borrow_mut()?; + let variable = VariableData::new(&mut *instance)?; + let name = CStr::from_ptr(name).to_owned(); + let result = Rc::as_ptr(&variable); + instance.variables.insert(name, variable); + *v = result; + Ok(()) +} + +pub(crate) unsafe fn get_material_count( + geometryinstance: GeometryInstance, + count: *mut u32, +) -> Result<(), RTresult> { + null_check(count)?; + let instance = null_unwrap(geometryinstance)?; + let instance = instance.borrow()?; + *count = instance.materials.len() as u32; + Ok(()) +} + +pub(crate) unsafe fn query_variable( + geometryinstance: GeometryInstance, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let geometryinstance = null_unwrap(geometryinstance)?; + let geometryinstance = (geometryinstance).borrow()?; + *v = geometryinstance + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) fn destroy(_geometryinstance: GeometryInstance) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn get_context( + geometryinstance: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let geometryinstance = null_unwrap(geometryinstance)?; + let geometryinstance = geometryinstance.borrow()?; + *context = geometryinstance.context.as_ptr(); + Ok(()) +} diff --git a/zluda_rt/src/geometry_triangles.rs b/zluda_rt/src/geometry_triangles.rs new file mode 100644 index 0000000..bafa53a --- /dev/null +++ b/zluda_rt/src/geometry_triangles.rs @@ -0,0 +1,269 @@ +use crate::{ + buffer::{Buffer, BufferData}, + context::{self, Context, ContextData}, + null_check, null_unwrap, + program::{Program, ProgramData}, + variable::{Variable, VariableData}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use hiprt_sys::hiprtTriangleMeshPrimitive; +use optix_types::*; +use rustc_hash::FxHashMap; +use std::{ + ffi::{c_void, CStr, CString}, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type GeometryTriangles = *const OptixCell; + +pub(crate) struct GeometryTrianglesData { + pub(crate) context: Weak>, + pub(crate) attribute_program: Option>>, + pub(crate) variables: FxHashMap>>, + triangle_count: u32, + indices: Option, + vertices: Option, + flags: FxHashMap, +} + +impl GeometryTrianglesData { + fn new(context: Weak>, _: &mut ContextData) -> Self { + Self { + context, + attribute_program: None, + variables: FxHashMap::default(), + triangle_count: 0, + indices: None, + vertices: None, + flags: FxHashMap::default(), + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.geometry_triangles.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn to_hiprt(&self) -> Result { + let vertices = self.vertices.as_ref().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let vertex_buffer = vertices + .vertex_buffer + .upgrade() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let vertex_buffer = vertex_buffer.borrow()?; + let mut result = hiprtTriangleMeshPrimitive { + vertices: unsafe { + (vertex_buffer.pointer_mip0().0 as *mut u8) + .add(vertices.vertex_buffer_byte_offset as usize) + } as *mut c_void, + vertexCount: vertices.vertex_count, + vertexStride: vertices.vertex_byte_stride as u32, + triangleIndices: ptr::null_mut(), + triangleCount: 0, + triangleStride: 0, + }; + if let Some(ref vertex_indices) = self.indices { + let index_buffer = vertex_indices + .index_buffer + .upgrade() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let index_buffer = index_buffer.borrow()?; + result.triangleIndices = unsafe { + (index_buffer.pointer_mip0().0 as *mut u8) + .add(vertex_indices.index_buffer_byte_offset as usize) + } as *mut c_void; + result.triangleCount = self.triangle_count; + result.triangleStride = vertex_indices.tri_indices_byte_stride as u32; + } else { + // TODO: implement + return Err(RTresult::RT_ERROR_UNKNOWN); + } + Ok(result) + } +} + +impl OptixObjectData for GeometryTrianglesData { + const TYPE: TypeTag = TypeTag::GeometryTriangles; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.geometry_triangles.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +struct Indices { + index_buffer: Weak>, + index_buffer_byte_offset: u64, + tri_indices_byte_stride: u64, +} + +struct Vertices { + vertex_count: ::std::os::raw::c_uint, + vertex_buffer: Weak>, + vertex_buffer_byte_offset: u64, + vertex_byte_stride: u64, +} + +pub(crate) unsafe fn create( + context: Context, + triangles: *mut GeometryTriangles, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(triangles)?; + *triangles = GeometryTrianglesData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_primitive_count( + triangles: GeometryTriangles, + triangle_count: u32, +) -> Result<(), RTresult> { + let triangles = null_unwrap(triangles)?; + let mut triangles = triangles.borrow_mut()?; + triangles.triangle_count = triangle_count; + Ok(()) +} + +pub(crate) unsafe fn set_triangle_indices( + triangles: GeometryTriangles, + index_buffer: Buffer, + index_buffer_byte_offset: u64, + tri_indices_byte_stride: u64, + tri_indices_format: RTformat, +) -> Result<(), RTresult> { + if tri_indices_format != RTformat::RT_FORMAT_UNSIGNED_INT3 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let triangles = null_unwrap(triangles)?; + let mut triangles = triangles.borrow_mut()?; + triangles.indices = Some(Indices { + index_buffer: OptixCell::clone_weak(index_buffer), + index_buffer_byte_offset, + tri_indices_byte_stride, + }); + Ok(()) +} + +pub(crate) unsafe fn set_vertices( + triangles: GeometryTriangles, + vertex_count: ::std::os::raw::c_uint, + vertex_buffer: Buffer, + vertex_buffer_byte_offset: u64, + vertex_byte_stride: u64, + position_format: RTformat, +) -> Result<(), RTresult> { + if position_format != RTformat::RT_FORMAT_FLOAT3 { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + let triangles = null_unwrap(triangles)?; + let mut triangles = triangles.borrow_mut()?; + triangles.vertices = Some(Vertices { + vertex_count, + vertex_buffer: OptixCell::clone_weak(vertex_buffer), + vertex_buffer_byte_offset, + vertex_byte_stride, + }); + Ok(()) +} + +pub(crate) fn validate(_geometrytriangles: GeometryTriangles) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn set_attribute( + triangles: GeometryTriangles, + program: Program, +) -> Result<(), RTresult> { + let triangles = null_unwrap(triangles)?; + let mut triangles = triangles.borrow_mut()?; + triangles.attribute_program = Some(OptixCell::clone_weak(program)); + Ok(()) +} + +pub(crate) unsafe fn set_flags_per_material( + triangles: GeometryTriangles, + material_index: u32, + flags: RTgeometryflags, +) -> Result<(), RTresult> { + let triangles = null_unwrap(triangles)?; + let mut triangles = triangles.borrow_mut()?; + let entry = triangles + .flags + .entry(material_index) + .or_insert(RTgeometryflags(0)); + entry.0 |= flags.0; + Ok(()) +} + +pub(crate) unsafe fn get_context( + geometrytriangles: GeometryTriangles, + context_ptr: *mut Context, +) -> Result<(), RTresult> { + let geometrytriangles = null_unwrap(geometrytriangles)?; + null_check(context_ptr)?; + let geometrytriangles = geometrytriangles.borrow()?; + let context = Weak::as_ptr(&geometrytriangles.context); + *context_ptr = context; + Ok(()) +} + +pub(crate) unsafe fn declare_variable( + geometrytriangles: GeometryTriangles, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(v)?; + let geometrytriangles = null_unwrap(geometrytriangles)?; + let mut geometrytriangles = geometrytriangles.borrow_mut()?; + let variable = VariableData::new(&mut *geometrytriangles)?; + let name = CStr::from_ptr(name).to_owned(); + let result = Rc::as_ptr(&variable); + geometrytriangles.variables.insert(name, variable); + *v = result; + Ok(()) +} + +pub(crate) unsafe fn query_variable( + geometrytriangles: GeometryTriangles, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let geometrytriangles = null_unwrap(geometrytriangles)?; + let geometrytriangles = (geometrytriangles).borrow()?; + *v = geometrytriangles + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) unsafe fn set_build_flags( + _geometrytriangles: GeometryTriangles, + _build_flags: RTgeometrybuildflags, +) -> Result<(), RTresult> { + // TODO: implement + if _build_flags != RTgeometrybuildflags::RT_GEOMETRY_BUILD_FLAG_NONE { + return Err(RTresult::RT_ERROR_NOT_SUPPORTED); + } + Ok(()) +} + +pub(crate) unsafe fn destroy(_geometrytriangles: GeometryTriangles) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} diff --git a/zluda_rt/src/group.rs b/zluda_rt/src/group.rs new file mode 100644 index 0000000..e43388c --- /dev/null +++ b/zluda_rt/src/group.rs @@ -0,0 +1,411 @@ +use crate::{ + acceleration::{Acceleration, AccelerationData, AccelerationOwner}, + context::{self, Context, ContextData}, + geometry_group::{BvhDetails, GeometryGroupData}, + geometry_instance::DeviceGeometryInstance, + hip, hiprt, null_check, null_unwrap, + repr_gpu::{self, TrivialHIPAllocator}, + transform::TransformData, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, TypedObjectWeak, UntypedObject, +}; +use hip_runtime_sys::*; +use hiprt_sys::*; +use optix_types::*; +use std::{ + alloc::Layout, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Group = *const OptixCell; + +pub(crate) struct GroupData { + pub(crate) context: Weak>, + acceleration: Option>>, + subgroups: Vec>, + pub(crate) index: u32, +} + +impl GroupData { + fn new(weak_context: Weak>, context: &mut ContextData) -> Self { + let index = context.geometry_group_count; + context.geometry_group_count += 1; + Self { + context: weak_context, + acceleration: None, + subgroups: Vec::new(), + index, + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.groups.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn prepare_globals( + &self, + allocator: &mut TrivialHIPAllocator, + ctx: &ContextData, + global_state: &mut repr_gpu::GlobalState, + ) -> Result { + let ray_type_count = ctx.ray_type_count; + let mut transforms = Vec::new(); + let mut children = Vec::new(); + let acceleration = self + .acceleration + .as_ref() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let acceleration = acceleration.borrow()?; + let mut build_flags = acceleration.to_hiprt().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + for child in self.subgroups.iter() { + let child = child.as_ref().ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + match child { + GroupChild::GeometryGroup(group) => { + let group = Weak::upgrade(&group).ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let group = group.borrow()?; + for _ in 0..group.children.len() { + transforms.push(None); + } + children.extend_from_slice(&group.children[..]); + let child_acceleration = group + .acceleration + .as_ref() + .ok_or(RTresult::RT_ERROR_UNKNOWN)? + .borrow()?; + let child_build_flags = child_acceleration + .to_hiprt() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + build_flags = Self::join_build_flags(build_flags, child_build_flags); + } + GroupChild::Transform(transform) => { + let transform_rc = + Weak::upgrade(&transform).ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let transform = transform_rc.borrow()?; + let dev_transform = transform.allocate(allocator)?; + let group = transform + .child + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let group = Weak::upgrade(group).ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let group = group.borrow()?; + for _ in 0..group.children.len() { + transforms.push(Some((transform_rc.clone(), dev_transform))); + } + children.extend_from_slice(&group.children[..]); + let child_acceleration = group + .acceleration + .as_ref() + .ok_or(RTresult::RT_ERROR_UNKNOWN)? + .borrow()?; + let child_build_flags = child_acceleration + .to_hiprt() + .ok_or(RTresult::RT_ERROR_UNKNOWN)?; + build_flags = Self::join_build_flags(build_flags, child_build_flags); + } + } + } + let mut hiprt_instances_host = Vec::with_capacity(children.len()); + let custom_func_table = allocator.new_func_table()?; + let mut custom_func_set_counter = 0u32; + let attribute_visitor = repr_gpu::AttributesVisitCallChain { + context: ctx, + children: &*children, + }; + let attribute_chain_layout = repr_gpu::get_layout(ray_type_count, &attribute_visitor)?; + let attribute_call_chain = allocator.allocate(attribute_chain_layout.layout.size())?; + repr_gpu::copy_to_gpu( + ray_type_count, + &attribute_visitor, + &attribute_chain_layout, + attribute_call_chain, + )?; + let hit_chains = (0..ray_type_count).map(|ray| { + let prologue_layout = Layout::new::(); + let any_hit_visitor = repr_gpu::HitProgramsVisitCallChain { + closest_hit: false, + ray, + children: &children, + context: ctx, + }; + let closest_hit_visitor = repr_gpu::HitProgramsVisitCallChain { + closest_hit: true, + ray, + children: &children, + context: ctx, + }; + let any_hit_chain_layout = repr_gpu::get_layout(ray_type_count, &any_hit_visitor)?; + let closest_hit_chain_layout = repr_gpu::get_layout(ray_type_count, &closest_hit_visitor)?; + let with_any_hit = prologue_layout + .extend(any_hit_chain_layout.layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let with_closest_hit = with_any_hit + .0 + .extend(closest_hit_chain_layout.layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let hit_chain_gpu = allocator.allocate(with_closest_hit.0.size())?; + let prolog = repr_gpu::HitProgramChain { + any_hit_start: with_any_hit.1 as u32, + closest_hit_start: with_closest_hit.1 as u32, + }; + hip! { hipMemcpyHtoD(hit_chain_gpu, &prolog as *const _ as _, prologue_layout.size()), RT_ERROR_UNKNOWN }; + repr_gpu::copy_to_gpu( + ray_type_count, + &any_hit_visitor, + &any_hit_chain_layout, + hipDeviceptr_t(unsafe { hit_chain_gpu.0.cast::().add(with_any_hit.1).cast() }), + )?; + repr_gpu::copy_to_gpu( + ray_type_count, + &closest_hit_visitor, + &closest_hit_chain_layout, + hipDeviceptr_t(unsafe { + hit_chain_gpu.0.cast::().add(with_closest_hit.1).cast() + }), + )?; + Ok(hit_chain_gpu) + }).collect::, _>>()?; + for (instance_index, instance) in children.iter().enumerate() { + let instance = instance.as_ref().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let instance = instance.borrow()?; + match instance.prepare_globals( + allocator, + ctx, + build_flags, + ray_type_count, + custom_func_set_counter, + global_state, + transforms[instance_index] + .as_ref() + .map(|(_, dev_ptr)| *dev_ptr) + .unwrap_or(hipDeviceptr_t(ptr::null_mut())), + )? { + DeviceGeometryInstance::Geometry { + custom_func_set, + hiprt_geometry, + } => { + hiprt_instances_host.push(hiprt_geometry); + hiprt! { ctx.hiprt.hiprtSetCustomFuncTable(ctx.context, custom_func_table, custom_func_set_counter, custom_func_set), RT_ERROR_UNKNOWN }; + custom_func_set_counter += 1; + } + DeviceGeometryInstance::GeometryTriangles { hiprt_geometry } => { + hiprt_instances_host.push(hiprt_geometry); + } + }; + } + let instance_frames_host = transforms + .iter() + .map(|transform| { + Ok::<_, RTresult>(match transform { + Some((transform, _)) => { + let transform = transform.borrow()?; + transform.to_hiprt() + } + None => hiprtFrame { + translation: hiprtFloat3 { + x: 0f32, + y: 0f32, + z: 0f32, + }, + scale: hiprtFloat3 { + x: 1f32, + y: 1f32, + z: 1f32, + }, + rotation: hiprtFloat4 { + x: 0f32, + y: 0f32, + z: 1.0f32, + w: 0f32, + }, + time: 0f32, + pad: 0, + }, + }) + }) + .collect::, _>>()?; + let instance_geometries = allocator.copy_to_device(&hiprt_instances_host[..])?; + let instance_frames = allocator.copy_to_device(&instance_frames_host[..])?; + let scene_input = hiprtSceneBuildInput { + instanceCount: children.len() as u32, + instanceGeometries: instance_geometries.0, + frameCount: children.len() as u32, + instanceFrames: instance_frames.0, + nodes: ptr::null_mut(), + instanceTransformHeaders: ptr::null_mut(), + instanceMasks: ptr::null_mut(), + }; + let build_options = hiprtBuildOptions { + buildFlags: build_flags.0, + }; + let transform_blocks = transforms + .iter() + .map(|maybe_transform| { + maybe_transform + .as_ref() + .map_or(hipDeviceptr_t(ptr::null_mut()), |(_, ptr)| *ptr) + }) + .collect::>(); + let transform_blocks = allocator.copy_to_device(&transform_blocks)?; + let hit_chains = allocator.copy_to_device(&hit_chains)?; + let scene = allocator.new_scene(scene_input, build_options)?; + Ok(BvhDetails { + scene, + func_set: custom_func_table, + attribute_call_chain, + transform_blocks, + hit_chains, + }) + } + + // We assume lower 2 bits are operator, higher bits are flags + fn join_build_flags(f1: hiprtBuildFlagBits, f2: hiprtBuildFlagBits) -> hiprtBuildFlagBits { + let op = u32::max(f1.0 & 3, f2.0 & 3); + let flags = ((f1.0 >> 2) | (f2.0 >> 2)) << 2; + return hiprtBuildFlagBits(op | flags); + } +} + +impl OptixObjectData for GroupData { + const TYPE: TypeTag = TypeTag::Group; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.groups.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +#[derive(Clone)] +enum GroupChild { + GeometryGroup(Weak>), + Transform(Weak>), +} + +pub(crate) unsafe fn create(context: Context, group: *mut Group) -> Result<(), RTresult> { + null_check(context)?; + null_check(group)?; + *group = GroupData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_acceleration( + group: Group, + acceleration: Acceleration, +) -> Result<(), RTresult> { + null_check(acceleration)?; + let group = null_unwrap(group)?; + let acceleration = null_unwrap(acceleration)?; + { + let mut group = group.borrow_mut()?; + group.acceleration = Some(OptixCell::clone_rc(acceleration)); + } + { + let mut acceleration = acceleration.borrow_mut()?; + acceleration.owner = Some(AccelerationOwner::Group(OptixCell::clone_weak(group))); + } + Ok(()) +} + +pub(crate) unsafe fn set_child_count(group: Group, count: u32) -> Result<(), RTresult> { + let group = null_unwrap(group)?; + let mut group = group.borrow_mut()?; + group.subgroups.resize(count as usize, None); + Ok(()) +} + +pub(crate) unsafe fn get_child( + group: Group, + index: u32, + child: *mut UntypedObject, +) -> Result<(), RTresult> { + let group = null_unwrap(group)?; + let group = group.borrow()?; + if index as usize >= group.subgroups.len() { + *child = ptr::null_mut(); + return Err(RTresult::RT_ERROR_INVALID_VALUE); + } + let result = match &group.subgroups[index as usize] { + Some(GroupChild::GeometryGroup(geo)) => { + let geo = Weak::upgrade(&geo).ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + OptixCell::as_untyped(&*geo) + } + Some(GroupChild::Transform(transform)) => { + let transform = Weak::upgrade(&transform).ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + OptixCell::as_untyped(&*transform) + } + None => ptr::null_mut(), + }; + *child = result; + Ok(()) +} + +pub(crate) unsafe fn get_child_count(group: Group, count: *mut u32) -> Result<(), RTresult> { + null_check(count)?; + let group = null_unwrap(group)?; + let group = group.borrow()?; + *count = group.subgroups.len() as u32; + Ok(()) +} + +pub(crate) unsafe fn set_child( + group: Group, + index: u32, + child: UntypedObject, +) -> Result<(), RTresult> { + null_check(child)?; + let group = null_unwrap(group)?; + let mut group = group.borrow_mut()?; + match group.subgroups.get_mut(index as usize) { + Some(instance_slot) => { + let child = TypedObjectWeak::clone_from(child)?; + let group = match child { + TypedObjectWeak::GeometryGroup(group) => GroupChild::GeometryGroup(group), + TypedObjectWeak::Transform(transform) => GroupChild::Transform(transform), + _ => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }; + *instance_slot = Some(group); + Ok(()) + } + None => Err(RTresult::RT_ERROR_INVALID_VALUE), + } +} + +pub(crate) unsafe fn get_acceleration( + group: Group, + acceleration: *mut Acceleration, +) -> Result<(), RTresult> { + null_check(acceleration)?; + let group = null_unwrap(group)?; + let group = group.borrow()?; + *acceleration = group + .acceleration + .as_ref() + .map(Rc::as_ptr) + .unwrap_or(ptr::null()); + Ok(()) +} + +pub(crate) fn destroy(_group: Group) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn get_context( + group: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let group = null_unwrap(group)?; + let group = group.borrow()?; + *context = group.context.as_ptr(); + Ok(()) +} diff --git a/zluda_rt/src/hip.rs b/zluda_rt/src/hip.rs new file mode 100644 index 0000000..647be3c --- /dev/null +++ b/zluda_rt/src/hip.rs @@ -0,0 +1,103 @@ +use hip_runtime_sys::*; +use optix_types::RTresult; +use std::{ + ffi::{c_void, CStr}, + mem, ptr, +}; + +use crate::div_positive_round_up; + +macro_rules! hip { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(err); + } + } + }; +} + +#[repr(transparent)] +pub(crate) struct Module(pub hipModule_t); + +impl Module { + pub(crate) fn launch_kernel_1d( + &self, + f: hipFunction_t, + size: u32, + shared_mem: u32, + stream: hipStream_t, + params: *mut *mut c_void, + ) -> Result<(), hipError_t> { + let groups = div_positive_round_up(size as u64, 32u64); + hip! { hipModuleLaunchKernel(f, groups as u32, 1, 1, 32, 1, 1, shared_mem, stream, params, ptr::null_mut()) }; + Ok(()) + } + + pub(crate) fn load_data(binary: &[u8]) -> Result { + let mut raw_module = ptr::null_mut(); + hip! { hipModuleLoadData(&mut raw_module, binary.as_ptr() as _) }; + Ok(Module(raw_module)) + } + + pub(crate) fn get_function(&self, kernel_name: &CStr) -> Result { + let mut function = ptr::null_mut(); + hip! { hipModuleGetFunction(&mut function, self.0, kernel_name.as_ptr() as _) }; + Ok(function) + } + + pub(crate) unsafe fn get_global(&self, name: &CStr) -> Result { + let (ptr, bytes) = self.get_pointer_to_global(name)?; + if bytes != mem::size_of::() { + return Err(hipError_t::hipErrorInvalidSymbol); + } + let mut result = mem::zeroed::(); + hip! { hipMemcpyDtoH(&mut result as *mut T as _, ptr, bytes) }; + Ok(result) + } + + pub(crate) fn get_pointer_to_global( + &self, + name: &CStr, + ) -> Result<(hipDeviceptr_t, usize), hipError_t> { + let mut ptr = unsafe { mem::zeroed() }; + let mut bytes = 0; + hip! { hipModuleGetGlobal(&mut ptr, &mut bytes, self.0, name.as_ptr() as _) }; + Ok((ptr, bytes)) + } +} + +impl Drop for Module { + #[allow(unused_must_use)] + fn drop(&mut self) { + unsafe { hipModuleUnload(self.0) }; + } +} + +pub(crate) fn copy_to_device(slice: &[T]) -> Result { + copy_to_device_impl(slice).map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED) +} + +fn copy_to_device_impl(slice: &[T]) -> Result { + let dev_ptr = malloc(slice.len() * mem::size_of::())?; + hip! { hipMemcpyHtoD(dev_ptr, slice.as_ptr() as _, slice.len() * mem::size_of::()) }; + Ok(dev_ptr) +} + +pub(crate) fn malloc(size: usize) -> Result { + let mut dev_ptr = ptr::null_mut(); + hip! { hipMalloc(&mut dev_ptr, size) }; + Ok(hipDeviceptr_t(dev_ptr)) +} + +pub(crate) fn free(ptr: hipDeviceptr_t) -> Result<(), hipError_t> { + hip! { hipFree(ptr.0) }; + Ok(()) +} + +pub(crate) fn zero_fill(ptr: hipDeviceptr_t, size: usize) -> Result<(), hipError_t> { + hip! { hipMemsetD8(ptr, 0, size) }; + Ok(()) +} diff --git a/zluda_rt/src/lib.rs b/zluda_rt/src/lib.rs new file mode 100644 index 0000000..985dbee --- /dev/null +++ b/zluda_rt/src/lib.rs @@ -0,0 +1,1884 @@ +#[macro_use] +extern crate nougat; + +mod acceleration; +mod buffer; +mod cache; +mod context; +mod eptx; +mod geometry; +mod geometry_group; +mod geometry_instance; +mod geometry_triangles; +mod group; +mod hip; +mod material; +mod program; +mod repr_gpu; +#[cfg(test)] +mod test_common; +#[cfg(test)] +mod tests; +mod texture_sampler; +mod transform; +mod variable; + +use crate::texture_sampler::{TextureSampler, TextureSamplerData}; +use acceleration::{Acceleration, AccelerationData}; +use buffer::{Buffer, BufferData}; +use context::{Context, ContextData}; +use geometry::{Geometry, GeometryData}; +use geometry_group::{GeometryGroup, GeometryGroupData}; +use geometry_instance::{GeometryInstance, GeometryInstanceData}; +use geometry_triangles::{GeometryTriangles, GeometryTrianglesData}; +use group::{Group, GroupData}; +use hip_runtime_sys::{ + hipDeviceAttribute_t, hipDeviceGetAttribute, hipDeviceTotalMem, hipDeviceptr_t, hipMemcpyDtoH, +}; +use material::{Material, MaterialData}; +use optix_types::*; +use paste::paste; +use program::{Program, ProgramData}; +use std::{ + alloc::Layout, + cell::{Ref, RefCell, RefMut}, + collections::HashSet, + ffi::c_void, + hash::{BuildHasherDefault, Hash, Hasher}, + mem::{self, ManuallyDrop}, + os::raw::c_char, + ptr::{self, NonNull}, + rc::{Rc, Weak}, +}; +use transform::{Transform, TransformData}; +use variable::{Variable, VariableData}; + +macro_rules! optix6_unimplemented { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + $( + #[no_mangle] + unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + definitions::unimplemented() + } + )* + }; +} + +macro_rules! optix6_fn { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + $( + #[no_mangle] + unsafe extern $abi fn $fn_name ( $( $arg_id : $arg_type),* ) -> $ret_type { + IntoOptix::<$ret_type>::into_optix(definitions::$fn_name( $( InternalRepresentation::to_internal($arg_id) ),* )) + } + )* + }; +} + +#[macro_export] +macro_rules! unwrap_or_continue { + ($option:expr) => { + match $option { + Some(x) => x, + None => continue, + } + }; +} + +#[macro_export] +macro_rules! hip { + ($expr:expr, $err:ident) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hip_runtime_sys::hipError_t::hipSuccess { + return Result::Err(RTresult::$err); + } + } + }; +} + +#[macro_export] +macro_rules! hiprt { + ($expr:expr, $err:ident) => { + #[allow(unused_unsafe)] + { + let err = unsafe { $expr }; + if err != hiprt_sys::hiprtError::hiprtSuccess { + return Result::Err(RTresult::$err); + } + } + }; +} + +optix_base::optix6_function_declarations!( + optix6_unimplemented, + optix6_fn, + [ + rtAccelerationCreate, + rtAccelerationDestroy, + rtAccelerationGetContext, + rtAccelerationSetBuilder, + rtAccelerationMarkDirty, + rtBufferCreate, + rtBufferCreateFromCallback, + rtBufferDestroy, + rtBufferSetElementSize, + rtBufferSetFormat, + rtBufferSetMipLevelCount, + rtBufferSetSize1D, + rtBufferSetSize2D, + rtBufferGetContext, + rtBufferGetDevicePointer, + rtBufferGetDimensionality, + rtBufferGetElementSize, + rtBufferGetFormat, + rtBufferGetGLBOId, + rtBufferGetId, + rtBufferGetMipLevelCount, + rtBufferGetMipLevelSize2D, + rtBufferGetSize1D, + rtBufferGetSize2D, + rtBufferGetSizev, + rtBufferMap, + rtBufferMapEx, + rtBufferUnmap, + rtBufferUnmapEx, + rtContextCreate, + rtContextDeclareVariable, + rtContextDestroy, + rtContextGetAttribute, + rtContextGetBufferFromId, + rtContextGetDeviceCount, + rtContextGetDevices, + rtContextGetErrorString, + rtContextLaunch2D, + rtContextQueryVariable, + rtContextSetAttribute, + rtContextSetDevices, + rtContextSetEntryPointCount, + rtContextSetExceptionEnabled, + rtContextSetExceptionProgram, + rtContextSetMaxCallableProgramDepth, + rtContextSetMaxTraceDepth, + rtContextSetMissProgram, + rtContextSetPrintEnabled, + rtContextSetPrintLaunchIndex, + rtContextSetRayGenerationProgram, + rtContextSetRayTypeCount, + rtContextSetStackSize, + rtContextSetUsageReportCallback, + rtContextValidate, + rtDeviceGetAttribute, + rtDeviceGetDeviceCount, + rtGeometryCreate, + rtGeometryDeclareVariable, + rtGeometryDestroy, + rtGeometryGetContext, + rtGeometryQueryVariable, + rtGeometrySetPrimitiveCount, + rtGeometrySetBoundingBoxProgram, + rtGeometrySetIntersectionProgram, + rtGeometryGroupCreate, + rtGeometryGroupDestroy, + rtGeometryGroupGetChildCount, + rtGeometryGroupGetContext, + rtGeometryGroupSetAcceleration, + rtGeometryGroupSetChild, + rtGeometryGroupSetChildCount, + rtGeometryGroupSetVisibilityMask, + rtGeometryInstanceCreate, + rtGeometryInstanceDeclareVariable, + rtGeometryInstanceDestroy, + rtGeometryInstanceQueryVariable, + rtGeometryInstanceGetContext, + rtGeometryInstanceGetMaterialCount, + rtGeometryInstanceSetGeometry, + rtGeometryInstanceSetGeometryTriangles, + rtGeometryInstanceSetMaterial, + rtGeometryInstanceSetMaterialCount, + rtGeometryTrianglesCreate, + rtGeometryTrianglesDeclareVariable, + rtGeometryTrianglesDestroy, + rtGeometryTrianglesGetContext, + rtGeometryTrianglesSetAttributeProgram, + rtGeometryTrianglesSetBuildFlags, + rtGeometryTrianglesSetFlagsPerMaterial, + rtGeometryTrianglesSetPrimitiveCount, + rtGeometryTrianglesSetTriangleIndices, + rtGeometryTrianglesSetVertices, + rtGeometryTrianglesQueryVariable, + rtGeometryTrianglesValidate, + rtGetVersion, + rtGlobalGetAttribute, + rtGlobalSetAttribute, + rtGroupCreate, + rtGroupDestroy, + rtGroupGetAcceleration, + rtGroupGetChild, + rtGroupGetChildCount, + rtGroupGetContext, + rtGroupSetAcceleration, + rtGroupSetChild, + rtGroupSetChildCount, + rtMaterialCreate, + rtMaterialDeclareVariable, + rtMaterialDestroy, + rtMaterialGetContext, + rtMaterialQueryVariable, + rtMaterialSetAnyHitProgram, + rtMaterialSetClosestHitProgram, + rtProgramCreateFromProgram, + rtProgramCreateFromPTXFile, + rtProgramCreateFromPTXString, + rtProgramDeclareVariable, + rtProgramDestroy, + rtProgramGetContext, + rtProgramGetId, + rtProgramQueryVariable, + rtProgramValidate, + rtTextureSamplerCreate, + rtTextureSamplerDestroy, + rtTextureSamplerGetBuffer, + rtTextureSamplerGetContext, + rtTextureSamplerGetId, + rtTextureSamplerSetArraySize, + rtTextureSamplerSetBuffer, + rtTextureSamplerSetFilteringModes, + rtTextureSamplerSetIndexingMode, + rtTextureSamplerSetMaxAnisotropy, + rtTextureSamplerSetMipLevelCount, + rtTextureSamplerSetReadMode, + rtTextureSamplerSetWrapMode, + rtTransformCreate, + rtTransformDestroy, + rtTransformGetContext, + rtTransformGetMotionKeyCount, + rtTransformSetChild, + rtTransformSetMatrix, + rtVariableSet1f, + rtVariableSet1i, + rtVariableSet1ui, + rtVariableSet1ull, + rtVariableSet3f, + rtVariableSet3fv, + rtVariableSet4f, + rtVariableSet4fv, + rtVariableSetObject, + rtVariableGetObject, + rtVariableSetUserData + ] +); + +pub(crate) trait InternalRepresentation: Sized { + fn to_internal(t: T) -> Self { + unsafe { mem::transmute_copy(&t) } + } +} + +impl> InternalRepresentation<*mut From> for *mut Into {} +impl> InternalRepresentation<*const From> for *const Into {} + +// Unchanged +impl InternalRepresentation for RTgeometrybuildflags {} +impl InternalRepresentation for RTresult {} +impl InternalRepresentation for RTformat {} +impl InternalRepresentation for RTwrapmode {} +impl InternalRepresentation for RTgeometryflags {} +impl InternalRepresentation for RTusagereportcallback {} +impl InternalRepresentation for RTexception {} +impl InternalRepresentation for RTcontextattribute {} +impl InternalRepresentation for RTglobalattribute {} +impl InternalRepresentation for RTtextureindexmode {} +impl InternalRepresentation for RTdeviceattribute {} +impl InternalRepresentation for RTtexturereadmode {} +impl InternalRepresentation for RTfiltermode {} +impl InternalRepresentation for c_char {} +impl InternalRepresentation for f32 {} +impl InternalRepresentation for i32 {} +impl InternalRepresentation for u32 {} +impl InternalRepresentation for u64 {} +impl InternalRepresentation for c_void {} +// ZLUDA +impl InternalRepresentation for UntypedObject {} +impl InternalRepresentation + for Option< + unsafe extern "C" fn( + callbackData: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> ::std::os::raw::c_int, + > +{ +} + +#[repr(C)] +struct OptixCell { + tag: TypeTag, + data: RefCell, +} + +impl OptixCell { + unsafe fn clone_rc(cell: *const OptixCell) -> Rc> { + let weak = ManuallyDrop::new(Rc::from_raw(cell)); + Rc::clone(&weak) + } + + unsafe fn clone_weak(cell: *const OptixCell) -> Weak> { + let weak = ManuallyDrop::new(Weak::from_raw(cell)); + Weak::clone(&weak) + } + + unsafe fn as_untyped(cell: *const OptixCell) -> UntypedObject { + cell.cast() + } +} + +struct RcHashSet(HashSet, BuildHasherDefault>>); + +#[repr(transparent)] +struct PtrEq(Rc); + +impl PartialEq for PtrEq { + fn eq(&self, other: &Self) -> bool { + Rc::ptr_eq(&self.0, &other.0) + } +} + +impl Eq for PtrEq {} + +impl Hash for PtrEq { + fn hash(&self, state: &mut H) { + state.write_usize(unsafe { mem::transmute_copy::, usize>(&self.0) }) + } +} +struct WritethroughHasher(*const T); + +impl Default for WritethroughHasher { + fn default() -> Self { + Self(ptr::null()) + } +} + +impl Hasher for WritethroughHasher { + fn finish(&self) -> u64 { + unsafe { mem::transmute(self.0) } + } + + fn write(&mut self, _bytes: &[u8]) { + unreachable!() + } + + fn write_usize(&mut self, i: usize) { + self.0 = i as *const T; + } +} + +impl RcHashSet { + fn new() -> Self { + Self(HashSet::default()) + } + + fn insert(&mut self, value: Rc) -> bool { + self.0.insert(PtrEq(value)) + } + + fn remove(&mut self, value: &Rc) -> bool { + self.0 + .remove(unsafe { mem::transmute::<&Rc, &PtrEq>(value) }) + } + + fn iter(&self) -> std::collections::hash_set::Iter<'_, Rc> { + unsafe { mem::transmute(self.0.iter()) } + } +} + +impl OptixCell { + fn new(t: T) -> Self { + Self { + tag: T::TYPE, + data: RefCell::new(t), + } + } + + fn borrow(&self) -> Result, RTresult> { + self.data + .try_borrow() + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + + fn borrow_mut(&self) -> Result, RTresult> { + let mut this = self + .data + .try_borrow_mut() + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + match this.context() { + MaybeWeakRefMut::Weak(weak_ctx) => { + let ctx = weak_ctx.upgrade().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + if let Ok(mut ctx) = ctx.borrow_mut() { + // We might be called from within launch2d, where ctx is already mutably borrowed + ctx.invalidate(); + } + drop(ctx); + } + MaybeWeakRefMut::Ref(ctx) => ctx.invalidate(), + } + Ok(this) + } + + fn borrow_mut_no_invalidate(&self) -> Result, RTresult> { + self.data + .try_borrow_mut() + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + + unsafe fn destroy(ptr: *const OptixCell) -> Result<(), RTresult> { + let obj = null_unwrap(ptr)?; + let mut this = obj.borrow_mut()?; + let rc_ptr = ManuallyDrop::new(Rc::from_raw(obj)); + this.deregister(&*rc_ptr) + } +} + +type UntypedObject = *const TypeTag; + +macro_rules! optix_types { + ($ctx:ident, [$($type_:ident),+]) => { + #[repr(u8)] + enum TypeTag { + $ctx = 1, + $( + $type_, + )+ + } + + optix_types!(@ $ctx, $($type_),+); + }; + (@ $($type_:ident),+) => { + $( + impl InternalRepresentation] }> for $type_ {} + )+ + + #[derive(Clone)] + enum TypedObjectWeak { + $( + $type_(Weak] } >>), + )+ + } + + impl TypedObjectWeak { + fn as_untyped(&self) -> UntypedObject { + match self { + $( + TypedObjectWeak::$type_(weak) => { + let result: $type_ = Weak::as_ptr(weak); + result as UntypedObject + }, + )+ + } + } + + + unsafe fn clone_from(obj: UntypedObject) -> Result { + null_check(obj)?; + Ok(match *obj { + $( + TypeTag::$type_ => { + let fake_strong = ManuallyDrop::new(Rc::from_raw(mem::transmute::<_, $type_>(obj))); + TypedObjectWeak::$type_(Rc::downgrade(&fake_strong)) + } + )+ + }) + } + + $( + paste!{ + #[allow(dead_code)] + #[allow(non_snake_case)] + unsafe fn [] ($type_: $type_) -> TypedObjectWeak { + let fake_strong = ManuallyDrop::new(Rc::from_raw($type_)); + TypedObjectWeak::$type_(Rc::downgrade(&fake_strong)) + } + } + )+ + } + }; +} + +optix_types!( + Context, + [ + Buffer, + Variable, + Program, + Material, + Geometry, + GeometryTriangles, + GeometryGroup, + Group, + Acceleration, + GeometryInstance, + TextureSampler, + Transform + ] +); + +struct AlignedBuffer { + size: usize, + pub(crate) ptr: NonNull, + align: u32, +} + +impl AlignedBuffer { + fn new(layout: Layout) -> Self { + let size = layout.size(); + let align = layout.align() as u32; + let ptr = NonNull::new(unsafe { std::alloc::alloc(layout) }).unwrap(); + Self { size, align, ptr } + } + + fn len(&self) -> usize { + self.size as usize + } + + fn from_hip(layout: Layout, dev_data: hipDeviceptr_t) -> Result { + let ptr = unsafe { std::alloc::alloc(layout) }; + hip! { hipMemcpyDtoH(ptr as _, dev_data, layout.size()), RT_ERROR_MEMORY_ALLOCATION_FAILED }; + let ptr = NonNull::new(ptr).unwrap(); + let size = layout.size(); + let align = layout.align() as u32; + Ok(Self { size, align, ptr }) + } + + fn as_ptr(&self) -> *mut c_void { + self.ptr.as_ptr() as _ + } + + fn as_bytes(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.size) } + } + + fn as_bytes_mut(&mut self) -> &mut [u8] { + unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.size) } + } +} + +impl Clone for AlignedBuffer { + fn clone(&self) -> Self { + let mut buffer = AlignedBuffer::new(unsafe { + Layout::from_size_align_unchecked(self.size, self.align as usize) + }); + buffer.as_bytes_mut().copy_from_slice(self.as_bytes()); + buffer + } +} + +impl Drop for AlignedBuffer { + fn drop(&mut self) { + unsafe { + std::alloc::dealloc( + self.ptr.as_ptr(), + Layout::from_size_align_unchecked(self.size, self.align as usize), + ) + } + } +} + +fn div_positive_round_up(dividend: u64, divisor: u64) -> u64 { + let mut result = dividend / divisor; + if (dividend % divisor) != 0 { + result += 1; + } + result +} + +unsafe fn slice_cast_mut<'a, T: Sized, U: Sized>(from: &'a mut [T], count: usize) -> &'a mut [U] { + assert!(from.len() * mem::size_of::() >= count * mem::size_of::()); + std::slice::from_raw_parts_mut(from.as_mut_ptr() as _, count) +} + +trait OptixObjectData: Sized { + const TYPE: TypeTag; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult>; + fn context<'a>(&'a mut self) -> MaybeWeakRefMut<'a, ContextData>; +} + +pub(crate) enum MaybeWeakRefMut<'a, T: OptixObjectData> { + Weak(&'a Weak>), + Ref(&'a mut T), +} + +pub(crate) trait IntoOptix { + fn into_optix(self) -> T; +} + +impl IntoOptix<()> for () { + fn into_optix(self) -> () { + self + } +} + +impl IntoOptix for () { + fn into_optix(self) -> RTresult { + RTresult::RT_SUCCESS + } +} + +impl IntoOptix for RTresult { + fn into_optix(self) -> RTresult { + self + } +} + +impl IntoOptix for Result<(), RTresult> { + fn into_optix(self) -> RTresult { + match self { + Ok(()) => IntoOptix::into_optix(()), + Err(err) => IntoOptix::into_optix(err), + } + } +} + +trait NullablePointer { + fn null() -> Self; +} + +impl NullablePointer for *mut T { + fn null() -> Self { + ptr::null_mut() + } +} + +impl NullablePointer for *const T { + fn null() -> Self { + ptr::null_mut() + } +} + +#[must_use] +fn null_check(ptr: T) -> Result<(), RTresult> { + if ptr == T::null() { + Err(RTresult::RT_ERROR_INVALID_VALUE) + } else { + Ok(()) + } +} + +#[must_use] +unsafe fn null_unwrap<'a, T>(t: *const T) -> Result<&'a T, RTresult> { + t.as_ref().ok_or(RTresult::RT_ERROR_INVALID_VALUE) +} + +#[must_use] +unsafe fn null_unwrap_mut<'a, T>(t: *mut T) -> Result<&'a mut T, RTresult> { + t.as_mut().ok_or(RTresult::RT_ERROR_INVALID_VALUE) +} + +#[allow(non_snake_case)] +mod definitions { + use crate::{ + acceleration::{self, Acceleration}, + buffer::{self, Buffer}, + context::{self, Context}, + geometry::{self, Geometry}, + geometry_group::{self, GeometryGroup}, + geometry_instance::{self, GeometryInstance}, + geometry_triangles::{self, GeometryTriangles}, + group::{self, Group}, + material::{self, Material}, + program::{self, Program}, + texture_sampler::{self, TextureSampler}, + transform::{self, Transform}, + variable::{self, Variable}, + UntypedObject, + }; + use optix_types::*; + use std::os::raw::{c_int, c_uint}; + + #[cfg(debug_assertions)] + pub(crate) fn unimplemented() -> RTresult { + unimplemented!() + } + + #[cfg(not(debug_assertions))] + pub(crate) fn unimplemented() -> RTresult { + RTresult::RT_ERROR_NOT_SUPPORTED + } + + pub(crate) unsafe fn rtAccelerationCreate( + context: Context, + acceleration: *mut Acceleration, + ) -> Result<(), RTresult> { + acceleration::create(context, acceleration) + } + + pub(crate) unsafe fn rtAccelerationDestroy(acceleration: Acceleration) -> Result<(), RTresult> { + acceleration::destroy(acceleration) + } + + pub(crate) unsafe fn rtAccelerationGetContext( + acceleration: Acceleration, + context: *mut Context, + ) -> Result<(), RTresult> { + acceleration::get_context(acceleration, context) + } + + pub(crate) unsafe fn rtAccelerationSetBuilder( + acceleration: Acceleration, + builder: *const ::std::os::raw::c_char, + ) -> Result<(), RTresult> { + acceleration::set_builder(acceleration, builder) + } + + pub(crate) unsafe fn rtAccelerationMarkDirty( + acceleration: Acceleration, + ) -> Result<(), RTresult> { + acceleration::mark_dirty(acceleration) + } + + pub(crate) unsafe fn rtBufferCreate( + context: Context, + bufferdesc: ::std::os::raw::c_uint, + buffer: *mut Buffer, + ) -> Result<(), RTresult> { + buffer::create(context, bufferdesc, buffer) + } + + pub(crate) unsafe fn rtBufferCreateFromCallback( + context: Context, + bufferdesc: ::std::os::raw::c_uint, + callback: Option< + unsafe extern "C" fn( + callbackData: *mut ::std::os::raw::c_void, + buffer: Buffer, + block: *mut RTmemoryblock, + ) -> ::std::os::raw::c_int, + >, + callback_data: *mut ::std::os::raw::c_void, + buffer: *mut Buffer, + ) -> Result<(), RTresult> { + buffer::create_from_callback(context, bufferdesc, callback, callback_data, buffer) + } + + pub(crate) unsafe fn rtBufferDestroy(buffer: Buffer) -> Result<(), RTresult> { + buffer::destroy(buffer) + } + + pub(crate) unsafe fn rtBufferSetElementSize( + buffer: Buffer, + element_size: u64, + ) -> Result<(), RTresult> { + buffer::set_element_size(buffer, element_size) + } + + pub(crate) unsafe fn rtBufferSetFormat( + buffer: Buffer, + format: RTformat, + ) -> Result<(), RTresult> { + buffer::set_format(buffer, format) + } + + pub(crate) unsafe fn rtBufferSetMipLevelCount( + buffer: Buffer, + levels: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + buffer::set_mip_level_count(buffer, levels) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferSetSize1D(buffer: Buffer, width: RTsize) -> Result<(), RTresult> { + buffer::set_size1d(buffer, width) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferSetSize2D( + buffer: Buffer, + width: RTsize, + height: RTsize, + ) -> Result<(), RTresult> { + buffer::set_size2d(buffer, width, height) + } + + pub(crate) unsafe fn rtBufferGetContext( + buffer: Buffer, + context: *mut Context, + ) -> Result<(), RTresult> { + buffer::get_context(buffer, context) + } + + pub(crate) unsafe fn rtBufferGetDevicePointer( + buffer: Buffer, + optix_device_ordinal: ::std::os::raw::c_int, + device_pointer: *mut *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + buffer::get_device_pointer(buffer, optix_device_ordinal, device_pointer) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferGetDimensionality( + buffer: Buffer, + dimensionality: *mut c_uint, + ) -> Result<(), RTresult> { + buffer::get_dimensionality(buffer, dimensionality) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferGetElementSize( + buffer: Buffer, + elementSize: *mut u64, + ) -> Result<(), RTresult> { + buffer::get_element_size(buffer, elementSize) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferGetGLBOId( + buffer: Buffer, + glid: *mut c_uint, + ) -> Result<(), RTresult> { + buffer::get_glboid(buffer, glid) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferGetFormat( + buffer: Buffer, + format: *mut RTformat, + ) -> Result<(), RTresult> { + buffer::get_format(buffer, format) + } + + pub(crate) unsafe fn rtBufferGetId( + buffer: Buffer, + bufferId: *mut ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + buffer::get_id(buffer, bufferId) + } + + pub(crate) unsafe fn rtBufferGetMipLevelCount( + buffer: Buffer, + level: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + buffer::get_miplevel_count(buffer, level) + } + + pub(crate) unsafe fn rtBufferGetMipLevelSize2D( + buffer: Buffer, + level: ::std::os::raw::c_uint, + width: *mut RTsize, + height: *mut RTsize, + ) -> Result<(), RTresult> { + buffer::get_miplevel_size2d(buffer, level, width, height) + } + + pub(crate) unsafe fn rtBufferGetSize1D( + buffer: Buffer, + width: *mut RTsize, + ) -> Result<(), RTresult> { + buffer::get_size1d(buffer, width) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferGetSize2D( + buffer: Buffer, + width: *mut RTsize, + height: *mut RTsize, + ) -> Result<(), RTresult> { + buffer::get_size2d(buffer, width, height) + } + + pub(crate) unsafe fn rtBufferGetSizev( + buffer: Buffer, + dimensionality: ::std::os::raw::c_uint, + dims: *mut RTsize, + ) -> Result<(), RTresult> { + buffer::get_sizev(buffer, dimensionality, dims) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferMap( + buffer: Buffer, + userPointer: *mut *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + buffer::map(buffer, userPointer) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferMapEx( + buffer: Buffer, + mapFlags: ::std::os::raw::c_uint, + level: ::std::os::raw::c_uint, + userOwned: *mut ::std::os::raw::c_void, + optixOwned: *mut *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + buffer::map_ex(buffer, mapFlags, level, userOwned, optixOwned) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferUnmap(buffer: Buffer) -> Result<(), RTresult> { + buffer::unmap(buffer) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtBufferUnmapEx( + buffer: Buffer, + level: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + buffer::unmap_ex(buffer, level) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtContextCreate(context: *mut Context) -> Result<(), RTresult> { + context::create(context) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtContextDeclareVariable( + context: Context, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + context::declare_variable(context, name, v) + } + + pub(crate) unsafe fn rtContextGetAttribute( + context: Context, + attrib: RTcontextattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + context::get_attribute(context, attrib, size, p) + } + + pub(crate) unsafe fn rtContextGetBufferFromId( + context: Context, + bufferId: ::std::os::raw::c_int, + buffer: *mut Buffer, + ) -> Result<(), RTresult> { + context::get_buffer_from_id(context, bufferId, buffer) + } + + pub(crate) unsafe fn rtContextGetDeviceCount( + context: Context, + count: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + context::get_device_count(context, count) + } + + pub(crate) unsafe fn rtContextGetDevices( + context: Context, + devices: *mut ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + context::get_devices(context, devices) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtContextDestroy(context: Context) -> Result<(), RTresult> { + context::destroy(context) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtContextGetErrorString( + ctx: Context, + code: RTresult, + string_return: *mut *const ::std::os::raw::c_char, + ) { + context::get_error_string(ctx, code, string_return) + } + + pub(crate) unsafe fn rtContextLaunch2D( + context: Context, + entry_point_index: ::std::os::raw::c_uint, + width: u64, + height: u64, + ) -> Result<(), RTresult> { + context::launch_2d(context, entry_point_index, width, height) + } + + pub(crate) unsafe fn rtContextQueryVariable( + context: Context, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + context::query_variable(context, name, v) + } + + pub(crate) unsafe fn rtContextSetAttribute( + context: Context, + attrib: RTcontextattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + context::set_attribute(context, attrib, size, p) + } + + pub(crate) unsafe fn rtContextSetDevices( + context: Context, + count: ::std::os::raw::c_uint, + devices: *const ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + context::set_devices(context, count, devices) + } + + pub(crate) unsafe fn rtContextSetEntryPointCount( + context: Context, + count: c_uint, + ) -> Result<(), RTresult> { + context::set_entry_point_count(context, count) + } + + pub(crate) fn rtContextSetExceptionEnabled( + context: Context, + exception: RTexception, + enabled: ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + context::set_exception_enabled(context, exception, enabled) + } + + pub(crate) unsafe fn rtContextSetExceptionProgram( + context: Context, + entry_point_index: ::std::os::raw::c_uint, + program: Program, + ) -> Result<(), RTresult> { + context::set_exception_program(context, entry_point_index, program) + } + + pub(crate) unsafe fn rtContextSetMaxCallableProgramDepth( + context: Context, + maxDepth: ::std::os::raw::c_uint, + ) -> RTresult { + context::set_max_callable_program_depth(context, maxDepth) + } + + pub(crate) unsafe fn rtContextSetMaxTraceDepth( + context: Context, + max_depth: u32, + ) -> Result<(), RTresult> { + context::set_max_depth(context, max_depth) + } + + pub(crate) unsafe fn rtContextSetMissProgram( + context: Context, + ray_type_index: ::std::os::raw::c_uint, + program: Program, + ) -> Result<(), RTresult> { + context::set_miss_program(context, ray_type_index, program) + } + + pub(crate) unsafe fn rtContextSetPrintEnabled( + context: Context, + enabled: ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + context::set_print_enabled(context, enabled) + } + + pub(crate) unsafe fn rtContextSetPrintLaunchIndex( + context: Context, + x: ::std::os::raw::c_int, + y: ::std::os::raw::c_int, + z: ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + context::set_print_launch_index(context, x, y, z) + } + + pub(crate) unsafe fn rtContextSetRayGenerationProgram( + context: Context, + entry_point_index: ::std::os::raw::c_uint, + program: Program, + ) -> Result<(), RTresult> { + context::set_ray_generation_program(context, entry_point_index, program) + } + + pub(crate) unsafe fn rtContextSetRayTypeCount( + context: Context, + ray_type_count: c_uint, + ) -> Result<(), RTresult> { + context::set_ray_type_count(context, ray_type_count) + } + + pub(crate) unsafe fn rtContextSetStackSize( + context: Context, + bytes: u64, + ) -> Result<(), RTresult> { + context::set_stack_size(context, bytes) + } + + pub(crate) fn rtContextSetUsageReportCallback( + context: Context, + callback: RTusagereportcallback, + verbosity: ::std::os::raw::c_int, + cbdata: *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + context::set_usage_report_callback(context, callback, verbosity, cbdata) + } + + pub(crate) unsafe fn rtContextValidate(context: Context) -> Result<(), RTresult> { + context::validate(context) + } + + pub(crate) unsafe fn rtDeviceGetAttribute( + ordinal: ::std::os::raw::c_int, + attrib: RTdeviceattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + super::device_get_attribute(ordinal, attrib, size, p) + } + + pub(crate) unsafe fn rtDeviceGetDeviceCount(device_count: *mut u32) -> RTresult { + super::device_get_count(device_count) + } + + pub(crate) unsafe fn rtGeometryCreate( + context: Context, + geometry: *mut Geometry, + ) -> Result<(), RTresult> { + geometry::create(context, geometry) + } + + pub(crate) unsafe fn rtGeometryDeclareVariable( + geometry: Geometry, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry::declare_variable(geometry, name, v) + } + + pub(crate) unsafe fn rtGeometryDestroy(geometry: Geometry) -> Result<(), RTresult> { + geometry::destroy(geometry) + } + + pub(crate) unsafe fn rtGeometryGetContext(geometry: Geometry, context: *mut Context) -> Result<(), RTresult> { + geometry::get_context(geometry, context) + } + + pub(crate) unsafe fn rtGeometryQueryVariable( + geometry: Geometry, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry::query_variable(geometry, name, v) + } + + pub(crate) unsafe fn rtGeometrySetPrimitiveCount( + geometry: Geometry, + primitiveCount: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + geometry::set_primitive_count(geometry, primitiveCount) + } + + pub(crate) unsafe fn rtGeometrySetBoundingBoxProgram( + geometry: Geometry, + program: Program, + ) -> Result<(), RTresult> { + geometry::set_bounding_box_program(geometry, program) + } + + pub(crate) unsafe fn rtGeometrySetIntersectionProgram( + geometry: Geometry, + program: Program, + ) -> Result<(), RTresult> { + geometry::set_intersection_program(geometry, program) + } + + pub(crate) unsafe fn rtGeometryGroupCreate( + context: Context, + geometrygroup: *mut GeometryGroup, + ) -> Result<(), RTresult> { + geometry_group::create(context, geometrygroup) + } + + pub(crate) unsafe fn rtGeometryGroupDestroy( + geometrygroup: GeometryGroup, + ) -> Result<(), RTresult> { + geometry_group::destroy(geometrygroup) + } + + pub(crate) unsafe fn rtGeometryGroupGetChildCount( + geometrygroup: GeometryGroup, + count: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + geometry_group::get_child_count(geometrygroup, count) + } + + pub(crate) unsafe fn rtGeometryGroupGetContext( + geometrygroup: GeometryGroup, + context: *mut Context, + ) -> Result<(), RTresult> { + geometry_group::get_context(geometrygroup, context) + } + + pub(crate) unsafe fn rtGeometryGroupSetAcceleration( + geometrygroup: GeometryGroup, + acceleration: Acceleration, + ) -> Result<(), RTresult> { + geometry_group::set_acceleration(geometrygroup, acceleration) + } + + pub(crate) unsafe fn rtGeometryGroupSetChild( + geometrygroup: GeometryGroup, + index: ::std::os::raw::c_uint, + geometryinstance: GeometryInstance, + ) -> Result<(), RTresult> { + geometry_group::set_child(geometrygroup, index, geometryinstance) + } + + pub(crate) unsafe fn rtGeometryGroupSetChildCount( + geometrygroup: GeometryGroup, + count: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + geometry_group::set_child_count(geometrygroup, count) + } + + pub(crate) unsafe fn rtGeometryGroupSetVisibilityMask( + geometrygroup: GeometryGroup, + mask: RTvisibilitymask, + ) -> Result<(), RTresult> { + geometry_group::set_visibility_mask(geometrygroup, mask) + } + + pub(crate) unsafe fn rtGeometryInstanceCreate( + context: Context, + geometryinstance: *mut GeometryInstance, + ) -> Result<(), RTresult> { + geometry_instance::create(context, geometryinstance) + } + + pub(crate) unsafe fn rtGeometryInstanceDeclareVariable( + geometryinstance: GeometryInstance, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry_instance::declare_variable(geometryinstance, name, v) + } + + pub(crate) unsafe fn rtGeometryInstanceDestroy( + geometryinstance: GeometryInstance, + ) -> Result<(), RTresult> { + geometry_instance::destroy(geometryinstance) + } + + pub(crate) unsafe fn rtGeometryInstanceQueryVariable( + geometryinstance: GeometryInstance, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry_instance::query_variable(geometryinstance, name, v) + } + + pub(crate) unsafe fn rtGeometryInstanceGetContext( + geometryinstance: GeometryInstance, + context: *mut Context, + ) -> Result<(), RTresult> { + geometry_instance::get_context(geometryinstance, context) + } + + pub(crate) unsafe fn rtGeometryInstanceGetMaterialCount( + geometryinstance: GeometryInstance, + count: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + geometry_instance::get_material_count(geometryinstance, count) + } + + pub(crate) unsafe fn rtGeometryInstanceSetGeometry( + geometryinstance: GeometryInstance, + geometry: Geometry, + ) -> Result<(), RTresult> { + geometry_instance::set_geometry(geometryinstance, geometry) + } + + pub(crate) unsafe fn rtGeometryInstanceSetGeometryTriangles( + geometryinstance: GeometryInstance, + geometrytriangles: GeometryTriangles, + ) -> Result<(), RTresult> { + geometry_instance::set_geometry_triangles(geometryinstance, geometrytriangles) + } + + pub(crate) unsafe fn rtGeometryInstanceSetMaterial( + geometryinstance: GeometryInstance, + index: ::std::os::raw::c_uint, + material: Material, + ) -> Result<(), RTresult> { + geometry_instance::set_material(geometryinstance, index, material) + } + + pub(crate) unsafe fn rtGeometryInstanceSetMaterialCount( + geometryinstance: GeometryInstance, + count: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + geometry_instance::set_material_count(geometryinstance, count) + } + + pub(crate) unsafe fn rtGeometryTrianglesCreate( + context: Context, + geometrytriangles: *mut GeometryTriangles, + ) -> Result<(), RTresult> { + geometry_triangles::create(context, geometrytriangles) + } + + pub(crate) unsafe fn rtGeometryTrianglesDeclareVariable( + geometrytriangles: GeometryTriangles, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry_triangles::declare_variable(geometrytriangles, name, v) + } + + pub(crate) unsafe fn rtGeometryTrianglesDestroy( + geometrytriangles: GeometryTriangles, + ) -> Result<(), RTresult> { + geometry_triangles::destroy(geometrytriangles) + } + + pub(crate) unsafe fn rtGeometryTrianglesGetContext( + geometrytriangles: GeometryTriangles, + context: *mut Context, + ) -> Result<(), RTresult> { + geometry_triangles::get_context(geometrytriangles, context) + } + + pub(crate) unsafe fn rtGeometryTrianglesSetAttributeProgram( + geometrytriangles: GeometryTriangles, + program: Program, + ) -> Result<(), RTresult> { + geometry_triangles::set_attribute(geometrytriangles, program) + } + + pub(crate) unsafe fn rtGeometryTrianglesSetBuildFlags( + geometrytriangles: GeometryTriangles, + _buildFlags: RTgeometrybuildflags, + ) -> Result<(), RTresult> { + geometry_triangles::set_build_flags(geometrytriangles, _buildFlags) + } + + pub(crate) unsafe fn rtGeometryTrianglesSetFlagsPerMaterial( + geometrytriangles: GeometryTriangles, + materialIndex: ::std::os::raw::c_uint, + flags: RTgeometryflags, + ) -> Result<(), RTresult> { + geometry_triangles::set_flags_per_material(geometrytriangles, materialIndex, flags) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtGeometryTrianglesSetPrimitiveCount( + geometrytriangles: GeometryTriangles, + triangle_count: c_uint, + ) -> Result<(), RTresult> { + geometry_triangles::set_primitive_count(geometrytriangles, triangle_count) + } + + pub(crate) unsafe fn rtGeometryTrianglesSetTriangleIndices( + geometrytriangles: GeometryTriangles, + indexBuffer: Buffer, + indexBufferByteOffset: u64, + triIndicesByteStride: u64, + triIndicesFormat: RTformat, + ) -> Result<(), RTresult> { + geometry_triangles::set_triangle_indices( + geometrytriangles, + indexBuffer, + indexBufferByteOffset, + triIndicesByteStride, + triIndicesFormat, + ) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtGeometryTrianglesSetVertices( + geometrytriangles: GeometryTriangles, + vertexCount: ::std::os::raw::c_uint, + vertexBuffer: Buffer, + vertexBufferByteOffset: u64, + vertexByteStride: u64, + positionFormat: RTformat, + ) -> Result<(), RTresult> { + geometry_triangles::set_vertices( + geometrytriangles, + vertexCount, + vertexBuffer, + vertexBufferByteOffset, + vertexByteStride, + positionFormat, + ) + } + + pub(crate) unsafe fn rtGeometryTrianglesQueryVariable( + geometrytriangles: GeometryTriangles, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + geometry_triangles::query_variable(geometrytriangles, name, v) + } + + pub(crate) unsafe fn rtGeometryTrianglesValidate( + geometrytriangles: GeometryTriangles, + ) -> Result<(), RTresult> { + geometry_triangles::validate(geometrytriangles) + } + + pub(crate) unsafe fn rtGetVersion(version: *mut u32) -> RTresult { + super::get_version(version) + } + + pub(crate) unsafe fn rtGlobalGetAttribute( + attrib: RTglobalattribute, + size: RTsize, + p: *mut ::std::os::raw::c_void, + ) -> RTresult { + super::global_get_attribute(attrib, size, p) + } + + pub(crate) unsafe fn rtGlobalSetAttribute( + attrib: RTglobalattribute, + size: RTsize, + p: *const ::std::os::raw::c_void, + ) -> RTresult { + super::global_set_attribute(attrib, size, p) + } + + pub(crate) unsafe fn rtGroupCreate( + context: Context, + group: *mut Group, + ) -> Result<(), RTresult> { + group::create(context, group) + } + + pub(crate) unsafe fn rtGroupDestroy(group: Group) -> Result<(), RTresult> { + group::destroy(group) + } + + pub(crate) unsafe fn rtGroupGetAcceleration( + group: Group, + acceleration: *mut Acceleration, + ) -> Result<(), RTresult> { + group::get_acceleration(group, acceleration) + } + + pub(crate) unsafe fn rtGroupGetChild( + group: Group, + index: ::std::os::raw::c_uint, + child: *mut UntypedObject, + ) -> Result<(), RTresult> { + group::get_child(group, index, child) + } + + pub(crate) unsafe fn rtGroupGetChildCount( + group: Group, + count: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + group::get_child_count(group, count) + } + + pub(crate) unsafe fn rtGroupGetContext( + group: Group, + context: *mut Context, + ) -> Result<(), RTresult> { + group::get_context(group, context) + } + + pub(crate) unsafe fn rtGroupSetAcceleration( + group: Group, + acceleration: Acceleration, + ) -> Result<(), RTresult> { + group::set_acceleration(group, acceleration) + } + + pub(crate) unsafe fn rtGroupSetChild( + group: Group, + index: ::std::os::raw::c_uint, + child: UntypedObject, + ) -> Result<(), RTresult> { + group::set_child(group, index, child) + } + + pub(crate) unsafe fn rtGroupSetChildCount( + group: Group, + count: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + group::set_child_count(group, count) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtMaterialCreate( + context: Context, + material: *mut Material, + ) -> Result<(), RTresult> { + material::create(context, material) + } + + pub(crate) unsafe fn rtMaterialDeclareVariable( + material: Material, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + material::declare_variable(material, name, v) + } + + pub(crate) unsafe fn rtMaterialDestroy(material: Material) -> Result<(), RTresult> { + material::destroy(material) + } + + pub(crate) unsafe fn rtMaterialGetContext( + material: Material, + context: *mut Context, + ) -> Result<(), RTresult> { + material::get_context(material, context) + } + + pub(crate) unsafe fn rtMaterialQueryVariable( + material: Material, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + material::query_variable(material, name, v) + } + + pub(crate) unsafe fn rtMaterialSetAnyHitProgram( + material: Material, + rayTypeIndex: ::std::os::raw::c_uint, + program: Program, + ) -> Result<(), RTresult> { + material::set_any_hit_program(material, rayTypeIndex, program) + } + + pub(crate) unsafe fn rtMaterialSetClosestHitProgram( + material: Material, + rayTypeIndex: ::std::os::raw::c_uint, + program: Program, + ) -> Result<(), RTresult> { + material::set_closest_hit_program(material, rayTypeIndex, program) + } + + pub(crate) unsafe fn rtProgramCreateFromProgram( + context: Context, + program_in: Program, + program_out: *mut Program, + ) -> Result<(), RTresult> { + program::create_from_program(context, program_in, program_out) + } + + pub(crate) unsafe fn rtProgramCreateFromPTXFile( + context: Context, + filename: *const ::std::os::raw::c_char, + program_name: *const ::std::os::raw::c_char, + program: *mut Program, + ) -> Result<(), RTresult> { + program::create_from_ptx_file(context, filename, program_name, program) + } + + pub(crate) unsafe fn rtProgramCreateFromPTXString( + context: Context, + ptx: *const ::std::os::raw::c_char, + program_name: *const ::std::os::raw::c_char, + program: *mut Program, + ) -> Result<(), RTresult> { + program::create_from_ptx_string(context, ptx, program_name, program) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtProgramDeclareVariable( + program: Program, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + program::declare_variable(program, name, v) + } + + pub(crate) unsafe fn rtProgramDestroy(program: Program) -> Result<(), RTresult> { + program::destroy(program) + } + + pub(crate) unsafe fn rtProgramGetContext(program: Program, context: *mut Context) -> Result<(), RTresult> { + program::get_context(program, context) + } + + pub(crate) unsafe fn rtProgramGetId( + program: Program, + program_id: *mut ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + program::get_id(program, program_id) + } + + pub(crate) unsafe fn rtProgramQueryVariable( + program: Program, + name: *const ::std::os::raw::c_char, + v: *mut Variable, + ) -> Result<(), RTresult> { + program::query_variable(program, name, v) + } + + pub(crate) unsafe fn rtProgramValidate(program: Program) -> Result<(), RTresult> { + program::validate(program) + } + + pub(crate) unsafe fn rtTextureSamplerCreate( + context: Context, + texturesampler: *mut TextureSampler, + ) -> Result<(), RTresult> { + texture_sampler::create(context, texturesampler) + } + + pub(crate) unsafe fn rtTextureSamplerDestroy( + texturesampler: TextureSampler, + ) -> Result<(), RTresult> { + texture_sampler::destroy(texturesampler) + } + + pub(crate) unsafe fn rtTextureSamplerGetBuffer( + texturesampler: TextureSampler, + deprecated0: ::std::os::raw::c_uint, + deprecated1: ::std::os::raw::c_uint, + buffer: *mut Buffer, + ) -> Result<(), RTresult> { + texture_sampler::get_buffer(texturesampler, deprecated0, deprecated1, buffer) + } + + pub(crate) unsafe fn rtTextureSamplerGetContext( + texturesampler: TextureSampler, + context: *mut Context, + ) -> Result<(), RTresult> { + texture_sampler::get_context(texturesampler, context) + } + + pub(crate) unsafe fn rtTextureSamplerGetId( + texturesampler: TextureSampler, + textureId: *mut ::std::os::raw::c_int, + ) -> Result<(), RTresult> { + texture_sampler::get_id(texturesampler, textureId) + } + + pub(crate) unsafe fn rtTextureSamplerSetArraySize( + texturesampler: TextureSampler, + textureCount: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + texture_sampler::set_array_size(texturesampler, textureCount) + } + + pub(crate) unsafe fn rtTextureSamplerSetBuffer( + texturesampler: TextureSampler, + _deprecated0: ::std::os::raw::c_uint, + _deprecated1: ::std::os::raw::c_uint, + buffer: Buffer, + ) -> Result<(), RTresult> { + texture_sampler::set_buffer(texturesampler, buffer) + } + + pub(crate) unsafe fn rtTextureSamplerSetFilteringModes( + texturesampler: TextureSampler, + minification: RTfiltermode, + magnification: RTfiltermode, + mipmapping: RTfiltermode, + ) -> Result<(), RTresult> { + texture_sampler::set_filtering_modes( + texturesampler, + minification, + magnification, + mipmapping, + ) + } + + pub(crate) unsafe fn rtTextureSamplerSetIndexingMode( + texturesampler: TextureSampler, + indexmode: RTtextureindexmode, + ) -> Result<(), RTresult> { + texture_sampler::set_indexing_mode(texturesampler, indexmode) + } + + pub(crate) unsafe fn rtTextureSamplerSetMaxAnisotropy( + texturesampler: TextureSampler, + value: f32, + ) -> Result<(), RTresult> { + texture_sampler::set_max_anisotropy(texturesampler, value) + } + + pub(crate) unsafe fn rtTextureSamplerSetMipLevelCount( + texturesampler: TextureSampler, + mipLevelCount: ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + texture_sampler::set_mip_level_count(texturesampler, mipLevelCount) + } + + pub(crate) unsafe fn rtTextureSamplerSetReadMode( + texturesampler: TextureSampler, + readmode: RTtexturereadmode, + ) -> Result<(), RTresult> { + texture_sampler::set_read_mode(texturesampler, readmode) + } + + pub(crate) unsafe fn rtTextureSamplerSetWrapMode( + texturesampler: TextureSampler, + dimension: ::std::os::raw::c_uint, + wrapmode: RTwrapmode, + ) -> Result<(), RTresult> { + texture_sampler::set_wrap_mode(texturesampler, dimension, wrapmode) + } + + pub(crate) unsafe fn rtTransformCreate( + context: Context, + transform: *mut Transform, + ) -> Result<(), RTresult> { + transform::create(context, transform) + } + + pub(crate) unsafe fn rtTransformDestroy(transform: Transform) -> Result<(), RTresult> { + transform::destroy(transform) + } + + pub(crate) unsafe fn rtTransformGetContext(transform: Transform, context: *mut Context) -> Result<(), RTresult> { + transform::get_context(transform, context) + } + + pub(crate) unsafe fn rtTransformGetMotionKeyCount( + transform: Transform, + n: *mut ::std::os::raw::c_uint, + ) -> Result<(), RTresult> { + transform::get_motion_key_count(transform, n) + } + + pub(crate) unsafe fn rtTransformSetChild( + transform: Transform, + child: UntypedObject, + ) -> Result<(), RTresult> { + transform::set_child(transform, child) + } + + pub(crate) unsafe fn rtTransformSetMatrix( + transform: Transform, + transpose: i32, + matrix: *const f32, + inverse_matrix: *const f32, + ) -> Result<(), RTresult> { + transform::set_matrix(transform, transpose, matrix, inverse_matrix) + } + + pub(crate) unsafe fn rtVariableSetObject( + v: Variable, + object: UntypedObject, + ) -> Result<(), RTresult> { + variable::set_object(v, object) + } + + pub(crate) unsafe fn rtVariableGetObject( + v: Variable, + object: *mut UntypedObject, + ) -> Result<(), RTresult> { + variable::get_object(v, object) + } + + pub(crate) unsafe fn rtVariableSet1f(v: Variable, f1: f32) -> Result<(), RTresult> { + variable::set_1f(v, f1) + } + + pub(crate) unsafe fn rtVariableSet1i(v: Variable, i1: c_int) -> Result<(), RTresult> { + variable::set_1i(v, i1) + } + + pub(crate) unsafe fn rtVariableSet1ui(v: Variable, u1: u32) -> Result<(), RTresult> { + variable::set_1ui(v, u1) + } + + pub(crate) unsafe fn rtVariableSet1ull( + v: Variable, + ull1: ::std::os::raw::c_ulonglong, + ) -> Result<(), RTresult> { + variable::set_1ull(v, ull1) + } + + #[allow(non_snake_case)] + pub(crate) unsafe fn rtVariableSet3f( + v: Variable, + f1: f32, + f2: f32, + f3: f32, + ) -> Result<(), RTresult> { + variable::set_3f(v, f1, f2, f3) + } + + pub(crate) unsafe fn rtVariableSet3fv(v: Variable, f: *const f32) -> Result<(), RTresult> { + variable::set_3fv(v, f) + } + + pub(crate) unsafe fn rtVariableSet4f( + v: Variable, + f1: f32, + f2: f32, + f3: f32, + f4: f32, + ) -> Result<(), RTresult> { + variable::set_4f(v, f1, f2, f3, f4) + } + + pub(crate) unsafe fn rtVariableSet4fv(v: Variable, f: *const f32) -> Result<(), RTresult> { + variable::set_4fv(v, f) + } + + pub(crate) unsafe fn rtVariableSetUserData( + v: Variable, + size: RTsize, + ptr: *const ::std::os::raw::c_void, + ) -> Result<(), RTresult> { + variable::set_user_data(v, size, ptr) + } +} + +pub(crate) unsafe fn get_version(version: *mut u32) -> RTresult { + *version = 60600; + RTresult::RT_SUCCESS +} + +pub(crate) unsafe fn device_get_count(device_count: *mut u32) -> RTresult { + *device_count = 1; + RTresult::RT_SUCCESS +} + +pub(crate) unsafe fn device_get_attribute( + ordinal: i32, + attrib: RTdeviceattribute, + size: u64, + p: *mut c_void, +) -> Result<(), RTresult> { + Ok(match attrib { + RTdeviceattribute::RT_DEVICE_ATTRIBUTE_CLOCK_RATE => { + hip! { hipDeviceGetAttribute( + p as _, + hipDeviceAttribute_t::hipDeviceAttributeClockRate, + ordinal, + ), RT_ERROR_UNKNOWN } + } + RTdeviceattribute::RT_DEVICE_ATTRIBUTE_NAME => { + let dev_name = "Graphics Device"; + let strlen = dev_name.len().min(size as usize - 1); + ptr::copy_nonoverlapping(dev_name.as_ptr(), p as _, strlen); + *(p as *mut u8).add(strlen) = 0; + } + RTdeviceattribute::RT_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY => { + *(p as *mut [u32; 2]) = [8u32, 6u32]; + } + RTdeviceattribute::RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY => { + hip! { hipDeviceTotalMem( + p as _, + ordinal, + ), RT_ERROR_UNKNOWN } + } + RTdeviceattribute::RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL => *(p as *mut i32) = ordinal, + _ => return Err(definitions::unimplemented()), + }) +} + +pub(crate) unsafe fn global_set_attribute( + attrib: RTglobalattribute, + _size: u64, + _p: *const c_void, +) -> RTresult { + match attrib { + RTglobalattribute::RT_GLOBAL_ATTRIBUTE_ENABLE_RTX => RTresult::RT_SUCCESS, + // TODO: reverse + RTglobalattribute(268435457) | optix_types::RTglobalattribute(4096) => { + return RTresult::RT_ERROR_NOT_SUPPORTED + } + _ => definitions::unimplemented(), + } +} + +fn global_get_attribute(_attrib: RTglobalattribute, _size: u64, _p: *mut c_void) -> RTresult { + RTresult::RT_ERROR_NOT_SUPPORTED +} diff --git a/zluda_rt/src/material.rs b/zluda_rt/src/material.rs new file mode 100644 index 0000000..4186165 --- /dev/null +++ b/zluda_rt/src/material.rs @@ -0,0 +1,142 @@ +use crate::{ + context::{self, Context, ContextData}, + null_check, null_unwrap, + program::{Program, ProgramData}, + variable::{Variable, VariableData}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use optix_types::*; +use rustc_hash::FxHashMap; +use std::{ + ffi::{CStr, CString}, + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Material = *const OptixCell; + +pub(crate) struct MaterialData { + pub(crate) context: Weak>, + pub(crate) variables: FxHashMap>>, + pub(crate) any_hit_programs: FxHashMap>>, + pub(crate) closest_hit_programs: FxHashMap>>, +} + +impl MaterialData { + fn new(weak_context: Weak>, _: &mut ContextData) -> Self { + Self { + context: weak_context, + variables: FxHashMap::default(), + any_hit_programs: FxHashMap::default(), + closest_hit_programs: FxHashMap::default(), + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.materials.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } +} + +impl OptixObjectData for MaterialData { + const TYPE: TypeTag = TypeTag::Material; + + fn deregister(&mut self, this: &std::rc::Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.materials.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) unsafe fn create(context: Context, material: *mut Material) -> Result<(), RTresult> { + null_check(context)?; + null_check(material)?; + *material = MaterialData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn declare_variable( + material_ptr: Material, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(v)?; + let material = null_unwrap(material_ptr)?; + let mut material = material.borrow_mut()?; + let variable = VariableData::new(&mut *material)?; + let name = CStr::from_ptr(name).to_owned(); + let result = Rc::as_ptr(&variable); + material.variables.insert(name, variable); + *v = result; + Ok(()) +} + +pub(crate) unsafe fn query_variable( + material_ptr: Material, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let material = null_unwrap(material_ptr)?; + let material = material.borrow()?; + *v = material + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) unsafe fn set_any_hit_program( + material: Material, + ray_type_index: u32, + program: Program, +) -> Result<(), RTresult> { + null_check(program)?; + let material = null_unwrap(material)?; + let mut material = material.borrow_mut()?; + material + .any_hit_programs + .insert(ray_type_index, OptixCell::clone_rc(program)); + Ok(()) +} + +pub(crate) unsafe fn set_closest_hit_program( + material: Material, + ray_type_index: u32, + program: Program, +) -> Result<(), RTresult> { + null_check(program)?; + let material = null_unwrap(material)?; + let mut material = material.borrow_mut()?; + material + .closest_hit_programs + .insert(ray_type_index, OptixCell::clone_rc(program)); + Ok(()) +} + +pub(crate) unsafe fn get_context( + material: Material, + context: *mut Context, +) -> Result<(), RTresult> { + null_check(context)?; + let material = null_unwrap(material)?; + let material = material.borrow()?; + *context = Weak::as_ptr(&material.context); + Ok(()) +} + +pub(crate) fn destroy(_material: Material) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} diff --git a/zluda_rt/src/program.rs b/zluda_rt/src/program.rs new file mode 100644 index 0000000..8865018 --- /dev/null +++ b/zluda_rt/src/program.rs @@ -0,0 +1,720 @@ +use crate::context::ContextData; +use crate::geometry::GeometryData; +use crate::geometry_instance::GeometryInstanceData; +use crate::geometry_triangles::GeometryTrianglesData; +use crate::material::MaterialData; +use crate::repr_gpu::TrivialHIPAllocator; +use crate::{ + context::Context, + null_check, null_unwrap, null_unwrap_mut, + variable::{Variable, VariableData}, + OptixCell, OptixObjectData, TypeTag, +}; +use crate::{div_positive_round_up, eptx, hip, hiprt, repr_gpu, AlignedBuffer, MaybeWeakRefMut}; +use comgr::Comgr; +use hip_common::raytracing::VariablesBlock; +use hip_runtime_sys::*; +use hiprt_sys::*; +use optix_types::*; +use ptx::{llvm, raytracing, ModuleParserExt}; +use rustc_hash::FxHashMap; +use std::alloc::Layout; +use std::ffi::c_void; +use std::mem::{self, ManuallyDrop}; +use std::rc::Weak; +use std::{ + ffi::{CStr, CString}, + rc::Rc, +}; +use std::{iter, ptr}; + +pub(crate) type Program = *const OptixCell; + +pub(crate) struct ProgramData { + pub(crate) context: Weak>, + pub(crate) variables: FxHashMap>>, + pub(crate) variables_block: VariablesBlock, + pub(crate) callable_index: Option, + // this field is shared between instances created by cloning existing program object + pub(crate) shared: Rc, +} + +pub(crate) struct ProgramShared { + pub(crate) binary: Vec, + pub(crate) module: hip::Module, +} + +impl OptixObjectData for ProgramData { + const TYPE: TypeTag = TypeTag::Program; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.programs.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +impl ProgramData { + pub(crate) const KERNEL_BOUNDING_BOX_NAME: &'static CStr = + raytracing::Module::KERNEL_BOUNDING_BOX_NAME; + pub(crate) const KERNEL_NAME: &'static CStr = raytracing::Module::KERNEL_NAME; + pub(crate) const ATTRIBUTE_FUNCTION_POINTER_NAME: &'static CStr = + raytracing::Module::ATTRIBUTE_FUNCTION_POINTER_NAME; + pub(crate) const FUNCTION_POINTER_NAME: &'static CStr = + raytracing::Module::FUNCTION_POINTER_NAME; + + pub(crate) fn get_program_block_layout(&self) -> Result { + Ok(self.variables_block.layout) + } + + pub(crate) fn try_from_binary( + context: Weak>, + binary: Vec, + ) -> Option<(Self, VariablesBlock)> { + let zluda_rt6_section = hip_common::kernel_metadata::get_section( + hip_common::kernel_metadata::zluda_rt6::SECTION_STR, + &*binary, + )?; + let zluda_rt6_metadata = + hip_common::kernel_metadata::zluda_rt6::read(&zluda_rt6_section).ok()?; + let module = hip::Module::load_data(&binary).ok()?; + Some(( + ProgramData { + context, + variables: FxHashMap::default(), + variables_block: zluda_rt6_metadata.variables, + callable_index: if zluda_rt6_metadata.is_callable { + Some(0) + } else { + None + }, + shared: Rc::new(ProgramShared { binary, module }), + }, + zluda_rt6_metadata.attribute_variables, + )) + } + + pub(crate) fn copy_program_block<'a>( + &'a self, + dst_buffer: &mut [u8], + get_variable: impl Fn(&CStr) -> Option<&'a Rc>>, + ) -> Result<(), RTresult> { + self.copy_program_block_impl(false, dst_buffer, get_variable) + } + + pub(crate) fn copy_attribute_program_block<'a>( + &'a self, + dst_buffer: &mut [u8], + get_variable: impl Fn(&CStr) -> Option<&'a Rc>>, + ) -> Result<(), RTresult> { + self.copy_program_block_impl(true, dst_buffer, get_variable) + } + + fn copy_program_block_impl<'a>( + &'a self, + is_attribute: bool, + dst_buffer: &mut [u8], + get_variable: impl Fn(&CStr) -> Option<&'a Rc>>, + ) -> Result<(), RTresult> { + let fn_ptr = if is_attribute { + self.get_attribute_function() + } else { + self.get_function() + }?; + dst_buffer[..mem::size_of::()] + .copy_from_slice(&(fn_ptr.0 as usize).to_ne_bytes()); + Self::copy_variable_block(&self.variables_block, dst_buffer, get_variable) + } + + pub(crate) fn copy_variable_block<'a>( + variables_block: &VariablesBlock, + dst_buffer: &mut [u8], + get_variable: impl Fn(&CStr) -> Option<&'a Rc>>, + ) -> Result<(), RTresult> { + for (name, var_details) in variables_block.variables.iter() { + match get_variable(name) { + Some(variable) => { + let variable = variable.borrow()?; + let variable_offset = var_details.offset as usize; + variable.copy_into_buffer( + &mut dst_buffer + [variable_offset..variable_offset + var_details.size as usize], + )?; + } + None => { + if var_details.default_value.len() == 0 { + continue; + } + if var_details.default_value.len() != var_details.size as usize { + return Err(RTresult::RT_ERROR_UNKNOWN); + } + let variable_offset = var_details.offset as usize; + dst_buffer[variable_offset..variable_offset + var_details.size as usize] + .copy_from_slice(&*var_details.default_value); + } + }; + } + Ok(()) + } + + pub(crate) fn launch_2d( + &self, + width: u32, + height: u32, + globals: &repr_gpu::GlobalState, + mut stack: hipDeviceptr_t, + mut variable_block: hipDeviceptr_t, + (mut exception, mut exception_var_block): (hipDeviceptr_t, hipDeviceptr_t), + ) -> Result<(), RTresult> { + let function = self + .shared + .module + .get_function(Self::KERNEL_NAME) + .map_err(|_| RTresult::RT_ERROR_INVALID_CONTEXT)?; + let mut globals = globals.clone(); + globals.width = width; + globals.height = height; + let (grid_dim_x, block_dim_x) = get_launch_dimensions_x(width)?; + let mut params = [ + &mut globals as *mut repr_gpu::GlobalState as *mut c_void, + &mut stack as *mut _ as *mut c_void, + &mut variable_block as *mut _ as *mut c_void, + &mut exception as *mut _ as *mut c_void, + &mut exception_var_block as *mut _ as *mut c_void, + ]; + //println!("enter"); + //let mut unused = String::new(); + //std::io::stdin().read_line(&mut unused).unwrap(); + hip! { + hipModuleLaunchKernel( + function, + grid_dim_x, + height as u32, + 1, + block_dim_x, + 1, + 1, + 0, + ptr::null_mut(), + params.as_mut_ptr() as _, + ptr::null_mut() + ), + RT_ERROR_UNKNOWN + }; + hip! { hipStreamSynchronize(ptr::null_mut()), RT_ERROR_UNKNOWN }; + Ok(()) + } + + pub(crate) fn get_variable_for_kernel<'a>( + &'a self, + context: &'a ContextData, + name: &CStr, + ) -> Option<&Rc>> { + self.variables + .get(name) + .or_else(|| context.variables.get(name)) + } + + pub(crate) fn get_variable_for_function<'a>( + &'a self, + geometry_instance: &'a GeometryInstanceData, + material: &'a MaterialData, + context: &'a ContextData, + name: &CStr, + ) -> Option<&Rc>> { + self.variables + .get(name) + .or_else(|| geometry_instance.variables.get(name)) + .or_else(|| material.variables.get(name)) + .or_else(|| context.variables.get(name)) + } + + pub(crate) fn get_variable_for_attribute<'a>( + &'a self, + geometry_triangles: &'a GeometryTrianglesData, + geometry_instance: &'a GeometryInstanceData, + context: &'a ContextData, + name: &CStr, + ) -> Option<&Rc>> { + self.variables + .get(name) + .or_else(|| geometry_triangles.variables.get(name)) + .or_else(|| geometry_instance.variables.get(name)) + .or_else(|| context.variables.get(name)) + } + + pub(crate) fn get_variable_for_function_non_hit<'a>( + &'a self, + geometry_instance: &'a GeometryInstanceData, + geometry: &'a GeometryData, + context: &'a ContextData, + name: &CStr, + ) -> Option<&Rc>> { + self.variables + .get(name) + .or_else(|| geometry_instance.variables.get(name)) + .or_else(|| geometry.variables.get(name)) + .or_else(|| context.variables.get(name)) + } + + pub(crate) fn prepare_variable_block_for_kernel( + &self, + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + ) -> Result { + let mut staging_buffer = AlignedBuffer::new(self.variables_block.layout); + Self::copy_variable_block( + &self.variables_block, + staging_buffer.as_bytes_mut(), + |name| self.get_variable_for_kernel(&*context, name), + )?; + allocator.copy_to_device(staging_buffer.as_bytes()) + } + + pub(crate) fn prepare_variable_block_for_function_non_hit<'a>( + &self, + allocator: &mut TrivialHIPAllocator, + geometry_instance: &'a GeometryInstanceData, + geometry: &GeometryData, + context: &'a ContextData, + ) -> Result { + let mut staging_buffer = AlignedBuffer::new(self.variables_block.layout); + ProgramData::copy_variable_block( + &self.variables_block, + staging_buffer.as_bytes_mut(), + |name| { + self.get_variable_for_function_non_hit(geometry_instance, geometry, &context, name) + }, + )?; + allocator.copy_to_device(staging_buffer.as_bytes()) + } + + pub fn get_attribute_function(&self) -> Result { + unsafe { + self.shared + .module + .get_global(Self::ATTRIBUTE_FUNCTION_POINTER_NAME) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + } + + pub fn get_function(&self) -> Result { + unsafe { + self.shared + .module + .get_global(Self::FUNCTION_POINTER_NAME) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + } + + unsafe fn create_from( + &self, + context_wrapper: &OptixCell, + context: &mut ContextData, + ) -> Result { + let callable_index = self.callable_index.map(|_| { + context.callable_program_counter += 1; + context.callable_program_counter + }); + let context_wrapper = OptixCell::clone_weak(context_wrapper); + let new_program = Rc::new(OptixCell::new(ProgramData { + context: context_wrapper, + variables: FxHashMap::default(), + variables_block: self.variables_block.clone(), + callable_index, + shared: self.shared.clone(), + })); + let program_ptr = Rc::as_ptr(&new_program); + context.programs.insert(new_program); + Ok(program_ptr) + } +} + +pub(crate) fn get_launch_dimensions_x(width: u32) -> Result<(u32, u32), RTresult> { + let block_size = 32; + Ok(( + div_positive_round_up(width as u64, block_size as u64) as u32, + block_size, + )) +} + +pub(crate) unsafe fn create_from_ptx_file( + context: Context, + filename: *const i8, + program_name: *const i8, + program: *mut Program, +) -> Result<(), RTresult> { + null_check(filename)?; + let path = CStr::from_ptr(filename) + .to_str() + .map_err(|_| RTresult::RT_ERROR_INVALID_VALUE)?; + let file = std::fs::read(path).map_err(|_| RTresult::RT_ERROR_FILE_NOT_FOUND)?; + create_from_ptx(context, PtxInput::Vec(file), program_name, program) +} + +pub(crate) unsafe fn create_from_ptx_string( + context: Context, + ptx: *const i8, + program_name: *const i8, + program: *mut Program, +) -> Result<(), RTresult> { + create_from_ptx( + context, + PtxInput::CStr(CStr::from_ptr(ptx)), + program_name, + program, + ) +} + +unsafe fn create_from_ptx( + raw_context: Context, + ptx: PtxInput, + program_name: *const i8, + program: *mut Program, +) -> Result<(), RTresult> { + let context = null_unwrap(raw_context)?; + null_check(program_name)?; + null_check(program)?; + let program_name = CStr::from_ptr(program_name); + let mut context = context.borrow_mut()?; + let ptx = ptx.decode( + &context.optix_salt[..], + &context.vendor_salt[..], + &context.public_vendor_key[..], + )?; + let mut_context = &mut *context; + let weak_context = Weak::clone(&ManuallyDrop::new(Weak::from_raw(raw_context))); + let (mut program_object, attribute_block, should_save) = + build_or_load(mut_context, weak_context, program_name, &ptx)?; + if let Some(ref mut callable_index) = program_object.callable_index { + mut_context.callable_program_counter += 1; + *callable_index = mut_context.callable_program_counter; + } + if should_save { + if let Some(ref mut cache) = mut_context.cache { + cache.save_program( + &mut_context.compiler_version, + &mut_context.hiprt_version, + &mut_context.isa, + program_name, + &ptx, + &program_object, + &mut_context.cumulative_attributes, + ); + } + } + mut_context.cumulative_attributes = attribute_block; + let program_object = Rc::new(OptixCell::new(program_object)); + let result = Rc::as_ptr(&program_object); + mut_context.programs.insert(program_object); + *program = result; + Ok(()) +} + +fn build_or_load( + mut_context: &mut ContextData, + weak_context: Weak>, + program_name: &CStr, + ptx: &String, +) -> Result<(ProgramData, VariablesBlock, bool), RTresult> { + if let Some(ref mut cache) = mut_context.cache { + if let Some((program, attribute_block)) = cache.try_load_program( + weak_context.clone(), + &mut_context.compiler_version, + &mut_context.hiprt_version, + &mut_context.isa, + program_name, + ptx, + &mut_context.cumulative_attributes, + ) { + return Ok((program, attribute_block, false)); + } + } + unsafe { + build( + weak_context, + &mut_context.hiprt, + &mut_context.comgr, + &mut_context.isa, + &mut_context.cumulative_attributes, + ptx, + program_name, + mut_context.context, + ) + } +} + +enum PtxInput<'a> { + Vec(Vec), + CStr(&'a CStr), +} + +impl<'a> PtxInput<'a> { + unsafe fn decode( + self, + optix_salt: &[u8], + vendor_salt: &[u8], + vendor_key: &[u8], + ) -> Result { + let is_eptx = &self.to_bytes()[..8] == b"eptx0001"; + let mut this = self.to_owned(); + if is_eptx { + let new_len = eptx::decode_ptx(&mut this, optix_salt, vendor_salt, vendor_key).len(); + this.truncate(new_len); + } + String::from_utf8(this).map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + + unsafe fn to_bytes(&self) -> &[u8] { + match self { + PtxInput::Vec(vec) => &vec[..], + PtxInput::CStr(cstr) => cstr.to_bytes(), + } + } + + unsafe fn to_owned(self) -> Vec { + match self { + PtxInput::Vec(vec) => vec, + PtxInput::CStr(cstr) => cstr.to_bytes().to_vec(), + } + } +} + +// TODO: drop rtc program +unsafe fn build( + weak_context: Weak>, + hiprt: &HipRt, + comgr: &Rc, + isa: &CStr, + cumulative_attributes: &VariablesBlock, + text: &str, + program_name: &CStr, + context: hiprtContext, +) -> Result<(ProgramData, VariablesBlock, bool), RTresult> { + let ast = + ptx::ModuleParser::parse_checked(text).map_err(|_| RTresult::RT_ERROR_INVALID_SOURCE)?; + let raytracing_module = ptx::to_llvm_module_for_raytracing( + ast, + std::str::from_utf8_unchecked(program_name.to_bytes()), + cumulative_attributes, + ) + .map_err(|_| RTresult::RT_ERROR_INVALID_SOURCE)?; + let debug_level = if cfg!(debug_assertions) { + b"-g\0".as_ptr() + } else { + b"-g0\0".as_ptr() + }; + let options = [ + debug_level, + // We just want to emit LLVM, we'd use O0, but somehow IR emitted by O0 prevents inling. + // Weirdly, -disable-llvm-optzns produces much bigger code + b"-O1\0".as_ptr(), + // Stop compilation at LLVM + b"-fgpu-rdc\0".as_ptr(), + // hiprtc injects -mcumode which we don't want + b"-mno-cumode\0".as_ptr(), + // Internalization makes so that _rt_trace_time_mask_flags_64 is module-private + // and does not get linked with the code generated by ptx compiler + b"-mllvm\0".as_ptr(), + b"-amdgpu-internalize-symbols=0\0".as_ptr(), + ]; + let mut rt_program = ptr::null_mut::(); + let headers = raytracing_module + .headers + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + let header_names = raytracing_module + .header_names + .iter() + .map(|s| s.as_ptr()) + .collect::>(); + hiprt! { + hiprt.hiprtBuildTraceProgram( + context, + raytracing::Module::KERNEL_NAME.as_ptr(), + raytracing_module.kernel_source.as_ptr() as _, + "zluda_rt_kernel\0".as_ptr() as _, + headers.len() as i32, + headers.as_ptr() as _, + header_names.as_ptr() as _, + options.as_ptr() as _, + options.len() as i32, + (&mut rt_program) as *mut _ as _ + ), + RT_ERROR_INVALID_SOURCE + }; + let main_bitcode = get_bitcode(rt_program)?; + let binary = llvm::MemoryBuffer::create_no_copy(&main_bitcode, false); + let isa_main = CStr::from_bytes_with_nul_unchecked(b"raytracing_main\0"); + let binary = comgr + .compile( + hip_common::CompilationMode::Wave32, + isa, + iter::once((binary, isa_main)) + .chain(raytracing_module.compilation_module.get_bitcode_all()), + &raytracing_module.linker_module, + ) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let module = hip::Module::load_data(&binary).map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + Ok(( + ProgramData { + context: weak_context, + variables: FxHashMap::default(), + variables_block: raytracing_module.variables, + callable_index: if raytracing_module.is_callable { + Some(0) + } else { + None + }, + shared: Rc::new(ProgramShared { binary, module }), + }, + raytracing_module.attribute_variables, + true, + )) +} + +#[cfg(windows)] +const HIPRTC: &'static str = "hiprtc\0"; + +#[cfg(not(windows))] +const HIPRTC: &'static str = "libhiprtc.so\0"; + +unsafe fn get_bitcode(rt_program: *mut c_void) -> Result, RTresult> { + use libloading::{Library, Symbol}; + let hiprtc = Library::new(HIPRTC).map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let hiprtc_get_bitcode_size: Symbol< + unsafe fn(prog: *mut c_void, bitcode_size: *mut usize) -> u32, + > = hiprtc + .get(b"hiprtcGetBitcodeSize\0") + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let hiprtc_get_bitcode: Symbol u32> = hiprtc + .get(b"hiprtcGetBitcode\0") + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + let mut program_size = 0; + let error = hiprtc_get_bitcode_size(rt_program, &mut program_size); + if error != 0 { + return Err(RTresult::RT_ERROR_UNKNOWN); + } + let mut main_bitcode = vec![0u8; program_size]; + let error = hiprtc_get_bitcode(rt_program, main_bitcode.as_mut_ptr()); + if error != 0 { + return Err(RTresult::RT_ERROR_UNKNOWN); + } + Ok(main_bitcode) +} + +pub(crate) unsafe fn declare_variable( + program_ptr: Program, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + let v = null_unwrap_mut(v)?; + let program = null_unwrap(program_ptr)?; + let mut program = program.borrow_mut()?; + let variable = VariableData::new(&mut *program)?; + let name = CStr::from_ptr(name as _).to_owned(); + let result = Rc::as_ptr(&variable); + program.variables.insert(name, variable); + *v = result; + Ok(()) +} + +pub(crate) unsafe fn destroy(program: Program) -> Result<(), RTresult> { + OptixCell::destroy(program) +} + +pub(crate) unsafe fn get_id(program: Program, program_id: *mut i32) -> Result<(), RTresult> { + let program = null_unwrap(program)?; + let program = program.borrow()?; + let callable_id = match program.callable_index { + Some(i) => i, + None => return Err(RTresult::RT_ERROR_INVALID_VALUE), + }; + *program_id = callable_id as i32; + Ok(()) +} + +pub(crate) unsafe fn query_variable( + program: Program, + name: *const i8, + v: *mut Variable, +) -> Result<(), RTresult> { + null_check(name)?; + null_check(v)?; + let program = null_unwrap(program)?; + let program = (program).borrow()?; + *v = program + .variables + .get(CStr::from_ptr(name)) + .map(|variable| Rc::as_ptr(variable)) + .unwrap_or(ptr::null_mut()); + Ok(()) +} + +pub(crate) fn validate(program: Program) -> Result<(), RTresult> { + null_check(program)?; + Ok(()) +} + +pub(crate) unsafe fn create_from_program( + context: Context, + program_in: Program, + program_out: *mut Program, +) -> Result<(), RTresult> { + null_check(program_out)?; + let context_wrapper = null_unwrap(context)?; + let mut context = context_wrapper.borrow_mut()?; + let program_in = null_unwrap(program_in)?; + let program_in = program_in.borrow()?; + *program_out = program_in.create_from(context_wrapper, &mut context)?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::test_common::OptixFns; + use crate::{optix_test, tests}; + use std::ptr; + + optix_test!(cloning_program_does_not_clone_variables); + + unsafe fn cloning_program_does_not_clone_variables(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let mut program1 = ptr::null_mut(); + let mut ptx = tests::ANY_HIT_INTERSECT_PTX.to_string(); + ptx.push('\0'); + o.rtProgramCreateFromPTXString( + ctx, + ptx.as_ptr() as _, + "set_buffer\0".as_ptr() as _, + &mut program1, + ); + let mut var1 = ptr::null_mut(); + o.rtProgramDeclareVariable(program1, b"output_buffer\0".as_ptr() as _, &mut var1); + let mut program2 = ptr::null_mut(); + o.rtProgramCreateFromProgram(ctx, program1, &mut program2); + let mut var2 = ptr::null_mut(); + o.rtProgramQueryVariable(program2, b"output_buffer\0".as_ptr() as _, &mut var2); + assert_ne!(var1, ptr::null_mut()); + assert_eq!(var2, ptr::null_mut()); + } +} + +pub(crate) unsafe fn get_context( + program: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let program = null_unwrap(program)?; + let program = program.borrow()?; + *context = program.context.as_ptr(); + Ok(()) +} diff --git a/zluda_rt/src/repr_gpu.rs b/zluda_rt/src/repr_gpu.rs new file mode 100644 index 0000000..b61e2fc --- /dev/null +++ b/zluda_rt/src/repr_gpu.rs @@ -0,0 +1,1320 @@ +use crate::acceleration::AccelerationOwner; +use crate::context::GlobalStack; +use crate::geometry_instance::{GeometryInstanceChild, GeometryInstanceData}; +use crate::geometry_triangles::GeometryTrianglesData; +use crate::material::MaterialData; +use crate::{ + context::ContextData, hip, program::ProgramData, slice_cast_mut, AlignedBuffer, OptixCell, +}; +use crate::{hiprt, unwrap_or_continue}; +use hip_runtime_sys::{hipDeviceptr_t, hipMemcpyHtoD}; +use hiprt_sys::*; +use optix_types::RTresult; +use static_assertions::const_assert_eq; +use std::rc::Weak; +use std::{alloc::Layout, rc::Rc}; +use std::{iter, mem, ptr}; + +#[repr(C)] +#[derive(Clone)] +pub(crate) struct GlobalState { + pub(crate) scenes: hipDeviceptr_t, + pub(crate) miss_programs: hipDeviceptr_t, + pub(crate) buffers: hipDeviceptr_t, + pub(crate) callable_programs: hipDeviceptr_t, + pub(crate) textures: hipDeviceptr_t, + pub(crate) ray_type_count: u32, + pub(crate) uv_attribute_offset: u32, + pub(crate) width: u32, + pub(crate) height: u32, + pub(crate) attribute_block_size: u16, + pub(crate) attribute_block_align: u16, + pub(crate) thread_global_stack_size: u16, + pub(crate) _padding: u16, +} +const_assert_eq!(mem::size_of::(), 64); + +#[repr(C)] +#[allow(dead_code)] +pub(crate) struct HitProgramChain { + pub(crate) any_hit_start: u32, + pub(crate) closest_hit_start: u32, +} + +#[repr(C)] +#[allow(dead_code)] +pub(crate) struct IntersectionInput { + pub transform_block: hipDeviceptr_t, + pub materials_start: u32, +} + +#[repr(C)] +#[allow(dead_code)] +pub(crate) struct OptixTransform { + pub transform: [f32; 16], + pub inverse_transform: [f32; 16], +} + +pub(crate) struct Scene { + exception_variable_blocks: Vec>, + entry_point_variable_blocks: Vec>, + global_state: GlobalState, + // _allocator is used implictly, it holds all the allocations used by the Scene object + _allocator: Option, +} + +impl Scene { + pub fn empty() -> Self { + Self { + exception_variable_blocks: Vec::new(), + entry_point_variable_blocks: Vec::new(), + global_state: unsafe { mem::zeroed() }, + _allocator: None, + } + } + + pub fn new(context: &ContextData) -> Result { + let mut allocator = TrivialHIPAllocator::new(context.context, context.hiprt.clone()); + let textures = Self::allocate_texture_samplers(context, &mut allocator)?; + let mut bvhs = (0..context.geometry_group_count) + .into_iter() + .map(|_| unsafe { mem::zeroed() }) + .collect::>(); + let miss_programs = context.allocate_miss_programs(&mut allocator)?; + let ray_type_count = context.ray_type_count; + let callable_programs = context.allocate_callable_programs(&mut allocator)?; + let uv_attribute_offset = context.get_uv_offset()?; + let buffers = context.allocate_buffers(&mut allocator)?; + let (attribute_block_size, attribute_block_align) = context.attributes_layout(); + let entry_point_variable_blocks = + Self::allocate_entry_variable_blocks(&mut allocator, context)?; + let exception_variable_blocks = + Self::allocate_exception_variable_blocks(&mut allocator, context)?; + let mut global_state = GlobalState { + scenes: hipDeviceptr_t(ptr::null_mut()), + miss_programs, + buffers, + callable_programs, + textures, + ray_type_count, + uv_attribute_offset, + attribute_block_size, + attribute_block_align, + width: 0, + height: 0, + thread_global_stack_size: GlobalStack::THREAD_STACK_DEPTH, + _padding: 0, + }; + for accel in context.accelerations.iter() { + let accel = OptixCell::borrow(accel)?; + if let Some(group) = accel.owner.as_ref() { + let (index, bvh) = match group { + AccelerationOwner::GeometryGroup(geo_group) => { + if let Some(geo_group) = geo_group.upgrade() { + let geo_group = OptixCell::borrow(&*geo_group)?; + let index = geo_group.index; + let bvh = geo_group.prepare_globals( + &mut allocator, + context, + &mut global_state, + )?; + (index, bvh) + } else { + continue; + } + } + AccelerationOwner::Group(group) => { + if let Some(group) = group.upgrade() { + let group = OptixCell::borrow(&*group)?; + let index = group.index; + let bvh = group.prepare_globals( + &mut allocator, + context, + &mut global_state, + )?; + (index, bvh) + } else { + continue; + } + } + }; + bvhs[index as usize] = bvh; + } + } + global_state.scenes = allocator.copy_to_device(&bvhs)?; + Ok(Self { + entry_point_variable_blocks, + exception_variable_blocks, + global_state, + _allocator: Some(allocator), + }) + } + + fn allocate_texture_samplers( + context: &ContextData, + allocator: &mut TrivialHIPAllocator, + ) -> Result { + let mut sampler_ptrs = vec![ptr::null_mut(); context.texture_counter as usize]; + for sampler in context.texture_samplers.iter() { + let mut sampler = sampler.borrow_mut()?; + unsafe { sampler.create_underlying()? }; + sampler_ptrs[sampler.index as usize - 1] = sampler.hip_object; + } + allocator.copy_to_device(&sampler_ptrs[..]) + } + + pub fn launch_2d( + &self, + entry_point_index: u32, + main_program: &ProgramData, + exception: Option>, + width: u32, + height: u32, + stack: hipDeviceptr_t, + ) -> Result<(), RTresult> { + let program_variable_block = self + .entry_point_variable_blocks + .get(entry_point_index as usize) + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)? + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + let exception = exception + .map(|program| { + let exception = program.get_function()?; + let var_block = self + .exception_variable_blocks + .get(entry_point_index as usize) + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)? + .ok_or(RTresult::RT_ERROR_INVALID_VALUE)?; + Ok::<_, RTresult>((exception, var_block)) + }) + .transpose()? + .unwrap_or(( + hipDeviceptr_t(ptr::null_mut()), + hipDeviceptr_t(ptr::null_mut()), + )); + main_program.launch_2d( + width, + height, + &self.global_state, + stack, + program_variable_block, + exception, + ) + } + + fn allocate_entry_variable_blocks( + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + ) -> Result>, RTresult> { + context + .entry_points + .iter() + .map(|program| { + program + .as_ref() + .map(|program| { + let program = program.borrow()?; + program.prepare_variable_block_for_kernel(allocator, context) + }) + .transpose() + }) + .collect::, _>>() + } + + fn allocate_exception_variable_blocks( + allocator: &mut TrivialHIPAllocator, + context: &ContextData, + ) -> Result>, RTresult> { + context + .exception_programs + .iter() + .map(|program| { + program + .as_ref() + .map(|program| { + let program = program.borrow()?; + program.prepare_variable_block_for_kernel(allocator, context) + }) + .transpose() + }) + .collect::, _>>() + } +} + +pub(crate) fn get_layout( + ray_type_count: u32, + layout_source: &S, +) -> Result { + let containers_len = layout_source.len(ray_type_count); + if containers_len == 0 { + return Ok(CallChainLayout { + layout: Layout::new::<()>(), + outer_offsets: vec![u32::MAX; containers_len], + inner_offsets: vec![vec![]; containers_len], + }); + } + let mut layouts = vec![vec![]; containers_len]; + layout_source.visit_alloc(ray_type_count, |outer_index, _, programs| { + let maybe_layout = programs + .map(|(_, prog)| S::get_program_block_layout(prog)) + .transpose()?; + layouts[outer_index].push(maybe_layout); + Ok(()) + })?; + let mut layout = Layout::new::<()>(); + layout = layout_extend_by_offset_array(layout, containers_len)?; + let mut outer_offsets = Vec::with_capacity(containers_len); + let mut inner_offsets = Vec::with_capacity(containers_len); + for sublayouts in layouts { + if sublayouts.len() == 0 { + outer_offsets.push(u32::MAX); + inner_offsets.push(Vec::new()); + continue; + } + let inner_layout_and_offsets = if sublayouts.len() == 1 { + let program = sublayouts[0]; + match program { + Some(inner_layout) => Some((inner_layout, vec![0])), + None => None, + } + } else { + let mut offsets = Vec::with_capacity(sublayouts.len()); + let mut inner_layout = + layout_extend_by_offset_array(Layout::new::<()>(), sublayouts.len())?; + let mut callable = 0usize; + for sublayout in sublayouts { + let prog_block_layout = match sublayout { + None => { + offsets.push(u32::MAX); + continue; + } + Some(l) => l, + }; + callable += 1; + let (new_layout, offset) = inner_layout + .extend(prog_block_layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + inner_layout = new_layout; + offsets.push(offset as u32); + } + if callable == 0 { + None + } else { + Some((inner_layout, offsets)) + } + }; + match inner_layout_and_offsets { + Some((inner_layout, offsets)) => { + let (outer_layout, mut outer_offset) = layout + .extend(inner_layout) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)?; + if offsets.len() > 1 { + //debug_assert!(outer_offset & 1 == 0); + outer_offset |= 1; + } + outer_offsets.push(outer_offset as u32); + inner_offsets.push(offsets); + layout = outer_layout; + } + None => { + outer_offsets.push(u32::MAX); + inner_offsets.push(Vec::new()); + } + } + } + Ok(CallChainLayout { + layout, + outer_offsets, + inner_offsets, + }) +} + +pub(crate) fn copy_to_gpu( + ray_type_count: u32, + layout_source: &S, + chain_layout: &CallChainLayout, + destination: hipDeviceptr_t, +) -> Result<(), RTresult> { + let staging_buffer = copy_to_cpu(ray_type_count, layout_source, chain_layout)?; + hip! { hipMemcpyHtoD(destination, staging_buffer.as_ptr(), staging_buffer.len()), RT_ERROR_UNKNOWN }; + Ok(()) +} + +pub(crate) fn copy_to_cpu( + ray_type_count: u32, + layout_source: &S, + chain_layout: &CallChainLayout, +) -> Result { + let mut staging_buffer = AlignedBuffer::new(chain_layout.layout); + if cfg!(test) { + staging_buffer.as_bytes_mut().fill(0u8); + } + let dst_buffer = staging_buffer.as_bytes_mut(); + copy_prologue_offsets(chain_layout, dst_buffer); + layout_source.visit_alloc(ray_type_count, |outer_index, inner_index, program| { + if let Some((copy_ctx, program)) = program { + let outer_offset = chain_layout.outer_offsets[outer_index] & !1u32; + let offset = outer_offset + chain_layout.inner_offsets[outer_index][inner_index]; + layout_source.copy_program_block( + copy_ctx, + program, + &mut dst_buffer[offset as usize..], + )?; + } + Ok(()) + })?; + Ok(staging_buffer) +} + +#[gat] +pub(crate) trait VisitCallChain { + type ProgramData; // This type parametrization is to enable testing + type CopyContext<'temp>; + fn len(&self, ray_type_count: u32) -> usize; + fn visit_alloc( + &self, + ray_type_count: u32, + visitor: impl FnMut( + usize, + usize, + Option<(Self::CopyContext<'_>, &Self::ProgramData)>, + ) -> Result<(), RTresult>, + ) -> Result<(), RTresult>; + fn get_program_block_layout(p: &Self::ProgramData) -> Result; + fn copy_program_block( + &self, + copy_ctx: Self::CopyContext<'_>, + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult>; +} + +trait VisitLayout { + fn len(&self, ray_type_count: u32) -> usize; + fn visit_layout( + &self, + ray_type_count: u32, + visitor: impl FnMut(Vec>) -> Result<(), RTresult>, + ) -> Result<(), RTresult>; +} + +impl VisitLayout for GeometryInstanceData { + fn len(&self, ray_type_count: u32) -> usize { + self.materials.len() * ray_type_count as usize + } + + fn visit_layout( + &self, + ray_type_count: u32, + mut visitor: impl FnMut(Vec>) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for material in self.materials.iter() { + for ray in 0..ray_type_count { + let material = material.as_ref().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let material = material.borrow()?; + let maybe_any_hit_program = material.any_hit_programs.get(&ray); + visitor(vec![maybe_any_hit_program + .map(|any_hit_program| { + let any_hit_program = any_hit_program.borrow()?; + any_hit_program.get_program_block_layout() + }) + .transpose()?])? + } + } + Ok(()) + } +} + +pub(crate) struct IntersectVisitCallChain<'a> { + pub(crate) context: &'a ContextData, + pub(crate) geometry_instance: &'a GeometryInstanceData, +} + +pub(crate) struct CallableProgramsVisitor<'a> { + context: &'a ContextData, + programs: Vec>>, +} + +impl<'a> CallableProgramsVisitor<'a> { + pub(crate) fn new(context: &'a ContextData) -> Result { + let mut programs = (0..context.callable_program_counter) + .into_iter() + .map(|_| None) + .collect::>(); + for program in context.programs.iter() { + let program = program.borrow()?; + let callable_index = unwrap_or_continue!(program.callable_index); + let index = (callable_index - 1) as usize; + programs[index] = Some(program); + } + Ok(Self { programs, context }) + } +} + +#[gat] +impl<'a> VisitCallChain for CallableProgramsVisitor<'a> { + type ProgramData = ProgramData; + type CopyContext<'unused> = (); + + fn len(&self, _ray_type_count: u32) -> usize { + self.programs.len() + } + + fn visit_alloc( + &self, + _ray_type_count: u32, + mut visitor: impl FnMut(usize, usize, Option<((), &Self::ProgramData)>) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (index, prog) in self.programs.iter().enumerate() { + visitor(index, 0, prog.as_deref().map(|prog| ((), prog)))?; + } + Ok(()) + } + + fn get_program_block_layout(prog: &Self::ProgramData) -> Result { + prog.get_program_block_layout() + } + + fn copy_program_block( + &self, + _: (), + prog: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + prog.copy_program_block(dst, |name| prog.get_variable_for_kernel(self.context, name)) + } +} + +#[gat] +impl<'a> VisitCallChain for IntersectVisitCallChain<'a> { + type ProgramData = ProgramData; + type CopyContext<'temp> = &'temp MaterialData; + + fn len(&self, ray_type_count: u32) -> usize { + self.geometry_instance.materials.len() * ray_type_count as usize + } + + fn visit_alloc( + &self, + ray_type_count: u32, + mut visitor: impl FnMut( + usize, + usize, + Option<(&MaterialData, &Self::ProgramData)>, + ) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (material_index, material) in self.geometry_instance.materials.iter().enumerate() { + for ray in 0..ray_type_count { + let material = material.as_ref().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let material = material.borrow()?; + let maybe_any_hit_program = material.any_hit_programs.get(&ray); + let outer_index = (ray_type_count as usize * material_index) + ray as usize; + visitor( + outer_index, + 0, + maybe_any_hit_program + .map(std::ops::Deref::deref) + .map(OptixCell::borrow) + .transpose()? + .as_deref() + .map(|prog| (&*material, prog)), + )?; + } + } + Ok(()) + } + + fn get_program_block_layout(p: &Self::ProgramData) -> Result { + p.get_program_block_layout() + } + + fn copy_program_block( + &self, + material: &MaterialData, + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + p.copy_program_block(dst, |name| { + p.get_variable_for_function(self.geometry_instance, material, self.context, name) + }) + } +} + +pub(crate) struct AttributesVisitCallChain<'a> { + pub(crate) context: &'a ContextData, + pub(crate) children: &'a [Option>>], +} + +#[gat] +impl<'a> VisitCallChain for AttributesVisitCallChain<'a> { + type ProgramData = ProgramData; + type CopyContext<'temp> = (&'temp GeometryTrianglesData, &'temp GeometryInstanceData); + + fn len(&self, _: u32) -> usize { + self.children.len() + } + + fn visit_alloc( + &self, + _: u32, + mut visitor: impl for<'x> FnMut( + usize, + usize, + Option<( + (&'x GeometryTrianglesData, &'x GeometryInstanceData), + &Self::ProgramData, + )>, + ) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (program_index, maybe_instance) in self.children.iter().enumerate() { + if let Some(instance) = maybe_instance { + let instance = instance.borrow()?; + match instance.child { + GeometryInstanceChild::None => return Err(RTresult::RT_ERROR_INVALID_CONTEXT), + GeometryInstanceChild::Geometry(_) => {} + GeometryInstanceChild::GeometryTriangles(ref geo) => { + let geo = geo.borrow()?; + if let Some(ref program) = geo.attribute_program { + if let Some(program) = Weak::upgrade(&program) { + let program = program.borrow()?; + visitor(program_index, 0, Some(((&geo, &instance), &program)))?; + continue; + } + } + } + } + visitor(program_index, 0, None)?; + } else { + return Err(RTresult::RT_ERROR_INVALID_CONTEXT); + } + } + Ok(()) + } + + fn get_program_block_layout(p: &Self::ProgramData) -> Result { + p.get_program_block_layout() + } + + fn copy_program_block( + &self, + (triangles, instance): (&GeometryTrianglesData, &GeometryInstanceData), + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + p.copy_attribute_program_block(dst, |name| { + p.get_variable_for_attribute(triangles, instance, self.context, name) + }) + } +} + +pub(crate) struct MissProgramsVisitCallChain<'a> { + pub(crate) context: &'a ContextData, + pub(crate) miss_programs: &'a [Option>>], +} + +#[gat] +impl<'a> VisitCallChain for MissProgramsVisitCallChain<'a> { + type ProgramData = ProgramData; + type CopyContext<'unused> = (); + + fn len(&self, _: u32) -> usize { + self.miss_programs.len() + } + + fn visit_alloc( + &self, + _: u32, + mut visitor: impl FnMut(usize, usize, Option<((), &Self::ProgramData)>) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (program_index, maybe_program) in self.miss_programs.iter().enumerate() { + visitor( + program_index, + 0, + maybe_program + .as_deref() + .map(OptixCell::borrow) + .transpose()? + .as_deref() + .map(|prog| ((), prog)), + )?; + } + Ok(()) + } + + fn get_program_block_layout(p: &Self::ProgramData) -> Result { + p.get_program_block_layout() + } + + fn copy_program_block( + &self, + _: (), + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + p.copy_program_block(dst, |name| p.get_variable_for_kernel(self.context, name)) + } +} + +pub(crate) struct HitProgramsVisitCallChain<'a> { + pub(crate) context: &'a ContextData, + pub(crate) children: &'a [Option>>], + pub(crate) closest_hit: bool, + pub(crate) ray: u32, +} + +#[gat] +impl<'a> VisitCallChain for HitProgramsVisitCallChain<'a> { + type ProgramData = ProgramData; + type CopyContext<'temp> = (&'temp GeometryInstanceData, &'temp MaterialData); + + fn len(&self, _: u32) -> usize { + self.children.len() + } + + fn visit_alloc( + &self, + _: u32, + mut visitor: impl for<'x, 'y> FnMut( + usize, + usize, + Option<( + (&'x GeometryInstanceData, &'x MaterialData), + &'y Self::ProgramData, + )>, + ) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (instance_idx, maybe_instance) in self.children.iter().enumerate() { + let instance = maybe_instance + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let instance = instance.borrow()?; + let ignore_any_hit = matches!(instance.child, GeometryInstanceChild::Geometry(..)); + if ignore_any_hit && !self.closest_hit { + continue; + } + for (material_index, material) in instance.materials.iter().enumerate() { + let material = material + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let material = material.borrow()?; + let hit_programs = if self.closest_hit { + &material.closest_hit_programs + } else { + &material.any_hit_programs + }; + visitor( + instance_idx, + material_index, + hit_programs + .get(&self.ray) + .map(std::ops::Deref::deref) + .map(OptixCell::borrow) + .transpose()? + .as_deref() + .map(|prog| ((&*instance, &*material), prog)), + )?; + } + } + Ok(()) + } + + fn get_program_block_layout(p: &Self::ProgramData) -> Result { + p.get_program_block_layout() + } + + fn copy_program_block( + &self, + (geometry_instance, material): (&GeometryInstanceData, &MaterialData), + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + p.copy_program_block(dst, |name| { + p.get_variable_for_function(geometry_instance, material, self.context, name) + }) + } +} + +pub(crate) struct VisitHitPrograms<'a> { + pub(crate) closest_hit: bool, + pub(crate) ray: u32, + pub(crate) children: &'a [Option>>], +} + +impl<'a> VisitLayout for VisitHitPrograms<'a> { + fn len(&self, _: u32) -> usize { + self.children.len() + } + + fn visit_layout( + &self, + _: u32, + mut visitor: impl FnMut(Vec>) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for maybe_instance in self.children.iter() { + let instance = maybe_instance + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let instance = instance.borrow()?; + let ignore_any_hit = matches!(instance.child, GeometryInstanceChild::Geometry(..)); + if ignore_any_hit && !self.closest_hit { + visitor(vec![])?; + continue; + } + visitor( + instance + .materials + .iter() + .map(|material| { + let material = material + .as_ref() + .ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?; + let material = material.borrow()?; + let hit_programs = if self.closest_hit { + &material.closest_hit_programs + } else { + &material.any_hit_programs + }; + hit_programs + .get(&self.ray) + .map(|prog| { + let prog = prog.borrow()?; + prog.get_program_block_layout() + }) + .transpose() + }) + .collect::, _>>()?, + )?; + } + Ok(()) + } +} + +pub(crate) struct CallChainLayout { + pub(crate) layout: Layout, + pub(crate) outer_offsets: Vec, + pub(crate) inner_offsets: Vec>, +} + +impl CallChainLayout { + fn offsets(&self) -> impl Iterator { + iter::once((0u32, &self.outer_offsets[..])).chain( + self.outer_offsets + .iter() + .enumerate() + .filter_map(move |(index, offset)| { + if *offset == u32::MAX { + None + } else if (offset & 1) == 1 { + Some((*offset & !1, &self.inner_offsets[index][..])) + } else { + None + } + }), + ) + } +} + +trait CallChainCopier { + fn copy_offsets(offset: u32, offsets: &[u32]); + fn copy_variable(offset: u32, offsets: &[u32]); +} + +fn layout_extend_by_offset_array(layout: Layout, programs_len: usize) -> Result { + Ok(layout + .extend(Layout::array::(programs_len).map_err(|_| RTresult::RT_ERROR_UNKNOWN)?) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN)? + .0) +} + +fn copy_prologue_offsets(chain_layout: &CallChainLayout, dst_buffer: &mut [u8]) { + for (offset, chain_prologue) in chain_layout.offsets() { + let dst = + unsafe { slice_cast_mut(&mut dst_buffer[offset as usize..], chain_prologue.len()) }; + dst.copy_from_slice(&*chain_prologue); + } +} + +#[must_use] +pub(crate) struct TrivialHIPAllocator { + context: hiprtContext, + hiprt: Rc, + geometries: Vec, + func_tables: Vec, + scenes: Vec, + allocations: Vec, + drop_flag: bool, +} + +impl TrivialHIPAllocator { + pub(crate) fn new(context: hiprtContext, hiprt: Rc) -> Self { + Self { + context, + hiprt, + geometries: Vec::new(), + func_tables: Vec::new(), + scenes: Vec::new(), + allocations: Vec::new(), + drop_flag: false, + } + } + + pub(crate) fn new_func_table(&mut self) -> Result { + let mut custom_func_table = ptr::null_mut(); + hiprt! { self.hiprt.hiprtCreateCustomFuncTable(self.context, &mut custom_func_table), RT_ERROR_UNKNOWN }; + Ok(custom_func_table) + } + + pub(crate) fn new_scene( + &mut self, + scene_input: hiprtSceneBuildInput, + build_options: hiprtBuildOptions, + ) -> Result { + let mut temp_mem_size = 0; + hiprt! { self.hiprt.hiprtGetSceneBuildTemporaryBufferSize(self.context, &scene_input, &build_options, &mut temp_mem_size), RT_ERROR_UNKNOWN }; + let temp_mem = self.allocate(temp_mem_size)?; + let mut scene = ptr::null_mut(); + hiprt! { self.hiprt.hiprtCreateScene(self.context, &scene_input, &build_options, &mut scene), RT_ERROR_UNKNOWN }; + self.scenes.push(scene); + hiprt! { self.hiprt.hiprtBuildScene(self.context, hiprtBuildOperation::hiprtBuildOperationBuild, &scene_input, &build_options, temp_mem.0, ptr::null_mut(), scene), RT_ERROR_UNKNOWN }; + Ok(scene) + } + + pub(crate) fn new_geometry( + &mut self, + geometry_input: hiprtGeometryBuildInput, + build_options: hiprtBuildOptions, + ) -> Result { + let mut temp_mem_size = 0; + hiprt! { self.hiprt.hiprtGetGeometryBuildTemporaryBufferSize(self.context, &geometry_input, &build_options, &mut temp_mem_size), RT_ERROR_UNKNOWN }; + let temp_mem = self.allocate(temp_mem_size)?; + let mut geometry = ptr::null_mut(); + hiprt! { self.hiprt.hiprtCreateGeometry(self.context, &geometry_input, &build_options, &mut geometry), RT_ERROR_UNKNOWN }; + self.geometries.push(geometry); + hiprt! { self.hiprt.hiprtBuildGeometry(self.context, hiprtBuildOperation::hiprtBuildOperationBuild, &geometry_input, &build_options, temp_mem.0, ptr::null_mut(), geometry), RT_ERROR_UNKNOWN }; + Ok(geometry) + } + + pub(crate) fn allocate(&mut self, size: usize) -> Result { + let dev_ptr = hip::malloc(size).map_err(|_| RTresult::RT_ERROR_MEMORY_ALLOCATION_FAILED)?; + self.allocations.push(dev_ptr); + Ok(dev_ptr) + } + + pub(crate) fn copy_to_device(&mut self, slice: &[T]) -> Result { + let dev_ptr = hip::copy_to_device(slice)?; + self.allocations.push(dev_ptr); + Ok(dev_ptr) + } + + fn dealloc_impl(&mut self) -> Result<(), RTresult> { + if self.drop_flag { + return Ok(()); + } + self.drop_flag = true; + let geometries_result = self + .geometries + .iter() + .copied() + .fold(Ok(()), |result, geometry| { + let destroy_result = + match unsafe { self.hiprt.hiprtDestroyGeometry(self.context, geometry) } { + hiprtError::hiprtSuccess => Ok(()), + _ => Err(RTresult::RT_ERROR_UNKNOWN), + }; + result.and(destroy_result) + }); + let func_tables_result = + self.func_tables + .iter() + .copied() + .fold(geometries_result, |result, func_table| { + let destroy_result = match unsafe { + self.hiprt + .hiprtDestroyCustomFuncTable(self.context, func_table) + } { + hiprtError::hiprtSuccess => Ok(()), + _ => Err(RTresult::RT_ERROR_UNKNOWN), + }; + result.and(destroy_result) + }); + let scenes_result = + self.scenes + .iter() + .copied() + .fold(func_tables_result, |result, scene| { + let destroy_result = + match unsafe { self.hiprt.hiprtDestroyScene(self.context, scene) } { + hiprtError::hiprtSuccess => Ok(()), + _ => Err(RTresult::RT_ERROR_UNKNOWN), + }; + result.and(destroy_result) + }); + self.allocations + .iter() + .copied() + .fold(scenes_result, |result, dev_ptr| { + result.and(hip::free(dev_ptr).map_err(|_| RTresult::RT_ERROR_UNKNOWN)) + }) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } +} + +// In case there is an early exit and we don't get to call .dealloc(...) +impl Drop for TrivialHIPAllocator { + fn drop(&mut self) { + self.dealloc_impl().ok(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::context::ContextData; + use crate::variable::VariableData; + use crate::AlignedBuffer; + use crate::MaybeWeakRefMut; + use crate::OptixCell; + use crate::OptixObjectData; + use crate::TypeTag; + use hip_common::raytracing::VariablesBlock; + use optix_types::RTresult; + use rustc_hash::FxHashMap; + use std::ffi::CString; + use std::rc::Rc; + use std::{alloc::Layout, mem}; + + #[test] + fn get_layout_empty() { + let chain_layout = get_layout( + 1, + &TestGroup { + containers: Vec::new(), + }, + ) + .unwrap(); + assert_eq!(Layout::new::<()>(), chain_layout.layout); + assert_eq!(0, chain_layout.inner_offsets.len()); + assert_eq!(0, chain_layout.outer_offsets.len()); + } + + #[test] + fn get_layout_complex() { + let context = Rc::new(OptixCell::new(ContextData::new().unwrap())); + let mut byte = 0x11; + let containers = vec![ + TestContainer::new(vec![Some(TestProgram::new(vec![], &context, &mut byte))]), // just pointer + TestContainer::new(vec![Some(TestProgram::new( + vec![Layout::new::()], + &context, + &mut byte, + ))]), // single byte + TestContainer::new(vec![]), // empty + TestContainer::new(vec![None]), // nothing + TestContainer::new(vec![None, None]), // uncallable + TestContainer::new(vec![Some(TestProgram::new( + vec![ + // three fields + Layout::new::(), + Layout::new::(), + Layout::new::(), + Layout::new::(), + ], + &context, + &mut byte, + ))]), + TestContainer::new(vec![ + // four subprograms + Some(TestProgram::new( + vec![ + Layout::new::(), + Layout::new::(), + Layout::new::(), + ], + &context, + &mut byte, + )), + None, + Some(TestProgram::new(vec![], &context, &mut byte)), + None, + ]), + TestContainer::new(vec![Some(TestProgram::new(vec![], &context, &mut byte))]), + TestContainer::new(vec![None]), + ]; + let chain_layout = get_layout(1, &TestGroup { containers }).unwrap(); + assert_eq!( + vec![40u32, 48, !0, !0, !0, 64, 97, 144, !0], + chain_layout.outer_offsets + ); + assert_eq!(152, chain_layout.layout.size()); + assert_eq!(8, chain_layout.layout.align()); + assert_eq!( + vec![ + vec![0u32], + vec![0u32], + vec![], + vec![], + vec![], + vec![0], + vec![16, !0, 40, !0], + vec![0], + vec![] + ], + chain_layout.inner_offsets + ); + } + + #[test] + fn copy_to_cpu_complex() { + let context = Rc::new(OptixCell::new(ContextData::new().unwrap())); + let chain_layout = CallChainLayout { + layout: Layout::from_size_align(152, 8).unwrap(), + inner_offsets: vec![ + vec![0u32], + vec![0u32], + vec![], + vec![], + vec![], + vec![0], + vec![16, !0, 40, !0], + vec![0], + vec![], + ], + outer_offsets: vec![40u32, 48, !0, !0, !0, 64, 97, 144, !0], + }; + let mut byte = 0x11; + let containers = vec![ + TestContainer::new(vec![Some(TestProgram::new(vec![], &context, &mut byte))]), // just pointer + TestContainer::new(vec![Some(TestProgram::new( + vec![Layout::new::()], + &context, + &mut byte, + ))]), // single byte + TestContainer::new(vec![]), // empty + TestContainer::new(vec![None]), // nothing + TestContainer::new(vec![None, None]), // uncallable + TestContainer::new(vec![Some(TestProgram::new( + vec![ + // three fields + Layout::new::(), + Layout::new::(), + Layout::new::(), + Layout::new::(), + ], + &context, + &mut byte, + ))]), + TestContainer::new(vec![ + // four subprograms + Some(TestProgram::new( + vec![ + Layout::new::(), + Layout::new::(), + Layout::new::(), + ], + &context, + &mut byte, + )), + None, + Some(TestProgram::new(vec![], &context, &mut byte)), + None, + ]), + TestContainer::new(vec![Some(TestProgram::new(vec![], &context, &mut byte))]), + TestContainer::new(vec![None]), + ]; + let buffer = super::copy_to_cpu(1, &TestGroup { containers }, &chain_layout).unwrap(); + assert_eq!( + buffer.as_bytes(), + vec![ + 40u8, 0, 0, 0, // prog 0 offset + 48, 0, 0, 0, // prog 1 offset + 255, 255, 255, 255, // prog 2 offset + 255, 255, 255, 255, // prog 3 offset + 255, 255, 255, 255, // prog 4 offset + 64, 0, 0, 0, // prog 5 offset + 97, 0, 0, 0, // multi-prog 6 offset + 144, 0, 0, 0, // prog 7 offset + 255, 255, 255, 255, // prog 8 offset + 0, 0, 0, 0, // offset table padding + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // prog 0, pointer + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, // prog 1, pointer + 0x33, // prog 1, field 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // prog 1 padding + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // prog 5, pointer + 0x55, 0x55, 0x55, 0x55, // prog 5, field 0 + 0x66, 0x66, // prog 5, field 1 + 0x00, 0x00, // prog 5, field 1 padding + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, // prog 5, field 2 + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // prog 5 padding + 16, 0, 0, 0, // prog 6, subprog 0 offset + 255, 255, 255, 255, // prog 6, subprog 1 offset + 40, 0, 0, 0, // prog 6, subprog 2 offset + 255, 255, 255, 255, // prog 6, subprog 3 offset + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, // prog 6, subprog 0, pointer + 0xaa, // prog 6, subprog 0, field 0 + 0x00, 0x00, 0x00, // prog 6, subprog 0, field 0 padding + 0xbb, 0xbb, 0xbb, 0xbb, // prog 6, subprog 0, field 1 + 0xcc, 0xcc, 0xcc, 0xcc, // prog 6, subprog 0, field 2 + 0x00, 0x00, 0x00, 0x00, // prog 6, subprog 0 padding + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, // prog 6, subprog 2, pointer + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, // prog 7, pointer + ] + ); + } + + struct TestGroup { + containers: Vec>>, + } + + #[gat] + impl<'a> VisitCallChain for TestGroup { + type ProgramData = TestProgram; + type CopyContext<'temp> = (); + + fn len(&self, _: u32) -> usize { + self.containers.len() + } + + fn visit_alloc( + &self, + _: u32, + mut visitor: impl FnMut( + usize, + usize, + Option<((), &Self::ProgramData)>, + ) -> Result<(), RTresult>, + ) -> Result<(), RTresult> { + for (outer_idx, container) in self.containers.iter().enumerate() { + let container = container.borrow()?; + for (inner_odx, program) in container.programs.iter().enumerate() { + visitor( + outer_idx, + inner_odx, + program + .as_deref() + .map(OptixCell::borrow) + .transpose()? + .as_deref() + .map(|prog| ((), prog)), + )? + } + } + Ok(()) + } + + fn get_program_block_layout(p: &Self::ProgramData) -> Result { + Ok(p.variables_block.layout) + } + + fn copy_program_block( + &self, + _: (), + p: &Self::ProgramData, + dst: &mut [u8], + ) -> Result<(), RTresult> { + dst[..mem::size_of::()].copy_from_slice(&p.ptr.to_ne_bytes()); + for (name, var) in p.variables_block.variables.iter() { + let var_data = &p.variables[name]; + let var_data = var_data.borrow()?; + let variable_offset = var.offset as usize; + var_data.copy_into_buffer( + &mut dst[variable_offset..variable_offset + var.size as usize], + )?; + } + Ok(()) + } + } + + struct TestContainer { + programs: Vec>>>, + } + + impl TestContainer { + fn new(programs: Vec>>>) -> Rc> { + Rc::new(OptixCell::new(Self { programs })) + } + } + + impl OptixObjectData for TestContainer { + const TYPE: TypeTag = TypeTag::GeometryInstance; + + fn deregister(&mut self, _this: &Rc>) -> Result<(), RTresult> { + Ok(()) + } + + fn context<'a>(&'a mut self) -> MaybeWeakRefMut<'a, ContextData> { + todo!() + } + } + + struct TestProgram { + ptr: usize, + variables_block: VariablesBlock, + variables: FxHashMap>>, + } + + impl TestProgram { + fn new( + vars: Vec, + _context: &Rc>, + byte: &mut u8, + ) -> Rc> { + let ptr = + usize::from_ne_bytes([*byte, *byte, *byte, *byte, *byte, *byte, *byte, *byte]); + *byte += 0x11; + let mut layout = Layout::new::(); + let variables = vars + .iter() + .enumerate() + .map(|(idx, l)| { + let (new_layout, offset) = layout.extend(*l).unwrap(); + layout = new_layout; + let name = idx.to_string(); + ( + CString::new(name).unwrap(), + hip_common::raytracing::Variable { + offset: offset as u32, + size: l.size() as u32, + default_value: Vec::new(), + }, + ) + }) + .collect::>(); + let variables_block = VariablesBlock { layout, variables }; + let variables = vars + .iter() + .enumerate() + .map(|(idx, l)| { + let (new_layout, _) = layout.extend(*l).unwrap(); + layout = new_layout; + let vec = vec![*byte; l.size()]; + let mut aligned_vec = AlignedBuffer::new(*l); + aligned_vec.as_bytes_mut().copy_from_slice(&*vec); + let variable = Rc::new(OptixCell::new(VariableData { + value: crate::variable::VariableValue::Boxed(aligned_vec), + context: unsafe { mem::zeroed() }, + })); + *byte += 0x11; + let name = idx.to_string(); + (CString::new(name).unwrap(), variable) + }) + .collect::>(); + Rc::new(OptixCell::new(Self { + ptr, + variables_block, + variables, + })) + } + } + + impl OptixObjectData for TestProgram { + const TYPE: TypeTag = TypeTag::Program; + + fn deregister(&mut self, _this: &Rc>) -> Result<(), RTresult> { + Ok(()) + } + + fn context<'a>(&'a mut self) -> MaybeWeakRefMut<'a, ContextData> { + panic!() + } + } +} diff --git a/zluda_rt/src/test_common.rs b/zluda_rt/src/test_common.rs new file mode 100644 index 0000000..7d982c9 --- /dev/null +++ b/zluda_rt/src/test_common.rs @@ -0,0 +1,125 @@ +use libloading::{Library, Symbol}; +use optix_types::*; +use std::ffi::c_void; + +#[cfg(windows)] +const OPTIX_DLL: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/bin/optix.6.5.0.dll"); + +#[cfg(not(windows))] +const OPTIX_DLL: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/bin/liboptix.so.6.5.0"); + +fn load_optix() -> Library { + unsafe { Library::new(OPTIX_DLL).unwrap() } +} + +fn get_proc_address<'a>(lib: &'a Library, name: &str) -> Symbol<'a, *mut c_void> { + unsafe { lib.get::<*mut c_void>(name.as_bytes()).unwrap() } +} + +pub struct Cuda { + lib: Library +} + +unsafe impl Send for Cuda {} +unsafe impl Sync for Cuda {} + +#[derive(Copy, Clone)] +pub struct Zluda; + +macro_rules! optix6_fn_table_void{ + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + pub trait OptixFnsVoid { + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type; + )* + } + + impl OptixFnsVoid for Cuda { + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + let fn_ptr = crate::test_common::get_proc_address(&self.lib, concat!(stringify!($fn_name), "\0")); + let cu_fn = std::mem::transmute::<_, unsafe extern $abi fn( $( $arg_id : $arg_type),* ) -> $ret_type>(fn_ptr); + cu_fn ( $( $arg_id),* ) + } + )* + } + + impl OptixFnsVoid for Zluda { + $( + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + crate::$fn_name ( $( $arg_id),* ) + } + )* + } + }; +} + +macro_rules! optix6_fn_table_rtresult { + ($($abi:literal fn $fn_name:ident( $($arg_id:ident : $arg_type:ty),* $(,)? ) -> $ret_type:ty);*) => { + pub trait OptixFns: OptixFnsVoid { + fn new() -> Self; + $( + paste::paste! { + unsafe fn $fn_name (&self, $( $arg_id : $arg_type),* ) { + let err = self. [< $fn_name _unchecked >] ( + $( $arg_id),* + ); + if err != optix_types::RTresult::RT_SUCCESS { + panic!("{}", err.0); + } + } + #[allow(non_snake_case)] + unsafe fn [< $fn_name _unchecked >] (&self, $( $arg_id : $arg_type),* ) -> $ret_type; + } + )* + } + + impl OptixFns for Cuda { + fn new() -> Self { + let lib = crate::test_common::load_optix(); + Self { lib } + } + $( + paste::paste! { + unsafe fn [< $fn_name _unchecked >] (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + let fn_ptr = crate::test_common::get_proc_address(&self.lib, concat!(stringify!($fn_name), "\0")); + let cu_fn = std::mem::transmute::<_, unsafe extern $abi fn( $( $arg_id : $arg_type),* ) -> $ret_type>(fn_ptr); + cu_fn ( $( $arg_id),* ) + } + } + )* + } + + impl OptixFns for Zluda { + fn new() -> Self { Self } + $( + paste::paste! { + unsafe fn [< $fn_name _unchecked >] (&self, $( $arg_id : $arg_type),* ) -> $ret_type { + crate::$fn_name ( $( $arg_id),* ) + } + } + )* + } + }; +} + +optix_base::optix6_function_declarations!(optix6_fn_table_rtresult, optix6_fn_table_void, [rtContextGetErrorString]); + +#[macro_export] +macro_rules! optix_test { + ($func:ident) => { + paste::paste! { + #[test] + #[allow(non_snake_case)] + fn [<$func _zluda>]() { + unsafe { $func::(crate::test_common::Zluda::new()) } + } + + #[test] + #[allow(non_snake_case)] + fn [<$func _cuda>]() { + unsafe { $func::(crate::test_common::Cuda::new()) } + } + } + }; +} diff --git a/zluda_rt/src/tests/alloca_bug.cu b/zluda_rt/src/tests/alloca_bug.cu new file mode 100644 index 0000000..520f615 --- /dev/null +++ b/zluda_rt/src/tests/alloca_bug.cu @@ -0,0 +1,22 @@ +// nvcc alloca_bug.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include + +rtDeclareVariable(rtCallableProgramId, sysBRDFEval, , ); +rtBuffer sysMaterialParameters; + +RT_PROGRAM void closest_hit() +{ + float3 mat = sysMaterialParameters[0]; + + if (mat.x != 0) + { + const float3 texColor = make_float3(0, 0,0); + mat = make_float3(powf(texColor.x, 2.2f), 0,0); + } + float3 prd2; + float3 f = sysBRDFEval(mat, prd2); + + if (prd2.x > 0.0f) + prd2 *= f; +} diff --git a/zluda_rt/src/tests/alloca_bug.ptx b/zluda_rt/src/tests/alloca_bug.ptx new file mode 100644 index 0000000..f2ae4d1 --- /dev/null +++ b/zluda_rt/src/tests/alloca_bug.ptx @@ -0,0 +1,126 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z11closest_hitv +.visible .global .align 4 .b8 sysBRDFEval[4]; +.visible .global .align 1 .b8 sysMaterialParameters[1]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo11sysBRDFEvalE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename11sysBRDFEvalE[54] = {114, 116, 67, 97, 108, 108, 97, 98, 108, 101, 80, 114, 111, 103, 114, 97, 109, 73, 100, 60, 102, 108, 111, 97, 116, 51, 40, 102, 108, 111, 97, 116, 51, 32, 38, 109, 97, 116, 44, 32, 102, 108, 111, 97, 116, 51, 32, 38, 112, 114, 100, 41, 62, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum11sysBRDFEvalE = 4920; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic11sysBRDFEvalE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation11sysBRDFEvalE[1]; + +.visible .entry _Z11closest_hitv() +{ + .local .align 4 .b8 __local_depot0[24]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .pred %p<3>; + .reg .f32 %f<13>; + .reg .b32 %r<5>; + .reg .b64 %rd<16>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd9, %SP, 0; + add.u64 %rd1, %SPL, 0; + mov.u64 %rd10, sysMaterialParameters; + cvta.global.u64 %rd4, %rd10; + mov.u32 %r1, 1; + mov.u32 %r2, 12; + mov.u64 %rd8, 0; + // begin inline asm + call (%rd3), _rt_buffer_get_64, (%rd4, %r1, %r2, %rd8, %rd8, %rd8, %rd8); + // end inline asm + ld.f32 %f5, [%rd3]; + ld.f32 %f6, [%rd3+4]; + ld.f32 %f7, [%rd3+8]; + st.local.f32 [%rd1], %f5; + st.local.f32 [%rd1+4], %f6; + st.local.f32 [%rd1+8], %f7; + setp.eq.f32 %p1, %f5, 0f00000000; + @%p1 bra $L__BB0_2; + + mov.u32 %r3, 0; + st.local.u32 [%rd1], %r3; + st.local.u32 [%rd1+4], %r3; + st.local.u32 [%rd1+8], %r3; + +$L__BB0_2: + ld.global.u32 %r4, [sysBRDFEval]; + // begin inline asm + call (%rd11), _rt_callable_program_from_id_v2_64, (%r4, %rd8); + // end inline asm + add.u64 %rd15, %SP, 12; + { // callseq 0, 0 + .reg .b32 temp_param_reg; + .param .b64 param0; + st.param.b64 [param0+0], %rd9; + .param .b64 param1; + st.param.b64 [param1+0], %rd15; + .param .align 4 .b8 retval0[12]; + prototype_0 : .callprototype (.param .align 4 .b8 _[12]) _ (.param .b64 _, .param .b64 _); + call (retval0), + %rd11, + ( + param0, + param1 + ) + , prototype_0; + ld.param.f32 %f1, [retval0+0]; + ld.param.f32 %f2, [retval0+4]; + ld.param.f32 %f3, [retval0+8]; + } // callseq 0 + add.u64 %rd2, %SPL, 12; + ld.local.f32 %f4, [%rd2]; + setp.leu.f32 %p2, %f4, 0f00000000; + @%p2 bra $L__BB0_4; + + mul.f32 %f8, %f1, %f4; + st.local.f32 [%rd2], %f8; + ld.local.f32 %f9, [%rd2+4]; + mul.f32 %f10, %f2, %f9; + st.local.f32 [%rd2+4], %f10; + ld.local.f32 %f11, [%rd2+8]; + mul.f32 %f12, %f3, %f11; + st.local.f32 [%rd2+8], %f12; + +$L__BB0_4: + ret; + +} + diff --git a/zluda_rt/src/tests/any_hit_intersect.cu b/zluda_rt/src/tests/any_hit_intersect.cu new file mode 100644 index 0000000..5b9bece --- /dev/null +++ b/zluda_rt/src/tests/any_hit_intersect.cu @@ -0,0 +1,78 @@ +#include +#include +#include + +using namespace optix; + +rtDeclareVariable(float4, sphere, , ); +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); +rtDeclareVariable(unsigned int, b_index, , ); +rtBuffer output_buffer; +rtBuffer output_buffer2; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); + +RT_PROGRAM void start(void) +{ + Ray ray = make_Ray(make_float3(0, 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void set_buffer(void) +{ + atomicAdd(&output_buffer[b_index], 1); +} + +RT_PROGRAM void set_buffer2(void) +{ + atomicAdd(&output_buffer2[b_index], 1); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O)-radius*radius; + float disc = b*b-c; + if(disc > 0.0f){ + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if( rtPotentialIntersection( (root1 + root11) * l ) ) { + //shading_normal = geometric_normal = (O + (root1 + root11)*D)/radius; + if(rtReportIntersection(launch_index.x)) + check_second = false; + } + if(check_second) { + float root2 = (-b + sdisc); + if( rtPotentialIntersection( root2 * l ) ) { + //shading_normal = geometric_normal = (O + root2*D)/radius; + rtReportIntersection(launch_index.x); + } + } + } +} + +RT_PROGRAM void bounds (int, float result[6]) +{ + const float3 cen = make_float3( sphere ); + const float3 rad = make_float3( sphere.w ); + + optix::Aabb* aabb = (optix::Aabb*)result; + + if( rad.x > 0.0f && !isinf(rad.x) ) { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } else { + aabb->invalidate(); + } +} diff --git a/zluda_rt/src/tests/any_hit_intersect.ptx b/zluda_rt/src/tests/any_hit_intersect.ptx new file mode 100644 index 0000000..d237fdd --- /dev/null +++ b/zluda_rt/src/tests/any_hit_intersect.ptx @@ -0,0 +1,271 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31442593 +// Cuda compilation tools, release 11.7, V11.7.99 +// Based on NVVM 7.0.1 +// + +.version 7.7 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.global .align 16 .b8 sphere[16]; +.global .align 8 .b8 launch_index[8]; +.global .align 4 .u32 b_index; +.global .align 1 .b8 output_buffer[1]; +.global .align 1 .b8 output_buffer2[1]; +.global .align 4 .b8 bvh[4]; +.global .align 4 .b8 ray[36]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo7b_indexE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename7b_indexE[13] = {117, 110, 115, 105, 103, 110, 101, 100, 32, 105, 110, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum7b_indexE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic7b_indexE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation7b_indexE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<6>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f7, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z10set_bufferv +.visible .entry _Z10set_bufferv() +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + ld.global.u32 %rd3, [b_index]; + mov.u64 %rd6, 0; + mov.u64 %rd7, output_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + atom.add.u32 %r3, [%rd1], 1; + ret; + +} + // .globl _Z11set_buffer2v +.visible .entry _Z11set_buffer2v() +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + ld.global.u32 %rd3, [b_index]; + mov.u64 %rd6, 0; + mov.u64 %rd7, output_buffer2; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + atom.add.u32 %r3, [%rd1], 1; + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<5>; + .reg .f32 %f<43>; + .reg .b32 %r<7>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB3_5; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f37, %f1, %f40; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB3_3; + + ld.global.u32 %r3, [launch_index]; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.ne.s32 %p3, %r2, 0; + @%p3 bra $L__BB3_5; + +$L__BB3_3: + sub.f32 %f42, %f4, %f2; + mul.f32 %f41, %f1, %f42; + // begin inline asm + call (%r4), _rt_potential_intersection, (%f41); + // end inline asm + setp.eq.s32 %p4, %r4, 0; + @%p4 bra $L__BB3_5; + + ld.global.u32 %r6, [launch_index]; + // begin inline asm + call (%r5), _rt_report_intersection, (%r6); + // end inline asm + +$L__BB3_5: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB4_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB4_3; + bra.uni $L__BB4_2; + +$L__BB4_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB4_4; + +$L__BB4_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB4_4: + ret; + +} + diff --git a/zluda_rt/src/tests/barycentrics.cu b/zluda_rt/src/tests/barycentrics.cu new file mode 100644 index 0000000..fdd600d --- /dev/null +++ b/zluda_rt/src/tests/barycentrics.cu @@ -0,0 +1,84 @@ +// nvcc barycentrics.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtDeclareVariable(float2, barycentrics, attribute rtTriangleBarycentrics, ); +rtBuffer output_buffer1; +rtBuffer output_buffer2; +rtBuffer output_buffer3; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(float4, sphere, , ); + +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); +rtDeclareVariable(int2, launch_index, rtLaunchIndex, ); + +RT_PROGRAM void start() { + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O)-radius*radius; + float disc = b*b-c; + if(disc > 0.0f){ + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if( rtPotentialIntersection( (root1 + root11) * l ) ) { + barycentrics = make_float2(100, 200); + if(rtReportIntersection(0)) + check_second = false; + } + if(check_second) { + float root2 = (-b + sdisc); + if( rtPotentialIntersection( root2 * l ) ) { + barycentrics = make_float2(100, 200); + rtReportIntersection(0); + } + } + } +} + +RT_PROGRAM void bounds (int, float result[6]) +{ + const float3 cen = make_float3( sphere ); + const float3 rad = make_float3( sphere.w ); + + optix::Aabb* aabb = (optix::Aabb*)result; + + if( rad.x > 0.0f && !isinf(rad.x) ) { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } else { + aabb->invalidate(); + } +} + +RT_PROGRAM void attribute_program() { + float2 read_barycentrics = rtGetTriangleBarycentrics(); + barycentrics.x = read_barycentrics.x; + barycentrics.y = 0.1; +} + +RT_PROGRAM void closest_hit() { + output_buffer1[launch_index.x] = barycentrics; + // rtGetTriangleBarycentrics() happens to work here, + // but is only valid in attribute programs + //output_buffer2[launch_index.x] = rtGetTriangleBarycentrics(); + output_buffer3[launch_index.x] = rtGetPrimitiveIndex(); +} \ No newline at end of file diff --git a/zluda_rt/src/tests/barycentrics.ptx b/zluda_rt/src/tests/barycentrics.ptx new file mode 100644 index 0000000..2e6c878 --- /dev/null +++ b/zluda_rt/src/tests/barycentrics.ptx @@ -0,0 +1,297 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 8 .b8 barycentrics[8]; +.visible .global .align 1 .b8 output_buffer1[1]; +.visible .global .align 1 .b8 output_buffer2[1]; +.visible .global .align 1 .b8 output_buffer3[1]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 16 .b8 sphere[16]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12barycentricsE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12barycentricsE[7] = {102, 108, 111, 97, 116, 50, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[5] = {105, 110, 116, 50, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12barycentricsE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12barycentricsE[33] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 114, 116, 84, 114, 105, 97, 110, 103, 108, 101, 66, 97, 114, 121, 99, 101, 110, 116, 114, 105, 99, 115, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12barycentricsE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.s32 %f1, %r6; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<5>; + .reg .f32 %f<47>; + .reg .b32 %r<7>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB1_5; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f37, %f1, %f40; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB1_3; + + mov.f32 %f41, 0f43480000; + mov.f32 %f42, 0f42C80000; + st.global.v2.f32 [barycentrics], {%f42, %f41}; + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.ne.s32 %p3, %r2, 0; + @%p3 bra $L__BB1_5; + +$L__BB1_3: + sub.f32 %f44, %f4, %f2; + mul.f32 %f43, %f1, %f44; + // begin inline asm + call (%r4), _rt_potential_intersection, (%f43); + // end inline asm + setp.eq.s32 %p4, %r4, 0; + @%p4 bra $L__BB1_5; + + mov.f32 %f45, 0f43480000; + mov.f32 %f46, 0f42C80000; + st.global.v2.f32 [barycentrics], {%f46, %f45}; + mov.u32 %r6, 0; + // begin inline asm + call (%r5), _rt_report_intersection, (%r6); + // end inline asm + +$L__BB1_5: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + // .globl _Z17attribute_programv +.visible .entry _Z17attribute_programv() +{ + .reg .f32 %f<4>; + + + // begin inline asm + call (%f1, %f2), _rt_get_triangle_barycentrics, (); + // end inline asm + mov.f32 %f3, 0f3DCCCCCD; + st.global.v2.f32 [barycentrics], {%f1, %f3}; + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .reg .f32 %f<7>; + .reg .b32 %r<8>; + .reg .b64 %rd<22>; + + + ld.global.v2.f32 {%f3, %f4}, [barycentrics]; + mov.u64 %rd18, 0; + ld.global.s32 %rd3, [launch_index]; + mov.u64 %rd19, output_buffer1; + cvta.global.u64 %rd2, %rd19; + mov.u32 %r6, 1; + mov.u32 %r4, 8; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r6, %r4, %rd3, %rd18, %rd18, %rd18); + // end inline asm + st.v2.f32 [%rd1], {%f3, %f4}; + // begin inline asm + call (%f1, %f2), _rt_get_triangle_barycentrics, (); + // end inline asm + ld.global.s32 %rd9, [launch_index]; + mov.u64 %rd20, output_buffer2; + cvta.global.u64 %rd8, %rd20; + // begin inline asm + call (%rd7), _rt_buffer_get_64, (%rd8, %r6, %r4, %rd9, %rd18, %rd18, %rd18); + // end inline asm + st.v2.f32 [%rd7], {%f1, %f2}; + // begin inline asm + call (%r5), _rt_get_primitive_index, (); + // end inline asm + ld.global.s32 %rd15, [launch_index]; + mov.u64 %rd21, output_buffer3; + cvta.global.u64 %rd14, %rd21; + mov.u32 %r7, 4; + // begin inline asm + call (%rd13), _rt_buffer_get_64, (%rd14, %r6, %r7, %rd15, %rd18, %rd18, %rd18); + // end inline asm + st.u32 [%rd13], %r5; + ret; + +} + diff --git a/zluda_rt/src/tests/buffer_id.cu b/zluda_rt/src/tests/buffer_id.cu new file mode 100644 index 0000000..968bc85 --- /dev/null +++ b/zluda_rt/src/tests/buffer_id.cu @@ -0,0 +1,13 @@ +// nvcc buffer_id.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer > buffers; + +RT_PROGRAM void start() { + buffers[0][2] = 0x0118378c; + buffers[0][1] = buffers[0].size(); +} diff --git a/zluda_rt/src/tests/buffer_id.ptx b/zluda_rt/src/tests/buffer_id.ptx new file mode 100644 index 0000000..4ae8645 --- /dev/null +++ b/zluda_rt/src/tests/buffer_id.ptx @@ -0,0 +1,80 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 buffers[1]; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; + +.visible .entry _Z5startv() +{ + .reg .b32 %r<17>; + .reg .b64 %rd<34>; + + + mov.u64 %rd33, buffers; + cvta.global.u64 %rd2, %rd33; + mov.u32 %r14, 1; + mov.u32 %r15, 4; + mov.u64 %rd32, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u64 %rd8, 2; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r14, %r15, %rd8, %rd32, %rd32, %rd32); + // end inline asm + mov.u32 %r16, 18364300; + st.u32 [%rd7], %r16; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18, %rd19, %rd20, %rd21), _rt_buffer_get_id_size_64, (%r8, %r14, %r15); + // end inline asm + // begin inline asm + call (%rd22), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r13, [%rd22]; + mov.u64 %rd29, 1; + // begin inline asm + call (%rd28), _rt_buffer_get_id_64, (%r13, %r14, %r15, %rd29, %rd32, %rd32, %rd32); + // end inline asm + st.u32 [%rd28], %rd18; + ret; + +} + diff --git a/zluda_rt/src/tests/buffer_id_call.cu b/zluda_rt/src/tests/buffer_id_call.cu new file mode 100644 index 0000000..a9c7659 --- /dev/null +++ b/zluda_rt/src/tests/buffer_id_call.cu @@ -0,0 +1,23 @@ +// nvcc buffer_id_call.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer > buffers; + +__noinline__ +__device__ void start2() { + buffers[0][2] = 0x0118378c; + buffers[0][1] = buffers[0].size(); +} + +__noinline__ +__device__ void start1() { + start2(); +} + +RT_PROGRAM void start() { + start1(); +} diff --git a/zluda_rt/src/tests/buffer_id_call.ptx b/zluda_rt/src/tests/buffer_id_call.ptx new file mode 100644 index 0000000..6c2432f --- /dev/null +++ b/zluda_rt/src/tests/buffer_id_call.ptx @@ -0,0 +1,112 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z6start2v +.visible .global .align 1 .b8 buffers[1]; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; + +.visible .func _Z6start2v() +{ + .reg .b32 %r<17>; + .reg .b64 %rd<34>; + + + mov.u64 %rd33, buffers; + cvta.global.u64 %rd2, %rd33; + mov.u32 %r14, 1; + mov.u32 %r15, 4; + mov.u64 %rd32, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u64 %rd8, 2; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r14, %r15, %rd8, %rd32, %rd32, %rd32); + // end inline asm + mov.u32 %r16, 18364300; + st.u32 [%rd7], %r16; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18, %rd19, %rd20, %rd21), _rt_buffer_get_id_size_64, (%r8, %r14, %r15); + // end inline asm + // begin inline asm + call (%rd22), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r13, [%rd22]; + mov.u64 %rd29, 1; + // begin inline asm + call (%rd28), _rt_buffer_get_id_64, (%r13, %r14, %r15, %rd29, %rd32, %rd32, %rd32); + // end inline asm + st.u32 [%rd28], %rd18; + ret; + +} + // .globl _Z6start1v +.visible .func _Z6start1v() +{ + + + + { // callseq 0, 0 + .reg .b32 temp_param_reg; + call.uni + _Z6start2v, + ( + ); + } // callseq 0 + ret; + +} + // .globl _Z5startv +.visible .entry _Z5startv() +{ + + + + { // callseq 1, 0 + .reg .b32 temp_param_reg; + call.uni + _Z6start1v, + ( + ); + } // callseq 1 + ret; + +} + diff --git a/zluda_rt/src/tests/buffer_id_callable.cu b/zluda_rt/src/tests/buffer_id_callable.cu new file mode 100644 index 0000000..e590d7e --- /dev/null +++ b/zluda_rt/src/tests/buffer_id_callable.cu @@ -0,0 +1,18 @@ +// nvcc buffer_id_callable.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer > buffers; +rtDeclareVariable(rtCallableProgramId, program,,); + +RT_CALLABLE_PROGRAM void callable() { + buffers[0][2] = 0x0118378c; + buffers[0][1] = buffers[0].size(); +} + +RT_PROGRAM void start() { + program(); +} diff --git a/zluda_rt/src/tests/buffer_id_callable.ptx b/zluda_rt/src/tests/buffer_id_callable.ptx new file mode 100644 index 0000000..4826996 --- /dev/null +++ b/zluda_rt/src/tests/buffer_id_callable.ptx @@ -0,0 +1,110 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z8callablev +.visible .global .align 1 .b8 buffers[1]; +.visible .global .align 4 .b8 program[4]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo7programE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename7programE[32] = {114, 116, 67, 97, 108, 108, 97, 98, 108, 101, 80, 114, 111, 103, 114, 97, 109, 73, 100, 60, 118, 111, 105, 100, 40, 118, 111, 105, 100, 41, 62, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum7programE = 4920; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic7programE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation7programE[1]; + +.visible .func _Z8callablev() +{ + .reg .b32 %r<17>; + .reg .b64 %rd<34>; + + + mov.u64 %rd33, buffers; + cvta.global.u64 %rd2, %rd33; + mov.u32 %r14, 1; + mov.u32 %r15, 4; + mov.u64 %rd32, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u64 %rd8, 2; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r14, %r15, %rd8, %rd32, %rd32, %rd32); + // end inline asm + mov.u32 %r16, 18364300; + st.u32 [%rd7], %r16; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18, %rd19, %rd20, %rd21), _rt_buffer_get_id_size_64, (%r8, %r14, %r15); + // end inline asm + // begin inline asm + call (%rd22), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd32, %rd32, %rd32, %rd32); + // end inline asm + ld.u32 %r13, [%rd22]; + mov.u64 %rd29, 1; + // begin inline asm + call (%rd28), _rt_buffer_get_id_64, (%r13, %r14, %r15, %rd29, %rd32, %rd32, %rd32); + // end inline asm + st.u32 [%rd28], %rd18; + ret; + +} + // .globl _Z5startv +.visible .entry _Z5startv() +{ + .reg .b32 %r<2>; + .reg .b64 %rd<4>; + + + ld.global.u32 %r1, [program]; + mov.u64 %rd2, 0; + // begin inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd2); + // end inline asm + { // callseq 0, 0 + .reg .b32 temp_param_reg; + prototype_0 : .callprototype ()_ (); + call + %rd1, + ( + ) + , prototype_0; + } // callseq 0 + ret; + +} + diff --git a/zluda_rt/src/tests/buffer_mipmap.cu b/zluda_rt/src/tests/buffer_mipmap.cu new file mode 100644 index 0000000..e08cc8a --- /dev/null +++ b/zluda_rt/src/tests/buffer_mipmap.cu @@ -0,0 +1,17 @@ +// nvcc buffer_id.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtDeclareVariable( uint, texture_id, , ); +rtBuffer output_buffer; + +RT_PROGRAM void start() { + bool isResident; + uint4 val0 = rtTex2DLodLoadOrRequest( texture_id, 0, 0, 0, isResident ); + output_buffer[0] = make_uint2(val0.x, val0.y); + uint4 val1 = rtTex2DLodLoadOrRequest( texture_id, 0, 0, 1000, isResident ); + output_buffer[1] = make_uint2(val1.x, val1.y); +} diff --git a/zluda_rt/src/tests/buffer_mipmap.ptx b/zluda_rt/src/tests/buffer_mipmap.ptx new file mode 100644 index 0000000..6889584 --- /dev/null +++ b/zluda_rt/src/tests/buffer_mipmap.ptx @@ -0,0 +1,89 @@ +// +// 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 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 4 .u32 texture_id; +.visible .global .align 1 .b8 output_buffer[1]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo10texture_idE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename10texture_idE[5] = {117, 105, 110, 116, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum10texture_idE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic10texture_idE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation10texture_idE[1]; + +.visible .entry _Z5startv( + +) +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .f32 %f<11>; + .reg .b32 %r<17>; + .reg .b64 %rd<16>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + ld.global.u32 %r5, [texture_id]; + mov.u32 %r14, 2; + mov.f32 %f9, 0f00000000; + add.u64 %rd8, %SP, 0; + // inline asm + call (%r1, %r2, %r3, %r4), _rt_texture_lod_load_or_request_u_id, (%r5, %r14, %f9, %f9, %f9, %f9, %f9, %rd8); + // inline asm + mov.u64 %rd15, output_buffer; + cvta.global.u64 %rd3, %rd15; + mov.u32 %r15, 1; + mov.u32 %r16, 8; + mov.u64 %rd14, 0; + // inline asm + call (%rd2), _rt_buffer_get_64, (%rd3, %r15, %r16, %rd14, %rd14, %rd14, %rd14); + // inline asm + st.v2.u32 [%rd2], {%r1, %r2}; + ld.global.u32 %r13, [texture_id]; + mov.f32 %f10, 0f447A0000; + // inline asm + call (%r9, %r10, %r11, %r12), _rt_texture_lod_load_or_request_u_id, (%r13, %r14, %f9, %f9, %f9, %f9, %f10, %rd8); + // inline asm + mov.u64 %rd11, 1; + // inline asm + call (%rd9), _rt_buffer_get_64, (%rd3, %r15, %r16, %rd11, %rd14, %rd14, %rd14); + // inline asm + st.v2.u32 [%rd9], {%r9, %r10}; + ret; +} + + diff --git a/zluda_rt/src/tests/callable_programs.cu b/zluda_rt/src/tests/callable_programs.cu new file mode 100644 index 0000000..c63aae5 --- /dev/null +++ b/zluda_rt/src/tests/callable_programs.cu @@ -0,0 +1,28 @@ +// nvcc callable_programs.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtDeclareVariable(unsigned int, value, , ); +rtBuffer output_buffer; + +typedef rtCallableProgramId int_operator; +rtDeclareVariable(int_operator, add_fn,,); +rtDeclareVariable(int_operator, mult_fn,,); + +RT_CALLABLE_PROGRAM unsigned int add_value(unsigned int input) { + return input + value; +} + +RT_CALLABLE_PROGRAM unsigned int multiply_value(unsigned int input) { + return input * value; +} + +RT_PROGRAM void start() { + unsigned int x = value; + x = add_fn(x); + x = mult_fn(x); + output_buffer[0] = x; +} diff --git a/zluda_rt/src/tests/callable_programs.ptx b/zluda_rt/src/tests/callable_programs.ptx new file mode 100644 index 0000000..b626980 --- /dev/null +++ b/zluda_rt/src/tests/callable_programs.ptx @@ -0,0 +1,152 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z9add_valuej +.visible .global .align 4 .u32 value; +.visible .global .align 1 .b8 output_buffer[1]; +.visible .global .align 4 .b8 add_fn[4]; +.visible .global .align 4 .b8 mult_fn[4]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo5valueE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6add_fnE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo7mult_fnE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename5valueE[13] = {117, 110, 115, 105, 103, 110, 101, 100, 32, 105, 110, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6add_fnE[13] = {105, 110, 116, 95, 111, 112, 101, 114, 97, 116, 111, 114, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename7mult_fnE[13] = {105, 110, 116, 95, 111, 112, 101, 114, 97, 116, 111, 114, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum5valueE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6add_fnE = 4920; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum7mult_fnE = 4920; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic5valueE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6add_fnE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic7mult_fnE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation5valueE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6add_fnE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation7mult_fnE[1]; + +.visible .func (.param .b32 func_retval0) _Z9add_valuej( + .param .b32 _Z9add_valuej_param_0 +) +{ + .reg .b32 %r<4>; + + + ld.param.u32 %r1, [_Z9add_valuej_param_0]; + ld.global.u32 %r2, [value]; + add.s32 %r3, %r2, %r1; + st.param.b32 [func_retval0+0], %r3; + ret; + +} + // .globl _Z14multiply_valuej +.visible .func (.param .b32 func_retval0) _Z14multiply_valuej( + .param .b32 _Z14multiply_valuej_param_0 +) +{ + .reg .b32 %r<4>; + + + ld.param.u32 %r1, [_Z14multiply_valuej_param_0]; + ld.global.u32 %r2, [value]; + mul.lo.s32 %r3, %r2, %r1; + st.param.b32 [func_retval0+0], %r3; + ret; + +} + // .globl _Z5startv +.visible .entry _Z5startv() +{ + .reg .b32 %r<8>; + .reg .b64 %rd<14>; + + + ld.global.u32 %r5, [value]; + mov.u64 %rd10, 0; + ld.global.u32 %r1, [add_fn]; + // begin inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd10); + // end inline asm + mov.u32 %r3, 1; + { // callseq 0, 0 + .reg .b32 temp_param_reg; + .param .b32 param0; + st.param.b32 [param0+0], %r5; + .param .b32 retval0; + prototype_0 : .callprototype (.param .b32 _) _ (.param .b32 _); + call (retval0), + %rd1, + ( + param0 + ) + , prototype_0; + ld.param.b32 %r6, [retval0+0]; + } // callseq 0 + ld.global.u32 %r2, [mult_fn]; + // begin inline asm + call (%rd3), _rt_callable_program_from_id_v2_64, (%r2, %rd10); + // end inline asm + { // callseq 1, 0 + .reg .b32 temp_param_reg; + .param .b32 param0; + st.param.b32 [param0+0], %r6; + .param .b32 retval0; + prototype_1 : .callprototype (.param .b32 _) _ (.param .b32 _); + call (retval0), + %rd3, + ( + param0 + ) + , prototype_1; + ld.param.b32 %r7, [retval0+0]; + } // callseq 1 + mov.u64 %rd13, output_buffer; + cvta.global.u64 %rd6, %rd13; + mov.u32 %r4, 4; + // begin inline asm + call (%rd5), _rt_buffer_get_64, (%rd6, %r3, %r4, %rd10, %rd10, %rd10, %rd10); + // end inline asm + st.u32 [%rd5], %r7; + ret; + +} + // .globl _Z10do_nothingv +.visible .entry _Z10do_nothingv() +{ + + + + ret; + +} + diff --git a/zluda_rt/src/tests/default_variable.cu b/zluda_rt/src/tests/default_variable.cu new file mode 100644 index 0000000..13e7a99 --- /dev/null +++ b/zluda_rt/src/tests/default_variable.cu @@ -0,0 +1,13 @@ +// nvcc default_variable.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer var_buffer; +rtDeclareVariable(unsigned int, x, , ) = 55; + +RT_PROGRAM void start() { + var_buffer[0] = x; +} diff --git a/zluda_rt/src/tests/default_variable.ptx b/zluda_rt/src/tests/default_variable.ptx new file mode 100644 index 0000000..22d1b96 --- /dev/null +++ b/zluda_rt/src/tests/default_variable.ptx @@ -0,0 +1,65 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 var_buffer[1]; +.visible .global .align 4 .u32 x = 55; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo1xE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename1xE[13] = {117, 110, 115, 105, 103, 110, 101, 100, 32, 105, 110, 116, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum1xE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic1xE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation1xE[1]; + +.visible .entry _Z5startv() +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + ld.global.u32 %r3, [x]; + mov.u64 %rd6, 0; + mov.u64 %rd7, var_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd6, %rd6, %rd6, %rd6); + // end inline asm + st.u32 [%rd1], %r3; + ret; + +} + diff --git a/zluda_rt/src/tests/exception.cu b/zluda_rt/src/tests/exception.cu new file mode 100644 index 0000000..c114768 --- /dev/null +++ b/zluda_rt/src/tests/exception.cu @@ -0,0 +1,50 @@ +// nvcc exception.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer var_buffer; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); +typedef rtCallableProgramId int_operator; +rtDeclareVariable(int_operator, callable1,,); +rtDeclareVariable(int_operator, callable2,,); +rtDeclareVariable(int_operator, callable3,,); + +RT_PROGRAM void trace() { + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void throw_() { + rtThrow(RT_EXCEPTION_USER); +} + +RT_PROGRAM void exception() { + var_buffer[0] = rtGetExceptionCode(); +} + +RT_PROGRAM void call_callable1() { + callable1(1); +} + +RT_CALLABLE_PROGRAM unsigned int call_callable2(unsigned int x) { + return callable2(x); +} + +RT_CALLABLE_PROGRAM unsigned int throw_callable(unsigned int x) { + rtThrow(RT_EXCEPTION_USER + x); + return x; +} + +__noinline__ __device__ void throw_callable_sub() { + callable3(1); +} + +RT_CALLABLE_PROGRAM unsigned int throw_callable_main(unsigned int x) { + throw_callable_sub(); + return x; +} diff --git a/zluda_rt/src/tests/exception.ptx b/zluda_rt/src/tests/exception.ptx new file mode 100644 index 0000000..b0304e0 --- /dev/null +++ b/zluda_rt/src/tests/exception.ptx @@ -0,0 +1,294 @@ +// +// 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 +.address_size 64 + + // .globl _Z14call_callable2j +.visible .global .align 1 .b8 var_buffer[1]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .b8 callable1[4]; +.visible .global .align 4 .b8 callable2[4]; +.visible .global .align 4 .b8 callable3[4]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo9callable1E[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo9callable2E[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo9callable3E[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename9callable1E[13] = {105, 110, 116, 95, 111, 112, 101, 114, 97, 116, 111, 114, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename9callable2E[13] = {105, 110, 116, 95, 111, 112, 101, 114, 97, 116, 111, 114, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename9callable3E[13] = {105, 110, 116, 95, 111, 112, 101, 114, 97, 116, 111, 114, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum9callable1E = 4920; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum9callable2E = 4920; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum9callable3E = 4920; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic9callable1E[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic9callable2E[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic9callable3E[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation9callable1E[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation9callable2E[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation9callable3E[1]; + +.visible .func (.param .b32 func_retval0) _Z14call_callable2j( + .param .b32 _Z14call_callable2j_param_0 +) +{ + .reg .b32 %r<4>; + .reg .b64 %rd<4>; + + + ld.param.u32 %r2, [_Z14call_callable2j_param_0]; + ld.global.u32 %r1, [callable2]; + mov.u64 %rd2, 0; + // inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd2); + // inline asm + // Callseq Start 0 + { + .reg .b32 temp_param_reg; + // } + .param .b32 param0; + st.param.b32 [param0+0], %r2; + .param .b32 retval0; + prototype_0 : .callprototype (.param .b32 _) _ (.param .b32 _) ; + call (retval0), + %rd1, + ( + param0 + ) + , prototype_0; + ld.param.b32 %r3, [retval0+0]; + + //{ + }// Callseq End 0 + st.param.b32 [func_retval0+0], %r3; + ret; +} + + // .globl _Z14throw_callablej +.visible .func (.param .b32 func_retval0) _Z14throw_callablej( + .param .b32 _Z14throw_callablej_param_0 +) +{ + .reg .b32 %r<3>; + + + ld.param.u32 %r2, [_Z14throw_callablej_param_0]; + add.s32 %r1, %r2, 1024; + // inline asm + call _rt_throw, (%r1); + // inline asm + st.param.b32 [func_retval0+0], %r2; + ret; +} + + // .globl _Z18throw_callable_subv +.visible .func _Z18throw_callable_subv( + +) +{ + .reg .b32 %r<4>; + .reg .b64 %rd<4>; + + + ld.global.u32 %r1, [callable3]; + mov.u64 %rd2, 0; + // inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd2); + // inline asm + mov.u32 %r2, 1; + // Callseq Start 1 + { + .reg .b32 temp_param_reg; + // } + .param .b32 param0; + st.param.b32 [param0+0], %r2; + .param .b32 retval0; + prototype_1 : .callprototype (.param .b32 _) _ (.param .b32 _) ; + call (retval0), + %rd1, + ( + param0 + ) + , prototype_1; + ld.param.b32 %r3, [retval0+0]; + + //{ + }// Callseq End 1 + ret; +} + + // .globl _Z19throw_callable_mainj +.visible .func (.param .b32 func_retval0) _Z19throw_callable_mainj( + .param .b32 _Z19throw_callable_mainj_param_0 +) +{ + .reg .b32 %r<2>; + + + ld.param.u32 %r1, [_Z19throw_callable_mainj_param_0]; + // Callseq Start 2 + { + .reg .b32 temp_param_reg; + // } + call.uni + _Z18throw_callable_subv, + ( + ); + + //{ + }// Callseq End 2 + st.param.b32 [func_retval0+0], %r1; + ret; +} + + // .globl _Z5tracev +.visible .entry _Z5tracev( + +) +{ + .local .align 1 .b8 __local_depot4[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot4; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.u32 %f1, %r6; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + // inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // inline asm + ret; +} + + // .globl _Z6throw_v +.visible .entry _Z6throw_v( + +) +{ + .reg .b32 %r<2>; + + + mov.u32 %r1, 1024; + // inline asm + call _rt_throw, (%r1); + // inline asm + ret; +} + + // .globl _Z9exceptionv +.visible .entry _Z9exceptionv( + +) +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + // inline asm + call (%r1), _rt_get_exception_code, (); + // inline asm + mov.u64 %rd7, var_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r2, 1; + mov.u32 %r3, 4; + mov.u64 %rd6, 0; + // inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r2, %r3, %rd6, %rd6, %rd6, %rd6); + // inline asm + st.u32 [%rd1], %r1; + ret; +} + + // .globl _Z14call_callable1v +.visible .entry _Z14call_callable1v( + +) +{ + .reg .b32 %r<4>; + .reg .b64 %rd<4>; + + + ld.global.u32 %r1, [callable1]; + mov.u64 %rd2, 0; + // inline asm + call (%rd1), _rt_callable_program_from_id_v2_64, (%r1, %rd2); + // inline asm + mov.u32 %r2, 1; + // Callseq Start 3 + { + .reg .b32 temp_param_reg; + // } + .param .b32 param0; + st.param.b32 [param0+0], %r2; + .param .b32 retval0; + prototype_3 : .callprototype (.param .b32 _) _ (.param .b32 _) ; + call (retval0), + %rd1, + ( + param0 + ) + , prototype_3; + ld.param.b32 %r3, [retval0+0]; + + //{ + }// Callseq End 3 + ret; +} + + diff --git a/zluda_rt/src/tests/exception_subfunc.cu b/zluda_rt/src/tests/exception_subfunc.cu new file mode 100644 index 0000000..4d57a77 --- /dev/null +++ b/zluda_rt/src/tests/exception_subfunc.cu @@ -0,0 +1,28 @@ +// nvcc exception.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer var_buffer; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); + +__device__ __noinline__ void trace() { + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void start() { + trace(); +} + +RT_PROGRAM void throw_() { + rtThrow(RT_EXCEPTION_USER); +} + +RT_PROGRAM void exception() { + var_buffer[0] = rtGetExceptionCode(); +} diff --git a/zluda_rt/src/tests/exception_subfunc.ptx b/zluda_rt/src/tests/exception_subfunc.ptx new file mode 100644 index 0000000..d05b30a --- /dev/null +++ b/zluda_rt/src/tests/exception_subfunc.ptx @@ -0,0 +1,148 @@ +// +// 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 +.address_size 64 + + // .globl _Z5tracev +.visible .global .align 1 .b8 var_buffer[1]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; + +.visible .func _Z5tracev( + +) +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.u32 %f1, %r6; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + // inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // inline asm + ret; +} + + // .globl _Z5startv +.visible .entry _Z5startv( + +) +{ + + + + // Callseq Start 0 + { + .reg .b32 temp_param_reg; + // } + call.uni + _Z5tracev, + ( + ); + + //{ + }// Callseq End 0 + ret; +} + + // .globl _Z6throw_v +.visible .entry _Z6throw_v( + +) +{ + .reg .b32 %r<2>; + + + mov.u32 %r1, 1024; + // inline asm + call _rt_throw, (%r1); + // inline asm + ret; +} + + // .globl _Z9exceptionv +.visible .entry _Z9exceptionv( + +) +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + // inline asm + call (%r1), _rt_get_exception_code, (); + // inline asm + mov.u64 %rd7, var_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r2, 1; + mov.u32 %r3, 4; + mov.u64 %rd6, 0; + // inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r2, %r3, %rd6, %rd6, %rd6, %rd6); + // inline asm + st.u32 [%rd1], %r1; + ret; +} + + diff --git a/zluda_rt/src/tests/get_transform.cu b/zluda_rt/src/tests/get_transform.cu new file mode 100644 index 0000000..59dbb17 --- /dev/null +++ b/zluda_rt/src/tests/get_transform.cu @@ -0,0 +1,80 @@ +// nvcc get_transform.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer object_transforms; +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(float4, sphere, , ); +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); + +RT_PROGRAM void start() { + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O)-radius*radius; + float disc = b*b-c; + if(disc > 0.0f){ + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if( rtPotentialIntersection( (root1 + root11) * l ) ) { + if(rtReportIntersection(0)) + { + rtGetTransform(RT_OBJECT_TO_WORLD, &object_transforms[16*0]); + check_second = false; + } + } + if(check_second) { + float root2 = (-b + sdisc); + if( rtPotentialIntersection( root2 * l ) ) { + if(rtReportIntersection(0)) + { + rtGetTransform(RT_OBJECT_TO_WORLD, &object_transforms[16*0]); + } + } + } + } +} + +RT_PROGRAM void bounds (int, float result[6]) +{ + // fails compilation + //rtGetTransform(RT_OBJECT_TO_WORLD, &object_transforms[16*0]); + const float3 cen = make_float3( sphere ); + const float3 rad = make_float3( sphere.w ); + + optix::Aabb* aabb = (optix::Aabb*)result; + + if( rad.x > 0.0f && !isinf(rad.x) ) { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } else { + aabb->invalidate(); + } +} + +RT_PROGRAM void any_hit() { + rtGetTransform(RT_OBJECT_TO_WORLD, &object_transforms[16*1]); +} + +RT_PROGRAM void closest_hit() { + rtGetTransform(RT_WORLD_TO_OBJECT, &object_transforms[16*2]); +} diff --git a/zluda_rt/src/tests/get_transform.ptx b/zluda_rt/src/tests/get_transform.ptx new file mode 100644 index 0000000..5b19a1c --- /dev/null +++ b/zluda_rt/src/tests/get_transform.ptx @@ -0,0 +1,368 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 object_transforms[1]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 16 .b8 sphere[16]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.u32 %f1, %r6; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<6>; + .reg .f32 %f<75>; + .reg .b32 %r<13>; + .reg .b64 %rd<15>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB1_7; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f37, %f1, %f40; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB1_4; + + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.eq.s32 %p3, %r2, 0; + @%p3 bra $L__BB1_4; + + mov.u64 %rd7, object_transforms; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r4, 1; + mov.u32 %r5, 4; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r4, %r5, %rd6, %rd6, %rd6, %rd6); + // end inline asm + mov.u32 %r6, 3841; + // begin inline asm + call (%f41, %f42, %f43, %f44, %f45, %f46, %f47, %f48, %f49, %f50, %f51, %f52, %f53, %f54, %f55, %f56), _rt_get_transform, (%r6); + // end inline asm + st.f32 [%rd1], %f41; + st.f32 [%rd1+4], %f42; + st.f32 [%rd1+8], %f43; + st.f32 [%rd1+12], %f44; + st.f32 [%rd1+16], %f45; + st.f32 [%rd1+20], %f46; + st.f32 [%rd1+24], %f47; + st.f32 [%rd1+28], %f48; + st.f32 [%rd1+32], %f49; + st.f32 [%rd1+36], %f50; + st.f32 [%rd1+40], %f51; + st.f32 [%rd1+44], %f52; + st.f32 [%rd1+48], %f53; + st.f32 [%rd1+52], %f54; + st.f32 [%rd1+56], %f55; + st.f32 [%rd1+60], %f56; + bra.uni $L__BB1_7; + +$L__BB1_4: + sub.f32 %f58, %f4, %f2; + mul.f32 %f57, %f1, %f58; + // begin inline asm + call (%r7), _rt_potential_intersection, (%f57); + // end inline asm + setp.eq.s32 %p4, %r7, 0; + @%p4 bra $L__BB1_7; + + mov.u32 %r9, 0; + // begin inline asm + call (%r8), _rt_report_intersection, (%r9); + // end inline asm + setp.eq.s32 %p5, %r8, 0; + @%p5 bra $L__BB1_7; + + mov.u64 %rd14, object_transforms; + cvta.global.u64 %rd9, %rd14; + mov.u32 %r10, 1; + mov.u32 %r11, 4; + mov.u64 %rd13, 0; + // begin inline asm + call (%rd8), _rt_buffer_get_64, (%rd9, %r10, %r11, %rd13, %rd13, %rd13, %rd13); + // end inline asm + mov.u32 %r12, 3841; + // begin inline asm + call (%f59, %f60, %f61, %f62, %f63, %f64, %f65, %f66, %f67, %f68, %f69, %f70, %f71, %f72, %f73, %f74), _rt_get_transform, (%r12); + // end inline asm + st.f32 [%rd8], %f59; + st.f32 [%rd8+4], %f60; + st.f32 [%rd8+8], %f61; + st.f32 [%rd8+12], %f62; + st.f32 [%rd8+16], %f63; + st.f32 [%rd8+20], %f64; + st.f32 [%rd8+24], %f65; + st.f32 [%rd8+28], %f66; + st.f32 [%rd8+32], %f67; + st.f32 [%rd8+36], %f68; + st.f32 [%rd8+40], %f69; + st.f32 [%rd8+44], %f70; + st.f32 [%rd8+48], %f71; + st.f32 [%rd8+52], %f72; + st.f32 [%rd8+56], %f73; + st.f32 [%rd8+60], %f74; + +$L__BB1_7: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + // .globl _Z7any_hitv +.visible .entry _Z7any_hitv() +{ + .reg .f32 %f<17>; + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + mov.u64 %rd7, object_transforms; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd3, 16; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + mov.u32 %r3, 3841; + // begin inline asm + call (%f1, %f2, %f3, %f4, %f5, %f6, %f7, %f8, %f9, %f10, %f11, %f12, %f13, %f14, %f15, %f16), _rt_get_transform, (%r3); + // end inline asm + st.f32 [%rd1], %f1; + st.f32 [%rd1+4], %f2; + st.f32 [%rd1+8], %f3; + st.f32 [%rd1+12], %f4; + st.f32 [%rd1+16], %f5; + st.f32 [%rd1+20], %f6; + st.f32 [%rd1+24], %f7; + st.f32 [%rd1+28], %f8; + st.f32 [%rd1+32], %f9; + st.f32 [%rd1+36], %f10; + st.f32 [%rd1+40], %f11; + st.f32 [%rd1+44], %f12; + st.f32 [%rd1+48], %f13; + st.f32 [%rd1+52], %f14; + st.f32 [%rd1+56], %f15; + st.f32 [%rd1+60], %f16; + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .reg .f32 %f<17>; + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + mov.u64 %rd7, object_transforms; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd3, 32; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + mov.u32 %r3, 3840; + // begin inline asm + call (%f1, %f2, %f3, %f4, %f5, %f6, %f7, %f8, %f9, %f10, %f11, %f12, %f13, %f14, %f15, %f16), _rt_get_transform, (%r3); + // end inline asm + st.f32 [%rd1], %f1; + st.f32 [%rd1+4], %f2; + st.f32 [%rd1+8], %f3; + st.f32 [%rd1+12], %f4; + st.f32 [%rd1+16], %f5; + st.f32 [%rd1+20], %f6; + st.f32 [%rd1+24], %f7; + st.f32 [%rd1+28], %f8; + st.f32 [%rd1+32], %f9; + st.f32 [%rd1+36], %f10; + st.f32 [%rd1+40], %f11; + st.f32 [%rd1+44], %f12; + st.f32 [%rd1+48], %f13; + st.f32 [%rd1+52], %f14; + st.f32 [%rd1+56], %f15; + st.f32 [%rd1+60], %f16; + ret; + +} + diff --git a/zluda_rt/src/tests/mod.rs b/zluda_rt/src/tests/mod.rs new file mode 100644 index 0000000..7db155d --- /dev/null +++ b/zluda_rt/src/tests/mod.rs @@ -0,0 +1,1648 @@ +use crate::optix_test; +use crate::test_common::OptixFns; +use float_cmp::assert_approx_eq; +use glam::{Mat4, Quat, Vec3}; +use optix_types::*; +use std::{ffi::CStr, mem, ptr}; + +const _SET_VARIABLE_CU: &'static [u8] = b" +#include +#include + +using namespace optix; + +struct Payload { + float data; +}; + +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); +rtDeclareVariable(float, value, , ); +rtBuffer output_buffer; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(Payload, payload, rtPayload, ); + +RT_PROGRAM void start(void) +{ + Payload p { float(launch_index.x) }; + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + rtTrace(bvh, ray, p); +} + +RT_PROGRAM void set_variable(void) +{ + output_buffer[launch_index.x] = value; +} +"; + +const SET_VARIABLE_PTX: &'static [u8] = b" +.version 7.0 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.global .align 8 .b8 launch_index[8]; +.global .align 4 .f32 value; +.global .align 1 .b8 output_buffer[1]; +.global .align 4 .b8 bvh[4]; +.global .align 4 .b8 payload[4]; +.global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo5valueE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 4 .b8 _ZN21rti_internal_typeinfo7payloadE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename5valueE[6] = {102, 108, 111, 97, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.global .align 1 .b8 _ZN21rti_internal_typename7payloadE[8] = {80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum5valueE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.global .align 4 .u32 _ZN21rti_internal_typeenum7payloadE = 4919; +.global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.global .align 1 .b8 _ZN21rti_internal_semantic5valueE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.global .align 1 .b8 _ZN21rti_internal_semantic7payloadE[10] = {114, 116, 80, 97, 121, 108, 111, 97, 100, 0}; +.global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation5valueE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.global .align 1 .b8 _ZN23rti_internal_annotation7payloadE[1]; + +.visible .entry _Z5startv( + +) +{ + .local .align 4 .b8 __local_depot0[4]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.u32 %f1, %r6; + st.local.f32 [%rd2], %f1; + ld.global.u32 %r1, [bvh]; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 4; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + // inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // inline asm + ret; +} + + // .globl _Z12set_variablev +.visible .entry _Z12set_variablev( + +) +{ + .reg .f32 %f<2>; + .reg .b32 %r<3>; + .reg .b64 %rd<8>; + + + ld.global.f32 %f1, [value]; + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd7, output_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd6, 0; + // inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // inline asm + st.f32 [%rd1], %f1; + ret; +}\0"; + +optix_test!(variable_scoping); + +// List of points, `+` means variable is set, `-` means variable is unset +// 0: Program-, GI-, Material-, Context+ => produces 4 +// 1: Program+, GI-, Material-, Context+ => produces 1 +// 2: Program-, GI+, Material-, Context+ => produces 2 +// 3: Program-, GI-, Material+, Context+ => produces 3 +unsafe fn variable_scoping(mut o: Optix) { + let variable_key = b"value\0"; + let triangles = 4; + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let mut ctx_variable = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, variable_key.as_ptr() as _, &mut ctx_variable); + o.rtVariableSet1f(ctx_variable, 4f32); + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize1D(output_buffer, triangles as u64); + o.rtBufferSetFormat(output_buffer, RTformat::RT_FORMAT_FLOAT); + let mut output_buffer_var = ptr::null_mut(); + o.rtContextDeclareVariable( + ctx, + b"output_buffer\0".as_ptr() as _, + &mut output_buffer_var, + ); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + let mut raygen = mem::zeroed(); + o.rtProgramCreateFromPTXString( + ctx, + SET_VARIABLE_PTX.as_ptr() as _, + b"start\0".as_ptr() as _, + &mut raygen, + ); + o.rtContextSetRayGenerationProgram(ctx, 0, raygen); + // we are reusing material&program pair to see how ZLUDA handles this + let anyhit_unset = create_anyhit_program(&mut o, ctx); + let material_unset = create_material(&mut o, ctx); + let triangle_instances = (0..triangles) + .map(|triangle| create_triangles(&mut o, ctx, triangle, 1, 0.0).0) + .collect::>(); + setup_geometry_instance( + &mut o, + triangle_instances[0], + material_unset, + anyhit_unset, + ptr::null_mut(), + ); + let anyhit_1 = create_anyhit_program_with_var(&mut o, ctx, variable_key, 1f32); + let material_1 = create_material(&mut o, ctx); + setup_geometry_instance( + &mut o, + triangle_instances[1], + material_1, + anyhit_1, + ptr::null_mut(), + ); + let mut variable_2 = ptr::null_mut(); + o.rtGeometryInstanceDeclareVariable( + triangle_instances[2], + variable_key.as_ptr() as _, + &mut variable_2, + ); + o.rtVariableSet1f(variable_2, 2f32); + setup_geometry_instance( + &mut o, + triangle_instances[2], + material_unset, + anyhit_unset, + ptr::null_mut(), + ); + let anyhit_3 = create_anyhit_program(&mut o, ctx); + let material_3 = create_material_with_var(&mut o, ctx, variable_key, 3f32); + setup_geometry_instance( + &mut o, + triangle_instances[3], + material_3, + anyhit_3, + ptr::null_mut(), + ); + let geo_group = create_geometry_group(&o, ctx, &triangle_instances); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + o.rtContextValidate(ctx); + launch_2d(&mut o, ctx, 0, triangles as u64, 1); + assert_buffer_eq(&mut o, output_buffer, &[4f32, 1f32, 2f32, 3f32][..]); + o.rtContextDestroy(ctx); +} + +unsafe fn create_context(o: &Optix) -> RTcontext { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let disable_cache = 0u32; + o.rtContextSetAttribute( + ctx, + RTcontextattribute::RT_CONTEXT_ATTRIBUTE_DISK_CACHE_ENABLED, + mem::size_of::() as u64, + &disable_cache as *const _ as _, + ); + ctx +} + +unsafe fn create_geometry_group( + o: &Optix, + ctx: *mut RTcontext_api, + triangle_instances: &[*mut RTgeometryinstance_api], +) -> *mut RTgeometrygroup_api { + let mut geo_group = ptr::null_mut(); + o.rtGeometryGroupCreate(ctx, &mut geo_group); + o.rtGeometryGroupSetChildCount(geo_group, triangle_instances.len() as u32); + for (idx, triangle) in triangle_instances.iter().enumerate() { + o.rtGeometryGroupSetChild(geo_group, idx as u32, *triangle); + } + geo_group +} + +unsafe fn create_set_accelerator( + o: &mut Optix, + ctx: *mut RTcontext_api, + geo_group: *mut RTgeometrygroup_api, + name: &[u8], +) { + let mut accel = ptr::null_mut(); + o.rtAccelerationCreate(ctx, &mut accel); + o.rtGeometryGroupSetAcceleration(geo_group, accel); + o.rtAccelerationSetBuilder(accel, b"Bvh\0".as_ptr() as _); + let mut bvh_var = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut bvh_var); + o.rtVariableSetObject(bvh_var, RTobject(geo_group as _)); +} + +unsafe fn create_set_accelerator_group( + o: &mut Optix, + ctx: RTcontext, + group: RTgroup, + name: &[u8], +) { + let mut accel = ptr::null_mut(); + o.rtAccelerationCreate(ctx, &mut accel); + o.rtGroupSetAcceleration(group, accel); + o.rtAccelerationSetBuilder(accel, b"Bvh\0".as_ptr() as _); + let mut bvh_var = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut bvh_var); + o.rtVariableSetObject(bvh_var, RTobject(group as _)); +} + +unsafe fn setup_geometry_instance( + o: &mut Optix, + triangle: RTgeometryinstance, + material: RTmaterial, + any_hit: RTprogram, + closest_hit: RTprogram, +) { + o.rtGeometryInstanceSetMaterialCount(triangle, 1); + o.rtGeometryInstanceSetMaterial(triangle, 0, material); + if any_hit != ptr::null_mut() { + o.rtMaterialSetAnyHitProgram(material, 0, any_hit); + } + if closest_hit != ptr::null_mut() { + o.rtMaterialSetClosestHitProgram(material, 0, closest_hit); + } +} + +unsafe fn create_anyhit_program_with_var( + o: &mut Optix, + ctx: RTcontext, + variable_key: &[u8], + value: f32, +) -> RTprogram { + let program = create_anyhit_program(o, ctx); + let mut program_variable = mem::zeroed(); + o.rtProgramDeclareVariable(program, variable_key.as_ptr() as _, &mut program_variable); + o.rtVariableSet1f(program_variable, value); + program +} + +unsafe fn create_anyhit_program(o: &mut Optix, ctx: RTcontext) -> RTprogram { + let mut anyhit = mem::zeroed(); + o.rtProgramCreateFromPTXString( + ctx, + SET_VARIABLE_PTX.as_ptr() as _, + b"set_variable\0".as_ptr() as _, + &mut anyhit, + ); + anyhit +} + +unsafe fn create_material_with_var( + o: &mut Optix, + ctx: RTcontext, + variable_key: &[u8], + value: f32, +) -> RTmaterial { + let material = create_material(o, ctx); + let mut program_variable = mem::zeroed(); + o.rtMaterialDeclareVariable(material, variable_key.as_ptr() as _, &mut program_variable); + o.rtVariableSet1f(program_variable, value); + material +} + +unsafe fn create_material(o: &mut Optix, ctx: RTcontext) -> RTmaterial { + let mut material_unset = mem::zeroed(); + o.rtMaterialCreate(ctx, &mut material_unset); + material_unset +} + +unsafe fn create_triangles( + o: &mut Optix, + ctx: RTcontext, + starting_triangle: usize, + triangle_count: usize, + depth: f32, +) -> (RTgeometryinstance, RTgeometrytriangles) { + create_triangles_scaled(o, ctx, starting_triangle, triangle_count, depth, 0.1) +} + +unsafe fn create_triangles_scaled( + o: &mut Optix, + ctx: RTcontext, + starting_triangle: usize, + triangle_count: usize, + depth: f32, + scale: f32, +) -> (RTgeometryinstance, RTgeometrytriangles) { + let mut input_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut input_buffer); + o.rtBufferSetFormat(input_buffer, RTformat::RT_FORMAT_FLOAT3); + o.rtBufferSetSize1D(input_buffer, (triangle_count * 3) as u64); + { + let mut host_ptr = ptr::null_mut(); + o.rtBufferMap(input_buffer, &mut host_ptr); + let ptr = host_ptr as *mut [(f32, f32, f32); 3]; + for i in 0..triangle_count { + let point = (starting_triangle + i) as f32; + let coords = [ + (point - scale, -scale, depth), + (point + scale, -scale, depth), + (point, scale, depth), + ]; + *ptr.add(i) = coords; + } + o.rtBufferUnmap(input_buffer); + } + let mut index_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut index_buffer); + o.rtBufferSetFormat(index_buffer, RTformat::RT_FORMAT_UNSIGNED_INT3); + o.rtBufferSetSize1D(index_buffer, triangle_count as u64); + { + let mut host_ptr = ptr::null_mut(); + o.rtBufferMap(index_buffer, &mut host_ptr); + let host_ptr = host_ptr as *mut u32; + let indices = (0..(triangle_count * 3) as u32).collect::>(); + ptr::copy_nonoverlapping(indices.as_ptr(), host_ptr, indices.len()); + o.rtBufferUnmap(index_buffer); + } + let mut geometry_triangles = ptr::null_mut(); + o.rtGeometryTrianglesCreate(ctx, &mut geometry_triangles); + o.rtGeometryTrianglesSetPrimitiveCount(geometry_triangles, triangle_count as u32); + o.rtGeometryTrianglesSetVertices( + geometry_triangles, + 3 * triangle_count as u32, + input_buffer, + 0, + 12, + RTformat::RT_FORMAT_FLOAT3, + ); + o.rtGeometryTrianglesSetTriangleIndices( + geometry_triangles, + index_buffer, + 0, + 12, + RTformat::RT_FORMAT_UNSIGNED_INT3, + ); + let mut geometry_instance = ptr::null_mut(); + o.rtGeometryTrianglesValidate(geometry_triangles); + o.rtGeometryInstanceCreate(ctx, &mut geometry_instance); + o.rtGeometryInstanceSetGeometryTriangles(geometry_instance, geometry_triangles); + (geometry_instance, geometry_triangles) +} + +pub const ANY_HIT_INTERSECT_PTX: &'static str = + concat!(include_str!("any_hit_intersect.ptx"), "\0"); + +optix_test!(fail_on_multi_material_triangles); +unsafe fn fail_on_multi_material_triangles(mut o: Optix) { + let variable_key = b"b_index\0"; + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let material_0 = create_material_with_var_u32(&mut o, ctx, variable_key, 0); + let material_1 = create_material_with_var_u32(&mut o, ctx, variable_key, 1); + let triangle = create_triangles(&mut o, ctx, 0, 1, 0.0).0; + o.rtGeometryInstanceSetMaterialCount(triangle, 2); + o.rtGeometryInstanceSetMaterial(triangle, 0, material_0); + o.rtGeometryInstanceSetMaterial(triangle, 1, material_1); + // Triangles instance: if it has multiple materials, those materials must be partitioned into + // triangles with rtGeometryTrianglesSetMaterialIndices + assert_eq!( + RTresult::RT_ERROR_INVALID_CONTEXT, + o.rtGeometryInstanceValidate_unchecked(triangle) + ); + o.rtContextDestroy(ctx); +} + +unsafe fn launch_2d( + o: &Optix, + ctx: *mut RTcontext_api, + entry_point: u32, + width: u64, + height: u64, +) { + let error = o.rtContextLaunch2D_unchecked(ctx, entry_point, width, height); + if error != RTresult::RT_SUCCESS { + let mut err_string = ptr::null(); + o.rtContextGetErrorString(ctx, error, &mut err_string); + panic!( + "{:?} {}", + error, + CStr::from_ptr(err_string).to_str().unwrap() + ); + } +} + +unsafe fn assert_buffer_eq( + o: &Optix, + output_buffer: *mut RTbuffer_api, + buff: &[T], +) { + let mut host_ptr = ptr::null_mut(); + let mut result = vec![T::default(); buff.len()]; + o.rtBufferMap(output_buffer, &mut host_ptr); + ptr::copy_nonoverlapping::(host_ptr as *const T, result.as_mut_ptr(), buff.len()); + o.rtBufferUnmap(output_buffer); + assert_eq!(&*result, buff); +} + +unsafe fn assert_buffer_eq_float( + o: &Optix, + epsilon: f32, + output_buffer: *mut RTbuffer_api, + buff: &[f32], +) { + let mut host_ptr = ptr::null_mut(); + let mut result = vec![0f32; buff.len()]; + o.rtBufferMap(output_buffer, &mut host_ptr); + ptr::copy_nonoverlapping::(host_ptr as *const f32, result.as_mut_ptr(), buff.len()); + o.rtBufferUnmap(output_buffer); + assert_approx_eq!(&[f32], buff, &*result, epsilon = epsilon); +} + +unsafe fn create_material_with_var_u32( + o: &mut Optix, + ctx: RTcontext, + variable_key: &[u8], + value: u32, +) -> RTmaterial { + let material = create_material(o, ctx); + let mut program_variable = mem::zeroed(); + o.rtMaterialDeclareVariable(material, variable_key.as_ptr() as _, &mut program_variable); + o.rtVariableSet1ui(program_variable, value); + material +} + +optix_test!(any_hit_multiple_materials); +unsafe fn any_hit_multiple_materials(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 2); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + let output_buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 2); + let output_buffer2 = create_buffer_u32(&mut o, ctx, "output_buffer2", 2); + let raygen = create_program(&mut o, ctx, ANY_HIT_INTERSECT_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, raygen); + let any_hit = create_program(&mut o, ctx, ANY_HIT_INTERSECT_PTX, "set_buffer\0"); + let closest_hit = create_program(&mut o, ctx, ANY_HIT_INTERSECT_PTX, "set_buffer2\0"); + let material_0 = create_material_with_var_u32(&mut o, ctx, b"b_index\0", 0); + let material_1 = create_material_with_var_u32(&mut o, ctx, b"b_index\0", 1); + let bb_prog = create_program(&mut o, ctx, ANY_HIT_INTERSECT_PTX, "bounds\0"); + let intersect_prog = create_program(&mut o, ctx, ANY_HIT_INTERSECT_PTX, "intersect\0"); + let sphere = create_custom_geometry(&mut o, ctx, 1, bb_prog, intersect_prog); + o.rtGeometryInstanceSetMaterialCount(sphere, 2); + o.rtGeometryInstanceSetMaterial(sphere, 0, material_0); + o.rtGeometryInstanceSetMaterial(sphere, 1, material_1); + o.rtMaterialSetAnyHitProgram(material_0, 0, any_hit); + o.rtMaterialSetAnyHitProgram(material_1, 0, any_hit); + o.rtMaterialSetClosestHitProgram(material_0, 0, closest_hit); + o.rtMaterialSetClosestHitProgram(material_1, 0, closest_hit); + let geo_group = create_geometry_group(&o, ctx, &[sphere]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 2, 1); + assert_buffer_eq(&mut o, output_buffer, &[1u32, 1][..]); + assert_buffer_eq(&mut o, output_buffer2, &[1u32, 1][..]); + o.rtContextDestroy(ctx); +} + +unsafe fn create_custom_geometry( + o: &mut Optix, + ctx: RTcontext, + primitives: u32, + bb_program: RTprogram, + intersect_program: RTprogram, +) -> RTgeometryinstance { + let mut geometry = ptr::null_mut(); + o.rtGeometryCreate(ctx, &mut geometry); + o.rtGeometrySetPrimitiveCount(geometry, primitives); + o.rtGeometrySetBoundingBoxProgram(geometry, bb_program); + o.rtGeometrySetIntersectionProgram(geometry, intersect_program); + let mut geometry_instance = ptr::null_mut(); + o.rtGeometryInstanceCreate(ctx, &mut geometry_instance); + o.rtGeometryInstanceSetGeometry(geometry_instance, geometry); + geometry_instance +} + +unsafe fn create_program( + o: &mut Optix, + ctx: RTcontext, + text: &str, + name: &str, +) -> RTprogram { + let mut program = mem::zeroed(); + o.rtProgramCreateFromPTXString(ctx, text.as_ptr() as _, name.as_ptr() as _, &mut program); + program +} + +unsafe fn create_buffer_u32( + o: &mut Optix, + ctx: *mut RTcontext_api, + name: &str, + len: usize, +) -> RTbuffer { + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize1D(output_buffer, len as u64); + o.rtBufferSetFormat(output_buffer, RTformat::RT_FORMAT_UNSIGNED_INT); + let mut host_ptr = ptr::null_mut(); + o.rtBufferMap(output_buffer, &mut host_ptr); + ptr::write_bytes(host_ptr as *mut u32, 0, len); + o.rtBufferUnmap(output_buffer); + let mut output_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut output_buffer_var); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + output_buffer +} + +unsafe fn create_buffer_u32_with_values( + o: &mut Optix, + ctx: *mut RTcontext_api, + name: &str, + values: &[u32], +) -> RTbuffer { + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize1D(output_buffer, values.len() as u64); + o.rtBufferSetFormat(output_buffer, RTformat::RT_FORMAT_USER); + o.rtBufferSetElementSize(output_buffer, 4); + let mut host_ptr: *mut std::ffi::c_void = ptr::null_mut(); + o.rtBufferMap(output_buffer, &mut host_ptr); + ptr::copy_nonoverlapping(values.as_ptr(), host_ptr.cast::(), values.len()); + o.rtBufferUnmap(output_buffer); + let mut output_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut output_buffer_var); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + output_buffer +} + +const CALLABLE_PROGRAMS_PTX: &'static str = concat!(include_str!("callable_programs.ptx"), "\0"); + +optix_test!(callable_programs); +unsafe fn callable_programs(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, CALLABLE_PROGRAMS_PTX, "start\0"); + let add_value = create_program(&mut o, ctx, CALLABLE_PROGRAMS_PTX, "add_value\0"); + let multiply_value = create_program(&mut o, ctx, CALLABLE_PROGRAMS_PTX, "multiply_value\0"); + let variable_name = b"value\0"; + context_set_u32(&mut o, ctx, variable_name, 1); + program_set_u32(&mut o, add_value, variable_name, 2); + program_set_u32(&mut o, multiply_value, variable_name, 2); + let add_fn_id = program_get_id(&mut o, add_value); + let multiply_fn_id = program_get_id(&mut o, multiply_value); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + context_set_u32(&mut o, ctx, b"add_fn\0", add_fn_id as u32); + context_set_u32(&mut o, ctx, b"mult_fn\0", multiply_fn_id as u32); + let output_buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, output_buffer, &[6u32]); + o.rtContextDestroy(ctx); +} + +unsafe fn program_get_id(o: &mut Optix, program: *mut RTprogram_api) -> i32 { + let mut prog_id = 0; + o.rtProgramGetId(program, &mut prog_id); + prog_id +} + +unsafe fn context_set_u32( + o: &mut Optix, + ctx: RTcontext, + variable_name: &[u8], + value: u32, +) -> RTvariable { + let mut variable = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, variable_name.as_ptr() as _, &mut variable); + o.rtVariableSet1ui(variable, value); + variable +} + +unsafe fn program_set_u32( + o: &mut Optix, + program: RTprogram, + variable_name: &[u8], + value: u32, +) -> RTvariable { + let mut variable = ptr::null_mut(); + o.rtProgramDeclareVariable(program, variable_name.as_ptr() as _, &mut variable); + o.rtVariableSet1ui(variable, value); + variable +} + +const TEXTURE_SAMPLER_PTX: &'static str = concat!(include_str!("texture_sampler.ptx"), "\0"); + +optix_test!(texture_sampler); +unsafe fn texture_sampler(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, TEXTURE_SAMPLER_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let image1 = create_image( + &mut o, + ctx, + &[ + (0.0, 0.25, 0.5, 0.75), + (1.0, 1.25, 1.5, 1.75), + (2.0, 2.25, 2.5, 2.75), + (3.0, 3.25, 3.5, 3.75), + ], + 2, + ); + let image2 = create_image( + &mut o, + ctx, + &[ + (4.0, 4.25, 4.5, 4.75), + (5.0, 5.25, 5.5, 5.75), + (6.0, 6.25, 6.5, 6.75), + (7.0, 7.25, 7.5, 7.75), + ], + 2, + ); + let output_buffer = create_buffer_2d( + &mut o, + ctx, + RTformat::RT_FORMAT_FLOAT4, + "output_buffer", + (2, 4), + ); + context_set_object(&mut o, ctx, b"image1\0", image1); + let mut image2_id = 0; + o.rtTextureSamplerGetId(image2, &mut image2_id); + context_set_u32(&mut o, ctx, b"image2\0", image2_id as u32); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq::<(f32, f32, f32, f32), _>( + &o, + output_buffer, + &[ + (0.0, 0.25, 0.5, 0.75), + (1.0, 1.25, 1.5, 1.75), + (2.0, 2.25, 2.5, 2.75), + (3.0, 3.25, 3.5, 3.75), + (4.0, 4.25, 4.5, 4.75), + (5.0, 5.25, 5.5, 5.75), + (6.0, 6.25, 6.5, 6.75), + (7.0, 7.25, 7.5, 7.75), + ], + ); + o.rtContextDestroy(ctx); +} + +unsafe fn context_set_object( + o: &mut Optix, + ctx: *mut RTcontext_api, + variable_name: &[u8], + value: *mut T, +) -> RTvariable { + let mut variable = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, variable_name.as_ptr() as _, &mut variable); + o.rtVariableSetObject(variable, RTobject(value as _)); + variable +} + +unsafe fn create_image( + o: &mut Optix, + ctx: *mut RTcontext_api, + content: &[(f32, f32, f32, f32)], + width: u32, +) -> RTtexturesampler { + let mut image = ptr::null_mut(); + o.rtTextureSamplerCreate(ctx, &mut image); + let mut buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut buffer); + o.rtBufferSetSize2D(buffer, width as u64, (content.len() as u32 / width) as u64); + o.rtBufferSetFormat(buffer, RTformat::RT_FORMAT_FLOAT4); + let mut buffer_pointer = ptr::null_mut(); + o.rtBufferMap(buffer, &mut buffer_pointer); + ptr::copy_nonoverlapping( + content.as_ptr(), + buffer_pointer as *mut (f32, f32, f32, f32), + content.len(), + ); + o.rtBufferUnmap(buffer); + o.rtTextureSamplerSetWrapMode(image, 0, RTwrapmode::RT_WRAP_REPEAT); + o.rtTextureSamplerSetWrapMode(image, 1, RTwrapmode::RT_WRAP_REPEAT); + o.rtTextureSamplerSetFilteringModes( + image, + RTfiltermode::RT_FILTER_NEAREST, + RTfiltermode::RT_FILTER_NEAREST, + RTfiltermode::RT_FILTER_NONE, + ); + o.rtTextureSamplerSetIndexingMode(image, RTtextureindexmode::RT_TEXTURE_INDEX_ARRAY_INDEX); + o.rtTextureSamplerSetReadMode(image, RTtexturereadmode::RT_TEXTURE_READ_NORMALIZED_FLOAT); + o.rtTextureSamplerSetMaxAnisotropy(image, 1.0f32); + o.rtTextureSamplerSetBuffer(image, 0, 0, buffer); + image +} + +unsafe fn create_buffer_1d( + o: &mut Optix, + ctx: *mut RTcontext_api, + format: RTformat, + name: &str, + width: u64, +) -> RTbuffer { + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize1D(output_buffer, width); + o.rtBufferSetFormat(output_buffer, format); + let mut output_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut output_buffer_var); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + output_buffer +} + +unsafe fn create_buffer_2d( + o: &mut Optix, + ctx: *mut RTcontext_api, + format: RTformat, + name: &str, + (width, height): (u64, u64), +) -> RTbuffer { + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize2D(output_buffer, width, height); + o.rtBufferSetFormat(output_buffer, format); + let mut output_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut output_buffer_var); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + output_buffer +} + +const BARYCENTRICS_PTX: &'static str = concat!(include_str!("barycentrics.ptx"), "\0"); + +optix_test!(barycentrics); +unsafe fn barycentrics(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, BARYCENTRICS_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let attribute_program = create_program(&mut o, ctx, BARYCENTRICS_PTX, "attribute_program\0"); + let closest_hit = create_program(&mut o, ctx, BARYCENTRICS_PTX, "closest_hit\0"); + let bounds = create_program(&mut o, ctx, BARYCENTRICS_PTX, "bounds\0"); + let intersect = create_program(&mut o, ctx, BARYCENTRICS_PTX, "intersect\0"); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + let output_buffer1 = + create_buffer(&mut o, ctx, RTformat::RT_FORMAT_FLOAT2, "output_buffer1", 4); + create_buffer(&mut o, ctx, RTformat::RT_FORMAT_FLOAT2, "output_buffer2", 4); + let output_buffer3 = create_buffer( + &mut o, + ctx, + RTformat::RT_FORMAT_UNSIGNED_INT, + "output_buffer3", + 4, + ); + let sphere = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let (triangles_instance, triangles) = create_triangles(&mut o, ctx, 0, 2, 0.0); + let (triangles_instance2, _) = create_triangles(&mut o, ctx, 2, 1, 0.0); + o.rtGeometryTrianglesSetAttributeProgram(triangles, attribute_program); + let material = create_material(&mut o, ctx); + setup_geometry_instance( + &mut o, + triangles_instance, + material, + ptr::null_mut(), + closest_hit, + ); + setup_geometry_instance( + &mut o, + triangles_instance2, + material, + ptr::null_mut(), + closest_hit, + ); + setup_geometry_instance(&mut o, sphere, material, ptr::null_mut(), closest_hit); + let mut group = ptr::null_mut(); + let triangles_group = + create_geometry_group(&o, ctx, &[triangles_instance, triangles_instance2]); + create_set_accelerator(&mut o, ctx, triangles_group, b"unused1\0"); + let sphere_group = create_geometry_group(&o, ctx, &[sphere]); + create_set_accelerator(&mut o, ctx, sphere_group, b"unused2\0"); + o.rtGroupCreate(ctx, &mut group); + o.rtGroupSetChildCount(group, 2); + o.rtGroupSetChild(group, 0, RTobject(triangles_group as _)); + o.rtGroupSetChild(group, 1, RTobject(sphere_group as _)); + create_set_accelerator_group(&mut o, ctx, group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 4, 1); + assert_buffer_eq_float( + &o, + 0.000001, + output_buffer1, + &[ + 0.25f32, 0.1f32, 0.25f32, 0.1f32, 0.25f32, 0.5f32, 100f32, 200f32, + ], + ); + /* + assert_buffer_eq_float( + &o, + 0.000001, + output_buffer2, + &[ + 0.25f32, 0.5f32, 0.25f32, 0.5f32, 0.25f32, 0.5f32, 100f32, 200f32, + ], + ); + */ + assert_buffer_eq(&o, output_buffer3, &[0u32, 1u32, 0u32, 0u32]); +} + +unsafe fn create_buffer( + o: &mut Optix, + ctx: *mut RTcontext_api, + format: RTformat, + name: &str, + len: usize, +) -> RTbuffer { + let mut output_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_OUTPUT.0, &mut output_buffer); + o.rtBufferSetSize1D(output_buffer, len as u64); + o.rtBufferSetFormat(output_buffer, format); + let mut output_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut output_buffer_var); + o.rtVariableSetObject(output_buffer_var, RTobject(output_buffer as _)); + output_buffer +} + +const TRACE_CONTROL_PTX: &'static str = concat!(include_str!("trace_control.ptx"), "\0"); + +optix_test!(ignore_intersection); +unsafe fn ignore_intersection(o: Optix) { + trace_control(o, "any_hit_ignore\0", 1) +} + +optix_test!(terminate_ray); +unsafe fn terminate_ray(o: Optix) { + trace_control(o, "any_hit_terminate\0", 2) +} + +unsafe fn trace_control(mut o: Optix, any_hit: &str, result: u32) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + let start = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let bounds = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "bounds\0"); + let intersect = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "intersect\0"); + let any_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, any_hit); + let closest_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "closest_hit\0"); + let output_buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 1); + create_buffer_u32(&mut o, ctx, "temp_buffer", 1); + let sphere1 = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let sphere2 = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let sphere3 = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let sphere4 = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let material = create_material(&mut o, ctx); + setup_geometry_instance(&mut o, sphere1, material, any_hit, closest_hit); + setup_geometry_instance(&mut o, sphere2, material, any_hit, closest_hit); + setup_geometry_instance(&mut o, sphere3, material, any_hit, closest_hit); + setup_geometry_instance(&mut o, sphere4, material, any_hit, closest_hit); + let geo_group = create_geometry_group(&o, ctx, &[sphere1, sphere2, sphere3, sphere4]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, output_buffer, &[result]); +} + +optix_test!(attribute_program_runs_before_closest_hit); +unsafe fn attribute_program_runs_before_closest_hit(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let attribute_program = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "attribute1\0"); + let any_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "any_hit_plus_one\0"); + let closest_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "closest_hit\0"); + let output_buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 1); + let temp_buffer = create_buffer_u32(&mut o, ctx, "temp_buffer", 1); + let material = create_material(&mut o, ctx); + let (triangle1_instance, triangle1) = create_triangles(&mut o, ctx, 0, 1, -0.1f32); + o.rtGeometryTrianglesSetAttributeProgram(triangle1, attribute_program); + setup_geometry_instance(&mut o, triangle1_instance, material, any_hit, closest_hit); + let geo_group = create_geometry_group(&o, ctx, &[triangle1_instance]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, output_buffer, &[0xc4bb2187u32 + 1]); + assert_buffer_eq(&o, temp_buffer, &[1]); +} + +optix_test!(rollback_attributes_on_ignore); +unsafe fn rollback_attributes_on_ignore(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let attribute_program = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "attribute2\0"); + let any_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "any_hit_always_ignore\0"); + let closest_hit = create_program(&mut o, ctx, TRACE_CONTROL_PTX, "closest_hit\0"); + let output_buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 1); + let temp_buffer = create_buffer_u32(&mut o, ctx, "temp_buffer", 1); + let material = create_material(&mut o, ctx); + let (triangle1_instance, triangle1) = create_triangles(&mut o, ctx, 0, 1, -0.1f32); + o.rtGeometryTrianglesSetAttributeProgram(triangle1, attribute_program); + setup_geometry_instance(&mut o, triangle1_instance, material, any_hit, closest_hit); + let geo_group = create_geometry_group(&o, ctx, &[triangle1_instance]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_neq(&o, output_buffer, 0xc4bb2187u32); + assert_buffer_eq(&o, temp_buffer, &[1]); +} + +unsafe fn assert_buffer_neq( + o: &Optix, + output_buffer: *mut RTbuffer_api, + value: T, +) { + let mut host_ptr = ptr::null_mut(); + let mut result = vec![T::default(); 1]; + o.rtBufferMap(output_buffer, &mut host_ptr); + ptr::copy_nonoverlapping::(host_ptr as *const T, result.as_mut_ptr(), 1); + o.rtBufferUnmap(output_buffer); + assert_ne!(value, result[0]); +} + +const BUFFER_ID_PTX: &'static str = concat!(include_str!("buffer_id.ptx"), "\0"); +const BUFFER_ID_CALL_PTX: &'static str = concat!(include_str!("buffer_id_call.ptx"), "\0"); + +optix_test!(buffer_id); +optix_test!(buffer_id_call); + +unsafe fn buffer_id(o: Optix) { + buffer_id_impl(o, BUFFER_ID_PTX) +} +unsafe fn buffer_id_call(o: Optix) { + buffer_id_impl(o, BUFFER_ID_CALL_PTX) +} + +unsafe fn buffer_id_impl(mut o: Optix, text: &str) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, text, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 3); + create_buffer_of_buffers(&mut o, ctx, "buffers", &[buffer][..]); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[0, 3, 0x0118378c]); +} + +unsafe fn create_buffer_of_buffers( + o: &mut Optix, + ctx: RTcontext, + name: &str, + buffer: &[RTbuffer], +) { + let sub_buffers = buffer + .iter() + .copied() + .map(|buffer| { + let mut buffer_id = 0; + unsafe { o.rtBufferGetId(buffer, &mut buffer_id) }; + buffer_id + }) + .collect::>(); + let mut main_buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut main_buffer); + o.rtBufferSetSize1D(main_buffer, sub_buffers.len() as u64); + o.rtBufferSetFormat(main_buffer, RTformat::RT_FORMAT_BUFFER_ID); + { + let mut host_ptr = ptr::null_mut(); + o.rtBufferMap(main_buffer, &mut host_ptr); + ptr::copy_nonoverlapping(sub_buffers.as_ptr(), host_ptr as _, sub_buffers.len()); + o.rtBufferUnmap(main_buffer); + } + let mut main_buffer_var = ptr::null_mut(); + let mut name = name.to_string(); + name.push('\0'); + o.rtContextDeclareVariable(ctx, name.as_ptr() as _, &mut main_buffer_var); + o.rtVariableSetObject(main_buffer_var, RTobject(main_buffer as _)); +} + +const BUFFER_ID_CALLABLE_PTX: &'static str = concat!(include_str!("buffer_id_callable.ptx"), "\0"); + +optix_test!(buffer_id_callable); + +unsafe fn buffer_id_callable(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, BUFFER_ID_CALLABLE_PTX, "start\0"); + let callable = create_program(&mut o, ctx, BUFFER_ID_CALLABLE_PTX, "callable\0"); + let callable_id = program_get_id(&mut o, callable); + context_set_u32(&mut o, ctx, b"program\0", callable_id as u32); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let buffer = create_buffer_u32(&mut o, ctx, "output_buffer", 3); + create_buffer_of_buffers(&mut o, ctx, "buffers", &[buffer][..]); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[0, 3, 0x0118378c]); +} + +const TRIANGLE_FRONT_PTX: &'static str = concat!(include_str!("triangle_front.ptx"), "\0"); + +optix_test!(triangle_front); +unsafe fn triangle_front(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, TRIANGLE_FRONT_PTX, "start\0"); + let bounds = create_program(&mut o, ctx, TRIANGLE_FRONT_PTX, "bounds\0"); + let intersect = create_program(&mut o, ctx, TRIANGLE_FRONT_PTX, "intersect\0"); + let closest_hit = create_program(&mut o, ctx, TRIANGLE_FRONT_PTX, "closest_hit\0"); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let output_buffer1 = create_buffer_u32(&mut o, ctx, "output_buffer1", 3); + let output_buffer2 = create_buffer_u32(&mut o, ctx, "output_buffer2", 3); + let output_buffer3 = create_buffer_u32(&mut o, ctx, "output_buffer3", 3); + let sphere = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let (triangles_instance1, _) = create_triangles(&mut o, ctx, 0, 1, 0.0); + let (triangles_instance2, _) = create_triangles(&mut o, ctx, 1, 1, 0.0); + let material = create_material(&mut o, ctx); + setup_geometry_instance(&mut o, sphere, material, ptr::null_mut(), closest_hit); + setup_geometry_instance( + &mut o, + triangles_instance1, + material, + ptr::null_mut(), + closest_hit, + ); + setup_geometry_instance( + &mut o, + triangles_instance2, + material, + ptr::null_mut(), + closest_hit, + ); + let mut group = ptr::null_mut(); + let triangles_group = + create_geometry_group(&o, ctx, &[triangles_instance1, triangles_instance2]); + create_set_accelerator(&mut o, ctx, triangles_group, b"unused1\0"); + let sphere_group = create_geometry_group(&o, ctx, &[sphere]); + create_set_accelerator(&mut o, ctx, sphere_group, b"unused2\0"); + o.rtGroupCreate(ctx, &mut group); + o.rtGroupSetChildCount(group, 2); + o.rtGroupSetChild(group, 0, RTobject(triangles_group as _)); + o.rtGroupSetChild(group, 1, RTobject(sphere_group as _)); + create_set_accelerator_group(&mut o, ctx, group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 3, 1); + assert_buffer_eq(&o, output_buffer1, &[2, 2, 1]); + assert_buffer_eq(&o, output_buffer2, &[2, 1, 1]); + assert_buffer_eq(&o, output_buffer3, &[1, 2, 1]); +} + +const TRANSFORM_PTX: &'static str = concat!(include_str!("transform.ptx"), "\0"); + +optix_test!(ray_transform); +unsafe fn ray_transform(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, TRANSFORM_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let bounds = create_program(&mut o, ctx, TRANSFORM_PTX, "bounds\0"); + let intersect = create_program(&mut o, ctx, TRANSFORM_PTX, "intersect\0"); + let attribute = create_program(&mut o, ctx, TRANSFORM_PTX, "attribute\0"); + let any_hit = create_program(&mut o, ctx, TRANSFORM_PTX, "any_hit\0"); + let closest_hit = create_program(&mut o, ctx, TRANSFORM_PTX, "closest_hit\0"); + let is_triangle = create_buffer_u32(&mut o, ctx, "is_triangle", 2); + let origin0 = create_buffer_1d(&mut o, ctx, RTformat::RT_FORMAT_FLOAT3, "origin0", 3); + let origin1 = create_buffer_1d(&mut o, ctx, RTformat::RT_FORMAT_FLOAT3, "origin1", 3); + create_buffer_of_buffers(&mut o, ctx, "origin", &[origin0, origin1]); + let direction0 = create_buffer_1d(&mut o, ctx, RTformat::RT_FORMAT_FLOAT3, "direction0", 3); + let direction1 = create_buffer_1d(&mut o, ctx, RTformat::RT_FORMAT_FLOAT3, "direction1", 3); + create_buffer_of_buffers(&mut o, ctx, "direction", &[direction0, direction1]); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + let sphere = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let (triangles, triangles_primitive) = create_triangles_scaled(&mut o, ctx, 1, 1, 0.0, 100.0); + o.rtGeometryTrianglesSetAttributeProgram(triangles_primitive, attribute); + let material = create_material(&mut o, ctx); + setup_geometry_instance(&mut o, sphere, material, any_hit, closest_hit); + setup_geometry_instance(&mut o, triangles, material, any_hit, closest_hit); + let sphere_group = create_geometry_group(&o, ctx, &[sphere]); + let triangles_group = create_geometry_group(&o, ctx, &[triangles]); + create_set_accelerator(&mut o, ctx, sphere_group, b"unused1\0"); + create_set_accelerator(&mut o, ctx, triangles_group, b"unused2\0"); + let transform1 = create_test_transform(&mut o, ctx); + let transform2 = create_test_transform(&mut o, ctx); + o.rtTransformSetChild(transform1, RTobject(sphere_group as _)); + o.rtTransformSetChild(transform2, RTobject(triangles_group as _)); + let mut group = ptr::null_mut(); + o.rtGroupCreate(ctx, &mut group); + o.rtGroupSetChildCount(group, 2); + o.rtGroupSetChild(group, 0, RTobject(transform1 as _)); + o.rtGroupSetChild(group, 1, RTobject(transform2 as _)); + create_set_accelerator_group(&mut o, ctx, group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 2, 1); + assert_buffer_eq(&o, is_triangle, &[1, 0]); + assert_buffer_eq_float( + &mut o, + 0.000001f32, + origin0, + &[ + 0.0, 0.0, -1.0, -0.3333333, -0.7440169, -0.3035612, 0.0, 0.0, -1.0, + ], + ); + assert_buffer_eq_float( + &mut o, + 0.000001f32, + origin1, + &[0.0, -0.86602545, 0.0, 0.0, -0.86602545, 0.0, 1.0, 0.0, -1.0], + ); + assert_buffer_eq_float( + &mut o, + 0.000001f32, + direction0, + &[ + 0.0, + 0.0, + 1.0, + -0.24401696, + 0.4553418, + 0.11111113, + 0.0, + 0.0, + 1.0, + ], + ); + assert_buffer_eq_float( + &mut o, + 0.000001f32, + direction1, + &[ + -0.24401696, + 0.4553418, + 0.11111113, + -0.24401696, + 0.4553418, + 0.11111113, + 0.0, + 0.0, + 1.0, + ], + ); +} + +unsafe fn create_test_transform(o: &mut Optix, ctx: RTcontext) -> RTtransform { + let mut transform = ptr::null_mut(); + o.rtTransformCreate(ctx, &mut transform); + let matrix = Mat4::from_scale_rotation_translation( + Vec3::from_array([1f32, 2f32, 3f32]), + Quat::from_axis_angle( + Vec3::from_array([1., 1., 1.]).normalize(), + (std::f64::consts::PI / 2f64) as f32, + ), + Vec3::from_array([1., 1., 1.]).normalize(), + ); + o.rtTransformSetMatrix( + transform, + 1, + matrix.to_cols_array().as_ptr(), + ptr::null_mut(), + ); + transform +} + +const GET_TRANSFORM_PTX: &'static str = concat!(include_str!("get_transform.ptx"), "\0"); + +optix_test!(get_transform); +unsafe fn get_transform(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, GET_TRANSFORM_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let bounds = create_program(&mut o, ctx, GET_TRANSFORM_PTX, "bounds\0"); + let intersect = create_program(&mut o, ctx, GET_TRANSFORM_PTX, "intersect\0"); + let any_hit = create_program(&mut o, ctx, GET_TRANSFORM_PTX, "any_hit\0"); + let closest_hit = create_program(&mut o, ctx, GET_TRANSFORM_PTX, "closest_hit\0"); + let object_transforms = create_buffer_1d( + &mut o, + ctx, + RTformat::RT_FORMAT_FLOAT, + "object_transforms", + 16 * 3, + ); + let mut sphere = ptr::null_mut(); + o.rtContextDeclareVariable(ctx, b"sphere\0".as_ptr() as _, &mut sphere); + o.rtVariableSet4f(sphere, 0.0, 0.0, 0.0, 100.0); + let sphere = create_custom_geometry(&mut o, ctx, 1, bounds, intersect); + let material = create_material(&mut o, ctx); + setup_geometry_instance(&mut o, sphere, material, any_hit, closest_hit); + let sphere_group = create_geometry_group(&o, ctx, &[sphere]); + create_set_accelerator(&mut o, ctx, sphere_group, b"unused1\0"); + let transform1 = create_test_transform(&mut o, ctx); + o.rtTransformSetChild(transform1, RTobject(sphere_group as _)); + let mut group = ptr::null_mut(); + o.rtGroupCreate(ctx, &mut group); + o.rtGroupSetChildCount(group, 1); + o.rtGroupSetChild(group, 0, RTobject(transform1 as _)); + create_set_accelerator_group(&mut o, ctx, group, b"bvh\0"); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq_float( + &mut o, + 0.000001f32, + object_transforms, + &[ + 0.33333337, + -0.4880339, + 2.7320507, + 0.57735026, + 0.9106836, + 0.66666675, + -0.73205084, + 0.57735026, + -0.24401695, + 1.8213671, + 1.0000001, + 0.57735026, + 0.0, + 0.0, + 0.0, + 1.0, + 0.33333337, + -0.4880339, + 2.7320507, + 0.57735026, + 0.9106836, + 0.66666675, + -0.73205084, + 0.57735026, + -0.24401695, + 1.8213671, + 1.0000001, + 0.57735026, + 0.0, + 0.0, + 0.0, + 1.0, + 0.33333337, + 0.9106836, + -0.24401696, + -0.57735026, + -0.12200849, + 0.16666669, + 0.4553418, + -0.28867513, + 0.3035612, + -0.08133899, + 0.11111113, + -0.19245009, + 0.0, + 0.0, + 0.0, + 1.0, + ], + ); +} + +const DEFAULT_VARIABLE_PTX: &'static str = concat!(include_str!("default_variable.ptx"), "\0"); + +optix_test!(default_variable); + +unsafe fn default_variable(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, DEFAULT_VARIABLE_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[55]); +} + +const EXCEPTION_PTX: &'static str = concat!(include_str!("exception.ptx"), "\0"); + +optix_test!(exception_raygen); + +unsafe fn exception_raygen(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +optix_test!(exception_miss); + +unsafe fn exception_miss(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let trace = create_program(&mut o, ctx, EXCEPTION_PTX, "trace\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + let throw_ = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, trace); + o.rtContextSetExceptionProgram(ctx, 0, exception); + o.rtContextSetMissProgram(ctx, 0, throw_); + let material = create_material(&mut o, ctx); + let (triangle, _) = create_triangles(&mut o, ctx, 999, 1, 0.0); + setup_geometry_instance(&mut o, triangle, material, ptr::null_mut(), ptr::null_mut()); + let geo_group = create_geometry_group(&o, ctx, &[triangle]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +optix_test!(exception_closest_hit); + +unsafe fn exception_closest_hit(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let trace = create_program(&mut o, ctx, EXCEPTION_PTX, "trace\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + let throw_ = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, trace); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let material = create_material(&mut o, ctx); + let (triangle, _) = create_triangles(&mut o, ctx, 0, 1, 0.0); + setup_geometry_instance(&mut o, triangle, material, ptr::null_mut(), throw_); + let geo_group = create_geometry_group(&o, ctx, &[triangle]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +optix_test!(exception_any_hit); + +unsafe fn exception_any_hit(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let trace = create_program(&mut o, ctx, EXCEPTION_PTX, "trace\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + let throw_ = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, trace); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let material = create_material(&mut o, ctx); + let (triangle, _) = create_triangles(&mut o, ctx, 0, 1, 0.0); + setup_geometry_instance(&mut o, triangle, material, throw_, ptr::null_mut()); + let geo_group = create_geometry_group(&o, ctx, &[triangle]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +optix_test!(exception_attribute); + +unsafe fn exception_attribute(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let trace = create_program(&mut o, ctx, EXCEPTION_PTX, "trace\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + let throw_ = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, trace); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let material = create_material(&mut o, ctx); + let (triangle_instance, triangle) = create_triangles(&mut o, ctx, 0, 1, 0.0); + o.rtGeometryTrianglesSetAttributeProgram(triangle, throw_); + setup_geometry_instance( + &mut o, + triangle_instance, + material, + ptr::null_mut(), + ptr::null_mut(), + ); + let geo_group = create_geometry_group(&o, ctx, &[triangle_instance]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +optix_test!(exception_callable); + +unsafe fn exception_callable(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let call_callable1 = create_program(&mut o, ctx, EXCEPTION_PTX, "call_callable1\0"); + let call_callable2 = create_program(&mut o, ctx, EXCEPTION_PTX, "call_callable2\0"); + let throw_callable = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_callable\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, call_callable1); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let call_callable2_id = program_get_id(&mut o, call_callable2); + let throw_callable_id = program_get_id(&mut o, throw_callable); + context_set_u32(&mut o, ctx, b"callable1\0", call_callable2_id as u32); + context_set_u32(&mut o, ctx, b"callable2\0", throw_callable_id as u32); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1025]); +} + +optix_test!(exception_callable_subfunc); + +unsafe fn exception_callable_subfunc(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let call_callable1 = create_program(&mut o, ctx, EXCEPTION_PTX, "call_callable1\0"); + let call_callable2 = create_program(&mut o, ctx, EXCEPTION_PTX, "call_callable2\0"); + let throw_callable = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_callable\0"); + let throw_callable_main = create_program(&mut o, ctx, EXCEPTION_PTX, "throw_callable_main\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_PTX, "exception\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, call_callable1); + o.rtContextSetExceptionProgram(ctx, 0, exception); + let call_callable2_id = program_get_id(&mut o, call_callable2); + let throw_callable_main_id = program_get_id(&mut o, throw_callable_main); + let throw_callable_id = program_get_id(&mut o, throw_callable); + context_set_u32(&mut o, ctx, b"callable1\0", call_callable2_id as u32); + context_set_u32(&mut o, ctx, b"callable2\0", throw_callable_main_id as u32); + context_set_u32(&mut o, ctx, b"callable3\0", throw_callable_id as u32); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1025]); +} + +const EXCEPTION_SUBFUNC_PTX: &'static str = concat!(include_str!("exception_subfunc.ptx"), "\0"); + +optix_test!(exception_subfunc); + +unsafe fn exception_subfunc(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, optix_types::RTexception::RT_EXCEPTION_ALL, 1); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let trace = create_program(&mut o, ctx, EXCEPTION_SUBFUNC_PTX, "start\0"); + let exception = create_program(&mut o, ctx, EXCEPTION_SUBFUNC_PTX, "exception\0"); + let throw_ = create_program(&mut o, ctx, EXCEPTION_SUBFUNC_PTX, "throw_\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, trace); + o.rtContextSetExceptionProgram(ctx, 0, exception); + o.rtContextSetMissProgram(ctx, 0, throw_); + let material = create_material(&mut o, ctx); + let (triangle, _) = create_triangles(&mut o, ctx, 999, 1, 0.0); + setup_geometry_instance(&mut o, triangle, material, ptr::null_mut(), ptr::null_mut()); + let geo_group = create_geometry_group(&o, ctx, &[triangle]); + create_set_accelerator(&mut o, ctx, geo_group, b"bvh\0"); + let buffer = create_buffer_u32(&mut o, ctx, "var_buffer", 1); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, buffer, &[1024]); +} + +const BUFFER_MIPMAP_PTX: &'static str = concat!(include_str!("buffer_mipmap.ptx"), "\0"); + +// Broken for now because HIP does not support image arrays +optix_test!(buffer_mipmap); + +unsafe fn buffer_mipmap(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let mut buffer = ptr::null_mut(); + o.rtBufferCreate(ctx, RTbuffertype::RT_BUFFER_INPUT.0, &mut buffer); + o.rtBufferSetSize2D(buffer, 3, 3); + o.rtBufferSetFormat(buffer, RTformat::RT_FORMAT_UNSIGNED_INT2); + o.rtBufferSetMipLevelCount(buffer, 2); + let mut width = 0; + let mut height = 0; + o.rtBufferGetMipLevelSize2D(buffer, 0, &mut width, &mut height); + assert_eq!((width, height), (3, 3)); + o.rtBufferGetMipLevelSize2D(buffer, 1, &mut width, &mut height); + assert_eq!((width, height), (1, 1)); + o.rtBufferGetMipLevelSize2D(buffer, 2, &mut width, &mut height); + assert_eq!((width, height), (1, 1)); + { + let mut host_buffer = ptr::null_mut(); + o.rtBufferMapEx( + buffer, + RTbuffermapflag::RT_BUFFER_MAP_READ_WRITE.0, + 0, + ptr::null_mut(), + &mut host_buffer, + ); + for i in 0..3 * 3 * 2 { + *(host_buffer.cast::().add(i)) = (i as u32) + 1; + } + o.rtBufferUnmapEx(buffer, 0); + } + { + let mut host_buffer = ptr::null_mut(); + o.rtBufferMapEx( + buffer, + RTbuffermapflag::RT_BUFFER_MAP_READ_WRITE.0, + 1, + ptr::null_mut(), + &mut host_buffer, + ); + *host_buffer.cast::<(u32, u32)>() = (100, 101); + o.rtBufferUnmapEx(buffer, 1); + } + let mut image = ptr::null_mut(); + o.rtTextureSamplerCreate(ctx, &mut image); + o.rtTextureSamplerSetBuffer(image, 0, 0, buffer); + o.rtTextureSamplerSetFilteringModes( + image, + RTfiltermode::RT_FILTER_NEAREST, + RTfiltermode::RT_FILTER_NEAREST, + RTfiltermode::RT_FILTER_NEAREST, + ); + o.rtTextureSamplerSetIndexingMode(image, RTtextureindexmode::RT_TEXTURE_INDEX_ARRAY_INDEX); + o.rtTextureSamplerSetReadMode(image, RTtexturereadmode::RT_TEXTURE_READ_ELEMENT_TYPE); + let start = create_program(&mut o, ctx, BUFFER_MIPMAP_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + let mut texture_id = mem::zeroed(); + o.rtTextureSamplerGetId(image, &mut texture_id); + context_set_u32(&mut o, ctx, b"texture_id\0", texture_id as u32); + let output_buffer = create_buffer_1d( + &mut o, + ctx, + RTformat::RT_FORMAT_UNSIGNED_INT2, + "output_buffer", + 3, + ); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, output_buffer, &[1, 2, 100, 101]); +} + +const OOB_PTX: &'static str = concat!(include_str!("oob.ptx"), "\0"); + +optix_test!(oob); + +unsafe fn oob(mut o: Optix) { + let ctx = create_context(&o); + o.rtContextSetExceptionEnabled(ctx, RTexception::RT_EXCEPTION_ALL, 0); + o.rtContextSetEntryPointCount(ctx, 1); + o.rtContextSetRayTypeCount(ctx, 1); + let start = create_program(&mut o, ctx, OOB_PTX, "start\0"); + o.rtContextSetRayGenerationProgram(ctx, 0, start); + create_buffer_u32_with_values(&mut o, ctx, "index_", &[4, 2]); + create_buffer_u32_with_values(&mut o, ctx, "input", &[10,11,12,13]); + let output = create_buffer_u32_with_values(&mut o, ctx, "output", &[u32::MAX, u32::MAX, u32::MAX]); + launch_2d(&mut o, ctx, 0, 1, 1); + assert_buffer_eq(&o, output, &[0, 12, 0]); +} diff --git a/zluda_rt/src/tests/oob.cu b/zluda_rt/src/tests/oob.cu new file mode 100644 index 0000000..cee8c65 --- /dev/null +++ b/zluda_rt/src/tests/oob.cu @@ -0,0 +1,16 @@ +// nvcc oob.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer index_; +rtBuffer input; +rtBuffer output; + +RT_PROGRAM void start() { + output[0] = input[index_[0]]; + output[1] = input[index_[1]]; + output[2] = *((unsigned int *)rt_buffer_get_id(0, 1, 4, 10,10,0,0)); +} diff --git a/zluda_rt/src/tests/oob.ptx b/zluda_rt/src/tests/oob.ptx new file mode 100644 index 0000000..be307ce --- /dev/null +++ b/zluda_rt/src/tests/oob.ptx @@ -0,0 +1,98 @@ +// +// 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 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 index_[1]; +.visible .global .align 1 .b8 input[1]; +.visible .global .align 1 .b8 output[1]; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; + +.visible .entry _Z5startv( + +) +{ + .reg .b32 %r<21>; + .reg .b64 %rd<51>; + + + mov.u64 %rd48, index_; + cvta.global.u64 %rd2, %rd48; + mov.u32 %r16, 1; + mov.u32 %r17, 4; + mov.u64 %rd47, 0; + // inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r16, %r17, %rd47, %rd47, %rd47, %rd47); + // inline asm + ld.u32 %rd9, [%rd1]; + mov.u64 %rd49, input; + cvta.global.u64 %rd8, %rd49; + // inline asm + call (%rd7), _rt_buffer_get_64, (%rd8, %r16, %r17, %rd9, %rd47, %rd47, %rd47); + // inline asm + ld.u32 %r18, [%rd7]; + mov.u64 %rd50, output; + cvta.global.u64 %rd14, %rd50; + // inline asm + call (%rd13), _rt_buffer_get_64, (%rd14, %r16, %r17, %rd47, %rd47, %rd47, %rd47); + // inline asm + st.u32 [%rd13], %r18; + mov.u64 %rd33, 1; + // inline asm + call (%rd19), _rt_buffer_get_64, (%rd2, %r16, %r17, %rd33, %rd47, %rd47, %rd47); + // inline asm + ld.u32 %rd27, [%rd19]; + // inline asm + call (%rd25), _rt_buffer_get_64, (%rd8, %r16, %r17, %rd27, %rd47, %rd47, %rd47); + // inline asm + ld.u32 %r19, [%rd25]; + // inline asm + call (%rd31), _rt_buffer_get_64, (%rd14, %r16, %r17, %rd33, %rd47, %rd47, %rd47); + // inline asm + st.u32 [%rd31], %r19; + mov.u32 %r13, 0; + mov.u64 %rd39, 10; + // inline asm + call (%rd37), _rt_buffer_get_id_64, (%r13, %r16, %r17, %rd39, %rd39, %rd47, %rd47); + // inline asm + ld.u32 %r20, [%rd37]; + mov.u64 %rd44, 2; + // inline asm + call (%rd42), _rt_buffer_get_64, (%rd14, %r16, %r17, %rd44, %rd47, %rd47, %rd47); + // inline asm + st.u32 [%rd42], %r20; + ret; +} + + diff --git a/zluda_rt/src/tests/texture_sampler.cu b/zluda_rt/src/tests/texture_sampler.cu new file mode 100644 index 0000000..a9ceae1 --- /dev/null +++ b/zluda_rt/src/tests/texture_sampler.cu @@ -0,0 +1,21 @@ +// nvcc texture_sampler.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer output_buffer; +rtTextureSampler image1; +rtDeclareVariable(unsigned int, image2, , ); + +RT_PROGRAM void start() { + output_buffer[make_uint2(0,0)] = tex2D(image1, 0, 0); + output_buffer[make_uint2(1,0)] = tex2D(image1, 1, 0); + output_buffer[make_uint2(0,1)] = tex2D(image1, 0, 1); + output_buffer[make_uint2(1,1)] = tex2D(image1, 1, 1); + output_buffer[make_uint2(0,2)] = rtTex2D(image2, 0, 0); + output_buffer[make_uint2(1,2)] = rtTex2D(image2, 1, 0); + output_buffer[make_uint2(0,3)] = rtTex2D(image2, 0, 1); + output_buffer[make_uint2(1,3)] = rtTex2D(image2, 1, 1); +} diff --git a/zluda_rt/src/tests/texture_sampler.ptx b/zluda_rt/src/tests/texture_sampler.ptx new file mode 100644 index 0000000..6d2d022 --- /dev/null +++ b/zluda_rt/src/tests/texture_sampler.ptx @@ -0,0 +1,119 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 output_buffer[1]; +.visible .global .texref image1; +.visible .global .align 4 .u32 image2; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6image2E[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6image2E[13] = {117, 110, 115, 105, 103, 110, 101, 100, 32, 105, 110, 116, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6image2E = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6image2E[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6image2E[1]; + +.visible .entry _Z5startv() +{ + .reg .f32 %f<49>; + .reg .b32 %r<25>; + .reg .b64 %rd<51>; + + + mov.u64 %rd49, output_buffer; + cvta.global.u64 %rd2, %rd49; + mov.u32 %r24, 2; + mov.u32 %r22, 16; + mov.u64 %rd48, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd48, %rd48, %rd48, %rd48); + // end inline asm + mov.f32 %f32, 0f00000000; + mov.u64 %rd45, 1; + mov.u64 %rd34, 2; + tex.2d.v4.f32.f32 {%f33, %f34, %f35, %f36}, [image1, {%f32, %f32}]; + mov.u64 %rd46, 3; + st.v4.f32 [%rd1], {%f33, %f34, %f35, %f36}; + // begin inline asm + call (%rd7), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd45, %rd48, %rd48, %rd48); + // end inline asm + mov.f32 %f30, 0f3F800000; + tex.2d.v4.f32.f32 {%f37, %f38, %f39, %f40}, [image1, {%f30, %f32}]; + st.v4.f32 [%rd7], {%f37, %f38, %f39, %f40}; + // begin inline asm + call (%rd13), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd48, %rd45, %rd48, %rd48); + // end inline asm + tex.2d.v4.f32.f32 {%f41, %f42, %f43, %f44}, [image1, {%f32, %f30}]; + st.v4.f32 [%rd13], {%f41, %f42, %f43, %f44}; + // begin inline asm + call (%rd19), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd45, %rd45, %rd48, %rd48); + // end inline asm + tex.2d.v4.f32.f32 {%f45, %f46, %f47, %f48}, [image1, {%f30, %f30}]; + st.v4.f32 [%rd19], {%f45, %f46, %f47, %f48}; + // begin inline asm + call (%rd25), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd48, %rd34, %rd48, %rd48); + // end inline asm + ld.global.u32 %r11, [image2]; + // begin inline asm + call (%f1, %f2, %f3, %f4), _rt_texture_get_f_id, (%r11, %r24, %f32, %f32, %f32, %f32); + // end inline asm + st.v4.f32 [%rd25], {%f1, %f2, %f3, %f4}; + // begin inline asm + call (%rd31), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd45, %rd34, %rd48, %rd48); + // end inline asm + ld.global.u32 %r15, [image2]; + // begin inline asm + call (%f9, %f10, %f11, %f12), _rt_texture_get_f_id, (%r15, %r24, %f30, %f32, %f32, %f32); + // end inline asm + st.v4.f32 [%rd31], {%f9, %f10, %f11, %f12}; + // begin inline asm + call (%rd37), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd48, %rd46, %rd48, %rd48); + // end inline asm + ld.global.u32 %r19, [image2]; + // begin inline asm + call (%f17, %f18, %f19, %f20), _rt_texture_get_f_id, (%r19, %r24, %f32, %f30, %f32, %f32); + // end inline asm + st.v4.f32 [%rd37], {%f17, %f18, %f19, %f20}; + // begin inline asm + call (%rd43), _rt_buffer_get_64, (%rd2, %r24, %r22, %rd45, %rd46, %rd48, %rd48); + // end inline asm + ld.global.u32 %r23, [image2]; + // begin inline asm + call (%f25, %f26, %f27, %f28), _rt_texture_get_f_id, (%r23, %r24, %f30, %f30, %f32, %f32); + // end inline asm + st.v4.f32 [%rd43], {%f25, %f26, %f27, %f28}; + ret; + +} + diff --git a/zluda_rt/src/tests/trace_control.cu b/zluda_rt/src/tests/trace_control.cu new file mode 100644 index 0000000..32e1583 --- /dev/null +++ b/zluda_rt/src/tests/trace_control.cu @@ -0,0 +1,121 @@ +// nvcc trace_control.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtDeclareVariable(float4, sphere, , ); +rtBuffer temp_buffer; +rtBuffer output_buffer; +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); +rtDeclareVariable(float, closest_distance, rtIntersectionDistance, ); +rtDeclareVariable(uint, increment, attribute increment, ); +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); + +RT_PROGRAM void start(void) +{ + Ray ray = make_Ray(make_float3(0, 0, -1), make_float3(0, 0, 1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O) - radius * radius; + float disc = b * b - c; + if (disc > 0.0f) + { + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if (rtPotentialIntersection(((root1 + root11) * l) - temp_buffer[launch_index.x])) + { + increment = temp_buffer[launch_index.x]; + if (rtReportIntersection(0)) + check_second = false; + } + if (check_second) + { + float root2 = (-b + sdisc); + if (rtPotentialIntersection((root2 * l) - temp_buffer[launch_index.x])) + { + increment = temp_buffer[launch_index.x]; + rtReportIntersection(0); + } + } + } +} + +RT_PROGRAM void bounds(int, float result[6]) +{ + const float3 cen = make_float3(sphere); + const float3 rad = make_float3(sphere.w); + + optix::Aabb *aabb = (optix::Aabb *)result; + + if (rad.x > 0.0f && !isinf(rad.x)) + { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } + else + { + aabb->invalidate(); + } +} + +RT_PROGRAM void any_hit_ignore(void) +{ + temp_buffer[launch_index.x] += 1; + if (temp_buffer[launch_index.x] >= 3) + { + rtIgnoreIntersection(); + } +} + +RT_PROGRAM void any_hit_terminate(void) +{ + temp_buffer[launch_index.x] += 1; + if (temp_buffer[launch_index.x] >= 3) + { + rtTerminateRay(); + } +} + +RT_PROGRAM void attribute1(void) +{ + increment = 0xc4bb2187 + temp_buffer[0]; +} + +RT_PROGRAM void any_hit_plus_one(void) +{ + temp_buffer[0] += 1; +} + +RT_PROGRAM void attribute2(void) +{ + increment = 0xc4bb2187; +} + +RT_PROGRAM void any_hit_always_ignore(void) +{ + temp_buffer[0] += 1; + rtIgnoreIntersection(); +} + +RT_PROGRAM void closest_hit(void) +{ + output_buffer[launch_index.x] = increment; +} \ No newline at end of file diff --git a/zluda_rt/src/tests/trace_control.ptx b/zluda_rt/src/tests/trace_control.ptx new file mode 100644 index 0000000..7536802 --- /dev/null +++ b/zluda_rt/src/tests/trace_control.ptx @@ -0,0 +1,442 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 16 .b8 sphere[16]; +.visible .global .align 1 .b8 temp_buffer[1]; +.visible .global .align 1 .b8 output_buffer[1]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .f32 closest_distance; +.visible .global .align 4 .u32 increment; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo16closest_distanceE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo9incrementE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename16closest_distanceE[6] = {102, 108, 111, 97, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename9incrementE[5] = {117, 105, 110, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum16closest_distanceE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum9incrementE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic16closest_distanceE[23] = {114, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 105, 111, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic9incrementE[20] = {97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 99, 114, 101, 109, 101, 110, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation16closest_distanceE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation9incrementE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<6>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f7, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<5>; + .reg .f32 %f<47>; + .reg .b32 %r<19>; + .reg .b64 %rd<29>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB1_5; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f41, %f1, %f40; + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd6, 0; + mov.u64 %rd7, temp_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r4, [%rd1]; + cvt.rn.f32.u32 %f42, %r4; + sub.f32 %f37, %f41, %f42; + // begin inline asm + call (%r3), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r3, 0; + @%p2 bra $L__BB1_3; + + ld.global.u32 %rd10, [launch_index]; + // begin inline asm + call (%rd8), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd10, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r9, [%rd8]; + st.global.u32 [increment], %r9; + mov.u32 %r8, 0; + // begin inline asm + call (%r7), _rt_report_intersection, (%r8); + // end inline asm + setp.ne.s32 %p3, %r7, 0; + @%p3 bra $L__BB1_5; + +$L__BB1_3: + sub.f32 %f44, %f4, %f2; + mul.f32 %f45, %f1, %f44; + ld.global.u32 %rd17, [launch_index]; + // begin inline asm + call (%rd15), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd17, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r13, [%rd15]; + cvt.rn.f32.u32 %f46, %r13; + sub.f32 %f43, %f45, %f46; + // begin inline asm + call (%r12), _rt_potential_intersection, (%f43); + // end inline asm + setp.eq.s32 %p4, %r12, 0; + @%p4 bra $L__BB1_5; + + ld.global.u32 %rd24, [launch_index]; + mov.u64 %rd27, 0; + mov.u32 %r14, 1; + mov.u32 %r15, 4; + // begin inline asm + call (%rd22), _rt_buffer_get_64, (%rd2, %r14, %r15, %rd24, %rd27, %rd27, %rd27); + // end inline asm + ld.u32 %r18, [%rd22]; + st.global.u32 [increment], %r18; + mov.u32 %r17, 0; + // begin inline asm + call (%r16), _rt_report_intersection, (%r17); + // end inline asm + +$L__BB1_5: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + // .globl _Z14any_hit_ignorev +.visible .entry _Z14any_hit_ignorev() +{ + .reg .pred %p<2>; + .reg .b32 %r<8>; + .reg .b64 %rd<14>; + + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd12, 0; + mov.u64 %rd13, temp_buffer; + cvta.global.u64 %rd2, %rd13; + mov.u32 %r3, 1; + mov.u32 %r4, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r3, %r4, %rd3, %rd12, %rd12, %rd12); + // end inline asm + ld.u32 %r5, [%rd1]; + add.s32 %r6, %r5, 1; + st.u32 [%rd1], %r6; + ld.global.u32 %rd9, [launch_index]; + // begin inline asm + call (%rd7), _rt_buffer_get_64, (%rd2, %r3, %r4, %rd9, %rd12, %rd12, %rd12); + // end inline asm + ld.u32 %r7, [%rd7]; + setp.lt.u32 %p1, %r7, 3; + @%p1 bra $L__BB3_2; + + // begin inline asm + call _rt_ignore_intersection, (); + // end inline asm + +$L__BB3_2: + ret; + +} + // .globl _Z17any_hit_terminatev +.visible .entry _Z17any_hit_terminatev() +{ + .reg .pred %p<2>; + .reg .b32 %r<8>; + .reg .b64 %rd<14>; + + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd12, 0; + mov.u64 %rd13, temp_buffer; + cvta.global.u64 %rd2, %rd13; + mov.u32 %r3, 1; + mov.u32 %r4, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r3, %r4, %rd3, %rd12, %rd12, %rd12); + // end inline asm + ld.u32 %r5, [%rd1]; + add.s32 %r6, %r5, 1; + st.u32 [%rd1], %r6; + ld.global.u32 %rd9, [launch_index]; + // begin inline asm + call (%rd7), _rt_buffer_get_64, (%rd2, %r3, %r4, %rd9, %rd12, %rd12, %rd12); + // end inline asm + ld.u32 %r7, [%rd7]; + setp.lt.u32 %p1, %r7, 3; + @%p1 bra $L__BB4_2; + + // begin inline asm + call _rt_terminate_ray, (); + // end inline asm + +$L__BB4_2: + ret; + +} + // .globl _Z10attribute1v +.visible .entry _Z10attribute1v() +{ + .reg .b32 %r<5>; + .reg .b64 %rd<8>; + + + mov.u64 %rd7, temp_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd6, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r3, [%rd1]; + add.s32 %r4, %r3, -994369145; + st.global.u32 [increment], %r4; + ret; + +} + // .globl _Z16any_hit_plus_onev +.visible .entry _Z16any_hit_plus_onev() +{ + .reg .b32 %r<5>; + .reg .b64 %rd<8>; + + + mov.u64 %rd7, temp_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd6, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r3, [%rd1]; + add.s32 %r4, %r3, 1; + st.u32 [%rd1], %r4; + ret; + +} + // .globl _Z10attribute2v +.visible .entry _Z10attribute2v() +{ + .reg .b32 %r<2>; + + + mov.u32 %r1, -994369145; + st.global.u32 [increment], %r1; + ret; + +} + // .globl _Z21any_hit_always_ignorev +.visible .entry _Z21any_hit_always_ignorev() +{ + .reg .b32 %r<5>; + .reg .b64 %rd<8>; + + + mov.u64 %rd7, temp_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + mov.u64 %rd6, 0; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd6, %rd6, %rd6, %rd6); + // end inline asm + ld.u32 %r3, [%rd1]; + add.s32 %r4, %r3, 1; + st.u32 [%rd1], %r4; + // begin inline asm + call _rt_ignore_intersection, (); + // end inline asm + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .reg .b32 %r<4>; + .reg .b64 %rd<8>; + + + ld.global.u32 %r3, [increment]; + mov.u64 %rd6, 0; + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd7, output_buffer; + cvta.global.u64 %rd2, %rd7; + mov.u32 %r1, 1; + mov.u32 %r2, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r1, %r2, %rd3, %rd6, %rd6, %rd6); + // end inline asm + st.u32 [%rd1], %r3; + ret; + +} + diff --git a/zluda_rt/src/tests/transform.cu b/zluda_rt/src/tests/transform.cu new file mode 100644 index 0000000..e5a1ce2 --- /dev/null +++ b/zluda_rt/src/tests/transform.cu @@ -0,0 +1,92 @@ +// nvcc transform.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer is_triangle; +rtBuffer> origin; +rtBuffer> direction; +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); +rtDeclareVariable(float4, sphere, , ); + +RT_PROGRAM void start() { + Ray ray = make_Ray(make_float3(float(launch_index.x), 0, -1), make_float3(0,0,1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O)-radius*radius; + float disc = b*b-c; + if(disc > 0.0f){ + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if( rtPotentialIntersection( (root1 + root11) * l ) ) { + if(rtReportIntersection(0)) + { + origin[launch_index.x][0] = ray.origin; + direction[launch_index.x][0] = ray.direction; + check_second = false; + } + } + if(check_second) { + float root2 = (-b + sdisc); + if( rtPotentialIntersection( root2 * l ) ) { + if(rtReportIntersection(0)) + { + origin[launch_index.x][0] = ray.origin; + direction[launch_index.x][0] = ray.direction; + } + } + } + } +} + +RT_PROGRAM void bounds (int, float result[6]) +{ + const float3 cen = make_float3( sphere ); + const float3 rad = make_float3( sphere.w ); + + optix::Aabb* aabb = (optix::Aabb*)result; + + if( rad.x > 0.0f && !isinf(rad.x) ) { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } else { + aabb->invalidate(); + } +} + +// attribute uses the same ray as related *hit function, +// so transformed for anyhit and untransformed for closesthit +RT_PROGRAM void attribute() { + origin[launch_index.x][0] = ray.origin; + direction[launch_index.x][0] = ray.direction; +} + +RT_PROGRAM void any_hit() { + origin[launch_index.x][1] = ray.origin; + direction[launch_index.x][1] = ray.direction; +} + +RT_PROGRAM void closest_hit() { + origin[launch_index.x][2] = ray.origin; + direction[launch_index.x][2] = ray.direction; + is_triangle[launch_index.x] = rtIsTriangleHit(); +} diff --git a/zluda_rt/src/tests/transform.ptx b/zluda_rt/src/tests/transform.ptx new file mode 100644 index 0000000..f04f24d --- /dev/null +++ b/zluda_rt/src/tests/transform.ptx @@ -0,0 +1,462 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 is_triangle[1]; +.visible .global .align 1 .b8 origin[1]; +.visible .global .align 1 .b8 direction[1]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 16 .b8 sphere[16]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[6] = {117, 105, 110, 116, 50, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + cvt.rn.f32.u32 %f1, %r6; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f3, 0fBF800000; + mov.f32 %f6, 0f3F800000; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + mov.u32 %r5, 1; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<6>; + .reg .f32 %f<55>; + .reg .b32 %r<27>; + .reg .b64 %rd<49>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB1_7; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f37, %f1, %f40; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB1_4; + + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.eq.s32 %p3, %r2, 0; + @%p3 bra $L__BB1_4; + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd22, 0; + mov.u64 %rd23, origin; + cvta.global.u64 %rd2, %rd23; + mov.u32 %r12, 1; + mov.u32 %r10, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r12, %r10, %rd3, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r6, [%rd1]; + mov.u32 %r13, 12; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r6, %r12, %r13, %rd22, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f41, [ray]; + ld.global.f32 %f42, [ray+4]; + ld.global.f32 %f43, [ray+8]; + st.f32 [%rd7], %f41; + st.f32 [%rd7+4], %f42; + st.f32 [%rd7+8], %f43; + ld.global.u32 %rd14, [launch_index]; + mov.u64 %rd24, direction; + cvta.global.u64 %rd13, %rd24; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd13, %r12, %r10, %rd14, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r11, [%rd12]; + // begin inline asm + call (%rd18), _rt_buffer_get_id_64, (%r11, %r12, %r13, %rd22, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f44, [ray+12]; + ld.global.f32 %f45, [ray+16]; + ld.global.f32 %f46, [ray+20]; + st.f32 [%rd18], %f44; + st.f32 [%rd18+4], %f45; + st.f32 [%rd18+8], %f46; + bra.uni $L__BB1_7; + +$L__BB1_4: + sub.f32 %f48, %f4, %f2; + mul.f32 %f47, %f1, %f48; + // begin inline asm + call (%r14), _rt_potential_intersection, (%f47); + // end inline asm + setp.eq.s32 %p4, %r14, 0; + @%p4 bra $L__BB1_7; + + mov.u32 %r16, 0; + // begin inline asm + call (%r15), _rt_report_intersection, (%r16); + // end inline asm + setp.eq.s32 %p5, %r15, 0; + @%p5 bra $L__BB1_7; + + ld.global.u32 %rd27, [launch_index]; + mov.u64 %rd46, 0; + mov.u64 %rd47, origin; + cvta.global.u64 %rd26, %rd47; + mov.u32 %r25, 1; + mov.u32 %r23, 4; + // begin inline asm + call (%rd25), _rt_buffer_get_64, (%rd26, %r25, %r23, %rd27, %rd46, %rd46, %rd46); + // end inline asm + ld.u32 %r19, [%rd25]; + mov.u32 %r26, 12; + // begin inline asm + call (%rd31), _rt_buffer_get_id_64, (%r19, %r25, %r26, %rd46, %rd46, %rd46, %rd46); + // end inline asm + ld.global.f32 %f49, [ray]; + ld.global.f32 %f50, [ray+4]; + ld.global.f32 %f51, [ray+8]; + st.f32 [%rd31], %f49; + st.f32 [%rd31+4], %f50; + st.f32 [%rd31+8], %f51; + ld.global.u32 %rd38, [launch_index]; + mov.u64 %rd48, direction; + cvta.global.u64 %rd37, %rd48; + // begin inline asm + call (%rd36), _rt_buffer_get_64, (%rd37, %r25, %r23, %rd38, %rd46, %rd46, %rd46); + // end inline asm + ld.u32 %r24, [%rd36]; + // begin inline asm + call (%rd42), _rt_buffer_get_id_64, (%r24, %r25, %r26, %rd46, %rd46, %rd46, %rd46); + // end inline asm + ld.global.f32 %f52, [ray+12]; + ld.global.f32 %f53, [ray+16]; + ld.global.f32 %f54, [ray+20]; + st.f32 [%rd42], %f52; + st.f32 [%rd42+4], %f53; + st.f32 [%rd42+8], %f54; + +$L__BB1_7: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + // .globl _Z9attributev +.visible .entry _Z9attributev() +{ + .reg .f32 %f<7>; + .reg .b32 %r<11>; + .reg .b64 %rd<25>; + + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd22, 0; + mov.u64 %rd23, origin; + cvta.global.u64 %rd2, %rd23; + mov.u32 %r9, 1; + mov.u32 %r7, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r9, %r7, %rd3, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u32 %r10, 12; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r9, %r10, %rd22, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f1, [ray]; + ld.global.f32 %f2, [ray+4]; + ld.global.f32 %f3, [ray+8]; + st.f32 [%rd7], %f1; + st.f32 [%rd7+4], %f2; + st.f32 [%rd7+8], %f3; + ld.global.u32 %rd14, [launch_index]; + mov.u64 %rd24, direction; + cvta.global.u64 %rd13, %rd24; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd13, %r9, %r7, %rd14, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18), _rt_buffer_get_id_64, (%r8, %r9, %r10, %rd22, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f4, [ray+12]; + ld.global.f32 %f5, [ray+16]; + ld.global.f32 %f6, [ray+20]; + st.f32 [%rd18], %f4; + st.f32 [%rd18+4], %f5; + st.f32 [%rd18+8], %f6; + ret; + +} + // .globl _Z7any_hitv +.visible .entry _Z7any_hitv() +{ + .reg .f32 %f<7>; + .reg .b32 %r<11>; + .reg .b64 %rd<25>; + + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd22, 0; + mov.u64 %rd23, origin; + cvta.global.u64 %rd2, %rd23; + mov.u32 %r9, 1; + mov.u32 %r7, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r9, %r7, %rd3, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u32 %r10, 12; + mov.u64 %rd19, 1; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r9, %r10, %rd19, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f1, [ray]; + ld.global.f32 %f2, [ray+4]; + ld.global.f32 %f3, [ray+8]; + st.f32 [%rd7], %f1; + st.f32 [%rd7+4], %f2; + st.f32 [%rd7+8], %f3; + ld.global.u32 %rd14, [launch_index]; + mov.u64 %rd24, direction; + cvta.global.u64 %rd13, %rd24; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd13, %r9, %r7, %rd14, %rd22, %rd22, %rd22); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18), _rt_buffer_get_id_64, (%r8, %r9, %r10, %rd19, %rd22, %rd22, %rd22); + // end inline asm + ld.global.f32 %f4, [ray+12]; + ld.global.f32 %f5, [ray+16]; + ld.global.f32 %f6, [ray+20]; + st.f32 [%rd18], %f4; + st.f32 [%rd18+4], %f5; + st.f32 [%rd18+8], %f6; + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .reg .pred %p<2>; + .reg .f32 %f<7>; + .reg .b32 %r<15>; + .reg .b64 %rd<32>; + + + ld.global.u32 %rd3, [launch_index]; + mov.u64 %rd28, 0; + mov.u64 %rd29, origin; + cvta.global.u64 %rd2, %rd29; + mov.u32 %r12, 1; + mov.u32 %r13, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r12, %r13, %rd3, %rd28, %rd28, %rd28); + // end inline asm + ld.u32 %r3, [%rd1]; + mov.u32 %r10, 12; + mov.u64 %rd19, 2; + // begin inline asm + call (%rd7), _rt_buffer_get_id_64, (%r3, %r12, %r10, %rd19, %rd28, %rd28, %rd28); + // end inline asm + ld.global.f32 %f1, [ray]; + ld.global.f32 %f2, [ray+4]; + ld.global.f32 %f3, [ray+8]; + st.f32 [%rd7], %f1; + st.f32 [%rd7+4], %f2; + st.f32 [%rd7+8], %f3; + ld.global.u32 %rd14, [launch_index]; + mov.u64 %rd30, direction; + cvta.global.u64 %rd13, %rd30; + // begin inline asm + call (%rd12), _rt_buffer_get_64, (%rd13, %r12, %r13, %rd14, %rd28, %rd28, %rd28); + // end inline asm + ld.u32 %r8, [%rd12]; + // begin inline asm + call (%rd18), _rt_buffer_get_id_64, (%r8, %r12, %r10, %rd19, %rd28, %rd28, %rd28); + // end inline asm + ld.global.f32 %f4, [ray+12]; + ld.global.f32 %f5, [ray+16]; + ld.global.f32 %f6, [ray+20]; + st.f32 [%rd18], %f4; + st.f32 [%rd18+4], %f5; + st.f32 [%rd18+8], %f6; + // begin inline asm + call (%r11), _rt_is_triangle_hit, (); + // end inline asm + setp.ne.s32 %p1, %r11, 0; + selp.u32 %r14, 1, 0, %p1; + ld.global.u32 %rd25, [launch_index]; + mov.u64 %rd31, is_triangle; + cvta.global.u64 %rd24, %rd31; + // begin inline asm + call (%rd23), _rt_buffer_get_64, (%rd24, %r12, %r13, %rd25, %rd28, %rd28, %rd28); + // end inline asm + st.u32 [%rd23], %r14; + ret; + +} + diff --git a/zluda_rt/src/tests/triangle_front.cu b/zluda_rt/src/tests/triangle_front.cu new file mode 100644 index 0000000..c6204a2 --- /dev/null +++ b/zluda_rt/src/tests/triangle_front.cu @@ -0,0 +1,76 @@ +// nvcc triangle_front.cu -I"C:\dev\OptiX SDK 6.5.0\include" -ptx -x cu -dc +#include +#include +#include + +using namespace optix; + +rtBuffer output_buffer1; +rtBuffer output_buffer2; +rtBuffer output_buffer3; +rtDeclareVariable(rtObject, bvh, , ); +rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); +rtDeclareVariable(float4, sphere, , ); +rtDeclareVariable(int2, launch_index, rtLaunchIndex, ); + +RT_PROGRAM void start() { + Ray ray; + if (launch_index.x == 1) + ray = make_Ray(make_float3(launch_index.x, 0, 1), make_float3(0, 0, -1), 0, 0.0, RT_DEFAULT_MAX); + else + ray = make_Ray(make_float3(launch_index.x, 0, -1), make_float3(0, 0, 1), 0, 0.0, RT_DEFAULT_MAX); + char unused = 0; + rtTrace(bvh, ray, unused); +} + +RT_PROGRAM void intersect(int primIdx) +{ + float3 center = make_float3(sphere); + float3 O = ray.origin - center; + float l = 1 / length(ray.direction); + float3 D = ray.direction * l; + float radius = sphere.w; + + float b = dot(O, D); + float c = dot(O, O)-radius*radius; + float disc = b*b-c; + if(disc > 0.0f){ + float sdisc = sqrtf(disc); + float root1 = (-b - sdisc); + + float root11 = 0.0f; + + bool check_second = true; + if( rtPotentialIntersection( (root1 + root11) * l ) ) { + if(rtReportIntersection(0)) + check_second = false; + } + if(check_second) { + float root2 = (-b + sdisc); + if( rtPotentialIntersection( root2 * l ) ) { + rtReportIntersection(0); + } + } + } +} + +RT_PROGRAM void bounds (int, float result[6]) +{ + const float3 cen = make_float3( sphere ); + const float3 rad = make_float3( sphere.w ); + + optix::Aabb* aabb = (optix::Aabb*)result; + + if( rad.x > 0.0f && !isinf(rad.x) ) { + aabb->m_min = cen - rad; + aabb->m_max = cen + rad; + } else { + aabb->invalidate(); + } +} + +RT_PROGRAM void closest_hit() { + output_buffer1[launch_index.x] = rtIsTriangleHit() + 1; + output_buffer2[launch_index.x] = rtIsTriangleHitBackFace() + 1; + output_buffer3[launch_index.x] = rtIsTriangleHitFrontFace() + 1; +} diff --git a/zluda_rt/src/tests/triangle_front.ptx b/zluda_rt/src/tests/triangle_front.ptx new file mode 100644 index 0000000..24089a7 --- /dev/null +++ b/zluda_rt/src/tests/triangle_front.ptx @@ -0,0 +1,280 @@ +// +// Generated by NVIDIA NVVM Compiler +// +// Compiler Build ID: CL-31833905 +// Cuda compilation tools, release 11.8, V11.8.89 +// Based on NVVM 7.0.1 +// + +.version 7.8 +.target sm_52 +.address_size 64 + + // .globl _Z5startv +.visible .global .align 1 .b8 output_buffer1[1]; +.visible .global .align 1 .b8 output_buffer2[1]; +.visible .global .align 1 .b8 output_buffer3[1]; +.visible .global .align 4 .b8 bvh[4]; +.visible .global .align 4 .b8 ray[36]; +.visible .global .align 16 .b8 sphere[16]; +.visible .global .align 8 .b8 launch_index[8]; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3bvhE[8] = {82, 97, 121, 0, 4, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo3rayE[8] = {82, 97, 121, 0, 36, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo6sphereE[8] = {82, 97, 121, 0, 16, 0, 0, 0}; +.visible .global .align 4 .b8 _ZN21rti_internal_typeinfo12launch_indexE[8] = {82, 97, 121, 0, 8, 0, 0, 0}; +.visible .global .align 8 .u64 _ZN21rti_internal_register20reg_bitness_detectorE; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail0E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail1E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail2E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail3E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail4E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail5E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail6E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail7E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail8E; +.visible .global .align 8 .u64 _ZN21rti_internal_register24reg_exception_64_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail0E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail1E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail2E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail3E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail4E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail5E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail6E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail7E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail8E; +.visible .global .align 4 .u32 _ZN21rti_internal_register21reg_exception_detail9E; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_xE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_yE; +.visible .global .align 4 .u32 _ZN21rti_internal_register14reg_rayIndex_zE; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3bvhE[9] = {114, 116, 79, 98, 106, 101, 99, 116, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename3rayE[11] = {111, 112, 116, 105, 120, 58, 58, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename6sphereE[7] = {102, 108, 111, 97, 116, 52, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_typename12launch_indexE[5] = {105, 110, 116, 50, 0}; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3bvhE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum3rayE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum6sphereE = 4919; +.visible .global .align 4 .u32 _ZN21rti_internal_typeenum12launch_indexE = 4919; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3bvhE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic3rayE[13] = {114, 116, 67, 117, 114, 114, 101, 110, 116, 82, 97, 121, 0}; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic6sphereE[1]; +.visible .global .align 1 .b8 _ZN21rti_internal_semantic12launch_indexE[14] = {114, 116, 76, 97, 117, 110, 99, 104, 73, 110, 100, 101, 120, 0}; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3bvhE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation3rayE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation6sphereE[1]; +.visible .global .align 1 .b8 _ZN23rti_internal_annotation12launch_indexE[1]; + +.visible .entry _Z5startv() +{ + .local .align 1 .b8 __local_depot0[1]; + .reg .b64 %SP; + .reg .b64 %SPL; + .reg .pred %p<2>; + .reg .b16 %rs<2>; + .reg .f32 %f<9>; + .reg .b32 %r<7>; + .reg .b64 %rd<3>; + + + mov.u64 %SPL, __local_depot0; + cvta.local.u64 %SP, %SPL; + add.u64 %rd1, %SP, 0; + add.u64 %rd2, %SPL, 0; + ld.global.u32 %r6, [launch_index]; + setp.eq.s32 %p1, %r6, 1; + mov.u32 %r5, 1; + cvt.rn.f32.s32 %f1, %r6; + selp.f32 %f3, 0f3F800000, 0fBF800000, %p1; + selp.f32 %f6, 0fBF800000, 0f3F800000, %p1; + mov.u16 %rs1, 0; + st.local.u8 [%rd2], %rs1; + ld.global.u32 %r1, [bvh]; + mov.f32 %f7, 0f00000000; + mov.f32 %f8, 0f6C4ECB8F; + mov.u32 %r3, 255; + mov.u32 %r4, 0; + // begin inline asm + call _rt_trace_mask_flags_64, (%r1, %f1, %f7, %f3, %f7, %f7, %f6, %r4, %f7, %f8, %r3, %r4, %rd1, %r5); + // end inline asm + ret; + +} + // .globl _Z9intersecti +.visible .entry _Z9intersecti( + .param .u32 _Z9intersecti_param_0 +) +{ + .reg .pred %p<5>; + .reg .f32 %f<43>; + .reg .b32 %r<7>; + + + ld.global.v4.f32 {%f5, %f6, %f7, %f8}, [sphere]; + ld.global.f32 %f13, [ray]; + sub.f32 %f14, %f13, %f5; + ld.global.f32 %f15, [ray+4]; + sub.f32 %f16, %f15, %f6; + ld.global.f32 %f17, [ray+8]; + sub.f32 %f18, %f17, %f7; + ld.global.f32 %f19, [ray+12]; + ld.global.f32 %f20, [ray+16]; + mul.f32 %f21, %f20, %f20; + fma.rn.f32 %f22, %f19, %f19, %f21; + ld.global.f32 %f23, [ray+20]; + fma.rn.f32 %f24, %f23, %f23, %f22; + sqrt.rn.f32 %f25, %f24; + rcp.rn.f32 %f1, %f25; + mul.f32 %f26, %f19, %f1; + mul.f32 %f27, %f1, %f20; + mul.f32 %f28, %f1, %f23; + mul.f32 %f29, %f16, %f27; + fma.rn.f32 %f30, %f14, %f26, %f29; + fma.rn.f32 %f2, %f18, %f28, %f30; + mul.f32 %f31, %f16, %f16; + fma.rn.f32 %f32, %f14, %f14, %f31; + fma.rn.f32 %f33, %f18, %f18, %f32; + mul.f32 %f34, %f8, %f8; + sub.f32 %f35, %f33, %f34; + mul.f32 %f36, %f2, %f2; + sub.f32 %f3, %f36, %f35; + setp.leu.f32 %p1, %f3, 0f00000000; + @%p1 bra $L__BB1_5; + + sqrt.rn.f32 %f4, %f3; + neg.f32 %f38, %f2; + sub.f32 %f39, %f38, %f4; + add.f32 %f40, %f39, 0f00000000; + mul.f32 %f37, %f1, %f40; + // begin inline asm + call (%r1), _rt_potential_intersection, (%f37); + // end inline asm + setp.eq.s32 %p2, %r1, 0; + @%p2 bra $L__BB1_3; + + mov.u32 %r3, 0; + // begin inline asm + call (%r2), _rt_report_intersection, (%r3); + // end inline asm + setp.ne.s32 %p3, %r2, 0; + @%p3 bra $L__BB1_5; + +$L__BB1_3: + sub.f32 %f42, %f4, %f2; + mul.f32 %f41, %f1, %f42; + // begin inline asm + call (%r4), _rt_potential_intersection, (%f41); + // end inline asm + setp.eq.s32 %p4, %r4, 0; + @%p4 bra $L__BB1_5; + + mov.u32 %r6, 0; + // begin inline asm + call (%r5), _rt_report_intersection, (%r6); + // end inline asm + +$L__BB1_5: + ret; + +} + // .globl _Z6boundsiPf +.visible .entry _Z6boundsiPf( + .param .u32 _Z6boundsiPf_param_0, + .param .u64 _Z6boundsiPf_param_1 +) +{ + .reg .pred %p<3>; + .reg .f32 %f<17>; + .reg .b32 %r<3>; + .reg .b64 %rd<3>; + + + ld.param.u64 %rd2, [_Z6boundsiPf_param_1]; + cvta.to.global.u64 %rd1, %rd2; + ld.global.v4.f32 {%f6, %f7, %f8, %f9}, [sphere]; + setp.leu.f32 %p1, %f9, 0f00000000; + @%p1 bra $L__BB2_2; + + abs.f32 %f10, %f9; + setp.neu.f32 %p2, %f10, 0f7F800000; + @%p2 bra $L__BB2_3; + bra.uni $L__BB2_2; + +$L__BB2_3: + sub.f32 %f11, %f6, %f9; + st.global.f32 [%rd1], %f11; + sub.f32 %f12, %f7, %f9; + st.global.f32 [%rd1+4], %f12; + sub.f32 %f13, %f8, %f9; + st.global.f32 [%rd1+8], %f13; + add.f32 %f14, %f6, %f9; + st.global.f32 [%rd1+12], %f14; + add.f32 %f15, %f7, %f9; + st.global.f32 [%rd1+16], %f15; + add.f32 %f16, %f8, %f9; + st.global.f32 [%rd1+20], %f16; + bra.uni $L__BB2_4; + +$L__BB2_2: + mov.u32 %r1, 2096152002; + st.global.u32 [%rd1], %r1; + st.global.u32 [%rd1+4], %r1; + st.global.u32 [%rd1+8], %r1; + mov.u32 %r2, -51331646; + st.global.u32 [%rd1+12], %r2; + st.global.u32 [%rd1+16], %r2; + st.global.u32 [%rd1+20], %r2; + +$L__BB2_4: + ret; + +} + // .globl _Z11closest_hitv +.visible .entry _Z11closest_hitv() +{ + .reg .pred %p<4>; + .reg .b32 %r<13>; + .reg .b64 %rd<22>; + + + // begin inline asm + call (%r1), _rt_is_triangle_hit, (); + // end inline asm + setp.eq.s32 %p1, %r1, 0; + selp.b32 %r10, 1, 2, %p1; + mov.u32 %r8, 1; + ld.global.s32 %rd3, [launch_index]; + mov.u64 %rd18, 0; + mov.u64 %rd19, output_buffer1; + cvta.global.u64 %rd2, %rd19; + mov.u32 %r9, 4; + // begin inline asm + call (%rd1), _rt_buffer_get_64, (%rd2, %r8, %r9, %rd3, %rd18, %rd18, %rd18); + // end inline asm + st.u32 [%rd1], %r10; + // begin inline asm + call (%r4), _rt_is_triangle_hit_back_face, (); + // end inline asm + setp.eq.s32 %p2, %r4, 0; + selp.b32 %r11, 1, 2, %p2; + ld.global.s32 %rd9, [launch_index]; + mov.u64 %rd20, output_buffer2; + cvta.global.u64 %rd8, %rd20; + // begin inline asm + call (%rd7), _rt_buffer_get_64, (%rd8, %r8, %r9, %rd9, %rd18, %rd18, %rd18); + // end inline asm + st.u32 [%rd7], %r11; + // begin inline asm + call (%r7), _rt_is_triangle_hit_front_face, (); + // end inline asm + setp.eq.s32 %p3, %r7, 0; + selp.b32 %r12, 1, 2, %p3; + ld.global.s32 %rd15, [launch_index]; + mov.u64 %rd21, output_buffer3; + cvta.global.u64 %rd14, %rd21; + // begin inline asm + call (%rd13), _rt_buffer_get_64, (%rd14, %r8, %r9, %rd15, %rd18, %rd18, %rd18); + // end inline asm + st.u32 [%rd13], %r12; + ret; + +} + diff --git a/zluda_rt/src/texture_sampler.rs b/zluda_rt/src/texture_sampler.rs new file mode 100644 index 0000000..cf8dfb0 --- /dev/null +++ b/zluda_rt/src/texture_sampler.rs @@ -0,0 +1,411 @@ +use crate::{ + buffer::{Buffer, BufferData}, + context::{self, Context, ContextData}, + hip, null_check, null_unwrap, MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, +}; +use hip_runtime_sys::*; +use optix_types::*; +use std::{ + mem, ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type TextureSampler = *const OptixCell; + +pub(crate) struct TextureSamplerData { + pub(crate) context: Weak>, + pub(crate) index: u32, + pub(crate) hip_object: hipTextureObject_t, + wrap_mode: [hipTextureAddressMode; 3], + normalized_coordinates: bool, + read_mode: hipTextureReadMode, + perform_srgb_conversion: bool, + max_anisotropy: f32, + mip_level_count: u32, + array_size: u32, + minification: RTfiltermode, + magnification: RTfiltermode, + mipmapping: RTfiltermode, + buffer: Option>>, +} + +impl TextureSamplerData { + fn new(weak_context: Weak>, context: &mut ContextData) -> Self { + context.texture_counter += 1; + let index = context.texture_counter; + Self { + context: weak_context, + index, + hip_object: ptr::null_mut(), + wrap_mode: [ + hipTextureAddressMode::hipAddressModeWrap, + hipTextureAddressMode::hipAddressModeWrap, + hipTextureAddressMode::hipAddressModeWrap, + ], + normalized_coordinates: true, + read_mode: hipTextureReadMode::hipReadModeNormalizedFloat, + perform_srgb_conversion: false, + max_anisotropy: 1.0, + mip_level_count: 0, + array_size: 0, + buffer: None, + minification: RTfiltermode::RT_FILTER_LINEAR, + magnification: RTfiltermode::RT_FILTER_LINEAR, + mipmapping: RTfiltermode::RT_FILTER_LINEAR, + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.texture_samplers.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) unsafe fn create_underlying(&mut self) -> Result<(), RTresult> { + let buffer = match self.buffer { + Some(ref buffer) => buffer.upgrade().ok_or(RTresult::RT_ERROR_INVALID_CONTEXT)?, + None => return Err(RTresult::RT_ERROR_INVALID_CONTEXT), + }; + let buffer = buffer.borrow()?; + // TODO: create mipmapped arrays when they work in HIP + // Currently hipMipmappedArrayCreate(...) fails, because it's "unuspported" + // (tested on Linux ROCm 5.4.3 on RX 6800 XT) + let mut hip_texture = ptr::null_mut(); + let mut array = ptr::null_mut(); + let array_desc = HIP_ARRAY3D_DESCRIPTOR { + Width: buffer.metadata.width as usize, + Height: buffer.metadata.height as usize, + Depth: buffer.metadata.depth(), + Format: buffer.metadata.array_format()?, + NumChannels: buffer.metadata.channels()?, + Flags: 0, + }; + hip! { hipArray3DCreate(&mut array, &array_desc), RT_ERROR_UNKNOWN }; + let copy_height = buffer.metadata.height.max(1); + let copy_depth = buffer.metadata.depth().max(1); + let params = hipMemcpy3DParms { + srcArray: ptr::null_mut(), + srcPos: hipPos { x: 0, y: 0, z: 0 }, + srcPtr: hipPitchedPtr { + ptr: buffer.pointer_mip0().0, + pitch: (buffer.metadata.width * buffer.metadata.element_size) as usize, + xsize: buffer.metadata.width as usize, + ysize: copy_height as usize, + }, + dstArray: array, + dstPos: hipPos { x: 0, y: 0, z: 0 }, + dstPtr: mem::zeroed::(), + extent: hipExtent { + width: buffer.metadata.width as usize, + height: copy_height as usize, + depth: copy_depth, + }, + kind: hipMemcpyKind::hipMemcpyDeviceToDevice, + }; + hip! { hipMemcpy3D(¶ms), RT_ERROR_UNKNOWN }; + let resource_desc = hipResourceDesc { + resType: hipResourceType::hipResourceTypeArray, + res: hipResourceDesc__bindgen_ty_1 { + array: hipResourceDesc__bindgen_ty_1__bindgen_ty_1 { array }, + }, + }; + let tex_desc = hipTextureDesc { + addressMode: self.wrap_mode, + filterMode: self.filter_mode(), + readMode: self.read_mode, + sRGB: self.perform_srgb_conversion as i32, + borderColor: [0.0, 0.0, 0.0, 0.0], + normalizedCoords: self.normalized_coordinates as i32, + maxAnisotropy: 0, // other values not supported by HIP + mipmapFilterMode: if self.mipmapping == RTfiltermode::RT_FILTER_LINEAR { + hipTextureFilterMode::hipFilterModeLinear + } else { + hipTextureFilterMode::hipFilterModePoint + }, + mipmapLevelBias: 0.0, // other values not supported by HIP + minMipmapLevelClamp: 0.0, // other values not supported by HIP + maxMipmapLevelClamp: 0.0, // other values not supported by HIP + }; + hip! { hipCreateTextureObject(&mut hip_texture, &resource_desc, &tex_desc, ptr::null()), RT_ERROR_UNKNOWN }; + self.hip_object = hip_texture; + Ok(()) + } + + // TODO: this is as good as it gets under CUDA/HIP + fn filter_mode(&self) -> hipTextureFilterMode { + if self.magnification == RTfiltermode::RT_FILTER_LINEAR + || self.minification == RTfiltermode::RT_FILTER_LINEAR + { + hipTextureFilterMode::hipFilterModeLinear + } else { + hipTextureFilterMode::hipFilterModePoint + } + } +} + +impl OptixObjectData for TextureSamplerData { + const TYPE: TypeTag = TypeTag::TextureSampler; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.texture_samplers.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) unsafe fn create( + context: *const OptixCell, + texturesampler: *mut TextureSampler, +) -> Result<(), RTresult> { + null_check(context)?; + null_check(texturesampler)?; + *texturesampler = TextureSamplerData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_wrap_mode( + texturesampler: TextureSampler, + dimension: u32, + wrap_mode: RTwrapmode, +) -> Result<(), RTresult> { + if dimension > 2 { + return Err(RTresult::RT_ERROR_INVALID_VALUE); + } + let wrap_mode = to_hip_address_mode(wrap_mode)?; + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.wrap_mode[dimension as usize] = wrap_mode; + Ok(()) +} + +fn to_hip_address_mode(wrap_mode: RTwrapmode) -> Result { + Ok(match wrap_mode { + RTwrapmode::RT_WRAP_REPEAT => hipTextureAddressMode::hipAddressModeWrap, + RTwrapmode::RT_WRAP_CLAMP_TO_EDGE => hipTextureAddressMode::hipAddressModeClamp, + RTwrapmode::RT_WRAP_MIRROR => hipTextureAddressMode::hipAddressModeMirror, + RTwrapmode::RT_WRAP_CLAMP_TO_BORDER => hipTextureAddressMode::hipAddressModeBorder, + _ => return Err(RTresult::RT_ERROR_INVALID_VALUE), + }) +} + +pub(crate) unsafe fn set_indexing_mode( + texturesampler: TextureSampler, + index_mode: RTtextureindexmode, +) -> Result<(), RTresult> { + let normalized_coordinates = match index_mode { + RTtextureindexmode::RT_TEXTURE_INDEX_NORMALIZED_COORDINATES => true, + RTtextureindexmode::RT_TEXTURE_INDEX_ARRAY_INDEX => false, + _ => return Err(RTresult::RT_ERROR_INVALID_VALUE), + }; + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.normalized_coordinates = normalized_coordinates; + Ok(()) +} + +pub(crate) unsafe fn set_read_mode( + texturesampler: TextureSampler, + read_mode: RTtexturereadmode, +) -> Result<(), RTresult> { + let (read_mode, perform_srgb_conversion) = to_hip_read_mode(read_mode)?; + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.read_mode = read_mode; + texturesampler.perform_srgb_conversion = perform_srgb_conversion; + Ok(()) +} + +fn to_hip_read_mode(read_mode: RTtexturereadmode) -> Result<(hipTextureReadMode, bool), RTresult> { + Ok(match read_mode { + RTtexturereadmode::RT_TEXTURE_READ_ELEMENT_TYPE => { + (hipTextureReadMode::hipReadModeElementType, false) + } + RTtexturereadmode::RT_TEXTURE_READ_NORMALIZED_FLOAT => { + (hipTextureReadMode::hipReadModeNormalizedFloat, false) + } + RTtexturereadmode::RT_TEXTURE_READ_ELEMENT_TYPE_SRGB => { + (hipTextureReadMode::hipReadModeElementType, true) + } + RTtexturereadmode::RT_TEXTURE_READ_NORMALIZED_FLOAT_SRGB => { + (hipTextureReadMode::hipReadModeNormalizedFloat, true) + } + _ => return Err(RTresult::RT_ERROR_INVALID_VALUE), + }) +} + +pub(crate) unsafe fn set_max_anisotropy( + texturesampler: TextureSampler, + max_anisotropy: f32, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.max_anisotropy = max_anisotropy; + Ok(()) +} + +pub(crate) unsafe fn set_mip_level_count( + texturesampler: TextureSampler, + mip_level_count: u32, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.mip_level_count = mip_level_count; + Ok(()) +} + +pub(crate) unsafe fn set_array_size( + texturesampler: TextureSampler, + array_size: u32, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.array_size = array_size; + Ok(()) +} + +pub(crate) unsafe fn set_buffer( + texturesampler: TextureSampler, + buffer: Buffer, +) -> Result<(), RTresult> { + let buffer = if buffer == ptr::null() { + None + } else { + Some(OptixCell::clone_weak(buffer)) + }; + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.buffer = buffer; + Ok(()) +} + +pub(crate) unsafe fn set_filtering_modes( + texturesampler: TextureSampler, + minification: RTfiltermode, + magnification: RTfiltermode, + mipmapping: RTfiltermode, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let mut texturesampler = texturesampler.borrow_mut()?; + texturesampler.minification = minification; + texturesampler.magnification = magnification; + texturesampler.mipmapping = mipmapping; + Ok(()) +} + +pub(crate) unsafe fn get_id( + texturesampler: TextureSampler, + texture_id: *mut i32, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let texturesampler = texturesampler.borrow()?; + *texture_id = texturesampler.index as i32; + Ok(()) +} + +pub(crate) unsafe fn get_buffer( + texturesampler: *const OptixCell, + _deprecated0: u32, + _deprecated1: u32, + buffer: *mut *const OptixCell, +) -> Result<(), RTresult> { + null_check(buffer)?; + let texturesampler = null_unwrap(texturesampler)?; + let texturesampler = texturesampler.borrow()?; + match texturesampler.buffer { + Some(ref weak_buffer) => { + *buffer = Weak::as_ptr(weak_buffer); + Ok(()) + } + None => { + *buffer = ptr::null_mut(); + Err(RTresult::RT_ERROR_INVALID_VALUE) + } + } +} + +pub(crate) unsafe fn get_context( + texturesampler: TextureSampler, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let texturesampler = null_unwrap(texturesampler)?; + let texturesampler = texturesampler.borrow()?; + *context = texturesampler.context.as_ptr(); + Ok(()) +} + +pub(crate) fn destroy( + _texturesampler: *const OptixCell, +) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::optix_test; + use crate::test_common::OptixFns; + use optix_types::*; + use std::{mem, ptr}; + + optix_test!(default_texture_sampler); + + unsafe fn default_texture_sampler(o: Optix) { + let mut ctx = ptr::null_mut(); + o.rtContextCreate(&mut ctx); + let mut sampler = ptr::null_mut(); + o.rtTextureSamplerCreate(ctx, &mut sampler); + let mut array_size = mem::zeroed(); + o.rtTextureSamplerGetArraySize(sampler, &mut array_size); + let mut buffer = mem::zeroed(); + o.rtTextureSamplerGetBuffer(sampler, 0, 0, &mut buffer); + let mut minification = mem::zeroed(); + let mut magnification = mem::zeroed(); + let mut mipmapping = mem::zeroed(); + o.rtTextureSamplerGetFilteringModes( + sampler, + &mut minification, + &mut magnification, + &mut mipmapping, + ); + let mut index_mode = mem::zeroed(); + o.rtTextureSamplerGetIndexingMode(sampler, &mut index_mode); + let mut max_aniso = mem::zeroed(); + o.rtTextureSamplerGetMaxAnisotropy(sampler, &mut max_aniso); + let mut mip_level = mem::zeroed(); + o.rtTextureSamplerGetMipLevelCount(sampler, &mut mip_level); + let mut read_mode = mem::zeroed(); + o.rtTextureSamplerGetReadMode(sampler, &mut read_mode); + let mut wrapmode0 = mem::zeroed(); + let mut wrapmode1 = mem::zeroed(); + let mut wrapmode2 = mem::zeroed(); + o.rtTextureSamplerGetWrapMode(sampler, 0, &mut wrapmode0); + o.rtTextureSamplerGetWrapMode(sampler, 0, &mut wrapmode1); + o.rtTextureSamplerGetWrapMode(sampler, 0, &mut wrapmode2); + assert_eq!(array_size, 0); + assert_eq!(buffer, ptr::null_mut()); + assert_eq!(minification, RTfiltermode::RT_FILTER_LINEAR); + assert_eq!(magnification, RTfiltermode::RT_FILTER_LINEAR); + assert_eq!(mipmapping, RTfiltermode::RT_FILTER_LINEAR); + assert_eq!( + index_mode, + RTtextureindexmode::RT_TEXTURE_INDEX_NORMALIZED_COORDINATES + ); + assert_eq!(max_aniso, 1.0); + assert_eq!(mip_level, 0); + assert_eq!( + read_mode, + RTtexturereadmode::RT_TEXTURE_READ_NORMALIZED_FLOAT + ); + assert_eq!(wrapmode0, RTwrapmode::RT_WRAP_REPEAT); + assert_eq!(wrapmode1, RTwrapmode::RT_WRAP_REPEAT); + assert_eq!(wrapmode2, RTwrapmode::RT_WRAP_REPEAT); + } +} diff --git a/zluda_rt/src/transform.rs b/zluda_rt/src/transform.rs new file mode 100644 index 0000000..1d5cc79 --- /dev/null +++ b/zluda_rt/src/transform.rs @@ -0,0 +1,196 @@ +use crate::{ + context::{self, Context, ContextData}, + geometry_group::GeometryGroupData, + null_check, null_unwrap, + repr_gpu::{self, TrivialHIPAllocator}, + MaybeWeakRefMut, OptixCell, OptixObjectData, TypeTag, TypedObjectWeak, UntypedObject, +}; + +use glam::{Quat, Vec3}; +use hip_runtime_sys::hipDeviceptr_t; +use hiprt_sys::{hiprtFloat3, hiprtFloat4, hiprtFrame}; +use optix_types::*; +use std::{ + ptr, + rc::{Rc, Weak}, +}; + +pub(crate) type Transform = *const OptixCell; + +pub(crate) struct TransformData { + pub(crate) context: Weak>, + pub(crate) transform: [f32; 16], + pub(crate) inverse_transform: [f32; 16], + pub(crate) scale: Vec3, + pub(crate) rotation: Quat, + pub(crate) translation: Vec3, + pub(crate) child: Option>>, +} + +impl TransformData { + fn new(weak_context: Weak>, _: &mut ContextData) -> Self { + let scale = Vec3::ONE; + let rotation = Quat::IDENTITY; + let translation = Vec3::ZERO; + let matrix = glam::Mat4::from_scale_rotation_translation(scale, rotation, translation); + let transform = matrix.transpose().to_cols_array(); + let inverse_transform = transform.clone(); + Self { + context: weak_context, + child: None, + scale, + rotation, + translation, + transform, + inverse_transform, + } + } + + fn register(this: Rc>, context: &mut ContextData) { + context.transforms.insert(this); + } + + unsafe fn create(context: Context) -> Result { + context::create_subobject(context, Self::new, Self::register) + } + + pub(crate) fn allocate( + &self, + allocator: &mut TrivialHIPAllocator, + ) -> Result { + let host_side = [repr_gpu::OptixTransform { + transform: self.transform, + inverse_transform: self.inverse_transform, + }]; + allocator + .copy_to_device(&host_side) + .map_err(|_| RTresult::RT_ERROR_UNKNOWN) + } + + pub(crate) fn to_hiprt(&self) -> hiprtFrame { + let rotation = Self::quat_to_hiprt(self.rotation); + let scale = Self::vec3_to_hiprt(self.scale); + let translation = Self::vec3_to_hiprt(self.translation); + hiprtFrame { + rotation, + scale, + translation, + time: 0.0, + pad: 0, + } + } + + fn vec3_to_hiprt(v: Vec3) -> hiprtFloat3 { + hiprtFloat3 { + x: v.x, + y: v.y, + z: v.z, + } + } + + fn quat_to_hiprt(q: Quat) -> hiprtFloat4 { + let (axis, angle) = q.to_axis_angle(); + hiprtFloat4 { + x: axis.x, + y: axis.y, + z: axis.z, + w: angle, + } + } +} + +impl OptixObjectData for TransformData { + const TYPE: TypeTag = TypeTag::Transform; + + fn deregister(&mut self, this: &Rc>) -> Result<(), RTresult> { + if let Some(context) = self.context.upgrade() { + let mut context = (*context).borrow_mut()?; + context.transforms.remove(this); + } + Ok(()) + } + + fn context<'a>(&'a mut self) -> crate::MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) unsafe fn create(context: Context, transform: *mut Transform) -> Result<(), RTresult> { + null_check(context)?; + null_check(transform)?; + *transform = TransformData::create(context)?; + Ok(()) +} + +pub(crate) unsafe fn set_matrix( + transform: Transform, + transpose: i32, + matrix: *const f32, + inverse_matrix: *const f32, +) -> Result<(), RTresult> { + null_check(matrix)?; + let transform = null_unwrap(transform)?; + let mut transform = transform.borrow_mut()?; + let mut matrix4 = glam::Mat4::from_cols_array(&*(matrix as *const [f32; 16])); + if transpose == 0 { + matrix4 = matrix4.transpose(); + } + let inverse_matrix = if inverse_matrix != ptr::null_mut() { + if transpose == 0 { + *&*(matrix as *const [f32; 16]) + } else { + let transposed_inverse_matrix4 = + glam::Mat4::from_cols_array(&*(matrix as *const [f32; 16])); + transposed_inverse_matrix4.to_cols_array() + } + } else { + matrix4.inverse().transpose().to_cols_array() + }; + let (scale, rotation, translation) = matrix4.to_scale_rotation_translation(); + transform.transform = matrix4.transpose().to_cols_array(); + transform.inverse_transform = inverse_matrix; + transform.scale = scale; + transform.rotation = rotation; + transform.translation = translation; + Ok(()) +} + +pub(crate) unsafe fn set_child( + transform: Transform, + object: UntypedObject, +) -> Result<(), RTresult> { + let object = TypedObjectWeak::clone_from(object)?; + let transform = null_unwrap(transform)?; + let mut transform = transform.borrow_mut()?; + let geometry_group = match object { + TypedObjectWeak::GeometryGroup(geometry_group) => geometry_group, + _ => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }; + transform.child = Some(geometry_group); + Ok(()) +} + +pub(crate) unsafe fn get_motion_key_count( + transform: Transform, + n: *mut u32, +) -> Result<(), RTresult> { + null_check(transform)?; + null_check(n)?; + *n = 1; + Ok(()) +} + +pub(crate) fn destroy(_transform: Transform) -> Result<(), RTresult> { + // TODO: implement + Ok(()) +} + +pub(crate) unsafe fn get_context( + transform: *const OptixCell, + context: *mut *const OptixCell, +) -> Result<(), RTresult> { + let transform = null_unwrap(transform)?; + let transform = transform.borrow()?; + *context = transform.context.as_ptr(); + Ok(()) +} diff --git a/zluda_rt/src/variable.rs b/zluda_rt/src/variable.rs new file mode 100644 index 0000000..764b8fb --- /dev/null +++ b/zluda_rt/src/variable.rs @@ -0,0 +1,237 @@ +use crate::{ + context::ContextData, null_check, null_unwrap, AlignedBuffer, MaybeWeakRefMut, OptixCell, + OptixObjectData, TypeTag, TypedObjectWeak, UntypedObject, +}; +use optix_types::RTresult; +use std::{ + alloc::Layout, + mem, ptr, + rc::{Rc, Weak}, + slice, +}; + +pub(crate) type Variable = *const OptixCell; + +#[derive(Clone)] +pub(crate) struct VariableData { + pub(crate) context: Weak>, + pub(crate) value: VariableValue, +} + +#[derive(Clone)] +pub(crate) enum VariableValue { + None, + Object(TypedObjectWeak), + Inline { + data: [u8; 4 * mem::size_of::()], + size: u8, + }, + Boxed(AlignedBuffer), +} + +impl VariableValue { + fn with_bytes(&self, f: impl FnOnce(&[u8]) -> T) -> Result { + Ok(match self { + VariableValue::None => return Err(RTresult::RT_ERROR_UNKNOWN), + VariableValue::Object(object) => match object { + TypedObjectWeak::Buffer(buffer) => { + let buffer = buffer.upgrade().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let buffer = buffer.borrow()?; + let device_buffer = buffer.get_device_mip0(); + let byte_slice = unsafe { + slice::from_raw_parts( + &device_buffer as *const _ as *const u8, + mem::size_of_val(&device_buffer), + ) + }; + f(byte_slice) + } + TypedObjectWeak::GeometryGroup(gg) => { + let gg = gg.upgrade().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let gg = gg.borrow()?; + f(&gg.index.to_ne_bytes()) + } + TypedObjectWeak::Group(group) => { + let group = group.upgrade().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let group = group.borrow()?; + f(&group.index.to_ne_bytes()) + } + TypedObjectWeak::TextureSampler(texture) => { + let texture = texture.upgrade().ok_or(RTresult::RT_ERROR_UNKNOWN)?; + let texture = texture.borrow()?; + f(&(texture.hip_object as usize).to_ne_bytes()) + } + TypedObjectWeak::Transform(_) + | TypedObjectWeak::Material(_) + | TypedObjectWeak::Geometry(_) + | TypedObjectWeak::GeometryTriangles(_) + | TypedObjectWeak::GeometryInstance(_) => todo!(), + TypedObjectWeak::Context(_) + | TypedObjectWeak::Variable(_) + | TypedObjectWeak::Program(_) + | TypedObjectWeak::Acceleration(_) => return Err(RTresult::RT_ERROR_NOT_SUPPORTED), + }, + VariableValue::Inline { data, size } => f(&data[..*size as usize]), + VariableValue::Boxed(data) => f(data.as_bytes()), + }) + } +} + +impl VariableData { + pub(crate) fn new( + owner: &mut T, + ) -> Result>, RTresult> { + let context = owner.context(); + let context = match context { + MaybeWeakRefMut::Weak(weak_ctx) => weak_ctx.clone(), + MaybeWeakRefMut::Ref(_) => return Err(RTresult::RT_ERROR_UNKNOWN), + }; + Ok(Rc::new(OptixCell::new(Self { + context, + value: VariableValue::None, + }))) + } + + pub(crate) fn new_with_context( + context: &OptixCell, + ) -> Result>, RTresult> { + let context = unsafe { OptixCell::clone_weak(context as _) }; + Ok(Rc::new(OptixCell::new(Self { + context: context, + value: VariableValue::None, + }))) + } + + pub(crate) fn copy_into_buffer(&self, buffer: &mut [u8]) -> Result<(), RTresult> { + self.value.with_bytes(|byte_buffer_host| { + if buffer.len() != byte_buffer_host.len() { + return Err(RTresult::RT_ERROR_UNKNOWN); + } + buffer.copy_from_slice(byte_buffer_host); + Ok(()) + })? + } +} + +impl OptixObjectData for VariableData { + const TYPE: TypeTag = TypeTag::Variable; + + fn deregister(&mut self, _this: &Rc>) -> Result<(), RTresult> { + // Variables are only ever destroyed implicitly + Err(RTresult::RT_ERROR_UNKNOWN) + } + + fn context<'a>(&'a mut self) -> MaybeWeakRefMut<'a, ContextData> { + MaybeWeakRefMut::Weak(&self.context) + } +} + +pub(crate) unsafe fn set_object(v: Variable, object: UntypedObject) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let object = TypedObjectWeak::clone_from(object)?; + let mut var = var.borrow_mut()?; + var.value = VariableValue::Object(object); + Ok(()) +} + +pub(crate) unsafe fn get_object(v: Variable, result: *mut UntypedObject) -> Result<(), RTresult> { + null_check(result)?; + let var = null_unwrap(v)?; + let var = var.borrow()?; + let object = match var.value { + VariableValue::Object(ref obj) => obj, + _ => return Err(RTresult::RT_ERROR_INVALID_VALUE), + }; + *result = object.as_untyped(); + Ok(()) +} + +pub(crate) unsafe fn set_1f(v: Variable, f1: f32) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value(f1); + Ok(()) +} + +pub(crate) unsafe fn set_1i(v: *const OptixCell, i1: i32) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value(i1); + Ok(()) +} + +pub(crate) unsafe fn set_1ui(v: Variable, u1: u32) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value(u1); + Ok(()) +} + +pub(crate) unsafe fn set_3f(v: Variable, f1: f32, f2: f32, f3: f32) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value([f1, f2, f3]); + Ok(()) +} + +pub(crate) unsafe fn set_3fv(v: Variable, f: *const f32) -> Result<(), RTresult> { + null_check(f)?; + let f = *(f as *const [f32; 3]); + set_3f(v, f[0], f[1], f[2]) +} + +pub(crate) unsafe fn set_4f( + v: Variable, + f1: f32, + f2: f32, + f3: f32, + f4: f32, +) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value([f1, f2, f3, f4]); + Ok(()) +} + +pub(crate) unsafe fn set_4fv(v: Variable, f: *const f32) -> Result<(), RTresult> { + null_check(f)?; + let f = *(f as *const [f32; 4]); + set_4f(v, f[0], f[1], f[2], f[3]) +} + +unsafe fn pack_into_value(t: T) -> VariableValue { + if mem::size_of::() > 4 * mem::size_of::() { + let buffer = AlignedBuffer::new(Layout::new::()); + VariableValue::Boxed(buffer) + } else { + let mut data = [0u8; 4 * mem::size_of::()]; + ptr::copy_nonoverlapping::(&t, data.as_mut_ptr() as _, 1); + let size = mem::size_of::() as u8; + VariableValue::Inline { data, size } + } +} + +pub(crate) unsafe fn set_user_data( + v: Variable, + size: u64, + ptr: *const std::ffi::c_void, +) -> Result<(), RTresult> { + null_check(ptr)?; + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + let buffer = AlignedBuffer::new(Layout::from_size_align_unchecked(size as usize, 1)); + ptr::copy_nonoverlapping( + ptr.cast::(), + buffer.as_ptr().cast::(), + size as usize, + ); + var.value = VariableValue::Boxed(buffer); + Ok(()) +} + +pub(crate) unsafe fn set_1ull(v: Variable, ull1: u64) -> Result<(), RTresult> { + let var = null_unwrap(v)?; + let mut var = var.borrow_mut()?; + var.value = pack_into_value(ull1); + Ok(()) +} diff --git a/zluda_sparse/Cargo.toml b/zluda_sparse/Cargo.toml new file mode 100644 index 0000000..3badf52 --- /dev/null +++ b/zluda_sparse/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "zluda_sparse" +version = "0.0.0" +authors = ["Andrzej Janik "] +edition = "2018" + +[lib] +name = "cusparse" +crate-type = ["cdylib"] + +[dependencies] +rocsparse-sys = { path = "../rocsparse-sys" } +hip_common = { path = "../hip_common" } +hip_runtime-sys = { path = "../hip_runtime-sys" } +zluda_dark_api = { path = "../zluda_dark_api" } +cuda_types = { path = "../cuda_types" } + +[package.metadata.zluda] +linux_only = true +linux_names = ["libcusparse.so.11"] +dump_names = ["libcusparse.so"] diff --git a/zluda_sparse/README b/zluda_sparse/README new file mode 100644 index 0000000..aaa758b --- /dev/null +++ b/zluda_sparse/README @@ -0,0 +1,2 @@ +bindgen /usr/local/cuda-11/targets/x86_64-linux/include/cusparse_v2.h -o src/cusparse11.rs --allowlist-function="^cusparse.*" --default-enum-style=newtype --no-layout-tests --no-derive-debug -- -I/usr/local/cuda-11/targets/x86_64-linux/include +sed -i -e 's/extern "C" {//g' -e 's/-> cusparseStatus_t;/-> cusparseStatus_t { crate::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "system" fn /g' src/cusparse.rs \ No newline at end of file diff --git a/zluda_sparse/src/cusparse.rs b/zluda_sparse/src/cusparse.rs new file mode 100644 index 0000000..a3eee08 --- /dev/null +++ b/zluda_sparse/src/cusparse.rs @@ -0,0 +1,8870 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +#[repr(C)] +#[repr(align(8))] +#[derive(Copy, Clone)] +pub struct float2 { + pub x: f32, + pub y: f32, +} +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub struct double2 { + pub x: f64, + pub y: f64, +} +pub type cuFloatComplex = float2; +pub type cuDoubleComplex = double2; +pub type cuComplex = cuFloatComplex; +impl cudaDataType_t { + pub const CUDA_R_16F: cudaDataType_t = cudaDataType_t(2); +} +impl cudaDataType_t { + pub const CUDA_C_16F: cudaDataType_t = cudaDataType_t(6); +} +impl cudaDataType_t { + pub const CUDA_R_16BF: cudaDataType_t = cudaDataType_t(14); +} +impl cudaDataType_t { + pub const CUDA_C_16BF: cudaDataType_t = cudaDataType_t(15); +} +impl cudaDataType_t { + pub const CUDA_R_32F: cudaDataType_t = cudaDataType_t(0); +} +impl cudaDataType_t { + pub const CUDA_C_32F: cudaDataType_t = cudaDataType_t(4); +} +impl cudaDataType_t { + pub const CUDA_R_64F: cudaDataType_t = cudaDataType_t(1); +} +impl cudaDataType_t { + pub const CUDA_C_64F: cudaDataType_t = cudaDataType_t(5); +} +impl cudaDataType_t { + pub const CUDA_R_4I: cudaDataType_t = cudaDataType_t(16); +} +impl cudaDataType_t { + pub const CUDA_C_4I: cudaDataType_t = cudaDataType_t(17); +} +impl cudaDataType_t { + pub const CUDA_R_4U: cudaDataType_t = cudaDataType_t(18); +} +impl cudaDataType_t { + pub const CUDA_C_4U: cudaDataType_t = cudaDataType_t(19); +} +impl cudaDataType_t { + pub const CUDA_R_8I: cudaDataType_t = cudaDataType_t(3); +} +impl cudaDataType_t { + pub const CUDA_C_8I: cudaDataType_t = cudaDataType_t(7); +} +impl cudaDataType_t { + pub const CUDA_R_8U: cudaDataType_t = cudaDataType_t(8); +} +impl cudaDataType_t { + pub const CUDA_C_8U: cudaDataType_t = cudaDataType_t(9); +} +impl cudaDataType_t { + pub const CUDA_R_16I: cudaDataType_t = cudaDataType_t(20); +} +impl cudaDataType_t { + pub const CUDA_C_16I: cudaDataType_t = cudaDataType_t(21); +} +impl cudaDataType_t { + pub const CUDA_R_16U: cudaDataType_t = cudaDataType_t(22); +} +impl cudaDataType_t { + pub const CUDA_C_16U: cudaDataType_t = cudaDataType_t(23); +} +impl cudaDataType_t { + pub const CUDA_R_32I: cudaDataType_t = cudaDataType_t(10); +} +impl cudaDataType_t { + pub const CUDA_C_32I: cudaDataType_t = cudaDataType_t(11); +} +impl cudaDataType_t { + pub const CUDA_R_32U: cudaDataType_t = cudaDataType_t(12); +} +impl cudaDataType_t { + pub const CUDA_C_32U: cudaDataType_t = cudaDataType_t(13); +} +impl cudaDataType_t { + pub const CUDA_R_64I: cudaDataType_t = cudaDataType_t(24); +} +impl cudaDataType_t { + pub const CUDA_C_64I: cudaDataType_t = cudaDataType_t(25); +} +impl cudaDataType_t { + pub const CUDA_R_64U: cudaDataType_t = cudaDataType_t(26); +} +impl cudaDataType_t { + pub const CUDA_C_64U: cudaDataType_t = cudaDataType_t(27); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E4M3: cudaDataType_t = cudaDataType_t(28); +} +impl cudaDataType_t { + pub const CUDA_R_8F_E5M2: cudaDataType_t = cudaDataType_t(29); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cudaDataType_t(pub ::std::os::raw::c_uint); +pub use self::cudaDataType_t as cudaDataType; +impl libraryPropertyType_t { + pub const MAJOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(0); +} +impl libraryPropertyType_t { + pub const MINOR_VERSION: libraryPropertyType_t = libraryPropertyType_t(1); +} +impl libraryPropertyType_t { + pub const PATCH_LEVEL: libraryPropertyType_t = libraryPropertyType_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct libraryPropertyType_t(pub ::std::os::raw::c_uint); +pub use self::libraryPropertyType_t as libraryPropertyType; +pub type FILE = _IO_FILE; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_marker { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_codecvt { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_wide_data { + _unused: [u8; 0], +} +pub type _IO_lock_t = ::std::os::raw::c_void; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _IO_FILE { + pub _flags: ::std::os::raw::c_int, + pub _IO_read_ptr: *mut ::std::os::raw::c_char, + pub _IO_read_end: *mut ::std::os::raw::c_char, + pub _IO_read_base: *mut ::std::os::raw::c_char, + pub _IO_write_base: *mut ::std::os::raw::c_char, + pub _IO_write_ptr: *mut ::std::os::raw::c_char, + pub _IO_write_end: *mut ::std::os::raw::c_char, + pub _IO_buf_base: *mut ::std::os::raw::c_char, + pub _IO_buf_end: *mut ::std::os::raw::c_char, + pub _IO_save_base: *mut ::std::os::raw::c_char, + pub _IO_backup_base: *mut ::std::os::raw::c_char, + pub _IO_save_end: *mut ::std::os::raw::c_char, + pub _markers: *mut _IO_marker, + pub _chain: *mut _IO_FILE, + pub _fileno: ::std::os::raw::c_int, + pub _flags2: ::std::os::raw::c_int, + pub _old_offset: __off_t, + pub _cur_column: ::std::os::raw::c_ushort, + pub _vtable_offset: ::std::os::raw::c_schar, + pub _shortbuf: [::std::os::raw::c_char; 1usize], + pub _lock: *mut _IO_lock_t, + pub _offset: __off64_t, + pub _codecvt: *mut _IO_codecvt, + pub _wide_data: *mut _IO_wide_data, + pub _freeres_list: *mut _IO_FILE, + pub _freeres_buf: *mut ::std::os::raw::c_void, + pub __pad5: usize, + pub _mode: ::std::os::raw::c_int, + pub _unused2: [::std::os::raw::c_char; 20usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseContext { + _unused: [u8; 0], +} +pub type cusparseHandle_t = *mut cusparseContext; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseMatDescr { + _unused: [u8; 0], +} +pub type cusparseMatDescr_t = *mut cusparseMatDescr; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csrsv2Info { + _unused: [u8; 0], +} +pub type csrsv2Info_t = *mut csrsv2Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csrsm2Info { + _unused: [u8; 0], +} +pub type csrsm2Info_t = *mut csrsm2Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bsrsv2Info { + _unused: [u8; 0], +} +pub type bsrsv2Info_t = *mut bsrsv2Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bsrsm2Info { + _unused: [u8; 0], +} +pub type bsrsm2Info_t = *mut bsrsm2Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csric02Info { + _unused: [u8; 0], +} +pub type csric02Info_t = *mut csric02Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bsric02Info { + _unused: [u8; 0], +} +pub type bsric02Info_t = *mut bsric02Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csrilu02Info { + _unused: [u8; 0], +} +pub type csrilu02Info_t = *mut csrilu02Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bsrilu02Info { + _unused: [u8; 0], +} +pub type bsrilu02Info_t = *mut bsrilu02Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csrgemm2Info { + _unused: [u8; 0], +} +pub type csrgemm2Info_t = *mut csrgemm2Info; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct csru2csrInfo { + _unused: [u8; 0], +} +pub type csru2csrInfo_t = *mut csru2csrInfo; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseColorInfo { + _unused: [u8; 0], +} +pub type cusparseColorInfo_t = *mut cusparseColorInfo; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pruneInfo { + _unused: [u8; 0], +} +pub type pruneInfo_t = *mut pruneInfo; +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_SUCCESS: cusparseStatus_t = cusparseStatus_t(0); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_NOT_INITIALIZED: cusparseStatus_t = cusparseStatus_t(1); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_ALLOC_FAILED: cusparseStatus_t = cusparseStatus_t(2); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_INVALID_VALUE: cusparseStatus_t = cusparseStatus_t(3); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_ARCH_MISMATCH: cusparseStatus_t = cusparseStatus_t(4); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_MAPPING_ERROR: cusparseStatus_t = cusparseStatus_t(5); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_EXECUTION_FAILED: cusparseStatus_t = cusparseStatus_t(6); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_INTERNAL_ERROR: cusparseStatus_t = cusparseStatus_t(7); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED: cusparseStatus_t = cusparseStatus_t(8); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_ZERO_PIVOT: cusparseStatus_t = cusparseStatus_t(9); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_NOT_SUPPORTED: cusparseStatus_t = cusparseStatus_t(10); +} +impl cusparseStatus_t { + pub const CUSPARSE_STATUS_INSUFFICIENT_RESOURCES: cusparseStatus_t = cusparseStatus_t(11); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseStatus_t(pub ::std::os::raw::c_uint); +impl cusparsePointerMode_t { + pub const CUSPARSE_POINTER_MODE_HOST: cusparsePointerMode_t = cusparsePointerMode_t(0); +} +impl cusparsePointerMode_t { + pub const CUSPARSE_POINTER_MODE_DEVICE: cusparsePointerMode_t = cusparsePointerMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparsePointerMode_t(pub ::std::os::raw::c_uint); +impl cusparseAction_t { + pub const CUSPARSE_ACTION_SYMBOLIC: cusparseAction_t = cusparseAction_t(0); +} +impl cusparseAction_t { + pub const CUSPARSE_ACTION_NUMERIC: cusparseAction_t = cusparseAction_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseAction_t(pub ::std::os::raw::c_uint); +impl cusparseMatrixType_t { + pub const CUSPARSE_MATRIX_TYPE_GENERAL: cusparseMatrixType_t = cusparseMatrixType_t(0); +} +impl cusparseMatrixType_t { + pub const CUSPARSE_MATRIX_TYPE_SYMMETRIC: cusparseMatrixType_t = cusparseMatrixType_t(1); +} +impl cusparseMatrixType_t { + pub const CUSPARSE_MATRIX_TYPE_HERMITIAN: cusparseMatrixType_t = cusparseMatrixType_t(2); +} +impl cusparseMatrixType_t { + pub const CUSPARSE_MATRIX_TYPE_TRIANGULAR: cusparseMatrixType_t = cusparseMatrixType_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseMatrixType_t(pub ::std::os::raw::c_uint); +impl cusparseFillMode_t { + pub const CUSPARSE_FILL_MODE_LOWER: cusparseFillMode_t = cusparseFillMode_t(0); +} +impl cusparseFillMode_t { + pub const CUSPARSE_FILL_MODE_UPPER: cusparseFillMode_t = cusparseFillMode_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseFillMode_t(pub ::std::os::raw::c_uint); +impl cusparseDiagType_t { + pub const CUSPARSE_DIAG_TYPE_NON_UNIT: cusparseDiagType_t = cusparseDiagType_t(0); +} +impl cusparseDiagType_t { + pub const CUSPARSE_DIAG_TYPE_UNIT: cusparseDiagType_t = cusparseDiagType_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseDiagType_t(pub ::std::os::raw::c_uint); +impl cusparseIndexBase_t { + pub const CUSPARSE_INDEX_BASE_ZERO: cusparseIndexBase_t = cusparseIndexBase_t(0); +} +impl cusparseIndexBase_t { + pub const CUSPARSE_INDEX_BASE_ONE: cusparseIndexBase_t = cusparseIndexBase_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseIndexBase_t(pub ::std::os::raw::c_uint); +impl cusparseOperation_t { + pub const CUSPARSE_OPERATION_NON_TRANSPOSE: cusparseOperation_t = cusparseOperation_t(0); +} +impl cusparseOperation_t { + pub const CUSPARSE_OPERATION_TRANSPOSE: cusparseOperation_t = cusparseOperation_t(1); +} +impl cusparseOperation_t { + pub const CUSPARSE_OPERATION_CONJUGATE_TRANSPOSE: cusparseOperation_t = cusparseOperation_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseOperation_t(pub ::std::os::raw::c_uint); +impl cusparseDirection_t { + pub const CUSPARSE_DIRECTION_ROW: cusparseDirection_t = cusparseDirection_t(0); +} +impl cusparseDirection_t { + pub const CUSPARSE_DIRECTION_COLUMN: cusparseDirection_t = cusparseDirection_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseDirection_t(pub ::std::os::raw::c_uint); +impl cusparseSolvePolicy_t { + pub const CUSPARSE_SOLVE_POLICY_NO_LEVEL: cusparseSolvePolicy_t = cusparseSolvePolicy_t(0); +} +impl cusparseSolvePolicy_t { + pub const CUSPARSE_SOLVE_POLICY_USE_LEVEL: cusparseSolvePolicy_t = cusparseSolvePolicy_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSolvePolicy_t(pub ::std::os::raw::c_uint); +impl cusparseColorAlg_t { + pub const CUSPARSE_COLOR_ALG0: cusparseColorAlg_t = cusparseColorAlg_t(0); +} +impl cusparseColorAlg_t { + pub const CUSPARSE_COLOR_ALG1: cusparseColorAlg_t = cusparseColorAlg_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseColorAlg_t(pub ::std::os::raw::c_uint); +impl cusparseAlgMode_t { + pub const CUSPARSE_ALG_MERGE_PATH: cusparseAlgMode_t = cusparseAlgMode_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseAlgMode_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreate(handle: *mut cusparseHandle_t) -> cusparseStatus_t { + crate::create(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroy(handle: cusparseHandle_t) -> cusparseStatus_t { + crate::sparse_destroy(handle) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetVersion( + handle: cusparseHandle_t, + version: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetProperty( + type_: libraryPropertyType, + value: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetErrorName( + status: cusparseStatus_t, +) -> *const ::std::os::raw::c_char { + b"\0".as_ptr().cast() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetErrorString( + status: cusparseStatus_t, +) -> *const ::std::os::raw::c_char { + b"\0".as_ptr().cast() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetStream( + handle: cusparseHandle_t, + streamId: cuda_types::CUstream, +) -> cusparseStatus_t { + crate::set_stream(handle, streamId) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetStream( + handle: cusparseHandle_t, + streamId: *mut cuda_types::CUstream, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetPointerMode( + handle: cusparseHandle_t, + mode: *mut cusparsePointerMode_t, +) -> cusparseStatus_t { + crate::get_pointer_mode(handle, mode) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetPointerMode( + handle: cusparseHandle_t, + mode: cusparsePointerMode_t, +) -> cusparseStatus_t { + crate::set_pointer_mode(handle, mode) +} +pub type cusparseLoggerCallback_t = ::std::option::Option< + unsafe extern "C" fn( + logLevel: ::std::os::raw::c_int, + functionName: *const ::std::os::raw::c_char, + message: *const ::std::os::raw::c_char, + ), +>; + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerSetCallback( + callback: cusparseLoggerCallback_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerSetFile(file: *mut FILE) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerOpenFile( + logFile: *const ::std::os::raw::c_char, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerSetLevel( + level: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerSetMask( + mask: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseLoggerForceDisable() -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateMatDescr( + descrA: *mut cusparseMatDescr_t, +) -> cusparseStatus_t { + crate::create_mat_descr(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyMatDescr( + descrA: cusparseMatDescr_t, +) -> cusparseStatus_t { + crate::destroy_mat_descr(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCopyMatDescr( + dest: cusparseMatDescr_t, + src: cusparseMatDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetMatType( + descrA: cusparseMatDescr_t, + type_: cusparseMatrixType_t, +) -> cusparseStatus_t { + crate::set_mat_type(descrA, type_) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetMatType( + descrA: cusparseMatDescr_t, +) -> cusparseMatrixType_t { + crate::get_mat_type(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetMatFillMode( + descrA: cusparseMatDescr_t, + fillMode: cusparseFillMode_t, +) -> cusparseStatus_t { + crate::set_mat_fill_mode(descrA, fillMode) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetMatFillMode( + descrA: cusparseMatDescr_t, +) -> cusparseFillMode_t { + crate::get_mat_fill_mode(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetMatDiagType( + descrA: cusparseMatDescr_t, + diagType: cusparseDiagType_t, +) -> cusparseStatus_t { + crate::set_mat_diag_type(descrA, diagType) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetMatDiagType( + descrA: cusparseMatDescr_t, +) -> cusparseDiagType_t { + crate::get_mat_diag_type(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetMatIndexBase( + descrA: cusparseMatDescr_t, + base: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::set_mat_index_base(descrA, base) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetMatIndexBase( + descrA: cusparseMatDescr_t, +) -> cusparseIndexBase_t { + crate::get_max_index_base(descrA) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsrsv2Info( + info: *mut csrsv2Info_t, +) -> cusparseStatus_t { + crate::create_csrsv2_info(info) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsrsv2Info(info: csrsv2Info_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsric02Info( + info: *mut csric02Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsric02Info(info: csric02Info_t) -> cusparseStatus_t { + crate::destroy_csric02info(info) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateBsric02Info( + info: *mut bsric02Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyBsric02Info(info: bsric02Info_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsrilu02Info( + info: *mut csrilu02Info_t, +) -> cusparseStatus_t { + crate::create_csrilu02_info(info) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsrilu02Info( + info: csrilu02Info_t, +) -> cusparseStatus_t { + crate::destory_csrilu02info(info) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateBsrilu02Info( + info: *mut bsrilu02Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyBsrilu02Info( + info: bsrilu02Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateBsrsv2Info( + info: *mut bsrsv2Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyBsrsv2Info(info: bsrsv2Info_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateBsrsm2Info( + info: *mut bsrsm2Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyBsrsm2Info(info: bsrsm2Info_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsru2csrInfo( + info: *mut csru2csrInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsru2csrInfo( + info: csru2csrInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateColorInfo( + info: *mut cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyColorInfo( + info: cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSetColorAlgs( + info: cusparseColorInfo_t, + alg: cusparseColorAlg_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGetColorAlgs( + info: cusparseColorInfo_t, + alg: *mut cusparseColorAlg_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreatePruneInfo(info: *mut pruneInfo_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyPruneInfo(info: pruneInfo_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSaxpyi( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + xVal: *const f32, + xInd: *const ::std::os::raw::c_int, + y: *mut f32, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDaxpyi( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + xVal: *const f64, + xInd: *const ::std::os::raw::c_int, + y: *mut f64, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCaxpyi( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + xVal: *const cuComplex, + xInd: *const ::std::os::raw::c_int, + y: *mut cuComplex, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZaxpyi( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + xVal: *const cuDoubleComplex, + xInd: *const ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgthr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *const f32, + xVal: *mut f32, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgthr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *const f64, + xVal: *mut f64, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgthr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *const cuComplex, + xVal: *mut cuComplex, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgthr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *const cuDoubleComplex, + xVal: *mut cuDoubleComplex, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgthrz( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *mut f32, + xVal: *mut f32, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgthrz( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *mut f64, + xVal: *mut f64, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgthrz( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *mut cuComplex, + xVal: *mut cuComplex, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgthrz( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + xVal: *mut cuDoubleComplex, + xInd: *const ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSsctr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *const f32, + xInd: *const ::std::os::raw::c_int, + y: *mut f32, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDsctr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *const f64, + xInd: *const ::std::os::raw::c_int, + y: *mut f64, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsctr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *const cuComplex, + xInd: *const ::std::os::raw::c_int, + y: *mut cuComplex, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZsctr( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *const cuDoubleComplex, + xInd: *const ::std::os::raw::c_int, + y: *mut cuDoubleComplex, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSroti( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *mut f32, + xInd: *const ::std::os::raw::c_int, + y: *mut f32, + c: *const f32, + s: *const f32, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDroti( + handle: cusparseHandle_t, + nnz: ::std::os::raw::c_int, + xVal: *mut f64, + xInd: *const ::std::os::raw::c_int, + y: *mut f64, + c: *const f64, + s: *const f64, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgemvi( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + xVal: *const f32, + xInd: *const ::std::os::raw::c_int, + beta: *const f32, + y: *mut f32, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgemvi_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + pBufferSize: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgemvi( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + xVal: *const f64, + xInd: *const ::std::os::raw::c_int, + beta: *const f64, + y: *mut f64, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgemvi_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + pBufferSize: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgemvi( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + xVal: *const cuComplex, + xInd: *const ::std::os::raw::c_int, + beta: *const cuComplex, + y: *mut cuComplex, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgemvi_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + pBufferSize: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgemvi( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + xVal: *const cuDoubleComplex, + xInd: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgemvi_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + pBufferSize: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsrmvEx_bufferSize( + handle: cusparseHandle_t, + alg: cusparseAlgMode_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + alphatype: cudaDataType, + descrA: cusparseMatDescr_t, + csrValA: *const ::std::os::raw::c_void, + csrValAtype: cudaDataType, + csrRowPtrA: *const ::std::os::raw::c_int, + csrColIndA: *const ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xtype: cudaDataType, + beta: *const ::std::os::raw::c_void, + betatype: cudaDataType, + y: *mut ::std::os::raw::c_void, + ytype: cudaDataType, + executiontype: cudaDataType, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsrmvEx( + handle: cusparseHandle_t, + alg: cusparseAlgMode_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const ::std::os::raw::c_void, + alphatype: cudaDataType, + descrA: cusparseMatDescr_t, + csrValA: *const ::std::os::raw::c_void, + csrValAtype: cudaDataType, + csrRowPtrA: *const ::std::os::raw::c_int, + csrColIndA: *const ::std::os::raw::c_int, + x: *const ::std::os::raw::c_void, + xtype: cudaDataType, + beta: *const ::std::os::raw::c_void, + betatype: cudaDataType, + y: *mut ::std::os::raw::c_void, + ytype: cudaDataType, + executiontype: cudaDataType, + buffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const f32, + beta: *const f32, + y: *mut f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const f64, + beta: *const f64, + y: *mut f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const cuComplex, + beta: *const cuComplex, + y: *mut cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrxmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + sizeOfMask: ::std::os::raw::c_int, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedMaskPtrA: *const ::std::os::raw::c_int, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedEndPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const f32, + beta: *const f32, + y: *mut f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrxmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + sizeOfMask: ::std::os::raw::c_int, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedMaskPtrA: *const ::std::os::raw::c_int, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedEndPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const f64, + beta: *const f64, + y: *mut f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrxmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + sizeOfMask: ::std::os::raw::c_int, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedMaskPtrA: *const ::std::os::raw::c_int, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedEndPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const cuComplex, + beta: *const cuComplex, + y: *mut cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrxmv( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + sizeOfMask: ::std::os::raw::c_int, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedMaskPtrA: *const ::std::os::raw::c_int, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedEndPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + x: *const cuDoubleComplex, + beta: *const cuDoubleComplex, + y: *mut cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrsv2_zeroPivot( + handle: cusparseHandle_t, + info: csrsv2Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsv2_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsv2_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::dcsr_sv2_buffersize( + handle, + transA, + m, + nnz, + descrA, + csrSortedValA, + csrSortedRowPtrA, + csrSortedColIndA, + info, + pBufferSizeInBytes, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsv2_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsv2_bufferSize( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsv2_analysis( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsv2_analysis( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::dcsr_sv2_analysis( + handle, + transA, + m, + nnz, + descrA, + csrSortedValA, + csrSortedRowPtrA, + csrSortedColIndA, + info, + policy, + pBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsv2_analysis( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsv2_analysis( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsv2_solve( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + f: *const f32, + x: *mut f32, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsv2_solve( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + f: *const f64, + x: *mut f64, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::dcsr_sv2_solve( + handle, + transA, + m, + nnz, + alpha, + descrA, + csrSortedValA, + csrSortedRowPtrA, + csrSortedColIndA, + info, + f, + x, + policy, + pBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsv2_solve( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + f: *const cuComplex, + x: *mut cuComplex, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsv2_solve( + handle: cusparseHandle_t, + transA: cusparseOperation_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrsv2Info_t, + f: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXbsrsv2_zeroPivot( + handle: cusparseHandle_t, + info: bsrsv2Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsv2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsv2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsv2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsv2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsv2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *mut cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsv2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsv2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsv2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsv2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsv2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsv2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + f: *const f32, + x: *mut f32, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsv2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + f: *const f64, + x: *mut f64, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsv2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + f: *const cuComplex, + x: *mut cuComplex, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsv2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrsv2Info_t, + f: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrmm( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrmm( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrmm( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrmm( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + kb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgemmi( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + A: *const f32, + lda: ::std::os::raw::c_int, + cscValB: *const f32, + cscColPtrB: *const ::std::os::raw::c_int, + cscRowIndB: *const ::std::os::raw::c_int, + beta: *const f32, + C: *mut f32, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgemmi( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + A: *const f64, + lda: ::std::os::raw::c_int, + cscValB: *const f64, + cscColPtrB: *const ::std::os::raw::c_int, + cscRowIndB: *const ::std::os::raw::c_int, + beta: *const f64, + C: *mut f64, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgemmi( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + cscValB: *const cuComplex, + cscColPtrB: *const ::std::os::raw::c_int, + cscRowIndB: *const ::std::os::raw::c_int, + beta: *const cuComplex, + C: *mut cuComplex, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgemmi( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + cscValB: *const cuDoubleComplex, + cscColPtrB: *const ::std::os::raw::c_int, + cscRowIndB: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + C: *mut cuDoubleComplex, + ldc: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsrsm2Info( + info: *mut csrsm2Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsrsm2Info(info: csrsm2Info_t) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrsm2_zeroPivot( + handle: cusparseHandle_t, + info: csrsm2Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsm2_analysis( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const f32, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsm2_analysis( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const f64, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsm2_analysis( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsm2_analysis( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrsm2_solve( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *mut f32, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrsm2_solve( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *mut f64, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrsm2_solve( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrsm2_solve( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + m: ::std::os::raw::c_int, + nrhs: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, + info: csrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXbsrsm2_zeroPivot( + handle: cusparseHandle_t, + info: bsrsm2Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsm2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsm2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsm2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsm2_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsm2_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transB: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsm2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsm2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsm2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsm2_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrsm2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + B: *const f32, + ldb: ::std::os::raw::c_int, + X: *mut f32, + ldx: ::std::os::raw::c_int, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrsm2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + B: *const f64, + ldb: ::std::os::raw::c_int, + X: *mut f64, + ldx: ::std::os::raw::c_int, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrsm2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + X: *mut cuComplex, + ldx: ::std::os::raw::c_int, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrsm2_solve( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + transA: cusparseOperation_t, + transXY: cusparseOperation_t, + mb: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrsm2Info_t, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + X: *mut cuDoubleComplex, + ldx: ::std::os::raw::c_int, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrilu02_numericBoost( + handle: cusparseHandle_t, + info: csrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrilu02_numericBoost( + handle: cusparseHandle_t, + info: csrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrilu02_numericBoost( + handle: cusparseHandle_t, + info: csrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrilu02_numericBoost( + handle: cusparseHandle_t, + info: csrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrilu02_zeroPivot( + handle: cusparseHandle_t, + info: csrilu02Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::xcsrilu02_zeropivot(handle, info, position) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrilu02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrilu02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::dcsrilu02_buffersize( + handle, + m, + nnz, + descrA, + csrSortedValA, + csrSortedRowPtrA, + csrSortedColIndA, + info, + pBufferSizeInBytes, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrilu02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrilu02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut f32, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut f64, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut cuComplex, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut cuDoubleComplex, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrilu02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrilu02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::dcsrilu02_analysis( + handle, + m, + nnz, + descrA, + csrSortedValA, + csrSortedRowPtrA, + csrSortedColIndA, + info, + policy, + pBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrilu02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrilu02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrilu02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrilu02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::dcsrilu02( + handle, + m, + nnz, + descrA, + csrSortedValA_valM, + csrSortedRowPtrA, + csrSortedColIndA, + info, + policy, + pBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrilu02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrilu02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrilu02_numericBoost( + handle: cusparseHandle_t, + info: bsrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrilu02_numericBoost( + handle: cusparseHandle_t, + info: bsrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrilu02_numericBoost( + handle: cusparseHandle_t, + info: bsrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrilu02_numericBoost( + handle: cusparseHandle_t, + info: bsrilu02Info_t, + enable_boost: ::std::os::raw::c_int, + tol: *mut f64, + boost_val: *mut cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXbsrilu02_zeroPivot( + handle: cusparseHandle_t, + info: bsrilu02Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrilu02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrilu02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrilu02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrilu02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrilu02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsrilu02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrilu02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrilu02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrilu02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrilu02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsrilu02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsrilu02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsrilu02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsrilu02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsrilu02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsric02_zeroPivot( + handle: cusparseHandle_t, + info: csric02Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsric02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsric02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsric02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsric02_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsric02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut f32, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsric02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut f64, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsric02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut cuComplex, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsric02_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedVal: *mut cuDoubleComplex, + csrSortedRowPtr: *const ::std::os::raw::c_int, + csrSortedColInd: *const ::std::os::raw::c_int, + info: csric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsric02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsric02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsric02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsric02_analysis( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsric02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsric02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsric02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsric02( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA_valM: *mut cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + info: csric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXbsric02_zeroPivot( + handle: cusparseHandle_t, + info: bsric02Info_t, + position: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsric02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsric02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsric02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsric02_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsric02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsric02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsric02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsric02_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockSize: ::std::os::raw::c_int, + info: bsric02Info_t, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsric02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pInputBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsric02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pInputBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsric02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pInputBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsric02_analysis( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pInputBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsric02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsric02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsric02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsric02( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedVal: *mut cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + info: bsric02Info_t, + policy: cusparseSolvePolicy_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *const f32, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *const f64, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *mut f32, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *mut f64, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2_nopivot_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *const f32, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2_nopivot_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *const f64, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2_nopivot_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + B: *const cuComplex, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2_nopivot_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + B: *const cuDoubleComplex, + ldb: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2_nopivot( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + B: *mut f32, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2_nopivot( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + B: *mut f64, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2_nopivot( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + B: *mut cuComplex, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2_nopivot( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + B: *mut cuDoubleComplex, + ldb: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2StridedBatch_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *const f32, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2StridedBatch_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *const f64, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2StridedBatch_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + x: *const cuComplex, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2StridedBatch_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + x: *const cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + bufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsv2StridedBatch( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *mut f32, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsv2StridedBatch( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *mut f64, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsv2StridedBatch( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + x: *mut cuComplex, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsv2StridedBatch( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + x: *mut cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + batchStride: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *const f32, + d: *const f32, + du: *const f32, + x: *const f32, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *const f64, + d: *const f64, + du: *const f64, + x: *const f64, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + x: *const cuComplex, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + x: *const cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgtsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *mut f32, + d: *mut f32, + du: *mut f32, + x: *mut f32, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgtsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *mut f64, + d: *mut f64, + du: *mut f64, + x: *mut f64, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgtsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *mut cuComplex, + d: *mut cuComplex, + du: *mut cuComplex, + x: *mut cuComplex, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgtsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + dl: *mut cuDoubleComplex, + d: *mut cuDoubleComplex, + du: *mut cuDoubleComplex, + x: *mut cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgpsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *const f32, + dl: *const f32, + d: *const f32, + du: *const f32, + dw: *const f32, + x: *const f32, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgpsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *const f64, + dl: *const f64, + d: *const f64, + du: *const f64, + dw: *const f64, + x: *const f64, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgpsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *const cuComplex, + dl: *const cuComplex, + d: *const cuComplex, + du: *const cuComplex, + dw: *const cuComplex, + x: *const cuComplex, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgpsvInterleavedBatch_bufferSizeExt( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *const cuDoubleComplex, + dl: *const cuDoubleComplex, + d: *const cuDoubleComplex, + du: *const cuDoubleComplex, + dw: *const cuDoubleComplex, + x: *const cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgpsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *mut f32, + dl: *mut f32, + d: *mut f32, + du: *mut f32, + dw: *mut f32, + x: *mut f32, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgpsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *mut f64, + dl: *mut f64, + d: *mut f64, + du: *mut f64, + dw: *mut f64, + x: *mut f64, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgpsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *mut cuComplex, + dl: *mut cuComplex, + d: *mut cuComplex, + du: *mut cuComplex, + dw: *mut cuComplex, + x: *mut cuComplex, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgpsvInterleavedBatch( + handle: cusparseHandle_t, + algo: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + ds: *mut cuDoubleComplex, + dl: *mut cuDoubleComplex, + d: *mut cuDoubleComplex, + du: *mut cuDoubleComplex, + dw: *mut cuDoubleComplex, + x: *mut cuDoubleComplex, + batchCount: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsrgemm2Info( + info: *mut csrgemm2Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyCsrgemm2Info( + info: csrgemm2Info_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrgemm2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const f32, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrgemm2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const f64, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrgemm2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const cuComplex, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrgemm2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrgemm2Nnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrgemm2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f32, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const f32, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedValD: *const f32, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrgemm2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f64, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const f64, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedValD: *const f64, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrgemm2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const cuComplex, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedValD: *const cuComplex, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuComplex, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrgemm2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + k: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuDoubleComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + descrD: cusparseMatDescr_t, + nnzD: ::std::os::raw::c_int, + csrSortedValD: *const cuDoubleComplex, + csrSortedRowPtrD: *const ::std::os::raw::c_int, + csrSortedColIndD: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuDoubleComplex, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: csrgemm2Info_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrgeam2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const f32, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f32, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrgeam2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const f64, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f64, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrgeam2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const cuComplex, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *const cuComplex, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrgeam2_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuDoubleComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *const cuDoubleComplex, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrgeam2Nnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + workspace: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrgeam2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f32, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const f32, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f32, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrgeam2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const f64, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const f64, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const f64, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrgeam2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const cuComplex, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrgeam2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + alpha: *const cuDoubleComplex, + descrA: cusparseMatDescr_t, + nnzA: ::std::os::raw::c_int, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + beta: *const cuDoubleComplex, + descrB: cusparseMatDescr_t, + nnzB: ::std::os::raw::c_int, + csrSortedValB: *const cuDoubleComplex, + csrSortedRowPtrB: *const ::std::os::raw::c_int, + csrSortedColIndB: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuDoubleComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsrcolor( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + fractionToColor: *const f32, + ncolors: *mut ::std::os::raw::c_int, + coloring: *mut ::std::os::raw::c_int, + reordering: *mut ::std::os::raw::c_int, + info: cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsrcolor( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + fractionToColor: *const f64, + ncolors: *mut ::std::os::raw::c_int, + coloring: *mut ::std::os::raw::c_int, + reordering: *mut ::std::os::raw::c_int, + info: cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsrcolor( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + fractionToColor: *const f32, + ncolors: *mut ::std::os::raw::c_int, + coloring: *mut ::std::os::raw::c_int, + reordering: *mut ::std::os::raw::c_int, + info: cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsrcolor( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + fractionToColor: *const f64, + ncolors: *mut ::std::os::raw::c_int, + coloring: *mut ::std::os::raw::c_int, + reordering: *mut ::std::os::raw::c_int, + info: cusparseColorInfo_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSnnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f32, + lda: ::std::os::raw::c_int, + nnzPerRowCol: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f64, + lda: ::std::os::raw::c_int, + nnzPerRowCol: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCnnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + nnzPerRowCol: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZnnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + nnzPerRowCol: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSnnz_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + descr: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzPerRow: *mut ::std::os::raw::c_int, + nnzC: *mut ::std::os::raw::c_int, + tol: f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnnz_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + descr: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzPerRow: *mut ::std::os::raw::c_int, + nnzC: *mut ::std::os::raw::c_int, + tol: f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCnnz_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + descr: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzPerRow: *mut ::std::os::raw::c_int, + nnzC: *mut ::std::os::raw::c_int, + tol: cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZnnz_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + descr: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzPerRow: *mut ::std::os::raw::c_int, + nnzC: *mut ::std::os::raw::c_int, + tol: cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2csr_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedColIndA: *const ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValC: *mut f32, + csrSortedColIndC: *mut ::std::os::raw::c_int, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + tol: f32, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2csr_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedColIndA: *const ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValC: *mut f64, + csrSortedColIndC: *mut ::std::os::raw::c_int, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + tol: f64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2csr_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedColIndA: *const ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValC: *mut cuComplex, + csrSortedColIndC: *mut ::std::os::raw::c_int, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + tol: cuComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2csr_compress( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedColIndA: *const ::std::os::raw::c_int, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValC: *mut cuDoubleComplex, + csrSortedColIndC: *mut ::std::os::raw::c_int, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + tol: cuDoubleComplex, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSdense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f32, + lda: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValA: *mut f32, + csrSortedRowPtrA: *mut ::std::os::raw::c_int, + csrSortedColIndA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDdense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f64, + lda: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValA: *mut f64, + csrSortedRowPtrA: *mut ::std::os::raw::c_int, + csrSortedColIndA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCdense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValA: *mut cuComplex, + csrSortedRowPtrA: *mut ::std::os::raw::c_int, + csrSortedColIndA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZdense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + nnzPerRow: *const ::std::os::raw::c_int, + csrSortedValA: *mut cuDoubleComplex, + csrSortedRowPtrA: *mut ::std::os::raw::c_int, + csrSortedColIndA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSdense2csc( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f32, + lda: ::std::os::raw::c_int, + nnzPerCol: *const ::std::os::raw::c_int, + cscSortedValA: *mut f32, + cscSortedRowIndA: *mut ::std::os::raw::c_int, + cscSortedColPtrA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDdense2csc( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const f64, + lda: ::std::os::raw::c_int, + nnzPerCol: *const ::std::os::raw::c_int, + cscSortedValA: *mut f64, + cscSortedRowIndA: *mut ::std::os::raw::c_int, + cscSortedColPtrA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCdense2csc( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuComplex, + lda: ::std::os::raw::c_int, + nnzPerCol: *const ::std::os::raw::c_int, + cscSortedValA: *mut cuComplex, + cscSortedRowIndA: *mut ::std::os::raw::c_int, + cscSortedColPtrA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZdense2csc( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + A: *const cuDoubleComplex, + lda: ::std::os::raw::c_int, + nnzPerCol: *const ::std::os::raw::c_int, + cscSortedValA: *mut cuDoubleComplex, + cscSortedRowIndA: *mut ::std::os::raw::c_int, + cscSortedColPtrA: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsc2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + cscSortedValA: *const f32, + cscSortedRowIndA: *const ::std::os::raw::c_int, + cscSortedColPtrA: *const ::std::os::raw::c_int, + A: *mut f32, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsc2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + cscSortedValA: *const f64, + cscSortedRowIndA: *const ::std::os::raw::c_int, + cscSortedColPtrA: *const ::std::os::raw::c_int, + A: *mut f64, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsc2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + cscSortedValA: *const cuComplex, + cscSortedRowIndA: *const ::std::os::raw::c_int, + cscSortedColPtrA: *const ::std::os::raw::c_int, + A: *mut cuComplex, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsc2dense( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + cscSortedValA: *const cuDoubleComplex, + cscSortedRowIndA: *const ::std::os::raw::c_int, + cscSortedColPtrA: *const ::std::os::raw::c_int, + A: *mut cuDoubleComplex, + lda: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcoo2csr( + handle: cusparseHandle_t, + cooRowInd: *const ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + csrSortedRowPtr: *mut ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsr2coo( + handle: cusparseHandle_t, + csrSortedRowPtr: *const ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + m: ::std::os::raw::c_int, + cooRowInd: *mut ::std::os::raw::c_int, + idxBase: cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsr2bsrNnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2bsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f32, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2bsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f64, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2bsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2bsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuDoubleComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSbsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDbsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCbsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZbsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + blockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuDoubleComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsc_bufferSize( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsc_bufferSize( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsc_bufferSize( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsc_bufferSize( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsc_bufferSizeExt( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsc_bufferSizeExt( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsc_bufferSizeExt( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsc_bufferSizeExt( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsc( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f32, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + bscVal: *mut f32, + bscRowInd: *mut ::std::os::raw::c_int, + bscColPtr: *mut ::std::os::raw::c_int, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsc( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const f64, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + bscVal: *mut f64, + bscRowInd: *mut ::std::os::raw::c_int, + bscColPtr: *mut ::std::os::raw::c_int, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsc( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + bscVal: *mut cuComplex, + bscRowInd: *mut ::std::os::raw::c_int, + bscColPtr: *mut ::std::os::raw::c_int, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsc( + handle: cusparseHandle_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + bsrSortedVal: *const cuDoubleComplex, + bsrSortedRowPtr: *const ::std::os::raw::c_int, + bsrSortedColInd: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + bscVal: *mut cuDoubleComplex, + bscRowInd: *mut ::std::os::raw::c_int, + bscColPtr: *mut ::std::os::raw::c_int, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXgebsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2csr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut cuDoubleComplex, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsr2gebsrNnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f32, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f64, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const cuDoubleComplex, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuDoubleComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDim: ::std::os::raw::c_int, + colBlockDim: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsr_bufferSize( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSizeInBytes: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsr_bufferSizeExt( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXgebsr2gebsrNnz( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSgebsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f32, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f32, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDgebsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const f64, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut f64, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCgebsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZgebsr2gebsr( + handle: cusparseHandle_t, + dirA: cusparseDirection_t, + mb: ::std::os::raw::c_int, + nb: ::std::os::raw::c_int, + nnzb: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + bsrSortedValA: *const cuDoubleComplex, + bsrSortedRowPtrA: *const ::std::os::raw::c_int, + bsrSortedColIndA: *const ::std::os::raw::c_int, + rowBlockDimA: ::std::os::raw::c_int, + colBlockDimA: ::std::os::raw::c_int, + descrC: cusparseMatDescr_t, + bsrSortedValC: *mut cuDoubleComplex, + bsrSortedRowPtrC: *mut ::std::os::raw::c_int, + bsrSortedColIndC: *mut ::std::os::raw::c_int, + rowBlockDimC: ::std::os::raw::c_int, + colBlockDimC: ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateIdentityPermutation( + handle: cusparseHandle_t, + n: ::std::os::raw::c_int, + p: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcoosort_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + cooRowsA: *const ::std::os::raw::c_int, + cooColsA: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcoosortByRow( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + cooRowsA: *mut ::std::os::raw::c_int, + cooColsA: *mut ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcoosortByColumn( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + cooRowsA: *mut ::std::os::raw::c_int, + cooColsA: *mut ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrsort_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrRowPtrA: *const ::std::os::raw::c_int, + csrColIndA: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcsrsort( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrRowPtrA: *const ::std::os::raw::c_int, + csrColIndA: *mut ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcscsort_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + cscColPtrA: *const ::std::os::raw::c_int, + cscRowIndA: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseXcscsort( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + cscColPtrA: *const ::std::os::raw::c_int, + cscRowIndA: *mut ::std::os::raw::c_int, + P: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsru2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *mut f32, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsru2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *mut f64, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsru2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *mut cuComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsru2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *mut cuDoubleComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsru2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut f32, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsru2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut f64, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsru2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut cuComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsru2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut cuDoubleComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScsr2csru( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut f32, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDcsr2csru( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut f64, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCcsr2csru( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut cuComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseZcsr2csru( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrVal: *mut cuDoubleComplex, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *mut ::std::os::raw::c_int, + info: csru2csrInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csrNnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csrNnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csr_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csrNnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csrNnz( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csr( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + threshold: *const f64, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csrByPercentage_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + info: pruneInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csrByPercentage_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + info: pruneInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csrNnzByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csrNnzByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneDense2csrByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f32, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneDense2csrByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + A: *const f64, + lda: ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csrByPercentage_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + info: pruneInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csrByPercentage_bufferSizeExt( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *const f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *const ::std::os::raw::c_int, + info: pruneInfo_t, + pBufferSizeInBytes: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csrNnzByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csrNnzByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedRowPtrC: *mut ::std::os::raw::c_int, + nnzTotalDevHostPtr: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpruneCsr2csrByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f32, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f32, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDpruneCsr2csrByPercentage( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnzA: ::std::os::raw::c_int, + descrA: cusparseMatDescr_t, + csrSortedValA: *const f64, + csrSortedRowPtrA: *const ::std::os::raw::c_int, + csrSortedColIndA: *const ::std::os::raw::c_int, + percentage: f32, + descrC: cusparseMatDescr_t, + csrSortedValC: *mut f64, + csrSortedRowPtrC: *const ::std::os::raw::c_int, + csrSortedColIndC: *mut ::std::os::raw::c_int, + info: pruneInfo_t, + pBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseCsr2CscAlg_t { + pub const CUSPARSE_CSR2CSC_ALG1: cusparseCsr2CscAlg_t = cusparseCsr2CscAlg_t(1); +} +impl cusparseCsr2CscAlg_t { + pub const CUSPARSE_CSR2CSC_ALG2: cusparseCsr2CscAlg_t = cusparseCsr2CscAlg_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseCsr2CscAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsr2cscEx2( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *const ::std::os::raw::c_void, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *const ::std::os::raw::c_int, + cscVal: *mut ::std::os::raw::c_void, + cscColPtr: *mut ::std::os::raw::c_int, + cscRowInd: *mut ::std::os::raw::c_int, + valType: cudaDataType, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + alg: cusparseCsr2CscAlg_t, + buffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::csr2cscex2( + handle, m, n, nnz, csrVal, csrRowPtr, csrColInd, cscVal, cscColPtr, cscRowInd, valType, + copyValues, idxBase, alg, buffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsr2cscEx2_bufferSize( + handle: cusparseHandle_t, + m: ::std::os::raw::c_int, + n: ::std::os::raw::c_int, + nnz: ::std::os::raw::c_int, + csrVal: *const ::std::os::raw::c_void, + csrRowPtr: *const ::std::os::raw::c_int, + csrColInd: *const ::std::os::raw::c_int, + cscVal: *mut ::std::os::raw::c_void, + cscColPtr: *mut ::std::os::raw::c_int, + cscRowInd: *mut ::std::os::raw::c_int, + valType: cudaDataType, + copyValues: cusparseAction_t, + idxBase: cusparseIndexBase_t, + alg: cusparseCsr2CscAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::csr2cscex2_buffersize( + handle, m, n, nnz, csrVal, csrRowPtr, csrColInd, cscVal, cscColPtr, cscRowInd, valType, + copyValues, idxBase, alg, bufferSize, + ) +} +impl cusparseFormat_t { + #[doc = "< Compressed Sparse Row (CSR)"] + pub const CUSPARSE_FORMAT_CSR: cusparseFormat_t = cusparseFormat_t(1); +} +impl cusparseFormat_t { + #[doc = "< Compressed Sparse Column (CSC)"] + pub const CUSPARSE_FORMAT_CSC: cusparseFormat_t = cusparseFormat_t(2); +} +impl cusparseFormat_t { + #[doc = "< Coordinate (COO) - Structure of Arrays"] + pub const CUSPARSE_FORMAT_COO: cusparseFormat_t = cusparseFormat_t(3); +} +impl cusparseFormat_t { + #[doc = "< Coordinate (COO) - Array of Structures"] + pub const CUSPARSE_FORMAT_COO_AOS: cusparseFormat_t = cusparseFormat_t(4); +} +impl cusparseFormat_t { + #[doc = "< Blocked ELL"] + pub const CUSPARSE_FORMAT_BLOCKED_ELL: cusparseFormat_t = cusparseFormat_t(5); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseFormat_t(pub ::std::os::raw::c_uint); +impl cusparseOrder_t { + #[doc = "< Column-Major Order - Matrix memory layout"] + pub const CUSPARSE_ORDER_COL: cusparseOrder_t = cusparseOrder_t(1); +} +impl cusparseOrder_t { + #[doc = "< Row-Major Order - Matrix memory layout"] + pub const CUSPARSE_ORDER_ROW: cusparseOrder_t = cusparseOrder_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseOrder_t(pub ::std::os::raw::c_uint); +impl cusparseIndexType_t { + #[doc = "< 16-bit unsigned integer for matrix/vector\n< indices"] + pub const CUSPARSE_INDEX_16U: cusparseIndexType_t = cusparseIndexType_t(1); +} +impl cusparseIndexType_t { + #[doc = "< 32-bit signed integer for matrix/vector indices"] + pub const CUSPARSE_INDEX_32I: cusparseIndexType_t = cusparseIndexType_t(2); +} +impl cusparseIndexType_t { + #[doc = "< 64-bit signed integer for matrix/vector indices"] + pub const CUSPARSE_INDEX_64I: cusparseIndexType_t = cusparseIndexType_t(3); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseIndexType_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpVecDescr { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseDnVecDescr { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpMatDescr { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseDnMatDescr { + _unused: [u8; 0], +} +pub type cusparseSpVecDescr_t = *mut cusparseSpVecDescr; +pub type cusparseDnVecDescr_t = *mut cusparseDnVecDescr; +pub type cusparseSpMatDescr_t = *mut cusparseSpMatDescr; +pub type cusparseDnMatDescr_t = *mut cusparseDnMatDescr; + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateSpVec( + spVecDescr: *mut cusparseSpVecDescr_t, + size: i64, + nnz: i64, + indices: *mut ::std::os::raw::c_void, + values: *mut ::std::os::raw::c_void, + idxType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroySpVec( + spVecDescr: cusparseSpVecDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVecGet( + spVecDescr: cusparseSpVecDescr_t, + size: *mut i64, + nnz: *mut i64, + indices: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + idxType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVecGetIndexBase( + spVecDescr: cusparseSpVecDescr_t, + idxBase: *mut cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVecGetValues( + spVecDescr: cusparseSpVecDescr_t, + values: *mut *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVecSetValues( + spVecDescr: cusparseSpVecDescr_t, + values: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateDnVec( + dnVecDescr: *mut cusparseDnVecDescr_t, + size: i64, + values: *mut ::std::os::raw::c_void, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::create_dn_vec(dnVecDescr, size, values, valueType) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyDnVec( + dnVecDescr: cusparseDnVecDescr_t, +) -> cusparseStatus_t { + crate::destory_dnvec(dnVecDescr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnVecGet( + dnVecDescr: cusparseDnVecDescr_t, + size: *mut i64, + values: *mut *mut ::std::os::raw::c_void, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnVecGetValues( + dnVecDescr: cusparseDnVecDescr_t, + values: *mut *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnVecSetValues( + dnVecDescr: cusparseDnVecDescr_t, + values: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::dnvec_set_values(dnVecDescr, values) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroySpMat( + spMatDescr: cusparseSpMatDescr_t, +) -> cusparseStatus_t { + crate::destroy_sp_mat(spMatDescr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetFormat( + spMatDescr: cusparseSpMatDescr_t, + format: *mut cusparseFormat_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetIndexBase( + spMatDescr: cusparseSpMatDescr_t, + idxBase: *mut cusparseIndexBase_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetValues( + spMatDescr: cusparseSpMatDescr_t, + values: *mut *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatSetValues( + spMatDescr: cusparseSpMatDescr_t, + values: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetSize( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, +) -> cusparseStatus_t { + crate::spmat_get_size(spMatDescr, rows, cols, nnz) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatSetStridedBatch( + spMatDescr: cusparseSpMatDescr_t, + batchCount: ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetStridedBatch( + spMatDescr: cusparseSpMatDescr_t, + batchCount: *mut ::std::os::raw::c_int, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCooSetStridedBatch( + spMatDescr: cusparseSpMatDescr_t, + batchCount: ::std::os::raw::c_int, + batchStride: i64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsrSetStridedBatch( + spMatDescr: cusparseSpMatDescr_t, + batchCount: ::std::os::raw::c_int, + offsetsBatchStride: i64, + columnsValuesBatchStride: i64, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSpMatAttribute_t { + pub const CUSPARSE_SPMAT_FILL_MODE: cusparseSpMatAttribute_t = cusparseSpMatAttribute_t(0); +} +impl cusparseSpMatAttribute_t { + pub const CUSPARSE_SPMAT_DIAG_TYPE: cusparseSpMatAttribute_t = cusparseSpMatAttribute_t(1); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpMatAttribute_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatGetAttribute( + spMatDescr: cusparseSpMatDescr_t, + attribute: cusparseSpMatAttribute_t, + data: *mut ::std::os::raw::c_void, + dataSize: usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMatSetAttribute( + spMatDescr: cusparseSpMatDescr_t, + attribute: cusparseSpMatAttribute_t, + data: *mut ::std::os::raw::c_void, + dataSize: usize, +) -> cusparseStatus_t { + crate::spmat_set_attribute(spMatDescr, attribute, data, dataSize) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsr( + spMatDescr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + nnz: i64, + csrRowOffsets: *mut ::std::os::raw::c_void, + csrColInd: *mut ::std::os::raw::c_void, + csrValues: *mut ::std::os::raw::c_void, + csrRowOffsetsType: cusparseIndexType_t, + csrColIndType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::create_csr( + spMatDescr, + rows, + cols, + nnz, + csrRowOffsets, + csrColInd, + csrValues, + csrRowOffsetsType, + csrColIndType, + idxBase, + valueType, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCsc( + spMatDescr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + nnz: i64, + cscColOffsets: *mut ::std::os::raw::c_void, + cscRowInd: *mut ::std::os::raw::c_void, + cscValues: *mut ::std::os::raw::c_void, + cscColOffsetsType: cusparseIndexType_t, + cscRowIndType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsrGet( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + csrRowOffsets: *mut *mut ::std::os::raw::c_void, + csrColInd: *mut *mut ::std::os::raw::c_void, + csrValues: *mut *mut ::std::os::raw::c_void, + csrRowOffsetsType: *mut cusparseIndexType_t, + csrColIndType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCscGet( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + cscColOffsets: *mut *mut ::std::os::raw::c_void, + cscRowInd: *mut *mut ::std::os::raw::c_void, + cscValues: *mut *mut ::std::os::raw::c_void, + cscColOffsetsType: *mut cusparseIndexType_t, + cscRowIndType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCsrSetPointers( + spMatDescr: cusparseSpMatDescr_t, + csrRowOffsets: *mut ::std::os::raw::c_void, + csrColInd: *mut ::std::os::raw::c_void, + csrValues: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::csr_set_pointers(spMatDescr, csrRowOffsets, csrColInd, csrValues) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCscSetPointers( + spMatDescr: cusparseSpMatDescr_t, + cscColOffsets: *mut ::std::os::raw::c_void, + cscRowInd: *mut ::std::os::raw::c_void, + cscValues: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCoo( + spMatDescr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + nnz: i64, + cooRowInd: *mut ::std::os::raw::c_void, + cooColInd: *mut ::std::os::raw::c_void, + cooValues: *mut ::std::os::raw::c_void, + cooIdxType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateCooAoS( + spMatDescr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + nnz: i64, + cooInd: *mut ::std::os::raw::c_void, + cooValues: *mut ::std::os::raw::c_void, + cooIdxType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCooGet( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + cooRowInd: *mut *mut ::std::os::raw::c_void, + cooColInd: *mut *mut ::std::os::raw::c_void, + cooValues: *mut *mut ::std::os::raw::c_void, + idxType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCooAoSGet( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, + cooInd: *mut *mut ::std::os::raw::c_void, + cooValues: *mut *mut ::std::os::raw::c_void, + idxType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCooSetPointers( + spMatDescr: cusparseSpMatDescr_t, + cooRows: *mut ::std::os::raw::c_void, + cooColumns: *mut ::std::os::raw::c_void, + cooValues: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateBlockedEll( + spMatDescr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + ellBlockSize: i64, + ellCols: i64, + ellColInd: *mut ::std::os::raw::c_void, + ellValue: *mut ::std::os::raw::c_void, + ellIdxType: cusparseIndexType_t, + idxBase: cusparseIndexBase_t, + valueType: cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseBlockedEllGet( + spMatDescr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + ellBlockSize: *mut i64, + ellCols: *mut i64, + ellColInd: *mut *mut ::std::os::raw::c_void, + ellValue: *mut *mut ::std::os::raw::c_void, + ellIdxType: *mut cusparseIndexType_t, + idxBase: *mut cusparseIndexBase_t, + valueType: *mut cudaDataType, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseCreateDnMat( + dnMatDescr: *mut cusparseDnMatDescr_t, + rows: i64, + cols: i64, + ld: i64, + values: *mut ::std::os::raw::c_void, + valueType: cudaDataType, + order: cusparseOrder_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDestroyDnMat( + dnMatDescr: cusparseDnMatDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnMatGet( + dnMatDescr: cusparseDnMatDescr_t, + rows: *mut i64, + cols: *mut i64, + ld: *mut i64, + values: *mut *mut ::std::os::raw::c_void, + type_: *mut cudaDataType, + order: *mut cusparseOrder_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnMatGetValues( + dnMatDescr: cusparseDnMatDescr_t, + values: *mut *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnMatSetValues( + dnMatDescr: cusparseDnMatDescr_t, + values: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnMatSetStridedBatch( + dnMatDescr: cusparseDnMatDescr_t, + batchCount: ::std::os::raw::c_int, + batchStride: i64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDnMatGetStridedBatch( + dnMatDescr: cusparseDnMatDescr_t, + batchCount: *mut ::std::os::raw::c_int, + batchStride: *mut i64, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseAxpby( + handle: cusparseHandle_t, + alpha: *const ::std::os::raw::c_void, + vecX: cusparseSpVecDescr_t, + beta: *const ::std::os::raw::c_void, + vecY: cusparseDnVecDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseGather( + handle: cusparseHandle_t, + vecY: cusparseDnVecDescr_t, + vecX: cusparseSpVecDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseScatter( + handle: cusparseHandle_t, + vecX: cusparseSpVecDescr_t, + vecY: cusparseDnVecDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseRot( + handle: cusparseHandle_t, + c_coeff: *const ::std::os::raw::c_void, + s_coeff: *const ::std::os::raw::c_void, + vecX: cusparseSpVecDescr_t, + vecY: cusparseDnVecDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVV_bufferSize( + handle: cusparseHandle_t, + opX: cusparseOperation_t, + vecX: cusparseSpVecDescr_t, + vecY: cusparseDnVecDescr_t, + result: *const ::std::os::raw::c_void, + computeType: cudaDataType, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpVV( + handle: cusparseHandle_t, + opX: cusparseOperation_t, + vecX: cusparseSpVecDescr_t, + vecY: cusparseDnVecDescr_t, + result: *mut ::std::os::raw::c_void, + computeType: cudaDataType, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSparseToDenseAlg_t { + pub const CUSPARSE_SPARSETODENSE_ALG_DEFAULT: cusparseSparseToDenseAlg_t = + cusparseSparseToDenseAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSparseToDenseAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSparseToDense_bufferSize( + handle: cusparseHandle_t, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + alg: cusparseSparseToDenseAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSparseToDense( + handle: cusparseHandle_t, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + alg: cusparseSparseToDenseAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseDenseToSparseAlg_t { + pub const CUSPARSE_DENSETOSPARSE_ALG_DEFAULT: cusparseDenseToSparseAlg_t = + cusparseDenseToSparseAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseDenseToSparseAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseDenseToSparse_bufferSize( + handle: cusparseHandle_t, + matA: cusparseDnMatDescr_t, + matB: cusparseSpMatDescr_t, + alg: cusparseDenseToSparseAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDenseToSparse_analysis( + handle: cusparseHandle_t, + matA: cusparseDnMatDescr_t, + matB: cusparseSpMatDescr_t, + alg: cusparseDenseToSparseAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseDenseToSparse_convert( + handle: cusparseHandle_t, + matA: cusparseDnMatDescr_t, + matB: cusparseSpMatDescr_t, + alg: cusparseDenseToSparseAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_MV_ALG_DEFAULT: cusparseSpMVAlg_t = cusparseSpMVAlg_t(0); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_COOMV_ALG: cusparseSpMVAlg_t = cusparseSpMVAlg_t(1); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_CSRMV_ALG1: cusparseSpMVAlg_t = cusparseSpMVAlg_t(2); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_CSRMV_ALG2: cusparseSpMVAlg_t = cusparseSpMVAlg_t(3); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_SPMV_ALG_DEFAULT: cusparseSpMVAlg_t = cusparseSpMVAlg_t(0); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_SPMV_CSR_ALG1: cusparseSpMVAlg_t = cusparseSpMVAlg_t(2); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_SPMV_CSR_ALG2: cusparseSpMVAlg_t = cusparseSpMVAlg_t(3); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_SPMV_COO_ALG1: cusparseSpMVAlg_t = cusparseSpMVAlg_t(1); +} +impl cusparseSpMVAlg_t { + pub const CUSPARSE_SPMV_COO_ALG2: cusparseSpMVAlg_t = cusparseSpMVAlg_t(4); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpMVAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMV( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + vecX: cusparseDnVecDescr_t, + beta: *const ::std::os::raw::c_void, + vecY: cusparseDnVecDescr_t, + computeType: cudaDataType, + alg: cusparseSpMVAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::spmv( + handle, + opA, + alpha, + matA, + vecX, + beta, + vecY, + computeType, + alg, + externalBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMV_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + vecX: cusparseDnVecDescr_t, + beta: *const ::std::os::raw::c_void, + vecY: cusparseDnVecDescr_t, + computeType: cudaDataType, + alg: cusparseSpMVAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::spmv_buffersize( + handle, + opA, + alpha, + matA, + vecX, + beta, + vecY, + computeType, + alg, + bufferSize, + ) +} +impl cusparseSpSVAlg_t { + pub const CUSPARSE_SPSV_ALG_DEFAULT: cusparseSpSVAlg_t = cusparseSpSVAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpSVAlg_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpSVDescr { + _unused: [u8; 0], +} +pub type cusparseSpSVDescr_t = *mut cusparseSpSVDescr; + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSV_createDescr( + descr: *mut cusparseSpSVDescr_t, +) -> cusparseStatus_t { + crate::spsv_create_descr(descr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSV_destroyDescr( + descr: cusparseSpSVDescr_t, +) -> cusparseStatus_t { + crate::spsv_drstroy_desc(descr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSV_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + vecX: cusparseDnVecDescr_t, + vecY: cusparseDnVecDescr_t, + computeType: cudaDataType, + alg: cusparseSpSVAlg_t, + spsvDescr: cusparseSpSVDescr_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::spsv_buffersize( + handle, + opA, + alpha, + matA, + vecX, + vecY, + computeType, + alg, + spsvDescr, + bufferSize, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSV_analysis( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + vecX: cusparseDnVecDescr_t, + vecY: cusparseDnVecDescr_t, + computeType: cudaDataType, + alg: cusparseSpSVAlg_t, + spsvDescr: cusparseSpSVDescr_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::spsv_analysis( + handle, + opA, + alpha, + matA, + vecX, + vecY, + computeType, + alg, + spsvDescr, + externalBuffer, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSV_solve( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + vecX: cusparseDnVecDescr_t, + vecY: cusparseDnVecDescr_t, + computeType: cudaDataType, + alg: cusparseSpSVAlg_t, + spsvDescr: cusparseSpSVDescr_t, +) -> cusparseStatus_t { + crate::spsv_solve( + handle, + opA, + alpha, + matA, + vecX, + vecY, + computeType, + alg, + spsvDescr, + ) +} +impl cusparseSpSMAlg_t { + pub const CUSPARSE_SPSM_ALG_DEFAULT: cusparseSpSMAlg_t = cusparseSpSMAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpSMAlg_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpSMDescr { + _unused: [u8; 0], +} +pub type cusparseSpSMDescr_t = *mut cusparseSpSMDescr; + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSM_createDescr( + descr: *mut cusparseSpSMDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSM_destroyDescr( + descr: cusparseSpSMDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSM_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpSMAlg_t, + spsmDescr: cusparseSpSMDescr_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSM_analysis( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpSMAlg_t, + spsmDescr: cusparseSpSMDescr_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpSM_solve( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpSMAlg_t, + spsmDescr: cusparseSpSMDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_MM_ALG_DEFAULT: cusparseSpMMAlg_t = cusparseSpMMAlg_t(0); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_COOMM_ALG1: cusparseSpMMAlg_t = cusparseSpMMAlg_t(1); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_COOMM_ALG2: cusparseSpMMAlg_t = cusparseSpMMAlg_t(2); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_COOMM_ALG3: cusparseSpMMAlg_t = cusparseSpMMAlg_t(3); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_CSRMM_ALG1: cusparseSpMMAlg_t = cusparseSpMMAlg_t(4); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_ALG_DEFAULT: cusparseSpMMAlg_t = cusparseSpMMAlg_t(0); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_COO_ALG1: cusparseSpMMAlg_t = cusparseSpMMAlg_t(1); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_COO_ALG2: cusparseSpMMAlg_t = cusparseSpMMAlg_t(2); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_COO_ALG3: cusparseSpMMAlg_t = cusparseSpMMAlg_t(3); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_COO_ALG4: cusparseSpMMAlg_t = cusparseSpMMAlg_t(5); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_CSR_ALG1: cusparseSpMMAlg_t = cusparseSpMMAlg_t(4); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_CSR_ALG2: cusparseSpMMAlg_t = cusparseSpMMAlg_t(6); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_CSR_ALG3: cusparseSpMMAlg_t = cusparseSpMMAlg_t(12); +} +impl cusparseSpMMAlg_t { + pub const CUSPARSE_SPMM_BLOCKED_ELL_ALG1: cusparseSpMMAlg_t = cusparseSpMMAlg_t(13); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpMMAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMM_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpMMAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMM_preprocess( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpMMAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMM( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpMMAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSpGEMMAlg_t { + pub const CUSPARSE_SPGEMM_DEFAULT: cusparseSpGEMMAlg_t = cusparseSpGEMMAlg_t(0); +} +impl cusparseSpGEMMAlg_t { + pub const CUSPARSE_SPGEMM_CSR_ALG_DETERMINITIC: cusparseSpGEMMAlg_t = cusparseSpGEMMAlg_t(1); +} +impl cusparseSpGEMMAlg_t { + pub const CUSPARSE_SPGEMM_CSR_ALG_NONDETERMINITIC: cusparseSpGEMMAlg_t = cusparseSpGEMMAlg_t(2); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpGEMMAlg_t(pub ::std::os::raw::c_uint); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpGEMMDescr { + _unused: [u8; 0], +} +pub type cusparseSpGEMMDescr_t = *mut cusparseSpGEMMDescr; + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMM_createDescr( + descr: *mut cusparseSpGEMMDescr_t, +) -> cusparseStatus_t { + crate::spgemm_create_descr(descr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMM_destroyDescr( + descr: cusparseSpGEMMDescr_t, +) -> cusparseStatus_t { + crate::spgemm_destroy_desc(descr) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMM_workEstimation( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, + bufferSize1: *mut usize, + externalBuffer1: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMM_compute( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, + bufferSize2: *mut usize, + externalBuffer2: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMM_copy( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMMreuse_workEstimation( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + matC: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, + bufferSize1: *mut usize, + externalBuffer1: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::spgemm_reuse_workestimation( + handle, + opA, + opB, + matA, + matB, + matC, + alg, + spgemmDescr, + bufferSize1, + externalBuffer1, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMMreuse_nnz( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + matC: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, + bufferSize2: *mut usize, + externalBuffer2: *mut ::std::os::raw::c_void, + bufferSize3: *mut usize, + externalBuffer3: *mut ::std::os::raw::c_void, + bufferSize4: *mut usize, + externalBuffer4: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::spgemm_reuse_nnz( + handle, + opA, + opB, + matA, + matB, + matC, + alg, + spgemmDescr, + bufferSize2, + externalBuffer2, + bufferSize3, + externalBuffer3, + bufferSize4, + externalBuffer4, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMMreuse_copy( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + matC: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, + bufferSize5: *mut usize, + externalBuffer5: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::spgemm_reuse_copy( + handle, + opA, + opB, + matA, + matB, + matC, + alg, + spgemmDescr, + bufferSize5, + externalBuffer5, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpGEMMreuse_compute( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseSpMatDescr_t, + matB: cusparseSpMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpGEMMAlg_t, + spgemmDescr: cusparseSpGEMMDescr_t, +) -> cusparseStatus_t { + crate::spgemm_reuse_compute( + handle, + opA, + opB, + alpha, + matA, + matB, + beta, + matC, + computeType, + alg, + spgemmDescr, + ) +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseConstrainedGeMM( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseDnMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseConstrainedGeMM_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseDnMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} +impl cusparseSDDMMAlg_t { + pub const CUSPARSE_SDDMM_ALG_DEFAULT: cusparseSDDMMAlg_t = cusparseSDDMMAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSDDMMAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSDDMM_bufferSize( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseDnMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSDDMMAlg_t, + bufferSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSDDMM_preprocess( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseDnMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSDDMMAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSDDMM( + handle: cusparseHandle_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + alpha: *const ::std::os::raw::c_void, + matA: cusparseDnMatDescr_t, + matB: cusparseDnMatDescr_t, + beta: *const ::std::os::raw::c_void, + matC: cusparseSpMatDescr_t, + computeType: cudaDataType, + alg: cusparseSDDMMAlg_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct cusparseSpMMOpPlan { + _unused: [u8; 0], +} +pub type cusparseSpMMOpPlan_t = *mut cusparseSpMMOpPlan; +impl cusparseSpMMOpAlg_t { + pub const CUSPARSE_SPMM_OP_ALG_DEFAULT: cusparseSpMMOpAlg_t = cusparseSpMMOpAlg_t(0); +} +#[repr(transparent)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct cusparseSpMMOpAlg_t(pub ::std::os::raw::c_uint); + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMMOp_createPlan( + handle: cusparseHandle_t, + plan: *mut cusparseSpMMOpPlan_t, + opA: cusparseOperation_t, + opB: cusparseOperation_t, + matA: cusparseSpMatDescr_t, + matB: cusparseDnMatDescr_t, + matC: cusparseDnMatDescr_t, + computeType: cudaDataType, + alg: cusparseSpMMOpAlg_t, + addOperationNvvmBuffer: *const ::std::os::raw::c_void, + addOperationBufferSize: usize, + mulOperationNvvmBuffer: *const ::std::os::raw::c_void, + mulOperationBufferSize: usize, + epilogueNvvmBuffer: *const ::std::os::raw::c_void, + epilogueBufferSize: usize, + SpMMWorkspaceSize: *mut usize, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMMOp( + plan: cusparseSpMMOpPlan_t, + externalBuffer: *mut ::std::os::raw::c_void, +) -> cusparseStatus_t { + crate::unsupported() +} + +#[no_mangle] +pub unsafe extern "system" fn cusparseSpMMOp_destroyPlan( + plan: cusparseSpMMOpPlan_t, +) -> cusparseStatus_t { + crate::unsupported() +} diff --git a/zluda_sparse/src/lib.rs b/zluda_sparse/src/lib.rs new file mode 100644 index 0000000..442963f --- /dev/null +++ b/zluda_sparse/src/lib.rs @@ -0,0 +1,1289 @@ +#![allow(warnings)] +mod cusparse; +pub use cusparse::*; + +use cuda_types::*; +use rocsparse_sys::*; +use std::{ffi::c_void, mem, ptr}; + +macro_rules! call { + ($expr:expr) => { + #[allow(unused_unsafe)] + { + unsafe { + let result = $expr; + if result != rocsparse_sys::rocsparse_status::rocsparse_status_success { + return to_cuda(result); + } + } + } + }; +} + +#[cfg(debug_assertions)] +pub(crate) fn unsupported() -> cusparseStatus_t { + unimplemented!() +} + +#[cfg(not(debug_assertions))] +pub(crate) fn unsupported() -> cusparseStatus_t { + cusparseStatus_t::CUSPARSE_STATUS_NOT_SUPPORTED +} + +// TODO: be more thorough +fn to_cuda(status: rocsparse_status) -> cusparseStatus_t { + match status { + rocsparse_status::rocsparse_status_success => cusparseStatus_t::CUSPARSE_STATUS_SUCCESS, + _ => cusparseStatus_t::CUSPARSE_STATUS_INTERNAL_ERROR, + } +} + +unsafe fn create(handle: *mut *mut cusparseContext) -> cusparseStatus_t { + to_cuda(rocsparse_create_handle(handle as _)) +} + +unsafe fn create_csr( + descr: *mut cusparseSpMatDescr_t, + rows: i64, + cols: i64, + nnz: i64, + csr_row_offsets: *mut std::ffi::c_void, + csr_col_ind: *mut std::ffi::c_void, + csr_values: *mut std::ffi::c_void, + csr_row_offsets_type: cusparseIndexType_t, + csr_col_ind_type: cusparseIndexType_t, + idx_base: cusparseIndexBase_t, + value_type: cudaDataType_t, +) -> cusparseStatus_t { + let csr_row_offsets_type = index_type(csr_row_offsets_type); + let csr_col_ind_type = index_type(csr_col_ind_type); + let idx_base = index_base(idx_base); + let value_type = data_type(value_type); + to_cuda(rocsparse_create_csr_descr( + descr as _, + rows, + cols, + nnz, + csr_row_offsets, + csr_col_ind, + csr_values, + csr_row_offsets_type, + csr_col_ind_type, + idx_base, + value_type, + )) +} + +fn data_type(data_type: cudaDataType_t) -> rocsparse_datatype { + match data_type { + cudaDataType_t::CUDA_R_32F => rocsparse_datatype::rocsparse_datatype_f32_r, + cudaDataType_t::CUDA_R_64F => rocsparse_datatype::rocsparse_datatype_f64_r, + cudaDataType_t::CUDA_C_32F => rocsparse_datatype::rocsparse_datatype_f32_c, + cudaDataType_t::CUDA_C_64F => rocsparse_datatype::rocsparse_datatype_f64_c, + cudaDataType_t::CUDA_R_8I => rocsparse_datatype::rocsparse_datatype_i8_r, + cudaDataType_t::CUDA_R_8U => rocsparse_datatype::rocsparse_datatype_u8_r, + cudaDataType_t::CUDA_R_32I => rocsparse_datatype::rocsparse_datatype_i32_r, + cudaDataType_t::CUDA_R_32U => rocsparse_datatype::rocsparse_datatype_u32_r, + _ => panic!(), + } +} + +fn index_type(index_type: cusparseIndexType_t) -> rocsparse_indextype { + match index_type { + cusparseIndexType_t::CUSPARSE_INDEX_16U => rocsparse_indextype::rocsparse_indextype_u16, + cusparseIndexType_t::CUSPARSE_INDEX_32I => rocsparse_indextype::rocsparse_indextype_i32, + cusparseIndexType_t::CUSPARSE_INDEX_64I => rocsparse_indextype::rocsparse_indextype_i64, + _ => panic!(), + } +} + +fn index_base(index_base: cusparseIndexBase_t) -> rocsparse_index_base { + match index_base { + cusparseIndexBase_t::CUSPARSE_INDEX_BASE_ZERO => { + rocsparse_index_base::rocsparse_index_base_zero + } + cusparseIndexBase_t::CUSPARSE_INDEX_BASE_ONE => { + rocsparse_index_base::rocsparse_index_base_one + } + _ => panic!(), + } +} + +unsafe fn create_csrsv2_info(info: *mut *mut csrsv2Info) -> cusparseStatus_t { + to_cuda(rocsparse_create_mat_info(info.cast())) +} + +unsafe fn create_dn_vec( + dn_vec_descr: *mut *mut cusparseDnVecDescr, + size: i64, + values: *mut std::ffi::c_void, + value_type: cudaDataType_t, +) -> cusparseStatus_t { + let value_type = data_type(value_type); + to_cuda(rocsparse_create_dnvec_descr( + dn_vec_descr.cast(), + size, + values, + value_type, + )) +} + +unsafe fn create_mat_descr(descr_a: *mut *mut cusparseMatDescr) -> cusparseStatus_t { + to_cuda(rocsparse_create_mat_descr(descr_a.cast())) +} + +unsafe fn destroy_mat_descr(descr_a: *mut cusparseMatDescr) -> cusparseStatus_t { + to_cuda(rocsparse_destroy_mat_descr(descr_a.cast())) +} + +unsafe fn dcsr_sv2_analysis( + handle: *mut cusparseContext, + trans_a: cusparseOperation_t, + m: i32, + nnz: i32, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a: *const f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrsv2Info, + policy: cusparseSolvePolicy_t, + p_buffer: *mut std::ffi::c_void, +) -> cusparseStatus_t { + let trans_a = operation(trans_a); + let (analysis, solve) = to_policy(policy); + to_cuda(rocsparse_dcsrsv_analysis( + handle.cast(), + trans_a, + m, + nnz, + descr_a.cast(), + csr_sorted_val_a, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + analysis, + solve, + p_buffer, + )) +} + +fn to_policy(policy: cusparseSolvePolicy_t) -> (rocsparse_analysis_policy, rocsparse_solve_policy) { + match policy { + cusparseSolvePolicy_t::CUSPARSE_SOLVE_POLICY_NO_LEVEL => ( + rocsparse_analysis_policy::rocsparse_analysis_policy_reuse, + rocsparse_solve_policy::rocsparse_solve_policy_auto, + ), + cusparseSolvePolicy_t::CUSPARSE_SOLVE_POLICY_USE_LEVEL => ( + rocsparse_analysis_policy::rocsparse_analysis_policy_reuse, + rocsparse_solve_policy::rocsparse_solve_policy_auto, + ), + _ => panic!(), + } +} + +fn operation(op: cusparseOperation_t) -> rocsparse_operation { + match op { + cusparseOperation_t::CUSPARSE_OPERATION_NON_TRANSPOSE => { + rocsparse_operation::rocsparse_operation_none + } + cusparseOperation_t::CUSPARSE_OPERATION_TRANSPOSE => { + rocsparse_operation::rocsparse_operation_transpose + } + cusparseOperation_t::CUSPARSE_OPERATION_CONJUGATE_TRANSPOSE => { + rocsparse_operation::rocsparse_operation_conjugate_transpose + } + _ => panic!(), + } +} + +unsafe fn dcsr_sv2_buffersize( + handle: *mut cusparseContext, + trans_a: cusparseOperation_t, + m: i32, + nnz: i32, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a: *mut f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrsv2Info, + p_buffer_size_in_bytes: *mut i32, +) -> cusparseStatus_t { + let trans_a = operation(trans_a); + let mut size = *p_buffer_size_in_bytes as usize; + let result = to_cuda(rocsparse_dcsrsv_buffer_size( + handle.cast(), + trans_a, + m, + nnz, + descr_a.cast(), + csr_sorted_val_a, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + &mut size as *mut usize, + )); + if size > i32::MAX as usize { + return cusparseStatus_t::CUSPARSE_STATUS_INSUFFICIENT_RESOURCES; + } + *p_buffer_size_in_bytes = size as i32; + result +} + +unsafe fn dcsr_sv2_solve( + handle: *mut cusparseContext, + trans_a: cusparseOperation_t, + m: i32, + nnz: i32, + alpha: *const f64, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a: *const f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrsv2Info, + f: *const f64, + x: *mut f64, + policy: cusparseSolvePolicy_t, + p_buffer: *mut std::ffi::c_void, +) -> cusparseStatus_t { + let trans_a = operation(trans_a); + let (_, policy) = to_policy(policy); + to_cuda(rocsparse_dcsrsv_solve( + handle.cast(), + trans_a, + m, + nnz, + alpha, + descr_a.cast(), + csr_sorted_val_a, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + f, + x, + policy, + p_buffer, + )) +} + +unsafe fn dnvec_set_values( + dn_vec_descr: *mut cusparseDnVecDescr, + values: *mut std::ffi::c_void, +) -> cusparseStatus_t { + to_cuda(rocsparse_dnvec_set_values(dn_vec_descr.cast(), values)) +} + +unsafe fn get_mat_diag_type(descr_a: *mut cusparseMatDescr) -> cusparseDiagType_t { + diag_type(rocsparse_get_mat_diag_type(descr_a.cast())) +} + +fn diag_type(diag_type: rocsparse_diag_type) -> cusparseDiagType_t { + match diag_type { + rocsparse_diag_type::rocsparse_diag_type_non_unit => { + cusparseDiagType_t::CUSPARSE_DIAG_TYPE_NON_UNIT + } + rocsparse_diag_type::rocsparse_diag_type_unit => { + cusparseDiagType_t::CUSPARSE_DIAG_TYPE_UNIT + } + _ => panic!(), + } +} + +unsafe fn set_mat_diag_type( + descr_a: *mut cusparseMatDescr, + diag_type: cusparseDiagType_t, +) -> cusparseStatus_t { + to_cuda(rocsparse_set_mat_diag_type( + descr_a.cast(), + diag_type_reverse(diag_type), + )) +} + +fn diag_type_reverse(diag_type: cusparseDiagType_t) -> rocsparse_diag_type { + match diag_type { + cusparseDiagType_t::CUSPARSE_DIAG_TYPE_NON_UNIT => { + rocsparse_diag_type::rocsparse_diag_type_non_unit + } + cusparseDiagType_t::CUSPARSE_DIAG_TYPE_UNIT => { + rocsparse_diag_type::rocsparse_diag_type_unit + } + _ => panic!(), + } +} + +unsafe fn get_mat_fill_mode(descr_a: *mut cusparseMatDescr) -> cusparseFillMode_t { + fill_mode(rocsparse_get_mat_fill_mode(descr_a.cast())) +} + +fn fill_mode(fill_mode: rocsparse_fill_mode) -> cusparseFillMode_t { + match fill_mode { + rocsparse_fill_mode::rocsparse_fill_mode_lower => { + cusparseFillMode_t::CUSPARSE_FILL_MODE_LOWER + } + rocsparse_fill_mode::rocsparse_fill_mode_upper => { + cusparseFillMode_t::CUSPARSE_FILL_MODE_UPPER + } + _ => panic!(), + } +} + +unsafe fn set_mat_fill_mode( + descr_a: *mut cusparseMatDescr, + fill_mode: cusparseFillMode_t, +) -> cusparseStatus_t { + to_cuda(rocsparse_set_mat_fill_mode( + descr_a.cast(), + fill_mode_reverse(fill_mode), + )) +} + +fn fill_mode_reverse(fill_mode: cusparseFillMode_t) -> rocsparse_fill_mode { + match fill_mode { + cusparseFillMode_t::CUSPARSE_FILL_MODE_LOWER => { + rocsparse_fill_mode::rocsparse_fill_mode_lower + } + cusparseFillMode_t::CUSPARSE_FILL_MODE_UPPER => { + rocsparse_fill_mode::rocsparse_fill_mode_upper + } + _ => panic!(), + } +} + +unsafe fn get_pointer_mode( + handle: *mut cusparseContext, + mode: *mut cusparsePointerMode_t, +) -> cusparseStatus_t { + let mut pointer_mode = mem::zeroed(); + let result = to_cuda(rocsparse_get_pointer_mode(handle.cast(), &mut pointer_mode)); + if result != cusparseStatus_t::CUSPARSE_STATUS_SUCCESS { + return result; + } + *mode = to_pointer_mode(pointer_mode); + result +} + +fn to_pointer_mode(pointer_mode: rocsparse_pointer_mode) -> cusparsePointerMode_t { + match pointer_mode { + rocsparse_pointer_mode::rocsparse_pointer_mode_host => { + cusparsePointerMode_t::CUSPARSE_POINTER_MODE_HOST + } + rocsparse_pointer_mode::rocsparse_pointer_mode_device => { + cusparsePointerMode_t::CUSPARSE_POINTER_MODE_DEVICE + } + _ => panic!(), + } +} + +unsafe fn set_pointer_mode( + handle: *mut cusparseContext, + mode: cusparsePointerMode_t, +) -> cusparseStatus_t { + to_cuda(rocsparse_set_pointer_mode( + handle.cast(), + to_pointer_mode_reverse(mode), + )) +} + +fn to_pointer_mode_reverse(pointer_mode: cusparsePointerMode_t) -> rocsparse_pointer_mode { + match pointer_mode { + cusparsePointerMode_t::CUSPARSE_POINTER_MODE_HOST => { + rocsparse_pointer_mode::rocsparse_pointer_mode_host + } + cusparsePointerMode_t::CUSPARSE_POINTER_MODE_DEVICE => { + rocsparse_pointer_mode::rocsparse_pointer_mode_device + } + _ => panic!(), + } +} + +unsafe fn set_mat_index_base( + descr_a: *mut cusparseMatDescr, + base: cusparseIndexBase_t, +) -> cusparseStatus_t { + to_cuda(rocsparse_set_mat_index_base( + descr_a.cast(), + index_base(base), + )) +} + +unsafe fn set_mat_type( + descr_a: *mut cusparseMatDescr, + type_: cusparseMatrixType_t, +) -> cusparseStatus_t { + to_cuda(rocsparse_set_mat_type(descr_a.cast(), matrix_type(type_))) +} + +fn matrix_type(type_: cusparseMatrixType_t) -> rocsparse_matrix_type_ { + match type_ { + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_GENERAL => { + rocsparse_matrix_type_::rocsparse_matrix_type_general + } + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_SYMMETRIC => { + rocsparse_matrix_type_::rocsparse_matrix_type_symmetric + } + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_HERMITIAN => { + rocsparse_matrix_type_::rocsparse_matrix_type_hermitian + } + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_TRIANGULAR => { + rocsparse_matrix_type_::rocsparse_matrix_type_triangular + } + _ => panic!(), + } +} + +unsafe fn set_stream(handle: *mut cusparseContext, stream_id: CUstream) -> cusparseStatus_t { + let lib = hip_common::zluda_ext::get_cuda_library().unwrap(); + let cu_get_export_table = lib + .get:: CUresult>(b"cuGetExportTable\0") + .unwrap(); + let mut export_table = ptr::null(); + (cu_get_export_table)(&mut export_table, &zluda_dark_api::ZludaExt::GUID); + let zluda_ext = zluda_dark_api::ZludaExt::new(export_table); + let stream: Result<_, _> = zluda_ext.get_hip_stream(stream_id as _).into(); + to_cuda(rocsparse_set_stream(handle as _, stream.unwrap() as _)) +} + +unsafe fn spmv( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + alpha: *const std::ffi::c_void, + mat_a: cusparseSpMatDescr_t, + vec_x: *mut cusparseDnVecDescr, + beta: *const std::ffi::c_void, + vec_y: *mut cusparseDnVecDescr, + compute_type: cudaDataType_t, + alg: cusparseSpMVAlg_t, + external_buffer: *mut std::ffi::c_void, +) -> cusparseStatus_t { + let op_a = operation(op_a); + let compute_type = data_type(compute_type); + let alg = to_spmv_alg(alg); + // divide by 2 in case there's any arithmetic done on it + let mut size = usize::MAX / 2; + to_cuda(rocsparse_spmv( + handle.cast(), + op_a, + alpha, + mat_a.cast(), + vec_x.cast(), + beta, + vec_y.cast(), + compute_type, + alg, + &mut size, + external_buffer, + )) +} + +unsafe fn spmv_buffersize( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + alpha: *const std::ffi::c_void, + mat_a: cusparseSpMatDescr_t, + vec_x: *mut cusparseDnVecDescr, + beta: *const std::ffi::c_void, + vec_y: *mut cusparseDnVecDescr, + compute_type: cudaDataType_t, + alg: cusparseSpMVAlg_t, + buffer_size: *mut usize, +) -> cusparseStatus_t { + let op_a = operation(op_a); + let compute_type = data_type(compute_type); + let alg = to_spmv_alg(alg); + to_cuda(rocsparse_spmv( + handle.cast(), + op_a, + alpha, + mat_a.cast(), + vec_x.cast(), + beta, + vec_y.cast(), + compute_type, + alg, + buffer_size, + ptr::null_mut(), + )) +} + +fn to_spmv_alg(alg: cusparseSpMVAlg_t) -> rocsparse_spmv_alg { + match alg { + cusparseSpMVAlg_t::CUSPARSE_SPMV_ALG_DEFAULT => { + rocsparse_spmv_alg::rocsparse_spmv_alg_default + } + cusparseSpMVAlg_t::CUSPARSE_SPMV_COO_ALG1 => rocsparse_spmv_alg::rocsparse_spmv_alg_coo, + cusparseSpMVAlg_t::CUSPARSE_SPMV_CSR_ALG1 => { + rocsparse_spmv_alg::rocsparse_spmv_alg_csr_adaptive + } + cusparseSpMVAlg_t::CUSPARSE_SPMV_CSR_ALG2 => { + rocsparse_spmv_alg::rocsparse_spmv_alg_csr_stream + } + cusparseSpMVAlg_t::CUSPARSE_SPMV_COO_ALG2 => { + rocsparse_spmv_alg::rocsparse_spmv_alg_coo_atomic + } + // other vlaues definied by cuSPARSE are aliases + _ => panic!(), + } +} + +unsafe fn destroy_sp_mat(sp_mat_descr: cusparseSpMatDescr_t) -> cusparseStatus_t { + if sp_mat_descr == ptr::null_mut() { + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } else { + to_cuda(rocsparse_destroy_spmat_descr(sp_mat_descr.cast())) + } +} + +unsafe fn spgemm_create_descr(descr: *mut *mut cusparseSpGEMMDescr) -> cusparseStatus_t { + *(descr.cast()) = Box::into_raw(Box::new(SPGEMMDescr { + temp_buffer_size: 0, + temp_buffer: ptr::null_mut(), + external_buffer3: ptr::null_mut(), + })); + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +struct SPGEMMDescr { + temp_buffer_size: usize, + temp_buffer: *mut c_void, + external_buffer3: *mut c_void, +} + +// If the case where we are doing spgemm and the C matrix has only NULL pointers, and +// we _must_ support it (for example petsc relies on this behavior), then: +// * `rocsparse_spgemm(..., rocsparse_spgemm_stage_nnz, ...)` fails because row pointer is NULL +// * If we try to set and unset pointers through `rocsparse_csr_set_pointers(...)` this fails because two other pointers are NULL +// * If we try to create whole new matrix C', this also fails, because there are some private fields that are set +// during `rocsparse_spgemm(..., rocsparse_spgemm_stage_buffer_size, ...)` +// * Another solution: creating a fake C' matrix during `rocsparse_spgemm(..., rocsparse_spgemm_stage_buffer_size, ...)` +// and actually using it during `rocsparse_spgemm(..., rocsparse_spgemm_stage_nnz, ...)`, this has the problem that +// there's no way to copy internal fields from C' to C +// * All that's left is to YOLO it and start touching matrix descriptor internals +#[repr(C)] +struct rocsparse_spmat_descr_internal { + init: bool, + analysed: bool, + + rows: i64, + cols: i64, + nnz: i64, + + row_data: *mut c_void, + col_data: *mut c_void, + ind_data: *mut c_void, + val_data: *mut c_void, +} + +unsafe fn spgemm_destroy_desc(descr: cusparseSpGEMMDescr_t) -> cusparseStatus_t { + Box::from_raw(descr.cast::()); + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +unsafe fn spgemm_reuse_workestimation( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + op_b: cusparseOperation_t, + mat_a: cusparseSpMatDescr_t, + mat_b: cusparseSpMatDescr_t, + mat_c: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemm_descr: *mut cusparseSpGEMMDescr, + buffer_size1: *mut usize, + external_buffer1: *mut std::ffi::c_void, +) -> cusparseStatus_t { + if external_buffer1 == ptr::null_mut() { + *buffer_size1 = 1; + /* + let mut c_rows = 0; + let mut c_row_ptr = ptr::null_mut(); + let mut data_type = rocsparse_datatype(0); + let error = to_cuda(rocsparse_csr_get( + mat_c.cast(), + &mut c_rows, + &mut 0, + &mut 0, + &mut c_row_ptr, + &mut ptr::null_mut(), + &mut ptr::null_mut(), + &mut rocsparse_indextype(0), + &mut rocsparse_indextype(0), + &mut rocsparse_index_base(0), + &mut data_type, + )); + if error != cusparseStatus_t::CUSPARSE_STATUS_SUCCESS { + return error; + } + *buffer_size1 = if c_row_ptr == ptr::null_mut() { + (c_rows + 1) as usize * element_size(data_type) + } else { + 1 + }; + */ + } else { + /* + let spgemm_descr = spgemm_descr.cast::().as_mut().unwrap(); + spgemm_descr.external_buffer1 = external_buffer1; + */ + } + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +unsafe fn spgemm_reuse_nnz( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + op_b: cusparseOperation_t, + mat_a: cusparseSpMatDescr_t, + mat_b: cusparseSpMatDescr_t, + mat_c: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemm_descr: *mut cusparseSpGEMMDescr, + buffer_size2: *mut usize, + external_buffer2: *mut std::ffi::c_void, + buffer_size3: *mut usize, + external_buffer3: *mut std::ffi::c_void, + buffer_size4: *mut usize, + external_buffer4: *mut std::ffi::c_void, +) -> cusparseStatus_t { + if external_buffer2 == ptr::null_mut() { + *buffer_size2 = 1; + } + let op_a = operation(op_a); + let op_b = operation(op_b); + let mut data_type = rocsparse_datatype(0); + // rocSPARSE checks later if mat_a, mat_b and mat_c are the same data type + let mut c_rows = 0; + let mut c_cols = 0; + let mut c_nnz = 0; + let mut c_row_ptr = ptr::null_mut(); + let mut c_col_ind = ptr::null_mut(); + let mut c_val = ptr::null_mut(); + let mut c_row_ptr_type = rocsparse_indextype::rocsparse_indextype_i32; + let mut c_col_ind_type = rocsparse_indextype::rocsparse_indextype_i32; + let mut c_idx_base = rocsparse_index_base::rocsparse_index_base_zero; + call! { rocsparse_csr_get( + mat_c.cast(), + &mut c_rows, + &mut c_cols, + &mut c_nnz, + &mut c_row_ptr, + &mut c_col_ind, + &mut c_val, + &mut c_row_ptr_type, + &mut c_col_ind_type, + &mut c_idx_base, + &mut data_type, + ) }; + if external_buffer3 == ptr::null_mut() { + *buffer_size3 = (c_rows + 1) as usize * element_size(c_row_ptr_type); + } + let spgemm_descr = spgemm_descr.cast::().as_mut().unwrap(); + let stage = if external_buffer4 == ptr::null_mut() { + rocsparse_spgemm_stage::rocsparse_spgemm_stage_buffer_size + } else { + if c_row_ptr == ptr::null_mut() { + let mat_c = mat_c + .cast::() + .as_mut() + .unwrap(); + assert_eq!(mat_c.row_data, ptr::null_mut()); + mat_c.row_data = external_buffer3; + spgemm_descr.external_buffer3 = external_buffer3; + } + rocsparse_spgemm_stage::rocsparse_spgemm_stage_nnz + }; + let temp_scalar = std::f64::consts::PI; + call! { rocsparse_spgemm( + handle.cast(), + op_a, + op_b, + &temp_scalar as *const _ as *const _, + mat_a.cast(), + mat_b.cast(), + &temp_scalar as *const _ as *const _, + mat_c.cast(), + mat_c.cast(), + data_type, + rocsparse_spgemm_alg::rocsparse_spgemm_alg_default, + stage, + buffer_size4, + external_buffer4, + ) }; + if stage == rocsparse_spgemm_stage::rocsparse_spgemm_stage_nnz { + if c_row_ptr == ptr::null_mut() { + let mat_c = mat_c + .cast::() + .as_mut() + .unwrap(); + assert_eq!(mat_c.row_data, external_buffer3); + mat_c.row_data = ptr::null_mut(); + } + spgemm_descr.temp_buffer_size = *buffer_size4; + spgemm_descr.temp_buffer = external_buffer4; + } + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +fn element_size(data_type: rocsparse_indextype) -> usize { + match data_type { + rocsparse_indextype::rocsparse_indextype_u16 => 2, + rocsparse_indextype::rocsparse_indextype_i32 => 4, + rocsparse_indextype::rocsparse_indextype_i64 => 8, + _ => panic!(), + } +} + +unsafe fn spgemm_reuse_copy( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + op_b: cusparseOperation_t, + mat_a: cusparseSpMatDescr_t, + mat_b: cusparseSpMatDescr_t, + mat_c: cusparseSpMatDescr_t, + alg: cusparseSpGEMMAlg_t, + spgemm_descr: *mut cusparseSpGEMMDescr, + buffer_size5: *mut usize, + external_buffer5: *mut std::ffi::c_void, +) -> cusparseStatus_t { + if external_buffer5 == ptr::null_mut() { + *buffer_size5 = 1; + } + let spgemm_descr = spgemm_descr.cast::().as_ref().unwrap(); + if spgemm_descr.external_buffer3 != ptr::null_mut() { + let mut c_rows = 0; + let mut c_row_ptr = ptr::null_mut(); + let mut c_row_ptr_type = rocsparse_indextype(0); + call! { rocsparse_csr_get( + mat_c.cast(), + &mut c_rows, + &mut 0, + &mut 0, + &mut c_row_ptr, + &mut ptr::null_mut(), + &mut ptr::null_mut(), + &mut c_row_ptr_type, + &mut rocsparse_indextype(0), + &mut rocsparse_index_base(0), + &mut rocsparse_datatype(0), + ) }; + if c_row_ptr != ptr::null_mut() { + let size: usize = (c_rows + 1) as usize * element_size(c_row_ptr_type); + let mut hip_stream = ptr::null_mut(); + call! { rocsparse_get_stream(handle.cast(), &mut hip_stream) }; + let error = hip_runtime_sys::hipMemcpyAsync( + c_row_ptr, + spgemm_descr.external_buffer3, + size, + hip_runtime_sys::hipMemcpyKind::hipMemcpyDefault, + hip_stream.cast(), + ); + if error != hip_runtime_sys::hipError_t::hipSuccess { + return cusparseStatus_t::CUSPARSE_STATUS_INTERNAL_ERROR; + } + } + } + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +unsafe fn spgemm_reuse_compute( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + op_b: cusparseOperation_t, + alpha: *const std::ffi::c_void, + mat_a: cusparseSpMatDescr_t, + mat_b: cusparseSpMatDescr_t, + beta: *const std::ffi::c_void, + mat_c: cusparseSpMatDescr_t, + compute_type: cudaDataType, + alg: cusparseSpGEMMAlg_t, + spgemm_descr: *mut cusparseSpGEMMDescr, +) -> cusparseStatus_t { + let spgemm_descr = spgemm_descr.cast::().as_ref(); + let spgemm_descr = match spgemm_descr { + Some(x) => x, + None => return cusparseStatus_t::CUSPARSE_STATUS_INVALID_VALUE, + }; + let op_a = operation(op_a); + let op_b = operation(op_b); + let compute_type = to_datatype(compute_type); + let mut temp_buffer_size = spgemm_descr.temp_buffer_size; + to_cuda(rocsparse_spgemm( + handle.cast(), + op_a, + op_b, + alpha, + mat_a.cast(), + mat_b.cast(), + beta, + mat_c.cast(), + mat_c.cast(), + compute_type, + rocsparse_spgemm_alg::rocsparse_spgemm_alg_default, + rocsparse_spgemm_stage::rocsparse_spgemm_stage_compute, + &mut temp_buffer_size, + spgemm_descr.temp_buffer, + )) +} + +fn to_datatype(compute_type: cudaDataType) -> rocsparse_datatype { + match compute_type { + cudaDataType::CUDA_R_32F => rocsparse_datatype::rocsparse_datatype_f32_r, + cudaDataType::CUDA_R_64F => rocsparse_datatype::rocsparse_datatype_f64_r, + cudaDataType::CUDA_C_32F => rocsparse_datatype::rocsparse_datatype_f32_c, + cudaDataType::CUDA_C_64F => rocsparse_datatype::rocsparse_datatype_f64_c, + cudaDataType::CUDA_R_8I => rocsparse_datatype::rocsparse_datatype_i8_r, + cudaDataType::CUDA_R_8U => rocsparse_datatype::rocsparse_datatype_u8_r, + cudaDataType::CUDA_R_32I => rocsparse_datatype::rocsparse_datatype_i32_r, + cudaDataType::CUDA_R_32U => rocsparse_datatype::rocsparse_datatype_u32_r, + _ => panic!(), + } +} + +unsafe fn spmat_get_size( + sp_mat_descr: cusparseSpMatDescr_t, + rows: *mut i64, + cols: *mut i64, + nnz: *mut i64, +) -> cusparseStatus_t { + to_cuda(rocsparse_spmat_get_size( + sp_mat_descr.cast(), + rows, + cols, + nnz, + )) +} + +unsafe fn csr_set_pointers( + sp_mat_descr: cusparseSpMatDescr_t, + csr_row_offsets: *mut c_void, + csr_col_ind: *mut c_void, + csr_values: *mut c_void, +) -> cusparseStatus_t { + to_cuda(rocsparse_csr_set_pointers( + sp_mat_descr.cast(), + csr_row_offsets, + csr_col_ind, + csr_values, + )) +} + +unsafe fn sparse_destroy(handle: *mut cusparseContext) -> cusparseStatus_t { + to_cuda(rocsparse_destroy_handle(handle.cast())) +} + +unsafe fn get_max_index_base(descr_a: *mut cusparseMatDescr) -> cusparseIndexBase_t { + to_mat_index_base(rocsparse_get_mat_index_base(descr_a.cast())) +} + +fn to_mat_index_base(index_base: rocsparse_index_base) -> cusparseIndexBase_t { + match index_base { + rocsparse_index_base::rocsparse_index_base_zero => { + cusparseIndexBase_t::CUSPARSE_INDEX_BASE_ZERO + } + rocsparse_index_base::rocsparse_index_base_one => { + cusparseIndexBase_t::CUSPARSE_INDEX_BASE_ONE + } + _ => panic!(), + } +} + +unsafe fn get_mat_type(descr_a: *mut cusparseMatDescr) -> cusparseMatrixType_t { + to_mat_type(rocsparse_get_mat_type(descr_a.cast())) +} + +fn to_mat_type(mat_type: rocsparse_matrix_type) -> cusparseMatrixType_t { + match mat_type { + rocsparse_matrix_type::rocsparse_matrix_type_general => { + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_GENERAL + } + rocsparse_matrix_type::rocsparse_matrix_type_symmetric => { + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_SYMMETRIC + } + rocsparse_matrix_type::rocsparse_matrix_type_hermitian => { + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_HERMITIAN + } + rocsparse_matrix_type::rocsparse_matrix_type_triangular => { + cusparseMatrixType_t::CUSPARSE_MATRIX_TYPE_TRIANGULAR + } + _ => panic!(), + } +} + +unsafe fn csr2cscex2_buffersize( + handle: *mut cusparseContext, + m: i32, + n: i32, + nnz: i32, + csr_val: *const c_void, + csr_row_ptr: *const i32, + csr_col_ind: *const i32, + csc_val: *mut c_void, + csc_col_ptr: *mut i32, + csc_row_ind: *mut i32, + val_type: cudaDataType, + copy_values: cusparseAction_t, + idx_base: cusparseIndexBase_t, + alg: cusparseCsr2CscAlg_t, + buffer_size: *mut usize, +) -> cusparseStatus_t { + let copy_values = to_action(copy_values); + to_cuda(rocsparse_csr2csc_buffer_size( + handle.cast(), + m, + n, + nnz, + csr_row_ptr, + csr_col_ind, + copy_values, + buffer_size, + )) +} + +fn to_action(copy_values: cusparseAction_t) -> rocsparse_action { + match copy_values { + cusparseAction_t::CUSPARSE_ACTION_SYMBOLIC => rocsparse_action::rocsparse_action_symbolic, + cusparseAction_t::CUSPARSE_ACTION_NUMERIC => rocsparse_action::rocsparse_action_numeric, + _ => panic!(), + } +} + +type rocsparse_csr2csc_generic = unsafe extern "C" fn( + handle: rocsparse_handle, + m: rocsparse_int, + n: rocsparse_int, + nnz: rocsparse_int, + csr_val: *const c_void, + csr_row_ptr: *const rocsparse_int, + csr_col_ind: *const rocsparse_int, + csc_val: *mut c_void, + csc_row_ind: *mut rocsparse_int, + csc_col_ptr: *mut rocsparse_int, + copy_values: rocsparse_action, + idx_base: rocsparse_index_base, + temp_buffer: *mut ::std::os::raw::c_void, +) -> rocsparse_status; + +unsafe fn csr2cscex2( + handle: *mut cusparseContext, + m: i32, + n: i32, + nnz: i32, + csr_val: *const c_void, + csr_row_ptr: *const i32, + csr_col_ind: *const i32, + csc_val: *mut c_void, + csc_col_ptr: *mut i32, + csc_row_ind: *mut i32, + val_type: cudaDataType, + copy_values: cusparseAction_t, + idx_base: cusparseIndexBase_t, + alg: cusparseCsr2CscAlg_t, + buffer: *mut c_void, +) -> cusparseStatus_t { + let rocsparse_csr2csc_generic = match val_type { + cudaDataType::CUDA_R_32F => { + mem::transmute::<_, rocsparse_csr2csc_generic>(rocsparse_scsr2csc as *const ()) + } + cudaDataType::CUDA_R_64F => { + mem::transmute::<_, rocsparse_csr2csc_generic>(rocsparse_dcsr2csc as *const ()) + } + cudaDataType::CUDA_C_32F => { + mem::transmute::<_, rocsparse_csr2csc_generic>(rocsparse_ccsr2csc as *const ()) + } + cudaDataType::CUDA_C_64F => { + mem::transmute::<_, rocsparse_csr2csc_generic>(rocsparse_zcsr2csc as *const ()) + } + _ => panic!(), + }; + let copy_values = to_action(copy_values); + let idx_base = index_base(idx_base); + to_cuda(rocsparse_csr2csc_generic( + handle.cast(), + m, + n, + nnz, + csr_val, + csr_row_ptr, + csr_col_ind, + csc_val, + csc_row_ind, + csc_col_ptr, + copy_values, + idx_base, + buffer, + )) +} + +unsafe fn destory_dnvec(dn_vec_descr: *mut cusparseDnVecDescr) -> cusparseStatus_t { + if dn_vec_descr == ptr::null_mut() { + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } else { + to_cuda(rocsparse_destroy_dnvec_descr(dn_vec_descr.cast())) + } +} + +unsafe fn destory_csrilu02info(info: *mut csrilu02Info) -> cusparseStatus_t { + if info == ptr::null_mut() { + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } else { + to_cuda(rocsparse_destroy_mat_info(info.cast())) + } +} + +unsafe fn destroy_csric02info(info: *mut csric02Info) -> cusparseStatus_t { + if info == ptr::null_mut() { + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } else { + to_cuda(rocsparse_destroy_mat_info(info.cast())) + } +} + +unsafe fn spmat_set_attribute( + sp_mat_descr: *mut cusparseSpMatDescr, + attribute: cusparseSpMatAttribute_t, + data: *mut c_void, + data_size: usize, +) -> cusparseStatus_t { + let attribute = to_attribute(attribute); + // Both diag type and fill mode are compatible, no adjustment needed + to_cuda(rocsparse_spmat_set_attribute( + sp_mat_descr.cast(), + attribute, + data, + data_size, + )) +} + +fn to_attribute(attribute: cusparseSpMatAttribute_t) -> rocsparse_spmat_attribute { + match attribute { + cusparseSpMatAttribute_t::CUSPARSE_SPMAT_DIAG_TYPE => { + rocsparse_spmat_attribute::rocsparse_spmat_diag_type + } + cusparseSpMatAttribute_t::CUSPARSE_SPMAT_FILL_MODE => { + rocsparse_spmat_attribute::rocsparse_spmat_fill_mode + } + _ => panic!(), + } +} + +unsafe fn create_csrilu02_info(info: *mut *mut csrilu02Info) -> cusparseStatus_t { + to_cuda(rocsparse_create_mat_info(info.cast())) +} + +struct SpSvDescr { + external_buffer: *mut c_void, +} + +unsafe fn spsv_create_descr(descr: *mut *mut cusparseSpSVDescr) -> cusparseStatus_t { + *(descr.cast()) = Box::into_raw(Box::new(SpSvDescr { + external_buffer: ptr::null_mut(), + })); + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +unsafe fn spsv_drstroy_desc(descr: *mut cusparseSpSVDescr) -> cusparseStatus_t { + if descr == ptr::null_mut() { + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } else { + Box::from_raw(descr.cast::()); + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS + } +} + +unsafe fn spsv_buffersize( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + alpha: *const c_void, + mat_a: *mut cusparseSpMatDescr, + vec_x: cusparseDnVecDescr_t, + vec_y: cusparseDnVecDescr_t, + compute_type: cudaDataType, + alg: cusparseSpSVAlg_t, + spsv_descr: *mut cusparseSpSVDescr, + buffer_size: *mut usize, +) -> cusparseStatus_t { + let op_a = operation(op_a); + let compute_type = data_type(compute_type); + let alg = to_spsv_alg(alg); + to_cuda(rocsparse_spsv( + handle.cast(), + op_a, + alpha, + mat_a.cast(), + vec_x.cast(), + vec_y.cast(), + compute_type, + alg, + rocsparse_spsv_stage::rocsparse_spsv_stage_buffer_size, + buffer_size, + ptr::null_mut(), + )) +} + +fn to_spsv_alg(alg: cusparseSpSVAlg_t) -> rocsparse_spsv_alg { + match alg { + cusparseSpSVAlg_t::CUSPARSE_SPSV_ALG_DEFAULT => { + rocsparse_spsv_alg::rocsparse_spsv_alg_default + } + _ => panic!(), + } +} + +unsafe fn spsv_analysis( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + alpha: *const c_void, + mat_a: *mut cusparseSpMatDescr, + vec_x: *mut cusparseDnVecDescr, + vec_y: *mut cusparseDnVecDescr, + compute_type: cudaDataType, + alg: cusparseSpSVAlg_t, + spsv_descr: *mut cusparseSpSVDescr, + external_buffer: *mut c_void, +) -> cusparseStatus_t { + let op_a = operation(op_a); + let compute_type = data_type(compute_type); + let alg = to_spsv_alg(alg); + let spsv_descr = spsv_descr.cast::().as_mut().unwrap(); + spsv_descr.external_buffer = external_buffer; + to_cuda(rocsparse_spsv( + handle.cast(), + op_a, + alpha, + mat_a.cast(), + vec_x.cast(), + vec_y.cast(), + compute_type, + alg, + rocsparse_spsv_stage::rocsparse_spsv_stage_preprocess, + ptr::null_mut(), + external_buffer, + )) +} + +unsafe fn spsv_solve( + handle: *mut cusparseContext, + op_a: cusparseOperation_t, + alpha: *const c_void, + mat_a: *mut cusparseSpMatDescr, + vec_x: *mut cusparseDnVecDescr, + vec_y: *mut cusparseDnVecDescr, + compute_type: cudaDataType, + alg: cusparseSpSVAlg_t, + spsv_descr: *mut cusparseSpSVDescr, +) -> cusparseStatus_t { + let op_a = operation(op_a); + let compute_type = data_type(compute_type); + let alg = to_spsv_alg(alg); + let spsv_descr = spsv_descr.cast::().as_ref().unwrap(); + to_cuda(rocsparse_spsv( + handle.cast(), + op_a, + alpha, + mat_a.cast(), + vec_x.cast(), + vec_y.cast(), + compute_type, + alg, + rocsparse_spsv_stage::rocsparse_spsv_stage_compute, + ptr::null_mut(), + spsv_descr.external_buffer, + )) +} + +unsafe fn dcsrilu02_buffersize( + handle: *mut cusparseContext, + m: i32, + nnz: i32, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a: *mut f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrilu02Info, + p_buffer_size_in_bytes: *mut i32, +) -> cusparseStatus_t { + let mut buffer_size = 0; + call! {rocsparse_dcsrilu0_buffer_size( + handle.cast(), + m, + nnz, + descr_a.cast(), + csr_sorted_val_a, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + &mut buffer_size, + ) }; + if buffer_size > i32::MAX as usize { + return cusparseStatus_t::CUSPARSE_STATUS_INTERNAL_ERROR; + } + *p_buffer_size_in_bytes = buffer_size as i32; + cusparseStatus_t::CUSPARSE_STATUS_SUCCESS +} + +unsafe fn dcsrilu02_analysis( + handle: *mut cusparseContext, + m: i32, + nnz: i32, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a: *const f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrilu02Info, + policy: cusparseSolvePolicy_t, + p_buffer: *mut c_void, +) -> cusparseStatus_t { + let (analysis, solve) = to_policy(policy); + to_cuda(rocsparse_dcsrilu0_analysis( + handle.cast(), + m, + nnz, + descr_a.cast(), + csr_sorted_val_a, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + analysis, + solve, + p_buffer, + )) +} + +unsafe fn xcsrilu02_zeropivot( + handle: *mut cusparseContext, + info: *mut csrilu02Info, + position: *mut i32, +) -> cusparseStatus_t { + to_cuda(rocsparse_csrilu0_zero_pivot( + handle.cast(), + info.cast(), + position, + )) +} + +unsafe fn dcsrilu02( + handle: *mut cusparseContext, + m: i32, + nnz: i32, + descr_a: *mut cusparseMatDescr, + csr_sorted_val_a_val_m: *mut f64, + csr_sorted_row_ptr_a: *const i32, + csr_sorted_col_ind_a: *const i32, + info: *mut csrilu02Info, + policy: cusparseSolvePolicy_t, + p_buffer: *mut c_void, +) -> cusparseStatus_t { + let (analysis, solve) = to_policy(policy); + to_cuda(rocsparse_dcsrilu0( + handle.cast(), + m, + nnz, + descr_a.cast(), + csr_sorted_val_a_val_m, + csr_sorted_row_ptr_a, + csr_sorted_col_ind_a, + info.cast(), + solve, + p_buffer, + )) +}